in reply to Capturing queries in POE::Component::IRC

What you want to do for this is create a whole new session, giving that session all the required state information. From that session's _start state, call $kernel->post('irc', 'whois', $nick), and then capture the output in irc_319() and process it accordingly.

This is (I think) the only safe way to do it because another command could come in while you're waiting for the whois command to come back, and so you'd get concurrency bugs.

Let me know if you want to see some code, because this is a great example for my POE tutorial that I'm going to give at The Perl Conf this year.

  • Comment on Re: Capturing queries in POE::Component::IRC

Replies are listed 'Best First'.
Re: Re: Capturing queries in POE::Component::IRC
by rendler (Pilgrim) on Mar 01, 2002 at 10:30 UTC
    Some code would be greatly appreicated, thanks :)
Re: Re: Capturing queries in POE::Component::IRC
by rendler (Pilgrim) on Mar 01, 2002 at 23:50 UTC
    Okay a little about my bot, first off my irc_public() from the main script looks a little something like this.
    sub irc_public { my ($kernel, $who, $where, $msg) = @_[KERNEL, ARG0 .. ARG2]; run_script($kernel, $bot_version, $bot_nick, $irc_admins, $qstat_m +aster, $who, $where, $msg, $qstat_addr, $User_Info, @randquote); }
    run_script() is contained in QStatBot::Scripts.pm, Scripts.pm itself contains 3 subs, the first one checks for all the scripts within the scripts/ directory and requires the file then
    my @alias = eval "${script}_load()";
    which will return 2 values from the script, the bot command seen from a public channel and the alias that it is used with it. And the information about those scripts are stored in a global hash inside the module. The sub itself:
    our %script_aliases = load_scripts(); sub load_scripts { my (%script_aliases, $script_aliases); if (-d "scripts") { while(<scripts/*.script>) { my $script_name = $_; my $script = $1 if $script_name =~ /\/(.*)\.script/; print "Loading script: $script_name\n"; require "$script_name"; my @alias = eval "${script}_load()"; $script_aliases{$alias[0]} = $alias[1]; } return %script_aliases; } else { die "Scripts directory does not exist.\n"; } }
    And then the next sub QStatBot::Script::run_script() which recives all those variables from irc_public() when ever something happens in the channel , the bot looks at the messages and determines if any of them are commands my checking the global hash to see if the key exists and then calling up the sub for which that command is tied to.
    sub run_script { our ($kernel, $bot_version, $bot_nick, $irc_admins, $qstat_master, + $irc_host, $irc_chan, $irc_msg, $qstat_addr, $User_Info, @randquote) + = @_; our ($irc_nick, $irc_hostmask) = split(/!/, $irc_host); if ($irc_msg =~ /^$bot_nick.* commands$/i) { my @commands; for (keys %script_aliases) { push @commands, $_; } @commands = sort @commands; my $commands = join ', ', @commands; send_chan_message($irc_chan, "commands: $commands", $kernel); } elsif ($irc_msg =~ /^$bot_nick.* /i) { for (keys %script_aliases) { if ($irc_msg =~ /^$bot_nick.* $_/) { eval "$script_aliases{$_}()"; last; } } } }
    Those variables also seem to have to be made global as well since they do not get imported into the scripts otherwise. Before I had declared all the variables I needed inside all the scripts beforehand such as:
    sub mem_usage_load { my $alias = 'mem usage'; my $sub = 'display_mem_usage'; my $variables = '$kernel, $irc_chan'; return ($alias, $sub, $variables); }
    And passed the variables through such as eval "$script_aliases{$_}{'sub'}($script_aliases{$_}{'variables'})"; but that was kinda awkward having to do it like that so I dropped the idea and just made the variables global to save on the hassles caused. Anways, it's these scripts that are the problem I need to call another sub QStatBot::Scripts::check_permission() (maybe from run_script() just before eval "$script_aliases{$_}()";) which I will later create to look for another predefined value returned from ${script}_load() and stored in the global hash, that of course will be returned from scriptname_load() from the various scripts. The value will be either 'v' or 'o' to define what the user who has issued the command has to currently be inside the channel (voice or operator). It's this sub I would have to issue the whois command to the server and collect the information returned and then process it and return a 0 or 1 to if the user is a allowed to use such a command. Thanks.
Re: Re: Capturing queries in POE::Component::IRC
by Anonymous Monk on Mar 02, 2002 at 08:55 UTC
    My suggestion is to base if off their hostmask rather then getting their nick and whois-ing it every time. The hostmask is sent along with every thing a user says to a channel (PRIVMSG in the irc protocol), so I'm sure there's some what POE::Component::IRC returns that. I know Net::IRC does.
      Yes gathering the hostmask is easy enough, but I do not want to go down the route of basing it off hostmask, things like keeping hostmasks up to date and adding and removing new ones become too mundane after awhile.