From 0293b9d684ce2f89a1850b7a0d4819bdd1c947ef Mon Sep 17 00:00:00 2001 From: William Heimbigner Date: Sun, 25 Nov 2007 21:33:40 +0000 Subject: better logging, better flood detection, command ignoring --- config-default/channels.xml | 31 ++++++++++++++++----- config-default/commands.xml | 9 +++++++ config-default/users.xml | 1 + meta.pl | 3 ++- modules/classes.pl | 32 ++++++++++++++++++++++ modules/command.pl | 1 + modules/event.pl | 12 ++++++++- modules/mysql.pl | 66 ++++++++++++++++++++++++++++++++++++++++++++- modules/util.pl | 11 ++++++++ 9 files changed, 157 insertions(+), 9 deletions(-) diff --git a/config-default/channels.xml b/config-default/channels.xml index c79d99b..a91e4af 100644 --- a/config-default/channels.xml +++ b/config-default/channels.xml @@ -6,7 +6,7 @@ - + ST47 alindeman @@ -54,6 +54,7 @@ + njan @@ -77,7 +78,7 @@ - + tomaw Dave2 @@ -100,6 +101,10 @@ #freenode-adb + + + + @@ -121,6 +126,10 @@ + + + + Mbimmler @@ -128,7 +137,7 @@ Fabexplosive - #wikimedia-ops + #wikimedia-ops @@ -164,6 +173,7 @@ Mbimmler Karlprof Martinp23 + Pilotguy Pilotguy Eagle-101 skenmy @@ -181,9 +191,11 @@ njan mike42 Pilotguy + kloeri #wikimedia-ops + ##wikimedia-ops @@ -195,7 +207,7 @@ - + Cometstyles Majorly Worby @@ -205,6 +217,7 @@ wimt werdan7 Animum + Deskana AppleBoy Soms Martinp23 @@ -214,12 +227,15 @@ #wikimedia-ops + ##wikimedia-ops TheLetterE werdan7 + GDonato + TheLetterE #wikimedia-ops @@ -251,6 +267,7 @@ Golbez + TheLetterE #wikimedia-ops @@ -263,8 +280,7 @@ ^requested by ChanServ - tinyurl\.com/ypvk4n - blah + blah .* ^DCC SEND |\bDCC SEND "?[A-Za-z0-9]+"? \d+ \d+ \d+ DCC SEND @@ -282,6 +298,7 @@ contentisuseless i=magical 5:3 + 5:3 150:20 .* RED ARMY OF LOL @@ -290,8 +307,10 @@ AfterDeath ST47 + troubled alindeman seanw + dave2 ##asb-nexus diff --git a/config-default/commands.xml b/config-default/commands.xml index 3ab49e9..5a4341c 100644 --- a/config-default/commands.xml +++ b/config-default/commands.xml @@ -1,4 +1,13 @@ + + {DBH}; + if ($1 eq 'log') { + $dbh = $::db->{DBH_LOG}; + } + $::db->raw($conn, $event->{to}->[0], $dbh, $2); + ]]> + privmsg($event->{to}->[0], "help is at http://meta.wikimedia.org/wiki/User:WHeimbigner/AntiSpamMeta"); diff --git a/config-default/users.xml b/config-default/users.xml index 88fbd66..f0fc3a6 100644 --- a/config-default/users.xml +++ b/config-default/users.xml @@ -17,5 +17,6 @@ + diff --git a/meta.pl b/meta.pl index faadd93..14c6f00 100755 --- a/meta.pl +++ b/meta.pl @@ -32,6 +32,7 @@ sub init { 'pass|p:s' => \$::pass, 'config|c:s' => \$::cset ); + $::debug = $debug; ASM::XML->readXML(); mkdir($::settings->{log}->{dir}); $::log = ASM::Log->new($::settings->{log}); @@ -39,7 +40,7 @@ sub init { $host = ${$::settings->{server}}[rand @{$::settings->{server}}]; print "Connecting to $host\n"; $irc->debug($debug); - $::db = ASM::DB->new($::mysql->{db}, $::mysql->{host}, $::mysql->{port}, $::mysql->{user}, $::mysql->{pass}, $::mysql->{table}); + $::db = ASM::DB->new($::mysql->{db}, $::mysql->{host}, $::mysql->{port}, $::mysql->{user}, $::mysql->{pass}, $::mysql->{table}, $::mysql->{dblog}); $conn = $irc->newconn( Server => $host, Port => $::settings->{port} || '6667', Nick => $::settings->{nick}, diff --git a/modules/classes.pl b/modules/classes.pl index 36a8031..775eae6 100644 --- a/modules/classes.pl +++ b/modules/classes.pl @@ -17,6 +17,7 @@ sub new "floodqueue" => \&floodqueue, "nickspam" => \&nickspam, "splitflood" => \&splitflood, + "advsplitflood" => \&advsplitflood, "re" => \&re, "nick" => \&nick, "ident" => \&ident, @@ -151,6 +152,37 @@ sub splitflood { return 0; } +sub advsplitflood { + my ($chk, $id, $event, $chan) = @_; + my $text; + my @cut = split(/:/, $chk->{content}); + $cf{$id}{timeout}=int($cut[1]); + if ($event->{type} =~ /^(public|notice|part|caction)$/) { + $text=$event->{args}->[0]; + } + return unless defined($text); + $text=~s/^\d+(.*)\d+$/$1/; + return unless length($text) >= 10; + if (defined($bs{$id}{$text}) && (time <= $bs{$id}{$text} + 600)) { + return 1; + } + push( @{$cf{$id}{$chan}{$text}}, time ); + while ( time >= $cf{$id}{$chan}{$text}[0] + $cf{$id}{'timeout'} ) { + last if ( $#{$cf{$id}{$chan}{$text}} == 0 ); + shift ( @{$cf{$id}{$chan}{$text}} ); + } + $cfc = $cfc + 1; + if ( $cfc >= 100 ) { + $cfc = 0; + process_cf(); + } + if ( $#{@{$cf{$id}{$chan}{$text}}}+1 == int($cut[0]) ) { + $bs{$id}{$text} = time; + return 1; + } + return 0; +} + sub re { my ($chk, $id, $event, $chan) = @_; my $match = $event->{args}->[0]; diff --git a/modules/command.pl b/modules/command.pl index 04f1d90..27cc5a9 100644 --- a/modules/command.pl +++ b/modules/command.pl @@ -19,6 +19,7 @@ sub command my $cmd = $args; my $d1; my $nick = lc $event->{nick}; + return 0 unless (ASM::Util->speak($event->{to}->[0])); foreach my $command ( @{$::commands->{command}} ) { if (defined($command->{flag})) { diff --git a/modules/event.pl b/modules/event.pl index c77fda1..2d247b6 100644 --- a/modules/event.pl +++ b/modules/event.pl @@ -96,11 +96,13 @@ sub on_join { @mship = (@mship, $chan); $::sn{$nick}->{mship} = \@mship; $::inspector->inspect( $conn, $event ); + $::db->logg($event); } else { $::sn{$nick} = {}; $::sn{$nick}->{mship} = [ $chan ]; if (defined($::needgeco{$nick})) { $::needgeco{$nick} = [ @{$::needgeco{$nick}}, $evcopy ]; + $::db->logg($event); } else { $::needgeco{$nick} = [ $evcopy ]; $conn->sl("whois $nick"); @@ -115,6 +117,7 @@ sub on_part $::inspector->inspect( $conn, $event ); my $nick = lc $event->{nick}; $::log->logg( $event ); + $::db->logg( $event ); if (defined($::sn{$nick}) && defined($::sn{$nick}->{mship})) { my @mship = @{$::sn{$nick}->{mship}}; @mship = grep { lc $_ ne lc $event->{to}->[0] } @mship; @@ -146,6 +149,7 @@ sub on_public my ($conn, $event) = @_; $::inspector->inspect( $conn, $event ); $::log->logg( $event ); + $::db->logg( $event ); $::commander->command( $conn, $event ); } @@ -154,6 +158,7 @@ sub on_notice my ($conn, $event) = @_; $::inspector->inspect( $conn, $event ); $::log->logg( $event ); + $::db->logg( $event ); $::services->doServices($conn, $event); } @@ -173,6 +178,7 @@ sub on_quit push ( @channels, $_ ) if delete $::sc{lc $_}{users}{lc $event->{nick}}; } $event->{to} = \@channels; + $::db->logg( $event ); delete($::sn{lc $event->{nick}}); $::inspector->inspect( $conn, $event ); $::log->logg( $event ); @@ -226,6 +232,7 @@ sub irc_topic { $::sc{lc $event->{to}->[0]}{topic}{text} = $event->{args}->[0]; } $::log->logg($event); + $::db->logg( $event ); } } @@ -242,10 +249,11 @@ sub on_nick { } } $::sn{lc $event->{args}->[0]} = $::sn{lc $event->{nick}}; + $::db->logg( $event ); delete( $::sn{lc $event->{nick}}); $event->{to} = \@channels; $::inspector->inspect($conn, $event); - $::log->logg($event) + $::log->logg($event); } sub on_kick { @@ -255,6 +263,7 @@ sub on_kick { } my $nick = lc $event->{to}->[0]; $::log->logg( $event ); + $::db->logg( $event ); if (defined($::sn{$nick}) && defined($::sn{$nick}->{mship})) { my @mship = @{$::sn{$nick}->{mship}}; @mship = grep { lc $_ ne lc $event->{to}->[0] } @mship; @@ -380,6 +389,7 @@ sub whois_user { if (defined( $::needgeco{$lnick} )) { foreach my $event (@{$::needgeco{$lnick}}) { $::inspector->inspect($conn, $event); + $::db->logg( $event ); } delete $::needgeco{$lnick}; } diff --git a/modules/mysql.pl b/modules/mysql.pl index 998c647..22369e1 100644 --- a/modules/mysql.pl +++ b/modules/mysql.pl @@ -6,10 +6,12 @@ use DBI; sub new { my $module = shift; - my ($db, $host, $port, $user, $pass, $table) = @_; + my ($db, $host, $port, $user, $pass, $table, $dblog) = @_; my $self = {}; $self->{DBH} = DBI->connect("DBI:mysql:database=$db;host=$host;port=$port", $user, $pass); + $self->{DBH_LOG} = DBI->connect("DBI:mysql:database=$dblog;host=$host;port=$port", $user, $pass); $self->{DBH}->{mysql_auto_reconnect} = 1; + $self->{DBH_LOG}->{mysql_auto_reconnect} = 1; $self->{TABLE} = $table; bless($self); return $self; @@ -22,6 +24,28 @@ sub new { # $::dbh->{mysql_auto_reconnect} = 1; #} +sub raw +{ + my $self = shift; + my ($conn, $tgt, $dbh, $qry) = @_; + my $sth = $dbh->prepare($qry); + $sth->execute; + my $names = $sth->{'NAME'}; + my $numFields = $sth->{'NUM_OF_FIELDS'}; + my $string = ""; + for (my $i = 0; $i < $numFields; $i++) { + $string = $string . sprintf("%s%s", $i ? "," : "", $$names[$i]); + } + $conn->privmsg($tgt, $string); + while (my $ref = $sth->fetchrow_arrayref) { + $string = ""; + for (my $i = 0; $i < $numFields; $i++) { + $string = $string . sprintf("%s%s", $i ? "," : "", $$ref[$i]); + } + $conn->privmsg($tgt, $string); + } +} + sub record { my $self = shift; @@ -36,6 +60,46 @@ sub record $dbh->quote($id) . ", " . $dbh->quote($reason) . ");"); } +#FIXME: This function is shit. Also, it doesn't work like I want it to with mode. +sub logg +{ + my $self = shift; + my ($event) = @_; + my $dbh = $self->{DBH_LOG}; + my $table = $event->{type}; + $table = 'action' if ($table eq 'caction'); + $table = 'privmsg' if ($table eq 'public'); + my $realtable = $table; + $realtable = 'joins' if $realtable eq 'join'; #mysql doesn't like a table named join + my $string = 'INSERT INTO `' . $realtable . '` ('; + if (($table ne 'nick') && ($table ne 'quit')) { + $string = $string . 'channel, '; + } + $string = $string . 'nick, user, host, geco'; + if ($table ne 'join') { + $string = $string . ', content1'; + } + if (($table eq 'kick') || ($table eq 'mode')) { + $string = $string . ', content2'; + } + $string = $string . ') VALUES ('; + if (($table ne 'nick') && ($table ne 'quit')) { + $string = $string . $dbh->quote($event->{to}->[0]) . ", "; + } + my $geco = $::sn{lc $event->{nick}}->{gecos}; + $string = $string . $dbh->quote($event->{nick}) . ", " . $dbh->quote($event->{user}) . ", " . + $dbh->quote($event->{host}) . ", " . $dbh->quote($geco); + if ($table ne 'join') { + $string = $string. ', ' . $dbh->quote($event->{args}->[0]); + } + if (($table eq 'kick') || ($table eq 'mode')) { + $string = $string . ', ' . $dbh->quote($event->{args}->[1]); + } + $string = $string . ');'; + print $string . "\n" if $::debug; + $dbh->do($string); +} + sub query { my $self = shift; diff --git a/modules/util.pl b/modules/util.pl index 4fe63ee..5a32e11 100644 --- a/modules/util.pl +++ b/modules/util.pl @@ -86,6 +86,17 @@ sub getLink return $chan; } +sub speak +{ + my ($module, $chan) = @_; + $chan = lc $chan; + if ( defined(cs($module, $chan)->{silence}) && (cs($module, $chan)->{silence} eq "yes") ) { + return 0; + } else { + return 1; + } +} + #this item is a stub, dur sub hostip { return gethostbyname($_[0]); -- cgit v1.2.3