mirror of
https://github.com/pragma-/pbot.git
synced 2024-10-04 18:38:47 +02:00
213 lines
7.0 KiB
Perl
213 lines
7.0 KiB
Perl
|
# File: PBot.pm
|
||
|
# Author: pragma_
|
||
|
#
|
||
|
# Purpose: IRC Bot (3rd generation)
|
||
|
|
||
|
package PBot::PBot;
|
||
|
|
||
|
use strict;
|
||
|
use warnings;
|
||
|
|
||
|
BEGIN {
|
||
|
use Exporter ();
|
||
|
use vars qw($VERSION @ISA @EXPORT_OK);
|
||
|
|
||
|
$VERSION = "0.5.0-beta";
|
||
|
@ISA = qw(Exporter);
|
||
|
# TODO: move all of these into the pbot object and pass that around instead
|
||
|
@EXPORT_OK = qw($VERSION %flood_watch $logger %commands $conn %admins $botnick %internal_commands
|
||
|
%is_opped @op_commands %quieted_nicks %ignore_list %unban_timeout @quotegrabs
|
||
|
$channels_file $MAX_NICK_MESSAGES %flood_watch $quotegrabs_file $export_quotegrabs_path $export_quotegrabs_timeout
|
||
|
$commands_file $module_dir $admins_file $export_factoids_timeout $export_factoids_path $max_msg_len
|
||
|
$export_factoids_time $export_quotegrabs_time $MAX_FLOOD_MESSAGES $identify_password);
|
||
|
}
|
||
|
|
||
|
use vars @EXPORT_OK;
|
||
|
|
||
|
# unbuffer stdout
|
||
|
STDOUT->autoflush(1);
|
||
|
|
||
|
use Net::IRC; # for the main IRC engine
|
||
|
use HTML::Entities; # for exporting
|
||
|
use Time::HiRes qw(gettimeofday alarm); # for timers
|
||
|
use Carp ();
|
||
|
use Data::Dumper;
|
||
|
|
||
|
use PBot::Logger;
|
||
|
use PBot::IRCHandlers;
|
||
|
use PBot::InternalCommands;
|
||
|
use PBot::ChannelStuff;
|
||
|
use PBot::StdinReader;
|
||
|
use PBot::Quotegrabs;
|
||
|
use PBot::FactoidStuff;
|
||
|
use PBot::Interpreter;
|
||
|
use PBot::IgnoreList;
|
||
|
use PBot::BotAdminStuff;
|
||
|
use PBot::Modules;
|
||
|
use PBot::AntiFlood;
|
||
|
use PBot::OperatorStuff;
|
||
|
use PBot::TimerStuff;
|
||
|
|
||
|
*admins = \%PBot::BotAdminStuff::admins;
|
||
|
*commands = \%PBot::FactoidStuff::commands;
|
||
|
*quotegrabs = \@PBot::Quotegrabs::quotegrabs;
|
||
|
|
||
|
# TODO: Move these into pbot object
|
||
|
my $ircserver;
|
||
|
|
||
|
sub new {
|
||
|
if(ref($_[1]) eq 'HASH') {
|
||
|
Carp::croak("Options to Logger should be key/value pairs, not hash reference");
|
||
|
}
|
||
|
|
||
|
my ($class, %conf) = @_;
|
||
|
|
||
|
my $log_file = delete $conf{log_file};
|
||
|
|
||
|
# TODO: Move all of these into pbot object
|
||
|
$channels_file = delete $conf{channels_file};
|
||
|
$commands_file = delete $conf{commands_file};
|
||
|
$quotegrabs_file = delete $conf{quotegrabs_file};
|
||
|
$admins_file = delete $conf{admins_file};
|
||
|
$module_dir = delete $conf{module_dir};
|
||
|
$ircserver = delete $conf{ircserver};
|
||
|
$botnick = delete $conf{botnick};
|
||
|
$identify_password = delete $conf{identify_password};
|
||
|
$max_msg_len = delete $conf{max_msg_len};
|
||
|
|
||
|
$export_factoids_timeout = delete $conf{export_factoids_timeout};
|
||
|
$export_factoids_path = delete $conf{export_factoids_path};
|
||
|
|
||
|
$export_quotegrabs_timeout = delete $conf{export_quotegrabs_timeout};
|
||
|
$export_quotegrabs_path = delete $conf{export_quotegrabs_path};
|
||
|
|
||
|
$MAX_FLOOD_MESSAGES = delete $conf{MAX_FLOOD_MESSAGES};
|
||
|
$MAX_NICK_MESSAGES = delete $conf{MAX_NICK_MESSAGES};
|
||
|
|
||
|
my $home = $ENV{HOME};
|
||
|
$channels_file = "$home/pbot/channels" unless defined $channels_file;
|
||
|
$commands_file = "$home/pbot/commands" unless defined $commands_file;
|
||
|
$quotegrabs_file = "$home/pbot/quotegrabs" unless defined $quotegrabs_file;
|
||
|
$admins_file = "$home/pbot/admins" unless defined $admins_file;
|
||
|
$module_dir = "$home/pbot/modules" unless defined $module_dir;
|
||
|
$ircserver = "irc.freenode.net" unless defined $ircserver;
|
||
|
$botnick = "pbot2" unless defined $botnick;
|
||
|
$identify_password = "" unless defined $identify_password;
|
||
|
|
||
|
$export_factoids_timeout = -1 unless defined $export_factoids_timeout;
|
||
|
$export_factoids_time = gettimeofday + $export_factoids_timeout;
|
||
|
|
||
|
$export_quotegrabs_timeout = -1 unless defined $export_quotegrabs_timeout;
|
||
|
$export_quotegrabs_time = gettimeofday + $export_quotegrabs_timeout;
|
||
|
|
||
|
$max_msg_len = 460 unless defined $max_msg_len;
|
||
|
$MAX_FLOOD_MESSAGES = 4 unless defined $MAX_FLOOD_MESSAGES;
|
||
|
$MAX_NICK_MESSAGES = 8 unless defined $MAX_NICK_MESSAGES;
|
||
|
|
||
|
$commands{version} = {
|
||
|
enabled => 1,
|
||
|
owner => $botnick,
|
||
|
text => "/say pbot2 version $VERSION",
|
||
|
timestamp => 0,
|
||
|
ref_count => 0,
|
||
|
ref_user => "nobody" };
|
||
|
|
||
|
# TODO: wrap these in Setters/Getters
|
||
|
unshift @quotegrabs, ({
|
||
|
nick => $botnick,
|
||
|
text => "Who's a bot?",
|
||
|
channel => "#pbot2",
|
||
|
grabbed_by => "pragma_",
|
||
|
id => 1,
|
||
|
timestamp => 0 });
|
||
|
|
||
|
$admins{$botnick} = {
|
||
|
password => '*',
|
||
|
level => 50,
|
||
|
login => 1,
|
||
|
host => "localhost" };
|
||
|
|
||
|
my $self = {
|
||
|
# TODO: add conf variables here
|
||
|
};
|
||
|
|
||
|
$logger = new PBot::Logger(log_file => $log_file);
|
||
|
|
||
|
bless $self, $class;
|
||
|
return $self;
|
||
|
}
|
||
|
|
||
|
my $irc = new Net::IRC;
|
||
|
|
||
|
sub connect {
|
||
|
my ($self, $server) = @_;
|
||
|
|
||
|
$server = $ircserver if not defined $server;
|
||
|
|
||
|
$logger->log("Connecting to $server ...\n");
|
||
|
$conn = $irc->newconn(
|
||
|
Nick => $botnick,
|
||
|
Username => 'pbot3', # FIXME: make this config
|
||
|
Ircname => 'http://www.iso-9899.info/wiki/Candide', # FIXME: make this config
|
||
|
Server => $server,
|
||
|
Port => 6667) # FIXME: make this config
|
||
|
or die "$0: Can't connect to IRC server.\n";
|
||
|
|
||
|
#set up handlers for the IRC engine
|
||
|
$conn->add_handler([ 251,252,253,254,302,255 ], \&PBot::IRCHandlers::on_init );
|
||
|
$conn->add_handler(376 , \&PBot::IRCHandlers::on_connect );
|
||
|
$conn->add_handler('disconnect' , \&PBot::IRCHandlers::on_disconnect );
|
||
|
$conn->add_handler('notice' , \&PBot::IRCHandlers::on_notice );
|
||
|
$conn->add_handler('caction' , \&PBot::IRCHandlers::on_action );
|
||
|
$conn->add_handler('public' , \&PBot::IRCHandlers::on_public );
|
||
|
$conn->add_handler('msg' , \&PBot::IRCHandlers::on_msg );
|
||
|
$conn->add_handler('mode' , \&PBot::IRCHandlers::on_mode );
|
||
|
$conn->add_handler('part' , \&PBot::IRCHandlers::on_departure );
|
||
|
$conn->add_handler('join' , \&PBot::IRCHandlers::on_join );
|
||
|
$conn->add_handler('quit' , \&PBot::IRCHandlers::on_departure );
|
||
|
}
|
||
|
|
||
|
#main loop
|
||
|
sub do_one_loop {
|
||
|
# process IRC events
|
||
|
$irc->do_one_loop();
|
||
|
|
||
|
# process STDIN events
|
||
|
check_stdin();
|
||
|
}
|
||
|
|
||
|
sub check_stdin {
|
||
|
my $input = PBot::StdinReader::check_stdin();
|
||
|
|
||
|
return if not defined $input;
|
||
|
|
||
|
$logger->log("---------------------------------------------\n");
|
||
|
$logger->log("Read '$input' from STDIN\n");
|
||
|
|
||
|
my ($from, $text);
|
||
|
|
||
|
if($input =~ m/^~([^ ]+)\s+(.*)/) {
|
||
|
$from = $1;
|
||
|
$text = "!$2";
|
||
|
} else {
|
||
|
$from = undef;
|
||
|
$text = "!$input";
|
||
|
}
|
||
|
|
||
|
return PBot::Interpreter::process_line($from, $botnick, "stdin", "localhost", $text);
|
||
|
}
|
||
|
|
||
|
sub load_channels {
|
||
|
return PBot::ChannelStuff::load_channels();
|
||
|
}
|
||
|
|
||
|
sub load_quotegrabs {
|
||
|
return PBot::Quotegrabs::load_quotegrabs();
|
||
|
}
|
||
|
|
||
|
sub load_commands {
|
||
|
return PBot::FactoidStuff::load_commands();
|
||
|
}
|
||
|
|
||
|
1;
|