Skip to content

Instantly share code, notes, and snippets.

@sarahhodne
Created April 16, 2009 15:57
Show Gist options
  • Save sarahhodne/96486 to your computer and use it in GitHub Desktop.
Save sarahhodne/96486 to your computer and use it in GitHub Desktop.
# blah blah redistribution blah warranty blah
use Irssi;
use strict;
use vars qw($VERSION %IRSSI);
$VERSION='0.1';
%IRSSI=(
authors => qw(grawity dvyjones),
name => 'Dvyjones\' nifty IRC bot',
description => 'Does things.',
license => 'WTFPL 2.0'
);
my $myOwner = '[email protected]';
my $trigger = 'dvyjonesniftybot';
sub demoronizeFunkyIPs {
my ($in) = @_;
my $out;
foreach my $piece (split /\./, $in) {
if (/^0x0*[0-9a-f]{1,2}$/i) {
$out .= "." . hex $piece;
}
elsif (/^0+[0-7]{1,2}$/) {
$out .= "." . oct $piece;
}
else {
$out .= "." . $piece;
}
}
}
sub onMessage {
my ($server, $message, $srcNick, $srcAddress, $target) = @_;
my $myNick = $server->{nick};
my $isOwner = $server->masks_match($myOwner, $srcNick, $srcAddress);
my $source = $srcNick."!".$srcAddress;
my ($isPrivate, $replyTo, $prettySource, $replyPrefix);
if ($target =~ /^#/) {
$isPrivate = 0;
$replyTo = $target;
$prettySource = $srcNick . " on " . $target;
$replyPrefix = $srcNick.": ";
}
else {
$isPrivate = 1;
$replyTo = $srcNick;
$prettySource = $srcNick;
$replyPrefix = "";
}
my @argv = split /\s+/, $message;
my $argc = @argv;
$message =~ m/^([^\s]*)\s(.*)$/;
my $command = $1;
my $args = $2;
for ($message) {
# check the entire line
if (/^&\/?last\s*/i) {
return if $argc < 1;
return if $isPrivate and not $isOwner;
return if $isPrivate and $argc < 2;
my $channel = $isPrivate ? $argv[1] : $target;
$channel =~ tr/A-Z/a-z/;
my $logfile = '~/.dvybot/irclogs/'.$server->{tag}.'/'.$channel.'.log';
my @tail = `tail -n 14 $logfile`;
$server->send_message($srcNick, '-----BEGIN LOG FOR '.$channel.'-----', 1);
foreach my $line (@tail) {
$server->send_message($srcNick, "[".$channel."] ".$line, 1);
}
$server->send_message($srcNick, '-----END LOG FOR '.$channel.'-----', 1);
}
elsif (/^&rule ([0-9a-z.]+)$/) {
my %rules = (
"0" => "Don't be an asshole",
"1.3.3.7" => "This rule doesn't exist. Stop trying",
"1.1" => "No Leetspeak",
"1.2" => "No Malicious or Illegal Bots",
"1.3" => "Obey All Channel Operators of the Channels You are In",
"1.4" => "Obey All Network Operators",
"1.5" => "No Threats of DoS or Other Illegal Attacks",
"1.6" => "No DNS Spam Hosts",
"1.7" => "No Colors in Channel Topics",
"1.8" => "No Ban Evasion",
"1.9" => "No Harassment or Flooding",
"1.10" => "No Spreading of Viruses, Intentionally or Unintentionally",
"1.11" => "No Illegal Activity",
"2.1" => "No Auto-Rejoin on Kick",
"2.2" => "No Blatant Insults or Nonconstructive Criticism",
"2.3" => "No Private-Message Without Permission",
"2.4" => "Speak English",
"2.5" => "Use Clueful Chatting to the Best of your Ability",
"2.6" => "No Promotion or Emulation of Illegal Activity",
"3.1" => "No Frivolous Kills or Bans"
);
if ($rules{$1} eq "") {
$server->command("/msg ".$replyTo." Rule ".$1."not found.");
}
else {
$server->command("/msg ".$replyTo." ClueNet IRC Rule ".$1.": ".$rules{$1});
}
}
elsif (/^&rules$/i) {
$server->command("/msg ".$replyTo." ClueNet IRC rules can be found at http://wiki.cluenet.org/IRC_Rules .");
}
elsif (/^\.ccl? ${myNick}\s*$/) {
return if $isPrivate;
sleep 1;
if (int rand(5) > 2) {
$server->command('/msg '.$replyTo.' '.$replyPrefix.'No thanks. I\'ll stay quiet.');
} else {
$server->command('/msg '.$replyTo.' '.$replyPrefix.'I\'m a bot, idiot. Bots don\'t talk.');
}
}
elsif (/^\.ld ${myNick}\s*$/) {
return if $isPrivate;
$server->command('/msg '.$srcNick.' Not funny.');
if ($srcNick eq 'Cobi' or $srcNick eq 'Crispy') {
sleep 5;
$server->command('/join '.$target);
$server->command('/msg '.$replyTo.' '.$replyPrefix.'Not funny.');
}
}
elsif (/^\.\/\.dvybot\/configure/) {
my @replies = (
'Bad command or file name',
'bash: ./.dvybot/configure: command not found',
'make install clean',
'%DCL-W-IVVERB, unrecognized command verb - check validity and spelling',
'sudo rm -rf /',
);
if (int rand(100) < 70) {
$server->command('/msg '.$replyTo.' '.$replies[int rand(1+$#replies)]);
}
}
elsif (($isPrivate and /a\/?s\/?l/i) or (not $isPrivate and /^${myNick}[:,]? a\/?s\/?l/i)) {
print "asl from ".$source;
my $age;
if (int rand(10) > 4) { $age = int rand(400) + 900; }
else { $age = int rand(100) - 100; }
srand time;
my @sex = qw(unknown male geek female uhh dude guy tree emo dumbass evilgenius nathan yourmom);
my @location = qw(USA Idiotistan Mars 127.0.0.1 Fuckyouville Hogwarts Internets your-arse Netherlands);
$server->command('/msg '.$replyTo.' '.$replyPrefix.$age.'/'.$sex[int rand($#sex)].'/'.$location[int rand($#location)]);
}
# no exact matches so far, check for "logbot:" prefix (not necessary for PMs)
elsif (($isPrivate and /^(.+)$/) or /^(?:dvybot|dvyjonesniftybot|computer|${myNick})[:,] (.+)$/i) {
for ($1) {
if (/^(die[^a-z]+|rm -rf|format [a-zA-Z]:)$/) {
$server->send_message("MemoServ", "send dvyjones dvybot shutdown requested by ".$source." on ".$server->{tag}, 1);
return unless $isOwner;
print "quit by ".$source;
$server->command("/msg ".$replyTo." Ok, ".$srcNick);
#$server->command("/disconnect ".$server->{tag}." requested by ".$prettySource);
$server->command("/quit requested by ".$prettySource."/".$server->{tag});
}
elsif (/^(can|would) you (please )?(kill|terminate|kick|get rid of) (.+)\?$/i) {
return unless $isOwner;
return if $isPrivate;
$server->command("/kick $replyTo $4 Requested by $srcNick.");
}
elsif (/^poke/) {
$server->send_message($replyTo, $replyPrefix."Ouch!", $isPrivate);
}
elsif (/^(run|plz|C:\\>) \//) {
return unless $isOwner;
$server->command("/msg ".$replyTo." Ok, ".$srcNick);
$args =~ /^[^\s]+ (\/.*)$/;
$server->command($1);
}
elsif (/^reload/) {
return unless $isOwner;
print "reload by ".$source;
$server->command("/run nifty_bot");
$server->command("/msg ".$replyTo." Ok, ".$srcNick);
}
elsif (/^slap (.+)$/) {
$server->command("/action $replyTo slaps $1 around a bit with a large trout");
}
elsif (/^(#.+)/) {
if ($1 =~ /,0/) {
$server->command("/kick $replyTo $srcNick This... Is... SPARTA!!@") unless $isPrivate;
return;
}
print "join -> ".$1." by ".$source;
$server->command("/msg ".$replyTo." Ok, ".$srcNick);
$server->channels_join($1, 1);
#$server->command("/join ".$1);
}
elsif (/^(leave|part)( #.+)?/) {
#return unless $isOwner;
return if $isPrivate;
return if $srcNick eq "Cobi" or $srcNick eq "Crispy" or $srcNick eq "C-N810";
my $channel = $2 eq "" ? $target : $2;
print "part <> ".$channel." by ".$source;
$server->command("/msg ".$replyTo." Ok, ".$srcNick);
$server->command("/part ".$channel);
}
elsif (/^invite (me|.*) to (#.+)\.?$/) {
my $who = ($1 eq "me" ? $srcNick : $1);
my $where = $2;
return if not $isOwner and $who ne $srcNick;
$server->command('/invite '.$who.' '.$where);
}
elsif (/^invite (.*)\.?$/) {
return if $isPrivate;
my $who = ($1 eq "me" ? $srcNick : $1);
my $where = $target;
$server->command('/invite '.$who.' '.$where);
}
elsif (/^kick (me|.*)(\.| for .+)\.?$/) {
return unless $isOwner or $1 eq "me";
return if $isPrivate;
my $targets = (($1 eq "me") ? $srcNick : $1);
my $reason = (($2 eq ".") ? "kthxbai" : $2);
$reason =~ s/^ for //;
$reason =~ s/\s$//;
$server->command('/kick '.$target.' '.$targets.' '.$reason);
}
elsif (/^\/?(|de|un)(op|voice|halfop) (?:on )?(me|.*[^.])\.?$/) {
return if $isPrivate;
my $mode = $isOwner? ($1 eq "" ? "+" : "-") : "-";
my $targets = $isOwner? ($3 eq "me"? $srcNick : $3) : $srcNick;
my %modes = (
'op' => 'o',
'voice' => 'v',
'halfop' => 'h',
'ban' => 'b',
'except' => 'e',
'key' => 'k',
'limit' => 'l',
'admin' => 'a',
'owner' => 'q'
);
foreach my $temp (split /\s+/, $targets) { $mode .= $modes{$2}; }
$server->command('/mode '.$target.' '.$mode.' '.$targets);
}
elsif (/^(|de|un|remove |unset )(op|voice|halfop|ban|except|key|limit|admin|owner) (?:on )?(me|.*[^.])\.?$/) {
return if $isPrivate;
my $mode = $isOwner? ($1 eq "" ? "+" : "-") : "-";
my $targets = $isOwner? ($3 eq "me"? $srcNick : $3) : $srcNick;
my %modes = (
'op' => 'o',
'voice' => 'v',
'halfop' => 'h',
'ban' => 'b',
'except' => 'e',
'key' => 'k',
'limit' => 'l',
'admin' => 'a',
'owner' => 'q'
);
foreach my $temp (split /\s+/, $targets) { $mode .= $modes{$2}; }
$server->command('/mode '.$target.' '.$mode.' '.$targets);
}
elsif (/^mode (.+)\.?$/) {
return unless $isOwner;
return if $isPrivate;
$server->command('/mode '.$target.' '.$1);
}
elsif (/^\/(.+)$/) {
if ($isOwner) {
$server->command($1);
}
else {
$server->command("/action ".$replyTo." kicks ".$srcNick);
}
}
elsif (/(.+)$/) {
return unless $isOwner;
my $max = 4; # including the [more] line
my $thing = $1;
if ($thing =~ /^all /) {
$thing =~ s/^all (.+)$/$1/;
$max = 0;
}
my @out = `$thing 2>&1`;
my $i = 0; my $count = 1+$#out; my $line; my $left;
while ((($max == 0) || ($i < $max)) && ($i < $count)) {
$line = $out[$i];
$left = $count - $i;
if (($max > 0) && ($i+1 == $max) && ($left > 1)) {
$server->command("/msg ${replyTo} [$left more lines]");
}
else {
$server->command("/msg ${replyTo} ${line}");
}
$i++;
}
}
}
} # end if $myNick
# handle all other private messages
elsif ($isPrivate and not $isOwner) {
#$server->send_message("MemoServ", "send grawity <".$source."> ".$_, 1);
$server->send_message("#clueirc", "<".$srcNick."> ".$_, 0);
}
}
}
sub onPrivateMessage {
my ($server, $message, $srcNick, $srcAddress) = @_;
onMessage($server, $message, $srcNick, $srcAddress, $srcNick);
}
Irssi::signal_add_last('message public','onMessage');
Irssi::signal_add_last('message private','onPrivateMessage');
sub onInvite {
my ($server, $channel, $srcNick, $srcAddress) = @_;
$server->channels_join($channel, 1);
$server->command("/action ".$channel." m00s contentedly at ".$srcNick.".");
}
Irssi::signal_add_last('message invite','onInvite');
sub onKick {
my ($server, $channel, $victim, $srcNick, $srcAddress, $reason) = @_;
if ($victim eq $server->{nick}) {
$server->command("/msg ".$srcNick." Owie. Why?");
}
}
#Irssi::signal_add_last('message kick','onKick');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment