3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-20 02:49:49 +01:00

Added unload_module, enable_command, disable_command

Automatically export factoids every 5 minutes
Fork modules
This commit is contained in:
Pragmatic Software 2007-07-01 22:39:06 +00:00
parent 9ba81accdd
commit ff4648cf4d

141
pbot2.pl
View File

@ -8,12 +8,15 @@
# Version History: # Version History:
######################## ########################
my $VERSION = "0.3.12"; my $VERSION = "0.3.13";
######################## ########################
# todo! add support for admin management # todo! add support for admin management
# todo! gah, multi-channel support pathetic # todo! multi-channel support pathetic
# todo! most of this crap needs to be refactored # todo! most of this crap needs to be refactored
# 0.3.13(07/01/07): fork all modules
# added unload_module, enable_command, disable_command
# automatically export factoids every $export_factoids_timeout seconds
# 0.3.12(05/20/07): lol? Prevent recursive aliasing infinite loop, x -> a, a -> x # 0.3.12(05/20/07): lol? Prevent recursive aliasing infinite loop, x -> a, a -> x
# 0.3.11(05/20/07): added 'alias' # 0.3.11(05/20/07): added 'alias'
# 0.3.10(05/08/05): dont ban by nick, wait for nickserv response before joining chans # 0.3.10(05/08/05): dont ban by nick, wait for nickserv response before joining chans
@ -98,6 +101,11 @@ use HTML::Entities; # for exporting
use Time::HiRes qw(gettimeofday alarm); use Time::HiRes qw(gettimeofday alarm);
use strict; use strict;
use POSIX 'WNOHANG';
# automatically reap children processes in background
$SIG{CHLD} = sub { while(waitpid(-1, WNOHANG) > 0) {} };
my $child = 0; # this process is not the child
#unbuffer stdout #unbuffer stdout
STDOUT->autoflush(1); STDOUT->autoflush(1);
@ -105,7 +113,7 @@ STDOUT->autoflush(1);
$SIG{ALRM} = \&sig_alarm_handler; $SIG{ALRM} = \&sig_alarm_handler;
# some configuration variables # some configuration variables
my $home = '/home/msmud'; my $home = $ENV{HOME};
my $channels_file = "$home/pbot2/channels"; my $channels_file = "$home/pbot2/channels";
my $commands_file = "$home/pbot2/commands"; my $commands_file = "$home/pbot2/commands";
my $admins_file = "$home/pbot2/admins"; my $admins_file = "$home/pbot2/admins";
@ -114,6 +122,8 @@ my $ircserver = 'irc.freenode.net';
my $botnick = 'pbot2'; my $botnick = 'pbot2';
my $altbotnick = 'pbot2_'; my $altbotnick = 'pbot2_';
my $identify_password = '*'; my $identify_password = '*';
my $export_factoids_timeout = 300; # every 5 minutes
my $export_factoids_path = "$home/htdocs/candide/factoids.html";
my $FLOOD_CHAT = 0; my $FLOOD_CHAT = 0;
my $FLOOD_JOIN = 1; my $FLOOD_JOIN = 1;
@ -128,14 +138,14 @@ my %commands = ( version => {
ref_user => "nobody" } ref_user => "nobody" }
); );
my %admins = ( adminnick => { my %admins = ( admin_nick => {
password => '*', password => '*',
level => 50, level => 50,
host => "host.com" }, host => "blackshell.com" },
anothernick => { another_admin => {
password => '*', password => '*',
level => 20, level => 50,
host => ".*.wildcardhost.com" } host => ".*.wildcard.edu" }
); );
my %channels = (); my %channels = ();
@ -171,8 +181,8 @@ my %internal_commands = (
list => { sub => \&list, level => 0 }, list => { sub => \&list, level => 0 },
load => { sub => \&load_module, level => 40 }, load => { sub => \&load_module, level => 40 },
unload => { sub => \&unload_module, level => 40 }, unload => { sub => \&unload_module, level => 40 },
enable => { sub => \&enable_module, level => 20 }, enable => { sub => \&enable_command, level => 20 },
disable => { sub => \&disable_module, level => 20 }, disable => { sub => \&disable_command,level => 20 },
quiet => { sub => \&quiet, level => 10 }, quiet => { sub => \&quiet, level => 10 },
unquiet => { sub => \&unquiet, level => 10 }, unquiet => { sub => \&unquiet, level => 10 },
ignore => { sub => \&ignore_user, level => 10 }, ignore => { sub => \&ignore_user, level => 10 },
@ -225,7 +235,6 @@ sub loggedin {
sub export { sub export {
my ($from, $nick, $host, $arguments) = @_; my ($from, $nick, $host, $arguments) = @_;
my $text;
if(not defined $arguments) { if(not defined $arguments) {
return "/msg $nick Usage: export <modules|factoids|admins>"; return "/msg $nick Usage: export <modules|factoids|admins>";
@ -236,7 +245,17 @@ sub export {
} }
if($arguments =~ /^factoids$/i) { if($arguments =~ /^factoids$/i) {
open FILE, "> /var/www/htdocs/candide/factoids.html"; return export_factoids();
}
if($arguments =~ /^admins$/i) {
return "/msg $nick Coming soon.";
}
}
sub export_factoids() {
my $text;
open FILE, "> $export_factoids_path" or return "Could not open export path.";
my $time = localtime; my $time = localtime;
print FILE "<html><body><i>Generated at $time</i><hr><h3>Candide's factoids:</h3><br>\n"; print FILE "<html><body><i>Generated at $time</i><hr><h3>Candide's factoids:</h3><br>\n";
my $i = 0; my $i = 0;
@ -259,14 +278,11 @@ sub export {
} }
} }
print FILE "</table>\n"; print FILE "</table>\n";
print FILE "<hr>$i factoids memorized.<br>This page is not generated in real-time. An admin must 'export factoids'.</body></html>"; print FILE "<hr>$i factoids memorized.<br>This page is automatically generated every $export_factoids_timeout seconds.</body></html>";
close(FILE); close(FILE);
return "$i factoids exported to http://pragma.homeip.net/candide/factoids.html"; plog "$i factoids exported.\n";
} return "$i factoids exported to http://blackshell.com/~msmud/candide/factoids.html";
if($arguments =~ /^admins$/i) {
return "/msg $nick Coming soon.";
}
} }
sub list { sub list {
@ -298,7 +314,7 @@ sub list {
} }
if($arguments =~ /^factoids$/i) { if($arguments =~ /^factoids$/i) {
return "For a list of factoids see http://pragma.homeip.net/candide/factoids.html"; return "For a list of factoids see http://blackshell.com/~msmud/candide/factoids.html";
} }
if($arguments =~ /^admins$/i) { if($arguments =~ /^admins$/i) {
@ -633,16 +649,49 @@ sub load_module {
sub unload_module { sub unload_module {
my ($from, $nick, $host, $arguments) = @_; my ($from, $nick, $host, $arguments) = @_;
if(not defined $arguments) {
return "/msg $nick Usage: unload <module>";
} elsif(not exists $commands{$arguments}) {
return "/msg $nick $arguments not found.";
} elsif(not exists $commands{$arguments}{module}) {
return "/msg $nick $arguments is not a module.";
} else {
delete $commands{$arguments};
save_commands();
plog "$nick ($host) unloaded module $arguments\n";
return "/msg $nick $arguments unloaded.";
}
} }
sub enable_module { sub enable_command {
my ($from, $nick, $host, $arguments) = @_; my ($from, $nick, $host, $arguments) = @_;
return "/msg $nick Coming soon.";
if(not defined $arguments) {
return "/msg $nick Usage: enable <command>";
} elsif(not exists $commands{$arguments}) {
return "/msg $nick $arguments not found.";
} else {
$commands{$arguments}{enabled} = 1;
save_commands();
plog "$nick ($host) enabled $arguments\n";
return "/msg $nick $arguments enabled.";
}
} }
sub disable_module { sub disable_command {
my ($from, $nick, $host, $arguments) = @_; my ($from, $nick, $host, $arguments) = @_;
return "/msg $nick Coming soon.";
if(not defined $arguments) {
return "/msg $nick Usage: disable <command>";
} elsif(not exists $commands{$arguments}) {
return "/msg $nick $arguments not found.";
} else {
$commands{$arguments}{enabled} = 0;
save_commands();
plog "$nick ($host) disabled $arguments\n";
return "/msg $nick $arguments disabled.";
}
} }
sub login { sub login {
@ -988,19 +1037,25 @@ sub interpret_command {
# Then, we check bot commands # Then, we check bot commands
foreach $command (keys %commands) { foreach $command (keys %commands) {
if(lc $keyword =~ /^\Q$command\E$/i) { if(lc $keyword =~ /^\Q$command\E$/i) {
# If it's a module, todo: add enable/disable support if(exists $commands{$keyword} && $commands{$keyword}{enabled} == 0) {
if(exists $commands{$keyword} && exists $commands{$keyword}{module}) { return "$keyword is currently disabled.";
} elsif(exists $commands{$keyword} && exists $commands{$keyword}{module}) {
$commands{$keyword}{ref_count}++; $commands{$keyword}{ref_count}++;
$commands{$keyword}{ref_user} = $nick; $commands{$keyword}{ref_user} = $nick;
# my $pid = fork(); my $pid = fork;
# return "Resources not available." if(not defined $pid); if(not defined $pid) {
# if($pid == 0) plog "Could not fork: $!\n";
# { return "/me groans loudly.";
}
if($pid == 0) {
$child = 1; # set to be killed after returning
if(defined $arguments) { if(defined $arguments) {
plog "($from): $nick ($host): Executing module $commands{$keyword}{module} $arguments\n"; plog "($from): $nick ($host): Executing module $commands{$keyword}{module} $arguments\n";
$arguments = quotemeta($arguments); $arguments = quotemeta($arguments);
$arguments =~ s/\\\s+/ /; $arguments =~ s/\\\s+/ /;
if(defined $tonick) { if(defined $tonick) {
plog "($from): $nick ($host) sent to $tonick\n"; plog "($from): $nick ($host) sent to $tonick\n";
$text = `$module_dir/$commands{$keyword}{module} $arguments`; $text = `$module_dir/$commands{$keyword}{module} $arguments`;
@ -1020,7 +1075,8 @@ sub interpret_command {
return `$module_dir/$commands{$keyword}{module}`; return `$module_dir/$commands{$keyword}{module}`;
} }
} #end if($arguments) } #end if($arguments)
# } #end if($pid == 0) return "/me moans loudly."; # er, didn't execute the module?
} #end if($pid == 0)
} }
# Now we check to see if it's a factoid # Now we check to see if it's a factoid
@ -1274,8 +1330,8 @@ sub check_quieted_timeouts {
delete $quieted_nicks{$nick}; delete $quieted_nicks{$nick};
$conn->privmsg($nick, "You may speak again."); $conn->privmsg($nick, "You may speak again.");
} else { } else {
my $timediff = $quieted_nicks{$nick}{time} - $now; #my $timediff = $quieted_nicks{$nick}{time} - $now;
plog "quiet: $nick has $timediff seconds remaining\n" #plog "quiet: $nick has $timediff seconds remaining\n"
} }
} }
} }
@ -1290,7 +1346,7 @@ sub check_ignore_timeouts {
unignore_user("", "floodcontrol", "", $host); unignore_user("", "floodcontrol", "", $host);
} else { } else {
my $timediff = $ignore_list{$host} - $now; my $timediff = $ignore_list{$host} - $now;
plog "ignore: $host has $timediff seconds remaining\n" #plog "ignore: $host has $timediff seconds remaining\n"
} }
} }
} }
@ -1302,7 +1358,7 @@ sub check_opped_timeout {
if($is_opped{$channel}{timeout} < $now) { if($is_opped{$channel}{timeout} < $now) {
lose_ops($channel); lose_ops($channel);
} else { } else {
my $timediff = $is_opped{$channel}{timeout} - $now; # my $timediff = $is_opped{$channel}{timeout} - $now;
# plog "deop $channel in $timediff seconds\n"; # plog "deop $channel in $timediff seconds\n";
} }
} }
@ -1317,18 +1373,28 @@ sub check_unban_timeouts {
gain_ops($unban_timeout{$ban}{channel}); gain_ops($unban_timeout{$ban}{channel});
delete $unban_timeout{$ban}; delete $unban_timeout{$ban};
} else { } else {
my $timediff = $unban_timeout{$ban}{timeout} - $now; #my $timediff = $unban_timeout{$ban}{timeout} - $now;
plog "$unban_timeout{$ban}{channel}: unban $ban in $timediff seconds\n"; #plog "$unban_timeout{$ban}{channel}: unban $ban in $timediff seconds\n";
} }
} }
} }
my $export_factoids_time = gettimeofday + $export_factoids_timeout;
sub check_export_timeout {
my $now = gettimeofday;
if($now > $export_factoids_time) {
export_factoids;
$export_factoids_time = $now + $export_factoids_timeout;
}
}
sub sig_alarm_handler { sub sig_alarm_handler {
# check timeouts # check timeouts
check_quieted_timeouts; check_quieted_timeouts;
check_ignore_timeouts; check_ignore_timeouts;
check_opped_timeout; check_opped_timeout;
check_unban_timeouts; check_unban_timeouts;
check_export_timeout;
alarm 10; alarm 10;
} }
@ -1400,6 +1466,7 @@ sub on_public {
$conn->privmsg($from, $result); $conn->privmsg($from, $result);
} }
} }
exit if($child != 0); # if this process is a child, it must die now
} }
} }
@ -1441,7 +1508,7 @@ sub on_mode {
} else { # bot not targeted } else { # bot not targeted
if($mode eq "+b") { if($mode eq "+b") {
if($nick eq "ChanServ") { if($nick eq "ChanServ") {
$unban_timeout{$target}{timeout} = gettimeofday + 3600 * 12; # 12 hours $unban_timeout{$target}{timeout} = gettimeofday + 3600 * 2; # 2 hours
$unban_timeout{$target}{channel} = $from; $unban_timeout{$target}{channel} = $from;
} }
} elsif($mode eq "+e" && $from eq $botnick) { } elsif($mode eq "+e" && $from eq $botnick) {