Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7902aba4c5 | ||
|
|
f3f58c8f94 | ||
|
|
c616931339 | ||
|
|
92c9a64793 | ||
|
|
cc1c8fd5bc | ||
|
|
ad799a32a2 | ||
|
|
35f58bf5b7 | ||
|
|
9ad245fc79 | ||
|
|
f9cafa11e7 | ||
|
|
6a7cf754cc | ||
|
|
24ab4aaf9a | ||
|
|
9ff384866e | ||
|
|
4eb157ad8e | ||
|
|
bec120c70f | ||
|
|
8898e74341 | ||
|
|
18a8752e28 | ||
|
|
27521072c5 | ||
|
|
01cc71d564 | ||
|
|
634a68b5f2 | ||
|
|
c330a59474 | ||
|
|
be43449e74 | ||
|
|
445b7e0db3 | ||
|
|
30d9e11f1f | ||
|
|
66c4b3441a | ||
|
|
ba6f7dba40 | ||
|
|
5f74bb3171 | ||
|
|
15f188edfb | ||
|
|
6e0263bcd8 | ||
|
|
411e08fd1c | ||
|
|
e93939d4cf | ||
|
|
88d7799569 | ||
|
|
234c8d1657 | ||
|
|
11dae6b927 | ||
|
|
897ad85615 | ||
|
|
96384f853a | ||
|
|
c5e0853cb1 | ||
|
|
1b853d9269 | ||
|
|
ec627df22e | ||
|
|
43e6ce1aaa | ||
|
|
a4ae87a86c | ||
|
|
7a9230c75a | ||
|
|
9288301259 | ||
|
|
85ea081435 | ||
|
|
eb3332241f | ||
|
|
deb95a7ee7 | ||
|
|
067da4d7ad | ||
|
|
49332e5d93 | ||
|
|
7108f3fdfa | ||
|
|
8077acd9ae | ||
|
|
7928f77083 | ||
|
|
f1b6e2f91b | ||
|
|
3f17cb99b2 | ||
|
|
6828aafc44 | ||
|
|
dbe32535d4 | ||
|
|
42cb5201f6 | ||
|
|
04949f38bf | ||
|
|
7dbebdeca9 | ||
|
|
f97b55a56c | ||
|
|
60cdd488ba | ||
|
|
c0aa9d981c | ||
|
|
187de7cdef | ||
|
|
42b58c73e9 | ||
|
|
795c1da38d | ||
|
|
5c9376524c | ||
|
|
c65f3afda4 | ||
|
|
c2b436f420 | ||
|
|
853c7e087e | ||
|
|
0abc3a8236 | ||
|
|
ac389ef399 | ||
|
|
a831e0c4ab | ||
|
|
e154175571 | ||
|
|
3c7e975c98 | ||
|
|
945edfaf54 | ||
|
|
bad3169336 | ||
|
|
6e61841e20 | ||
|
|
b133ef7a6f | ||
|
|
29f00aba27 | ||
|
|
df401193dc | ||
|
|
55071e09d0 | ||
|
|
7f6cd84af8 | ||
|
|
e543af08ad | ||
|
|
31e2c8b4f9 | ||
|
|
934a10d880 | ||
|
|
cf45c4468a | ||
|
|
c2e58299d7 | ||
|
|
9de515a172 | ||
|
|
f274f04c3b | ||
|
|
42cd6da78c | ||
|
|
c9181cf4ce | ||
|
|
a75e3ee771 | ||
|
|
50a3f73a82 | ||
|
|
80004fe047 | ||
|
|
6706445dff | ||
|
|
02ce09749c | ||
|
|
6bff5da689 | ||
|
|
536fc0bc48 | ||
|
|
69c9ccb917 | ||
|
|
0bbf9ae5f1 | ||
|
|
e73fe3138a | ||
|
|
20a8e8c2e4 | ||
|
|
7f4655121e | ||
|
|
650ffdd39f | ||
|
|
fe57f6df3e | ||
|
|
27e242bbef | ||
|
|
b43daecd97 | ||
|
|
e9cf2bda42 | ||
|
|
74b20cb9e7 | ||
|
|
87692dd0ea | ||
|
|
bd7f52d574 | ||
|
|
c21ed7bacb | ||
|
|
f9d624abd0 | ||
|
|
3c1cb00628 |
No files matched your search
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
*.conf
|
auto.conf
|
||||||
build/*
|
build/*
|
||||||
*.swp
|
*.swp
|
||||||
|
autodoc/*
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
8""""8
|
||||||
|
8 8 e e eeeee eeeee
|
||||||
|
8eeee8 8 8 8 8 88
|
||||||
|
88 8 8e 8 8e 8 8
|
||||||
|
88 8 88 8 88 8 8
|
||||||
|
88 8 88ee8 88 8eee8
|
||||||
|
|
||||||
|
3.0
|
||||||
|
|
||||||
|
|
||||||
|
The future of IRC bots is here! Xelhua gives to you, Auto 3.0, a new version of
|
||||||
|
the popular Auto IRC bot.
|
||||||
|
|
||||||
|
In this alpha5 release, we have added:
|
||||||
|
|
||||||
|
* LinkTitle module for returning the page title of links sent to a channel.
|
||||||
|
* Added core command MODLIST.
|
||||||
|
* Added SEARCH and MORE to QDB. Amount of results returned at a time with
|
||||||
|
qdb_search_resnum in the config.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* Fixed a bug when viewing non-existent quotes.
|
||||||
|
* SEVERE: Fixed a bug that caused rehash to fail.
|
||||||
|
|
||||||
|
Incompatibilities:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
We thank you for choosing Auto. Please remember that he is still in early
|
||||||
|
development stages. But we hope we've piqued your interest, as Auto's upcoming
|
||||||
|
module repository will allow modules to be created by anyone and uploaded
|
||||||
|
there for everyone to use.
|
||||||
|
|
||||||
|
Auto's goal is to create an efficient, stable and highly customizable IRC bot
|
||||||
|
in Perl. To offer an alternative to other platforms.
|
||||||
|
|
||||||
|
Enjoy Auto 3.0.0 Alpha 5!
|
||||||
@@ -5,53 +5,49 @@
|
|||||||
# Written in sh because the user may not have Perl...to run Auto....
|
# Written in sh because the user may not have Perl...to run Auto....
|
||||||
|
|
||||||
PID=bin/auto.pid
|
PID=bin/auto.pid
|
||||||
MODS="Mouse Class::Unload"
|
MODS="Class::Unload DBI"
|
||||||
EMODS="MIME::Base64 XML::Simple"
|
|
||||||
|
|
||||||
if [ "$1" = "start" ] ; then
|
if [ "$1" = "start" ] ; then
|
||||||
if [ -e $PID ]; then
|
if [ -e $PID ]; then
|
||||||
if [ "$2" = "force" ]; then
|
if [ "$2" = "force" ]; then
|
||||||
echo "Starting Auto. . ."
|
echo "Starting Auto. . ."
|
||||||
bin/auto
|
bin/auto
|
||||||
sleep 2
|
sleep 2
|
||||||
if [ ! -r $PID ]; then
|
if [ ! -r $PID ]; then
|
||||||
echo "Possible failed startup... check Auto logs for more information."
|
echo "Possible failed startup... check Auto logs for more information."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "Auto appears to be running already. Run ./auto start force to start anyway."
|
echo "Auto appears to be running already. Run ./auto start force to start anyway."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "Starting Auto. . ."
|
echo "Starting Auto. . ."
|
||||||
bin/auto
|
bin/auto
|
||||||
sleep 2
|
sleep 2
|
||||||
if [ ! -r $PID ]; then
|
if [ ! -r $PID ]; then
|
||||||
echo "Possible failed startup... check Auto logs for more information"
|
echo "Possible failed startup... check Auto logs for more information"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
elif [ "$1" = "stop" ]; then
|
elif [ "$1" = "stop" ]; then
|
||||||
echo "Stopping Auto. . ."
|
echo "Stopping Auto. . ."
|
||||||
kill -TERM `cat $PID`
|
kill -TERM `cat $PID`
|
||||||
|
|
||||||
elif [ "$1" = "rehash" ]; then
|
elif [ "$1" = "rehash" ]; then
|
||||||
echo "Rehashing Auto. . ."
|
echo "Rehashing Auto. . ."
|
||||||
kill -HUP `cat $PID`
|
kill -HUP `cat $PID`
|
||||||
|
|
||||||
elif [ "$1" = "status" ]; then
|
elif [ "$1" = "status" ]; then
|
||||||
if [ -e $PID ]; then
|
if [ -e $PID ]; then
|
||||||
echo "Status: Auto appears to be running."
|
echo "Status: Auto appears to be running."
|
||||||
else
|
else
|
||||||
echo "Status: Auto appears to not be running."
|
echo "Status: Auto appears to not be running."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
elif [ "$1" = "getmodules" ]; then
|
elif [ "$1" = "getmodules" ]; then
|
||||||
cpan -i $MODS
|
cpan -i $MODS
|
||||||
|
|
||||||
elif [ "$1" = "getextras" ]; then
|
|
||||||
cpan -i $EMODS
|
|
||||||
|
|
||||||
else
|
else
|
||||||
echo "Usage: auto (start|stop|rehash|status|getmodules|getextras)"
|
echo "Usage: auto (start|stop|rehash|status|getmodules)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
@@ -7,7 +7,7 @@ package Auto;
|
|||||||
use 5.010_000;
|
use 5.010_000;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
no feature qw(say state);
|
no feature qw(state);
|
||||||
use POSIX;
|
use POSIX;
|
||||||
use locale;
|
use locale;
|
||||||
use English qw(-no_match_vars);
|
use English qw(-no_match_vars);
|
||||||
@@ -15,7 +15,6 @@ use Sys::Hostname;
|
|||||||
use IO::Socket;
|
use IO::Socket;
|
||||||
use IO::Select;
|
use IO::Select;
|
||||||
use DBI;
|
use DBI;
|
||||||
use DBD::SQLite;
|
|
||||||
use Class::Unload;
|
use Class::Unload;
|
||||||
use FindBin qw($Bin);
|
use FindBin qw($Bin);
|
||||||
our $Bin = $Bin; ## no critic qw(NamingConventions::Capitalization Variables::ProhibitPackageVars)
|
our $Bin = $Bin; ## no critic qw(NamingConventions::Capitalization Variables::ProhibitPackageVars)
|
||||||
@@ -24,17 +23,17 @@ BEGIN {
|
|||||||
|
|
||||||
# Set version information.
|
# Set version information.
|
||||||
use constant { ## no critic qw(ValuesAndExpressions::ProhibitConstantPragma)
|
use constant { ## no critic qw(ValuesAndExpressions::ProhibitConstantPragma)
|
||||||
NAME => 'Auto IRC Bot',
|
NAME => 'Auto IRC Bot',
|
||||||
VER => 3,
|
VER => 3,
|
||||||
SVER => 0,
|
SVER => 0,
|
||||||
REV => 0,
|
REV => 0,
|
||||||
RSTAGE => 'd',
|
RSTAGE => 'd',
|
||||||
GR => substr `cat $Bin/../.git/refs/heads/indev`, 0, 7
|
GR => substr `cat $Bin/../.git/refs/heads/indev`, 0, 7
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
use Lib::Auto;
|
use Lib::Auto;
|
||||||
use API::Std qw(conf_get err);
|
use API::Std qw(conf_get err);
|
||||||
use API::Log qw(println alog dbug);
|
use API::Log qw(alog dbug);
|
||||||
#use DB::Flatfile;
|
#use DB::Flatfile;
|
||||||
use Parser::Config;
|
use Parser::Config;
|
||||||
use Parser::Lang;
|
use Parser::Lang;
|
||||||
@@ -47,41 +46,41 @@ local $PROGRAM_NAME = 'auto';
|
|||||||
|
|
||||||
# Check for build files.
|
# Check for build files.
|
||||||
if (!-e "$Bin/../build/os" or !-e "$Bin/../build/perl" or !-e "$Bin/../build/time" or !-e "$Bin/../build/ver") {
|
if (!-e "$Bin/../build/os" or !-e "$Bin/../build/perl" or !-e "$Bin/../build/time" or !-e "$Bin/../build/ver") {
|
||||||
println 'Missing build file(s). Please build Auto before running it.' and exit;
|
say 'Missing build file(s). Please build Auto before running it.' and exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check build OS.
|
# Check build OS.
|
||||||
open my $BFOS, '<', "$Bin/../build/os" or println 'Cannot start: Broken build.' and exit;
|
open my $BFOS, '<', "$Bin/../build/os" or say 'Cannot start: Broken build.' and exit;
|
||||||
my @BFOS = <$BFOS>;
|
my @BFOS = <$BFOS>;
|
||||||
close $BFOS or println 'Cannot start: Broken build.' and exit;
|
close $BFOS or say 'Cannot start: Broken build.' and exit;
|
||||||
if ($BFOS[0] ne $OSNAME."\n") {
|
if ($BFOS[0] ne $OSNAME."\n") {
|
||||||
println 'Cannot start: Broken build.' and exit;
|
say 'Cannot start: Broken build.' and exit;
|
||||||
}
|
}
|
||||||
undef @BFOS;
|
undef @BFOS;
|
||||||
|
|
||||||
# Check build features.
|
# Check build features.
|
||||||
our $ENFEAT;
|
our $ENFEAT;
|
||||||
open my $BFFEAT, '<', "$Bin/../build/feat" or println 'Cannot start: Broken build.' and exit;
|
open my $BFFEAT, '<', "$Bin/../build/feat" or say 'Cannot start: Broken build.' and exit;
|
||||||
my @BFFEAT = <$BFFEAT>;
|
my @BFFEAT = <$BFFEAT>;
|
||||||
close $BFFEAT or println 'Cannot start: Broken build.' and exit;
|
close $BFFEAT or say 'Cannot start: Broken build.' and exit;
|
||||||
$ENFEAT = substr $BFFEAT[0], 0, length($BFFEAT[0]) - 1;
|
$ENFEAT = substr $BFFEAT[0], 0, length($BFFEAT[0]) - 1;
|
||||||
undef @BFFEAT;
|
undef @BFFEAT;
|
||||||
|
|
||||||
# Check build Perl version.
|
# Check build Perl version.
|
||||||
open my $BFPERL, '<', "$Bin/../build/perl" or println 'Cannot start: Broken build.' and exit;
|
open my $BFPERL, '<', "$Bin/../build/perl" or say 'Cannot start: Broken build.' and exit;
|
||||||
my @BFPERL = <$BFPERL>;
|
my @BFPERL = <$BFPERL>;
|
||||||
close $BFPERL or println 'Cannot start: Broken build.' and exit;
|
close $BFPERL or say 'Cannot start: Broken build.' and exit;
|
||||||
if ($BFPERL[0] ne $]."\n") {
|
if ($BFPERL[0] ne $]."\n") {
|
||||||
println 'Cannot start: Broken build.' and exit;
|
say 'Cannot start: Broken build.' and exit;
|
||||||
}
|
}
|
||||||
undef @BFPERL;
|
undef @BFPERL;
|
||||||
|
|
||||||
# Check build Auto version.
|
# Check build Auto version.
|
||||||
open my $BFVER, '<', "$Bin/../build/ver" or println 'Cannot start: Broken build.' and exit;
|
open my $BFVER, '<', "$Bin/../build/ver" or say 'Cannot start: Broken build.' and exit;
|
||||||
my @BFVER = <$BFVER>;
|
my @BFVER = <$BFVER>;
|
||||||
close $BFVER or println 'Cannot start: Broken build.' and exit;
|
close $BFVER or say 'Cannot start: Broken build.' and exit;
|
||||||
if ($BFVER[0] ne VER.q{.}.SVER.q{.}.REV.RSTAGE."\n") {
|
if ($BFVER[0] ne VER.q{.}.SVER.q{.}.REV.RSTAGE."\n") {
|
||||||
println 'Cannot start: Broken build.' and exit;
|
say 'Cannot start: Broken build.' and exit;
|
||||||
}
|
}
|
||||||
undef @BFVER;
|
undef @BFVER;
|
||||||
|
|
||||||
@@ -97,7 +96,7 @@ API::Std::event_add('on_sighup');
|
|||||||
|
|
||||||
|
|
||||||
# Print startup message.
|
# Print startup message.
|
||||||
println <<'EOF';
|
say <<'EOF';
|
||||||
8""""8
|
8""""8
|
||||||
8 8 e e eeeee eeeee
|
8 8 e e eeeee eeeee
|
||||||
8eeee8 8 8 8 8 88
|
8eeee8 8 8 8 8 88
|
||||||
@@ -105,7 +104,7 @@ println <<'EOF';
|
|||||||
88 8 88 8 88 8 8
|
88 8 88 8 88 8 8
|
||||||
88 8 88ee8 88 8eee8
|
88 8 88ee8 88 8eee8
|
||||||
EOF
|
EOF
|
||||||
println '* '.NAME.' (version '.VER.q{.}.SVER.q{.}.REV.RSTAGE.') is starting up...';
|
say '* '.NAME.' (version '.VER.q{.}.SVER.q{.}.REV.RSTAGE.') is starting up...';
|
||||||
|
|
||||||
our ($APID, %TIMERS);
|
our ($APID, %TIMERS);
|
||||||
|
|
||||||
@@ -113,8 +112,8 @@ our ($APID, %TIMERS);
|
|||||||
our $DEBUG = 0;
|
our $DEBUG = 0;
|
||||||
our $NUC = 0;
|
our $NUC = 0;
|
||||||
if (defined $ARGV[0]) {
|
if (defined $ARGV[0]) {
|
||||||
foreach (@ARGV) {
|
foreach (@ARGV) {
|
||||||
given ($_) {
|
given ($_) {
|
||||||
when ('-d') { $DEBUG = 1; }
|
when ('-d') { $DEBUG = 1; }
|
||||||
when ('-nuc') { $NUC = 1; }
|
when ('-nuc') { $NUC = 1; }
|
||||||
}
|
}
|
||||||
@@ -130,49 +129,122 @@ if ($ENFEAT =~ /ipv6/) { require IO::Socket::INET6; }
|
|||||||
if ($ENFEAT =~ /ssl/) { require IO::Socket::SSL; }
|
if ($ENFEAT =~ /ssl/) { require IO::Socket::SSL; }
|
||||||
|
|
||||||
# Parse configuration file.
|
# Parse configuration file.
|
||||||
println '* Parsing configuration file auto.conf...';
|
say '* Parsing configuration file auto.conf...';
|
||||||
our $CONF = Parser::Config->new('auto.conf') or err(1, 'Failed to parse configuration file!', 1);
|
our $CONF = Parser::Config->new('auto.conf') or err(1, 'Failed to parse configuration file!', 1);
|
||||||
our %SETTINGS = $CONF->parse or err(1, 'Failed to parse configuration file!', 1);
|
our %SETTINGS = $CONF->parse or err(1, 'Failed to parse configuration file!', 1);
|
||||||
println ' Success';
|
say ' Success';
|
||||||
|
|
||||||
if (conf_get('die')) {
|
if (conf_get('die')) {
|
||||||
if ((conf_get('die'))[0][0] == 1) {
|
if ((conf_get('die'))[0][0] == 1) {
|
||||||
println '!!! You didn\'t read the whole config.';
|
say '!!! You didn\'t read the whole config.';
|
||||||
println '!!! Insert new user then try again.';
|
say '!!! Insert new user then try again.';
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check for required configuration values.
|
# Check for required configuration values.
|
||||||
my @REQCVALS = qw(locale expire_logs server fantasy_pf ratelimit);
|
my @REQCVALS = qw(locale expire_logs server fantasy_pf ratelimit database:format bantype);
|
||||||
foreach my $REQCVAL (@REQCVALS) {
|
foreach my $REQCVAL (@REQCVALS) {
|
||||||
if (!conf_get($REQCVAL)) {
|
if (!conf_get($REQCVAL)) {
|
||||||
my $err = 2;
|
my $err = 2;
|
||||||
if ($REQCVAL eq 'expire_logs') {
|
if ($REQCVAL eq 'expire_logs') {
|
||||||
$err = 1;
|
$err = 1;
|
||||||
}
|
}
|
||||||
err($err, "Missing required configuration value: $REQCVAL", 1);
|
err($err, "Missing required configuration value: $REQCVAL", 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
undef @REQCVALS;
|
undef @REQCVALS;
|
||||||
|
|
||||||
# Parse translations.
|
# Parse translations.
|
||||||
println '* Parsing translation files...';
|
say '* Parsing translation files...';
|
||||||
our $LOCALE = (conf_get('locale'))[0][0];
|
our $LOCALE = (conf_get('locale'))[0][0];
|
||||||
my @lang = split m/[_]/, $LOCALE;
|
my @lang = split m/[_]/, $LOCALE;
|
||||||
Parser::Lang::parse($lang[0]) or err(2, 'Failed to parse translation files!', 1);
|
Parser::Lang::parse($lang[0]) or err(2, 'Failed to parse translation files!', 1);
|
||||||
undef @lang;
|
undef @lang;
|
||||||
println ' Success';
|
say ' Success';
|
||||||
|
|
||||||
# Expire old logs.
|
# Expire old logs.
|
||||||
API::Log::expire_logs();
|
API::Log::expire_logs();
|
||||||
|
|
||||||
# Connect to database.
|
# Connect to database.
|
||||||
if (!-e "$Bin/../etc/auto.db") {
|
our $DB;
|
||||||
system "touch $Bin/../etc/auto.db";
|
given (lc((conf_get('database:format'))[0][0])) {
|
||||||
system "chmod a+x $Bin/../etc/auto.db";
|
when ('sqlite') {
|
||||||
|
# SQLite.
|
||||||
|
if ($ENFEAT !~ /sqlite/) { err(2, 'Auto not built with SQLite support. Aborting.', 1); }
|
||||||
|
if (!conf_get('database:filename')) { err(2, 'Missing required configuration value database:filename. Aborting.', 1); }
|
||||||
|
|
||||||
|
# Import DBD::SQLite.
|
||||||
|
require DBD::SQLite;
|
||||||
|
|
||||||
|
if (!-e "$Bin/../etc/".(conf_get('database:filename'))[0][0]) {
|
||||||
|
# Create <database:filename> if it's missing.
|
||||||
|
system "touch $Bin/../etc/".(conf_get('database:filename'))[0][0];
|
||||||
|
system "chmod a+x $Bin/../etc/".(conf_get('database:filename'))[0][0];
|
||||||
|
}
|
||||||
|
# Connect to database.
|
||||||
|
$DB = DBI->connect("dbi:SQLite:dbname=$Bin/../etc/".(conf_get('database:filename'))[0][0]) or err(2, 'Failed to connect to database!', 1);
|
||||||
|
}
|
||||||
|
when ('mysql') {
|
||||||
|
# MySQL.
|
||||||
|
if ($ENFEAT !~ /mysql/) { err(2, 'Auto not built with MySQL support. Aborting.', 1); }
|
||||||
|
my @reqcval = qw(database:host database:name database:username database:password);
|
||||||
|
foreach (@reqcval) { if (!conf_get($_)) { err(2, "Missing required configuration value $_. Aborting.", 1); } }
|
||||||
|
undef @reqcval;
|
||||||
|
|
||||||
|
# Import DBD::mysql.
|
||||||
|
require DBD::mysql;
|
||||||
|
|
||||||
|
# Connect to database.
|
||||||
|
if (conf_get('database:port')) {
|
||||||
|
# If we were given a port, connect with it.
|
||||||
|
$DB = DBI->connect('DBI:mysql:database='.(conf_get('database:name'))[0][0].';host='.(conf_get('database:host'))[0][0].';port='.(conf_get('database:port'))[0][0],
|
||||||
|
(conf_get('database:username'))[0][0], (conf_get('database:password'))[0][0]) or err(2, 'Failed to connect to database!', 1);;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# If not, connect without specifying a port.
|
||||||
|
$DB = DBI->connect('DBI:mysql:database='.(conf_get('database:name'))[0][0].';host='.(conf_get('database:host'))[0][0],
|
||||||
|
(conf_get('database:username'))[0][0], (conf_get('database:password'))[0][0]) or err(2, 'Failed to connect to database!', 1);;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# CSV no work. :(
|
||||||
|
#when ('csv') {
|
||||||
|
# # CSV.
|
||||||
|
# if ($ENFEAT !~ /csv/) { err(2, 'Auto not built with CSV support.', 1); }
|
||||||
|
# if (!conf_get('database:dir')) { err(2, 'Missing required configuration value database:dir. Aborting.', 1); }
|
||||||
|
#
|
||||||
|
# # Import DBD::CSV.
|
||||||
|
# require DBD::CSV;
|
||||||
|
#
|
||||||
|
# # Connect to database.
|
||||||
|
# $DB = DBI->connect("dbi:CSV:f_dir=$Bin/../etc/".(conf_get('database:dir'))[0][0]) or err(2, 'Failed to connect to database!', 1);
|
||||||
|
#}
|
||||||
|
when ('pgsql') {
|
||||||
|
# PostgreSQL.
|
||||||
|
if ($ENFEAT !~ /pgsql/) { err(2, 'Auto not built with PostgreSQL support. Aborting.', 1); }
|
||||||
|
my @reqcval = qw(database:name database:host database:username database:password);
|
||||||
|
foreach (@reqcval) { if (!conf_get($_)) { err(2, "Missing required configuration value $_. Aborting.", 1); } }
|
||||||
|
undef @reqcval;
|
||||||
|
|
||||||
|
# Import DBD::Pg.
|
||||||
|
require DBD::Pg;
|
||||||
|
|
||||||
|
# Connect to database.
|
||||||
|
if (conf_get('database:port')) {
|
||||||
|
# If a specific port was given, use it.
|
||||||
|
$DB = DBI->connect('dbi:Pg:db='.(conf_get('database:name'))[0][0].';host='.(conf_get('database:host'))[0][0].';port='.(conf_get('database:port'))[0][0],
|
||||||
|
(conf_get('database:username'))[0][0], (conf_get('database:password'))[0][0]) or err(2, 'Failed to connect to database!', 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# We were not given a port, connect using PGPORT (usually 5432)
|
||||||
|
$DB = DBI->connect('dbi:Pg:db='.(conf_get('database:name'))[0][0].';host='.(conf_get('database:host'))[0][0],
|
||||||
|
(conf_get('database:username'))[0][0], (conf_get('database:password'))[0][0]) or err(2, 'Failed to connect to database!', 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Unknown database format.
|
||||||
|
default { err(2, 'Unknown database format \''.lc((conf_get('database:format'))[0][0]).'\'. Aborting.', 1); }
|
||||||
}
|
}
|
||||||
our $DB = DBI->connect("dbi:SQLite:dbname=$Bin/../etc/auto.db", q{}, q{});
|
|
||||||
|
|
||||||
# Ratelimit timer.
|
# Ratelimit timer.
|
||||||
Core::IRC::clear_usercmd_timer();
|
Core::IRC::clear_usercmd_timer();
|
||||||
@@ -181,59 +253,59 @@ Core::IRC::clear_usercmd_timer();
|
|||||||
our (%PRIVILEGES);
|
our (%PRIVILEGES);
|
||||||
# If there are any privsets.
|
# If there are any privsets.
|
||||||
if (conf_get('privset')) {
|
if (conf_get('privset')) {
|
||||||
# Get them.
|
# Get them.
|
||||||
my %tcprivs = conf_get('privset');
|
my %tcprivs = conf_get('privset');
|
||||||
|
|
||||||
foreach my $tckpriv (keys %tcprivs) {
|
foreach my $tckpriv (keys %tcprivs) {
|
||||||
# For each privset, get the inner values.
|
# For each privset, get the inner values.
|
||||||
my %mcprivs = conf_get("privset:$tckpriv");
|
my %mcprivs = conf_get("privset:$tckpriv");
|
||||||
|
|
||||||
# Iterate through them.
|
# Iterate through them.
|
||||||
foreach my $mckpriv (keys %mcprivs) {
|
foreach my $mckpriv (keys %mcprivs) {
|
||||||
# Switch statement for the values.
|
# Switch statement for the values.
|
||||||
given ($mckpriv) {
|
given ($mckpriv) {
|
||||||
# If it's 'priv', save it as a privilege.
|
# If it's 'priv', save it as a privilege.
|
||||||
when ('priv') {
|
when ('priv') {
|
||||||
if (defined $PRIVILEGES{$tckpriv}) {
|
if (defined $PRIVILEGES{$tckpriv}) {
|
||||||
# If this privset exists, push to it.
|
# If this privset exists, push to it.
|
||||||
push @{ $PRIVILEGES{$tckpriv} }, ($mcprivs{$mckpriv})[0][0];
|
push @{ $PRIVILEGES{$tckpriv} }, ($mcprivs{$mckpriv})[0][0];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, create it.
|
# Otherwise, create it.
|
||||||
@{ $PRIVILEGES{$tckpriv} } = (($mcprivs{$mckpriv})[0][0]);
|
@{ $PRIVILEGES{$tckpriv} } = (($mcprivs{$mckpriv})[0][0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# If it's 'inherit', inherit the privileges of another privset.
|
# If it's 'inherit', inherit the privileges of another privset.
|
||||||
when ('inherit') {
|
when ('inherit') {
|
||||||
# If the privset we're inheriting exists, continue.
|
# If the privset we're inheriting exists, continue.
|
||||||
if (defined $PRIVILEGES{($mcprivs{$mckpriv})[0][0]}) {
|
if (defined $PRIVILEGES{($mcprivs{$mckpriv})[0][0]}) {
|
||||||
# Iterate through each privilege.
|
# Iterate through each privilege.
|
||||||
foreach (@{ $PRIVILEGES{($mcprivs{$mckpriv})[0][0]} }) {
|
foreach (@{ $PRIVILEGES{($mcprivs{$mckpriv})[0][0]} }) {
|
||||||
# And save them to the privset inheriting them
|
# And save them to the privset inheriting them
|
||||||
if (defined $PRIVILEGES{$tckpriv}) {
|
if (defined $PRIVILEGES{$tckpriv}) {
|
||||||
# If this privset exists, push to it.
|
# If this privset exists, push to it.
|
||||||
push @{ $PRIVILEGES{$tckpriv} }, $_;
|
push @{ $PRIVILEGES{$tckpriv} }, $_;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, create it.
|
# Otherwise, create it.
|
||||||
@{ $PRIVILEGES{$tckpriv} } = ($_);
|
@{ $PRIVILEGES{$tckpriv} } = ($_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Successful startup.
|
# Successful startup.
|
||||||
our $STARTTIME = time;
|
our $STARTTIME = time;
|
||||||
println '* Auto successfully started at '.POSIX::strftime('%Y-%m-%d %I:%M:%S %p', localtime).q{.};
|
say '* Auto successfully started at '.POSIX::strftime('%Y-%m-%d %I:%M:%S %p', localtime).q{.};
|
||||||
alog 'Auto successfully started.';
|
alog 'Auto successfully started.';
|
||||||
|
|
||||||
# Fork into the background if not in debug mode.
|
# Fork into the background if not in debug mode.
|
||||||
if (!$DEBUG) {
|
if (!$DEBUG) {
|
||||||
println '*** Becoming a daemon...';
|
say '*** Becoming a daemon...';
|
||||||
open STDIN, '<', '/dev/null' or err(2, "Can't read /dev/null: $ERRNO", 1);
|
open STDIN, '<', '/dev/null' or err(2, "Can't read /dev/null: $ERRNO", 1);
|
||||||
open STDOUT, '>>', '/dev/null' or err(2, "Can't write to /dev/null: $ERRNO", 1);
|
open STDOUT, '>>', '/dev/null' or err(2, "Can't write to /dev/null: $ERRNO", 1);
|
||||||
open STDERR, '>>', '/dev/null' or err(2, "Can't write to /dev/null: $ERRNO", 1);
|
open STDERR, '>>', '/dev/null' or err(2, "Can't write to /dev/null: $ERRNO", 1);
|
||||||
@@ -241,11 +313,11 @@ if (!$DEBUG) {
|
|||||||
if ($APID != 0) {
|
if ($APID != 0) {
|
||||||
alog '* Successfully forked into the background. Process ID: '.$APID;
|
alog '* Successfully forked into the background. Process ID: '.$APID;
|
||||||
if (!-e "$Bin/auto.pid") {
|
if (!-e "$Bin/auto.pid") {
|
||||||
system "touch $Bin/auto.pid";
|
system "touch $Bin/auto.pid";
|
||||||
}
|
}
|
||||||
open my $FPID, '>', "$Bin/auto.pid" or exit;
|
open my $FPID, '>', "$Bin/auto.pid" or exit;
|
||||||
print {$FPID} "$APID\n" or exit;
|
print {$FPID} "$APID\n" or exit;
|
||||||
close $FPID or exit;
|
close $FPID or exit;
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
POSIX::setsid() or err(2, "Can't start a new session: $ERRNO", 1);
|
POSIX::setsid() or err(2, "Can't start a new session: $ERRNO", 1);
|
||||||
@@ -259,11 +331,11 @@ API::Std::event_add('on_preconnect');
|
|||||||
|
|
||||||
# Load modules.
|
# Load modules.
|
||||||
if (conf_get('module')) {
|
if (conf_get('module')) {
|
||||||
alog '* Loading modules...';
|
alog '* Loading modules...';
|
||||||
dbug '* Loading modules...';
|
dbug '* Loading modules...';
|
||||||
foreach (@{ (conf_get('module'))[0] }) {
|
foreach (@{ (conf_get('module'))[0] }) {
|
||||||
mod_load($_);
|
mod_load($_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
## Create sockets.
|
## Create sockets.
|
||||||
@@ -279,13 +351,13 @@ my $it = 0;
|
|||||||
foreach my $cskey (keys %cservers) {
|
foreach my $cskey (keys %cservers) {
|
||||||
# Prepare socket data.
|
# Prepare socket data.
|
||||||
my %conndata = (
|
my %conndata = (
|
||||||
Proto => 'tcp',
|
Proto => 'tcp',
|
||||||
LocalAddr => $cservers{$cskey}{'bind'}[0],
|
LocalAddr => $cservers{$cskey}{'bind'}[0],
|
||||||
PeerAddr => $cservers{$cskey}{'host'}[0],
|
PeerAddr => $cservers{$cskey}{'host'}[0],
|
||||||
PeerPort => $cservers{$cskey}{'port'}[0],
|
PeerPort => $cservers{$cskey}{'port'}[0],
|
||||||
Timeout => 20,
|
Timeout => 20,
|
||||||
);
|
);
|
||||||
# Set IPv6/SSL data.
|
# Set IPv6/SSL data.
|
||||||
my $use6 = 0;
|
my $use6 = 0;
|
||||||
my $usessl = 0;
|
my $usessl = 0;
|
||||||
if (defined $cservers{$cskey}{'ipv6'}[0]) { $use6 = $cservers{$cskey}{'ipv6'}[0]; }
|
if (defined $cservers{$cskey}{'ipv6'}[0]) { $use6 = $cservers{$cskey}{'ipv6'}[0]; }
|
||||||
@@ -311,50 +383,50 @@ foreach my $cskey (keys %cservers) {
|
|||||||
|
|
||||||
# Create the socket.
|
# Create the socket.
|
||||||
if ($use6) {
|
if ($use6) {
|
||||||
$SOCKET{$cskey} = IO::Socket::INET6->new(%conndata) or # Or error.
|
$SOCKET{$cskey} = IO::Socket::INET6->new(%conndata) or # Or error.
|
||||||
err(2, 'Failed to connect to server ('.$ERRNO.'): '.$cskey.' ['.$cservers{$cskey}{'host'}[0].q{:}.$cservers{$cskey}{'port'}[0].']', 0)
|
err(2, 'Failed to connect to server ('.$ERRNO.'): '.$cskey.' ['.$cservers{$cskey}{'host'}[0].q{:}.$cservers{$cskey}{'port'}[0].']', 0)
|
||||||
and delete $SOCKET{$cskey} and next;
|
and delete $SOCKET{$cskey} and next;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ($usessl) {
|
if ($usessl) {
|
||||||
$SOCKET{$cskey} = IO::Socket::SSL->new(%conndata) or # Or error.
|
$SOCKET{$cskey} = IO::Socket::SSL->new(%conndata) or # Or error.
|
||||||
err(2, 'Failed to connect to server ('.$ERRNO.'): '.$cskey.' ['.$cservers{$cskey}{'host'}[0].q{:}.$cservers{$cskey}{'port'}[0].']', 0)
|
err(2, 'Failed to connect to server ('.$ERRNO.'): '.$cskey.' ['.$cservers{$cskey}{'host'}[0].q{:}.$cservers{$cskey}{'port'}[0].']', 0)
|
||||||
and delete $SOCKET{$cskey} and next;
|
and delete $SOCKET{$cskey} and next;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$SOCKET{$cskey} = IO::Socket::INET->new(%conndata) or # Or error.
|
$SOCKET{$cskey} = IO::Socket::INET->new(%conndata) or # Or error.
|
||||||
err(2, 'Failed to connect to server ('.$ERRNO.'): '.$cskey.' ['.$cservers{$cskey}{'host'}[0].q{:}.$cservers{$cskey}{'port'}[0].']', 0)
|
err(2, 'Failed to connect to server ('.$ERRNO.'): '.$cskey.' ['.$cservers{$cskey}{'host'}[0].q{:}.$cservers{$cskey}{'port'}[0].']', 0)
|
||||||
and delete $SOCKET{$cskey} and next;
|
and delete $SOCKET{$cskey} and next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Send PASS if we have one.
|
# Send PASS if we have one.
|
||||||
if (defined $cservers{$cskey}{'pass'}[0]) {
|
if (defined $cservers{$cskey}{'pass'}[0]) {
|
||||||
socksnd($cskey, 'PASS :'.$cservers{$cskey}{'pass'}[0]) or
|
socksnd($cskey, 'PASS :'.$cservers{$cskey}{'pass'}[0]) or
|
||||||
err(2, 'Failed to connect to server: '.$cskey.' ['.$cservers{$cskey}{'host'}[0].q{:}.$cservers{$cskey}{'port'}[0].']', 0)
|
err(2, 'Failed to connect to server: '.$cskey.' ['.$cservers{$cskey}{'host'}[0].q{:}.$cservers{$cskey}{'port'}[0].']', 0)
|
||||||
and next;
|
and next;
|
||||||
}
|
}
|
||||||
API::Std::event_run('on_preconnect', $cskey);
|
API::Std::event_run('on_preconnect', $cskey);
|
||||||
# Send NICK/USER.
|
# Send NICK/USER.
|
||||||
API::IRC::nick($cskey, $cservers{$cskey}{'nick'}[0]);
|
API::IRC::nick($cskey, $cservers{$cskey}{'nick'}[0]);
|
||||||
socksnd($cskey, 'USER '.$cservers{$cskey}{'ident'}[0].q{ }.hostname.q{ }.$cservers{$cskey}{'host'}[0].' :'.$cservers{$cskey}{'realname'}[0]) or
|
socksnd($cskey, 'USER '.$cservers{$cskey}{'ident'}[0].q{ }.hostname.q{ }.$cservers{$cskey}{'host'}[0].' :'.$cservers{$cskey}{'realname'}[0]) or
|
||||||
err(2, 'Failed to connect to server: '.$cskey.' ['.$cservers{$cskey}{'host'}[0].q{:}.$cservers{$cskey}{'port'}[0].']', 0)
|
err(2, 'Failed to connect to server: '.$cskey.' ['.$cservers{$cskey}{'host'}[0].q{:}.$cservers{$cskey}{'port'}[0].']', 0)
|
||||||
and next;
|
and next;
|
||||||
# Add to select.
|
# Add to select.
|
||||||
$SELECT->add($SOCKET{$cskey});
|
$SELECT->add($SOCKET{$cskey});
|
||||||
# Success!
|
# Success!
|
||||||
alog '** Successfully connected to server: '.$cskey;
|
alog '** Successfully connected to server: '.$cskey;
|
||||||
dbug '** Successfully connected to server: '.$cskey;
|
dbug '** Successfully connected to server: '.$cskey;
|
||||||
$it = 1;
|
$it = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Success!
|
# Success!
|
||||||
if ($it) {
|
if ($it) {
|
||||||
alog '** Success: Connected to server(s).';
|
alog '** Success: Connected to server(s).';
|
||||||
dbug '** Success: Connected to server(s).';
|
dbug '** Success: Connected to server(s).';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
err(2, 'No server connections.', 1);
|
err(2, 'No server connections.', 1);
|
||||||
}
|
}
|
||||||
undef $it;
|
undef $it;
|
||||||
|
|
||||||
@@ -362,6 +434,7 @@ undef $it;
|
|||||||
API::Std::cmd_add('MODLOAD', 1, 'cfunc.modules', \%Core::Cmd::HELP_MODLOAD, \&Core::Cmd::cmd_modload);
|
API::Std::cmd_add('MODLOAD', 1, 'cfunc.modules', \%Core::Cmd::HELP_MODLOAD, \&Core::Cmd::cmd_modload);
|
||||||
API::Std::cmd_add('MODUNLOAD', 1, 'cfunc.modules', \%Core::Cmd::HELP_MODUNLOAD, \&Core::Cmd::cmd_modunload);
|
API::Std::cmd_add('MODUNLOAD', 1, 'cfunc.modules', \%Core::Cmd::HELP_MODUNLOAD, \&Core::Cmd::cmd_modunload);
|
||||||
API::Std::cmd_add('MODRELOAD', 1, 'cfunc.modules', \%Core::Cmd::HELP_MODRELOAD, \&Core::Cmd::cmd_modreload);
|
API::Std::cmd_add('MODRELOAD', 1, 'cfunc.modules', \%Core::Cmd::HELP_MODRELOAD, \&Core::Cmd::cmd_modreload);
|
||||||
|
API::Std::cmd_add('MODLIST', 1, 'cfunc.modules', \%Core::Cmd::HELP_MODLIST, \&Core::Cmd::cmd_modlist);
|
||||||
API::Std::cmd_add('SHUTDOWN', 2, 'cmd.shutdown', \%Core::Cmd::HELP_SHUTDOWN, \&Core::Cmd::cmd_shutdown);
|
API::Std::cmd_add('SHUTDOWN', 2, 'cmd.shutdown', \%Core::Cmd::HELP_SHUTDOWN, \&Core::Cmd::cmd_shutdown);
|
||||||
API::Std::cmd_add('RESTART', 2, 'cmd.restart', \%Core::Cmd::HELP_RESTART, \&Core::Cmd::cmd_restart);
|
API::Std::cmd_add('RESTART', 2, 'cmd.restart', \%Core::Cmd::HELP_RESTART, \&Core::Cmd::cmd_restart);
|
||||||
API::Std::cmd_add('REHASH', 2, 'cmd.rehash', \%Core::Cmd::HELP_REHASH, \&Core::Cmd::cmd_rehash);
|
API::Std::cmd_add('REHASH', 2, 'cmd.rehash', \%Core::Cmd::HELP_REHASH, \&Core::Cmd::cmd_rehash);
|
||||||
@@ -369,58 +442,66 @@ API::Std::cmd_add('HELP', 2, 0, \%Core::Cmd::HELP_HELP, \&Core::Cmd::cmd_help);
|
|||||||
|
|
||||||
# Infinite while loop.
|
# Infinite while loop.
|
||||||
while (1) {
|
while (1) {
|
||||||
# Timer check.
|
# Timer check.
|
||||||
foreach my $tk (keys %TIMERS) {
|
foreach my $tk (keys %TIMERS) {
|
||||||
if ($TIMERS{$tk}{time} <= time) {
|
if ($TIMERS{$tk}{time} <= time) {
|
||||||
&{ $TIMERS{$tk}{sub} }();
|
&{ $TIMERS{$tk}{sub} }();
|
||||||
if ($TIMERS{$tk}{type} == 1) {
|
if ($TIMERS{$tk}{type} == 1) {
|
||||||
# If it's type 1, delete from memory.
|
# If it's type 1, delete from memory.
|
||||||
delete $TIMERS{$tk};
|
delete $TIMERS{$tk};
|
||||||
}
|
}
|
||||||
elsif ($TIMERS{$tk}{type} == 2) {
|
elsif ($TIMERS{$tk}{type} == 2) {
|
||||||
# If it's type 2, reset timer.
|
# If it's type 2, reset timer.
|
||||||
$TIMERS{$tk}{time} = time + $TIMERS{$tk}{secs};
|
$TIMERS{$tk}{time} = time + $TIMERS{$tk}{secs};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# This should never happen.
|
# This should never happen.
|
||||||
delete $TIMERS{$tk};
|
delete $TIMERS{$tk};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# Socket check.
|
# Socket check.
|
||||||
foreach my $sock ($SELECT->can_read(1)) {
|
foreach my $sock ($SELECT->can_read(1)) {
|
||||||
# Figure out what network is sending us data.
|
# Figure out what network is sending us data.
|
||||||
my $sockid;
|
my $sockid;
|
||||||
foreach (keys %SOCKET) {
|
foreach (keys %SOCKET) {
|
||||||
if ($SOCKET{$_} eq $sock) { $sockid = $_; }
|
if ($SOCKET{$_} eq $sock) { $sockid = $_; }
|
||||||
}
|
}
|
||||||
# Read the data.
|
# Read the data.
|
||||||
my $idata;
|
my $idata;
|
||||||
sysread $sock, $idata, POSIX::BUFSIZ, 0;
|
sysread $sock, $idata, POSIX::BUFSIZ, 0;
|
||||||
|
|
||||||
# Check for the data.
|
# Check for the data.
|
||||||
if (!defined $idata || length($idata) == 0) {
|
if (!defined $idata || length($idata) == 0) {
|
||||||
# Got EOF, close socket
|
# Got EOF, close socket
|
||||||
err(2, "Lost connection to $sockid!", 0);
|
err(2, "Lost connection to $sockid!", 0);
|
||||||
$SELECT->remove($sock);
|
$SELECT->remove($sock);
|
||||||
delete $SOCKET{$sockid};
|
delete $SOCKET{$sockid};
|
||||||
|
if (!keys %SOCKET) {
|
||||||
|
# No more connections, stop the program.
|
||||||
|
API::Std::event_run('on_shutdown');
|
||||||
|
dbug '* No more IRC connections, shutting down.';
|
||||||
|
alog '* No more IRC connections, shutting down.';
|
||||||
|
sleep 1;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Read the buffer.
|
# Read the buffer.
|
||||||
my $data .= $idata;
|
my $data .= $idata;
|
||||||
while ($data =~ s/(.*\n)//) {
|
while ($data =~ s/(.*\n)//) {
|
||||||
my $line = $1;
|
my $line = $1;
|
||||||
|
|
||||||
# Remove the newlines.
|
# Remove the newlines.
|
||||||
chomp $line;
|
chomp $line;
|
||||||
# Debug.
|
# Debug.
|
||||||
dbug $sockid.' >> '.$line;
|
dbug $sockid.' >> '.$line;
|
||||||
|
|
||||||
# Parse data.
|
# Parse data.
|
||||||
Parser::IRC::ircparse($sockid, $line);
|
Parser::IRC::ircparse($sockid, $line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
###############
|
###############
|
||||||
@@ -430,16 +511,16 @@ while (1) {
|
|||||||
# Send data to socket.
|
# Send data to socket.
|
||||||
sub socksnd
|
sub socksnd
|
||||||
{
|
{
|
||||||
my ($svr, $data) = @_;
|
my ($svr, $data) = @_;
|
||||||
|
|
||||||
if (defined $SOCKET{$svr}) {
|
if (defined $SOCKET{$svr}) {
|
||||||
syswrite $SOCKET{$svr}, $data."\n", POSIX::BUFSIZ, 0;
|
syswrite $SOCKET{$svr}, $data."\n", POSIX::BUFSIZ, 0;
|
||||||
dbug "$svr << $data";
|
dbug "$svr << $data";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load a module.
|
# Load a module.
|
||||||
|
|||||||
+40
-1
@@ -8,6 +8,8 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use English qw(-no_match_vars);
|
use English qw(-no_match_vars);
|
||||||
use FindBin qw($Bin);
|
use FindBin qw($Bin);
|
||||||
|
use Pod::Html;
|
||||||
|
use Pod::Man;
|
||||||
our $Bin = $Bin;
|
our $Bin = $Bin;
|
||||||
|
|
||||||
our $VERSION = 1.00;
|
our $VERSION = 1.00;
|
||||||
@@ -103,12 +105,49 @@ foreach (@pars) {
|
|||||||
print 'Checking Perl version..... '.$PERL_VERSION.' - ';
|
print 'Checking Perl version..... '.$PERL_VERSION.' - ';
|
||||||
if ($] < $val) { $die = 1; }
|
if ($] < $val) { $die = 1; }
|
||||||
say (($die) ? 'Not OK' : 'OK');
|
say (($die) ? 'Not OK' : 'OK');
|
||||||
print $RS;
|
|
||||||
if ($die) { say 'Failed to build '.$module.'.'; exit; }
|
if ($die) { say 'Failed to build '.$module.'.'; exit; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Generate documentation.
|
||||||
|
my $got_end = 0;
|
||||||
|
open my $FMPH, '<', $modulep;
|
||||||
|
my @MPBUF = <$FMPH>;
|
||||||
|
close $FMPH;
|
||||||
|
|
||||||
|
say 'Generating documentation.....';
|
||||||
|
my $podbuf;
|
||||||
|
foreach my $line (@MPBUF) {
|
||||||
|
if (!defined $line) { $line = ' '; }
|
||||||
|
$line =~ s/(\r|\n)//g;
|
||||||
|
|
||||||
|
if ($line eq '__END__') {
|
||||||
|
$got_end = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($got_end and $line ne '__END__') {
|
||||||
|
$podbuf .= $line."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the autodoc/ dir if it doesn't exist.
|
||||||
|
if (!-d "$Bin/../autodoc") {
|
||||||
|
mkdir "$Bin/../autodoc";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Save to POD file in autodoc/
|
||||||
|
open my $FMPNH, '>', "$Bin/../autodoc/$module.pod";
|
||||||
|
print {$FMPNH} $podbuf;
|
||||||
|
close $FMPNH;
|
||||||
|
|
||||||
|
# Create HTML.
|
||||||
|
pod2html("--infile=$Bin/../autodoc/$module.pod", "--outfile=$Bin/../autodoc/$module.html");
|
||||||
|
# Create *roff.
|
||||||
|
my $manifier = Pod::Man->new();
|
||||||
|
$manifier->parse_from_file("$Bin/../autodoc/$module.pod", "$Bin/../autodoc/$module.1");
|
||||||
|
|
||||||
|
print $RS;
|
||||||
say 'Done.';
|
say 'Done.';
|
||||||
|
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
@@ -2,6 +2,50 @@ Auto IRC Bot 3.0: Change Log
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
3.0 Indev
|
3.0 Indev
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Fixed broken rehash.
|
||||||
|
* Ignore PRIVMSG's if they're from an invalid source.
|
||||||
|
* Fixed an odd bug when viewing non-existent quotes.
|
||||||
|
* You can now define how many results are returned by QDB SEARCH/MORE at a
|
||||||
|
time with qdb_search_resnum in the config.
|
||||||
|
* Added SEARCH and MORE to QDB.
|
||||||
|
* Killed EMODS in the starter script and updated MODS
|
||||||
|
* Added core command MODLIST.
|
||||||
|
* Added command level 3 for logchan-only command.
|
||||||
|
* Added a LinkTitle module for getting the title of a web page posted in a
|
||||||
|
channel.
|
||||||
|
|
||||||
|
3.0 Alpha 4
|
||||||
|
===============================================================================
|
||||||
|
* Added a Dictionary module for looking up definitions of words.
|
||||||
|
* server:ajoin now supports channel keys by spacing the name and key.
|
||||||
|
* Hooks can now block events by returning -1.
|
||||||
|
* bin/buildmod now retrieves the POD from modules and creates man(1) page
|
||||||
|
plus HTML file.
|
||||||
|
* cjoin() now supports a channel key as the last argument.
|
||||||
|
* Added a ChanTopics module for advanced management of channel topics.
|
||||||
|
* bantype is now a required configuration value.
|
||||||
|
* Added ban() to API::IRC.
|
||||||
|
* Changed on_cprivmsg arguments to: \%src, $channel, @msg
|
||||||
|
* Changed on_uprivmsg arguments to: \%src, @msg
|
||||||
|
* Bug fix: Commands getting Permission denied even with incorrect prefix.
|
||||||
|
* Changed command callback arguments to: \%src, @args
|
||||||
|
* Bundle server with \%src in the on_rcjoin event.
|
||||||
|
* logchan is now joined automatically.
|
||||||
|
* Changed on_notice arguments to: \%src, $target, @msg
|
||||||
|
* Clean up shutdown.
|
||||||
|
* Created event on_shutdown.
|
||||||
|
* Shutdown if there are no more IRC connections.
|
||||||
|
* Added the ability to use printf(3) % variables in trans().
|
||||||
|
* Added slog() to API::Log for logging to IRC.
|
||||||
|
* Added a Greet module for greeting users on join.
|
||||||
|
* Added PostgreSQL support. Official modules do not support this yet.
|
||||||
|
* database:format now a required configuration value.
|
||||||
|
* Added support for MySQL. ./install --with-mysql
|
||||||
|
* Added a database upgrade script for upgrading the `qdb` table in 3.0.0a3
|
||||||
|
to the new format used by 3.0.0a4.
|
||||||
|
|
||||||
|
3.0 Alpha 3
|
||||||
===============================================================================
|
===============================================================================
|
||||||
* Added command rate limiting.
|
* Added command rate limiting.
|
||||||
* Added module installer to ./install.
|
* Added module installer to ./install.
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ Legend:
|
|||||||
? = Being questioned.
|
? = Being questioned.
|
||||||
+ = Planned for Auto v3.1.
|
+ = Planned for Auto v3.1.
|
||||||
|
|
||||||
|
[ ] Cleanup
|
||||||
|
[ ] Replace println with Perl 5.10's say.
|
||||||
|
|
||||||
[X] Language
|
[X] Language
|
||||||
[X] Create method of translation.
|
[X] Create method of translation.
|
||||||
@@ -21,15 +23,17 @@ Legend:
|
|||||||
[X] Create basic modular functions
|
[X] Create basic modular functions
|
||||||
[X] Create logging functions
|
[X] Create logging functions
|
||||||
[X] Create command creation functions
|
[X] Create command creation functions
|
||||||
[!] Create user permissions (levels)
|
|
||||||
|
|
||||||
[!] IRC
|
[!] IRC
|
||||||
[X] Create IRC parser
|
[X] Create IRC parser
|
||||||
|
|
||||||
[!] DB
|
[!] DB
|
||||||
[X] Create Auto-Flatfile database format
|
[O] Create Auto-Flatfile database format
|
||||||
[X] Implement Auto-Flatfile as the main format
|
[O] Implement Auto-Flatfile as the main format
|
||||||
[ ] Add MySQL support
|
[X] Add SQLite support as default
|
||||||
|
[x] Add MySQL support
|
||||||
|
[X] Add PostgreSQL support
|
||||||
|
[O] Add Oracle DB support
|
||||||
|
|
||||||
[O] Sys
|
[O] Sys
|
||||||
[ ] Create system file for UNIX (or: Linux, BSD, etc.)
|
[ ] Create system file for UNIX (or: Linux, BSD, etc.)
|
||||||
@@ -42,7 +46,7 @@ Legend:
|
|||||||
[ ] Google Search module
|
[ ] Google Search module
|
||||||
[ ] IRC Relay module
|
[ ] IRC Relay module
|
||||||
[ ] (Google?) News module
|
[ ] (Google?) News module
|
||||||
[ ] QDB module
|
[X] QDB module
|
||||||
[ ] Tumblr module
|
[ ] Tumblr module
|
||||||
[X] Google Calculator module
|
[X] Google Calculator module
|
||||||
[ ] YouTube Search module
|
[ ] YouTube Search module
|
||||||
|
|||||||
@@ -86,10 +86,30 @@ user "#bot-ops" {
|
|||||||
privs "op";
|
privs "op";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Database.
|
||||||
|
database {
|
||||||
|
# Format. This can be one of the following:
|
||||||
|
# sqlite Requires database:filename. Recommended.
|
||||||
|
# mysql Requires database:name,host,username,password and that Auto be built with --with-mysql. Optional: database:port
|
||||||
|
# pgsql Requires database:name,host,username,password and that Auto be built with --with-pgsql. Optional: database:port
|
||||||
|
format "sqlite";
|
||||||
|
|
||||||
|
# If you chose SQLite, uncomment this and choose a filename.
|
||||||
|
# filename "somebot.db";
|
||||||
|
|
||||||
|
# If you chose MySQL or PostgreSQL, uncomment these and set them.
|
||||||
|
# name "auto";
|
||||||
|
# host "localhost";
|
||||||
|
# username "root";
|
||||||
|
# password "moocows";
|
||||||
|
}
|
||||||
|
|
||||||
# Locale.
|
# Locale.
|
||||||
locale "en_US";
|
locale "en_US";
|
||||||
|
|
||||||
|
# Logging to IRC. Uncomment this and set it to setup an IRC logchan.
|
||||||
|
# logchan "Freenode/#logchan";
|
||||||
|
|
||||||
# Expire logs in days. 0 disables.
|
# Expire logs in days. 0 disables.
|
||||||
expire_logs 15;
|
expire_logs 15;
|
||||||
|
|
||||||
@@ -103,6 +123,14 @@ ratelimit_time 6;
|
|||||||
# How many commands can be used by a user in each period.
|
# How many commands can be used by a user in each period.
|
||||||
ratelimit_amount 3;
|
ratelimit_amount 3;
|
||||||
|
|
||||||
|
# Type of ban.
|
||||||
|
# 1 - *!*@h
|
||||||
|
# 2 - n!*@*
|
||||||
|
# 3 - *!u@h
|
||||||
|
# 4 - n!*u@h
|
||||||
|
# 5 - *!*@*.h+
|
||||||
|
bantype 1;
|
||||||
|
|
||||||
# Module autoload.
|
# Module autoload.
|
||||||
module "HelloChan";
|
module "HelloChan";
|
||||||
|
|
||||||
|
|||||||
@@ -17,30 +17,36 @@ our $VERSION = 1.00;
|
|||||||
our $ERROR = 0;
|
our $ERROR = 0;
|
||||||
|
|
||||||
# Iterate through the arguments passed to us.
|
# Iterate through the arguments passed to us.
|
||||||
my $features = "base ssl";
|
my $features = 'base ssl sqlite';
|
||||||
if (defined $ARGV[0]) {
|
if (defined $ARGV[0]) {
|
||||||
foreach (@ARGV) {
|
foreach (@ARGV) {
|
||||||
if ($_ eq "-h" or $_ eq "--help") {
|
if ($_ eq '-h' or $_ eq '--help') {
|
||||||
println "*** ./install help ***";
|
println '*** ./install help ***';
|
||||||
println " --enable-sasl - Enable support for SASL.";
|
println ' --enable-sasl - Enable support for SASL.';
|
||||||
println " --enable-ipv6 - Enable support for IPv6.";
|
println ' --enable-ipv6 - Enable support for IPv6.';
|
||||||
println " --disable-ssl - Disable support for SSL.";
|
println ' --disable-ssl - Disable support for SSL.';
|
||||||
println "*** End of Help ***";
|
println '*** End of Help ***';
|
||||||
exit;
|
exit 1;
|
||||||
}
|
}
|
||||||
elsif ($_ eq "--enable-sasl") {
|
elsif ($_ eq '--enable-sasl') {
|
||||||
$features .= " sasl";
|
$features .= ' sasl';
|
||||||
}
|
}
|
||||||
elsif ($_ eq "--disable-ssl") {
|
elsif ($_ eq '--disable-ssl') {
|
||||||
$features =~ s/ ssl//g;
|
$features =~ s/ ssl//g;
|
||||||
}
|
}
|
||||||
elsif ($_ eq "--enable-ipv6") {
|
elsif ($_ eq '--enable-ipv6') {
|
||||||
$features .= " ipv6";
|
$features .= ' ipv6';
|
||||||
}
|
}
|
||||||
else {
|
elsif ($_ eq '--with-mysql') {
|
||||||
println "Warning: Unknown option '".$_."'";
|
$features =~ s/(sqlite|pgsql)/mysql/g;
|
||||||
}
|
}
|
||||||
}
|
elsif ($_ eq '--with-pgsql') {
|
||||||
|
$features =~ s/(sqlite|mysql)/pgsql/g;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println "Warning: Unknown option '$_'";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check Perl version.
|
# Check Perl version.
|
||||||
@@ -52,32 +58,32 @@ eval {
|
|||||||
# Check operating system.
|
# Check operating system.
|
||||||
print "Checking operating system..... $OSNAME - ";
|
print "Checking operating system..... $OSNAME - ";
|
||||||
if ($OSNAME =~ /dos/i) {
|
if ($OSNAME =~ /dos/i) {
|
||||||
print "DOS is not supported.\r\n";
|
print "DOS is not supported.\r\n";
|
||||||
}
|
}
|
||||||
elsif ($OSNAME eq "MSWin32") {
|
elsif ($OSNAME eq "MSWin32") {
|
||||||
print "Microsoft Windows is not supported. Support is planned for the future.\r\n";
|
print "Microsoft Windows is not supported. Support is planned for the future.\r\n";
|
||||||
}
|
}
|
||||||
elsif ($OSNAME eq "NetWare") {
|
elsif ($OSNAME eq "NetWare") {
|
||||||
print "NetWare is not supported.\r\n";
|
print "NetWare is not supported.\r\n";
|
||||||
}
|
}
|
||||||
elsif ($OSNAME eq "linux") {
|
elsif ($OSNAME eq "linux") {
|
||||||
print "OK\n";
|
print "OK\n";
|
||||||
}
|
}
|
||||||
elsif ($OSNAME eq "os2") {
|
elsif ($OSNAME eq "os2") {
|
||||||
print "IBM OS/2 is not supported.\r\n";
|
print "IBM OS/2 is not supported.\r\n";
|
||||||
}
|
}
|
||||||
elsif ($OSNAME =~ /mac/i or $OSNAME =~ /darwin/i) {
|
elsif ($OSNAME =~ /mac/i or $OSNAME =~ /darwin/i) {
|
||||||
print "OK\r";
|
print "OK\r";
|
||||||
}
|
}
|
||||||
elsif ($OSNAME eq "freebsd") {
|
elsif ($OSNAME eq "freebsd") {
|
||||||
print "OK\n";
|
print "OK\n";
|
||||||
}
|
}
|
||||||
elsif ($OSNAME eq "openbsd") {
|
elsif ($OSNAME eq "openbsd") {
|
||||||
print "OK\n";
|
print "OK\n";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print "Unknown operating system. Contact support.\r\n";
|
print "Unknown operating system. Contact support.\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check for Perl core modules.
|
# Check for Perl core modules.
|
||||||
println "Checking for core Perl modules.....";
|
println "Checking for core Perl modules.....";
|
||||||
@@ -97,7 +103,9 @@ println 'Checking for required CPAN modules......';
|
|||||||
println "\0";
|
println "\0";
|
||||||
#modfind("Mouse");
|
#modfind("Mouse");
|
||||||
modfind('DBI');
|
modfind('DBI');
|
||||||
modfind('DBD::SQLite');
|
modfind('DBD::SQLite') if $features =~ /sqlite/;
|
||||||
|
modfind('DBD::mysql') if $features =~ /mysql/;
|
||||||
|
modfind('DBD::Pg') if $features =~ /pgsql/;
|
||||||
modfind('Class::Unload');
|
modfind('Class::Unload');
|
||||||
modfind('IO::Socket::INET6') if $features =~ /ipv6/;
|
modfind('IO::Socket::INET6') if $features =~ /ipv6/;
|
||||||
modfind('IO::Socket::SSL') if $features =~ /ssl/;
|
modfind('IO::Socket::SSL') if $features =~ /ssl/;
|
||||||
@@ -116,19 +124,19 @@ else {
|
|||||||
println "\0";
|
println "\0";
|
||||||
println "Building.....";
|
println "Building.....";
|
||||||
if (!-d "$Bin/build") {
|
if (!-d "$Bin/build") {
|
||||||
system "mkdir $Bin/build";
|
system "mkdir $Bin/build";
|
||||||
}
|
}
|
||||||
if (!-e "$Bin/build/time") {
|
if (!-e "$Bin/build/time") {
|
||||||
system "touch $Bin/build/time";
|
system "touch $Bin/build/time";
|
||||||
}
|
}
|
||||||
if (!-e "$Bin/build/os") {
|
if (!-e "$Bin/build/os") {
|
||||||
system "touch $Bin/build/os";
|
system "touch $Bin/build/os";
|
||||||
}
|
}
|
||||||
if (!-e "$Bin/build/perl") {
|
if (!-e "$Bin/build/perl") {
|
||||||
system "touch $Bin/build/perl";
|
system "touch $Bin/build/perl";
|
||||||
}
|
}
|
||||||
if (!-e "$Bin/build/ver") {
|
if (!-e "$Bin/build/ver") {
|
||||||
system "touch $Bin/build/ver";
|
system "touch $Bin/build/ver";
|
||||||
}
|
}
|
||||||
|
|
||||||
build($features);
|
build($features);
|
||||||
|
|||||||
+125
-91
@@ -4,78 +4,112 @@
|
|||||||
package API::IRC;
|
package API::IRC;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
use feature qw(switch);
|
||||||
use Exporter;
|
use Exporter;
|
||||||
|
|
||||||
our @ISA = qw(Exporter);
|
our @ISA = qw(Exporter);
|
||||||
our @EXPORT_OK = qw(cjoin cpart cmode umode kick privmsg notice quit nick names topic
|
our @EXPORT_OK = qw(ban cjoin cpart cmode umode kick privmsg notice quit nick names
|
||||||
usrc match_mask);
|
topic usrc match_mask);
|
||||||
|
|
||||||
|
|
||||||
|
# Set a ban, based on config bantype value.
|
||||||
|
sub ban
|
||||||
|
{
|
||||||
|
my ($svr, $chan, $type, $user) = @_;
|
||||||
|
my $cbt = (API::Std::conf_get('bantype'))[0][0];
|
||||||
|
|
||||||
|
# Prepare the mask we're going to ban.
|
||||||
|
my $mask;
|
||||||
|
given ($cbt) {
|
||||||
|
when (1) { $mask = '*!*@'.$user->{host}; }
|
||||||
|
when (2) { $mask = $user->{nick}.'!*@*'; }
|
||||||
|
when (3) { $mask = '*!'.$user->{user}.'@'.$user->{host}; }
|
||||||
|
when (4) { $mask = $user->{nick}.'!*'.$user->{user}.'@'.$user->{host}; }
|
||||||
|
when (5) {
|
||||||
|
my @hd = split m/[\.]/, $user->{host};
|
||||||
|
shift @hd;
|
||||||
|
$mask = '*!*@*.'.join ' ', @hd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now set the ban.
|
||||||
|
if (lc $type eq 'b') {
|
||||||
|
# We were requested to set a regular ban.
|
||||||
|
cmode($svr, $chan, "+b $mask");
|
||||||
|
}
|
||||||
|
elsif (lc $type eq 'q') {
|
||||||
|
# We were requested to set a ratbox-style quiet.
|
||||||
|
cmode($svr, $chan, "+q $mask");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
# Join a channel.
|
# Join a channel.
|
||||||
sub cjoin
|
sub cjoin
|
||||||
{
|
{
|
||||||
my ($svr, $chan) = @_;
|
my ($svr, $chan, $key) = @_;
|
||||||
|
|
||||||
Auto::socksnd($svr, "JOIN $chan");
|
Auto::socksnd($svr, "JOIN ".((defined $key) ? "$chan $key" : "$chan"));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Part a channel.
|
# Part a channel.
|
||||||
sub cpart
|
sub cpart
|
||||||
{
|
{
|
||||||
my ($svr, $chan, $reason) = @_;
|
my ($svr, $chan, $reason) = @_;
|
||||||
|
|
||||||
if (defined $reason) {
|
if (defined $reason) {
|
||||||
Auto::socksnd($svr, "PART $chan :$reason");
|
Auto::socksnd($svr, "PART $chan :$reason");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Auto::socksnd($svr, "PART $chan :Leaving");
|
Auto::socksnd($svr, "PART $chan :Leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined $Parser::IRC::botchans{$svr}{$chan}) { delete $Parser::IRC::botchans{$svr}{$chan}; }
|
if (defined $Parser::IRC::botchans{$svr}{$chan}) { delete $Parser::IRC::botchans{$svr}{$chan}; }
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set mode(s) on a channel.
|
# Set mode(s) on a channel.
|
||||||
sub cmode
|
sub cmode
|
||||||
{
|
{
|
||||||
my ($svr, $chan, $modes) = @_;
|
my ($svr, $chan, $modes) = @_;
|
||||||
|
|
||||||
Auto::socksnd($svr, "MODE $chan $modes");
|
Auto::socksnd($svr, "MODE $chan $modes");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set mode(s) on us.
|
# Set mode(s) on us.
|
||||||
sub umode
|
sub umode
|
||||||
{
|
{
|
||||||
my ($svr, $modes) = @_;
|
my ($svr, $modes) = @_;
|
||||||
|
|
||||||
Auto::socksnd($svr, "MODE ".$Parser::IRC::botnick{$svr}{nick}." $modes");
|
Auto::socksnd($svr, "MODE ".$Parser::IRC::botnick{$svr}{nick}." $modes");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Send a PRIVMSG.
|
# Send a PRIVMSG.
|
||||||
sub privmsg
|
sub privmsg
|
||||||
{
|
{
|
||||||
my ($svr, $target, $message) = @_;
|
my ($svr, $target, $message) = @_;
|
||||||
|
|
||||||
Auto::socksnd($svr, "PRIVMSG $target :$message");
|
Auto::socksnd($svr, "PRIVMSG $target :$message");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Send a NOTICE.
|
# Send a NOTICE.
|
||||||
sub notice
|
sub notice
|
||||||
{
|
{
|
||||||
my ($svr, $target, $message) = @_;
|
my ($svr, $target, $message) = @_;
|
||||||
|
|
||||||
Auto::socksnd($svr, "NOTICE $target :$message");
|
Auto::socksnd($svr, "NOTICE $target :$message");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Send an ACTION PRIVMSG.
|
# Send an ACTION PRIVMSG.
|
||||||
@@ -91,33 +125,33 @@ sub act
|
|||||||
# Change bot nickname.
|
# Change bot nickname.
|
||||||
sub nick
|
sub nick
|
||||||
{
|
{
|
||||||
my ($svr, $newnick) = @_;
|
my ($svr, $newnick) = @_;
|
||||||
|
|
||||||
Auto::socksnd($svr, "NICK $newnick");
|
Auto::socksnd($svr, "NICK $newnick");
|
||||||
|
|
||||||
$Parser::IRC::botnick{$svr}{newnick} = $newnick;
|
$Parser::IRC::botnick{$svr}{newnick} = $newnick;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Request the users of a channel.
|
# Request the users of a channel.
|
||||||
sub names
|
sub names
|
||||||
{
|
{
|
||||||
my ($svr, $chan) = @_;
|
my ($svr, $chan) = @_;
|
||||||
|
|
||||||
Auto::socksnd($svr, "NAMES $chan");
|
Auto::socksnd($svr, "NAMES $chan");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Send a topic to the channel.
|
# Send a topic to the channel.
|
||||||
sub topic
|
sub topic
|
||||||
{
|
{
|
||||||
my ($svr, $chan, $topic) = @_;
|
my ($svr, $chan, $topic) = @_;
|
||||||
|
|
||||||
Auto::socksnd($svr, "TOPIC $chan :$topic");
|
Auto::socksnd($svr, "TOPIC $chan :$topic");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Kick a user.
|
# Kick a user.
|
||||||
@@ -125,7 +159,7 @@ sub kick
|
|||||||
{
|
{
|
||||||
my ($svr, $chan, $nick, $msg) = @_;
|
my ($svr, $chan, $nick, $msg) = @_;
|
||||||
|
|
||||||
Auto::socksnd($svr, "KICK $chan $nick :$msg");
|
Auto::socksnd($svr, "KICK $chan $nick :".((defined $msg) ? $msg : 'No reason'));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -133,54 +167,54 @@ sub kick
|
|||||||
# Quit IRC.
|
# Quit IRC.
|
||||||
sub quit
|
sub quit
|
||||||
{
|
{
|
||||||
my ($svr, $reason) = @_;
|
my ($svr, $reason) = @_;
|
||||||
|
|
||||||
if (defined $reason) {
|
if (defined $reason) {
|
||||||
Auto::socksnd($svr, "QUIT :$reason");
|
Auto::socksnd($svr, "QUIT :$reason");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Auto::socksnd($svr, "QUIT :Leaving");
|
Auto::socksnd($svr, "QUIT :Leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
delete $Parser::IRC::got_001{$svr} if (defined $Parser::IRC::got_001{$svr});
|
delete $Parser::IRC::got_001{$svr} if (defined $Parser::IRC::got_001{$svr});
|
||||||
delete $Parser::IRC::botnick{$svr} if (defined $Parser::IRC::botnick{$svr});
|
delete $Parser::IRC::botnick{$svr} if (defined $Parser::IRC::botnick{$svr});
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Get nick, ident and host from a <nick>!<ident>@<host>
|
# Get nick, ident and host from a <nick>!<ident>@<host>
|
||||||
sub usrc
|
sub usrc
|
||||||
{
|
{
|
||||||
my ($ex) = @_;
|
my ($ex) = @_;
|
||||||
|
|
||||||
my @si = split('!', $ex);
|
my @si = split('!', $ex);
|
||||||
my @sii = split('@', $si[1]);
|
my @sii = split('@', $si[1]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
nick => $si[0],
|
nick => $si[0],
|
||||||
user => $sii[0],
|
user => $sii[0],
|
||||||
host => $sii[1]
|
host => $sii[1]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Match two IRC masks.
|
# Match two IRC masks.
|
||||||
sub match_mask
|
sub match_mask
|
||||||
{
|
{
|
||||||
my ($mu, $mh) = @_;
|
my ($mu, $mh) = @_;
|
||||||
|
|
||||||
# Prepare the regex.
|
# Prepare the regex.
|
||||||
$mh =~ s/\./\\\./g;
|
$mh =~ s/\./\\\./g;
|
||||||
$mh =~ s/\?/\./g;
|
$mh =~ s/\?/\./g;
|
||||||
$mh =~ s/\*/\.\*/g;
|
$mh =~ s/\*/\.\*/g;
|
||||||
$mh = '^'.$mh.'$';
|
$mh = '^'.$mh.'$';
|
||||||
|
|
||||||
# Let's grep the user's mask.
|
# Let's grep the user's mask.
|
||||||
if (grep(/$mh/, $mu)) {
|
if (grep(/$mh/, $mu)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+90
-56
@@ -4,6 +4,7 @@
|
|||||||
package API::Log;
|
package API::Log;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
use feature qw(say);
|
||||||
use English qw(-no_match_vars);
|
use English qw(-no_match_vars);
|
||||||
use POSIX;
|
use POSIX;
|
||||||
use Time::Local;
|
use Time::Local;
|
||||||
@@ -11,17 +12,17 @@ use Exporter;
|
|||||||
use base qw(Exporter);
|
use base qw(Exporter);
|
||||||
use API::Std qw(conf_get);
|
use API::Std qw(conf_get);
|
||||||
|
|
||||||
our @EXPORT_OK = qw(println dbug alog);
|
our @EXPORT_OK = qw(println dbug alog slog);
|
||||||
|
|
||||||
|
|
||||||
# Print with the system newline appended.
|
# Print with the system newline appended.
|
||||||
sub println
|
sub println
|
||||||
{
|
{
|
||||||
my ($out) = @_;
|
my ($out) = @_;
|
||||||
|
|
||||||
if (!defined $out) {
|
if (!defined $out) {
|
||||||
print $RS;
|
print $RS;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print $out.$RS;
|
print $out.$RS;
|
||||||
}
|
}
|
||||||
@@ -32,81 +33,114 @@ sub println
|
|||||||
# Print only if in debug mode.
|
# Print only if in debug mode.
|
||||||
sub dbug
|
sub dbug
|
||||||
{
|
{
|
||||||
my ($out) = @_;
|
my ($out) = @_;
|
||||||
|
|
||||||
if ($Auto::DEBUG) {
|
if ($Auto::DEBUG) {
|
||||||
# We're in debug mode; print it out.
|
# We're in debug mode; print it out.
|
||||||
println $out;
|
say $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Log to file.
|
# Log to file.
|
||||||
sub alog
|
sub alog
|
||||||
{
|
{
|
||||||
my ($lmsg) = @_;
|
my ($lmsg) = @_;
|
||||||
|
|
||||||
# Expire old logs first.
|
# Expire old logs first.
|
||||||
expire_logs();
|
expire_logs();
|
||||||
|
|
||||||
# Get date and time in the desired format.
|
# Get date and time in the desired format.
|
||||||
my $date = POSIX::strftime('%Y%m%d', localtime);
|
my $date = POSIX::strftime('%Y%m%d', localtime);
|
||||||
my $time = POSIX::strftime('%Y-%m-%d %I:%M:%S %p', localtime);
|
my $time = POSIX::strftime('%Y-%m-%d %I:%M:%S %p', localtime);
|
||||||
|
|
||||||
# Create var/ if it doesn't exist.
|
# Create var/ if it doesn't exist.
|
||||||
if (!-d "$Auto::Bin/../var") {
|
if (!-d "$Auto::Bin/../var") {
|
||||||
mkdir "$Auto::Bin/../var", 0600; ## no critic qw(ValuesAndExpressions::ProhibitMagicNumbers)
|
mkdir "$Auto::Bin/../var", 0600; ## no critic qw(ValuesAndExpressions::ProhibitMagicNumbers)
|
||||||
}
|
}
|
||||||
# Create var/DATE.log if it doesn't exist.
|
# Create var/DATE.log if it doesn't exist.
|
||||||
if (!-e "$Auto::Bin/../var/$date.log") {
|
if (!-e "$Auto::Bin/../var/$date.log") {
|
||||||
system "touch $Auto::Bin/../var/$date.log";
|
system "touch $Auto::Bin/../var/$date.log";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Open the logfile, print the log message to it and close it.
|
# Open the logfile, print the log message to it and close it.
|
||||||
open my $FLOG, '>>', "$Auto::Bin/../var/$date.log" or return;
|
open my $FLOG, '>>', "$Auto::Bin/../var/$date.log" or return;
|
||||||
print {$FLOG} "[$time] $lmsg\n" or return;
|
print {$FLOG} "[$time] $lmsg\n" or return;
|
||||||
close $FLOG or return;
|
close $FLOG or return;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Expire old logs.
|
# Expire old logs.
|
||||||
sub expire_logs
|
sub expire_logs
|
||||||
{
|
{
|
||||||
# Get configuration value.
|
# Get configuration value.
|
||||||
my $celog = (conf_get('expire_logs'))[0][0] or return;
|
my $celog = (conf_get('expire_logs'))[0][0] or return;
|
||||||
|
|
||||||
# Check for invalid values.
|
# Check for invalid values.
|
||||||
if ($celog =~ m/[^0-9]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
if ($celog =~ m/[^0-9]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
||||||
# Must be numbers only.
|
# Must be numbers only.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
elsif (!$celog) {
|
elsif (!$celog) {
|
||||||
# No expire.
|
# No expire.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Iterate through each logfile.
|
# Iterate through each logfile.
|
||||||
foreach my $file (glob "$Auto::Bin/../var/*") {
|
foreach my $file (glob "$Auto::Bin/../var/*") {
|
||||||
my (undef, $file) = split 'bin/../var/', $file; ## no critic qw(BuiltinFunctions::ProhibitStringySplit)
|
my (undef, $file) = split 'bin/../var/', $file; ## no critic qw(BuiltinFunctions::ProhibitStringySplit)
|
||||||
|
|
||||||
# Convert filename to UNIX time.
|
# Convert filename to UNIX time.
|
||||||
my $yyyy = substr $file, 0, 4; ## no critic qw(ValuesAndExpressions::ProhibitMagicNumbers)
|
my $yyyy = substr $file, 0, 4; ## no critic qw(ValuesAndExpressions::ProhibitMagicNumbers)
|
||||||
my $mm = substr $file, 4, 2; ## no critic qw(ValuesAndExpressions::ProhibitMagicNumbers)
|
my $mm = substr $file, 4, 2; ## no critic qw(ValuesAndExpressions::ProhibitMagicNumbers)
|
||||||
$mm = $mm - 1;
|
$mm = $mm - 1;
|
||||||
my $dd = substr $file, 6, 2; ## no critic qw(ValuesAndExpressions::ProhibitMagicNumbers)
|
my $dd = substr $file, 6, 2; ## no critic qw(ValuesAndExpressions::ProhibitMagicNumbers)
|
||||||
my $epoch = timelocal(0, 0, 0, $dd, $mm, $yyyy);
|
my $epoch = timelocal(0, 0, 0, $dd, $mm, $yyyy);
|
||||||
|
|
||||||
# If it's older than <config_value> days, delete it.
|
# If it's older than <config_value> days, delete it.
|
||||||
if (time - $epoch > 86_400 * $celog) { ## no critic qw(ValuesAndExpressions::ProhibitMagicNumbers)
|
if (time - $epoch > 86_400 * $celog) { ## no critic qw(ValuesAndExpressions::ProhibitMagicNumbers)
|
||||||
unlink "$Auto::Bin/../var/$file";
|
unlink "$Auto::Bin/../var/$file";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Subroutine for logging to an IRC logchan.
|
||||||
|
sub slog
|
||||||
|
{
|
||||||
|
my ($msg) = @_;
|
||||||
|
|
||||||
|
# Check if logging to channel is enabled.
|
||||||
|
if (conf_get('logchan')) {
|
||||||
|
# It is, continue.
|
||||||
|
|
||||||
|
# Split the network and channel.
|
||||||
|
my ($net, $chan) = split '/', (conf_get('logchan'))[0][0];
|
||||||
|
$chan = lc $chan;
|
||||||
|
|
||||||
|
# Check if we're connected to the network.
|
||||||
|
if (!defined $Auto::SOCKET{$net}) {
|
||||||
|
dbug 'WARNING: slog(): Unable to log to IRC: Not connected to network.';
|
||||||
|
alog 'WARNING: slog(): Unable to log to IRC: Not connected to network.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if we're in the channel.
|
||||||
|
if (!defined $Parser::IRC::botchans{$net}{$chan}) {
|
||||||
|
dbug 'WARNING: slog(): Unable to log to IRC: Not in channel.';
|
||||||
|
alog 'WARNING: slog(): Unable to log to IRC: Not in channel.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Log to IRC.
|
||||||
|
API::IRC::privmsg($net, $chan, "\002LOG:\002 $msg");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
+283
-264
@@ -4,234 +4,244 @@
|
|||||||
package API::Std;
|
package API::Std;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
use feature qw(say);
|
||||||
use Exporter;
|
use Exporter;
|
||||||
use base qw(Exporter);
|
use base qw(Exporter);
|
||||||
|
|
||||||
|
|
||||||
our (%LANGE, %MODULE, %EVENTS, %HOOKS, %CMDS);
|
our (%LANGE, %MODULE, %EVENTS, %HOOKS, %CMDS);
|
||||||
our @EXPORT_OK = qw(conf_get trans err awarn timer_add timer_del cmd_add
|
our @EXPORT_OK = qw(conf_get trans err awarn timer_add timer_del cmd_add
|
||||||
cmd_del hook_add hook_del rchook_add rchook_del match_user
|
cmd_del hook_add hook_del rchook_add rchook_del match_user
|
||||||
has_priv mod_exists ratelimit_check);
|
has_priv mod_exists ratelimit_check);
|
||||||
|
|
||||||
|
|
||||||
# Initialize a module.
|
# Initialize a module.
|
||||||
sub mod_init
|
sub mod_init
|
||||||
{
|
{
|
||||||
my ($name, $author, $version, $autover, $pkg) = @_;
|
my ($name, $author, $version, $autover, $pkg) = @_;
|
||||||
|
|
||||||
# Log/debug.
|
# Log/debug.
|
||||||
API::Log::dbug('MODULES: Attempting to load '.$name.' (version '.$version.') by '.$author.'...');
|
API::Log::dbug('MODULES: Attempting to load '.$name.' (version '.$version.') by '.$author.'...');
|
||||||
API::Log::alog('MODULES: Attempting to load '.$name.' (version '.$version.') by '.$author.'...');
|
API::Log::alog('MODULES: Attempting to load '.$name.' (version '.$version.') by '.$author.'...');
|
||||||
|
if (keys %Auto::SOCKET) { API::Log::slog('MODULES: Attempting to load '.$name.' (version '.$version.') by '.$author.'...'); }
|
||||||
|
|
||||||
# Check if this module is compatible with this version of Auto.
|
# Check if this module is compatible with this version of Auto.
|
||||||
if ($autover ne '3.0.0d') {
|
if ($autover ne '3.0.0a4' and $autover ne '3.0.0a5') {
|
||||||
API::Log::dbug('MODULES: Failed to load '.$name.': Incompatible with your version of Auto.');
|
API::Log::dbug('MODULES: Failed to load '.$name.': Incompatible with your version of Auto.');
|
||||||
API::Log::alog('MODULES: Failed to load '.$name.': Incompatible with your version of Auto.');
|
API::Log::alog('MODULES: Failed to load '.$name.': Incompatible with your version of Auto.');
|
||||||
return;
|
if (keys %Auto::SOCKET) { API::Log::slog('MODULES: Failed to load '.$name.': Incompatible with your version of Auto.'); }
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
# Run the module's _init sub.
|
# Run the module's _init sub.
|
||||||
my $mi = eval($pkg.'::_init();'); ## no critic qw(BuiltinFunctions::ProhibitStringyEval)
|
my $mi = eval($pkg.'::_init();'); ## no critic qw(BuiltinFunctions::ProhibitStringyEval)
|
||||||
|
|
||||||
if ($mi) {
|
if ($mi) {
|
||||||
# If successful, add to hash.
|
# If successful, add to hash.
|
||||||
$MODULE{$name}{name} = $name;
|
$MODULE{$name}{name} = $name;
|
||||||
$MODULE{$name}{version} = $version;
|
$MODULE{$name}{version} = $version;
|
||||||
$MODULE{$name}{author} = $author;
|
$MODULE{$name}{author} = $author;
|
||||||
$MODULE{$name}{pkg} = $pkg;
|
$MODULE{$name}{pkg} = $pkg;
|
||||||
|
|
||||||
API::Log::dbug('MODULES: '.$name.' successfully loaded.');
|
API::Log::dbug('MODULES: '.$name.' successfully loaded.');
|
||||||
API::Log::alog('MODULES: '.$name.' successfully loaded.');
|
API::Log::alog('MODULES: '.$name.' successfully loaded.');
|
||||||
|
if (keys %Auto::SOCKET) { API::Log::slog('MODULES: '.$name.' successfully loaded.'); }
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, return a failed to load message.
|
# Otherwise, return a failed to load message.
|
||||||
API::Log::dbug('MODULES: Failed to load '.$name.q{.});
|
API::Log::dbug('MODULES: Failed to load '.$name.q{.});
|
||||||
API::Log::alog('MODULES: Failed to load '.$name.q{.});
|
API::Log::alog('MODULES: Failed to load '.$name.q{.});
|
||||||
|
if (keys %Auto::SOCKET) { API::Log::slog('MODULES: Failed to load '.$name.q{.}); }
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if a module exists.
|
# Check if a module exists.
|
||||||
sub mod_exists
|
sub mod_exists
|
||||||
{
|
{
|
||||||
my ($name) = @_;
|
my ($name) = @_;
|
||||||
|
|
||||||
if (defined $API::Std::MODULE{$name}) { return 1; }
|
if (defined $API::Std::MODULE{$name}) { return 1; }
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Void a module.
|
# Void a module.
|
||||||
sub mod_void
|
sub mod_void
|
||||||
{
|
{
|
||||||
my ($module) = @_;
|
my ($module) = @_;
|
||||||
|
|
||||||
# Log/debug.
|
# Log/debug.
|
||||||
API::Log::dbug('MODULES: Attempting to unload module: '.$module.'...');
|
API::Log::dbug('MODULES: Attempting to unload module: '.$module.'...');
|
||||||
API::Log::alog('MODULES: Attempting to unload module: '.$module.'...');
|
API::Log::alog('MODULES: Attempting to unload module: '.$module.'...');
|
||||||
|
if (keys %Auto::SOCKET) { API::Log::slog('MODULES: Attempting to unload module: '.$module.'...'); }
|
||||||
|
|
||||||
# Check if this module exists.
|
# Check if this module exists.
|
||||||
if (!defined $MODULE{$module}) {
|
if (!defined $MODULE{$module}) {
|
||||||
API::Log::dbug('MODULES: Failed to unload '.$module.'. No such module?');
|
API::Log::dbug('MODULES: Failed to unload '.$module.'. No such module?');
|
||||||
API::Log::alog('MODULES: Failed to unload '.$module.'. No such module?');
|
API::Log::alog('MODULES: Failed to unload '.$module.'. No such module?');
|
||||||
return;
|
if (keys %Auto::SOCKET) { API::Log::slog('MODULES: Failed to unload '.$module.'. No such module?'); }
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
# Run the module's _void sub.
|
# Run the module's _void sub.
|
||||||
my $mi = eval($MODULE{$module}{pkg}.'::_void();'); ## no critic qw(BuiltinFunctions::ProhibitStringyEval)
|
my $mi = eval($MODULE{$module}{pkg}.'::_void();'); ## no critic qw(BuiltinFunctions::ProhibitStringyEval)
|
||||||
|
|
||||||
if ($mi) {
|
if ($mi) {
|
||||||
# If successful, delete class from program and delete module from hash.
|
# If successful, delete class from program and delete module from hash.
|
||||||
Class::Unload->unload($MODULE{$module}{pkg});
|
Class::Unload->unload($MODULE{$module}{pkg});
|
||||||
delete $MODULE{$module};
|
delete $MODULE{$module};
|
||||||
API::Log::dbug('MODULES: Successfully unloaded '.$module.q{.});
|
API::Log::dbug('MODULES: Successfully unloaded '.$module.q{.});
|
||||||
API::Log::alog('MODULES: Successfully unloaded '.$module.q{.});
|
API::Log::alog('MODULES: Successfully unloaded '.$module.q{.});
|
||||||
return 1;
|
if (keys %Auto::SOCKET) { API::Log::slog('MODULES: Successfully unloaded '.$module.q{.}); }
|
||||||
}
|
return 1;
|
||||||
else {
|
}
|
||||||
# Otherwise, return a failed to unload message.
|
else {
|
||||||
API::Log::dbug('MODULES: Failed to unload '.$module.q{.});
|
# Otherwise, return a failed to unload message.
|
||||||
API::Log::alog('MODULES: Failed to unload '.$module.q{.});
|
API::Log::dbug('MODULES: Failed to unload '.$module.q{.});
|
||||||
return;
|
API::Log::alog('MODULES: Failed to unload '.$module.q{.});
|
||||||
}
|
if (keys %Auto::SOCKET) { API::Log::slog('MODULES: Failed to unload '.$module.q{.}); }
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add a command to Auto.
|
# Add a command to Auto.
|
||||||
sub cmd_add
|
sub cmd_add
|
||||||
{
|
{
|
||||||
my ($cmd, $lvl, $priv, $help, $sub) = @_;
|
my ($cmd, $lvl, $priv, $help, $sub) = @_;
|
||||||
$cmd = uc $cmd;
|
$cmd = uc $cmd;
|
||||||
|
|
||||||
if (defined $API::Std::CMDS{$cmd}) { return; }
|
if (defined $API::Std::CMDS{$cmd}) { return; }
|
||||||
if ($lvl =~ m/[^0-2]/sm) { return; } ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
if ($lvl =~ m/[^0-3]/sm) { return; } ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
||||||
|
|
||||||
$API::Std::CMDS{$cmd}{lvl} = $lvl;
|
$API::Std::CMDS{$cmd}{lvl} = $lvl;
|
||||||
$API::Std::CMDS{$cmd}{help} = $help;
|
$API::Std::CMDS{$cmd}{help} = $help;
|
||||||
$API::Std::CMDS{$cmd}{priv} = $priv;
|
$API::Std::CMDS{$cmd}{priv} = $priv;
|
||||||
$API::Std::CMDS{$cmd}{sub} = $sub;
|
$API::Std::CMDS{$cmd}{'sub'} = $sub;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Delete a command from Auto.
|
# Delete a command from Auto.
|
||||||
sub cmd_del
|
sub cmd_del
|
||||||
{
|
{
|
||||||
my ($cmd) = @_;
|
my ($cmd) = @_;
|
||||||
$cmd = uc $cmd;
|
$cmd = uc $cmd;
|
||||||
|
|
||||||
if (defined $API::Std::CMDS{$cmd}) {
|
if (defined $API::Std::CMDS{$cmd}) {
|
||||||
delete $API::Std::CMDS{$cmd};
|
delete $API::Std::CMDS{$cmd};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add an event to Auto.
|
# Add an event to Auto.
|
||||||
sub event_add
|
sub event_add
|
||||||
{
|
{
|
||||||
my ($name) = @_;
|
my ($name) = @_;
|
||||||
|
|
||||||
if (!defined $EVENTS{lc $name}) {
|
if (!defined $EVENTS{lc $name}) {
|
||||||
$EVENTS{lc $name} = 1;
|
$EVENTS{lc $name} = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
API::Log::dbug('DEBUG: Attempt to add a pre-existing event ('.lc $name.')! Ignoring...');
|
API::Log::dbug('DEBUG: Attempt to add a pre-existing event ('.lc $name.')! Ignoring...');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Delete an event from Auto.
|
# Delete an event from Auto.
|
||||||
sub event_del
|
sub event_del
|
||||||
{
|
{
|
||||||
my ($name) = @_;
|
my ($name) = @_;
|
||||||
|
|
||||||
if (defined $EVENTS{lc $name}) {
|
if (defined $EVENTS{lc $name}) {
|
||||||
delete $EVENTS{lc $name};
|
delete $EVENTS{lc $name};
|
||||||
delete $HOOKS{lc $name};
|
delete $HOOKS{lc $name};
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
API::Log::dbug('DEBUG: Attempt to delete a non-existing event ('.lc $name.')! Ignoring...');
|
API::Log::dbug('DEBUG: Attempt to delete a non-existing event ('.lc $name.')! Ignoring...');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Trigger an event.
|
# Trigger an event.
|
||||||
sub event_run
|
sub event_run
|
||||||
{
|
{
|
||||||
my ($event, @args) = @_;
|
my ($event, @args) = @_;
|
||||||
|
|
||||||
if (defined $EVENTS{lc $event} and defined $HOOKS{lc $event}) {
|
if (defined $EVENTS{lc $event} and defined $HOOKS{lc $event}) {
|
||||||
foreach my $hk (keys %{ $HOOKS{lc $event} }) {
|
foreach my $hk (keys %{ $HOOKS{lc $event} }) {
|
||||||
&{ $HOOKS{lc $event}{$hk} }(@args);
|
my $ri = &{ $HOOKS{lc $event}{$hk} }(@args);
|
||||||
}
|
if ($ri == -1) { last; }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add a hook to Auto.
|
# Add a hook to Auto.
|
||||||
sub hook_add
|
sub hook_add
|
||||||
{
|
{
|
||||||
my ($event, $name, $sub) = @_;
|
my ($event, $name, $sub) = @_;
|
||||||
|
|
||||||
if (!defined $API::Std::HOOKS{lc $name}) {
|
if (!defined $API::Std::HOOKS{lc $name}) {
|
||||||
if (defined $API::Std::EVENTS{lc $event}) {
|
if (defined $API::Std::EVENTS{lc $event}) {
|
||||||
$API::Std::HOOKS{lc $event}{lc $name} = $sub;
|
$API::Std::HOOKS{lc $event}{lc $name} = $sub;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Delete a hook from Auto.
|
# Delete a hook from Auto.
|
||||||
sub hook_del
|
sub hook_del
|
||||||
{
|
{
|
||||||
my ($event, $name) = @_;
|
my ($event, $name) = @_;
|
||||||
|
|
||||||
if (defined $API::Std::HOOKS{lc $event}{lc $name}) {
|
if (defined $API::Std::HOOKS{lc $event}{lc $name}) {
|
||||||
delete $API::Std::HOOKS{lc $event}{lc $name};
|
delete $API::Std::HOOKS{lc $event}{lc $name};
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add a timer to Auto.
|
# Add a timer to Auto.
|
||||||
sub timer_add
|
sub timer_add
|
||||||
{
|
{
|
||||||
my ($name, $type, $time, $sub) = @_;
|
my ($name, $type, $time, $sub) = @_;
|
||||||
$name = lc $name;
|
$name = lc $name;
|
||||||
|
|
||||||
# Check for invalid type/time.
|
# Check for invalid type/time.
|
||||||
if ($type =~ m/[^1-2]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
if ($type =~ m/[^1-2]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($time =~ m/[^0-9]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
if ($time =~ m/[^0-9]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!defined $Auto::TIMERS{$name}) {
|
if (!defined $Auto::TIMERS{$name}) {
|
||||||
$Auto::TIMERS{$name}{type} = $type;
|
$Auto::TIMERS{$name}{type} = $type;
|
||||||
$Auto::TIMERS{$name}{time} = time + $time;
|
$Auto::TIMERS{$name}{time} = time + $time;
|
||||||
if ($type == 2) { $Auto::TIMERS{$name}{secs} = $time; }
|
if ($type == 2) { $Auto::TIMERS{$name}{secs} = $time; }
|
||||||
$Auto::TIMERS{$name}{sub} = $sub;
|
$Auto::TIMERS{$name}{sub} = $sub;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -239,123 +249,123 @@ sub timer_add
|
|||||||
# Delete a timer from Auto.
|
# Delete a timer from Auto.
|
||||||
sub timer_del
|
sub timer_del
|
||||||
{
|
{
|
||||||
my ($name) = @_;
|
my ($name) = @_;
|
||||||
$name = lc $name;
|
$name = lc $name;
|
||||||
|
|
||||||
if (defined $Auto::TIMERS{$name}) {
|
if (defined $Auto::TIMERS{$name}) {
|
||||||
delete $Auto::TIMERS{$name};
|
delete $Auto::TIMERS{$name};
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Hook onto a raw command.
|
# Hook onto a raw command.
|
||||||
sub rchook_add
|
sub rchook_add
|
||||||
{
|
{
|
||||||
my ($cmd, $sub) = @_;
|
my ($cmd, $sub) = @_;
|
||||||
$cmd = uc $cmd;
|
$cmd = uc $cmd;
|
||||||
|
|
||||||
if (defined $Parser::IRC::RAWC{$cmd}) { return; }
|
if (defined $Parser::IRC::RAWC{$cmd}) { return; }
|
||||||
|
|
||||||
$Parser::IRC::RAWC{$cmd} = $sub;
|
$Parser::IRC::RAWC{$cmd} = $sub;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Delete a raw command hook.
|
# Delete a raw command hook.
|
||||||
sub rchook_del
|
sub rchook_del
|
||||||
{
|
{
|
||||||
my ($cmd) = @_;
|
my ($cmd) = @_;
|
||||||
$cmd = uc $cmd;
|
$cmd = uc $cmd;
|
||||||
|
|
||||||
if (!defined $Parser::IRC::RAWC{$cmd}) { return; }
|
if (!defined $Parser::IRC::RAWC{$cmd}) { return; }
|
||||||
|
|
||||||
delete $Parser::IRC::RAWC{$cmd};
|
delete $Parser::IRC::RAWC{$cmd};
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Configuration value getter.
|
# Configuration value getter.
|
||||||
sub conf_get
|
sub conf_get
|
||||||
{
|
{
|
||||||
my ($value) = @_;
|
my ($value) = @_;
|
||||||
|
|
||||||
# Create an array out of the value.
|
# Create an array out of the value.
|
||||||
my @val;
|
my @val;
|
||||||
if ($value =~ m/:/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
if ($value =~ m/:/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
||||||
@val = split m/[:]/sm, $value; ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
@val = split m/[:]/sm, $value; ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@val = ($value);
|
@val = ($value);
|
||||||
}
|
}
|
||||||
# Undefine this as it's unnecessary now.
|
# Undefine this as it's unnecessary now.
|
||||||
undef $value;
|
undef $value;
|
||||||
|
|
||||||
# Get the count of elements in the array.
|
# Get the count of elements in the array.
|
||||||
my $count = scalar @val;
|
my $count = scalar @val;
|
||||||
|
|
||||||
# Return the requested configuration value(s).
|
# Return the requested configuration value(s).
|
||||||
if ($count == 1) {
|
if ($count == 1) {
|
||||||
if (ref $Auto::SETTINGS{$val[0]} eq 'HASH') {
|
if (ref $Auto::SETTINGS{$val[0]} eq 'HASH') {
|
||||||
return %{ $Auto::SETTINGS{$val[0]} };
|
return %{ $Auto::SETTINGS{$val[0]} };
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return $Auto::SETTINGS{$val[0]};
|
return $Auto::SETTINGS{$val[0]};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ($count == 2) {
|
elsif ($count == 2) {
|
||||||
if (ref $Auto::SETTINGS{$val[0]}{$val[1]} eq 'HASH') {
|
if (ref $Auto::SETTINGS{$val[0]}{$val[1]} eq 'HASH') {
|
||||||
return %{ $Auto::SETTINGS{$val[0]}{$val[1]} };
|
return %{ $Auto::SETTINGS{$val[0]}{$val[1]} };
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return $Auto::SETTINGS{$val[0]}{$val[1]};
|
return $Auto::SETTINGS{$val[0]}{$val[1]};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ($count == 3) {
|
elsif ($count == 3) {
|
||||||
if (ref $Auto::SETTINGS{$val[0]}{$val[1]}{$val[2]} eq 'HASH') {
|
if (ref $Auto::SETTINGS{$val[0]}{$val[1]}{$val[2]} eq 'HASH') {
|
||||||
return %{ $Auto::SETTINGS{$val[0]}{$val[1]}{$val[2]} };
|
return %{ $Auto::SETTINGS{$val[0]}{$val[1]}{$val[2]} };
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return $Auto::SETTINGS{$val[0]}{$val[1]}{$val[2]};
|
return $Auto::SETTINGS{$val[0]}{$val[1]}{$val[2]};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Translation subroutine.
|
# Translation subroutine.
|
||||||
sub trans
|
sub trans
|
||||||
{
|
{
|
||||||
my ($id) = @_;
|
my $id = shift;
|
||||||
$id =~ s/ /_/gsm;
|
$id =~ s/ /_/gsm;
|
||||||
|
|
||||||
if (defined $API::Std::LANGE{$id}) {
|
if (defined $API::Std::LANGE{$id}) {
|
||||||
return $API::Std::LANGE{$id};
|
return sprintf $API::Std::LANGE{$id}, @_;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$id =~ s/_/ /gsm;
|
$id =~ s/_/ /gsm;
|
||||||
return $id;
|
return $id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Match user subroutine.
|
# Match user subroutine.
|
||||||
sub match_user
|
sub match_user
|
||||||
{
|
{
|
||||||
my (%user) = @_;
|
my (%user) = @_;
|
||||||
|
|
||||||
# Get data from config.
|
# Get data from config.
|
||||||
if (!conf_get('user')) { return; }
|
if (!conf_get('user')) { return; }
|
||||||
my %uhp = conf_get('user');
|
my %uhp = conf_get('user');
|
||||||
|
|
||||||
foreach my $userkey (keys %uhp) {
|
foreach my $userkey (keys %uhp) {
|
||||||
# For each user block.
|
# For each user block.
|
||||||
my %ulhp = %{ $uhp{$userkey} };
|
my %ulhp = %{ $uhp{$userkey} };
|
||||||
foreach my $uhk (keys %ulhp) {
|
foreach my $uhk (keys %ulhp) {
|
||||||
# For each user.
|
# For each user.
|
||||||
|
|
||||||
if ($uhk eq 'net') {
|
if ($uhk eq 'net') {
|
||||||
if (defined $user{svr}) {
|
if (defined $user{svr}) {
|
||||||
if (lc $user{svr} ne lc(($ulhp{$uhk})[0][0])) {
|
if (lc $user{svr} ne lc(($ulhp{$uhk})[0][0])) {
|
||||||
# config.user:net conflicts with irc.user:svr.
|
# config.user:net conflicts with irc.user:svr.
|
||||||
@@ -364,13 +374,13 @@ sub match_user
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ($uhk eq 'mask') {
|
elsif ($uhk eq 'mask') {
|
||||||
# Put together the user information.
|
# Put together the user information.
|
||||||
my $mask = $user{nick}.q{!}.$user{user}.q{@}.$user{host};
|
my $mask = $user{nick}.q{!}.$user{user}.q{@}.$user{host};
|
||||||
if (API::IRC::match_mask($mask, ($ulhp{$uhk})[0][0])) {
|
if (API::IRC::match_mask($mask, ($ulhp{$uhk})[0][0])) {
|
||||||
# We've got a host match.
|
# We've got a host match.
|
||||||
return $userkey;
|
return $userkey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ($uhk eq 'chanstatus' and defined $ulhp{'net'}) {
|
elsif ($uhk eq 'chanstatus' and defined $ulhp{'net'}) {
|
||||||
my ($ccst, $ccnm) = split m/[:]/sm, ($ulhp{$uhk})[0][0]; ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
my ($ccst, $ccnm) = split m/[:]/sm, ($ulhp{$uhk})[0][0]; ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
||||||
my $svr = $ulhp{net}[0];
|
my $svr = $ulhp{net}[0];
|
||||||
@@ -391,28 +401,28 @@ sub match_user
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Privilege subroutine.
|
# Privilege subroutine.
|
||||||
sub has_priv
|
sub has_priv
|
||||||
{
|
{
|
||||||
my ($cuser, $cpriv) = @_;
|
my ($cuser, $cpriv) = @_;
|
||||||
|
|
||||||
if (conf_get("user:$cuser:privs")) {
|
if (conf_get("user:$cuser:privs")) {
|
||||||
my $cups = (conf_get("user:$cuser:privs"))[0][0];
|
my $cups = (conf_get("user:$cuser:privs"))[0][0];
|
||||||
|
|
||||||
if (defined $Auto::PRIVILEGES{$cups}) {
|
if (defined $Auto::PRIVILEGES{$cups}) {
|
||||||
foreach (@{ $Auto::PRIVILEGES{$cups} }) {
|
foreach (@{ $Auto::PRIVILEGES{$cups} }) {
|
||||||
if ($_ eq $cpriv or $_ eq 'ALL') { return 1; }
|
if ($_ eq $cpriv or $_ eq 'ALL') { return 1; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ratelimit check subroutine.
|
# Ratelimit check subroutine.
|
||||||
@@ -430,6 +440,7 @@ sub ratelimit_check
|
|||||||
# If the user has not passed the rate limit.
|
# If the user has not passed the rate limit.
|
||||||
if ($Core::IRC::usercmd{$src{nick}.'@'.$src{host}.'/'.$src{svr}} <= (conf_get('ratelimit_amount'))[0][0]) {
|
if ($Core::IRC::usercmd{$src{nick}.'@'.$src{host}.'/'.$src{svr}} <= (conf_get('ratelimit_amount'))[0][0]) {
|
||||||
# Increment their uses and return 1.
|
# Increment their uses and return 1.
|
||||||
|
|
||||||
$Core::IRC::usercmd{$src{nick}.'@'.$src{host}.'/'.$src{svr}}++;
|
$Core::IRC::usercmd{$src{nick}.'@'.$src{host}.'/'.$src{svr}}++;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -450,51 +461,59 @@ sub ratelimit_check
|
|||||||
# Error subroutine.
|
# Error subroutine.
|
||||||
sub err ## no critic qw(Subroutines::ProhibitBuiltinHomonyms)
|
sub err ## no critic qw(Subroutines::ProhibitBuiltinHomonyms)
|
||||||
{
|
{
|
||||||
my ($lvl, $msg, $fatal) = @_;
|
my ($lvl, $msg, $fatal) = @_;
|
||||||
|
|
||||||
# Check for an invalid level.
|
# Check for an invalid level.
|
||||||
if ($lvl =~ m/[^0-9]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
if ($lvl =~ m/[^0-9]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($fatal =~ m/[^0-1]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
if ($fatal =~ m/[^0-1]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Level 1: Print to screen.
|
# Level 1: Print to screen.
|
||||||
if ($lvl >= 1) {
|
if ($lvl >= 1) {
|
||||||
API::Log::println("ERROR: $msg");
|
say "ERROR: $msg";
|
||||||
}
|
}
|
||||||
# Level 2: Log to file.
|
# Level 2: Log to file.
|
||||||
if ($lvl >= 2) {
|
if ($lvl >= 2) {
|
||||||
API::Log::alog("ERROR: $msg");
|
API::Log::alog("ERROR: $msg");
|
||||||
}
|
}
|
||||||
|
# Level 3: Log to IRC.
|
||||||
|
if ($lvl >= 3) {
|
||||||
|
API::Log::slog("ERROR: $msg");
|
||||||
|
}
|
||||||
|
|
||||||
# If it's a fatal error, exit the program.
|
# If it's a fatal error, exit the program.
|
||||||
if ($fatal) { exit; }
|
if ($fatal) { exit; }
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Warn subroutine.
|
# Warn subroutine.
|
||||||
sub awarn
|
sub awarn
|
||||||
{
|
{
|
||||||
my ($lvl, $msg) = @_;
|
my ($lvl, $msg) = @_;
|
||||||
|
|
||||||
# Check for an invalid level.
|
# Check for an invalid level.
|
||||||
if ($lvl =~ m/[^0-9]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
if ($lvl =~ m/[^0-9]/sm) { ## no critic qw(RegularExpressions::RequireExtendedFormatting)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Level 1: Print to screen.
|
# Level 1: Print to screen.
|
||||||
if ($lvl >= 1) {
|
if ($lvl >= 1) {
|
||||||
API::Log::println("WARNING: $msg");
|
say "WARNING: $msg";
|
||||||
}
|
}
|
||||||
# Level 2: Log to file.
|
# Level 2: Log to file.
|
||||||
if ($lvl >= 2) {
|
if ($lvl >= 2) {
|
||||||
API::Log::alog("WARNING: $msg");
|
API::Log::alog("WARNING: $msg");
|
||||||
}
|
}
|
||||||
|
# Level 3: Log to IRC.
|
||||||
|
if ($lvl >= 3) {
|
||||||
|
API::Log::slog("WARNING: $msg");
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+67
-51
@@ -16,18 +16,17 @@ our %HELP_MODLOAD = (
|
|||||||
# MODLOAD callback.
|
# MODLOAD callback.
|
||||||
sub cmd_modload
|
sub cmd_modload
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @argv) = @_;
|
||||||
my @argv = @{ $data{args} };
|
|
||||||
|
|
||||||
# Check for the needed parameters.
|
# Check for the needed parameters.
|
||||||
if (!defined $argv[0]) {
|
if (!defined $argv[0]) {
|
||||||
notice($data{svr}, $data{nick}, trans("Not enough parameters").".");
|
notice($src->{svr}, $src->{nick}, trans("Not enough parameters").".");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if the module is already loaded.
|
# Check if the module is already loaded.
|
||||||
if (API::Std::mod_exists($argv[0])) {
|
if (API::Std::mod_exists($argv[0])) {
|
||||||
notice($data{svr}, $data{nick}, "Module \002".$argv[0]."\002 is already loaded.");
|
notice($src->{svr}, $src->{nick}, "Module \002".$argv[0]."\002 is already loaded.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,11 +36,11 @@ sub cmd_modload
|
|||||||
# Check if we were successful or not.
|
# Check if we were successful or not.
|
||||||
if ($tn) {
|
if ($tn) {
|
||||||
# We were!
|
# We were!
|
||||||
notice($data{svr}, $data{nick}, "Module \002".$argv[0]."\002 successfully loaded.");
|
notice($src->{svr}, $src->{nick}, "Module \002".$argv[0]."\002 successfully loaded.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# We weren't.
|
# We weren't.
|
||||||
notice($data{svr}, $data{nick}, "Module \002".$argv[0]."\002 failed to load.");
|
notice($src->{svr}, $src->{nick}, "Module \002".$argv[0]."\002 failed to load.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,18 +54,17 @@ our %HELP_MODUNLOAD = (
|
|||||||
# MODUNLOAD callback.
|
# MODUNLOAD callback.
|
||||||
sub cmd_modunload
|
sub cmd_modunload
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @argv) = @_;
|
||||||
my @argv = @{ $data{args} };
|
|
||||||
|
|
||||||
# Check for the needed parameters.
|
# Check for the needed parameters.
|
||||||
if (!defined $argv[0]) {
|
if (!defined $argv[0]) {
|
||||||
notice($data{svr}, $data{nick}, trans("Not enough parameters").".");
|
notice($src->{svr}, $src->{nick}, trans("Not enough parameters").".");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if the module exists.
|
# Check if the module exists.
|
||||||
if (!API::Std::mod_exists($argv[0])) {
|
if (!API::Std::mod_exists($argv[0])) {
|
||||||
notice($data{svr}, $data{nick}, "Module \002".$argv[0]."\002 is not loaded.");
|
notice($src->{svr}, $src->{nick}, "Module \002".$argv[0]."\002 is not loaded.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,11 +74,11 @@ sub cmd_modunload
|
|||||||
# Check if we were successful or not.
|
# Check if we were successful or not.
|
||||||
if ($tn) {
|
if ($tn) {
|
||||||
# We were!
|
# We were!
|
||||||
notice($data{svr}, $data{nick}, "Module \002".$argv[0]."\002 successfully unloaded.");
|
notice($src->{svr}, $src->{nick}, "Module \002".$argv[0]."\002 successfully unloaded.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# We weren't.
|
# We weren't.
|
||||||
notice($data{svr}, $data{nick}, "Module \002".$argv[0]."\002 failed to unload.");
|
notice($src->{svr}, $src->{nick}, "Module \002".$argv[0]."\002 failed to unload.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,18 +92,17 @@ our %HELP_MODRELOAD = (
|
|||||||
# MODRELOAD callback.
|
# MODRELOAD callback.
|
||||||
sub cmd_modreload
|
sub cmd_modreload
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @argv) = @_;
|
||||||
my @argv = @{ $data{args} };
|
|
||||||
|
|
||||||
# Check for the needed parameters.
|
# Check for the needed parameters.
|
||||||
if (!defined $argv[0]) {
|
if (!defined $argv[0]) {
|
||||||
notice($data{svr}, $data{nick}, trans("Not enough parameters").".");
|
notice($src->{svr}, $src->{nick}, trans("Not enough parameters").".");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if the module exists.
|
# Check if the module exists.
|
||||||
if (!API::Std::mod_exists($argv[0])) {
|
if (!API::Std::mod_exists($argv[0])) {
|
||||||
notice($data{svr}, $data{nick}, "Module \002".$argv[0]."\002 is not loaded.");
|
notice($src->{svr}, $src->{nick}, "Module \002".$argv[0]."\002 is not loaded.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,33 +114,54 @@ sub cmd_modreload
|
|||||||
# Check if we were successful or not.
|
# Check if we were successful or not.
|
||||||
if ($tvn and $tln) {
|
if ($tvn and $tln) {
|
||||||
# We were!
|
# We were!
|
||||||
notice($data{svr}, $data{nick}, "Module \002".$argv[0]."\002 successfully reloaded.");
|
notice($src->{svr}, $src->{nick}, "Module \002".$argv[0]."\002 successfully reloaded.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# We weren't.
|
# We weren't.
|
||||||
notice($data{svr}, $data{nick}, "Module \002".$argv[0]."\002 failed to reload.");
|
notice($src->{svr}, $src->{nick}, "Module \002".$argv[0]."\002 failed to reload.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Help hash for MODLIST. Spanish, French and German needed.
|
||||||
|
our %HELP_MODLIST = (
|
||||||
|
'en' => "This will return a list of all currently loaded modules. \2Syntax:\2 MODLIST",
|
||||||
|
);
|
||||||
|
# MODLIST callback.
|
||||||
|
sub cmd_modlist
|
||||||
|
{
|
||||||
|
my ($src, undef) = @_;
|
||||||
|
|
||||||
|
# Iterate through all loaded modules.
|
||||||
|
my $str;
|
||||||
|
foreach (keys %API::Std::MODULE) {
|
||||||
|
$str .= ", \2$_\2 (v".$API::Std::MODULE{$_}{version}.')';
|
||||||
|
}
|
||||||
|
|
||||||
|
# Return it.
|
||||||
|
$str = substr $str, 2;
|
||||||
|
notice($src->{svr}, $src->{nick}, "\2Module List:\2 $str");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
# Help hash for SHUTDOWN. Spanish, French and German needed.
|
# Help hash for SHUTDOWN. Spanish, French and German needed.
|
||||||
our %HELP_SHUTDOWN = (
|
our %HELP_SHUTDOWN = (
|
||||||
'en' => 'This will send out shutdown notifications, quit all networks, flush the database then exit the program.',
|
'en' => "This will send out shutdown notifications, quit all networks, flush the database then exit the program. \2Syntax:\2 SHUTDOWN",
|
||||||
);
|
);
|
||||||
# SHUTDOWN callback.
|
# SHUTDOWN callback.
|
||||||
sub cmd_shutdown
|
sub cmd_shutdown
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, undef) = @_;
|
||||||
|
|
||||||
# Goodbye world!
|
# Goodbye world!
|
||||||
notice($data{svr}, $data{nick}, "Shutting down.");
|
notice($src->{svr}, $src->{nick}, "Shutting down.");
|
||||||
dbug "Got SHUTDOWN from ".$data{nick}."!".$data{user}."@".$data{host}."/".$data{svr}."! Shutting down. . .";
|
dbug "Got SHUTDOWN from ".$src->{nick}."!".$src->{user}."@".$src->{host}."/".$src->{svr}."! Shutting down. . .";
|
||||||
alog "Got SHUTDOWN from ".$data{nick}."!".$data{user}."@".$data{host}."/".$data{svr}."! Shutting down. . .";
|
alog "Got SHUTDOWN from ".$src->{nick}."!".$src->{user}."@".$src->{host}."/".$src->{svr}."! Shutting down. . .";
|
||||||
quit($_, "SHUTDOWN from ".$data{nick}."/".$data{svr}) foreach (keys %Auto::SOCKET);
|
quit($_, "SHUTDOWN from ".$src->{nick}."/".$src->{svr}) foreach (keys %Auto::SOCKET);
|
||||||
$Auto::DB->disconnect;
|
API::Std::event_run('on_shutdown');
|
||||||
system("rm $Auto::Bin/auto.pid");
|
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
# To appease PerlCritic.
|
# To appease PerlCritic.
|
||||||
@@ -157,15 +175,14 @@ our %HELP_RESTART = (
|
|||||||
# RESTART callback.
|
# RESTART callback.
|
||||||
sub cmd_restart
|
sub cmd_restart
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, undef) = @_;
|
||||||
|
|
||||||
# Goodbye world!
|
# Goodbye world!
|
||||||
notice($data{svr}, $data{nick}, "Restarting.");
|
notice($src->{svr}, $src->{nick}, "Restarting.");
|
||||||
dbug "Got RESTART from ".$data{nick}."!".$data{user}."@".$data{host}."/".$data{svr}."! Restarting. . .";
|
dbug "Got RESTART from ".$src->{nick}."!".$src->{user}."@".$src->{host}."/".$src->{svr}."! Restarting. . .";
|
||||||
alog "Got RESTART from ".$data{nick}."!".$data{user}."@".$data{host}."/".$data{svr}."! Restarting. . .";
|
alog "Got RESTART from ".$src->{nick}."!".$src->{user}."@".$src->{host}."/".$src->{svr}."! Restarting. . .";
|
||||||
quit($_, "RESTART from ".$data{nick}."/".$data{svr}) foreach (keys %Auto::SOCKET);
|
quit($_, "RESTART from ".$src->{nick}."/".$src->{svr}) foreach (keys %Auto::SOCKET);
|
||||||
$Auto::DB->disconnect;
|
API::Std::event_run('on_shutdown');
|
||||||
system("rm $Auto::Bin/auto.pid") if -e "$Auto::Bin/auto.pid";
|
|
||||||
|
|
||||||
# Time to come back from the dead!
|
# Time to come back from the dead!
|
||||||
if ($Auto::DEBUG) {
|
if ($Auto::DEBUG) {
|
||||||
@@ -187,16 +204,16 @@ our %HELP_REHASH = (
|
|||||||
# REHASH callback.
|
# REHASH callback.
|
||||||
sub cmd_rehash
|
sub cmd_rehash
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, undef) = @_;
|
||||||
|
|
||||||
# Send out notifications.
|
# Send out notifications.
|
||||||
notice($data{svr}, $data{nick}, "Rehashing.");
|
notice($src->{svr}, $src->{nick}, "Rehashing.");
|
||||||
dbug "Got REHASH from ".$data{nick}."!".$data{user}."@".$data{host}."/".$data{svr}."! Rehashing. . .";
|
dbug "Got REHASH from ".$src->{nick}."!".$src->{user}."@".$src->{host}."/".$src->{svr}."! Rehashing. . .";
|
||||||
alog "Got REHASH from ".$data{nick}."!".$data{user}."@".$data{host}."/".$data{svr}."! Rehashing. . .";
|
alog "Got REHASH from ".$src->{nick}."!".$src->{user}."@".$src->{host}."/".$src->{svr}."! Rehashing. . .";
|
||||||
|
|
||||||
# Rehash.
|
# Rehash.
|
||||||
Lib::Auto::rehash();
|
Lib::Auto::rehash();
|
||||||
notice($data{svr}, $data{nick}, "Done.");
|
notice($src->{svr}, $src->{nick}, "Done.");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -208,18 +225,17 @@ our %HELP_HELP = (
|
|||||||
# HELP callback.
|
# HELP callback.
|
||||||
sub cmd_help
|
sub cmd_help
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @argv) = @_;
|
||||||
my @argv = @{ $data{args} }; delete $data{args};
|
|
||||||
|
|
||||||
# Check for arguments and reply accordingly.
|
# Check for arguments and reply accordingly.
|
||||||
if (!defined $argv[0]) {
|
if (!defined $argv[0]) {
|
||||||
# No command specified. List commands.
|
# No command specified. List commands.
|
||||||
my $cmdlist = '';
|
my $cmdlist = '';
|
||||||
foreach (sort keys %API::Std::CMDS) {
|
foreach (sort keys %API::Std::CMDS) {
|
||||||
if (defined $data{chan}) {
|
if (defined $src->{chan}) {
|
||||||
if ($API::Std::CMDS{$_}{lvl} == 0 or $API::Std::CMDS{$_}{lvl} == 2) {
|
if ($API::Std::CMDS{$_}{lvl} == 0 or $API::Std::CMDS{$_}{lvl} == 2) {
|
||||||
if ($API::Std::CMDS{$_}{priv}) {
|
if ($API::Std::CMDS{$_}{priv}) {
|
||||||
if (has_priv(match_user(%data), $API::Std::CMDS{$_}{priv})) {
|
if (has_priv(match_user(%$src), $API::Std::CMDS{$_}{priv})) {
|
||||||
$cmdlist .= ", \002".uc($_)."\002";
|
$cmdlist .= ", \002".uc($_)."\002";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,7 +247,7 @@ sub cmd_help
|
|||||||
else {
|
else {
|
||||||
if ($API::Std::CMDS{$_}{lvl} == 1 or $API::Std::CMDS{$_}{lvl} == 2) {
|
if ($API::Std::CMDS{$_}{lvl} == 1 or $API::Std::CMDS{$_}{lvl} == 2) {
|
||||||
if ($API::Std::CMDS{$_}{priv}) {
|
if ($API::Std::CMDS{$_}{priv}) {
|
||||||
if (has_priv(match_user(%data), $API::Std::CMDS{$_}{priv})) {
|
if (has_priv(match_user(%$src), $API::Std::CMDS{$_}{priv})) {
|
||||||
$cmdlist .= ", \002".uc($_)."\002";
|
$cmdlist .= ", \002".uc($_)."\002";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,7 +259,7 @@ sub cmd_help
|
|||||||
}
|
}
|
||||||
$cmdlist = substr($cmdlist, 2);
|
$cmdlist = substr($cmdlist, 2);
|
||||||
|
|
||||||
notice($data{svr}, $data{nick}, "Command List: ".$cmdlist);
|
notice($src->{svr}, $src->{nick}, "Command List: ".$cmdlist);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Help for a specific command was requested. Lets get it.
|
# Help for a specific command was requested. Lets get it.
|
||||||
@@ -254,8 +270,8 @@ sub cmd_help
|
|||||||
|
|
||||||
# Check for necessary privileges.
|
# Check for necessary privileges.
|
||||||
if ($API::Std::CMDS{$rcm}{priv}) {
|
if ($API::Std::CMDS{$rcm}{priv}) {
|
||||||
if (!has_priv(match_user(%data), $API::Std::CMDS{$rcm}{priv})) {
|
if (!has_priv(match_user(%$src), $API::Std::CMDS{$rcm}{priv})) {
|
||||||
notice($data{svr}, $data{nick}, trans("Access denied").".");
|
notice($src->{svr}, $src->{nick}, trans("Access denied").".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,28 +284,28 @@ sub cmd_help
|
|||||||
|
|
||||||
if (defined ${ $API::Std::CMDS{$rcm}{help} }{$lang}) {
|
if (defined ${ $API::Std::CMDS{$rcm}{help} }{$lang}) {
|
||||||
# If help for this command is available in the configured language.
|
# If help for this command is available in the configured language.
|
||||||
notice($data{svr}, $data{nick}, "Help for \002".$rcm."\002: ".${ $API::Std::CMDS{$rcm}{help} }{$lang});
|
notice($src->{svr}, $src->{nick}, "Help for \002".$rcm."\002: ".${ $API::Std::CMDS{$rcm}{help} }{$lang});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# If it isn't, default to English.
|
# If it isn't, default to English.
|
||||||
if (defined ${ $API::Std::CMDS{$rcm}{help} }{en}) {
|
if (defined ${ $API::Std::CMDS{$rcm}{help} }{en}) {
|
||||||
# If help for this command is available in English.
|
# If help for this command is available in English.
|
||||||
notice($data{svr}, $data{nick}, "Help for \002".$rcm."\002: ".${ $API::Std::CMDS{$rcm}{help} }{en});
|
notice($src->{svr}, $src->{nick}, "Help for \002".$rcm."\002: ".${ $API::Std::CMDS{$rcm}{help} }{en});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# If it isn't, no help.
|
# If it isn't, no help.
|
||||||
notice($data{svr}, $data{nick}, "No help for \002".$rcm."\002 available.");
|
notice($src->{svr}, $src->{nick}, "No help for \002".$rcm."\002 available.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# If it isn't valid, no help.
|
# If it isn't valid, no help.
|
||||||
notice($data{svr}, $data{nick}, "No help for \002".$rcm."\002 available.");
|
notice($src->{svr}, $src->{nick}, "No help for \002".$rcm."\002 available.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# If there is no help, don't give any.
|
# If there is no help, don't give any.
|
||||||
notice($data{svr}, $data{nick}, "No help for \002".$rcm."\002 available.");
|
notice($src->{svr}, $src->{nick}, "No help for \002".$rcm."\002 available.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+54
-26
@@ -12,15 +12,14 @@ our (%usercmd);
|
|||||||
|
|
||||||
# CTCP VERSION reply.
|
# CTCP VERSION reply.
|
||||||
hook_add("on_uprivmsg", "ctcp_version_reply", sub {
|
hook_add("on_uprivmsg", "ctcp_version_reply", sub {
|
||||||
my (($svr, @ex)) = @_;
|
my (($src, @msg)) = @_;
|
||||||
my %src = usrc(substr($ex[0], 1));
|
|
||||||
|
|
||||||
if ($ex[3] eq ":\001VERSION\001") {
|
if ($msg[0] eq "\001VERSION\001") {
|
||||||
if (Auto::RSTAGE ne 'd') {
|
if (Auto::RSTAGE ne 'd') {
|
||||||
notice($svr, $src{nick}, "\001VERSION ".Auto::NAME." ".Auto::VER.".".Auto::SVER.".".Auto::REV.Auto::RSTAGE." ".$OSNAME."\001");
|
notice($src->{svr}, $src->{nick}, "\001VERSION ".Auto::NAME." ".Auto::VER.".".Auto::SVER.".".Auto::REV.Auto::RSTAGE." ".$OSNAME."\001");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
notice($svr, $src{nick}, "\001VERSION ".Auto::NAME." ".Auto::VER.".".Auto::SVER.".".Auto::REV.Auto::RSTAGE."-".Auto::GR." ".$OSNAME."\001");
|
notice($src->{svr}, $src->{nick}, "\001VERSION ".Auto::NAME." ".Auto::VER.".".Auto::SVER.".".Auto::REV.Auto::RSTAGE."-".Auto::GR." ".$OSNAME."\001");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,22 +43,22 @@ hook_add("on_quit", "quit_update_chanusers", sub {
|
|||||||
hook_add("on_connect", "on_connect_modes", sub {
|
hook_add("on_connect", "on_connect_modes", sub {
|
||||||
my ($svr) = @_;
|
my ($svr) = @_;
|
||||||
|
|
||||||
if (conf_get("server:$svr:modes")) {
|
if (conf_get("server:$svr:modes")) {
|
||||||
my $connmodes = (conf_get("server:$svr:modes"))[0][0];
|
my $connmodes = (conf_get("server:$svr:modes"))[0][0];
|
||||||
API::IRC::umode($svr, $connmodes);
|
API::IRC::umode($svr, $connmodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
# Plaintext auth.
|
# Plaintext auth.
|
||||||
hook_add("on_connect", "plaintext_auth", sub {
|
hook_add("on_connect", "plaintext_auth", sub {
|
||||||
my ($svr) = @_;
|
my ($svr) = @_;
|
||||||
|
|
||||||
if (conf_get("server:$svr:idstr")) {
|
if (conf_get("server:$svr:idstr")) {
|
||||||
my $idstr = (conf_get("server:$svr:idstr"))[0][0];
|
my $idstr = (conf_get("server:$svr:idstr"))[0][0];
|
||||||
Auto::socksnd($svr, $idstr);
|
Auto::socksnd($svr, $idstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
@@ -68,19 +67,48 @@ hook_add("on_connect", "plaintext_auth", sub {
|
|||||||
hook_add("on_connect", "autojoin", sub {
|
hook_add("on_connect", "autojoin", sub {
|
||||||
my ($svr) = @_;
|
my ($svr) = @_;
|
||||||
|
|
||||||
# Get the auto-join from the config.
|
# Get the auto-join from the config.
|
||||||
my @cajoin = @{ (conf_get("server:$svr:ajoin"))[0] };
|
my @cajoin = @{ (conf_get("server:$svr:ajoin"))[0] };
|
||||||
|
|
||||||
# Join the channels.
|
# Join the channels.
|
||||||
if (!defined $cajoin[1]) {
|
if (!defined $cajoin[1]) {
|
||||||
# For single-line ajoins.
|
# For single-line ajoins.
|
||||||
my @sajoin = split(',', $cajoin[0]);
|
my @sajoin = split(',', $cajoin[0]);
|
||||||
|
|
||||||
API::IRC::cjoin($svr, $_) foreach (@sajoin);
|
foreach (@sajoin) {
|
||||||
}
|
# Check if a key was specified.
|
||||||
else {
|
if ($_ =~ m/\s/xsm) {
|
||||||
# For multi-line ajoins.
|
# There was, join with it.
|
||||||
API::IRC::cjoin($svr, $_) foreach (@cajoin);
|
my ($chan, $key) = split / /;
|
||||||
|
API::IRC::cjoin($svr, $chan, $key);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Else join without one.
|
||||||
|
API::IRC::cjoin($svr, $_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# For multi-line ajoins.
|
||||||
|
foreach (@cajoin) {
|
||||||
|
# Check if a key was specified.
|
||||||
|
if ($_ =~ m/\s/xsm) {
|
||||||
|
# There was, join with it.
|
||||||
|
my ($chan, $key) = split / /;
|
||||||
|
API::IRC::cjoin($svr, $chan, $key);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Else join without one.
|
||||||
|
API::IRC::cjoin($svr, $_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# And logchan, if applicable.
|
||||||
|
if (conf_get('logchan')) {
|
||||||
|
my ($lcn, $lcc) = split '/', (conf_get('logchan'))[0][0];
|
||||||
|
if ($lcn eq $svr) {
|
||||||
|
API::IRC::cjoin($svr, $lcc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
+27
-21
@@ -4,18 +4,23 @@
|
|||||||
package Lib::Auto;
|
package Lib::Auto;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
use feature qw(say);
|
||||||
use English qw(-no_match_vars);
|
use English qw(-no_match_vars);
|
||||||
use Sys::Hostname;
|
use Sys::Hostname;
|
||||||
use feature qw(switch);
|
use feature qw(switch);
|
||||||
use API::Std qw(conf_get err);
|
use API::Std qw(hook_add conf_get err);
|
||||||
use API::Log qw(println dbug alog);
|
use API::Log qw(dbug alog);
|
||||||
our $VERSION = 3.000000;
|
our $VERSION = 3.000000;
|
||||||
|
|
||||||
|
# Core events.
|
||||||
|
API::Std::event_add('on_shutdown');
|
||||||
|
API::Std::event_add('on_rehash');
|
||||||
|
|
||||||
# Update checker.
|
# Update checker.
|
||||||
sub checkver
|
sub checkver
|
||||||
{
|
{
|
||||||
if (!$Auto::NUC and Auto::RSTAGE ne 'd') {
|
if (!$Auto::NUC and Auto::RSTAGE ne 'd') {
|
||||||
println '* Connecting to update server...';
|
say '* Connecting to update server...';
|
||||||
my $uss = IO::Socket::INET->new(
|
my $uss = IO::Socket::INET->new(
|
||||||
'Proto' => 'tcp',
|
'Proto' => 'tcp',
|
||||||
'PeerAddr' => 'dist.xelhua.org',
|
'PeerAddr' => 'dist.xelhua.org',
|
||||||
@@ -33,11 +38,11 @@ sub checkver
|
|||||||
}
|
}
|
||||||
elsif ($v eq 'version') {
|
elsif ($v eq 'version') {
|
||||||
if (Auto::VER.q{.}.Auto::SVER.q{.}.Auto::REV.Auto::RSTAGE ne $c) {
|
if (Auto::VER.q{.}.Auto::SVER.q{.}.Auto::REV.Auto::RSTAGE ne $c) {
|
||||||
println('!!! NOTICE !!! Your copy of Auto is outdated. Current version: '.Auto::VER.q{.}.Auto::SVER.q{.}.Auto::REV.Auto::RSTAGE.' - Latest version: '.$c);
|
say('!!! NOTICE !!! Your copy of Auto is outdated. Current version: '.Auto::VER.q{.}.Auto::SVER.q{.}.Auto::REV.Auto::RSTAGE.' - Latest version: '.$c);
|
||||||
println('!!! NOTICE !!! You can get the latest Auto by downloading '.$dll);
|
say('!!! NOTICE !!! You can get the latest Auto by downloading '.$dll);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
println('* Auto is up-to-date.');
|
say('* Auto is up-to-date.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +55,7 @@ sub rehash
|
|||||||
my %newsettings = $Auto::CONF->parse or err(2, 'Failed to parse configuration file!', 0) and return;
|
my %newsettings = $Auto::CONF->parse or err(2, 'Failed to parse configuration file!', 0) and return;
|
||||||
|
|
||||||
# Check for required configuration values.
|
# Check for required configuration values.
|
||||||
my @REQCVALS = qw(locale expire_logs server fantasy_pf);
|
my @REQCVALS = qw(locale expire_logs server fantasy_pf ratelimit bantype);
|
||||||
foreach my $REQCVAL (@REQCVALS) {
|
foreach my $REQCVAL (@REQCVALS) {
|
||||||
if (!defined $newsettings{$REQCVAL}) {
|
if (!defined $newsettings{$REQCVAL}) {
|
||||||
err(2, "Missing required configuration value: $REQCVAL", 0) and return;
|
err(2, "Missing required configuration value: $REQCVAL", 0) and return;
|
||||||
@@ -200,9 +205,19 @@ sub rehash
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Now trigger on_rehash.
|
||||||
|
API::Std::event_run('on_rehash');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Shutdown.
|
||||||
|
hook_add('on_shutdown', 'shutdown.core_cleanup', sub {
|
||||||
|
if (defined $Auto::DB) { $Auto::DB->disconnect; }
|
||||||
|
if (-e "$Auto::Bin/auto.pid") { unlink "$Auto::Bin/auto.pid"; }
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# Signal handlers #
|
# Signal handlers #
|
||||||
###################
|
###################
|
||||||
@@ -211,13 +226,10 @@ sub rehash
|
|||||||
sub signal_term
|
sub signal_term
|
||||||
{
|
{
|
||||||
API::Std::event_run('on_sigterm');
|
API::Std::event_run('on_sigterm');
|
||||||
|
API::Std::event_run('on_shutdown');
|
||||||
foreach (keys %Auto::SOCKET) { API::IRC::quit($_, 'Caught SIGTERM'); }
|
foreach (keys %Auto::SOCKET) { API::IRC::quit($_, 'Caught SIGTERM'); }
|
||||||
$Auto::DB->disconnect;
|
|
||||||
dbug '!!! Caught SIGTERM; terminating...';
|
dbug '!!! Caught SIGTERM; terminating...';
|
||||||
alog '!!! Caught SIGTERM; terminating...';
|
alog '!!! Caught SIGTERM; terminating...';
|
||||||
if (-e "$Auto::Bin/auto.pid") {
|
|
||||||
unlink "$Auto::Bin/auto.pid";
|
|
||||||
}
|
|
||||||
sleep 1;
|
sleep 1;
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@@ -226,13 +238,10 @@ sub signal_term
|
|||||||
sub signal_int
|
sub signal_int
|
||||||
{
|
{
|
||||||
API::Std::event_run('on_sigint');
|
API::Std::event_run('on_sigint');
|
||||||
|
API::Std::event_run('on_shutdown');
|
||||||
foreach (keys %Auto::SOCKET) { API::IRC::quit($_, 'Caught SIGINT'); }
|
foreach (keys %Auto::SOCKET) { API::IRC::quit($_, 'Caught SIGINT'); }
|
||||||
$Auto::DB->disconnect;
|
|
||||||
dbug '!!! Caught SIGINT; terminating...';
|
dbug '!!! Caught SIGINT; terminating...';
|
||||||
alog '!!! Caught SIGINT; terminating...';
|
alog '!!! Caught SIGINT; terminating...';
|
||||||
if (-e "$Auto::Bin/auto.pid") {
|
|
||||||
unlink "$Auto::Bin/auto.pid";
|
|
||||||
}
|
|
||||||
sleep 1;
|
sleep 1;
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@@ -253,7 +262,7 @@ sub signal_perlwarn
|
|||||||
my ($warnmsg) = @_;
|
my ($warnmsg) = @_;
|
||||||
$warnmsg =~ s/(\n|\r)//xsmg;
|
$warnmsg =~ s/(\n|\r)//xsmg;
|
||||||
alog 'Perl Warning: '.$warnmsg;
|
alog 'Perl Warning: '.$warnmsg;
|
||||||
if ($Auto::DEBUG) { println 'Perl Warning: '.$warnmsg; }
|
if ($Auto::DEBUG) { say 'Perl Warning: '.$warnmsg; }
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,12 +275,9 @@ sub signal_perldie
|
|||||||
return if $EXCEPTIONS_BEING_CAUGHT;
|
return if $EXCEPTIONS_BEING_CAUGHT;
|
||||||
alog 'Perl Fatal: '.$diemsg.' -- Terminating program!';
|
alog 'Perl Fatal: '.$diemsg.' -- Terminating program!';
|
||||||
foreach (keys %Auto::SOCKET) { API::IRC::quit($_, 'A fatal error occurred!'); }
|
foreach (keys %Auto::SOCKET) { API::IRC::quit($_, 'A fatal error occurred!'); }
|
||||||
$Auto::DB->disconnect;
|
API::Std::event_run('on_shutdown');
|
||||||
if (-e "$Auto::Bin/auto.pid") {
|
|
||||||
unlink "$Auto::Bin/auto.pid";
|
|
||||||
}
|
|
||||||
sleep 1;
|
sleep 1;
|
||||||
println 'FATAL: '.$diemsg;
|
say 'FATAL: '.$diemsg;
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -119,7 +119,7 @@ sub installmods
|
|||||||
chomp $response;
|
chomp $response;
|
||||||
if (lc $response eq 'y') {
|
if (lc $response eq 'y') {
|
||||||
println 'What modules would you like to install? (separate by commas)';
|
println 'What modules would you like to install? (separate by commas)';
|
||||||
println 'Available modules: Badwords, Bitly, Calc, EightBall, FML, HelloChan, IsItUp, QDB, SASLAuth, Weather';
|
println 'Available modules: Badwords, Bitly, Calc, EightBall, FML, Greet, HelloChan, IsItUp, QDB, SASLAuth, Weather';
|
||||||
print '> ';
|
print '> ';
|
||||||
my $modules = <STDIN>; chomp $modules;
|
my $modules = <STDIN>; chomp $modules;
|
||||||
$modules =~ s/ //g;
|
$modules =~ s/ //g;
|
||||||
|
|||||||
+152
-152
@@ -12,18 +12,18 @@ sub new
|
|||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
my $self = bless {}, $class;
|
my $self = bless {}, $class;
|
||||||
|
|
||||||
# Check to see if the configuration file exists.
|
# Check to see if the configuration file exists.
|
||||||
if (!-e "$Auto::Bin/../etc/$file") {
|
if (!-e "$Auto::Bin/../etc/$file") {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Open, read and close the config.
|
# Open, read and close the config.
|
||||||
open(my $FCONF, q{<}, "$Auto::Bin/../etc/$file") or return 0;
|
open(my $FCONF, q{<}, "$Auto::Bin/../etc/$file") or return 0;
|
||||||
my @cosfl = <$FCONF> or return 0;
|
my @cosfl = <$FCONF> or return 0;
|
||||||
close $FCONF or return 0;
|
close $FCONF or return 0;
|
||||||
|
|
||||||
# Save it to self variable.
|
# Save it to self variable.
|
||||||
$self->{'config'}->{'path'} = "$Auto::Bin/../etc/$file";
|
$self->{'config'}->{'path'} = "$Auto::Bin/../etc/$file";
|
||||||
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
@@ -31,148 +31,148 @@ sub new
|
|||||||
# Parse the configuration file.
|
# Parse the configuration file.
|
||||||
sub parse
|
sub parse
|
||||||
{
|
{
|
||||||
# Get the path to the file.
|
# Get the path to the file.
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $file = $self->{'config'}->{'path'};
|
my $file = $self->{'config'}->{'path'};
|
||||||
my $blk = 0;
|
my $blk = 0;
|
||||||
my (%rs);
|
my (%rs);
|
||||||
|
|
||||||
# Open, read and close it.
|
# Open, read and close it.
|
||||||
open(my $FCONF, q{<}, "$file") or return 0;
|
open(my $FCONF, q{<}, "$file") or return 0;
|
||||||
my @fbuf = <$FCONF> or return 0;
|
my @fbuf = <$FCONF> or return 0;
|
||||||
close $FCONF or return 0;
|
close $FCONF or return 0;
|
||||||
|
|
||||||
# Iterate the file.
|
# Iterate the file.
|
||||||
foreach my $buff (@fbuf) {
|
foreach my $buff (@fbuf) {
|
||||||
# Main newline buffer.
|
# Main newline buffer.
|
||||||
if (defined $buff) {
|
if (defined $buff) {
|
||||||
# If the line begins with a #, it's a comment so ignore it.
|
# If the line begins with a #, it's a comment so ignore it.
|
||||||
if (substr($buff, 0, 1) eq '#') {
|
if (substr($buff, 0, 1) eq '#') {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($buff =~ m/;/) {
|
if ($buff =~ m/;/) {
|
||||||
# Semicolon buffer.
|
# Semicolon buffer.
|
||||||
my @asbuf = split(';', $buff);
|
my @asbuf = split(';', $buff);
|
||||||
foreach my $asbuff (@asbuf) {
|
foreach my $asbuff (@asbuf) {
|
||||||
if (defined $asbuff) {
|
if (defined $asbuff) {
|
||||||
|
|
||||||
# Space buffer.
|
# Space buffer.
|
||||||
my @ebuf = split(' ', $asbuff);
|
my @ebuf = split(' ', $asbuff);
|
||||||
if (!defined $ebuf[0] or !defined $ebuf[1]) {
|
if (!defined $ebuf[0] or !defined $ebuf[1]) {
|
||||||
# Garbage. Ignoring.
|
# Garbage. Ignoring.
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
my $param = $ebuf[1];
|
my $param = $ebuf[1];
|
||||||
|
|
||||||
if (substr($param, 0, 1) eq '"' and substr($param, length($param) - 1, 1) ne '"') {
|
if (substr($param, 0, 1) eq '"' and substr($param, length($param) - 1, 1) ne '"') {
|
||||||
# Multi-word string.
|
# Multi-word string.
|
||||||
$param = substr($param, 1);
|
$param = substr($param, 1);
|
||||||
|
|
||||||
for (my $i = 2; $i < scalar(@ebuf); $i++) {
|
for (my $i = 2; $i < scalar(@ebuf); $i++) {
|
||||||
if (substr($ebuf[$i], length($ebuf[$i]) - 1, 1) eq '"') {
|
if (substr($ebuf[$i], length($ebuf[$i]) - 1, 1) eq '"') {
|
||||||
$param .= " ".substr($ebuf[$i], 0, length($ebuf[$i]) - 1);
|
$param .= " ".substr($ebuf[$i], 0, length($ebuf[$i]) - 1);
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$param .= " ".$ebuf[$i];
|
$param .= " ".$ebuf[$i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif (substr($param, 0, 1) eq '"' and substr($param, length($param) - 1, 1) eq '"') {
|
elsif (substr($param, 0, 1) eq '"' and substr($param, length($param) - 1, 1) eq '"') {
|
||||||
# Single-word string.
|
# Single-word string.
|
||||||
$param = substr($param, 1, length($ebuf[1]) - 2);
|
$param = substr($param, 1, length($ebuf[1]) - 2);
|
||||||
}
|
}
|
||||||
elsif ($param =~ m/[0-9]/) {
|
elsif ($param =~ m/[0-9]/) {
|
||||||
# Numeric.
|
# Numeric.
|
||||||
$param =~ s/[^0-9.]//g;
|
$param =~ s/[^0-9.]//g;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Garbage.
|
# Garbage.
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
my @param = ($param);
|
my @param = ($param);
|
||||||
|
|
||||||
unless (!$blk) {
|
unless (!$blk) {
|
||||||
# We're inside a block.
|
# We're inside a block.
|
||||||
if ($blk =~ m/@@@/) {
|
if ($blk =~ m/@@@/) {
|
||||||
# We're inside a block with a parameter.
|
# We're inside a block with a parameter.
|
||||||
my @sblk = split('@@@', $blk);
|
my @sblk = split('@@@', $blk);
|
||||||
|
|
||||||
# Check to see if this config option already exists.
|
# Check to see if this config option already exists.
|
||||||
if (defined $rs{$sblk[0]}{$sblk[1]}{$ebuf[0]}) {
|
if (defined $rs{$sblk[0]}{$sblk[1]}{$ebuf[0]}) {
|
||||||
# It does, so merely push this second one to the existing array.
|
# It does, so merely push this second one to the existing array.
|
||||||
push(@{ $rs{$sblk[0]}{$sblk[1]}{$ebuf[0]} }, $param);
|
push(@{ $rs{$sblk[0]}{$sblk[1]}{$ebuf[0]} }, $param);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# It doesn't, create it as an array.
|
# It doesn't, create it as an array.
|
||||||
@{ $rs{$sblk[0]}{$sblk[1]}{$ebuf[0]} } = @param;
|
@{ $rs{$sblk[0]}{$sblk[1]}{$ebuf[0]} } = @param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# We're inside a block with no parameter.
|
# We're inside a block with no parameter.
|
||||||
|
|
||||||
# Check to see if this config option already exists.
|
# Check to see if this config option already exists.
|
||||||
if (defined $rs{$blk}{$ebuf[0]}) {
|
if (defined $rs{$blk}{$ebuf[0]}) {
|
||||||
# It does, so merely push this second one to the existing array.
|
# It does, so merely push this second one to the existing array.
|
||||||
push(@{ $rs{$blk}{$ebuf[0]} }, $param);
|
push(@{ $rs{$blk}{$ebuf[0]} }, $param);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# It doesn't, create it as an array.
|
# It doesn't, create it as an array.
|
||||||
@{ $rs{$blk}{$ebuf[0]} } = @param;
|
@{ $rs{$blk}{$ebuf[0]} } = @param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# We're not inside a block.
|
# We're not inside a block.
|
||||||
|
|
||||||
# Check to see if this config option already exists.
|
# Check to see if this config option already exists.
|
||||||
if (defined $rs{$ebuf[0]}) {
|
if (defined $rs{$ebuf[0]}) {
|
||||||
# It does, so merely push this second one to the existing array.
|
# It does, so merely push this second one to the existing array.
|
||||||
push(@{ $rs{$ebuf[0]} }, $param);
|
push(@{ $rs{$ebuf[0]} }, $param);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# It doesn't, create it as an array.
|
# It doesn't, create it as an array.
|
||||||
@{ $rs{$ebuf[0]} } = @param;
|
@{ $rs{$ebuf[0]} } = @param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# No semicolon space buffer.
|
# No semicolon space buffer.
|
||||||
my @ebuf = split(' ', $buff);
|
my @ebuf = split(' ', $buff);
|
||||||
|
|
||||||
if (!defined $ebuf[0]) {
|
if (!defined $ebuf[0]) {
|
||||||
# Garbage. Ignoring.
|
# Garbage. Ignoring.
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined $ebuf[1]) {
|
if (defined $ebuf[1]) {
|
||||||
if ($ebuf[1] eq '{') {
|
if ($ebuf[1] eq '{') {
|
||||||
# This is the beginning of a block with no parameter.
|
# This is the beginning of a block with no parameter.
|
||||||
$blk = $ebuf[0];
|
$blk = $ebuf[0];
|
||||||
}
|
}
|
||||||
elsif (defined $ebuf[2]) {
|
elsif (defined $ebuf[2]) {
|
||||||
if ($ebuf[2] eq '{') {
|
if ($ebuf[2] eq '{') {
|
||||||
# This is the beginning of a block with a parameter.
|
# This is the beginning of a block with a parameter.
|
||||||
my $param = $ebuf[1];
|
my $param = $ebuf[1];
|
||||||
$param =~ s/"//g;
|
$param =~ s/"//g;
|
||||||
$blk = $ebuf[0].'@@@'.$param;
|
$blk = $ebuf[0].'@@@'.$param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($ebuf[0] eq '}') {
|
if ($ebuf[0] eq '}') {
|
||||||
# This is the end of a block.
|
# This is the end of a block.
|
||||||
$blk = 0;
|
$blk = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Return the configuration data.
|
# Return the configuration data.
|
||||||
return %rs;
|
return %rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+343
-295
@@ -9,26 +9,26 @@ use API::IRC;
|
|||||||
|
|
||||||
# Raw parsing hash.
|
# Raw parsing hash.
|
||||||
our %RAWC = (
|
our %RAWC = (
|
||||||
'001' => \&num001,
|
'001' => \&num001,
|
||||||
'005' => \&num005,
|
'005' => \&num005,
|
||||||
'353' => \&num353,
|
'353' => \&num353,
|
||||||
'432' => \&num432,
|
'432' => \&num432,
|
||||||
'433' => \&num433,
|
'433' => \&num433,
|
||||||
'438' => \&num438,
|
'438' => \&num438,
|
||||||
'465' => \&num465,
|
'465' => \&num465,
|
||||||
'471' => \&num471,
|
'471' => \&num471,
|
||||||
'473' => \&num473,
|
'473' => \&num473,
|
||||||
'474' => \&num474,
|
'474' => \&num474,
|
||||||
'475' => \&num475,
|
'475' => \&num475,
|
||||||
'477' => \&num477,
|
'477' => \&num477,
|
||||||
'JOIN' => \&cjoin,
|
'JOIN' => \&cjoin,
|
||||||
'KICK' => \&kick,
|
'KICK' => \&kick,
|
||||||
'MODE' => \&mode,
|
'MODE' => \&mode,
|
||||||
'NICK' => \&nick,
|
'NICK' => \&nick,
|
||||||
'NOTICE' => \¬ice,
|
'NOTICE' => \¬ice,
|
||||||
'PART' => \&part,
|
'PART' => \&part,
|
||||||
'PRIVMSG' => \&privmsg,
|
'PRIVMSG' => \&privmsg,
|
||||||
'QUIT' => \&quit,
|
'QUIT' => \&quit,
|
||||||
'TOPIC' => \&topic,
|
'TOPIC' => \&topic,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -50,33 +50,33 @@ API::Std::event_add("on_topic");
|
|||||||
# Parse raw data.
|
# Parse raw data.
|
||||||
sub ircparse
|
sub ircparse
|
||||||
{
|
{
|
||||||
my ($svr, $data) = @_;
|
my ($svr, $data) = @_;
|
||||||
|
|
||||||
# Split spaces into @ex.
|
# Split spaces into @ex.
|
||||||
my @ex = split(' ', $data);
|
my @ex = split /\s+/, $data;
|
||||||
|
|
||||||
# Make sure there is enough data.
|
# Make sure there is enough data.
|
||||||
if (defined $ex[0] and defined $ex[1]) {
|
if (defined $ex[0] and defined $ex[1]) {
|
||||||
# If it's a ping...
|
# If it's a ping...
|
||||||
if ($ex[0] eq 'PING') {
|
if ($ex[0] eq 'PING') {
|
||||||
# send a PONG.
|
# send a PONG.
|
||||||
Auto::socksnd($svr, "PONG ".$ex[1]);
|
Auto::socksnd($svr, "PONG ".$ex[1]);
|
||||||
}
|
}
|
||||||
# If it's AUTHENTICATE
|
# If it's AUTHENTICATE
|
||||||
elsif ($ex[0] eq 'AUTHENTICATE') {
|
elsif ($ex[0] eq 'AUTHENTICATE') {
|
||||||
if (API::Std::mod_exists("SASLAuth")) {
|
if (API::Std::mod_exists("SASLAuth")) {
|
||||||
m_SASLAuth::handle_authenticate($svr, @ex);
|
M::SASLAuth::handle_authenticate($svr, @ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# otherwise, check %RAWC for ex[1].
|
# otherwise, check %RAWC for ex[1].
|
||||||
if (defined $RAWC{$ex[1]}) {
|
if (defined $RAWC{$ex[1]}) {
|
||||||
&{ $RAWC{$ex[1]} }($svr, @ex);
|
&{ $RAWC{$ex[1]} }($svr, @ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
###########################
|
###########################
|
||||||
@@ -87,41 +87,41 @@ sub ircparse
|
|||||||
# Successful connection.
|
# Successful connection.
|
||||||
sub num001
|
sub num001
|
||||||
{
|
{
|
||||||
my ($svr, @ex) = @_;
|
my ($svr, @ex) = @_;
|
||||||
|
|
||||||
$got_001{$svr} = 1;
|
$got_001{$svr} = 1;
|
||||||
|
|
||||||
# In case we don't get NICK from the server.
|
# In case we don't get NICK from the server.
|
||||||
if (defined $botnick{$svr}{newnick}) {
|
if (defined $botnick{$svr}{newnick}) {
|
||||||
$botnick{$svr}{nick} = $botnick{$svr}{newnick};
|
$botnick{$svr}{nick} = $botnick{$svr}{newnick};
|
||||||
delete $botnick{$svr}{newnick};
|
delete $botnick{$svr}{newnick};
|
||||||
}
|
}
|
||||||
|
|
||||||
# Trigger on_connect.
|
# Trigger on_connect.
|
||||||
API::Std::event_run("on_connect", $svr);
|
API::Std::event_run("on_connect", $svr);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:005
|
# Parse: Numeric:005
|
||||||
# Prefixes and channel modes.
|
# Prefixes and channel modes.
|
||||||
sub num005
|
sub num005
|
||||||
{
|
{
|
||||||
my ($svr, @ex) = @_;
|
my ($svr, @ex) = @_;
|
||||||
|
|
||||||
# Find PREFIX and CHANMODES.
|
# Find PREFIX and CHANMODES.
|
||||||
foreach my $ex (@ex) {
|
foreach my $ex (@ex) {
|
||||||
if ($ex =~ m/^PREFIX/xsm) {
|
if ($ex =~ m/^PREFIX/xsm) {
|
||||||
# Found PREFIX.
|
# Found PREFIX.
|
||||||
my $rpx = substr($ex, 8);
|
my $rpx = substr($ex, 8);
|
||||||
my ($pm, $pp) = split('\)', $rpx);
|
my ($pm, $pp) = split('\)', $rpx);
|
||||||
my @apm = split(//, $pm);
|
my @apm = split(//, $pm);
|
||||||
my @app = split(//, $pp);
|
my @app = split(//, $pp);
|
||||||
foreach my $ppm (@apm) {
|
foreach my $ppm (@apm) {
|
||||||
# Store data.
|
# Store data.
|
||||||
$csprefix{$svr}{$ppm} = shift(@app);
|
$csprefix{$svr}{$ppm} = shift(@app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ($ex =~ m/^CHANMODES/xsm) {
|
elsif ($ex =~ m/^CHANMODES/xsm) {
|
||||||
# Found CHANMODES.
|
# Found CHANMODES.
|
||||||
my ($mtl, $mtp, $mtpp, $mts) = split m/[,]/xsm, substr($ex, 10);
|
my ($mtl, $mtp, $mtpp, $mts) = split m/[,]/xsm, substr($ex, 10);
|
||||||
@@ -134,183 +134,186 @@ sub num005
|
|||||||
# Modes without parameter.
|
# Modes without parameter.
|
||||||
foreach (split(//, $mts)) { $chanmodes{$svr}{$_} = 4; }
|
foreach (split(//, $mts)) { $chanmodes{$svr}{$_} = 4; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:353
|
# Parse: Numeric:353
|
||||||
# NAMES reply.
|
# NAMES reply.
|
||||||
sub num353
|
sub num353
|
||||||
{
|
{
|
||||||
my ($svr, @ex) = @_;
|
my ($svr, @ex) = @_;
|
||||||
|
|
||||||
# Get rid of the colon.
|
# Get rid of the colon.
|
||||||
$ex[5] = substr($ex[5], 1);
|
$ex[5] = substr($ex[5], 1);
|
||||||
# Delete the old chanusers hash if it exists.
|
# Delete the old chanusers hash if it exists.
|
||||||
delete $chanusers{$svr}{$ex[4]} if (defined $chanusers{$svr}{$ex[4]});
|
delete $chanusers{$svr}{$ex[4]} if (defined $chanusers{$svr}{$ex[4]});
|
||||||
# Iterate through each user.
|
# Iterate through each user.
|
||||||
for (my $i = 5; $i < scalar(@ex); $i++) {
|
for (my $i = 5; $i < scalar(@ex); $i++) {
|
||||||
my $fi = 0;
|
my $fi = 0;
|
||||||
foreach (keys %{ $csprefix{$svr} }) {
|
foreach (keys %{ $csprefix{$svr} }) {
|
||||||
# Check if the user has status in the channel.
|
# Check if the user has status in the channel.
|
||||||
if (substr($ex[$i], 0, 1) eq $csprefix{$svr}{$_}) {
|
if (substr($ex[$i], 0, 1) eq $csprefix{$svr}{$_}) {
|
||||||
# He/she does. Lets set that.
|
# He/she does. Lets set that.
|
||||||
if (defined $chanusers{$svr}{$ex[4]}{lc(substr($ex[$i], 1))}) {
|
if (defined $chanusers{$svr}{$ex[4]}{lc(substr($ex[$i], 1))}) {
|
||||||
# If the user has multiple statuses.
|
# If the user has multiple statuses.
|
||||||
$chanusers{$svr}{$ex[4]}{lc(substr($ex[$i], 1))} .= $_;
|
$chanusers{$svr}{$ex[4]}{lc(substr($ex[$i], 1))} .= $_;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Or not.
|
# Or not.
|
||||||
$chanusers{$svr}{$ex[4]}{lc(substr($ex[$i], 1))} = $_;
|
$chanusers{$svr}{$ex[4]}{lc(substr($ex[$i], 1))} = $_;
|
||||||
}
|
}
|
||||||
$fi = 1;
|
$fi = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# They had status, so go to the next user.
|
# They had status, so go to the next user.
|
||||||
next if $fi;
|
next if $fi;
|
||||||
# They didn't, set them as a normal user.
|
# They didn't, set them as a normal user.
|
||||||
if (!defined $chanusers{$svr}{$ex[4]}{lc($ex[$i])}) {
|
if (!defined $chanusers{$svr}{$ex[4]}{lc($ex[$i])}) {
|
||||||
$chanusers{$svr}{$ex[4]}{lc($ex[$i])} = 1;
|
$chanusers{$svr}{$ex[4]}{lc($ex[$i])} = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:432
|
# Parse: Numeric:432
|
||||||
# Erroneous nickname.
|
# Erroneous nickname.
|
||||||
sub num432
|
sub num432
|
||||||
{
|
{
|
||||||
my ($svr, undef) = @_;
|
my ($svr, undef) = @_;
|
||||||
|
|
||||||
if ($got_001{$svr}) {
|
if ($got_001{$svr}) {
|
||||||
err(3, "Got error from server[".$svr."]: Erroneous nickname.", 0);
|
err(3, "Got error from server[".$svr."]: Erroneous nickname.", 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
err(2, "Got error from server[".$svr."] before 001: Erroneous nickname. Closing connection.", 0);
|
err(2, "Got error from server[".$svr."] before 001: Erroneous nickname. Closing connection.", 0);
|
||||||
API::IRC::quit($svr, "An error occurred.");
|
API::IRC::quit($svr, "An error occurred.");
|
||||||
}
|
}
|
||||||
|
|
||||||
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:433
|
# Parse: Numeric:433
|
||||||
# Nickname is already in use.
|
# Nickname is already in use.
|
||||||
sub num433
|
sub num433
|
||||||
{
|
{
|
||||||
my ($svr, undef) = @_;
|
my ($svr, undef) = @_;
|
||||||
|
|
||||||
if (defined $botnick{$svr}{newnick}) {
|
if (defined $botnick{$svr}{newnick}) {
|
||||||
API::IRC::nick($svr, $botnick{$svr}{newnick}."_");
|
API::IRC::nick($svr, $botnick{$svr}{newnick}."_");
|
||||||
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:438
|
# Parse: Numeric:438
|
||||||
# Nick change too fast.
|
# Nick change too fast.
|
||||||
sub num438
|
sub num438
|
||||||
{
|
{
|
||||||
my ($svr, @ex) = @_;
|
my ($svr, @ex) = @_;
|
||||||
|
|
||||||
if (defined $botnick{$svr}{newnick}) {
|
if (defined $botnick{$svr}{newnick}) {
|
||||||
API::Std::timer_add("num438_".$botnick{$svr}{newnick}, 1, $ex[11], sub {
|
API::Std::timer_add("num438_".$botnick{$svr}{newnick}, 1, $ex[11], sub {
|
||||||
API::IRC::nick($Parser::IRC::botnick{$svr}{newnick});
|
API::IRC::nick($Parser::IRC::botnick{$svr}{newnick});
|
||||||
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:465
|
# Parse: Numeric:465
|
||||||
# You're banned creep!
|
# You're banned creep!
|
||||||
sub num465
|
sub num465
|
||||||
{
|
{
|
||||||
my ($svr, undef) = @_;
|
my ($svr, undef) = @_;
|
||||||
|
|
||||||
err(3, "Banned from ".$svr."! Closing link...", 0);
|
err(3, "Banned from ".$svr."! Closing link...", 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:471
|
# Parse: Numeric:471
|
||||||
# Cannot join channel: Channel is full.
|
# Cannot join channel: Channel is full.
|
||||||
sub num471
|
sub num471
|
||||||
{
|
{
|
||||||
my ($svr, (undef, undef, undef, $chan)) = @_;
|
my ($svr, (undef, undef, undef, $chan)) = @_;
|
||||||
|
|
||||||
err(3, "Cannot join channel ".$chan." on ".$svr.": Channel is full.", 0);
|
err(3, "Cannot join channel ".$chan." on ".$svr.": Channel is full.", 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:473
|
# Parse: Numeric:473
|
||||||
# Cannot join channel: Channel is invite-only.
|
# Cannot join channel: Channel is invite-only.
|
||||||
sub num473
|
sub num473
|
||||||
{
|
{
|
||||||
my ($svr, (undef, undef, undef, $chan)) = @_;
|
my ($svr, (undef, undef, undef, $chan)) = @_;
|
||||||
|
|
||||||
err(3, "Cannot join channel ".$chan." on ".$svr.": Channel is invite-only.", 0);
|
err(3, "Cannot join channel ".$chan." on ".$svr.": Channel is invite-only.", 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:474
|
# Parse: Numeric:474
|
||||||
# Cannot join channel: Banned from channel.
|
# Cannot join channel: Banned from channel.
|
||||||
sub num474
|
sub num474
|
||||||
{
|
{
|
||||||
my ($svr, (undef, undef, undef, $chan)) = @_;
|
my ($svr, (undef, undef, undef, $chan)) = @_;
|
||||||
|
|
||||||
err(3, "Cannot join channel ".$chan." on ".$svr.": Banned from channel.", 0);
|
err(3, "Cannot join channel ".$chan." on ".$svr.": Banned from channel.", 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:475
|
# Parse: Numeric:475
|
||||||
# Cannot join channel: Bad key.
|
# Cannot join channel: Bad key.
|
||||||
sub num475
|
sub num475
|
||||||
{
|
{
|
||||||
my ($svr, (undef, undef, undef, $chan)) = @_;
|
my ($svr, (undef, undef, undef, $chan)) = @_;
|
||||||
|
|
||||||
err(3, "Cannot join channel ".$chan." on ".$svr.": Bad key.", 0);
|
err(3, "Cannot join channel ".$chan." on ".$svr.": Bad key.", 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: Numeric:477
|
# Parse: Numeric:477
|
||||||
# Cannot join channel: Need registered nickname.
|
# Cannot join channel: Need registered nickname.
|
||||||
sub num477
|
sub num477
|
||||||
{
|
{
|
||||||
my ($svr, (undef, undef, undef, $chan)) = @_;
|
my ($svr, (undef, undef, undef, $chan)) = @_;
|
||||||
|
|
||||||
err(3, "Cannot join channel ".$chan." on ".$svr.": Need registered nickname.", 0);
|
err(3, "Cannot join channel ".$chan." on ".$svr.": Need registered nickname.", 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: JOIN
|
# Parse: JOIN
|
||||||
sub cjoin
|
sub cjoin
|
||||||
{
|
{
|
||||||
my ($svr, @ex) = @_;
|
my ($svr, @ex) = @_;
|
||||||
my %src = API::IRC::usrc(substr($ex[0], 1));
|
my %src = API::IRC::usrc(substr($ex[0], 1));
|
||||||
|
my $chan = $ex[2];
|
||||||
# Check if this is coming from ourselves.
|
$chan =~ s/^://gxsm;
|
||||||
if ($src{nick} eq $botnick{$svr}{nick}) {
|
|
||||||
$botchans{$svr}{substr $ex[2], 1} = 1;
|
# Check if this is coming from ourselves.
|
||||||
API::Std::event_run("on_ucjoin", ($svr, substr($ex[2], 1)));
|
if ($src{nick} eq $botnick{$svr}{nick}) {
|
||||||
}
|
$botchans{$svr}{lc $chan} = 1;
|
||||||
else {
|
API::Std::event_run("on_ucjoin", ($svr, $chan));
|
||||||
# It isn't. Update chanusers and trigger on_rcjoin.
|
}
|
||||||
$chanusers{$svr}{substr $ex[2], 1}{$src{nick}} = 1;
|
else {
|
||||||
API::Std::event_run("on_rcjoin", ($svr, \%src, substr($ex[2], 1)));
|
# It isn't. Update chanusers and trigger on_rcjoin.
|
||||||
}
|
$chanusers{$svr}{lc $chan}{$src{nick}} = 1;
|
||||||
|
$src{svr} = $svr;
|
||||||
return 1;
|
API::Std::event_run("on_rcjoin", (\%src, $chan));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: KICK
|
# Parse: KICK
|
||||||
@@ -451,39 +454,50 @@ sub mode
|
|||||||
# Parse: NICK
|
# Parse: NICK
|
||||||
sub nick
|
sub nick
|
||||||
{
|
{
|
||||||
my ($svr, ($uex, undef, $nex)) = @_;
|
my ($svr, ($uex, undef, $nex)) = @_;
|
||||||
$nex = substr($nex, 1);
|
$nex = substr($nex, 1);
|
||||||
|
|
||||||
my %src = API::IRC::usrc(substr($uex, 1));
|
my %src = API::IRC::usrc(substr($uex, 1));
|
||||||
|
|
||||||
# Check if this is coming from ourselves.
|
# Check if this is coming from ourselves.
|
||||||
if ($src{nick} eq $botnick{$svr}{nick}) {
|
if ($src{nick} eq $botnick{$svr}{nick}) {
|
||||||
# It is. Update bot nick hash.
|
# It is. Update bot nick hash.
|
||||||
$botnick{$svr}{nick} = $nex;
|
$botnick{$svr}{nick} = $nex;
|
||||||
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
delete $botnick{$svr}{newnick} if (defined $botnick{$svr}{newnick});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# It isn't. Update chanusers and trigger on_nick.
|
# It isn't. Update chanusers and trigger on_nick.
|
||||||
foreach my $chk (keys %{ $chanusers{$svr} }) {
|
foreach my $chk (keys %{ $chanusers{$svr} }) {
|
||||||
if (defined $chanusers{$svr}{$chk}{$src{nick}}) {
|
if (defined $chanusers{$svr}{$chk}{$src{nick}}) {
|
||||||
$chanusers{$svr}{$chk}{$nex} = $chanusers{$svr}{$chk}{$src{nick}};
|
$chanusers{$svr}{$chk}{$nex} = $chanusers{$svr}{$chk}{$src{nick}};
|
||||||
delete $chanusers{$svr}{$chk}{$src{nick}};
|
delete $chanusers{$svr}{$chk}{$src{nick}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
API::Std::event_run("on_nick", ($svr, \%src, $nex));
|
API::Std::event_run("on_nick", ($svr, \%src, $nex));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: NOTICE
|
# Parse: NOTICE
|
||||||
sub notice
|
sub notice
|
||||||
{
|
{
|
||||||
my ($svr, @ex) = @_;
|
my ($svr, @ex) = @_;
|
||||||
|
|
||||||
API::Std::event_run("on_notice", ($svr, @ex));
|
# Ensure this is coming from a user rather than a server.
|
||||||
|
if ($ex[0] !~ m/!/xsm) { return; }
|
||||||
return 1;
|
|
||||||
|
# Prepare all the data.
|
||||||
|
my %src = API::IRC::usrc(substr $ex[0], 1);
|
||||||
|
my $target = $ex[2];
|
||||||
|
shift @ex; shift @ex; shift @ex;
|
||||||
|
$ex[0] = substr $ex[0], 1;
|
||||||
|
$src{svr} = $svr;
|
||||||
|
|
||||||
|
# Send it off.
|
||||||
|
API::Std::event_run("on_notice", (\%src, $target, @ex));
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: PART
|
# Parse: PART
|
||||||
@@ -515,102 +529,136 @@ sub part
|
|||||||
# Parse: PRIVMSG
|
# Parse: PRIVMSG
|
||||||
sub privmsg
|
sub privmsg
|
||||||
{
|
{
|
||||||
my ($svr, @ex) = @_;
|
my ($svr, @ex) = @_;
|
||||||
my %data = API::IRC::usrc(substr($ex[0], 1));
|
my %data = API::IRC::usrc(substr($ex[0], 1));
|
||||||
|
|
||||||
my @argv;
|
# Ensure this is coming from a user rather than a server.
|
||||||
for (my $i = 4; $i < scalar(@ex); $i++) {
|
if ($ex[0] !~ m/!/xsm) { return; }
|
||||||
push(@argv, $ex[$i]);
|
|
||||||
}
|
my @argv;
|
||||||
$data{svr} = $svr;
|
for (my $i = 4; $i < scalar(@ex); $i++) {
|
||||||
@{ $data{args} } = @argv;
|
push(@argv, $ex[$i]);
|
||||||
|
}
|
||||||
my ($cmd, $cprefix, $rprefix);
|
$data{svr} = $svr;
|
||||||
# Check if it's to a channel or to us.
|
|
||||||
if (lc($ex[2]) eq lc($botnick{$svr}{nick})) {
|
my ($cmd, $cprefix, $rprefix);
|
||||||
# It is coming to us in a private message.
|
# Check if it's to a channel or to us.
|
||||||
$cmd = uc(substr($ex[3], 1));
|
if (lc($ex[2]) eq lc($botnick{$svr}{nick})) {
|
||||||
if (defined $API::Std::CMDS{$cmd}) {
|
# It is coming to us in a private message.
|
||||||
# If this is indeed a command, continue.
|
|
||||||
if ($API::Std::CMDS{$cmd}{lvl} == 1 or $API::Std::CMDS{$cmd}{lvl} == 2) {
|
# Ensure it's a valid length.
|
||||||
# Ensure the level is private or all.
|
if (length($ex[3]) > 1) {
|
||||||
if (!defined $Core::IRC::usercmd{$data{nick}.'@'.$data{host}}) { $Core::IRC::usercmd{$data{nick}.'@'.$data{host}} = 0; }
|
$cmd = uc(substr($ex[3], 1));
|
||||||
if (API::Std::ratelimit_check(%data)) {
|
if (defined $API::Std::CMDS{$cmd}) {
|
||||||
# Continue if the user has not passed the ratelimit amount.
|
# If this is indeed a command, continue.
|
||||||
if ($API::Std::CMDS{$cmd}{priv}) {
|
if ($API::Std::CMDS{$cmd}{lvl} == 1 or $API::Std::CMDS{$cmd}{lvl} == 2) {
|
||||||
# If this command requires a privilege...
|
# Ensure the level is private or all.
|
||||||
if (API::Std::has_priv(API::Std::match_user(%data), $API::Std::CMDS{$cmd}{priv})) {
|
if (API::Std::ratelimit_check(%data)) {
|
||||||
# Make sure they have it.
|
# Continue if the user has not passed the ratelimit amount.
|
||||||
&{ $API::Std::CMDS{$cmd}{'sub'} }(%data);
|
if ($API::Std::CMDS{$cmd}{priv}) {
|
||||||
|
# If this command requires a privilege...
|
||||||
|
if (API::Std::has_priv(API::Std::match_user(%data), $API::Std::CMDS{$cmd}{priv})) {
|
||||||
|
# Make sure they have it.
|
||||||
|
&{ $API::Std::CMDS{$cmd}{'sub'} }(\%data, @argv);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Else give them the boot.
|
||||||
|
API::IRC::notice($data{svr}, $data{nick}, API::Std::trans("Permission denied").".");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Else give them the boot.
|
# Else execute the command without any extra checks.
|
||||||
API::IRC::notice($data{svr}, $data{nick}, API::Std::trans("Permission denied").".");
|
&{ $API::Std::CMDS{$cmd}{'sub'} }(\%data, @argv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Else execute the command without any extra checks.
|
# Send them a notice about their bad deed.
|
||||||
&{ $API::Std::CMDS{$cmd}{'sub'} }(%data);
|
API::IRC::notice($data{svr}, $data{nick}, trans('Rate limit exceeded').q{.});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
# Send them a notice about their bad deed.
|
}
|
||||||
API::IRC::notice($data{svr}, $data{nick}, trans('Rate limit exceeded').q{.});
|
|
||||||
}
|
# Trigger event on_uprivmsg.
|
||||||
}
|
shift @ex; shift @ex; shift @ex;
|
||||||
}
|
$ex[0] = substr $ex[0], 1;
|
||||||
|
API::Std::event_run("on_uprivmsg", (\%data, @ex));
|
||||||
# Trigger event on_uprivmsg.
|
}
|
||||||
API::Std::event_run("on_uprivmsg", ($svr, @ex));
|
else {
|
||||||
}
|
# It is coming to us in a channel message.
|
||||||
else {
|
$data{chan} = $ex[2];
|
||||||
# It is coming to us in a channel message.
|
# Ensure it's a valid length before continuing.
|
||||||
$data{chan} = $ex[2];
|
if (length($ex[3]) > 1) {
|
||||||
$cprefix = (conf_get("fantasy_pf"))[0][0];
|
$cprefix = (conf_get("fantasy_pf"))[0][0];
|
||||||
$rprefix = substr($ex[3], 1, 1);
|
$rprefix = substr($ex[3], 1, 1);
|
||||||
$cmd = uc(substr($ex[3], 2));
|
$cmd = uc(substr($ex[3], 2));
|
||||||
if (defined $API::Std::CMDS{$cmd}) {
|
if (defined $API::Std::CMDS{$cmd} and $rprefix eq $cprefix) {
|
||||||
# If this is indeed a command, continue.
|
# If this is indeed a command, continue.
|
||||||
if ($API::Std::CMDS{$cmd}{lvl} == 0 or $API::Std::CMDS{$cmd}{lvl} == 2) {
|
if ($API::Std::CMDS{$cmd}{lvl} == 0 or $API::Std::CMDS{$cmd}{lvl} == 2) {
|
||||||
# Ensure the level is public or all.
|
# Ensure the level is public or all.
|
||||||
if (!defined $Core::IRC::usercmd{$data{nick}.'@'.$data{host}}) { $Core::IRC::usercmd{$data{nick}.'@'.$data{host}} = 0; }
|
if (API::Std::ratelimit_check(%data)) {
|
||||||
if (API::Std::ratelimit_check(%data)) {
|
# Continue if the user has not passed the ratelimit amount.
|
||||||
# Continue if the user has not passed the ratelimit amount.
|
if ($API::Std::CMDS{$cmd}{priv}) {
|
||||||
if ($API::Std::CMDS{$cmd}{priv}) {
|
# If this command takes a privilege...
|
||||||
# If this command takes a privilege...
|
if (API::Std::has_priv(API::Std::match_user(%data), $API::Std::CMDS{$cmd}{priv})) {
|
||||||
if (API::Std::has_priv(API::Std::match_user(%data), $API::Std::CMDS{$cmd}{priv})) {
|
# Make sure they have it.
|
||||||
# Make sure they have it.
|
&{ $API::Std::CMDS{$cmd}{'sub'} }(\%data, @argv);
|
||||||
&{ $API::Std::CMDS{$cmd}{'sub'} }(%data) if $rprefix eq $cprefix;
|
}
|
||||||
|
else {
|
||||||
|
# Else give them the boot.
|
||||||
|
API::IRC::notice($data{svr}, $data{nick}, API::Std::trans('Permission denied').q{.});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Else give them the boot.
|
# Else continue executing without any extra checks.
|
||||||
API::IRC::notice($data{svr}, $data{nick}, API::Std::trans("Permission denied").".");
|
&{ $API::Std::CMDS{$cmd}{'sub'} }(\%data, @argv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Else continue executing without any extra checks.
|
# Send them a notice about their bad deed.
|
||||||
&{ $API::Std::CMDS{$cmd}{'sub'} }(%data) if $rprefix eq $cprefix;
|
API::IRC::notice($data{svr}, $data{nick}, trans('Rate limit exceeded').q{.});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
elsif ($API::Std::CMDS{$cmd}{lvl} == 3) {
|
||||||
# Send them a notice about their bad deed.
|
# Or if it's a logchan command...
|
||||||
API::IRC::notice($data{svr}, $data{nick}, trans('Rate limit exceeded').q{.});
|
my ($lcn, $lcc) = split '/', (conf_get('logchan'))[0][0];
|
||||||
|
if ($lcn eq $data{svr} and lc $lcc eq lc $data{chan}) {
|
||||||
|
# Check if it's being sent from the logchan.
|
||||||
|
if ($API::Std::CMDS{$cmd}{priv}) {
|
||||||
|
# If this command takes a privilege...
|
||||||
|
if (API::Std::has_priv(API::Std::match_user(%data), $API::Std::CMDS{$cmd}{priv})) {
|
||||||
|
# Make sure they have it.
|
||||||
|
&{ $API::Std::CMDS{$cmd}{'sub'} }(\%data, @argv);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Else give them the boot.
|
||||||
|
API::IRC::notice($data{svr}, $data{nick}, API::Std::trans('Permission denied').q{.});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Else continue executing without any extra checks.
|
||||||
|
&{ $API::Std::CMDS{$cmd}{'sub'} }(\%data, @argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Trigger event on_cprivmsg.
|
# Trigger event on_cprivmsg.
|
||||||
API::Std::event_run("on_cprivmsg", ($svr, @ex));
|
my $target = $ex[2]; delete $data{chan};
|
||||||
}
|
shift @ex; shift @ex; shift @ex;
|
||||||
|
$ex[0] = substr $ex[0], 1;
|
||||||
return 1;
|
API::Std::event_run("on_cprivmsg", (\%data, $target, @ex));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse: QUIT
|
# Parse: QUIT
|
||||||
sub quit
|
sub quit
|
||||||
{
|
{
|
||||||
my ($svr, @ex) = @_;
|
my ($svr, @ex) = @_;
|
||||||
my %src = API::IRC::usrc(substr($ex[0], 1));
|
my %src = API::IRC::usrc(substr($ex[0], 1));
|
||||||
|
|
||||||
# Set $msg to the quit message.
|
# Set $msg to the quit message.
|
||||||
my $msg = 0;
|
my $msg = 0;
|
||||||
@@ -632,23 +680,23 @@ sub quit
|
|||||||
# Parse: TOPIC
|
# Parse: TOPIC
|
||||||
sub topic
|
sub topic
|
||||||
{
|
{
|
||||||
my ($svr, @ex) = @_;
|
my ($svr, @ex) = @_;
|
||||||
my %src = API::IRC::usrc(substr($ex[0], 1));
|
my %src = API::IRC::usrc(substr($ex[0], 1));
|
||||||
|
|
||||||
# Ignore it if it's coming from us.
|
# Ignore it if it's coming from us.
|
||||||
if (lc($src{nick}) ne lc($botnick{$svr}{nick})) {
|
if (lc($src{nick}) ne lc($botnick{$svr}{nick})) {
|
||||||
$src{chan} = $ex[2];
|
$src{chan} = $ex[2];
|
||||||
my (@argv);
|
my (@argv);
|
||||||
$argv[0] = substr($ex[3], 1);
|
$argv[0] = substr($ex[3], 1);
|
||||||
if (defined $ex[4]) {
|
if (defined $ex[4]) {
|
||||||
for (my $i = 4; $i < scalar(@ex); $i++) {
|
for (my $i = 4; $i < scalar(@ex); $i++) {
|
||||||
push(@argv, $ex[$i]);
|
push(@argv, $ex[$i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
API::Std::event_run("on_topic", ($svr, \%src, @argv));
|
API::Std::event_run("on_topic", ($svr, \%src, @argv));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+50
-50
@@ -10,56 +10,56 @@ use API::Log qw(dbug alog);
|
|||||||
# Parser.
|
# Parser.
|
||||||
sub parse
|
sub parse
|
||||||
{
|
{
|
||||||
my ($lang) = @_;
|
my ($lang) = @_;
|
||||||
|
|
||||||
# Check that the language file exists.
|
# Check that the language file exists.
|
||||||
unless (-e "$Auto::Bin/../lang/$lang.alf") {
|
unless (-e "$Auto::Bin/../lang/$lang.alf") {
|
||||||
# Otherwise, use English.
|
# Otherwise, use English.
|
||||||
dbug "Language '$lang' not found. Using English.";
|
dbug "Language '$lang' not found. Using English.";
|
||||||
alog "Language '$lang' not found. Using English.";
|
alog "Language '$lang' not found. Using English.";
|
||||||
$lang = "en";
|
$lang = "en";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Open, read and close the file.
|
# Open, read and close the file.
|
||||||
open(my $FALF, q{<}, "$Auto::Bin/../lang/$lang.alf") or return 0;
|
open(my $FALF, q{<}, "$Auto::Bin/../lang/$lang.alf") or return 0;
|
||||||
my @fbuf = <$FALF>;
|
my @fbuf = <$FALF>;
|
||||||
close $FALF;
|
close $FALF;
|
||||||
|
|
||||||
# Iterate the file buffer.
|
# Iterate the file buffer.
|
||||||
foreach my $buff (@fbuf) {
|
foreach my $buff (@fbuf) {
|
||||||
if (defined $buff) {
|
if (defined $buff) {
|
||||||
# Space buffer.
|
# Space buffer.
|
||||||
my @sbuf = split(' ', $buff);
|
my @sbuf = split(' ', $buff);
|
||||||
|
|
||||||
# Check for all required values.
|
# Check for all required values.
|
||||||
if (!defined $sbuf[0] or !defined $sbuf[1] or !defined $sbuf[2]) {
|
if (!defined $sbuf[0] or !defined $sbuf[1] or !defined $sbuf[2]) {
|
||||||
# Missing a value.
|
# Missing a value.
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Make sure the first value is "msge".
|
# Make sure the first value is "msge".
|
||||||
if ($sbuf[0] ne "msge") {
|
if ($sbuf[0] ne "msge") {
|
||||||
# It isn't.
|
# It isn't.
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $id = $sbuf[1];
|
my $id = $sbuf[1];
|
||||||
my $val = $sbuf[2];
|
my $val = $sbuf[2];
|
||||||
|
|
||||||
# If the translation is multi-word, continue to parse.
|
# If the translation is multi-word, continue to parse.
|
||||||
if (defined $sbuf[3]) {
|
if (defined $sbuf[3]) {
|
||||||
for (my $i = 3; $i < scalar(@sbuf); $i++) {
|
for (my $i = 3; $i < scalar(@sbuf); $i++) {
|
||||||
$val .= " ".$sbuf[$i];
|
$val .= " ".$sbuf[$i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Save to memory.
|
# Save to memory.
|
||||||
$id =~ s/"//g;
|
$id =~ s/"//g;
|
||||||
$val =~ s/"//g;
|
$val =~ s/"//g;
|
||||||
$API::Std::LANGE{$id} = $val;
|
$API::Std::LANGE{$id} = $val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+20
-22
@@ -1,23 +1,23 @@
|
|||||||
# Module: Badwords. See below for documentation.
|
# Module: Badwords. See below for documentation.
|
||||||
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
# This program is free software; rights to this code are stated in doc/LICENSE.
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
package m_Badwords;
|
package M::Badwords;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use feature qw(switch);
|
use feature qw(switch);
|
||||||
use API::Std qw(hook_add hook_del conf_get err);
|
use API::Std qw(hook_add hook_del conf_get err);
|
||||||
use API::IRC qw(privmsg notice kick cmode);
|
use API::IRC qw(privmsg notice kick ban);
|
||||||
|
|
||||||
# Initialization subroutine.
|
# Initialization subroutine.
|
||||||
sub _init
|
sub _init
|
||||||
{
|
{
|
||||||
# Check for required configuration values.
|
# Check for required configuration values.
|
||||||
if (!conf_get('badwords')) {
|
if (!conf_get('badwords')) {
|
||||||
err(2, 'Please verify that you have a badwords block with word entries defined in your configuration file.', 0);
|
err(2, 'Please verify that you have a badwords block with word entries defined in your configuration file.', 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
# Create the act_on_badword hook.
|
# Create the act_on_badword hook.
|
||||||
hook_add('on_cprivmsg', 'act_on_badword', \&m_Badwords::actonbadword) or return;
|
hook_add('on_cprivmsg', 'act_on_badword', \&M::Badwords::actonbadword) or return;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
@@ -27,23 +27,21 @@ sub _init
|
|||||||
sub _void
|
sub _void
|
||||||
{
|
{
|
||||||
# Delete the act_on_badword hook.
|
# Delete the act_on_badword hook.
|
||||||
hook_del('act_on_badword') or return 0;
|
hook_del('act_on_badword') or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Callback for act_on_badword hook.
|
# Callback for act_on_badword hook.
|
||||||
sub actonbadword
|
sub actonbadword
|
||||||
{
|
{
|
||||||
my (($svr, @ex)) = @_;
|
my (($src, $chan, @msg)) = @_;
|
||||||
my %src = API::IRC::usrc(substr $ex[0], 1);
|
|
||||||
|
|
||||||
my $msg = substr $ex[3], 1;
|
my $msg = join ' ', @msg;
|
||||||
for (my $i = 4; $i < scalar @ex; $i++) { $msg .= q{ }.$ex[$i]; }
|
|
||||||
|
|
||||||
if (conf_get("badwords:$ex[2]:word")) {
|
if (conf_get("badwords:$chan:word")) {
|
||||||
my @words = @{ (conf_get("badwords:$ex[2]:word"))[0] };
|
my @words = @{ (conf_get("badwords:$chan:word"))[0] };
|
||||||
|
|
||||||
foreach (@words) {
|
foreach (@words) {
|
||||||
my ($w, $a) = split m/[:]/, $_;
|
my ($w, $a) = split m/[:]/, $_;
|
||||||
@@ -51,17 +49,17 @@ sub actonbadword
|
|||||||
if ($msg =~ m/($w)/ixsm) {
|
if ($msg =~ m/($w)/ixsm) {
|
||||||
given ($a) {
|
given ($a) {
|
||||||
when ('kick') {
|
when ('kick') {
|
||||||
kick($svr, $ex[2], $src{nick}, 'Foul language is prohibited here.');
|
kick($src->{svr}, $chan, $src->{nick}, 'Foul language is prohibited here.');
|
||||||
}
|
}
|
||||||
when ('kickban') {
|
when ('kickban') {
|
||||||
cmode($svr, $ex[2], '+b *!*@'.$src{host});
|
ban($src->{svr}, $chan, 'b', $src);
|
||||||
kick($svr, $ex[2], $src{nick}, 'Foul language is prohibited here.');
|
kick($src->{svr}, $chan, $src->{nick}, 'Foul language is prohibited here.');
|
||||||
}
|
}
|
||||||
when ('quiet') {
|
when ('quiet') {
|
||||||
cmode($svr, $ex[2], '+q *!*@'.$src{host});
|
ban($src->{svr}, $chan, 'q', $src);
|
||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
kick($svr, $ex[2], $src{nick}, 'Foul language is prohibited here.');
|
kick($src->{svr}, $chan, $src->{nick}, 'Foul language is prohibited here.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,7 +70,7 @@ sub actonbadword
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
API::Std::mod_init("Badwords", "Xelhua", "1.00", "3.0.0d", __PACKAGE__);
|
API::Std::mod_init('Badwords', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
# build: perl=5.010000
|
# build: perl=5.010000
|
||||||
|
|
||||||
@@ -124,6 +122,6 @@ Changing the obvious to your wish.
|
|||||||
|
|
||||||
=over
|
=over
|
||||||
|
|
||||||
This module is compatible with Auto version 3.0.0a3+.
|
This module is compatible with Auto version 3.0.0a4+.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
+36
-38
@@ -1,7 +1,7 @@
|
|||||||
# Module: Bitly. See below for documentation.
|
# Module: Bitly. See below for documentation.
|
||||||
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
# This program is free software; rights to this code are stated in doc/LICENSE.
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
package m_Bitly;
|
package M::Bitly;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use API::Std qw(cmd_add cmd_del conf_get err trans);
|
use API::Std qw(cmd_add cmd_del conf_get err trans);
|
||||||
@@ -13,13 +13,13 @@ use URI::Escape;
|
|||||||
sub _init
|
sub _init
|
||||||
{
|
{
|
||||||
# Check for required configuration values.
|
# Check for required configuration values.
|
||||||
if (!(conf_get('bitly:user'))[0][0] or !(conf_get('bitly:key'))[0][0]) {
|
if (!(conf_get('bitly:user'))[0][0] or !(conf_get('bitly:key'))[0][0]) {
|
||||||
err(2, "Please verify that you have bitly_user and bitly_key defined in your configuration file.", 0);
|
err(2, "Please verify that you have bitly_user and bitly_key defined in your configuration file.", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
# Create the SHORTEN and REVERSE commands.
|
# Create the SHORTEN and REVERSE commands.
|
||||||
cmd_add("SHORTEN", 0, 0, \%m_Bitly::HELP_SHORTEN, \&m_Bitly::shorten) or return 0;
|
cmd_add("SHORTEN", 0, 0, \%M::Bitly::HELP_SHORTEN, \&M::Bitly::shorten) or return 0;
|
||||||
cmd_add("REVERSE", 0, 0, \%m_Bitly::HELP_REVERSE, \&m_Bitly::reverse) or return 0;
|
cmd_add("REVERSE", 0, 0, \%M::Bitly::HELP_REVERSE, \&M::Bitly::reverse) or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
@@ -29,11 +29,11 @@ sub _init
|
|||||||
sub _void
|
sub _void
|
||||||
{
|
{
|
||||||
# Delete the SHORTEN and REVERSE commands.
|
# Delete the SHORTEN and REVERSE commands.
|
||||||
cmd_del("SHORTEN") or return 0;
|
cmd_del("SHORTEN") or return 0;
|
||||||
cmd_del("REVERSE") or return 0;
|
cmd_del("REVERSE") or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Help hashes.
|
# Help hashes.
|
||||||
@@ -47,44 +47,43 @@ our %HELP_REVERSE = (
|
|||||||
# Callback for SHORTEN command.
|
# Callback for SHORTEN command.
|
||||||
sub shorten
|
sub shorten
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @args) = @_;
|
||||||
|
|
||||||
# Create an instance of LWP::UserAgent.
|
# Create an instance of LWP::UserAgent.
|
||||||
my $ua = LWP::UserAgent->new();
|
my $ua = LWP::UserAgent->new();
|
||||||
$ua->agent('Auto IRC Bot');
|
$ua->agent('Auto IRC Bot');
|
||||||
$ua->timeout(2);
|
$ua->timeout(2);
|
||||||
|
|
||||||
# Put together the call to the Bit.ly API.
|
# Put together the call to the Bit.ly API.
|
||||||
my @args = @{ $data{args} };
|
|
||||||
if (!defined $args[0]) {
|
if (!defined $args[0]) {
|
||||||
notice($data{svr}, $data{nick}, trans("Not enough parameters").".");
|
notice($src->{svr}, $src->{nick}, trans("Not enough parameters").".");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
my ($surl, $user, $key) = ($args[0], (conf_get('bitly:user'))[0][0], (conf_get('bitly:key'))[0][0]);
|
my ($surl, $user, $key) = ($args[0], (conf_get('bitly:user'))[0][0], (conf_get('bitly:key'))[0][0]);
|
||||||
$surl = uri_escape($surl);
|
$surl = uri_escape($surl);
|
||||||
my $url = "http://api.bit.ly/v3/shorten?version=3.0.1&longUrl=".$surl."&apiKey=".$key."&login=".$user."&format=txt";
|
my $url = "http://api.bit.ly/v3/shorten?version=3.0.1&longUrl=".$surl."&apiKey=".$key."&login=".$user."&format=txt";
|
||||||
# Get the response via HTTP.
|
# Get the response via HTTP.
|
||||||
my $response = $ua->get($url);
|
my $response = $ua->get($url);
|
||||||
|
|
||||||
if ($response->is_success) {
|
if ($response->is_success) {
|
||||||
# If successful, decode the content.
|
# If successful, decode the content.
|
||||||
my $d = $response->decoded_content;
|
my $d = $response->decoded_content;
|
||||||
chomp $d;
|
chomp $d;
|
||||||
# And send to channel.
|
# And send to channel.
|
||||||
privmsg($data{svr}, $data{chan}, "URL: ".$d);
|
privmsg($src->{svr}, $src->{chan}, "URL: ".$d);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, send an error message.
|
# Otherwise, send an error message.
|
||||||
privmsg($data{svr}, $data{chan}, "An error occurred while shortening your URL.");
|
privmsg($src->{svr}, $src->{chan}, "An error occurred while shortening your URL.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Callback for REVERSE command.
|
# Callback for REVERSE command.
|
||||||
sub reverse
|
sub reverse
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @args) = @_;
|
||||||
|
|
||||||
# Create an instance of LWP::UserAgent.
|
# Create an instance of LWP::UserAgent.
|
||||||
my $ua = LWP::UserAgent->new();
|
my $ua = LWP::UserAgent->new();
|
||||||
@@ -92,9 +91,8 @@ sub reverse
|
|||||||
$ua->timeout(2);
|
$ua->timeout(2);
|
||||||
|
|
||||||
# Put together the call to the Bit.ly API.
|
# Put together the call to the Bit.ly API.
|
||||||
my @args = @{ $data{args} };
|
|
||||||
if (!defined $args[0]) {
|
if (!defined $args[0]) {
|
||||||
notice($data{svr}, $data{nick}, trans("Not enough parameters").".");
|
notice($src->{svr}, $src->{nick}, trans("Not enough parameters").".");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
my ($surl, $user, $key) = ($args[0], (conf_get('bitly:user'))[0][0], (conf_get('bitly:key'))[0][0]);
|
my ($surl, $user, $key) = ($args[0], (conf_get('bitly:user'))[0][0], (conf_get('bitly:key'))[0][0]);
|
||||||
@@ -106,21 +104,21 @@ sub reverse
|
|||||||
if ($response->is_success) {
|
if ($response->is_success) {
|
||||||
# If successful, decode the content.
|
# If successful, decode the content.
|
||||||
my $d = $response->decoded_content;
|
my $d = $response->decoded_content;
|
||||||
chomp $d;
|
chomp $d;
|
||||||
# And send it to channel.
|
# And send it to channel.
|
||||||
privmsg($data{svr}, $data{chan}, "URL: ".$d);
|
privmsg($src->{svr}, $src->{chan}, "URL: ".$d);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, send an error message.
|
# Otherwise, send an error message.
|
||||||
privmsg($data{svr}, $data{chan}, "An error occurred while reversing your URL.");
|
privmsg($src->{svr}, $src->{chan}, "An error occurred while reversing your URL.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Start initialization.
|
# Start initialization.
|
||||||
API::Std::mod_init("Bitly", "Xelhua", "1.00", "3.0.0d", __PACKAGE__);
|
API::Std::mod_init('Bitly', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
# build: cpan=LWP::UserAgent,URI::Escape perl=5.010000
|
# build: cpan=LWP::UserAgent,URI::Escape perl=5.010000
|
||||||
|
|
||||||
@@ -178,9 +176,9 @@ Add Bitly to module auto-load and the following to your configuration file:
|
|||||||
|
|
||||||
=over
|
=over
|
||||||
|
|
||||||
This module adds extra dependencies: LWP::UserAgent and URI::Escape.
|
This module adds extra dependencies: LWP::UserAgent and URI::Escape. You can
|
||||||
You can get it from the CPAN <http://www.cpan.org>.
|
get it from the CPAN <http://www.cpan.org>.
|
||||||
|
|
||||||
This module is compatible with Auto version 3.0.0a2+.
|
This module is compatible with Auto version 3.0.0a4+.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
+41
-47
@@ -1,7 +1,7 @@
|
|||||||
# Module: Calc. See below for documentation.
|
# Module: Calc. See below for documentation.
|
||||||
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
# This program is free software; rights to this code are stated in doc/LICENSE.
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
package m_Calc;
|
package M::Calc;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use API::Std qw(cmd_add cmd_del trans);
|
use API::Std qw(cmd_add cmd_del trans);
|
||||||
@@ -13,78 +13,72 @@ use JSON -support_by_pp;
|
|||||||
# Initialization subroutine.
|
# Initialization subroutine.
|
||||||
sub _init
|
sub _init
|
||||||
{
|
{
|
||||||
# Check for JSON::PP.
|
# Create the CALC command.
|
||||||
eval {
|
cmd_add("CALC", 0, 0, \%M::Calc::HELP_CALC, \&M::Calc::calc) or return 0;
|
||||||
require JSON::PP;
|
|
||||||
1;
|
|
||||||
} or return 0;
|
|
||||||
# Create the CALC command.
|
|
||||||
cmd_add("CALC", 0, 0, \%m_Calc::HELP_CALC, \&m_Calc::calc) or return 0;
|
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Void subroutine.
|
# Void subroutine.
|
||||||
sub _void
|
sub _void
|
||||||
{
|
{
|
||||||
# Delete the CALC command.
|
# Delete the CALC command.
|
||||||
cmd_del("CALC") or return 0;
|
cmd_del("CALC") or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Help hash.
|
# Help hash.
|
||||||
our %FHELP_CALC = (
|
our %FHELP_CALC = (
|
||||||
'en' => "This command will calculate an expression using Google Calculator. \002Syntax:\002 CALC <expression>",
|
'en' => "This command will calculate an expression using Google Calculator. \002Syntax:\002 CALC <expression>",
|
||||||
);
|
);
|
||||||
|
|
||||||
# Callback for CALC command.
|
# Callback for CALC command.
|
||||||
sub calc
|
sub calc
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @args) = @_;
|
||||||
|
|
||||||
# Create an instance of LWP::UserAgent.
|
# Create an instance of LWP::UserAgent.
|
||||||
my $ua = LWP::UserAgent->new();
|
my $ua = LWP::UserAgent->new();
|
||||||
$ua->agent('Auto IRC Bot');
|
$ua->agent('Auto IRC Bot');
|
||||||
$ua->timeout(2);
|
$ua->timeout(2);
|
||||||
# Create an instance of JSON.
|
# Create an instance of JSON.
|
||||||
my $json = JSON->new();
|
my $json = JSON->new();
|
||||||
# Put together the call to the Google Calculator API.
|
# Put together the call to the Google Calculator API.
|
||||||
my @args = @{ $data{args} };
|
|
||||||
if (!defined $args[0]) {
|
if (!defined $args[0]) {
|
||||||
notice($data{svr}, $data{nick}, trans("Not enough parameters").".");
|
notice($src->{svr}, $src->{nick}, trans("Not enough parameters").".");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
my $expr = join(' ', @args);
|
my $expr = join(' ', @args);
|
||||||
my $url = "http://www.google.com/ig/calculator?q=".uri_escape($expr);
|
my $url = "http://www.google.com/ig/calculator?q=".uri_escape($expr);
|
||||||
# Get the response via HTTP.
|
# Get the response via HTTP.
|
||||||
my $response = $ua->get($url);
|
my $response = $ua->get($url);
|
||||||
|
|
||||||
if ($response->is_success) {
|
if ($response->is_success) {
|
||||||
# If successful, decode the content.
|
# If successful, decode the content.
|
||||||
my $d = $json->allow_nonref->relaxed->escape_slash->loose->allow_singlequote->allow_barekey->decode($response->decoded_content);
|
my $d = $json->allow_nonref->relaxed->escape_slash->loose->allow_singlequote->allow_barekey->decode($response->decoded_content);
|
||||||
|
|
||||||
if ($d->{error} eq "" or $d->{error} == 0) {
|
if ($d->{error} eq "" or $d->{error} == 0) {
|
||||||
# And send to channel
|
# And send to channel
|
||||||
privmsg($data{svr}, $data{chan}, "Result: ".$d->{lhs}." = ".$d->{rhs});
|
privmsg($src->{svr}, $src->{chan}, "Result: ".$d->{lhs}." = ".$d->{rhs});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, send an error message.
|
# Otherwise, send an error message.
|
||||||
privmsg($data{svr}, $data{chan}, "Google Calculator sent an error.");
|
privmsg($src->{svr}, $src->{chan}, "Google Calculator sent an error.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, send an error message.
|
# Otherwise, send an error message.
|
||||||
privmsg($data{svr}, $data{chan}, "An error occurred while sending your expression to Google Calculator.");
|
privmsg($src->{svr}, $src->{chan}, "An error occurred while sending your expression to Google Calculator.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start initialization.
|
# Start initialization.
|
||||||
API::Std::mod_init("Calc", "Xelhua", "1.00", "3.0.0d", __PACKAGE__);
|
API::Std::mod_init('Calc', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
# build: cpan=LWP::UserAgent,URI::Escape,JSON,JSON::PP perl=5.010000
|
# build: cpan=LWP::UserAgent,URI::Escape,JSON,JSON::PP perl=5.010000
|
||||||
|
|
||||||
@@ -125,6 +119,6 @@ Google Calculator.
|
|||||||
This module requires LWP::UserAgent, URI::Escape and JSON/JSON::PP.
|
This module requires LWP::UserAgent, URI::Escape and JSON/JSON::PP.
|
||||||
All are obtainable from the CPAN <http://www.cpan.org>.
|
All are obtainable from the CPAN <http://www.cpan.org>.
|
||||||
|
|
||||||
This module is compatible with Auto version 3.0.0a2+.
|
This module is compatible with Auto version 3.0.0a4+.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
@@ -0,0 +1,345 @@
|
|||||||
|
# Module: ChanTopics. See below for documentation.
|
||||||
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
|
package M::ChanTopics;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use API::Std qw(cmd_add cmd_del trans);
|
||||||
|
use API::IRC qw(notice topic);
|
||||||
|
|
||||||
|
# Initialization subroutine.
|
||||||
|
sub _init
|
||||||
|
{
|
||||||
|
# PostgreSQL is not supported.
|
||||||
|
if ($Auto::ENFEAT =~ /pgsql/) { err(3, 'Unable to load ChanTopics: PostgreSQL is not supported.', 0); return; }
|
||||||
|
|
||||||
|
# Create database table if it's missing.
|
||||||
|
$Auto::DB->do('CREATE TABLE IF NOT EXISTS topics (net TEXT, chan TEXT, topic TEXT, divider TEXT, owner TEXT, verb TEXT, status TEXT, other TEXT, static TEXT)') or print "$!\n" and return;
|
||||||
|
|
||||||
|
# Create the TOPIC command.
|
||||||
|
cmd_add('TOPIC', 0, 'topic.topic', \%M::ChanTopics::HELP_TOPIC, \&M::ChanTopics::cmd_topic) or return;
|
||||||
|
# Create the DIVIDER command.
|
||||||
|
cmd_add('DIVIDER', 0, 'topic.topic', \%M::ChanTopics::HELP_DIVIDER, \&M::ChanTopics::cmd_divider) or return;
|
||||||
|
# Create the OWNER command.
|
||||||
|
cmd_add('OWNER', 0, 'topic.owner', \%M::ChanTopics::HELP_OWNER, \&M::ChanTopics::cmd_owner) or return;
|
||||||
|
# Create the VERB command.
|
||||||
|
cmd_add('VERB', 0, 'topic.status', \%M::ChanTopics::HELP_VERB, \&M::ChanTopics::cmd_verb) or return;
|
||||||
|
# Create the STATUS command.
|
||||||
|
cmd_add('STATUS', 0, 'topic.status', \%M::ChanTopics::HELP_STATUS, \&M::ChanTopics::cmd_status) or return;
|
||||||
|
# Create the OTHER command.
|
||||||
|
cmd_add('OTHER', 0, 'topic.static', \%M::ChanTopics::HELP_OTHER, \&M::ChanTopics::cmd_other) or return;
|
||||||
|
# Create the STATIC command.
|
||||||
|
cmd_add('STATIC', 0, 'topic.static', \%M::ChanTopics::HELP_STATIC, \&M::ChanTopics::cmd_static) or return;
|
||||||
|
# Create the TSYNC command.
|
||||||
|
cmd_add('TSYNC', 0, 'topic.topic', \%M::ChanTopics::HELP_TSYNC, \&M::ChanTopics::cmd_tsync) or return;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Void subroutine.
|
||||||
|
sub _void
|
||||||
|
{
|
||||||
|
# Delete all the commands.
|
||||||
|
cmd_del('TOPIC') or return;
|
||||||
|
cmd_del('DIVIDER') or return;
|
||||||
|
cmd_del('OWNER') or return;
|
||||||
|
cmd_del('VERB') or return;
|
||||||
|
cmd_del('STATUS') or return;
|
||||||
|
cmd_del('OTHER') or return;
|
||||||
|
cmd_del('STATIC') or return;
|
||||||
|
cmd_del('TSYNC') or return;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Help hashes for the TOPIC, OWNER, VERB, STATUS, OTHER, STATIC, DIVIDER and TSYNC commands. Spanish, French and German translations needed.
|
||||||
|
our %HELP_TOPIC = (
|
||||||
|
'en' => "This command allows you to set the topic section of a channel topic. \002Syntax:\002 TOPIC <new topic>",
|
||||||
|
);
|
||||||
|
our %HELP_DIVIDER = (
|
||||||
|
'en' => "This command allows you to set the divider for topic sections in a channel topic. \002Syntax:\002 DIVIDER <new divider>",
|
||||||
|
);
|
||||||
|
our %HELP_OWNER = (
|
||||||
|
'en' => "This command allows you to set the channel owner section of a channel topic. \002Syntax:\002 OWNER <new owner>",
|
||||||
|
);
|
||||||
|
our %HELP_VERB = (
|
||||||
|
'en' => "This command allows you to set the status verb section of a channel topic. \002Syntax:\002 VERB <new verb>",
|
||||||
|
);
|
||||||
|
our %HELP_STATUS = (
|
||||||
|
'en' => "This command allows you to set the status section of a channel topic. \002Syntax:\002 STATUS <new status>",
|
||||||
|
);
|
||||||
|
our %HELP_OTHER = (
|
||||||
|
'en' => "This command allows you to set the other static section of a channel topic. \002Syntax:\002 OTHER <new other static>",
|
||||||
|
);
|
||||||
|
our %HELP_STATIC = (
|
||||||
|
'en' => "This command allows you to set the static section of a channel topic. \002Syntax:\002 STATIC <new static>",
|
||||||
|
);
|
||||||
|
our %HELP_TSYNC = (
|
||||||
|
'en' => "This command allows you to sync the channel topic with the topic in the database. \002Syntax:\002 TSYNC",
|
||||||
|
);
|
||||||
|
|
||||||
|
# Callback for TOPIC command.
|
||||||
|
sub cmd_topic
|
||||||
|
{
|
||||||
|
my ($src, @argv) = @_;
|
||||||
|
|
||||||
|
# Check for required parameters.
|
||||||
|
if (!defined $argv[0]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get existing topic data.
|
||||||
|
my (undef, $div, $owner, $verb, $status, $other, $static) = _getdata(lc $src->{svr}, lc $src->{chan});
|
||||||
|
|
||||||
|
# Query the database with the new topic.
|
||||||
|
my $dbq = $Auto::DB->prepare('UPDATE topics SET topic = ? WHERE net = ? AND chan = ?') or return;
|
||||||
|
$dbq->execute(join(' ', @argv), lc $src->{svr}, lc $src->{chan}) or return;
|
||||||
|
|
||||||
|
# Set new topic.
|
||||||
|
topic($src->{svr}, $src->{chan}, "Topic: ".join(' ', @argv)." $div $owner $verb $status $div $other $div $static");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Callback for DIVIDER command.
|
||||||
|
sub cmd_divider
|
||||||
|
{
|
||||||
|
my ($src, @argv) = @_;
|
||||||
|
|
||||||
|
# Check for required parameters.
|
||||||
|
if (!defined $argv[0]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get existing topic data.
|
||||||
|
my ($topic, undef, $owner, $verb, $status, $other, $static) = _getdata(lc $src->{svr}, lc $src->{chan});
|
||||||
|
|
||||||
|
# Query the database with the new divider.
|
||||||
|
my $dbq = $Auto::DB->prepare('UPDATE topics SET divider = ? WHERE net = ? AND chan = ?') or return;
|
||||||
|
$dbq->execute($argv[0], lc $src->{svr}, lc $src->{chan}) or return;
|
||||||
|
|
||||||
|
# Set new topic.
|
||||||
|
topic($src->{svr}, $src->{chan}, "Topic: $topic $argv[0] $owner $verb $status $argv[0] $other $argv[0] $static");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Callback for OWNER command.
|
||||||
|
sub cmd_owner
|
||||||
|
{
|
||||||
|
my ($src, @argv) = @_;
|
||||||
|
|
||||||
|
# Check for required parameters.
|
||||||
|
if (!defined $argv[0]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get existing topic data.
|
||||||
|
my ($topic, $div, undef, $verb, $status, $other, $static) = _getdata(lc $src->{svr}, lc $src->{chan});
|
||||||
|
|
||||||
|
# Query the database with the new owner.
|
||||||
|
my $dbq = $Auto::DB->prepare('UPDATE topics SET owner = ? WHERE net = ? AND chan = ?') or return;
|
||||||
|
$dbq->execute($argv[0], lc $src->{svr}, lc $src->{chan}) or return;
|
||||||
|
|
||||||
|
# Set new topic.
|
||||||
|
topic($src->{svr}, $src->{chan}, "Topic: $topic $div $argv[0] $verb $status $div $other $div $static");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Callback for VERB command.
|
||||||
|
sub cmd_verb
|
||||||
|
{
|
||||||
|
my ($src, @argv) = @_;
|
||||||
|
|
||||||
|
# Check for required parameters.
|
||||||
|
if (!defined $argv[0]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get existing topic data.
|
||||||
|
my ($topic, $div, $owner, undef, $status, $other, $static) = _getdata(lc $src->{svr}, lc $src->{chan});
|
||||||
|
|
||||||
|
# Query the database with the new verb.
|
||||||
|
my $dbq = $Auto::DB->prepare('UPDATE topics SET verb = ? WHERE net = ? AND chan = ?') or return;
|
||||||
|
$dbq->execute($argv[0], lc $src->{svr}, lc $src->{chan}) or return;
|
||||||
|
|
||||||
|
# Set new topic.
|
||||||
|
topic($src->{svr}, $src->{chan}, "Topic: $topic $div $owner $argv[0] $status $div $other $div $static");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Callback for STATUS command.
|
||||||
|
sub cmd_status
|
||||||
|
{
|
||||||
|
my ($src, @argv) = @_;
|
||||||
|
|
||||||
|
# Check for required parameters.
|
||||||
|
if (!defined $argv[0]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get existing topic data.
|
||||||
|
my ($topic, $div, $owner, $verb, undef, $other, $static) = _getdata(lc $src->{svr}, lc $src->{chan});
|
||||||
|
|
||||||
|
# Query the database with the new status.
|
||||||
|
my $dbq = $Auto::DB->prepare('UPDATE topics SET status = ? WHERE net = ? AND chan = ?') or return;
|
||||||
|
$dbq->execute(join(' ', @argv), lc $src->{svr}, lc $src->{chan}) or return;
|
||||||
|
|
||||||
|
# Set new topic.
|
||||||
|
topic($src->{svr}, $src->{chan}, "Topic: $topic $div $owner $verb ".join(' ', @argv)." $div $other $div $static");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Callback for OTHER command.
|
||||||
|
sub cmd_other
|
||||||
|
{
|
||||||
|
my ($src, @argv) = @_;
|
||||||
|
|
||||||
|
# Check for required parameters.
|
||||||
|
if (!defined $argv[0]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get existing topic data.
|
||||||
|
my ($topic, $div, $owner, $verb, $status, undef, $static) = _getdata(lc $src->{svr}, lc $src->{chan});
|
||||||
|
|
||||||
|
# Query the database with the new other.
|
||||||
|
my $dbq = $Auto::DB->prepare('UPDATE topics SET other = ? WHERE net = ? AND chan = ?') or return;
|
||||||
|
$dbq->execute(join(' ', @argv), lc $src->{svr}, lc $src->{chan}) or return;
|
||||||
|
|
||||||
|
# Set new topic.
|
||||||
|
topic($src->{svr}, $src->{chan}, "Topic: $topic $div $owner $verb $status $div ".join(' ', @argv)." $div $static");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Callback for STATIC command.
|
||||||
|
sub cmd_static
|
||||||
|
{
|
||||||
|
my ($src, @argv) = @_;
|
||||||
|
|
||||||
|
# Check for required parameters.
|
||||||
|
if (!defined $argv[0]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get existing topic data.
|
||||||
|
my ($topic, $div, $owner, $verb, $status, $other, undef) = _getdata(lc $src->{svr}, lc $src->{chan});
|
||||||
|
|
||||||
|
# Query the database with the new static.
|
||||||
|
my $dbq = $Auto::DB->prepare('UPDATE topics SET static = ? WHERE net = ? AND chan = ?') or return;
|
||||||
|
$dbq->execute(join(' ', @argv), lc $src->{svr}, lc $src->{chan}) or return;
|
||||||
|
|
||||||
|
# Set new topic.
|
||||||
|
topic($src->{svr}, $src->{chan}, "Topic: $topic $div $owner $verb $status $div $other $div ".join(' ', @argv));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Callback for TSYNC command.
|
||||||
|
sub cmd_tsync
|
||||||
|
{
|
||||||
|
my ($src, @argv) = @_;
|
||||||
|
|
||||||
|
# Get the topic data.
|
||||||
|
my ($topic, $div, $owner, $verb, $status, $other, $static) = _getdata(lc $src->{svr}, lc $src->{chan});
|
||||||
|
|
||||||
|
# Set new topic.
|
||||||
|
topic($src->{svr}, $src->{chan}, "Topic: $topic $div $owner $verb $status $div $other $div $static");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Subroutine for getting topic data.
|
||||||
|
sub _getdata
|
||||||
|
{
|
||||||
|
my ($net, $chan) = @_;
|
||||||
|
|
||||||
|
# Check if there is a database entry for this channel.
|
||||||
|
if (!$Auto::DB->selectrow_array('SELECT * FROM topics WHERE net = "'.$net.'" AND chan = "'.$chan.'"')) {
|
||||||
|
# There is not; create it.
|
||||||
|
my $dbq = $Auto::DB->prepare('INSERT INTO topics (net, chan, topic, divider, owner, verb, status, other, static) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)') or return;
|
||||||
|
$dbq->execute($net, $chan, 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL') or return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now retrieve all the desired data.
|
||||||
|
my $dbq = $Auto::DB->prepare('SELECT topic,divider,owner,verb,status,other,static FROM topics WHERE net = ? AND chan = ?') or return;
|
||||||
|
$dbq->execute($net, $chan) or return;
|
||||||
|
my $data = $dbq->fetchrow_hashref or return;
|
||||||
|
|
||||||
|
# And return it.
|
||||||
|
return ($data->{topic}, $data->{divider}, $data->{owner}, $data->{verb}, $data->{status}, $data->{other}, $data->{static});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
API::Std::mod_init('ChanTopics', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
|
# vim: set ai sw=4 ts=4:
|
||||||
|
# build: perl=5.010000
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=head1 ChanTopics
|
||||||
|
|
||||||
|
=head2 Description
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
This module adds the TOPIC, DIVIDER, OWNER, VERB, STATUS, OTHER and STATIC
|
||||||
|
commands for advanced yet simple management of a channel's topic.
|
||||||
|
|
||||||
|
Topic Format: Topic: TOPIC DIVIDER OWNER VERB STATUS DIVIDER OTHER DIVIDER STATIC
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head2 How To Use
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
This module adds the topic.topic, topic.owner, topic.status and topic.static
|
||||||
|
privileges. topic.topic grants access to TOPIC, topic.owner to OWNER,
|
||||||
|
topic.status to VERB and STATUS, and topic.static to OTHER and STATIC.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head2 Examples
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
<JohnSmith> !topic Random Nonsense
|
||||||
|
* Auto changes topic to: Topic: Random Nonsense | JohnSmith is here | Welcome to #johnsmith | Website at http://example.com
|
||||||
|
<JohnSmith> !status sleeping
|
||||||
|
* Auto changes topic to: Topic: Random Nonsense | JohnSmith is sleeping | Welcome to #johnsmith | Website at http://example.com
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head2 To Do
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
* Spanish, French and German translations for the help hashes.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head2 Technical
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
This module adds no extra dependencies.
|
||||||
|
|
||||||
|
This module is not compatible with PostgreSQL, yet.
|
||||||
|
|
||||||
|
This module is compatible with Auto v3.0.0a4+.
|
||||||
|
|
||||||
|
Ported from v1.0.
|
||||||
|
|
||||||
|
=back
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
# Module: Dictionary. See below for documentation.
|
||||||
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
|
package M::Dictionary;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Net::Dict;
|
||||||
|
use API::Std qw(cmd_add cmd_del trans);
|
||||||
|
use API::IRC qw(notice privmsg);
|
||||||
|
|
||||||
|
# Initialization subroutine.
|
||||||
|
sub _init
|
||||||
|
{
|
||||||
|
# Create the DICT command.
|
||||||
|
cmd_add('DICT', 0, 0, \%M::Dictionary::HELP_DICT, \&M::Dictionary::cmd_dict) or return;
|
||||||
|
|
||||||
|
# Success.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Void subroutine.
|
||||||
|
sub _void
|
||||||
|
{
|
||||||
|
# Delete the DICT command.
|
||||||
|
cmd_del('DICT') or return;
|
||||||
|
|
||||||
|
# Success.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Help hash for DICT. Spanish, French and German translations needed.
|
||||||
|
our %HELP_DICT = (
|
||||||
|
'en' => "This command allows you to lookup a word through Dict.org. \002Syntax:\002 DICT <word>",
|
||||||
|
);
|
||||||
|
|
||||||
|
# Callback for DICT command.
|
||||||
|
sub cmd_dict
|
||||||
|
{
|
||||||
|
my ($src, ($word)) = @_;
|
||||||
|
|
||||||
|
# Check for needed parameters.
|
||||||
|
if (!defined $word) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create an instance of Net::Dict.
|
||||||
|
my $dictv = Net::Dict->new('dict.org');
|
||||||
|
|
||||||
|
# Get the definition for this word.
|
||||||
|
my $res = $dictv->define($word);
|
||||||
|
|
||||||
|
# Check if there was a result.
|
||||||
|
if (defined $res) {
|
||||||
|
# Return the results.
|
||||||
|
privmsg($src->{svr}, $src->{chan}, "Results for \2$word\2:");
|
||||||
|
foreach (@{ $res }) {
|
||||||
|
# Split the newlines.
|
||||||
|
my @lines = split m/\n/, @$_[1];
|
||||||
|
foreach (@lines) {
|
||||||
|
if ($_ =~ m/[^\s]/) {
|
||||||
|
privmsg($src->{svr}, $src->{chan}, $_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Else return no results.
|
||||||
|
privmsg($src->{svr}, $src->{chan}, "No results for \2$word\2.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Start initialization.
|
||||||
|
API::Std::mod_init('Dictionary', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
|
# vim: set ai sw=4 ts=4:
|
||||||
|
# build: cpan=Net::Dict perl=5.010000
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=head1 Dictionary
|
||||||
|
|
||||||
|
=head2 Description
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
This module allows users to lookup definitions for words from dict.org via the
|
||||||
|
DICT command.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head2 Technical
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
This module adds an extra dependency: Net::Dict. You can get it from the CPAN
|
||||||
|
<http://www.cpan.org>.
|
||||||
|
|
||||||
|
This module is compatible with Auto v3.0.0a4+.
|
||||||
|
|
||||||
|
=back
|
||||||
+17
-19
@@ -1,7 +1,7 @@
|
|||||||
# Module: EightBall. See below for documentation.
|
# Module: EightBall. See below for documentation.
|
||||||
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
# This program is free software; rights to this code are stated in doc/LICENSE.
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
package m_EightBall;
|
package M::EightBall;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use feature qw(switch);
|
use feature qw(switch);
|
||||||
@@ -13,8 +13,8 @@ our $ANSWER = 0;
|
|||||||
sub _init
|
sub _init
|
||||||
{
|
{
|
||||||
# Create the 8BALL and RIGBALL commands.
|
# Create the 8BALL and RIGBALL commands.
|
||||||
cmd_add("8BALL", 0, 0, \%m_EightBall::HELP_8BALL, \&m_EightBall::c_8ball) or return 0;
|
cmd_add('8BALL', 0, 0, \%M::EightBall::HELP_8BALL, \&M::EightBall::c_8ball) or return 0;
|
||||||
cmd_add("RIGBALL", 1, "cmd.rigball", \%m_EightBall::HELP_RIGBALL, \&m_EightBall::rigball) or return 0;
|
cmd_add('RIGBALL', 1, 'cmd.rigball', \%M::EightBall::HELP_RIGBALL, \&M::EightBall::rigball) or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
@@ -24,11 +24,11 @@ sub _init
|
|||||||
sub _void
|
sub _void
|
||||||
{
|
{
|
||||||
# Delete the 8BALL and RIGBALL commands.
|
# Delete the 8BALL and RIGBALL commands.
|
||||||
cmd_del("8BALL") or return 0;
|
cmd_del('8BALL') or return 0;
|
||||||
cmd_del("RIGBALL") or return 0;
|
cmd_del('RIGBALL') or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Help hashes.
|
# Help hashes.
|
||||||
@@ -42,15 +42,14 @@ our %HELP_RIGBALL = (
|
|||||||
# Callback for 8BALL command.
|
# Callback for 8BALL command.
|
||||||
sub c_8ball
|
sub c_8ball
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @argv) = @_;
|
||||||
my @argv = @{ $data{args} }; delete $data{args};
|
|
||||||
|
|
||||||
if (!defined $argv[0]) {
|
if (!defined $argv[0]) {
|
||||||
notice($data{svr}, $data{nick}, trans("Not enough parameters").".");
|
notice($src->{svr}, $src->{nick}, trans("Not enough parameters").".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
privmsg($data{svr}, $data{chan}, "\002Question:\002 ".join(" ", @argv));
|
privmsg($src->{svr}, $src->{chan}, "\002Question:\002 ".join(" ", @argv));
|
||||||
|
|
||||||
my $a = '';
|
my $a = '';
|
||||||
if (!$ANSWER) {
|
if (!$ANSWER) {
|
||||||
@@ -76,32 +75,31 @@ sub c_8ball
|
|||||||
$ANSWER = 0;
|
$ANSWER = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
privmsg($data{svr}, $data{chan}, "\002Answer:\002 ".$a);
|
privmsg($src->{svr}, $src->{chan}, "\002Answer:\002 ".$a);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Callback for RIGBALL command.
|
# Callback for RIGBALL command.
|
||||||
sub rigball
|
sub rigball
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @argv) = @_;
|
||||||
my @argv = @{ $data{args} }; delete $data{args};
|
|
||||||
|
|
||||||
# Check for necessary parameters.
|
# Check for necessary parameters.
|
||||||
if (!defined $argv[0]) {
|
if (!defined $argv[0]) {
|
||||||
privmsg($data{svr}, $data{nick}, trans("Not enough parameters").".");
|
privmsg($src->{svr}, $src->{nick}, trans("Not enough parameters").".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ANSWER = join(" ", @argv);
|
$ANSWER = join(" ", @argv);
|
||||||
privmsg($data{svr}, $data{nick}, "Answer set to: ".$ANSWER);
|
privmsg($src->{svr}, $src->{nick}, "Answer set to: ".$ANSWER);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Start initialization.
|
# Start initialization.
|
||||||
API::Std::mod_init("EightBall", "Xelhua", "1.00", "3.0.0d", __PACKAGE__);
|
API::Std::mod_init('EightBall', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
# build: perl=5.010000
|
# build: perl=5.010000
|
||||||
|
|
||||||
@@ -145,7 +143,7 @@ command for setting ("rigging") the 8-Ball's next answer.
|
|||||||
|
|
||||||
=over
|
=over
|
||||||
|
|
||||||
This module is compatible with Auto version 3.0.0a2+.
|
This module is compatible with Auto version 3.0.0a4+.
|
||||||
|
|
||||||
Ported from Auto 1.0.
|
Ported from Auto 1.0.
|
||||||
|
|
||||||
|
|||||||
+17
-17
@@ -1,7 +1,7 @@
|
|||||||
# Module: FML. See below for documentation.
|
# Module: FML. See below for documentation.
|
||||||
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
# This program is free software; rights to this code are stated in doc/LICENSE.
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
package m_FML;
|
package M::FML;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use API::Std qw(cmd_add cmd_del trans);
|
use API::Std qw(cmd_add cmd_del trans);
|
||||||
@@ -12,7 +12,7 @@ use LWP::UserAgent;
|
|||||||
sub _init
|
sub _init
|
||||||
{
|
{
|
||||||
# Create the FML command.
|
# Create the FML command.
|
||||||
cmd_add("FML", 0, 0, \%m_FML::HELP_FML, \&m_FML::fml) or return 0;
|
cmd_add('FML', 0, 0, \%M::FML::HELP_FML, \&M::FML::fml) or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
@@ -22,10 +22,10 @@ sub _init
|
|||||||
sub _void
|
sub _void
|
||||||
{
|
{
|
||||||
# Delete the FML command.
|
# Delete the FML command.
|
||||||
cmd_del("FML") or return 0;
|
cmd_del('FML') or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Help hash.
|
# Help hash.
|
||||||
@@ -36,38 +36,38 @@ our %HELP_FML = (
|
|||||||
# Callback for FML command.
|
# Callback for FML command.
|
||||||
sub fml
|
sub fml
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, undef) = @_;
|
||||||
|
|
||||||
# Create an instance of LWP::UserAgent.
|
# Create an instance of LWP::UserAgent.
|
||||||
my $ua = LWP::UserAgent->new();
|
my $ua = LWP::UserAgent->new();
|
||||||
$ua->agent('Auto IRC Bot');
|
$ua->agent('Auto IRC Bot');
|
||||||
$ua->timeout(2);
|
$ua->timeout(2);
|
||||||
|
|
||||||
# Get the random FML via HTTP.
|
# Get the random FML via HTTP.
|
||||||
my $rp = $ua->get("http://rscript.org/lookup.php?type=fml");
|
my $rp = $ua->get('http://rscript.org/lookup.php?type=fml');
|
||||||
|
|
||||||
if ($rp->is_success) {
|
if ($rp->is_success) {
|
||||||
# If successful, decode the content.
|
# If successful, decode the content.
|
||||||
my $d = $rp->decoded_content;
|
my $d = $rp->decoded_content;
|
||||||
$d =~ s/(\n|\r)//g;
|
$d =~ s/(\n|\r)//g;
|
||||||
|
|
||||||
# Get the FML.
|
# Get the FML.
|
||||||
my (undef, $dfa) = split('Text: ', $d);
|
my (undef, $dfa) = split('Text: ', $d);
|
||||||
my ($fml, undef) = split('Agree:', $dfa);
|
my ($fml, undef) = split('Agree:', $dfa);
|
||||||
|
|
||||||
# And send to channel.
|
# And send to channel.
|
||||||
privmsg($data{svr}, $data{chan}, "\002Random FML:\002 ".$fml);
|
privmsg($src->{svr}, $src->{chan}, "\002Random FML:\002 ".$fml);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, send an error message.
|
# Otherwise, send an error message.
|
||||||
privmsg($data{svr}, $data{chan}, "An error occurred while retrieving the FML.");
|
privmsg($src->{svr}, $src->{chan}, "An error occurred while retrieving the FML.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start initialization.
|
# Start initialization.
|
||||||
API::Std::mod_init("FML", "Xelhua", "1.00", "3.0.0d", __PACKAGE__);
|
API::Std::mod_init('FML', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
# build: cpan=LWP::UserAgent perl=5.010000
|
# build: cpan=LWP::UserAgent perl=5.010000
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ have my hand back?" FML
|
|||||||
This module adds an extra dependency: LWP::UserAgent. You can get it from
|
This module adds an extra dependency: LWP::UserAgent. You can get it from
|
||||||
the CPAN <http://www.cpan.org>.
|
the CPAN <http://www.cpan.org>.
|
||||||
|
|
||||||
This module is compatible with Auto version 3.0.0a2+.
|
This module is compatible with Auto version 3.0.0a4+.
|
||||||
|
|
||||||
Ported from Auto 2.0.
|
Ported from Auto 2.0.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,159 @@
|
|||||||
|
# Module: Greet. See below for documentation.
|
||||||
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
|
package M::Greet;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use feature qw(switch);
|
||||||
|
use API::Std qw(cmd_add cmd_del hook_add hook_del trans);
|
||||||
|
use API::IRC qw(privmsg notice);
|
||||||
|
|
||||||
|
# Initialization subroutine.
|
||||||
|
sub _init
|
||||||
|
{
|
||||||
|
# Not compatible with PostgreSQL.
|
||||||
|
if ($Auto::ENFEAT =~ /pgsql/) { err(2, 'Unable to load Greet: PostgreSQL is not supported.', 0); return; }
|
||||||
|
|
||||||
|
# Create the `greets` table.
|
||||||
|
$Auto::DB->do('CREATE TABLE IF NOT EXISTS greets (nick TEXT, greet TEXT)') or return;
|
||||||
|
# Create the GREET command.
|
||||||
|
cmd_add('GREET', 2, 'cmd.greet', \%M::Greet::HELP_GREET, \&M::Greet::cmd_greet) or return;
|
||||||
|
# Create the greet_onjoin hook.
|
||||||
|
hook_add('on_rcjoin', 'greet_onjoin', \&M::Greet::hook_rcjoin) or return;
|
||||||
|
|
||||||
|
# Success.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Void subroutine.
|
||||||
|
sub _void
|
||||||
|
{
|
||||||
|
# Delete the GREET command.
|
||||||
|
cmd_del('GREET') or return;
|
||||||
|
# Delete the greet_onjoin hook.
|
||||||
|
hook_del('on_rcjoin') or return;
|
||||||
|
|
||||||
|
# Success.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Help hash for GREET. Spanish, French and German translation needed.
|
||||||
|
our %HELP_GREET = (
|
||||||
|
'en' => "This command allows management of greets. \002Syntax:\002 GREET (ADD|DEL) [nick] [greet]",
|
||||||
|
);
|
||||||
|
# Callback for GREET.
|
||||||
|
sub cmd_greet
|
||||||
|
{
|
||||||
|
my ($src, @argv) = @_;
|
||||||
|
|
||||||
|
# Check for required parameters.
|
||||||
|
if (!defined $argv[0]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check what action we're being told to take.
|
||||||
|
given (uc $argv[0]) {
|
||||||
|
when ('ADD') {
|
||||||
|
# GREET ADD
|
||||||
|
|
||||||
|
# Check for needed parameters.
|
||||||
|
if (!defined $argv[1] or !defined $argv[2]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
my $nick = $argv[1]; shift @argv; shift @argv;
|
||||||
|
$nick = lc $nick;
|
||||||
|
my $greet = join(' ', @argv);
|
||||||
|
|
||||||
|
# Make sure it doesn't already exist.
|
||||||
|
if ($Auto::DB->selectrow_array('SELECT * FROM greets WHERE nick = "'.$nick.'"')) {
|
||||||
|
notice($src->{svr}, $src->{nick}, "A greet for \002$nick\002 already exists.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Insert into database.
|
||||||
|
my $dbq = $Auto::DB->prepare('INSERT INTO greets (nick, greet) VALUES (?, ?)') or notice($src->{svr}, $src->{nick}, trans('An error occurred').q{.}) and return;
|
||||||
|
$dbq->execute($nick, $greet) or notice($src->{svr}, $src->{nick}, trans('An error occurred').q{.}) and return;
|
||||||
|
|
||||||
|
API::Log::slog('cmd_greet(): Creating new greet.');
|
||||||
|
# Done.
|
||||||
|
notice($src->{svr}, $src->{nick}, "Successfully added greet for \002$nick\002.");
|
||||||
|
}
|
||||||
|
when ('DEL') {
|
||||||
|
# GREET DEL
|
||||||
|
|
||||||
|
# Check for needed parameters.
|
||||||
|
if (!defined $argv[1]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
my $nick = lc $argv[1];
|
||||||
|
|
||||||
|
# Check if there is a greet for this user.
|
||||||
|
if (!$Auto::DB->selectrow_array('SELECT * FROM greets WHERE nick = "'.$nick.'"')) {
|
||||||
|
notice($src->{svr}, $src->{nick}, "There is no greet for \002$nick\002.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Delete it.
|
||||||
|
$Auto::DB->do('DELETE FROM greets WHERE nick = "'.$nick.'"') or notice($src->{svr}, $src->{nick}, trans('An error occurred').q{.}) and return;
|
||||||
|
notice($src->{svr}, $src->{nick}, "Greet for \002$nick\002 successfully deleted.");
|
||||||
|
}
|
||||||
|
default { notice($src->{svr}, $src->{nick}, "Unknown action \002$argv[0]\002. \002Syntax:\002 GREET (ADD|DEL)"); return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Call back for on_rcjoin hook.
|
||||||
|
sub hook_rcjoin
|
||||||
|
{
|
||||||
|
my (($src, $chan)) = @_;
|
||||||
|
my $nick = lc $src->{nick};
|
||||||
|
|
||||||
|
# Check if there's a greet for this user.
|
||||||
|
if ($Auto::DB->selectrow_array('SELECT * FROM greets WHERE nick = "'.$nick.'"')) {
|
||||||
|
# Get data.
|
||||||
|
my @data = $Auto::DB->selectrow_array('SELECT * FROM greets WHERE nick = "'.$nick.'"');
|
||||||
|
|
||||||
|
# Send the greet.
|
||||||
|
privmsg($src->{svr}, $chan, "[\002".$src->{nick}."\002] ".$data[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start initialization.
|
||||||
|
API::Std::mod_init('Greet', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
|
# vim: set ai sw=4 ts=4:
|
||||||
|
# build: perl=5.010000
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=head1 Greet
|
||||||
|
|
||||||
|
=head2 Description
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
This module adds GREET ADD|DEL for greet management. Greets are sent when a
|
||||||
|
user that has a greet in the database joins a channel the bot is in.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head2 To Do
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
* Add Spanish, French and German translations for the help hash.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head2 Technical
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
This module is compatible with Auto version 3.0.0a4+.
|
||||||
|
|
||||||
|
=back
|
||||||
+24
-14
@@ -1,7 +1,7 @@
|
|||||||
# Module: HelloChan.
|
# Module: HelloChan.
|
||||||
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
# This program is free software; rights to this code are stated in doc/LICENSE.
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
package m_HelloChan;
|
package M::HelloChan;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use API::Std qw(hook_add hook_del);
|
use API::Std qw(hook_add hook_del);
|
||||||
@@ -10,32 +10,42 @@ use API::IRC qw(privmsg);
|
|||||||
# Initialization subroutine.
|
# Initialization subroutine.
|
||||||
sub _init
|
sub _init
|
||||||
{
|
{
|
||||||
# Add a hook for when we join a channel.
|
# Add a hook for when we join a channel.
|
||||||
hook_add("on_ucjoin", "HelloChan", \&m_HelloChan::hello) or return 0;
|
hook_add("on_ucjoin", "HelloChan", \&M::HelloChan::hello) or return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Void subroutine.
|
# Void subroutine.
|
||||||
sub _void
|
sub _void
|
||||||
{
|
{
|
||||||
# Delete the hook.
|
# Delete the hook.
|
||||||
hook_del("on_ucjoin", "HelloChan") or return 0;
|
hook_del("on_ucjoin", "HelloChan") or return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main subroutine.
|
# Main subroutine.
|
||||||
sub hello
|
sub hello
|
||||||
{
|
{
|
||||||
my (($svr, $chan)) = @_;
|
my (($svr, $chan)) = @_;
|
||||||
|
|
||||||
# Send a PRIVMSG.
|
# Send a PRIVMSG.
|
||||||
privmsg($svr, $chan, "Hello channel! I am a bot!");
|
privmsg($svr, $chan, "Hello channel! I am a bot!");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Start initialization.
|
# Start initialization.
|
||||||
API::Std::mod_init("HelloChan", "Xelhua", "1.00", "3.0.0d", __PACKAGE__);
|
API::Std::mod_init('HelloChan', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
# build: perl=5.010000
|
# build: perl=5.010000
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=head1 HelloChan
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
This is an example module. Also, cows go moo.
|
||||||
|
|
||||||
|
=back
|
||||||
+38
-39
@@ -1,7 +1,7 @@
|
|||||||
# Module: IsItUp. See below for documentation.
|
# Module: IsItUp. See below for documentation.
|
||||||
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
# This program is free software; rights to this code are stated in doc/LICENSE.
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
package m_IsItUp;
|
package M::IsItUp;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use API::Std qw(cmd_add cmd_del trans);
|
use API::Std qw(cmd_add cmd_del trans);
|
||||||
@@ -11,66 +11,65 @@ use LWP::UserAgent;
|
|||||||
# Initialization subroutine.
|
# Initialization subroutine.
|
||||||
sub _init
|
sub _init
|
||||||
{
|
{
|
||||||
# Create the ISITUP command.
|
# Create the ISITUP command.
|
||||||
cmd_add("ISITUP", 0, 0, \%m_IsItUp::HELP_ISITUP, \&m_IsItUp::check) or return 0;
|
cmd_add('ISITUP', 0, 0, \%M::IsItUp::HELP_ISITUP, \&M::IsItUp::check) or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Void subroutine.
|
# Void subroutine.
|
||||||
sub _void
|
sub _void
|
||||||
{
|
{
|
||||||
# Delete the ISITUP command.
|
# Delete the ISITUP command.
|
||||||
cmd_del("ISITUP") or return 0;
|
cmd_del('ISITUP') or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Help hashes.
|
# Help hashes.
|
||||||
our %HELP_ISITUP = (
|
our %HELP_ISITUP = (
|
||||||
'en' => "This command will check if a website appears up or down to the bot. \002Syntax:\002 ISITUP <url>",
|
'en' => "This command will check if a website appears up or down to the bot. \002Syntax:\002 ISITUP <url>",
|
||||||
);
|
);
|
||||||
|
|
||||||
# Callback for ISITUP command.
|
# Callback for ISITUP command.
|
||||||
sub check
|
sub check
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @argv) = @_;
|
||||||
|
|
||||||
# Create an instance of LWP::UserAgent.
|
# Create an instance of LWP::UserAgent.
|
||||||
my $ua = LWP::UserAgent->new();
|
my $ua = LWP::UserAgent->new();
|
||||||
$ua->agent('Auto IRC Bot');
|
$ua->agent('Auto IRC Bot');
|
||||||
$ua->timeout(2);
|
$ua->timeout(2);
|
||||||
my @args = @{ $data{args} };
|
# Do we have enough parameters?
|
||||||
my $curl = $args[0];
|
if (!defined $argv[0]) {
|
||||||
# Do we have enough parameters?
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
if (!defined $args[0]) {
|
return 0;
|
||||||
notice($data{svr}, $data{nick}, trans("Not enough parameters").".");
|
}
|
||||||
return 0;
|
my $curl = $argv[0];
|
||||||
}
|
# Does the URL start with http(s)?
|
||||||
# Does the URL start with http(s)?
|
if ($curl !~ m/^http/) {
|
||||||
if ($curl !~ m/^http/) {
|
$curl = 'http://'.$curl;
|
||||||
$curl = "http://".$curl;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# Get the response via HTTP.
|
# Get the response via HTTP.
|
||||||
my $response = $ua->get($curl);
|
my $response = $ua->get($curl);
|
||||||
|
|
||||||
if ($response->is_success) {
|
if ($response->is_success) {
|
||||||
# If successful, it's up.
|
# If successful, it's up.
|
||||||
privmsg($data{svr}, $data{chan}, $curl." appears to be up from here.");
|
privmsg($src->{svr}, $src->{chan}, $curl.' appears to be up from here.');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, it's down.
|
# Otherwise, it's down.
|
||||||
privmsg($data{svr}, $data{chan}, $curl." appears to be down from here.");
|
privmsg($src->{svr}, $src->{chan}, $curl.' appears to be down from here.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start initialization.
|
# Start initialization.
|
||||||
API::Std::mod_init("IsItUp", "Xelhua", "1.00", "3.0.0d", __PACKAGE__);
|
API::Std::mod_init('IsItUp', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
# build: cpan=LWP::UserAgent perl=5.010000
|
# build: cpan=LWP::UserAgent perl=5.010000
|
||||||
|
|
||||||
@@ -111,6 +110,6 @@ appears up or down to Auto.
|
|||||||
This module requires LWP::UserAgent. You can get it from
|
This module requires LWP::UserAgent. You can get it from
|
||||||
the CPAN <http://www.cpan.org>.
|
the CPAN <http://www.cpan.org>.
|
||||||
|
|
||||||
This module is compatible with Auto version 3.0.0a2+.
|
This module is compatible with Auto version 3.0.0a4+.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
# Module: LinkTitle. See below for documentation.
|
||||||
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
|
package M::LinkTitle;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use LWP::UserAgent;
|
||||||
|
use HTML::Entities;
|
||||||
|
use API::Std qw(hook_add hook_del);
|
||||||
|
use API::IRC qw(privmsg);
|
||||||
|
|
||||||
|
# Initialization subroutine.
|
||||||
|
sub _init
|
||||||
|
{
|
||||||
|
# Create the on_cprivmsg hook.
|
||||||
|
hook_add('on_cprivmsg', 'privmsg.html.returntitle', \&M::LinkTitle::gettitle) or return;
|
||||||
|
|
||||||
|
# Success.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Void subroutine.
|
||||||
|
sub _void
|
||||||
|
{
|
||||||
|
# Delete the hook we created.
|
||||||
|
hook_del('on_cprivmsg', 'privmsg.html.returntitle') or return;
|
||||||
|
|
||||||
|
# Success.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Hook callback.
|
||||||
|
sub gettitle
|
||||||
|
{
|
||||||
|
my ($src, $chan, @msg) = @_;
|
||||||
|
|
||||||
|
# Check if the message contains a URL.
|
||||||
|
foreach my $smw (@msg) {
|
||||||
|
if ($smw =~ m{(http|https)://}xsm) {
|
||||||
|
# We've got a match, connect to the server.
|
||||||
|
my $srv = $1;
|
||||||
|
# Create an instance of LWP::UserAgent.
|
||||||
|
my $ua = LWP::UserAgent->new();
|
||||||
|
$ua->agent('Auto IRC Bot');
|
||||||
|
$ua->timeout(3);
|
||||||
|
# Get data.
|
||||||
|
my $res = $ua->get($smw);
|
||||||
|
|
||||||
|
# Check if we're successful.
|
||||||
|
if ($res->is_success) {
|
||||||
|
# We were, decode the data.
|
||||||
|
my $data = $res->decoded_content;
|
||||||
|
|
||||||
|
# Check for <title>
|
||||||
|
if ($data =~ m{<title>(.*)</title>}ixsm) {
|
||||||
|
# Found. Decode it.
|
||||||
|
my $title = decode_entities($1);
|
||||||
|
# Return to channel.
|
||||||
|
privmsg($src->{svr}, $chan, "\2Title:\2 $title");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start initialization.
|
||||||
|
API::Std::mod_init('LinkTitle', 'Xelhua', '1.00', '3.0.0a5', __PACKAGE__);
|
||||||
|
# vim: set ai sw=4 ts=4:
|
||||||
|
# build: cpan=LWP::UserAgent,HTML::Entities perl=5.010000
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
LinkTitle - A module for returning the page title of links.
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
1.00
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
<starcoder> http://xelhua.org/auto.php
|
||||||
|
<blue> Title: Xelhua / Projects / Auto
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
This module will make Auto parse all links sent to a channel. When a link is
|
||||||
|
detected, Auto will connect to it and get the page title by scanning for the
|
||||||
|
<title> tag and returning its contents to the channel.
|
||||||
|
|
||||||
|
=head1 DEPENDENCIES
|
||||||
|
|
||||||
|
This module is dependent on two modules from the CPAN.
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item L<LWP::UserAgent|LWP::UserAgent>
|
||||||
|
|
||||||
|
This module is used for connecting to the target web server via HTTP(S).
|
||||||
|
|
||||||
|
=item L<HTML::Entities|HTML::Entities>
|
||||||
|
|
||||||
|
This module is used for decoding HTML entities in the response we receive from
|
||||||
|
the server.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
This module was written by Elijah Perrault.
|
||||||
|
|
||||||
|
This module is maintained by Xelhua Development Group.
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This module is Copyright 2010-2011 Xelhua Development Group. All rights
|
||||||
|
reserved.
|
||||||
|
|
||||||
|
This module is released under the same licensing terms as Auto itself.
|
||||||
+145
-55
@@ -1,20 +1,24 @@
|
|||||||
# Module: QDB. See below for documentation.
|
# Module: QDB. See below for documentation.
|
||||||
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
# This program is free software; rights to this code are stated in doc/LICENSE.
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
package m_QDB;
|
package M::QDB;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use feature qw(switch);
|
use feature qw(switch);
|
||||||
use API::Std qw(cmd_add cmd_del trans has_priv match_user);
|
use API::Std qw(cmd_add cmd_del trans has_priv conf_get match_user);
|
||||||
use API::IRC qw(privmsg notice);
|
use API::IRC qw(privmsg notice);
|
||||||
|
our @BUFFER;
|
||||||
|
|
||||||
sub _init
|
sub _init
|
||||||
{
|
{
|
||||||
# Create the QDB command.
|
# Create the QDB command.
|
||||||
cmd_add('QDB', 0, 0, \%m_QDB::HELP_QDB, \&m_QDB::cmd_qdb) or return;
|
cmd_add('QDB', 0, 0, \%M::QDB::HELP_QDB, \&M::QDB::cmd_qdb) or return;
|
||||||
|
|
||||||
|
# Check the database format. Fail to load if it's PostgreSQL.
|
||||||
|
if ($Auto::ENFEAT =~ /pgsql/) { err(2, 'Unable to load QDB: PostgreSQL is not supported.', 0); return; }
|
||||||
|
|
||||||
# Check for database table.
|
# Check for database table.
|
||||||
$Auto::DB->do('CREATE TABLE IF NOT EXISTS qdb (key INTEGER PRIMARY KEY, creator TEXT, time INTEGER, quote TEXT)') or return;
|
$Auto::DB->do('CREATE TABLE IF NOT EXISTS qdb (quoteid INTEGER PRIMARY KEY, creator TEXT, time INTEGER, quote TEXT)') or return;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
@@ -31,142 +35,228 @@ sub _void
|
|||||||
|
|
||||||
# Help hash for QDB. Spanish, French and German translations needed.
|
# Help hash for QDB. Spanish, French and German translations needed.
|
||||||
our %HELP_QDB = (
|
our %HELP_QDB = (
|
||||||
'en' => "This command allows you to add, read, and delete quotes. \002Syntax:\002 QDB (ADD|VIEW|COUNT|RAND|DEL) [quote]",
|
'en' => "This command allows you to add, read, and delete quotes. \002Syntax:\002 QDB (ADD|VIEW|COUNT|RAND|SEARCH|MORE|DEL) [quote|expression]",
|
||||||
);
|
);
|
||||||
sub cmd_qdb
|
sub cmd_qdb
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @argv) = @_;
|
||||||
my @argv = @{ $data{args} };
|
|
||||||
|
|
||||||
# Check for needed parameter.
|
# Check for needed parameter.
|
||||||
if (!defined $argv[0]) {
|
if (!defined $argv[0]) {
|
||||||
notice($data{svr}, $data{nick}, trans('Not enough parameters').q{.});
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ADD|VIEW|COUNT|RAND|DEL.
|
# ADD|VIEW|COUNT|RAND|SEARCH|MORE|DEL.
|
||||||
given (uc $argv[0]) {
|
given (uc $argv[0]) {
|
||||||
when ('ADD') {
|
when ('ADD') {
|
||||||
# QDB ADD.
|
# QDB ADD.
|
||||||
if (!defined $argv[1]) {
|
if (!defined $argv[1]) {
|
||||||
notice($data{svr}, $data{nick}, trans('Not enough parameters').q{.});
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get rid of the ADD part.
|
|
||||||
shift @argv;
|
|
||||||
|
|
||||||
# Insert into database.
|
# Insert into database.
|
||||||
my $dbq = $Auto::DB->prepare('INSERT INTO qdb (creator, time, quote) VALUES (?, ?, ?)') or
|
my $dbq = $Auto::DB->prepare('INSERT INTO qdb (creator, time, quote) VALUES (?, ?, ?)') or
|
||||||
notice($data{svr}, $data{nick}, trans('An error occurred').q{.}) and return;
|
notice($src->{svr}, $src->{nick}, trans('An error occurred').q{.}) and return;
|
||||||
$dbq->execute($data{nick}, time, join(q{ }, @argv)) or
|
$dbq->execute($src->{nick}, time, join(q{ }, @argv[1..$#argv])) or
|
||||||
notice($data{svr}, $data{nick}, trans('An error occurred').q{.}) and return;
|
notice($src->{svr}, $src->{nick}, trans('An error occurred').q{.}) and return;
|
||||||
|
|
||||||
# Get ID.
|
# Get ID.
|
||||||
my $count = $Auto::DB->selectrow_array('SELECT COUNT(*) FROM qdb') or
|
my $count = $Auto::DB->selectrow_array('SELECT COUNT(*) FROM qdb') or
|
||||||
notice($data{svr}, $data{nick}, trans('An error occurred').q{.}) and return;
|
notice($src->{svr}, $src->{nick}, trans('An error occurred').q{.}) and return;
|
||||||
|
|
||||||
privmsg($data{svr}, $data{chan}, 'Quote successfully submitted. ID: '.$count);
|
privmsg($src->{svr}, $src->{chan}, 'Quote successfully submitted. ID: '.$count);
|
||||||
}
|
}
|
||||||
when ('VIEW') {
|
when ('VIEW') {
|
||||||
# QDB VIEW.
|
# QDB VIEW.
|
||||||
if (!defined $argv[1]) {
|
if (!defined $argv[1]) {
|
||||||
notice($data{svr}, $data{nick}, trans('Not enough parameters').q{.});
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get quote.
|
# Get quote.
|
||||||
my $dbq = $Auto::DB->prepare('SELECT * FROM qdb WHERE key = ?') or
|
my $dbq = $Auto::DB->prepare('SELECT * FROM qdb WHERE quoteid = ?') or
|
||||||
notice($data{svr}, $data{nick}, trans('An error occurred').'. Quote might not exist.') and return;
|
notice($src->{svr}, $src->{nick}, trans('An error occurred').'. Quote might not exist.') and return;
|
||||||
$dbq->execute($argv[1]) or notice($data{svr}, $data{nick}, trans('An error occurred').'. Quote might not exist.') and return;
|
$dbq->execute($argv[1]) or notice($src->{svr}, $src->{nick}, trans('An error occurred').'. Quote might not exist.') and return;
|
||||||
my @data = $dbq->fetchrow_array;
|
my @data = $dbq->fetchrow_array;
|
||||||
|
|
||||||
|
# Check for an unusual issue.
|
||||||
|
if (!defined $data[1]) { notice($src->{svr}, $src->{nick}, trans('An error occurred').'. Quote might not exist.'); return; }
|
||||||
|
|
||||||
# Send it back.
|
# Send it back.
|
||||||
privmsg($data{svr}, $data{chan}, "\002Submitted by\002 $data[1] \002on\002 ".POSIX::strftime('%F', localtime($data[2]))." \002at\002 ".POSIX::strftime('%I:%M %p', localtime($data[2])));
|
privmsg($src->{svr}, $src->{chan}, "\002Submitted by\002 $data[1] \002on\002 ".POSIX::strftime('%F', localtime($data[2]))." \002at\002 ".POSIX::strftime('%I:%M %p', localtime($data[2])));
|
||||||
privmsg($data{svr}, $data{chan}, $data[3]);
|
privmsg($src->{svr}, $src->{chan}, $data[3]);
|
||||||
}
|
}
|
||||||
when ('COUNT') {
|
when ('COUNT') {
|
||||||
# Get count.
|
# Get count.
|
||||||
my $count = $Auto::DB->selectrow_array('SELECT COUNT(*) FROM qdb') or
|
my $count = $Auto::DB->selectrow_array('SELECT COUNT(*) FROM qdb') or
|
||||||
notice($data{svr}, $data{nick}, trans('An error occurred').q{.}) and return;
|
notice($src->{svr}, $src->{nick}, trans('An error occurred').q{.}) and return;
|
||||||
|
|
||||||
# Send it back.
|
# Send it back.
|
||||||
privmsg($data{svr}, $data{chan}, "There is currently \002$count\002 quotes in my database.");
|
privmsg($src->{svr}, $src->{chan}, "There is currently \002$count\002 quotes in my database.");
|
||||||
}
|
}
|
||||||
when ('RAND') {
|
when ('RAND') {
|
||||||
# Get count.
|
# Get count.
|
||||||
my $count = $Auto::DB->selectrow_array('SELECT COUNT(*) FROM qdb') or
|
my $count = $Auto::DB->selectrow_array('SELECT COUNT(*) FROM qdb') or
|
||||||
notice($data{svr}, $data{nick}, trans('An error occurred').q{.}) and return;
|
notice($src->{svr}, $src->{nick}, trans('An error occurred').q{.}) and return;
|
||||||
|
|
||||||
# Random number.
|
# Random number.
|
||||||
my $rand = int(rand($count));
|
my $rand = int(rand($count));
|
||||||
if ($rand == 0) { $rand = $count; }
|
if ($rand == 0) { $rand = $count; }
|
||||||
|
|
||||||
# Get quote.
|
# Get quote.
|
||||||
my $dbq = $Auto::DB->prepare('SELECT * FROM qdb WHERE key = ?') or
|
my $dbq = $Auto::DB->prepare('SELECT * FROM qdb WHERE quoteid = ?') or
|
||||||
notice($data{svr}, $data{nick}, trans('An error occurred').q{.}) and return;
|
notice($src->{svr}, $src->{nick}, trans('An error occurred').q{.}) and return;
|
||||||
$dbq->execute($rand) or notice($data{svr}, $data{nick}, trans('An error occurred').q{.}) and return;
|
$dbq->execute($rand) or notice($src->{svr}, $src->{nick}, trans('An error occurred').q{.}) and return;
|
||||||
my @data = $dbq->fetchrow_array;
|
my @data = $dbq->fetchrow_array;
|
||||||
|
|
||||||
# Send it back.
|
# Send it back.
|
||||||
privmsg($data{svr}, $data{chan}, "\002ID:\002 $data[0] - \002Submitted by\002 $data[1] \002on\002 ".POSIX::strftime('%F', localtime($data[2]))." \002at\002 ".POSIX::strftime('%I:%M %p', localtime($data[2])));
|
privmsg($src->{svr}, $src->{chan}, "\002ID:\002 $data[0] - \002Submitted by\002 $data[1] \002on\002 ".POSIX::strftime('%F', localtime($data[2]))." \002at\002 ".POSIX::strftime('%I:%M %p', localtime($data[2])));
|
||||||
privmsg($data{svr}, $data{chan}, $data[3]);
|
privmsg($src->{svr}, $src->{chan}, $data[3]);
|
||||||
|
}
|
||||||
|
when ('SEARCH') {
|
||||||
|
# QDB SEARCH.
|
||||||
|
|
||||||
|
# Get all quotes.
|
||||||
|
my $dbq = $Auto::DB->prepare('SELECT * FROM qdb') or return;
|
||||||
|
$dbq->execute or return;
|
||||||
|
my $quotes = $dbq->fetchall_hashref('quoteid') or return;
|
||||||
|
|
||||||
|
# Set expression.
|
||||||
|
my $expr = my $rexpr = join ' ', @argv[1 .. $#argv];
|
||||||
|
$rexpr =~ s{\(}{\\\(}g;
|
||||||
|
$rexpr =~ s{\)}{\\\)}g;
|
||||||
|
$rexpr =~ s{\?}{\\\?}g;
|
||||||
|
$rexpr =~ s{\*}{\\\*}g;
|
||||||
|
$rexpr =~ s{\[}{\\\[}g;
|
||||||
|
$rexpr =~ s{\]}{\\\]}g;
|
||||||
|
$rexpr =~ s{\.}{\\\.}g;
|
||||||
|
$rexpr =~ s{\$}{\\\$}g;
|
||||||
|
$rexpr =~ s{\^}{\\\^}g;
|
||||||
|
|
||||||
|
# Clear the buffer.
|
||||||
|
@BUFFER = ();
|
||||||
|
|
||||||
|
# Iterate through all quotes.
|
||||||
|
foreach my $qkt (keys %$quotes) {
|
||||||
|
# Check if we have a match.
|
||||||
|
if ($quotes->{$qkt}->{quote} =~ m/$rexpr/ixsm) {
|
||||||
|
# Match. Add to buffer.
|
||||||
|
push @BUFFER, "\2ID:\2 $qkt - ".$quotes->{$qkt}->{quote};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if we had any matches.
|
||||||
|
if (!defined $BUFFER[0]) {
|
||||||
|
privmsg($src->{svr}, $src->{chan}, "No results for \2$expr\2.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Return four quotes.
|
||||||
|
privmsg($src->{svr}, $src->{chan}, "\2".scalar @BUFFER."\2 results for \2$expr\2:");
|
||||||
|
my $i = 0;
|
||||||
|
my $si = 3;
|
||||||
|
if (conf_get('qdb_search_resnum')) { $si = (conf_get('qdb_search_resnum'))[0][0] - 1; }
|
||||||
|
while ($i <= $si) {
|
||||||
|
if (!defined $BUFFER[0]) {
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
|
privmsg($src->{svr}, $src->{chan}, shift @BUFFER);
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
when ('MORE') {
|
||||||
|
# Check if there's any quotes in the buffer.
|
||||||
|
if (!defined $BUFFER[0]) {
|
||||||
|
notice($src->{svr}, $src->{nick}, 'No quotes in buffer.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Return four quotes.
|
||||||
|
my $i = 0;
|
||||||
|
my $si = 3;
|
||||||
|
if (conf_get('qdb_search_resnum')) { $si = (conf_get('qdb_search_resnum'))[0][0] - 1; }
|
||||||
|
while ($i <= $si) {
|
||||||
|
if (!defined $BUFFER[0]) {
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
|
privmsg($src->{svr}, $src->{chan}, shift @BUFFER);
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
when ('DEL') {
|
when ('DEL') {
|
||||||
# Check for the cmd.qdbdel privilege.
|
# Check for the cmd.qdbdel privilege.
|
||||||
if (!has_priv(match_user(%data), 'cmd.qdbdel')) {
|
if (!has_priv(match_user(%$src), 'cmd.qdbdel')) {
|
||||||
notice($data{svr}, $data{chan}, trans('Permission denied').q{.});
|
notice($src->{svr}, $src->{chan}, trans('Permission denied').q{.});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
# Check for the needed parameter.
|
# Check for the needed parameter.
|
||||||
if (!defined $argv[1]) {
|
if (!defined $argv[1]) {
|
||||||
notice($data{svr}, $data{nick}, trans('Not enough parameters').q{.});
|
notice($src->{svr}, $src->{nick}, trans('Not enough parameters').q{.});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Update database.
|
# Update database.
|
||||||
my $dbq = $Auto::DB->do("UPDATE qdb SET quote = \"NOTICE: Quote deleted.\" WHERE key = $argv[1]");
|
my $dbq = $Auto::DB->do("UPDATE qdb SET quote = \"NOTICE: Quote deleted.\" WHERE quoteid = $argv[1]");
|
||||||
|
|
||||||
notice($data{svr}, $data{nick}, (($dbq) ? 'Done.' : trans('An error occurred').q{.}));
|
notice($src->{svr}, $src->{nick}, (($dbq) ? 'Done.' : trans('An error occurred').q{.}));
|
||||||
}
|
}
|
||||||
default { notice($data{svr}, $data{nick}, "Unknown action \002".uc($argv[0])."\002. \002Syntax:\002 QDB (ADD|VIEW|COUNT|RAND|DEL) [quote]"); return; }
|
default { notice($src->{svr}, $src->{nick}, "Unknown action \002".uc($argv[0])."\002. \002Syntax:\002 QDB (ADD|VIEW|COUNT|RAND|DEL) [quote]"); return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
API::Std::mod_init('QDB', 'Xelhua', '1.00', '3.0.0d', __PACKAGE__);
|
API::Std::mod_init('QDB', 'Xelhua', '1.02', '3.0.0a4', __PACKAGE__);
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
# build: perl=5.010000
|
# build: perl=5.010000
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
=head1 QDB
|
=head1 NAME
|
||||||
|
|
||||||
=head2 Description
|
QDB - Quote database module.
|
||||||
|
|
||||||
=over
|
=head1 VERSION
|
||||||
|
|
||||||
This module adds the QDB (ADD|VIEW|COUNT|RAND|DEL) command, for adding,
|
1.02
|
||||||
viewing, listing number of, viewing a random, deleting a quote from the Auto
|
|
||||||
database.
|
|
||||||
|
|
||||||
=back
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
=head2 Examples
|
<JohnSmith> !qdb add <JohnDoe> moocows
|
||||||
|
<Auto> Quote successfully submitted. ID: 732
|
||||||
|
|
||||||
=over
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
<JohnSmith> !qdb add <JohnDoe> moocows
|
This module adds the QDB (ADD|VIEW|COUNT|RAND|SEARCH|MORE|DEL) command, for
|
||||||
<Auto> Quote successfully submitted. ID: 732
|
adding, viewing, listing number of, viewing a random, deleting a quote from the
|
||||||
|
Auto database.
|
||||||
|
|
||||||
=back
|
=head1 INSTALL
|
||||||
|
|
||||||
=head2 Technical
|
Before using QDB, we'd recommend adding the following to your configuration
|
||||||
|
file:
|
||||||
|
|
||||||
=over
|
qdb_search_resnum <number>;
|
||||||
|
|
||||||
This module is compatible with Auto v3.0.0a3+.
|
Where <number> is the amount of results returned per SEARCH/MORE load.
|
||||||
|
|
||||||
=back
|
This is not required, 4 will be used if it is not specified.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
This module was written by Elijah Perrault.
|
||||||
|
|
||||||
|
This module is maintained by Xelhua Development Group.
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This module is Copyright 2010-2011 Xelhua Development Group.
|
||||||
|
|
||||||
|
Released under the same licensing terms as Auto itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
+17
-17
@@ -1,7 +1,7 @@
|
|||||||
# Module: SASLAuth. See below for documentation.
|
# Module: SASLAuth. See below for documentation.
|
||||||
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
# This program is free software; rights to this code are stated in doc/LICENSE.
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
package m_SASLAuth;
|
package M::SASLAuth;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use feature qw(switch);
|
use feature qw(switch);
|
||||||
@@ -13,32 +13,32 @@ use API::IRC qw(privmsg);
|
|||||||
# Initialization subroutine.
|
# Initialization subroutine.
|
||||||
sub _init
|
sub _init
|
||||||
{
|
{
|
||||||
# Check if this Auto was built with SASL support.
|
# Check if this Auto was built with SASL support.
|
||||||
err(2, "Auto was not built with SASL support. Aborting SASLAuth.", 0) and return 0 if $Auto::ENFEAT !~ /sasl/;
|
err(2, "Auto was not built with SASL support. Aborting SASLAuth.", 0) and return 0 if $Auto::ENFEAT !~ /sasl/;
|
||||||
# Add a hook for before we connect.
|
# Add a hook for before we connect.
|
||||||
hook_add('on_preconnect', 'CAP', sub { my ($srv) = @_; Auto::socksnd($srv, 'CAP LS'); }
|
hook_add('on_preconnect', 'CAP', sub { my ($srv) = @_; Auto::socksnd($srv, 'CAP LS'); }
|
||||||
) or return 0;
|
) or return 0;
|
||||||
# Hook for parsing CAP.
|
# Hook for parsing CAP.
|
||||||
rchook_add('CAP', \&m_SASLAuth::handle_cap) or return 0;
|
rchook_add('CAP', \&M::SASLAuth::handle_cap) or return 0;
|
||||||
# Hook for parsing 903.
|
# Hook for parsing 903.
|
||||||
rchook_add('903', \&m_SASLAuth::handle_903) or return 0;
|
rchook_add('903', \&M::SASLAuth::handle_903) or return 0;
|
||||||
# Hook for parsing 904.
|
# Hook for parsing 904.
|
||||||
rchook_add('904', \&m_SASLAuth::handle_904) or return 0;
|
rchook_add('904', \&M::SASLAuth::handle_904) or return 0;
|
||||||
# Hook for parsing 906.
|
# Hook for parsing 906.
|
||||||
rchook_add('906', \&m_SASLAuth::handle_906) or return 0;
|
rchook_add('906', \&M::SASLAuth::handle_906) or return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Void subroutine.
|
# Void subroutine.
|
||||||
sub _void
|
sub _void
|
||||||
{
|
{
|
||||||
# Delete the hooks.
|
# Delete the hooks.
|
||||||
hook_del("on_preconnect", "CAP") or return 0;
|
hook_del("on_preconnect", "CAP") or return 0;
|
||||||
rchook_del('CAP');
|
rchook_del('CAP');
|
||||||
rchook_del('903');
|
rchook_del('903');
|
||||||
rchook_del('904');
|
rchook_del('904');
|
||||||
rchook_del('906');
|
rchook_del('906');
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub handle_cap {
|
sub handle_cap {
|
||||||
@@ -123,20 +123,20 @@ sub handle_904
|
|||||||
# SASL authentication aborted.
|
# SASL authentication aborted.
|
||||||
sub handle_906
|
sub handle_906
|
||||||
{
|
{
|
||||||
my ($svr, undef) = @_;
|
my ($svr, undef) = @_;
|
||||||
Auto::socksnd($svr, 'CAP END');
|
Auto::socksnd($svr, 'CAP END');
|
||||||
timer_del('auth_timeout');
|
timer_del('auth_timeout');
|
||||||
awarn(2, "SASL authentication aborted!");
|
awarn(2, "SASL authentication aborted!");
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start initialization.
|
# Start initialization.
|
||||||
API::Std::mod_init("SASLAuth", "Xelhua", "1.00", "3.0.0d", __PACKAGE__);
|
API::Std::mod_init('SASLAuth', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
# build: perl=5.010000
|
# build: perl=5.010000
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
=head1 SASL Auth
|
=head1 SASLAuth
|
||||||
|
|
||||||
=head2 Description
|
=head2 Description
|
||||||
|
|
||||||
@@ -188,6 +188,6 @@ block(s) you wish to use SASL with:
|
|||||||
This adds an extra dependency: You must build Auto with the
|
This adds an extra dependency: You must build Auto with the
|
||||||
--enable-sasl option.
|
--enable-sasl option.
|
||||||
|
|
||||||
This module is compatible with Auto v3.0.0a1+.
|
This module is compatible with Auto v3.0.0a4+.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
+47
-48
@@ -1,7 +1,7 @@
|
|||||||
# Module: Weather. See below for documentation.
|
# Module: Weather. See below for documentation.
|
||||||
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
# This program is free software; rights to this code are stated in doc/LICENSE.
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
package m_Weather;
|
package M::Weather;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use API::Std qw(cmd_add cmd_del trans);
|
use API::Std qw(cmd_add cmd_del trans);
|
||||||
@@ -12,74 +12,73 @@ use XML::Simple;
|
|||||||
# Initialization subroutine.
|
# Initialization subroutine.
|
||||||
sub _init
|
sub _init
|
||||||
{
|
{
|
||||||
# Create the Weather command.
|
# Create the Weather command.
|
||||||
cmd_add("WEATHER", 0, 0, \%m_Weather::HELP_WEATHER, \&m_Weather::weather) or return 0;
|
cmd_add("WEATHER", 0, 0, \%M::Weather::HELP_WEATHER, \&M::Weather::weather) or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Void subroutine.
|
# Void subroutine.
|
||||||
sub _void
|
sub _void
|
||||||
{
|
{
|
||||||
# Delete the Weather command.
|
# Delete the Weather command.
|
||||||
cmd_del("WEATHER") or return 0;
|
cmd_del("WEATHER") or return 0;
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Help hashes.
|
# Help hashes.
|
||||||
our %HELP_WEATHER = (
|
our %HELP_WEATHER = (
|
||||||
'en' => "This command will retrieve the weather via Wunderground for the specified location. \002Syntax:\002 WEATHER <location>",
|
'en' => "This command will retrieve the weather via Wunderground for the specified location. \002Syntax:\002 WEATHER <location>",
|
||||||
);
|
);
|
||||||
|
|
||||||
# Callback for Weather command.
|
# Callback for Weather command.
|
||||||
sub weather
|
sub weather
|
||||||
{
|
{
|
||||||
my (%data) = @_;
|
my ($src, @args) = @_;
|
||||||
|
|
||||||
# Create an instance of LWP::UserAgent.
|
# Create an instance of LWP::UserAgent.
|
||||||
my $ua = LWP::UserAgent->new();
|
my $ua = LWP::UserAgent->new();
|
||||||
$ua->agent('Auto IRC Bot');
|
$ua->agent('Auto IRC Bot');
|
||||||
$ua->timeout(2);
|
$ua->timeout(2);
|
||||||
# Put together the call to the Wunderground API.
|
# Put together the call to the Wunderground API.
|
||||||
my @args = @{ $data{args} };
|
if (!defined $args[0]) {
|
||||||
if (!defined $args[0]) {
|
notice($src->{svr}, $src->{nick}, trans("Not enough parameters").".");
|
||||||
notice($data{svr}, $data{nick}, trans("Not enough parameters").".");
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
my $loc = join(' ', @args);
|
||||||
my $loc = join(' ', @args);
|
$loc =~ s/ /%20/g;
|
||||||
$loc =~ s/ /%20/g;
|
my $url = "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=".$loc;
|
||||||
my $url = "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=".$loc;
|
# Get the response via HTTP.
|
||||||
# Get the response via HTTP.
|
my $response = $ua->get($url);
|
||||||
my $response = $ua->get($url);
|
|
||||||
|
|
||||||
if ($response->is_success) {
|
if ($response->is_success) {
|
||||||
# If successful, decode the content.
|
# If successful, decode the content.
|
||||||
my $d = XMLin($response->decoded_content);
|
my $d = XMLin($response->decoded_content);
|
||||||
# And send to channel
|
# And send to channel
|
||||||
if (!ref($d->{observation_location}->{country})) {
|
if (!ref($d->{observation_location}->{country})) {
|
||||||
my $windc = $d->{wind_string};
|
my $windc = $d->{wind_string};
|
||||||
if (substr($windc, length($windc) - 1, 1) eq " ") { $windc = substr($windc, 0, length($windc) - 1); }
|
if (substr($windc, length($windc) - 1, 1) eq " ") { $windc = substr($windc, 0, length($windc) - 1); }
|
||||||
privmsg($data{svr}, $data{chan}, "Results for \2".$d->{observation_location}->{full}."\2 - \2Temperature:\2 ".$d->{temperature_string}." \2Wind Conditions:\2 ".$windc." \2Conditions:\2 ".$d->{weather});
|
privmsg($src->{svr}, $src->{chan}, "Results for \2".$d->{observation_location}->{full}."\2 - \2Temperature:\2 ".$d->{temperature_string}." \2Wind Conditions:\2 ".$windc." \2Conditions:\2 ".$d->{weather});
|
||||||
privmsg($data{svr}, $data{chan}, "\2Heat index:\2 ".$d->{heat_index_string}." \2Humidity:\2 ".$d->{relative_humidity}." \2Pressure:\2 ".$d->{pressure_string}." - ".$d->{observation_time});
|
privmsg($src->{svr}, $src->{chan}, "\2Heat index:\2 ".$d->{heat_index_string}." \2Humidity:\2 ".$d->{relative_humidity}." \2Pressure:\2 ".$d->{pressure_string}." - ".$d->{observation_time});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, send an error message.
|
# Otherwise, send an error message.
|
||||||
privmsg($data{svr}, $data{chan}, "Location not found.");
|
privmsg($src->{svr}, $src->{chan}, "Location not found.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Otherwise, send an error message.
|
# Otherwise, send an error message.
|
||||||
privmsg($data{svr}, $data{chan}, "An error occurred while retrieving your weather.");
|
privmsg($src->{svr}, $src->{chan}, "An error occurred while retrieving your weather.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start initialization.
|
# Start initialization.
|
||||||
API::Std::mod_init("Weather", "Xelhua", "1.00", "3.0.0d", __PACKAGE__);
|
API::Std::mod_init('Weather', 'Xelhua', '1.00', '3.0.0a4', __PACKAGE__);
|
||||||
# vim: set ai sw=4 ts=4:
|
# vim: set ai sw=4 ts=4:
|
||||||
# build: cpan=LWP::UserAgent,XML::Simple perl=5.010000
|
# build: cpan=LWP::UserAgent,XML::Simple perl=5.010000
|
||||||
|
|
||||||
@@ -122,6 +121,6 @@ From the NE at 9 MPH Gusting to 22 MPH Conditions: Overcast
|
|||||||
This module requires LWP::UserAgent and XML::Simple. Both are
|
This module requires LWP::UserAgent and XML::Simple. Both are
|
||||||
obtainable from CPAN <http://www.cpan.org>.
|
obtainable from CPAN <http://www.cpan.org>.
|
||||||
|
|
||||||
This module is compatible with Auto version 3.0.0a2+.
|
This module is compatible with Auto version 3.0.0a4+.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
Executable
+66
@@ -0,0 +1,66 @@
|
|||||||
|
# upgrade.pl - Upgrade SQLite database from 3.0.0a3 to 3.0.0a4.
|
||||||
|
# Copyright (C) 2010-2011 Xelhua Development Group, et al.
|
||||||
|
# This program is free software; rights to this code are stated in doc/LICENSE.
|
||||||
|
use 5.010_000;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use DBI;
|
||||||
|
use DBD::SQLite;
|
||||||
|
use Carp;
|
||||||
|
use Cwd;
|
||||||
|
our $Bin = getcwd();
|
||||||
|
|
||||||
|
#################
|
||||||
|
# Configuration #
|
||||||
|
#################
|
||||||
|
|
||||||
|
# Old database filename. (relative to etc/)
|
||||||
|
my $olddbfile = 'auto.db';
|
||||||
|
# New database filename. (relative to etc/)
|
||||||
|
my $newdbfile = 'somebot.db';
|
||||||
|
|
||||||
|
##########################
|
||||||
|
# Program - Don't touch. #
|
||||||
|
##########################
|
||||||
|
|
||||||
|
# Print startup message.
|
||||||
|
say 'Converting database from Auto-3.0.0a3 format to Auto-3.0.0a4 format...';
|
||||||
|
|
||||||
|
# Connect to database.
|
||||||
|
my $DB = DBI->connect("dbi:SQLite:dbname=$Bin/etc/$olddbfile") or croak 'Failed to open old DB!';
|
||||||
|
|
||||||
|
# Query the database for the data from the `qdb` table.
|
||||||
|
my $dbq = $DB->prepare('SELECT * FROM qdb') or croak 'Failed to query for `qdb` data!';
|
||||||
|
$dbq->execute() or croak 'Failed to query for `qdb` data!';
|
||||||
|
my $data = $dbq->fetchall_hashref('key');
|
||||||
|
my %data = %$data;
|
||||||
|
|
||||||
|
# Disconnect from database.
|
||||||
|
$DB->disconnect;
|
||||||
|
|
||||||
|
|
||||||
|
# Now, connect to the new database so we can enter the data in the new format.
|
||||||
|
if (!-e "$Bin/etc/$newdbfile") {
|
||||||
|
system "touch $Bin/etc/$newdbfile";
|
||||||
|
chmod 0755, "$Bin/etc/$newdbfile";
|
||||||
|
}
|
||||||
|
|
||||||
|
$DB = DBI->connect("dbi:SQLite:dbname=$Bin/etc/$newdbfile") or croak 'Failed to open new DB!';
|
||||||
|
|
||||||
|
# Create the `qdb` table.
|
||||||
|
$DB->do('CREATE TABLE IF NOT EXISTS qdb (quoteid INTEGER PRIMARY KEY, creator TEXT, time INT, quote TEXT)') or croak 'Failed to create `qdb` table!';
|
||||||
|
|
||||||
|
# Iterate through the data.
|
||||||
|
foreach my $qid (sort keys %data) {
|
||||||
|
# Prepare query to insert data.
|
||||||
|
my $ndbq = $DB->prepare('INSERT INTO qdb (quoteid, creator, time, quote) VALUES (?, ?, ?, ?)') or croak 'Failed to query `qdb` table!';
|
||||||
|
|
||||||
|
# Insert data.
|
||||||
|
$ndbq->execute($qid, $data{$qid}{creator}, $data{$qid}{'time'}, $data{$qid}{quote}) or croak 'Failed to query `qdb` table!';
|
||||||
|
}
|
||||||
|
|
||||||
|
# Disconnect from database.
|
||||||
|
$DB->disconnect;
|
||||||
|
|
||||||
|
# Success.
|
||||||
|
say 'Done.';
|
||||||
Reference in new issue
Block a user