Source code
Source code listing for nanobot
- Copyright (c) 2011, Insomnia 24/7 All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer. Redistributions in binary
- form must reproduce the above copyright notice, this list of conditions and
- the following disclaimer in the documentation and/or other materials
- provided with the distribution. Neither the name of Insomnia 24/7 nor
- the names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- DAMAGE.
- !/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.
- 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 = ();
- 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;
}
}
- Kick things off ######
logts("Nanobot is starting...\n");
&directories;
while(1) {
&connct;
sleep(2);
}
- 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");
}
}
}
- Screen output subroutine #####
sub logts {
if ($logging == 1){
print STDOUT "$_[0]";
}
}
- 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]";
}
}
- 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;
}
- Subroutine for sending data to the IRC server #####
sub snd {
print $sock "$_[0]\n";
debug_extra("<== $_[0]\n");
}
- Subroutine for sending messages to the IRC server #####
sub msg {
snd("PRIVMSG $_[0] :$_[1]");
}
- Subroutine for sending notices to the IRC server #####
sub ntc {
snd("NOTICE $_[0] :$_[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; }
}
}
}
}
- 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;
}
- NickServ AUTH ######
sub nickserv{
if ($nsp) {
logts("Identifying nick ..... ");
msg("NickServ", "identify $nsp");
logts("[OK]\n");
}
}
- Join listed channels #####
sub joinlist {
logts("Joining channel(s) ... ");
foreach $chan (@channels) {
snd("JOIN $chan");
}
logts("[OK]\n");
# Also call autoload modules now
&autoload;
}
- Attempt to autoload specified modules #####
sub autoload {
foreach $loadme (@autoload) {
&autoloadmodule($loadme);
}
}
- !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");
}
- !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");
}
}
}
}
}
- 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";
}
}
}
}
}
- !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.");
}
}
- !raw #####
sub raw {
debug("Received \"raw\"-command.\n");
my ($cmd,@data) = split(/ /, $args);
snd("@data");
logts("Raw command was used by $from.\n");
}
- !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");
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
}
}
- !loaded #####
sub loaded {
snd("NOTICE $from :Loaded modules: @modules");
}
- !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");
}
- !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");
}
}
- 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");
}
}
}
- !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");
}
}
- !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");
}
}
}
}
- 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);
}
}
- 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++;
}
}
}
- !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");
}
- !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.");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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");
}
}
- !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;
}
- Process exit subroutine #####
sub shutd {
logts("Shutting down.\n");
debug("Final line of code before exit call.\n");
exit(0);
}