1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#!/usr/bin/perl
#
# bzirc.pl - A script that echoes messages from a bzflag server to an IRC
# channel and from the channel to the server.
#
# Use it like this:
# bzirc.pl <IRCNICK> <IRCHOST>:<PORT> <CHANNEL> <BZADMINOPTS> <BZNICK>@<BZHOST>
#
# Inspired by ircbot.pl by detour@metalshell.com (http://www.metalshell.com).
#
# This script uses the POE and POE::Component::IRC modules.
# A simple way to get these is using the cpan module.
# perl -MCPAN -eshell
# cpan> install POE
# cpan> install POE::Component::IRC
#FIXME: Why not make this available as a bzfs command? something like /irc irc.freenode.net #bzflag Hello world!
use strict;
use IPC::Open2;
use POE;
use POE::Component::IRC;
# some global variables
my ($nick, $host, $port, $channel, $callsign, $bzopts,
$bzadminpid, $bzin, $bzout, $c);
$nick = @ARGV[0];
$host = @ARGV[1];
$c = index($host, ':');
if ($c != -1) {
$port = substr($host, $c + 1, length($host));
$host = substr($host, 0, $c);
}
else {
$port = 6667;
}
$channel = @ARGV[2];
$callsign = '@' . substr($ARGV[$#ARGV], 0, index($ARGV[$#ARGV], '@'));
$bzopts = join ' ', @ARGV[3..$#ARGV];
$bzadminpid;
$bzin;
$bzout;
# do some POE magic
POE::Component::IRC->new("irc_client");
POE::Session->new(_start => \&irc_start,
irc_join => \&irc_join,
irc_quit => \&irc_quit,
irc_376 => \&irc_connect,
irc_public => \&irc_pub_msg,
bzreadable => \&readfrombz);
# a handler that is called once when this session is started
sub irc_start {
my $kernel = $_[KERNEL];
my $heap = $_[HEAP];
my $session = $_[SESSION];
$kernel->refcount_increment( $session->ID(), "bzirc");
$kernel->post(irc_client=>register=> "all");
$kernel->post(irc_client=>connect=>{ Nick => $nick,
Username => $nick,
Ircname => $nick,
Server => $host,
Port => $port,
});
}
# a handler that is called when we have connected to the IRC server and
# received the MOTD
sub irc_connect {
my $kernel = $_[KERNEL];
$kernel->post(irc_client=>join=>$channel);
}
# a handler that is called when someone joins a channel
sub irc_join {
my $joiner = (split /!/, $_[ARG0])[0];
my $joinchannel = $_[ARG1];
my $kernel = $_[KERNEL];
if ($joiner eq $nick && $joinchannel eq $channel) {
print "Joined $channel, starting bzadmin...\n";
$bzadminpid = open2($bzout, $bzin, "bzadmin -ui stdboth $bzopts");
$kernel->select_read($bzout, 'bzreadable');
}
}
# a handler that is called when someone quits IRC
sub irc_quit {
my $quitter = $_[ARG0];
my $reason = $_[ARG1];
if ($quitter eq $nick) {
print "Disconnected.\n";
}
}
# a handler that is called when someone sends a message to the channel or to us
sub irc_pub_msg{
my $talker = (split /!/, $_[ARG0])[0];
my $talkchannel = $_[ARG1]->[0];
my $msg = $_[ARG2];
if ($talker ne $nick && $talkchannel eq $channel) {
print "->bz: $talker: $msg\n";
print $bzin "$talker: $msg\n";
}
}
# a handler that is called when the bzadmin pipe is readable
sub readfrombz {
my $msg = <$bzout>;
my $kernel = $_[KERNEL];
if (substr($msg, 0, length(" $callsign: ")) ne " $callsign: ") {
print "->irc: $msg";
$kernel->post('irc_client'=>privmsg=>$channel,$msg);
}
}
# start the POE kernel
$poe_kernel->run();
# Local Variables: ***
# mode:Perl ***
# tab-width: 8 ***
# c-basic-offset: 2 ***
# indent-tabs-mode: t ***
# End: ***
# ex: shiftwidth=2 tabstop=8
|