plasmatwin
Programmer
Hi,
I'm frustrated at the moment because my IRC bot has stopped functioning and I don't know why. I made allot of changes without testing it and I don't know what went wrong... It gives me an error saying:
I tested a simple POE irc bot on the computer and it connects perfectly, so I assume it must be a problem with my script... :/
I guess my only choice is to paste the whole script here and ask for help with debugging... I have no idea what is not working, it all looks fine to me. Bear in mind this script is still being worked on heavily so there are peices of code commented out all over the place and they might hold a clue to what I have done wrong... the actual reading of the config file that it uses works fine for the time being, something is wrong with the connection part... it is designed on a unix system and I am unsure if it will work on a win32 system or any other. Please help me... I'm a little stuck for ideas:
and the config file "battleserv.conf" looks like this:
You might want to paste the code into a syntax highlighting text editor for ease of reading... sorry for the lack of comments in it...
Thanks for your time... please help me :-(
I'm frustrated at the moment because my IRC bot has stopped functioning and I don't know why. I made allot of changes without testing it and I don't know what went wrong... It gives me an error saying:
Code:
getservbyname error 99: Cannot assign requested address
I tested a simple POE irc bot on the computer and it connects perfectly, so I assume it must be a problem with my script... :/
I guess my only choice is to paste the whole script here and ask for help with debugging... I have no idea what is not working, it all looks fine to me. Bear in mind this script is still being worked on heavily so there are peices of code commented out all over the place and they might hold a clue to what I have done wrong... the actual reading of the config file that it uses works fine for the time being, something is wrong with the connection part... it is designed on a unix system and I am unsure if it will work on a win32 system or any other. Please help me... I'm a little stuck for ideas:
Code:
#!/usr/bin/perl -w
# BattleServ v0.0.1ALPHA
# Designed by Graham Lyon
# (c) Graham Lyon 2005
use strict;
use File::Basename;
use POSIX;
use POE;
use POE::Component::IRC;
# declare global config stuff here so they don't fall out of scope later on
my %config;
# find where we are located, read the config for the first time and sepperate from the terminal
$config{'scriptdir'} = &finddir;
if (!&config_rehash) { die "FATAL: Failed initial read of config\n"; }
push @INC, "$config{'scriptdir'}/$config{'moduledir'}";
#require Proc::Daemon;
#&Proc::Daemon::Init;
# write out the PID file
open(PIDFILE, ">$config{'scriptdir'}/$config{'pidfile'}");
printf PIDFILE "%d\n", getpid();
close(PIDFILE);
my $battleserv = POE::Component::IRC->spawn();
POE::Session->new( _start => \&_start,
_stop => \&_stop,
_default => \&_default, # this will fill up your logfile faster then you can say knife...
# set daemon to 0 in your config file so that everthing prints to the terminal
irc_connect => \&irc_connect, # event to trigger a connection to IRC
irc_disconnect => \&irc_disconnect, # event to GRACEFULLY stop the connection to IRC
irc_socketerr => \&irc_socketerr, # deal with IRC socket errors
irc_error => \&irc_error, # error with the IRC protocol
irc_connected => \&irc_connected, # triggered when you first connect
irc_disconnected => \&irc_disconnected, # triggered when disconnected
irc_001 => \&irc_001,
irc_msg => \&irc_msg,
irc_ctcp_version => \&irc_ctcp_version,
irc_ctcp_finger => \&irc_ctcp_finger,
);
# start everything
$poe_kernel->run();
exit 0;
#################################################
# Below here is only subroutines... the script
# it's self terminates at the "exit 0;" line
# above.
#################################################
#################################################
######### Starting and stopping...
#################################################
sub _start
{
my $kernel = $_[KERNEL];
$battleserv->yield(register=> "all");
&log_error("Battleserv started");
&dumpconfig;
$kernel->yield("irc_connect");
}
sub _stop
{
&log_error("Received stop signal, unregistering events...");
$battleserv->yield(unregister=> "all");
$battleserv->yield("shutdown");
&log_error("Battleserv stopped");
}
#################################################
######### Config subroutines
#################################################
sub config_rehash
{
my $config = @_[0] || "$config{'scriptdir'}/battleserv.conf";
&log_error("Loading config from \"$config\"...");
my $seen_warning;
my $seen_error;
# read the config file into an array and then close it
if (!open(CONFIG, $config))
{
&log_error("ERROR: Could not open config file, config not loaded");
&log_error("Failed to load config, please check the above for possible errors");
return 0;
}
my @config=<CONFIG>;
close(CONFIG);
chomp(@config);
# first read through will check the config file by passing it into the hash "%check_config"
# and then seeing if required values are there aswell as checking sanity of other values
my %check_config;
$check_config{'scriptdir'} = $config{'scriptdir'}; # place the scriptdir back into the config
my @check_channels;
foreach (@config)
{
if ((/^\#/) || !(/=/)) { next; }
(my $config, my $value) = split(/=/, $_, 2);
if ($config eq "channel")
{
my $dontadd = 0;
foreach (@{ $check_config{'channels'} })
{
if ("$_" == "$value")
{
$dontadd = 1;
$seen_warning = 1;
&log_error("WARNING: Repeat channel in config ($value), omitting...");
next;
}
}
if (!$dontadd) { push(@{ $check_config{'channels'} }, "$value"); }
}
else
{
if ($check_config{$config}) {
$seen_warning = 1;
&log_error("WARNING: repeat value of $config in config file (current value: $check_config{$config}), replacing with newest value ($value)");
}
$check_config{$config} = "$value";
}
}
my %critical_config = ( "moduledir", "modules",
"errorlog", "error.log",
"logfile", "battleserv.log",
"pidfile", "battleserv.pid",
"botnick", "BattleServ",
"botident", "BattleServ",
"botname", "Battle Service Bot",
"server", "",
"port", "6667",
"daemon", 0,
);
foreach (keys(%critical_config))
{
if (!$check_config{$_})
{
if ($critical_config{$_} eq "")
{
$seen_error = 1;
&log_error("ERROR: Missing config option \"$_\"");
}
else
{
$check_config{$_} = $critical_config{$_};
}
}
}
###################################################################################
###################################################################################
## WAAAAAAY more sanitising needs to be done here....
###################################################################################
###################################################################################
if ($seen_warning) { &log_error("Warnings were flagged in the config, while this still has produced a working config there is the possibility that the config will not perform the way you expect. If the bot is not operating the way you expect then check the above for possible errors in your config."); }
if ($seen_error) { &log_error("Failed to load config, please check the above for possible errors"); return 0; }
# clean the global array out and copy the sane array into the clean global array
undef %config;
%config = %check_config;
&log_error("Config loaded successfully");
return 1;
}
sub dumpconfig
{
&log_error("Config dump:");
while (my @config = each(%config))
{
&log_error("$config[0] => $config[1]");
}
&log_error("Channels array:");
foreach (@{ $config{'channels'} })
{
&log_error("$_");
}
}
sub finddir
{
if (dirname($0) !~ /^./) { return dirname($0); }
elsif (`pwd`)
{
my $dir = `pwd`;
chomp($dir);
my $dir2 = $0;
$dir2 =~ s/^.//;
$dir = $dir . $dir2;
return dirname($dir);
}
else { return 0; }
}
#################################################
######### Logging
#################################################
sub log_error
{
if((!"$config{'errorlog'}") || (!$config{'daemon'}))
{
# config still hasn't loaded, we are still attached to the terminal
print "$_[0]\n";
return 1;
}
if(!open(ERROR, ">>$config{'scriptdir'}/$config{'errorlog'}"))
{
return 0;
}
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
printf ERROR "%4d-%02d-%02d %02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec;
print ERROR " => $_[0]\n";
close(ERROR);
return 1;
}
#################################################
######### Debug stuff...
#################################################
sub _default
{
my ( $event, $args ) = @_[ ARG0 .. $#_ ];
print "unhandled $event";
my $arg_number = 0;
foreach (@$args)
{
print " ARG$arg_number = ";
if ( ref($_) eq 'ARRAY' )
{
print "$_ = [", join ( ", ", @$_ ), "]\n";
}
else
{
print "'$_'\n";
}
$arg_number++;
}
return 0; # Don't handle signals.
}
#################################################
######### Connection related sub routines
#################################################
sub irc_connect
{
&log_error("Connecting to $config{'server'} on port $config{'port'}...");
$battleserv->yield(connect=> {
nick => $config{'botnick'},
username => $config{'botident'},
ircname => $config{'botname'},
server => $config{'server'},
port => $config{'port'},
}
);
}
sub irc_connected
{
&log_error("Connection to $config{'server'} on port $config{'port'} established...");
}
sub irc_disconnected
{
&log_error("Disconnected from $_[ARG0]");
}
sub irc_socketerr
{
&log_error("Connection to $config{'server'} on port $config{'port'} failed...");
&log_error("reason: $_[ARG0]");
}
sub irc_error
{
&log_error("$_[ARG0]");
}
#################################################
######### RAW 001-099
#################################################
sub irc_001world
{
$battleserv->yield(join=>"$_") for (@{ $config{'channels'} })
}
#################################################
######### Named RAW events
#################################################
sub irc_msg
{
if ($_[ARG2] =~ /^!quit/i)
{
&log_error("Recieved !quit command");
my $nick = (split /!/, $_[ARG0])[0];
$battleserv->yield(quit=>'yarr');
}
}
#################################################
######### CTCP events
#################################################
sub irc_ctcp_version
{
my $nick = (split /!/, $_[ARG0])[0];
$battleserv->yield(ctcpreply=>$nick=>"VERSION BattleServ v0.1ALPHA designed by eviltwin");
}
sub irc_ctcp_finger
{
my $nick = (split /!/, $_[ARG0])[0];
$battleserv->yield(ctcpreply=>$nick=>"FINGER Battle Service bot - Admin: Graham Lyon AKA eviltwin");
}
and the config file "battleserv.conf" looks like this:
Code:
#this is a comment ;)
moduledir=modules
botnick=BattleServ
botident=BattleServ
botname=Battle Service Bot
server=[a server here]
port=6667
channel=#world
You might want to paste the code into a syntax highlighting text editor for ease of reading... sorry for the lack of comments in it...
Thanks for your time... please help me :-(