220 lines
4.6 KiB
Perl
220 lines
4.6 KiB
Perl
# Auto IRC Bot. An advanced, lightweight and powerful IRC bot.
|
|
# Copyright (C) 2010-2011 Xelhua Development Team (doc/CREDITS)
|
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
|
|
|
# Subroutines for parsing incoming data from IRC.
|
|
package Parser::IRC;
|
|
use strict;
|
|
use warnings;
|
|
use API::Std qw(conf_get err awarn);
|
|
use API::IRC;
|
|
|
|
# Raw parsing hash.
|
|
our %RAWC = (
|
|
'001' => \&num001,
|
|
'432' => \&num432,
|
|
'433' => \&num433,
|
|
'438' => \&num438,
|
|
'465' => \&num465,
|
|
'471' => \&num471,
|
|
'473' => \&num473,
|
|
'474' => \&num474,
|
|
'475' => \&num475,
|
|
'477' => \&num477,
|
|
'JOIN' => \&cjoin,
|
|
'NICK' => \&nick,
|
|
);
|
|
|
|
# Variables for various functions.
|
|
our (%got_001, %botnick, %botchans);
|
|
|
|
# Parse raw data.
|
|
sub _parse
|
|
{
|
|
my ($svr, $data) = @_;
|
|
|
|
# Split spaces into @ex.
|
|
my @ex = split(' ', $data);
|
|
|
|
# Make sure there is enough data.
|
|
if (defined $ex[0] and defined $ex[1]) {
|
|
# If it's a ping...
|
|
if ($ex[0] eq 'PING') {
|
|
# send a PONG.
|
|
Auto::socksnd($svr, "PONG ".$ex[1]);
|
|
}
|
|
else {
|
|
# otherwise, check %RAWC for ex[1].
|
|
if (defined $RAWC{$ex[1]}) {
|
|
&{ $RAWC{$ex[1]} }($svr, @ex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
###########################
|
|
# Raw parsing subroutines #
|
|
###########################
|
|
|
|
# Parse: Numeric:001
|
|
# Successful connection.
|
|
sub num001
|
|
{
|
|
my ($svr, @ex) = @_;
|
|
|
|
$got_001{$svr} = 1;
|
|
|
|
# Identify string.
|
|
unless (!conf_get("server:$svr:idstr")) {
|
|
my $idstr = (conf_get("server:$svr:idstr"))[0][0];
|
|
Auto::socksnd($svr, $idstr);
|
|
}
|
|
|
|
# Get the auto-join from the config.
|
|
my @cajoin = @{ (conf_get("server:$svr:ajoin"))[0] };
|
|
|
|
# Join the channels.
|
|
unless (defined $cajoin[1]) {
|
|
# For single-line ajoins.
|
|
my @sajoin = split(',', $cajoin[0]);
|
|
|
|
API::IRC::cjoin($svr, $_) foreach (@sajoin);
|
|
}
|
|
else {
|
|
# For multi-line ajoins.
|
|
API::IRC::cjoin($svr, $_) foreach (@cajoin);
|
|
}
|
|
}
|
|
|
|
# Parse: Numeric:432
|
|
# Erroneous nickname.
|
|
sub num432
|
|
{
|
|
my ($svr, undef) = @_;
|
|
|
|
if ($got_001{$svr}) {
|
|
err(3, "Got error from server[".$svr."]: Erroneous nickname.", 0);
|
|
}
|
|
else {
|
|
err(2, "Got error from server[".$svr."] before 001: Erroneous nickname. Closing connection.", 0);
|
|
API::IRC::quit($svr, "An error occurred.");
|
|
}
|
|
|
|
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
|
}
|
|
|
|
# Parse: Numeric:433
|
|
# Nickname is already in use.
|
|
sub num433
|
|
{
|
|
my ($svr, undef) = @_;
|
|
|
|
if (defined $botnick{$svr}{newnick}) {
|
|
API::IRC::nick($svr, $botnick{$svr}{newnick}."_");
|
|
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
|
}
|
|
}
|
|
|
|
# Parse: Numeric:438
|
|
# Nick change too fast.
|
|
sub num438
|
|
{
|
|
my ($svr, @ex) = @_;
|
|
|
|
if (defined $botnick{$svr}{newnick}) {
|
|
API::Std::timer_add("num438_".$botnick{$svr}{newnick}, 1, $ex[11], sub {
|
|
API::IRC::nick($Parser::IRC::botnick{$svr}{newnick});
|
|
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
|
});
|
|
}
|
|
}
|
|
|
|
# Parse: Numeric:465
|
|
# You're banned creep!
|
|
sub num465
|
|
{
|
|
my ($svr, undef) = @_;
|
|
|
|
err(3, "Banned from ".$svr."! Closing link...", 0);
|
|
}
|
|
|
|
# Parse: Numeric:471
|
|
# Cannot join channel: Channel is full.
|
|
sub num471
|
|
{
|
|
my ($svr, (undef, undef, undef, $chan)) = @_;
|
|
|
|
err(3, "Cannot join channel ".$chan." on ".$svr.": Channel is full.", 0);
|
|
}
|
|
|
|
# Parse: Numeric:473
|
|
# Cannot join channel: Channel is invite-only.
|
|
sub num473
|
|
{
|
|
my ($svr, (undef, undef, undef, $chan)) = @_;
|
|
|
|
err(3, "Cannot join channel ".$chan." on ".$svr.": Channel is invite-only.", 0);
|
|
}
|
|
|
|
# Parse: Numeric:474
|
|
# Cannot join channel: Banned from channel.
|
|
sub num474
|
|
{
|
|
my ($svr, (undef, undef, undef, $chan)) = @_;
|
|
|
|
err(3, "Cannot join channel ".$chan." on ".$svr.": Banned from channel.", 0);
|
|
}
|
|
|
|
# Parse: Numeric:475
|
|
# Cannot join channel: Bad key.
|
|
sub num475
|
|
{
|
|
my ($svr, (undef, undef, undef, $chan)) = @_;
|
|
|
|
err(3, "Cannot join channel ".$chan." on ".$svr.": Bad key.", 0);
|
|
}
|
|
|
|
# Parse: Numeric:477
|
|
# Cannot join channel: Need registered nickname.
|
|
sub num473
|
|
{
|
|
my ($svr, (undef, undef, undef, $chan)) = @_;
|
|
|
|
err(3, "Cannot join channel ".$chan." on ".$svr.": Need registered nickname.", 0);
|
|
}
|
|
|
|
# Parse: JOIN
|
|
sub cjoin
|
|
{
|
|
my ($svr, @ex) = @_;
|
|
my %src = API::IRC::usrc(substr($ex[0], 1));
|
|
|
|
# Check if this is coming from ourselves.
|
|
if ($src{nick} eq $botnick{$svr}) {
|
|
unless (defined $botchans{$svr}) {
|
|
@{ $botchans{$svr} } = (substr($ex[2], 1));
|
|
}
|
|
else {
|
|
push(@{ $botchans{$svr} }, substr($ex[2], 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
# Parse: NICK
|
|
sub nick
|
|
{
|
|
my ($svr, @ex) = @_;
|
|
|
|
my %src = API::IRC::usrc(substr($ex[0], 1));
|
|
|
|
# Check if this is coming from ourselves.
|
|
if ($src{nick} eq $botnick{$svr}) {
|
|
$botnick{$svr} = $ex[2];
|
|
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
1;
|