diff --git a/Irpg/Admin.pm b/Irpg/Admin.pm index f12b8e796d00aa3664bb3ea9fb7cb8c9135fff57..06fb3bad2af3cd60cac3528756e66f6abf654b7f 100644 --- a/Irpg/Admin.pm +++ b/Irpg/Admin.pm @@ -16,50 +16,50 @@ my $rps; =item SCALAR (ref) - reference to the options hash =item SCALAR (ref) - reference to the players hash =cut -sub init_hashes { ($opts, $rps) = @_; } +sub init_pkg { ($opts, $rps) = @_; } sub join_chans { for (@_[3..$#_]) { - sts("JOIN $_"); + Irpg::Irc::sts("JOIN $_"); } } sub leave_chans { for (@_[3..$#_]) { - sts("PART $_"); + Irpg::Irc::sts("PART $_"); } } sub peval { my ($usernick, $username, $source, @arg) = @_; if ($opts->{ownerpevalonly} && $opts->{owner} ne $username) { - privmsg("You don't have access to PEVAL.", $usernick); + Irpg::Irc::privmsg("You don't have access to PEVAL.", $usernick); } else { my @peval = eval "@arg"; if (@peval >= 4 || length("@peval") > 1024) { - privmsg("Command produced too much output to send ". + Irpg::Irc::privmsg("Command produced too much output to send ". "outright; queueing ".length("@peval"). " bytes in ".scalar(@peval)." items. Use ". "CLEARQ to clear queue if needed.",$usernick,1); - privmsg($_,$usernick) for @peval; + Irpg::Irc::privmsg($_,$usernick) for @peval; } - else { privmsg($_,$usernick, 1) for @peval; } - privmsg("EVAL ERROR: $@", $usernick, 1) if $@; + else { Irpg::Irc::privmsg($_,$usernick, 1) for @peval; } + Irpg::Irc::privmsg("EVAL ERROR: $@", $usernick, 1) if $@; } } sub delold { my ($usernick, $username, $source, @arg) = @_; if ($arg[0] !~ /^[\d\.]+$/) { - privmsg("Try: DELOLD <# of days>", $usernick, 1); + Irpg::Irc::privmsg("Try: DELOLD <# of days>", $usernick, 1); } else { my @oldaccounts = grep { (time()-$rps->{$_}{lastlogin}) > ($arg[0] * 86400) && !$rps->{$_}{online} } keys(%$rps); delete(@$rps->{@oldaccounts}); - chanmsg(scalar(@oldaccounts)." accounts not accessed in ". + Irpg::Irc::chanmsg(scalar(@oldaccounts)." accounts not accessed in ". "the last $arg[0] days removed by $usernick."); } } @@ -67,97 +67,97 @@ sub delold { sub delacct { my ($usernick, $username, $source, @arg) = @_; if (!defined($arg[0])) { - privmsg("Try: DEL <char name>", $usernick, 1); + Irpg::Irc::privmsg("Try: DEL <char name>", $usernick, 1); } elsif (!exists($rps->{$arg[0]})) { - privmsg("No such account $arg[0].", $usernick, 1); + Irpg::Irc::privmsg("No such account $arg[0].", $usernick, 1); } else { delete($rps->{$arg[0]}); - chanmsg("Account $arg[0] removed by $usernick."); + Irpg::Irc::chanmsg("Account $arg[0] removed by $usernick."); } } sub mkadmin { my ($usernick, $username, $source, @arg) = @_; if ($opts->{owneraddonly} && $opts->{owner} ne $username) { - privmsg("You don't have access to MKADMIN.", $usernick); + Irpg::Irc::privmsg("You don't have access to MKADMIN.", $usernick); } elsif (!defined($arg[0])) { - privmsg("Try: MKADMIN <char name>", $usernick, 1); + Irpg::Irc::privmsg("Try: MKADMIN <char name>", $usernick, 1); } elsif (!exists($rps->{$arg[0]})) { - privmsg("No such account $arg[0].", $usernick, 1); + Irpg::Irc::privmsg("No such account $arg[0].", $usernick, 1); } else { $rps->{$arg[0]}{isadmin}=1; - privmsg("Account $arg[0] is now a bot admin.",$usernick, 1); + Irpg::Irc::privmsg("Account $arg[0] is now a bot admin.",$usernick, 1); } } sub rmadmin { my ($usernick, $username, $source, @arg) = @_; if ($opts->{ownerdelonly} && $opts->{owner} ne $username) { - privmsg("You don't have access to RMADMIN.", $usernick); + Irpg::Irc::privmsg("You don't have access to RMADMIN.", $usernick); } elsif (!defined($arg[0])) { - privmsg("Try: RMADMIN <char name>", $usernick, 1); + Irpg::Irc::privmsg("Try: RMADMIN <char name>", $usernick, 1); } elsif (!exists($rps->{$arg[0]})) { - privmsg("No such account $arg[0].", $usernick, 1); + Irpg::Irc::privmsg("No such account $arg[0].", $usernick, 1); } elsif ($arg[0] eq $opts->{owner}) { - privmsg("Cannot RMADMIN owner account.", $usernick, 1); + Irpg::Irc::privmsg("Cannot RMADMIN owner account.", $usernick, 1); } else { $rps->{$arg[0]}{isadmin}=0; - privmsg("Account $arg[0] is no longer a bot admin.", + Irpg::Irc::privmsg("Account $arg[0] is no longer a bot admin.", $usernick, 1); } } sub do_hog { my ($usernick, $username, $source, @arg) = @_; - chanmsg("$usernick has summoned the Hand of God."); + Irpg::Irc::chanmsg("$usernick has summoned the Hand of God."); hog(); } sub rehash { my ($usernick, $username, $source, @arg) = @_; readconfig(); - privmsg("Reread config file.",$usernick,1); + Irpg::Irc::privmsg("Reread config file.",$usernick,1); $opts->{botchan} =~ s/ .*//; # strip channel key if present } sub chpass { my ($usernick, $username, $source, @arg) = @_; if (!defined($arg[1])) { - privmsg("Try: CHPASS <char name> <new pass>", $usernick, 1); + Irpg::Irc::privmsg("Try: CHPASS <char name> <new pass>", $usernick, 1); } elsif (!exists($rps->{$arg[0]})) { - privmsg("No such username $arg[0].", $usernick, 1); + Irpg::Irc::privmsg("No such username $arg[0].", $usernick, 1); } else { $rps->{$arg[0]}{pass} = crypt($arg[1],mksalt()); - privmsg("Password for $arg[0] changed.", $usernick, 1); + Irpg::Irc::privmsg("Password for $arg[0] changed.", $usernick, 1); } } sub chuser { my ($usernick, $username, $source, @arg) = @_; if (!defined($arg[1])) { - privmsg("Try: CHUSER <char name> <new char name>", + Irpg::Irc::privmsg("Try: CHUSER <char name> <new char name>", $usernick, 1); } elsif (!exists($rps->{$arg[0]})) { - privmsg("No such username $arg[0].", $usernick, 1); + Irpg::Irc::privmsg("No such username $arg[0].", $usernick, 1); } elsif (exists($rps->{$arg[1]})) { - privmsg("Username $arg[1] is already taken.", $usernick,1); + Irpg::Irc::privmsg("Username $arg[1] is already taken.", $usernick,1); } else { $rps->{$arg[1]} = delete($rps->{$arg[0]}); - privmsg("Username for $arg[0] changed to $arg[1].", + Irpg::Irc::privmsg("Username for $arg[0] changed to $arg[1].", $usernick, 1); } } @@ -166,22 +166,22 @@ sub push { my ($usernick, $username, $source, @arg) = @_; # insure it's a positive or negative, integral number of seconds if ($arg[1] !~ /^\-?\d+$/) { - privmsg("Try: PUSH <char name> <seconds>", $usernick, 1); + Irpg::Irc::privmsg("Try: PUSH <char name> <seconds>", $usernick, 1); } elsif (!exists($rps->{$arg[0]})) { - privmsg("No such username $arg[0].", $usernick, 1); + Irpg::Irc::privmsg("No such username $arg[0].", $usernick, 1); } elsif ($arg[1] > $rps->{$arg[0]}{next}) { - privmsg("Time to level for $arg[0] ($rps->{$arg[0]}{next}s) ". + Irpg::Irc::privmsg("Time to level for $arg[0] ($rps->{$arg[0]}{next}s) ". "is lower than $arg[1]; setting TTL to 0.", $usernick, 1); - chanmsg("$usernick has pushed $arg[0] $rps->{$arg[0]}{next} ". + Irpg::Irc::chanmsg("$usernick has pushed $arg[0] $rps->{$arg[0]}{next} ". "seconds toward level ".($rps->{$arg[0]}{level}+1)); $rps->{$arg[0]}{next}=0; } else { $rps->{$arg[0]}{next} -= $arg[1]; - chanmsg("$usernick has pushed $arg[0] $arg[1] seconds ". + Irpg::Irc::chanmsg("$usernick has pushed $arg[0] $arg[1] seconds ". "toward level ".($rps->{$arg[0]}{level}+1).". ". "$arg[0] reaches next level in ". duration($rps->{$arg[0]}{next})."."); @@ -192,13 +192,13 @@ sub bot_die { my ($usernick, $username, $source, @arg) = @_; $opts->{reconnect} = 0; writedb($opts, $rps); - sts("QUIT :DIE from $usernick",1); + Irpg::Irc::sts("QUIT :DIE from $usernick",1); } sub restart { my ($usernick, $username, $source, @arg) = @_; writedb(); - sts("QUIT :RESTART from $usernick",1); + Irpg::Irc::sts("QUIT :RESTART from $usernick",1); close($Irpg::Irc::sock); exec("perl $0"); } @@ -206,15 +206,15 @@ sub restart { sub do_backup { my ($usernick, $username, $source, @arg) = @_; backup(); - privmsg("$opts->{dbfile} copied to ". + Irpg::Irc::privmsg("$opts->{dbfile} copied to ". ".dbbackup/$opts->{dbfile}".time(),$usernick,1); } sub clearq { my ($usernick, $username, $source, @arg) = @_; undef(@Irpg::Irc::queue); - chanmsg("Outgoing message queue cleared by $usernick."); - privmsg("Outgoing message queue cleared.",$usernick,1); + Irpg::Irc::chanmsg("Outgoing message queue cleared by $usernick."); + Irpg::Irc::privmsg("Outgoing message queue cleared.",$usernick,1); } diff --git a/Irpg/Event.pm b/Irpg/Event.pm index 6546ce040ebab42f7d92027bba6e24bfde363246..d57821c3da00afd1a326e7225fdc1bc1612a9782 100644 --- a/Irpg/Event.pm +++ b/Irpg/Event.pm @@ -18,7 +18,7 @@ my $rps; =item SCALAR (ref) - reference to the options hash =item SCALAR (ref) - reference to the players hash =cut -sub init_hashes { ($opts, $rps) = @_; } +sub init_pkg { ($opts, $rps) = @_; } sub find_item { # find item for argument player diff --git a/Irpg/Fight.pm b/Irpg/Fight.pm index 4bfdf7939d7716626e3de9c1f565f330f3de49c3..3b4d4f2a99131bfb0e00f2038c66479cb9739566 100644 --- a/Irpg/Fight.pm +++ b/Irpg/Fight.pm @@ -18,7 +18,7 @@ my $rps; =item SCALAR (ref) - reference to the options hash =item SCALAR (ref) - reference to the players hash =cut -sub init_hashes { ($opts, $rps, $primnick_ref) = @_; } +sub init_pkg { ($opts, $rps, $primnick_ref) = @_; } sub fisher_yates_shuffle { diff --git a/Irpg/Irc.pm b/Irpg/Irc.pm index b992f4dd378326db8e1bda15d6f022cf5cd58838..e8e66f8643ace1dbfe20e275c22105b216c14be2 100644 --- a/Irpg/Irc.pm +++ b/Irpg/Irc.pm @@ -26,8 +26,8 @@ our @EXPORT_OK = qw($sock @queue &irc_connect &irc_clean &checkmsg &fq &sts &privmsg &chanmsg ¬ice $inbytes); -our %EXPORT_TAGS = (connection=>[qw($sock &irc_connect &irc_clean &checkmsg &fq)], - interaction=>[qw(&sts &privmsg &chanmsg ¬ice)]); +our %EXPORT_TAGS = (connection=>[qw($sock &irc_connect &irc_clean &checkmsg)], + interaction=>[qw(fq sts privmsg chanmsg notice)]); my $outbytes = 0; # sent bytes @@ -42,6 +42,8 @@ my $conn_tries = 0; # number of connection tries. gives up after trying each my $sock; # IO::Socket::INET object my $freemessages = 4; # number of "free" privmsgs we can send. 0..$freemessages +my $opts; + =head1 FUNCTION irc_connect This function manage the connection to the irc server. =over @@ -49,7 +51,7 @@ my $freemessages = 4; # number of "free" privmsgs we can send. 0..$freemessages =back =cut sub irc_connect { - my $opts = shift; + $opts = shift; while (!$sock && $conn_tries < 2*@{$opts->{servers}}) { debug("Connecting to $opts->{servers}->[0]..."); my %sockinfo = (PeerAddr => $opts->{servers}->[0], @@ -102,22 +104,23 @@ sub irc_clean { =cut sub checkmsg { my($readable) = IO::Select->select($sel,undef,undef,0.5); - my @ret; + my @ret = (); if (defined($readable)) { my $fh = $readable->[0]; my $buffer2; $fh->recv($buffer2,512,0); if (length($buffer2)) { + push @ret, 1; $buffer .= $buffer2; while (index($buffer,"\n") != -1) { my $line = substr($buffer,0,index($buffer,"\n")+1); $buffer = substr($buffer,length($line)); - @ret = (1, $line); + push @ret, $line; } } else { # uh oh, we've been disconnected from the server - @ret = (0, undef); + push @ret, 0; close($fh); $sel->remove($fh); @@ -125,7 +128,7 @@ sub checkmsg { } } else { select(undef,undef,undef,1); } - return @ret ? @ret : (1, undef); + return @ret ? @ret : (1); } =head1 FUNCTION fq @@ -201,14 +204,13 @@ sub sts { # send to server =over =item SCALAR (string) - message to send =item SCALAR (string) - target -=item SCALAR (bool) - force (default false) =back =cut sub privmsg { # send a message to an arbitrary entity my $msg = shift or return undef; my $target = shift or return undef; my $force = shift; - if (($silentmode == 3 || ($target !~ /^[\+\&\#]/ && $silentmode == 2)) + if (($Irpg::Main::silentmode == 3 || ($target !~ /^[\+\&\#]/ && $Irpg::Main::silentmode == 2)) && !$force) { return undef; } @@ -222,15 +224,11 @@ sub privmsg { # send a message to an arbitrary entity Sends a message to the channel =over =item SCALAR (string) - message to send -=item SCALAR (ref) - reference to the options hash -=item SCALAR (int) - silentmode =back =cut sub chanmsg { # send a message to the channel my $msg = shift or return undef; - my $opts = shift or return undef; - my $silentmode = shift; - if ($silentmode & 1) { return undef; } + if ($Irpg::Main::silentmode & 1) { return undef; } privmsg($msg, $opts->{botchan}, shift); } @@ -239,16 +237,14 @@ sub chanmsg { # send a message to the channel =over =item SCALAR (string) - message to send =item SCALAR (string) - target -=item SCALAR (int) - silentmode =item SCALAR (bool) - force (default false) =back =cut sub notice { # send a notice to an arbitrary entity my $msg = shift or return undef; my $target = shift or return undef; - my $silentmode = shift; my $force = shift; - if (($silentmode == 3 || ($target !~ /^[\+\&\#]/ && $silentmode == 2)) + if (($Irpg::Main::silentmode == 3 || ($target !~ /^[\+\&\#]/ && $Irpg::Main::silentmode == 2)) && !$force) { return undef; } diff --git a/Irpg/Main.pm b/Irpg/Main.pm index 37eb0ec304913d69ea70fecfde603d0fbb8d4b43..1c75a2f14c88494c94a86cb0ab348597272d3f92 100644 --- a/Irpg/Main.pm +++ b/Irpg/Main.pm @@ -11,8 +11,8 @@ Irpg/Main.pm - Entry point of the irpg functionnalities =cut use strict; use warnings; -use Irpg::Utils qw(&checksplits &duration &backup &writedb); -use Irpg::Irc qw(:interaction $inbytes); +use Irpg::Utils qw(:DEFAULT &checksplits &duration &backup &writedb); +use Irpg::Irc qw(:DEFAULT :interaction $inbytes); use Irpg::Quest; use Irpg::Fight; use Irpg::Event; @@ -63,29 +63,29 @@ sub init_pkg { sub pause_mode { my ($usernick, $username, $source, @arg) = @_; $pausemode = $pausemode ? 0 : 1; - privmsg("PAUSE_MODE set to $pausemode.",$usernick,1); + Irpg::Irc::privmsg("PAUSE_MODE set to $pausemode.",$usernick,1); } sub silent_mode { my ($usernick, $username, $source, @arg) = @_; if (!defined($arg[0]) || $arg[0] < 0 || $arg[0] > 3) { - privmsg("Try: SILENT <mode>", $usernick,1); + Irpg::Irc::privmsg("Try: SILENT <mode>", $usernick,1); } else { $silentmode = $arg[0]; - privmsg("SILENT_MODE set to $silentmode.",$usernick,1); + Irpg::Irc::privmsg("SILENT_MODE set to $silentmode.",$usernick,1); } } sub reloaddb { my ($usernick, $username, $source, @arg) = @_; if (!$pausemode) { - privmsg("ERROR: Can only use LOADDB while in PAUSE mode.", + Irpg::Irc::privmsg("ERROR: Can only use LOADDB while in PAUSE mode.", $usernick, 1); } else { loaddb(); - privmsg("Reread player database file; ".scalar(keys(%$rps)). + Irpg::Irc::privmsg("Reread player database file; ".scalar(keys(%$rps)). " accounts loaded.",$usernick,1); } } @@ -185,7 +185,7 @@ sub penalize { $rps->{$username}{$pen_key} += $pen if (exists($rps->{$username}{$pen_key})); $rps->{$username}{next} += $pen; if (defined($reason)) { - notice("Penalty of ".duration($pen)." added to your timer for ". + Irpg::Irc::notice("Penalty of ".duration($pen)." added to your timer for ". "$reason.",$rps->{$username}{nick}); } questpencheck($username) if ($pen > 0); @@ -214,7 +214,7 @@ sub moveplayers { !$positions{$rps->{$player}{x}}{$rps->{$player}{y}}{battled}) { if ($rps->{$positions{$rps->{$player}{x}}{$rps->{$player}{y}}{user}}{isadmin} && !$rps->{$player}{isadmin} && rand(100) < 1) { - chanmsg("$player encounters ". + Irpg::Irc::chanmsg("$player encounters ". $positions{$rps->{$player}{x}}{$rps->{$player}{y}}{user}. " and bows humbly."); } @@ -239,7 +239,8 @@ sub rpcheck { # check levels, update database # check splits hash to see if any split users have expired checksplits() if $opts->{detectsplits}; # send out $freemessages lines of text from the outgoing message queue - fq(); + #fq(); + Irpg::Irc::fq(); # clear registration limiting $lastreg = 0; my $online = scalar(grep { $rps->{$_}{online} } keys(%$rps)); @@ -260,10 +261,10 @@ sub rpcheck { # check levels, update database if ($rpreport && $rpreport%36000==0) { # 10 hours my @u = sort { $rps->{$b}{level} <=> $rps->{$a}{level} || $rps->{$a}{next} <=> $rps->{$b}{next} } keys(%$rps); - chanmsg("Idle RPG Top Players:") if @u; + Irpg::Irc::chanmsg("Idle RPG Top Players:") if @u; for my $i (0..2) { $#u >= $i and - chanmsg("$u[$i], the level $rps->{$u[$i]}{level} ". + Irpg::Irc::chanmsg("$u[$i], the level $rps->{$u[$i]}{level} ". "$rps->{$u[$i]}{class}, is #" . ($i + 1) . "! Next level in ". (duration($rps->{$u[$i]}{next}))."."); } @@ -273,14 +274,14 @@ sub rpcheck { # check levels, update database ### RETRIEVE NICK (if in use by other user) ### if ($rpreport%1800==0) { # 30 mins if ($opts->{botnick} ne $primnick) { - sts($opts->{botghostcmd}) if $opts->{botghostcmd}; - sts("NICK $primnick"); + Irpg::Irc::sts($opts->{botghostcmd}) if $opts->{botghostcmd}; + Irpg::Irc::sts("NICK $primnick"); } } ### WARN IF PAUSE MODE ### if ($rpreport%600==0 && $pausemode) { # warn every 10m - chanmsg("WARNING: Cannot write database in PAUSE mode!"); + Irpg::Irc::chanmsg("WARNING: Cannot write database in PAUSE mode!"); } ### UPDATE PLAYERS DATA ### @@ -309,7 +310,7 @@ sub rpcheck { # check levels, update database $rps->{$k}{next} = int($opts->{rpbase} * ($opts->{rpstep}**$rps->{$k}{level})); } - chanmsg("$k, the $rps->{$k}{class}, has attained level ". + Irpg::Irc::chanmsg("$k, the $rps->{$k}{class}, has attained level ". "$rps->{$k}{level}! Next level in ". duration($rps->{$k}{next})."."); find_item($k); @@ -342,7 +343,7 @@ sub parse { my $usernick = substr((split(/!/,$arg[0]))[0],1); # logged in char name of nickname, or undef if nickname is not online my $username = finduser($usernick); - if (lc($arg[0]) eq 'ping') { sts("PONG $arg[1]",1); } + if (lc($arg[0]) eq 'ping') { Irpg::Irc::sts("PONG $arg[1]",1); } elsif (lc($arg[0]) eq 'error') { # uh oh, we've been disconnected from the server, possibly before we've # logged in the users in %$auto_login. so, we'll set those users' online @@ -355,7 +356,7 @@ sub parse { $arg[1] = lc($arg[1]); # original case no longer matters if ($arg[1] eq '433' && $opts->{botnick} eq $arg[3]) { $opts->{botnick} .= 0; - sts("NICK $opts->{botnick}"); + Irpg::Irc::sts("NICK $opts->{botnick}"); } elsif ($arg[1] eq 'join') { # %onchan holds time user joined channel. used for the advertisement ban @@ -364,15 +365,15 @@ sub parse { delete($split{substr($arg[0],1)}); } elsif ($opts->{botnick} eq $usernick && $opts->{botchan} eq substr($arg[2], 1)) { - sts("WHO $opts->{botchan}"); + Irpg::Irc::sts("WHO $opts->{botchan}"); (my $opcmd = $opts->{botopcmd}) =~ s/%botnick%/$opts->{botnick}/eg; - sts($opcmd); + Irpg::Irc::sts($opcmd); $$lasttime_ref = time(); # start rpcheck() } } elsif ($arg[1] eq 'quit') { # if we see our nick come open, grab it (skipping queue) - if ($usernick eq $primnick) { sts("NICK $primnick",1); } + if ($usernick eq $primnick) { Irpg::Irc::sts("NICK $primnick",1); } elsif ($opts->{'detectsplits'} && "@arg[2..$#arg]" =~ /^:\S+\.\S+ \S+\.\S+$/) { if (defined($username)) { # user was online @@ -392,7 +393,7 @@ sub parse { } # if we see our nick come open, grab it (skipping queue), unless it was # us who just lost it - elsif ($usernick eq $primnick) { sts("NICK $primnick",1); } + elsif ($usernick eq $primnick) { Irpg::Irc::sts("NICK $primnick",1); } else { penalize($username,"nick",$arg[2]); if (exists($onchan{$usernick})) { @@ -415,41 +416,40 @@ sub parse { } elsif ($arg[1] eq '001') { # send our identify command, set our usermode, join channel - sts($opts->{botident}); - sts("MODE $opts->{botnick} :$opts->{botmodes}"); - sts("JOIN $opts->{botchan}"); + Irpg::Irc::sts($opts->{botident}); + Irpg::Irc::sts("MODE $opts->{botnick} :$opts->{botmodes}"); + Irpg::Irc::sts("JOIN $opts->{botchan}"); for (@{$opts->{listenchan}}) { - sts("JOIN $_"); + Irpg::Irc::sts("JOIN $_"); } $opts->{botchan} =~ s/ .*//; # strip channel key if present } elsif ($arg[1] eq '315') { # 315 is /WHO end. report who we automagically signed online iff it will # print < 1k of text - print "@arg"; if (keys(%$auto_login)) { # not a true measure of size, but easy if (length("%$auto_login") < 1024 && $opts->{senduserlist}) { - chanmsg(scalar(keys(%$auto_login))." users matching ". + Irpg::Irc::chanmsg(scalar(keys(%$auto_login))." users matching ". scalar(keys(%$prev_online))." hosts automatically ". "logged in; accounts: ".join(", ",keys(%$auto_login))); } else { - chanmsg(scalar(keys(%$auto_login))." users matching ". + Irpg::Irc::chanmsg(scalar(keys(%$auto_login))." users matching ". scalar(keys(%$prev_online))." hosts automatically ". "logged in."); } if ($opts->{voiceonlogin}) { my @vnicks = map { $rps->{$_}{nick} } keys(%$auto_login); while (@vnicks) { - sts("MODE $opts->{botchan} +". + Irpg::Irc::sts("MODE $opts->{botchan} +". ('v' x $opts->{modesperline})." ". join(" ",@vnicks[0..$opts->{modesperline}-1])); splice(@vnicks,0,$opts->{modesperline}); } } } - else { chanmsg("0 users qualified for auto login."); } + else { Irpg::Irc::chanmsg("0 users qualified for auto login."); } undef($prev_online); undef($auto_login); } @@ -457,12 +457,10 @@ sub parse { if ("@arg" =~ /MODES=(\d+)/) { $opts->{modesperline}=$1; } } elsif ($arg[1] eq '352') { - my $user; - my $channel = $arg[3]; # 352 is one line of /WHO. check that the nick!user@host exists as a key # in %$prev_online, the list generated in loaddb(). the value is the user # to login - $onchan{$arg[7]}=time() if ($opts->{botchan} eq substr($arg[2], 1)); + $onchan{$arg[7]}=time() if ($opts->{botchan} eq $arg[3]); if (exists($prev_online->{$arg[7]."!".$arg[4]."\@".$arg[5]})) { $rps->{$prev_online->{$arg[7]."!".$arg[4]."\@".$arg[5]}}{online} = 1; $auto_login->{$prev_online->{$arg[7]."!".$arg[4]."\@".$arg[5]}}=1; @@ -470,6 +468,7 @@ sub parse { } elsif ($arg[1] eq 'privmsg') { $arg[0] = substr($arg[0],1); # strip leading : from privmsgs + $arg[3] = lc(substr($arg[3],1)); # lowercase, strip leading : # if the first word of the msg is "botnick:", # we interpret the following as a potential command @@ -477,34 +476,42 @@ sub parse { @arg = (@arg[0..2], $opts->{token}.$arg[4], @arg[5..$#arg]) } my $msgtype = ''; - my $pref = ''; + my $source = ''; + my $token_need; + my $token_given = 0; + if ($arg[3] =~ m/\Q$opts->{token}\E/) { + $token_given = 1; + $arg[3] = substr($arg[3], 1); + } if (lc($arg[2]) eq lc($opts->{botnick})) { # to us, not channel $msgtype = 'prv'; - $pref = '?'; + $token_need = 0; + $source = $usernick; } else { # in a channel $msgtype = 'pub'; - + $token_need = 1; + $source = $arg[2]; } - if (grep /^\Q$opts->{token}\E$pref\Q$arg[3]\E/, - @{grep({ $_{$msgtype} } keys(%commands))}) { + if ((!$token_need || $token_given) && + grep /\Q$arg[3]\E/, + grep({ $commands{$_}->{$msgtype} } keys(%commands))) { # the message is a command valid in $msgtype message if (!$commands{$arg[3]}->{adm} || ha($usernick)) { # the user has right to execute the command if (exists $onchan{$usernick}) { # the user is on the game chan # we execute the command - # $arg[2] is the source (chan or user), - # and from $arg[4], it is the message content + # from $arg[4], it is the message content $commands{$arg[3]}->{ref}($usernick, $username, - $arg[2], @arg[4..$#arg]); + $source, @arg[4..$#arg]); } else { - notice("Sorry, you're not in $opts->{botchan}.", + Irpg::Irc::notice("Sorry, you're not in $opts->{botchan}.", $usernick); } } else { - privmsg("You don't have access to ".uc($arg[3]).".", $usernick); + Irpg::Irc::privmsg("You don't have access to ".uc($arg[3]).".", $usernick); } } else { # the message is not a command diff --git a/Irpg/Quest.pm b/Irpg/Quest.pm index 4ae7e1c7087d0a90ef750c41ebbb74b027ff5d92..37a80ce838fbff49c34d54c9bf84312050f03e09 100644 --- a/Irpg/Quest.pm +++ b/Irpg/Quest.pm @@ -26,7 +26,7 @@ my $rps; =item SCALAR (ref) - reference to the options hash =item SCALAR (ref) - reference to the players hash =cut -sub init_hashes { ($opts, $rps) = @_; } +sub init_pkg { ($opts, $rps) = @_; } =head FUNCTION writequestfile This function write the state of the current quest diff --git a/Irpg/Users.pm b/Irpg/Users.pm index 5aa354d700b357451a650899aaf517972156eed4..31d070e24e6f82c67500a98f8eed77e320edb4ca 100644 --- a/Irpg/Users.pm +++ b/Irpg/Users.pm @@ -1,9 +1,10 @@ -package Irpg::User; +package Irpg::Users; use strict; use warnings; use Irpg::Utils qw(:data :text); use Irpg::Irc qw(:interaction @queue); +use Irpg::Main; my $opts; my $rps; @@ -16,8 +17,8 @@ my ($primnick_ref, $lastreg_ref, $silentmode_ref, $pausemode_ref); =item SCALAR (ref) - reference to the options hash =item SCALAR (ref) - reference to the players hash =cut -sub init_hashes { - ($opts, $rps, $onchan, $$primnick_ref, +sub init_pkg { + ($opts, $rps, $onchan, $primnick_ref, $lastreg_ref, $silentmode_ref, $pausemode_ref) = @_; } @@ -25,67 +26,67 @@ sub register { my ($usernick, $username, $source, @arg) = @_; if (defined $username) { - privmsg("Sorry, you are already online as $username.", + Irpg::Irc::privmsg("Sorry, you are already online as $username.", $usernick); } else { if ($#arg < 3 || $arg[2] eq "") { - privmsg("Try: REGISTER <char name> <password> <class>", + Irpg::Irc::privmsg("Try: REGISTER <char name> <password> <class>", $usernick); - privmsg("IE : REGISTER Poseidon MyPassword M God of the ". + Irpg::Irc::privmsg("IE : REGISTER Poseidon MyPassword M God of the ". "Sea",$usernick); } elsif ($$pausemode_ref) { - privmsg("Sorry, new accounts may not be registered ". + Irpg::Irc::privmsg("Sorry, new accounts may not be registered ". "while the bot is in pause mode; please wait ". "a few minutes and try again.",$usernick); } elsif (exists $rps->{$arg[0]} || ($opts->{casematters} && scalar(grep { lc($arg[0]) eq lc($_) } keys(%$rps)))) { - privmsg("Sorry, that character name is already in use.", + Irpg::Irc::privmsg("Sorry, that character name is already in use.", $usernick); } elsif (lc($arg[0]) eq lc($opts->{botnick}) || lc($arg[0]) eq lc($$primnick_ref)) { - privmsg("Sorry, that character name cannot be ". + Irpg::Irc::privmsg("Sorry, that character name cannot be ". "registered.",$usernick); } elsif (!exists($onchan->{$usernick})) { - privmsg("Sorry, you're not in $opts->{botchan}.", + Irpg::Irc::privmsg("Sorry, you're not in $opts->{botchan}.", $usernick); } elsif (length($arg[0]) > 16 || length($arg[0]) < 1) { - privmsg("Sorry, character names must be < 17 and > 0 ". + Irpg::Irc::privmsg("Sorry, character names must be < 17 and > 0 ". "chars long.", $usernick); } elsif ($arg[0] =~ /^#/) { - privmsg("Sorry, character names may not begin with #.", + Irpg::Irc::privmsg("Sorry, character names may not begin with #.", $usernick); } elsif ($arg[0] =~ /\001/) { - privmsg("Sorry, character names may not include ". + Irpg::Irc::privmsg("Sorry, character names may not include ". "character \\001.",$usernick); } elsif ($opts->{noccodes} && ($arg[0] =~ /[[:cntrl:]]/ || "@arg[2..$#arg]" =~ /[[:cntrl:]]/)) { - privmsg("Sorry, neither character names nor classes ". + Irpg::Irc::privmsg("Sorry, neither character names nor classes ". "may include control codes.",$usernick); } elsif ($opts->{nononp} && ($arg[0] =~ /[[:^print:]]/ || "@arg[2..$#arg]" =~ /[[:^print:]]/)) { - privmsg("Sorry, neither character names nor classes ". + Irpg::Irc::privmsg("Sorry, neither character names nor classes ". "may include non-printable chars.",$usernick); } elsif (length("@arg[3..$#arg]") > 30) { - privmsg("Sorry, character classes must be < 31 chars ". + Irpg::Irc::privmsg("Sorry, character classes must be < 31 chars ". "long.",$usernick); } elsif (time() == $$lastreg_ref) { - privmsg("Wait 1 second and try again.",$usernick); + Irpg::Irc::privmsg("Wait 1 second and try again.",$usernick); } else { if ($opts->{voiceonlogin}) { - sts("MODE $opts->{botchan} +v :$usernick"); + Irpg::Irc::sts("MODE $opts->{botchan} +v :$usernick"); } $$lastreg_ref = time(); $rps->{$arg[0]}{next} = $opts->{rpbase}; @@ -112,13 +113,13 @@ sub register { "pen_logout","pen_logout","pen_class") { $rps->{$arg[0]}{$pen} = 0; } - chanmsg("Welcome $usernick\'s new player $arg[0], the ". + Irpg::Irc::chanmsg("Welcome $usernick\'s new player $arg[0], the ". "@arg[6..$#arg]! Next level in ". duration($opts->{rpbase})."."); - privmsg("Success! Account $arg[0] created. You have ". + Irpg::Irc::privmsg("Success! Account $arg[0] created. You have ". "$opts->{rpbase} seconds idleness until you ". "reach level 1. ", $usernick); - privmsg("NOTE: The point of the game is to see who ". + Irpg::Irc::privmsg("NOTE: The point of the game is to see who ". "can idle the longest. As such, ". "parting, quitting, and changing ". "nicks all penalize you.",$usernick); @@ -130,21 +131,21 @@ sub register { sub chclass { my ($usernick, $username, $source, @arg) = @_; if ($#arg < 3) { - privmsg("Try: CHCLASS <char name> <passwd> <new char class>", + Irpg::Irc::privmsg("Try: CHCLASS <char name> <passwd> <new char class>", $usernick, 1); } elsif (!exists($rps->{$arg[0]})) { - privmsg("No such username $arg[0].", $usernick, 1); + Irpg::Irc::privmsg("No such username $arg[0].", $usernick, 1); } elsif ($rps->{$arg[0]}{pass} ne crypt($arg[1],$rps->{$arg[0]}{pass})) { - notice("Wrong password.", $usernick); + Irpg::Irc::notice("Wrong password.", $usernick); } else { $rps->{$arg[0]}{class} = "@arg[2..$#arg]"; - privmsg("Class for $arg[0] changed to @arg[2..$#arg].", + Irpg::Irc::privmsg("Class for $arg[0] changed to @arg[2..$#arg].", $usernick, 1); - chanmsg("Class for $arg[0] changed to @arg[2..$#arg]."); + Irpg::Irc::chanmsg("Class for $arg[0] changed to @arg[2..$#arg]."); penalize($username,"chclass"); } } @@ -153,38 +154,38 @@ sub chclass { sub login { my ($usernick, $username, $source, @arg) = @_; if (defined($username)) { - notice("Sorry, you are already online as $username.", + Irpg::Irc::notice("Sorry, you are already online as $username.", $usernick); } else { if ($#arg < 2 || $arg[1] eq "") { - notice("Try: LOGIN <username> <password>", $usernick); + Irpg::Irc::notice("Try: LOGIN <username> <password>", $usernick); } elsif (!exists $rps->{$arg[0]}) { - notice("Sorry, no such account name. Note that ". + Irpg::Irc::notice("Sorry, no such account name. Note that ". "account names are case sensitive.",$usernick); } elsif (!exists $onchan->{$opts->{botchan}}{$usernick}) { - notice("Sorry, you're not in $opts->{botchan}.", + Irpg::Irc::notice("Sorry, you're not in $opts->{botchan}.", $usernick); } elsif ($rps->{$arg[0]}{pass} ne crypt($arg[1],$rps->{$arg[0]}{pass})) { - notice("Wrong password.", $usernick); + Irpg::Irc::notice("Wrong password.", $usernick); } else { if ($opts->{voiceonlogin}) { - sts("MODE $opts->{botchan} +v :$usernick"); + Irpg::Irc::sts("MODE $opts->{botchan} +v :$usernick"); } $rps->{$arg[0]}{online} = 1; $rps->{$arg[0]}{nick} = $usernick; $rps->{$arg[0]}{userhost} = $arg[0]; $rps->{$arg[0]}{lastlogin} = time(); - chanmsg("$arg[0], the level $rps->{$arg[0]}{level} ". + Irpg::Irc::chanmsg("$arg[0], the level $rps->{$arg[0]}{level} ". "$rps->{$arg[0]}{class}, is now online from ". "nickname $usernick. Next level in ". duration($rps->{$arg[0]}{next})."."); - notice("Logon successful. Next level in ". + Irpg::Irc::notice("Logon successful. Next level in ". duration($rps->{$arg[0]}{next}).".", $usernick); } } @@ -197,7 +198,7 @@ sub logout { penalize($username,"logout"); } else { - privmsg("You are not logged in.", $usernick); + Irpg::Irc::privmsg("You are not logged in.", $usernick); } } @@ -205,14 +206,14 @@ sub status { return unless ($opts->{statuscmd}); my ($usernick, $username, $source, @arg) = @_; if (!defined($username)) { - privmsg("You are not logged in.", $usernick); + Irpg::Irc::privmsg("You are not logged in.", $usernick); } # argument is optional elsif ($arg[0] && !exists($rps->{$arg[0]})) { - privmsg("No such user.",$usernick); + Irpg::Irc::privmsg("No such user.",$usernick); } elsif ($arg[0]) { # optional 'user' argument - privmsg("$arg[0]: Level $rps->{$arg[0]}{level} ". + Irpg::Irc::privmsg("$arg[0]: Level $rps->{$arg[0]}{level} ". "$rps->{$arg[0]}{class}; Status: O". ($rps->{$arg[0]}{online}?"n":"ff")."line; ". "TTL: ".duration($rps->{$arg[0]}{next})."; ". @@ -222,7 +223,7 @@ sub status { ,$usernick); } else { # no argument, look up this user - privmsg("$username: Level $rps->{$username}{level} ". + Irpg::Irc::privmsg("$username: Level $rps->{$username}{level} ". "$rps->{$username}{class}; Status: O". ($rps->{$username}{online}?"n":"ff")."line; ". "TTL: ".duration($rps->{$username}{next})."; ". @@ -236,10 +237,10 @@ sub status { sub whoami { my ($usernick, $username, $source, @arg) = @_; if (!defined($username)) { - privmsg("You are not logged in.", $usernick); + Irpg::Irc::privmsg("You are not logged in.", $usernick); } else { - privmsg("You are $username, the level ". + Irpg::Irc::privmsg("You are $username, the level ". $rps->{$username}{level}." $rps->{$username}{class}. ". "Next level in ".duration($rps->{$username}{next}), $usernick); @@ -249,31 +250,31 @@ sub whoami { sub newpass { my ($usernick, $username, $source, @arg) = @_; if (!defined($username)) { - privmsg("You are not logged in.", $usernick) + Irpg::Irc::privmsg("You are not logged in.", $usernick) } elsif (!defined($arg[0])) { - privmsg("Try: NEWPASS <new password>", $usernick); + Irpg::Irc::privmsg("Try: NEWPASS <new password>", $usernick); } else { $rps->{$username}{pass} = crypt($arg[0],mksalt()); - privmsg("Your password was changed.",$usernick); + Irpg::Irc::privmsg("Your password was changed.",$usernick); } } sub align { my ($usernick, $username, $source, @arg) = @_; if (!defined($username)) { - privmsg("You are not logged in.", $usernick) + Irpg::Irc::privmsg("You are not logged in.", $usernick) } elsif (!defined($arg[0]) || (lc($arg[0]) ne "good" && lc($arg[0]) ne "neutral" && lc($arg[0]) ne "evil")) { - privmsg("Try: ALIGN <good|neutral|evil>", $usernick); + Irpg::Irc::privmsg("Try: ALIGN <good|neutral|evil>", $usernick); } else { $rps->{$username}{alignment} = substr(lc($arg[0]),0,1); - chanmsg("$username has changed alignment to: ".lc($arg[0]). + Irpg::Irc::chanmsg("$username has changed alignment to: ".lc($arg[0]). "."); - privmsg("Your alignment was changed to ".lc($arg[0]).".", + Irpg::Irc::privmsg("Your alignment was changed to ".lc($arg[0]).".", $usernick); } } @@ -281,16 +282,16 @@ sub align { sub gender { my ($usernick, $username, $source, @arg) = @_; if (!defined($username)) { - privmsg("You are not logged in.", $usernick) + Irpg::Irc::privmsg("You are not logged in.", $usernick) } elsif (!defined($arg[0]) || $arg[0] =~ /[^MFN]/) { - privmsg("Try: GENDER <M|F|N>",$usernick); + Irpg::Irc::privmsg("Try: GENDER <M|F|N>",$usernick); } else { $rps->{$username}{gender} = substr(lc($arg[0]),0,1); - chanmsg("$username has changed gender to: ".lc($arg[0]). + Irpg::Irc::chanmsg("$username has changed gender to: ".lc($arg[0]). "."); - privmsg("Your gender was changed to ".lc($arg[0]).".", + Irpg::Irc::privmsg("Your gender was changed to ".lc($arg[0]).".", $usernick); } } @@ -298,11 +299,11 @@ sub gender { sub rmplayer { my ($usernick, $username, $source, @arg) = @_; if (!defined($username)) { - privmsg("You are not logged in.", $usernick) + Irpg::Irc::privmsg("You are not logged in.", $usernick) } else { - privmsg("Account $username removed.",$usernick); - chanmsg("$usernick removed his account, $username, the ". + Irpg::Irc::privmsg("Account $username removed.",$usernick); + Irpg::Irc::chanmsg("$usernick removed his account, $username, the ". $rps->{$username}{class}."."); delete($rps->{$username}); } @@ -310,13 +311,14 @@ sub rmplayer { sub help { my ($usernick, $username, $source, @arg) = @_; - if (!ha($username) || $source !~ /^#/) { - privmsg("For information on IRPG bot commands, see ". + print "$source\n"; + if ($source !~ /^#/ || !Irpg::Main::ha($usernick)) { + Irpg::Irc::privmsg("For information on IRPG bot commands, see ". $opts->{helpurl}, $source); } else { - privmsg("Help URL is $opts->{helpurl}", $usernick, 1); - privmsg("Admin commands URL is $opts->{admincommurl}", + Irpg::Irc::privmsg("Help URL is $opts->{helpurl}", $usernick, 1); + Irpg::Irc::privmsg("Admin commands URL is $opts->{admincommurl}", $usernick, 1); } } @@ -324,7 +326,7 @@ sub help { sub info { my ($usernick, $username, $source, @arg) = @_; my $info; - if (!ha($username)) { + if (!Irpg::Main::ha($usernick)) { $info = "IRPG bot by ElTata, ". "based on jotun's initial work.". "https://gennuso.iiens.net/irpg. On via server: ". @@ -332,7 +334,7 @@ sub info { join(", ", map { $rps->{$_}{nick} } grep { $rps->{$_}{isadmin} && $rps->{$_}{online} } keys(%$rps))."."; - privmsg($info, $usernick); + Irpg::Irc::privmsg($info, $usernick); } else { my $queuedbytes = 0; @@ -355,7 +357,7 @@ sub info { join(", ",map { $rps->{$_}{nick} } grep { $rps->{$_}{isadmin} && $rps->{$_}{online} } keys(%$rps))); - privmsg($info, $usernick, 1); + Irpg::Irc::privmsg($info, $usernick, 1); } } diff --git a/Irpg/Utils.pm b/Irpg/Utils.pm index bd7d010a2cd72ddcc9fba66e45129ef8d1070f18..caf96a64611169707f1d333c63448745b16e46dd 100644 --- a/Irpg/Utils.pm +++ b/Irpg/Utils.pm @@ -108,7 +108,7 @@ sub debug { my $die = shift; if ($debug || $verbose) { open(DBG,">>$debugfile") or do { - chanmsg("Error: Cannot open debug file: $!"); + Irpg::Irc::chanmsg("Error: Cannot open debug file: $!"); return; }; print DBG ts()."$text\n"; @@ -131,7 +131,7 @@ sub clog { my $opts = shift; open(B,">>$opts->{modsfile}") or do { debug("Error: Cannot open $opts->{modsfile}: $!"); - chanmsg("Error: Cannot open $opts->{modsfile}: $!"); + Irpg::Irc::chanmsg("Error: Cannot open $opts->{modsfile}: $!"); return $mesg; }; print B ts()."$mesg\n"; @@ -247,7 +247,7 @@ sub loaddb { # load the players database my %rps = (); my %prev_online = (); if (!open(RPS,$opts->{dbfile}) && -e $opts->{dbfile}) { - sts("QUIT :loaddb() failed: $!"); + Irpg::Irc::sts("QUIT :loaddb() failed: $!"); } while ($l=<RPS>) { chomp($l); @@ -255,7 +255,7 @@ sub loaddb { # load the players database my @i = split("\t",$l); print Dumper(@i) if @i != 34; if (@i != 34) { - sts("QUIT: Anomaly in loaddb(); line $. of $opts->{dbfile} has ". + Irpg::Irc::sts("QUIT: Anomaly in loaddb(); line $. of $opts->{dbfile} has ". "wrong fields (".scalar(@i).")"); debug("Anomaly in loaddb(); line $. of $opts->{dbfile} has wrong ". "fields (".scalar(@i).")",1); @@ -315,7 +315,7 @@ sub writedb { my $opts = shift; my $rps = shift; open(RPS,">$opts->{dbfile}") or do { - chanmsg("ERROR: Cannot write $opts->{dbfile}: $!"); + Irpg::Irc::chanmsg("ERROR: Cannot write $opts->{dbfile}: $!"); return 0; }; print RPS join("\t","# username", diff --git a/irpg_bot.pl b/irpg_bot.pl index 1fb5b7f36ce45fc268e7bf85ece13ead3f41f303..6509c887f3deb822d596c41a114090146e97b1a0 100644 --- a/irpg_bot.pl +++ b/irpg_bot.pl @@ -142,8 +142,8 @@ my $lasttime = 1; # last time that rpcheck() was run $rps = createdb(\%opts) unless -e $opts{dbfile}; -print "\n".debug("Becoming a daemon...")."\n"; -daemonize(\%opts); +#print "\n".debug("Becoming a daemon...")."\n"; +#daemonize(\%opts); $SIG{HUP} = "readconfig"; # sighup = reread config file @@ -159,9 +159,9 @@ Irpg::Main::init_pkg(\%opts, $rps, \$lasttime, $prev_online, $auto_login); # MAIN LOOP # #-----------------# while (1) { - my @line = checkmsg(); - if ($line[0]) { - parse($line[1]) if defined($line[1]); + my @lines = checkmsg(); + if ($lines[0]) { + parse($_) foreach (@lines[1..$#lines]); } else { # uh oh, we've been disconnected from the server, possibly before