User:AntiSpamBot/Source
From Wikipedia, the free encyclopedia
A slightly cleaned-up (read: scrubbed passwords) version of the Shadowbot source. Please don't leave me messages about my coding/database design or style, I hear it enough. If you don't like it, then fix the code and give me a *nix-style .patch file. Shadow1 (talk) 19:37, 4 February 2007 (UTC)
#First, let's declare our modules. use Net::IRC; use Shadowbot; use Perlwikipedia; use DBI; use threads; use threads::shared; my $page_grabber=Perlwikipedia->new; #Now we'll set up the mechanism we'll use for editing/retrieving pages my $editor=Shadowbot->new; my $username='Shadowbot'; my $password='*************'; my $login_status=$editor->login($username,$password); #Log us in, cap'n! my %info : shared; my $number_of_jobs : shared=0; $info{timeon}=localtime(); $info{users}=0; unless ($login_status eq 'Success') { #Darn, we didn't log in die "Failed to log into Wikipedia.\n"; } if ($login_status eq 'Success') { #We've logged in. print "Logged into Wikipedia.\n"; } #Declare all sorts of IRC-related goodness my $nickname = 'shadowbot'; my $username = 'Shadowbot'; my $ircname = 'Shadowbot anti-spam bot'; my $ircserver = 'niven.freenode.net'; my $port = 8001; my @channels = ( '#wikipedia-en-spam', '#wikipedia-en-spam-bot', '#wikipedia-spam-t' ); #Set up various data structures my $do_i_revert : shared=1; my $revert_once : shared=1; my $detect_refs : shared=1; my $sizelimit : shared =500; my $irc=new Net::IRC; my $freenode=$irc->newconn(Nick =>$nickname, Username =>$username, Ircname =>$ircname, Server =>$ircserver, Port =>$port ); $freenode->add_handler('376',\&connect); $freenode->add_handler('public',\&public_message_handler); $irc->start; sub connect { print "Connected to $ircserver.\n"; $freenode->privmsg("NickServ","identify *******"); sleep 5; foreach $channel (@channels) { $freenode->join($channel); } } sub public_message_handler { my ($self,$event) = @_; my $handler_thread=threads->new(\&irc_public, $self, $event)->detach; } sub irc_public { my ($self) = shift; my ($event) = shift; my ($message) = ($event->args); my ($nick) = ($event->nick); my ($cloak)=($event->userhost); my $channel = ($event->to)[0]; $cloak=(split /@/, $cloak)[1]; $message =~ s/\cC\d{1,2}(?:,\d{1,2})?|[\cC\cB\cI\cU\cR\cO]//g; #Kill any color codes. if ( $channel eq '#wikipedia-en-spam-bot' ) { #Are we talking in the bot channel? if (check_mysql("authorized_bots",$nick)) { #Yep, it's a bot $number_of_jobs++; processalert($message); #Process the message. --$number_of_jobs; } #It's a bot } #It's a bot channel if ( $channel eq '#wikipedia-en-spam' | $channel eq '#wikipedia-spam-t') { #Command channel? if ($message=~m/^!shadowbot activate override (.+)/) { my $rule=$1; my $verified=authenticate($cloak); if ($verified) { set_override($rule,1); $freenode->privmsg($channel,"$rule override turned on."); } else { $freenode->privmsg($channel,"User $nick not in my list of trusted users."); } } if ($message=~m/^!shadowbot deactivate override (.+)/) { my $rule=$1; my $verified=authenticate($cloak); if ($verified) { set_override($rule,0); $freenode->privmsg($channel,"$rule override turned off."); } else { $freenode->privmsg($channel,"User $nick not in my list of trusted users."); } } if ($message=~m/^!shadowbot status/) { my $message_to_send="I've been active since $info{timeon}. I've reverted $info{users} times. "; if ($revert_once) { $message_to_send.="I'm currently in calm mode. "; } else { $message_to_send.="I'm currently in angry mode. "; } $message_to_send.="I have $number_of_jobs active jobs running."; $freenode->privmsg($channel,$message_to_send); } if ($message=~m/^!shadowbot linksearch (.+)/) { my $number=do_linksearch($1); if ($number) { $freenode->privmsg($channel,"$1 appears in $number article(s)."); } else{$freenode->privmsg($channel,"$1 does not appear in any articles."); } } if ($message=~m/^!shadowbot mode (.+)/) { my $mode=$1; $verified=authenticate($cloak); if ($verified) { if ($mode=~/angry/) { $revert_once=0; $freenode->privmsg($channel,"Safety check disabled."); } elsif($mode=~/calm/) { $revert_once=1; $freenode->privmsg($channel,"Safety check enabled."); } else { $freenode->privmsg($channel,"Mode $mode not recognized."); } } else { $freenode->privmsg($channel,"User $nick not in my list of trusted users."); } } if ($message=~m/^!shadowbot size (\d+)/) { #It's a size command my $verified=0; my $newsize=$1; $verified=authenticate($cloak); #Authenticate the user if ($verified==1) { #Are they supposed to do this? $sizelimit=$newsize; #Change the size $freenode->privmsg($channel,"Size limit changed to $sizelimit."); #Report back } #They're supposed to do this elsif ($verified==0) { #They're not supposed to do this $freenode->privmsg($channel,"User $nick not in my list of trusted users."); #Tell them they've been naughty } #They're not supposed to do this } if ( $message =~ m/^!shadowbot references/ ) { #Checking refs? my $verified = 0; $verified=authenticate($cloak); if ($verified==1) { #Authed? $detect_refs=1; $freenode->privmsg($channel,"Now detecting references."); }#Authed elsif ($verified==0) { #Not authed? $freenode->privmsg($channel,"User $nick not in my list of trusted users."); }#Not authed }#References command if ( $message =~ m/^!shadowbot noreferences/ ) { #Checking refs? my $verified = 0; $verified=authenticate($cloak); if ($verified==1) { #Authed? $detect_refs=0; $freenode->privmsg($channel,"References detection disabled."); }#Authed elsif ($verified==0) { #Not authed? $freenode->privmsg($channel,"User $nick not in my list of trusted users."); }#Not authed }#NoReferences command if ($message=~m/^!shadowbot add authorized (.+)/) { #Adding a bot my $verified=0; my $botname=$1; $verified=authenticate($cloak); if ($verified==1) { $exists=check_mysql("authorized_bots",$botname); unless ($exists) { #Make sure it doesn't exist $authorized_bots{$botname}=''; #Add the bot $freenode->privmsg($channel,"New authorized bot \"$botname\" added."); return; } if ($exists) { $freenode->privmsg($channel,"Bot already exists in my database."); return; } } elsif ($verified==0) { $freenode->privmsg($channel,"User $nick not in my list of trusted users."); } } if ($message=~m/^!shadowbot remove authorized (.+)/) { my $verified=0; my $botname=$1; $verified=authenticate($cloak); if ($verified==1) { $exists=check_mysql("authorized_bots",$botname); unless ($exists) { $freenode->privmsg($channel,"Bot does not exist in my database."); return; } if ($exists) { delete $authorized_bots{$botname}; $freenode->privmsg($channel,"Authorized bot \"$botname\" deleted."); return; } } elsif ($verified==0) { $freenode->privmsg($channel,"User $nick not in my list of trusted users."); } } if ($message=~m/^!shadowbot depth (.+)/) { #It's a depth command my $verified=0; my $newdepth=$1; $verified=authenticate($cloak); #Authenticate the user if ($verified==1) { #Are they supposed to do this? $searchdepth=$newdepth; #Change the depth $freenode->privmsg($channel,"Search depth changed to $searchdepth."); #Report back } #They're supposed to do this elsif ($verified==0) { #They're not supposed to do this $freenode->privmsg($channel,"User $nick not in my list of trusted users."); #Tell them they've been naughty } #They're not supposed to do this } #It's a depth command if ( $message =~ m/^!shadowbot revert/ ) { #Are we going to go into revert mode? my $verified = 0; $verified=authenticate($cloak); if ($verified==1) { #Verified? $freenode->privmsg($channel,"Reverting enabled."); $do_i_revert=1; #Activate reverting } #Verified? elsif ($verified==0) { #Not verified. $freenode->privmsg($channel,"User $nick not in my list of trusted users."); } #Not verified } #Revert command if ( $message =~ m/^!shadowbot norevert/ ) { #Turning off reversion? my $verified = 0; $verified=authenticate($cloak); if ($verified==1) { #Authed? $do_i_revert=0; $freenode->privmsg($channel,"Reverting disabled."); }#Authed elsif ($verified==0) { #Not authed? $freenode->privmsg($channel,"User $nick not in my list of trusted users."); }#Not authed }#Norevert command if ( $message =~ m/^!link bl add (.+)/ ) { #adding to linkwatcher blacklist? my $toadd = $1; add_mysql("quarantine",'single',$toadd);#Initialize the key with a blank def. $freenode->privmsg($channel,"Item \"$toadd\" has been added to my quarantine list." ); #Report back } #adding to lw blacklist if ( $message =~ m/^!link bl del (.+)/ ) { #deleting from lw blacklist? my $todel = $1; delete_mysql("quarantine",$todel);; #delete the key $freenode->privmsg($channel,"Item \"$todel\" has been removed from my quarantine list." ); }#deleting from lw blacklist if ( $message =~ m/^!shadowbot blacklist search (.+)/ ) { #Search the blacklist my $search = $1; my $exists=check_mysql("blacklist",$search); unless($exists) { #Darn, didn't find it $freenode->privmsg($channel,"$search was not found in my blacklist." ); } #Didn't find string if ($exists) { #Hoorah, we found it $freenode->privmsg($channel,"$search was found in my blacklist." ); } #Found string } #Searching blacklist if ( $message =~ m/^!shadowbot quarantine add (.+)/ ) { #Add to quarantine my $toadd = $1; my $exists=check_mysql("quarantine",$toadd); if ($exists) { #Rule is already there $freenode->privmsg($channel,"Item $toadd is already in my quarantine."); } #Already there unless ($exists) { add_mysql("quarantine",'single',$toadd); $freenode->privmsg($channel,"Item $toadd has been added to my quarantine."); } } } if ( $message =~ m/^!shadowbot approve (.+)/ ) { my $toapprove = $1; my $verified = 0; $verified = authenticate($cloak); if ( $verified == 1 ) { my $exists=check_mysql("quarantine",$toapprove); unless ($exists) { $freenode->privmsg($channel,"Item $toapprove does not exist in my quarantine list." ); } if ($exists) { add_mysql("blacklist",'single',$toapprove); delete_mysql("quarantine",$toapprove); $freenode->privmsg($channel,"Item $toapprove has been approved and added to my blacklist." ); logit("$nick added blacklist rule $toapprove"); my $number=do_linksearch($toapprove); $freenode->privmsg($channel,"$toapprove appears in $number articles."); } } elsif ( $verified == 0 ) { $freenode->privmsg($channel,"User $nick is not in my list of trusted users." ); } } if ( $message =~ m/^!shadowbot deny (.+)/ ) { my $todeny = $1; if ( $message =~ m/!shadowbot deny (.+)/ ) { my $verified = 0; $verified = authenticate($cloak); if ( $verified == 1 ) { my $exists=check_mysql("quarantine",$todeny); unless ($exists) { $freenode->privmsg($channel,"Item $todeny does not exist in my quarantine list."); } if ($exists) { delete_mysql("quarantine",$todeny); $freenode->privmsg($channel,"Item $todeny has been denied and has been removed from my quarantine list."); } } elsif ( $verified == 0 ) { $freenode->privmsg($channel,"User $nick is not in my list of trusted users." ); } } } if ( $message =~ m/^!shadowbot blacklist add (.+)/ ) { my $toadd = $1; if ( $cloak eq 'wikimedia/shadow42' ) { my $exists=check_mysql("blacklist",$toadd); if ($exists) { $freenode->privmsg($channel,"Item $toadd already exists in my blacklist."); } unless ($exists) { add_mysql("blacklist",'single',$toadd); $freenode->privmsg($channel,"Item $toadd has been added to my blacklist."); } } elsif ( $cloak ne 'wikimedia/shadow42' ) { $freenode->privmsg($channel,"Operation \"add\" is restricted to Shadow42." ); } } if ( $message =~ m/^!shadowbot blacklist remove (.+)/ ) { my $toremove = $1; if ( $cloak eq 'wikimedia/shadow42' ) { my $exists=check_mysql("blacklist",$toremove); unless ($exists) { $freenode->privmsg($channel,"Item $toremove does not exist in my blacklist." ); } if ($exists) { delete_mysql("blacklist",$toremove); $freenode->privmsg($channel,"Item $toremove has been removed from my blacklist."); } } elsif ( $cloak ne 'wikimedia/shadow42' ) { $freenode->privmsg($channel,"Operation \"remove\" is restricted to Shadow42." ); } } if ( $message =~ m/^!shadowbot add trusted (.+)/ ) { my $totrust = $1; my $verified = 0; $verified=authenticate($cloak); if ($verified == 1) { my $exists=check_mysql("trusted_users",$totrust); if ($exists) { $freenode->privmsg( $channel => "User cloak $totrust is already in my list of trusted users."); } unless ($exists) { add_mysql("trusted_users","single",$totrust); $freenode->privmsg( $channel => "User cloak $totrust has been added to my list of trusted users."); } elsif ($verified == 0) { $freenode->privmsg( $channel => "User $nick not in my list of trusted users."); } } if ( $message =~ m/^!shadowbot remove trusted (.+)/ ) { my $todelete = $1; my $verified = 0; $verified=authenticate($cloak); if ($verified == 1) { delete_mysql("trusted_users",$todelete); $freenode->privmsg( $channel => "User cloak $todelete has been removed from my list of trusted users."); } elsif ($verified == 0) { $freenode->privmsg( $channel => "User $nick not in my list of trusted users."); } } } } sub parsealert { my $alert = shift; my $pagename; my $user; my $diffurl; my $size; my @rules=(); if ( $alert =~ m/diff=<(.+?)> user=<(.+?)> title=<(.+?)>/ ) { $diffurl =$1; $user =$2; $pagename=$3; } if ($alert=~m/size=<(.+?)>/) { $size=$1; } while ($alert=~m/rule=<(.+?)>/) { my $rule=$1; push(@rules,$rule); $alert=~s/rule=<.+>//; } if ($size=~m/-(\d+)/) { $size=-$1; } elsif ($size=~m/(\d+)/) { $size=$1; } print "Received an alert for $user on $pagename.\n"; return $pagename, $user, $diffurl, $size, @rules; } sub authenticate { my $cloak = shift; my $exists=check_mysql("trusted_users",$cloak); if ($exists) { return 1; } else { return 0; } } sub processalert { my $message=shift; my ( $pagename, $user, $diff, $size, @rules ) = parsealert($message); my @page_revids=$editor->get_history($pagename,'revids'); my $revisionid=$page_revids[1]; my $pagecontents=$editor->grab_text($pagename); my $override=0; foreach $rule (@rules) { $override=check_mysql("overrides",$rule); } if ($size>$sizelimit) { unless ($override) { $freenode->privmsg("#wikipedia-en-spam","ERROR: Failed to revert to $revisionid on $pagename: Edit larger than $sizelimit ($diff)."); return; } } foreach $rule (@rules) { my $exists=check_mysql("blacklist",$rule); unless ($exists) { $freenode->privmsg("#wikipedia-en-spam","ERROR: Rule \"$rule\" was not found in my blacklist, so I can't revert on diff \"$diff\"."); return; } } foreach $rule (@rules) { unless ($pagecontents=~m/$rule/) { $freenode->privmsg("#wikipedia-en-spam","ERROR: Rule \"$rule\" was not found in the on-top version of $pagename ($diff)."); return; } } foreach $rule (@rules) { if ($pagecontents=~m/\{\{.+?$rule.+?\}\}/ | $pagecontents=~m/\<ref.+?\>.+?$rule.+?\<\/ref\>/) { if ($detect_refs==1) { $freenode->privmsg("#wikipedia-en-spam","ERROR: Detected \"$rule\" inside of a reference or template, please manually check ($diff)."); $freenode->privmsg("#wikipedia-spam-t","ERROR: Detected \"$rule\" inside of a reference or template, please manually check ($diff)."); return; } } } if ($do_i_revert==1) { my $rule=$rules[0]; my $edit_summary="BOT--Reverting edits by $user to revision $revisionid ($rule)"; unless ($revisionid==0) { my $safety_status=check_if_safe($pagename,$user,$override); if ($safety_status eq 'Pass') { $editor->revert($pagename,$edit_summary,$revisionid); $freenode->privmsg("#wikipedia-en-spam","Reverted to $revisionid on $pagename ($diff)($rule)."); logit("Reverted to $revisionid on $pagename."); warn_user($user,$diff,$pagename,$rule); $info{users}++; update_rules_stats(@rules); return; } elsif ($safety_status eq 'Fail') { $freenode->privmsg("#wikipedia-en-spam","ERROR: Failed to revert to $revisionid on $pagename: Someone has edited since the spammer ($diff)."); logit("ERROR: Failed to revert to $revisionid on $pagename: Someone has edited since the spammer."); return; } elsif ($safety_status eq 'Alreadydid') { $freenode->privmsg("#wikipedia-en-spam","ERROR: Failed to revert to $revisionid on $pagename: I've already reverted ($diff)."); $freenode->privmsg("#wikipedia-spam-t","ERROR: Failed to revert to $revisionid on $pagename: I've already reverted ($diff)."); logit("ERROR: Failed to revert to $revisionid on $pagename: I've already reverted."); } elsif ($safety_status eq 'Reversion') { $freenode->privmsg("#wikipedia-en-spam","ERROR: Failed to revert to $revisionid on $pagename: Detected reversion ($diff)."); logit("ERROR: Failed to revert to $revisionid on $pagename: Detected reversion."); } } if ($revisionid==0) { $freenode->privmsg("#wikipedia-en-spam","ERROR: An unknown error occurred in my revid retrieval function while reverting $user ($diff)."); logit("ERROR: An unknown error occurred in my revid retrieval function."); return; } } elsif ($do_i_revert==0) { unless ($revisionid==0) { my $safety_status=check_if_safe($pagename,$user); if ($safety_status eq 'Pass') { $freenode->privmsg("#wikipedia-en-spam","Fake-reverted to $revisionid on $pagename ($diff)."); return; } elsif ($safety_status eq 'Fail') { $freenode->privmsg("#wikipedia-en-spam","ERROR: Failed to fake-revert to $revisionid on $pagename: Someone has edited since the spammer ($diff)."); return; } elsif ($safety_status eq 'Alreadydid') { $freenode->privmsg("#wikipedia-en-spam","ERROR: Failed to fake-revert to $revisionid on $pagename: I've already reverted ($diff)."); } elsif ($safety_status eq 'Reversion') { $freenode->privmsg("#wikipedia-en-spam","ERROR: Failed to fake-revert to $revisionid on $pagename: Detected reversion ($diff)."); } } } } sub check_if_safe { my $pagename = shift; my $user = shift; my $override = shift; my @users=$editor->get_history($pagename,'users'); my @comments=$editor->get_history($pagename,'comments'); print "Comparing $users[0] to $user.\n"; unless ($users[0] eq $user) { print "Not equal.\n"; return 'Fail'; } foreach $user (@users[1..2]) { if ($user eq $username) { unless($revert_once==0 || $override==1) {return 'Alreadydid';} } } foreach $comment (@comments[1..2]) { if ($comment=~m/\b(rvv|rv|revert|reverting|VP2|rvt|reverted|reversion|robot|bot|rollback|roll back|rolling back|rolled back)\b/) { return 'Reversion'; } } return 'Pass'; } sub warn_user { my $user=shift; my $diffurl=shift; my $pagename=shift; my $rule=shift; my $time=time(); my $summary=''; my $exists=check_mysql("users",$user); unless ($exists) { add_mysql("users","multiple",$user,$time,"1"); } my $lasttime=query_mysql("users",$user,"2"); my $warninglevel=query_mysql("users",$user,"3"); if (($time-$lasttime)>14400) { $warninglevel=1; } if ($warninglevel==1) { $talk_page="Thank you for contributing to Wikipedia, $user! However, your edit [$diffurl here] was reverted by an automated bot that attempts to remove [[WP:SPAM|spam]] from Wikipedia. If you were trying to insert a good link, please accept my creator's apologies, but note that the link you added, matching rule $rule, is on my list of links to remove and probably shouldn't be included in Wikipedia. Please read [[WP:EL|Wikipedia's external links policy]] for more information. If the link was to an image, please read [[WP:IMAGE|Wikipedia's image tutorial]] on how to use a more appropriate method to insert the image into an article. If your link was intended to promote a site you own, are affiliated with, or will make money from inclusion in Wikipedia, please note that inserting spam into Wikipedia is against policy. For more information about me, see [[User:Shadowbot/FAQ|my FAQ page]]. Thanks! ~~~~"; $summary="Regarding edits made to [[$pagename]]"; } elsif ($warninglevel==2) { $talk_page="Please stop adding inappropriate links to Wikipedia. It is considered [[WP:SPAM|spamming]] and will be removed. Thanks. ~~~~"; } elsif ($warninglevel==3) { $talk_page="Please stop [[WP:SPAM|spamming]] Wikipedia. If you continue, you will be [[WP:BLOCK|blocked]] from editing. ~~~~"; } elsif ($warninglevel==4) { $talk_page="[[Image:Stop hand.svg|30px|left]] This is your '''last warning'''. The next time you insert a [[WP:SPAM|spam]] link, you will be '''blocked''' from editing Wikipedia. ~~~~"; } elsif ($warninglevel>4) { $freenode->privmsg("#wikipedia-spam-t","!admin ALERT: [[User:$user]] has a warning level of $warninglevel."); $freenode->privmsg("#wikipedia-spam","!admin ALERT: [[User:$user]] has a warning level of $warninglevel."); } if ($warninglevel==5) { my $message; if ($user=~m/\d+\.\d+\.\d+\.\d+/) { $message="{{IPvandal|$user}} Has spammed after final warning. ~~~~"; } else { $message="{{vandal|$user}} Has spammed after final warning. ~~~~"; } my $text=$editor->grab_text("Wikipedia:Administrator intervention against vandalism/TB2"); $text .="\n$message"; $editor->edit("Wikipedia:Administrator intervention against vandalism/TB2","Reporting persistent spammer",$text); $freenode->privmsg("#wikipedia-spam","Reported $user to AIV."); $freenode->privmsg("#wikipedia-spam-t","Reported $user to AIV."); } unless ($warninglevel>4) {$editor->edit_talk($user,$summary,$talk_page);} $warninglevel++; update_mysql("users",$user,$time,$warninglevel); } sub do_linksearch { $number_of_jobs++; my $link_pre=shift; $link_pre=~s/\\//g; my $linksearch_page=$page_grabber->{mech}->get("http://en.wikipedia.org/w/index.php?title=Special:Linksearch&target=$link_pre&limit=5000&offset=0")->content; my @links=$linksearch_page=~m{<li>.+\slinked from.+?title="(.+)".+</li>}g; while (my $res = $page_grabber->{mech}->follow_link(text => 'next 5,000')) { my $contents=$res->content; my @new_links=$linksearch_page=~m{<li>.+\slinked from.+title="(.+)".+</li>}g; foreach(@new_links) {push(@links,$_);} sleep 3; } my @links_final; foreach(@links) {unless (/^.+:.+$/) {push (@links_final,$_);} } $number_of_jobs--; return (scalar @links_final); } sub query_mysql { my $mysql_handle=DBI->connect("dbi:mysql:shadowbot;localhost","shadowbot","********"); my $table=shift; my $data=shift; my $field_number=shift; my @results; my $query; $data=$mysql_handle->quote($data); if ($table eq 'users') { $query="SELECT * FROM $table WHERE user_name=$data"; } my $query_handle=$mysql_handle->prepare($query); print "Executing query $query\n"; $query_handle->execute; $query_handle->bind_columns(\$user_name,\$user_time,\$user_level); while ($query_handle->fetch) { push(@results,{1=>$user_name,2=>$user_time,3=>$user_level}); } $query_handle->finish; my $result=$results[0]->{$field_number}; return $result; } sub add_mysql { my $mysql_handle=DBI->connect("dbi:mysql:shadowbot;localhost","shadowbot","********"); my $table=shift; my $type=shift; if ($type eq 'single') { my $value=shift; $value=$mysql_handle->quote($value); my $query="INSERT INTO $table VALUES ($value)"; my $query_handle=$mysql_handle->prepare($query); print "Executing query $query\n"; $query_handle->execute; $query_handle->finish; } elsif ($type eq 'multiple') { my $user_name=shift; my $user_time=shift; my $user_level=shift; $user_name=$mysql_handle->quote($user_name); my $query="INSERT INTO $table VALUES ($user_name,$user_time,$user_level)"; my $query_handle=$mysql_handle->prepare($query); print "Executing query $query\n"; $query_handle->execute; $query_handle->finish; } } sub update_mysql { my $mysql_handle=DBI->connect("dbi:mysql:shadowbot;localhost","shadowbot","******"); my $table=shift; my ($user_name,$user_time,$user_level)=@_; $user_name=$mysql_handle->quote($user_name); my $query="UPDATE $table SET user_time=$user_time,user_level='$user_level' WHERE user_name=$user_name"; my $query_handle=$mysql_handle->prepare($query); print "Executing query $query\n"; $query_handle->execute; $query_handle->finish; } sub check_mysql { my $mysql_handle=DBI->connect("dbi:mysql:shadowbot;localhost","shadowbot","*******"); my $table=shift; my $value=shift; my $query="SELECT * FROM $table WHERE "; if ($table eq 'authorized_bots') { $query.="bot_name="; } elsif ($table eq 'trusted_users') { $query.="user_cloak="; } elsif ($table eq 'blacklist' || $table eq 'quarantine' || $table eq 'overrides' || $table eq 'rules_stats') { $query.="rule="; } elsif ($table eq 'users') { $query.="user_name="; } $value=$mysql_handle->quote($value); $query.="$value"; my $query_handle=$mysql_handle->prepare($query); print "Executing query $query.\n"; $query_handle->execute; my $result=0; if ($query_handle->rows > 0) { $result=1; } return $result; } sub delete_mysql { my $mysql_handle=DBI->connect("dbi:mysql:shadowbot;localhost","shadowbot","*******"); my $table=shift; my $value=shift; $value=$mysql_handle->quote($value); my $query="DELETE FROM $table WHERE "; if ($table eq 'authorized_bots') { $query.="bot_name="; } elsif ($table eq 'trusted_users') { $query.="user_cloak="; } elsif ($table eq 'blacklist' || $table eq 'quarantine') { $query.="rule="; } elsif ($table eq 'users') { $query.="user_name="; } $query.="$value"; my $query_handle=$mysql_handle->prepare($query); print "Executing query $query\n"; $query_handle->execute; $query_handle->finish; } sub set_override { my $rule=shift; my $option=shift; my $mysql_handle=DBI->connect("dbi:mysql:shadowbot;localhost","shadowbot","*******"); $rule=$mysql_handle->quote($rule); my $query; if ($option==1) { $query="INSERT INTO overrides VALUES($rule)"; } else {$query="DELETE FROM overrides WHERE rule=$rule";} my $query_handle=$mysql_handle->prepare($query); print "Executing query $query\n"; $query_handle->execute; $query_handle->finish; } sub update_rules_stats { my @rules=shift; my $mysql_handle=DBI->connect("dbi:mysql:shadowbot;localhost","shadowbot","******"); foreach $rule (@rules) { my $query; my $exists=check_mysql("rules_stats",$rule); $rule=$mysql_handle->quote($rule); if (!$exists) { $query="INSERT INTO rules_stats VALUES($rule,1)"; } elsif ($exists) { $query="UPDATE rules_stats SET count=count + 1 WHERE rule=$rule"; } my $query_handle=$mysql_handle->prepare($query); print "Executing query $query\n"; $query_handle->execute; $query_handle->finish; } } sub logit { my $message = shift; my $mysql_handle=DBI->connect("dbi:mysql:shadowbot;localhost","shadowbot","*******"); $message=$mysql_handle->quote($message); my $query="INSERT INTO log VALUES(DEFAULT,$message)"; my $query_handle=$mysql_handle->prepare($query); $query_handle->execute; $query_handle->finish; }

