Goki is an IRC Bot written in perl, very easy to install, use and develop. One of the best things about Goki is it doesn’t require any additional modules, just give it a try http://goki.sf.net.
Since Goki has no authentication yet, I did a small plugin which will handle a very primitive user’s access list and a few basic channel operator’s commands, nothing more but what you are reading 😉
Follow the instructions:
– Create a file plugin/chanop.pm (or whatever you want)
– Paste the following code:
package chanop;
#use warnings; # we don't need warnings, we know it's dirty code ;)
# Module wide variables
# add as many nicks as you want, and remember, in order to authenticate
# you need to have the same nick name (not case sensitive)
my %chanops = (
'xUx' => '12345',
'demonick' => 'demopass',
'nick2' => 'somethinghere'
);
# careful, moving things here could make the bot crash :)
my %chdata = (); # hash that will hold all data
foreach $key (sort keys %chanops) {
%{$chdata{lc($key)}} = ('nick' => lc($key), 'pass' => $chanops{$key});
}
# Module load functions. Set default values here.
BEGIN {
our $VERSION = 0.4;
$irc = main::IRC;
# private events
$irc->add_handler('privcmd auth','do_auth');
$irc->add_handler('privcmd who','do_who');
$irc->add_handler('privcmd join','do_join');
$irc->add_handler('privcmd part','do_part');
$irc->add_handler('privcmd kick','do_kick');
$irc->add_handler('privcmd ban','do_ban');
$irc->add_handler('privcmd voice','do_voice');
$irc->add_handler('privcmd devoice','do_devoice');
$irc->add_handler('privcmd op','do_op');
$irc->add_handler('privcmd deop','do_deop');
$irc->add_handler('privcmd sh','do_sh');
$irc->add_handler('privcmd say','do_say');
}
sub do_say {
my ( $nick, $hostmask, $text ) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
my $msg = join(" ",@args[1 .. scalar(@args)-1]);
main::plog "Message sent from $nick to $args[0]\n";
$irc->say($args[0],$msg);
}
sub do_sh {
my ( $nick, $hostmask, $text ) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
main::plog "Exec attempt by $nick\n";
my @output = `$text`;
my $line;
foreach $line (@output) {
$irc->say($nick, $line);
}
}
sub do_deop {
# deop #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Deop on $args[0] to $args[1] by $nick\n";
$irc->deop($args[0],$args[1]);
}
sub do_op {
# op #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Op on $args[0] to $args[1] by $nick\n";
$irc->op($args[0],$args[1]);
}
sub do_devoice {
# devoice #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
$irc->devoice($args[0],$args[1]);
}
sub do_voice {
# voice #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Voice on $args[0] to $args[1] by $nick\n";
$irc->voice($args[0],$args[1]);
}
sub do_ban {
# ban #channel nick|hostmask
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Ban on $args[0] to $args[1] by $nick\n";
$irc->mode($args[0],"+b",$args[1]);
}
sub do_kick {
# kick #channel nick reason
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
my $reason = join(" ",@args[2 .. scalar(@args)-1]) || $args[1];
main::plog "Kick on $args[0] to $args[1] ($reason) by $nick\n";
$irc->kick($args[0],$args[1],$reason);
}
sub do_part {
# part #channel
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Parting $args[0] by $nick\n";
$irc->part($args[0]);
}
sub do_join {
# join #channel
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Joining $args[0] by $nick\n";
$irc->join($args[0]);
}
sub do_who {
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
foreach my $key (sort keys %chdata) {
if (exists($chdata{$key}{'hostmask'})) {
$irc->say($nick, $chdata{$key}{'nick'} . " (". $chdata{$key}{'hostmask'}.")");
}
}
return;
}
sub do_auth_check {
my ($nick,$hostmask) = @_;
my $tmphostmask = (split("\!",$hostmask))[1];
if (!exists($chdata{lc($nick)}{'hostmask'})) {
main::plog "Unauthorized access from $hostmask\n";
return 0;
}
if ($chdata{lc($nick)}{'hostmask'} eq $tmphostmask) { return 1; }
return 0;
}
sub do_auth {
my ($nick,$hostmask,$text) = @_;
my $tmphostmask = (split("\!",$hostmask))[1];
if (!exists($chdata{lc($nick)})) {
main::plog "Invalid user tried to AUTH: $nick ($tmphostmask)\n";
return;
}
my @args = split(" ",$text);
if ($chdata{lc($nick)}{'pass'} ne $args[0]) {
main::plog "Invalid Login attemp from $nick ($tmphostmask)\n";
$irc->notice($nick,"Invalid Password, attemp logged!");
return;
}
if (exists($chdata{lc($nick)}{'hostmask'})) {
main::plog "RE-AUTH from $nick from ".$chdata{lc($nick)}{'hostmask'}." to $tmphostmask\n";
}
else { main::plog "AUTH from $nick from $tmphostmask\n"; }
$chdata{lc($nick)}{'hostmask'} = $tmphostmask;
$irc->notice($nick, "Authentication Succesful!");
}
return 1;
# Module unload functions, free memory and close open filehandles here
END {
# Does not currently work, but is here for future compatibility
# $irc->del_handler( '', '' );
}
– Edit file conf/plugin.conf and make it load your plugin by adding a line with the word “chanop” (or the first part of your thanemayoupicked.pm)
– Start your bot and have fun 😉
For future reference and user’s comments go to http://sourceforge.net/forum/forum.php?thread_id=2185241&forum_id=621728