User:SinBot~enwiktionary/code

Resources This is the code for SinBot. and this is the code that shall be followed in order for SinBot to execute its actions nicely. Any questions go on my talk page. Thank you. Uses If the code was written correctly, then the following shall be SinBots duties:   thats about it. If my bot does anyhing else, let me know. Request I am currently still waiting for this bot to be accepted, then i shall paste the code onto here.
 * 1) Cleaning up vandalism at the click of a button
 * 2) Warning me of pages that were deleted
 * 3) Warning me of blanked pages

wikibot.classes.php  <?PHP class http { private $ch; private $uid; public $postfollowredirs; public $getfollowredirs;

function data_encode ($data, $keyprefix = "", $keypostfix = "") { assert( is_array($data) ); $vars=null; foreach($data as $key=>$value) { if(is_array($value)) $vars .= $this->data_encode($value, $keyprefix.$key.$keypostfix.urlencode("["), urlencode("]")); else $vars .= $keyprefix.$key.$keypostfix."=".urlencode($value)."&"; }                       return $vars; }

function __construct { $this->ch = curl_init; $this->uid = dechex(rand(0,99999999)); curl_setopt($this->ch,CURLOPT_COOKIEJAR,'/tmp/cluewikibot.cookies.'.$this->uid.'.dat'); curl_setopt($this->ch,CURLOPT_COOKIEFILE,'/tmp/cluewikibot.cookies.'.$this->uid.'.dat'); curl_setopt($this->ch,CURLOPT_MAXCONNECTS,100); curl_setopt($this->ch,CURLOPT_CLOSEPOLICY,CURLCLOSEPOLICY_LEAST_RECENTLY_USED); $this->postfollowredirs = 0; $this->getfollowredirs = 1; }

function post ($url,$data) { //                     echo 'POST: '.$url."\n"; $time = microtime(1); curl_setopt($this->ch,CURLOPT_URL,$url); curl_setopt($this->ch,CURLOPT_FOLLOWLOCATION,$this->postfollowredirs); curl_setopt($this->ch,CURLOPT_MAXREDIRS,10); curl_setopt($this->ch,CURLOPT_HEADER,0); curl_setopt($this->ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($this->ch,CURLOPT_TIMEOUT,30); curl_setopt($this->ch,CURLOPT_CONNECTTIMEOUT,10); curl_setopt($this->ch,CURLOPT_POST,1); //                     curl_setopt($this->ch,CURLOPT_POSTFIELDS, substr($this->data_encode($data), 0, -1) ); curl_setopt($this->ch,CURLOPT_POSTFIELDS, $data); $data = curl_exec($this->ch); //var_dump($data); echo 'POST: '.$url.' ('.(microtime(1) - $time).' s) ('.strlen($data)." b)\n"; return $data; }

function get ($url) { //echo 'GET: '.$url."\n"; $time = microtime(1); curl_setopt($this->ch,CURLOPT_URL,$url); curl_setopt($this->ch,CURLOPT_FOLLOWLOCATION,$this->getfollowredirs); curl_setopt($this->ch,CURLOPT_MAXREDIRS,10); curl_setopt($this->ch,CURLOPT_HEADER,0); curl_setopt($this->ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($this->ch,CURLOPT_TIMEOUT,30); curl_setopt($this->ch,CURLOPT_CONNECTTIMEOUT,10); curl_setopt($this->ch,CURLOPT_HTTPGET,1); $data = curl_exec($this->ch); //var_dump($data); echo 'GET: '.$url.' ('.(microtime(1) - $time).' s) ('.strlen($data)." b)\n"; return $data; }

function __destruct { curl_close($this->ch); @unlink('/tmp/cluewikibot.cookies.'.$this->uid.'.dat'); }       }

class wiktionaryquery { private $http; public $queryurl = 'http://en.wiktionary.org/w/query.php';

function __construct { global $__wp__http; if (!isset($__wp__http)) { $__wp__http = new http; }                       $this->http = &$__wp__http; }               function getpage ($page) { $ret = unserialize($this->http->get($this->queryurl.'?what=content&format=php&titles='.urlencode($page))); foreach ($ret['pages'] as $page) { return $page['content']['*']; }               }

function getpageid ($page) { $ret = unserialize($this->http->get($this->queryurl.'?what=content&format=php&titles='.urlencode($page))); foreach ($ret['pages'] as $page) { return $page['id']; }               }

function contribcount ($user) { $ret = unserialize($this->http->get($this->queryurl.'?what=contribcounter&format=php&titles=User:'.urlencode($user))); foreach ($ret['pages'] as $page) { return $page['contribcounter']['count']; }               }        }

class wiktionaryapi { private $http; public $apiurl = 'http://en.wiktionary.org/w/api.php';

function __construct { global $__wp__http; if (!isset($__wp__http)) { $__wp__http = new http; }                       $this->http = &$__wp__http; }

function login ($user,$pass) { $this->http->post($this->apiurl.'?action=login',array('lgname' => $user, 'lgpassword' => $pass)); }

function getedittoken { $x = $this->http->get($this->apiurl.'?action=query&format=php&prop=info&intoken=edit&titles=Main%20Page'); $x = unserialize($x); foreach ($x['query']['pages'] as $y) { return $y['edittoken']; }               }

function recentchanges ($count = 10,$namespace = null,$dir = 'older',$ts = null) { $append = ''; if ($ts !== null) { $append .= '&rcstart='.urlencode($ts); } $append .= '&rcdir='.urlencode($dir); if ($namespace !== null) { $append .= '&rcnamespace='.urlencode($namespace); } $x = $this->http->get($this->apiurl.'?action=query&list=recentchanges&rcprop=user|comment|flags|timestamp|title|ids|sizes&format=php&rclimit='.$count.$append); $x = unserialize($x); return $x['query']['recentchanges']; }

function search ($search,$limit = 10,$offset = 0,$namespace = 0,$what = 'text',$redirs = false) { $append = ''; if ($limit != null) $append .= '&srlimit='.urlencode($limit); if ($offset != null) $append .= '&sroffset='.urlencode($offset); if ($namespace != null) $append .= '&srnamespace='.urlencode($namespace); if ($what != null) $append .= '&srwhat='.urlencode($what); if ($redirs == true) $append .= '&srredirects=1'; else $append .= '&srredirects=0'; $x = $this->http->get($this->apiurl.'?action=query&list=search&format=php&srsearch='.urlencode($search).$append); $x = unserialize($x); return $x['query']['search']; }

function logs ($user = null,$title = null,$limit = 50,$type = null,$start = null,$end = null,$dir = 'older') { $append = ''; if ($user != null) $append.= '&leuser='.urlencode($user); if ($title != null) $append.= '&letitle='.urlencode($title); if ($limit != null) $append.= '&lelimit='.urlencode($limit); if ($type != null) $append.= '&letype='.urlencode($type); if ($start != null) $append.= '&lestart='.urlencode($start); if ($end != null) $append.= '&leend='.urlencode($end); if ($dir != null) $append.= '&ledir='.urlencode($dir); $x = $this->http->get($this->apiurl.'?action=query&format=php&list=logevents&leprop=ids|title|type|user|timestamp|comment|details'.$append); $x = unserialize($x); return $x['query']['logevents']; }

function usercontribs ($user,$count = 50,&$continue = null,$dir = 'older') { if ($continue != null) { $append = '&ucstart='.urlencode($continue); } else { $append = ''; }                       $x = $this->http->get($this->apiurl.'?action=query&format=php&list=usercontribs&ucuser='.urlencode($user).'&uclimit='.urlencode($count).'&ucdir='.urlencode($dir).$append); $x = unserialize($x); $continue = $x['query-continue']['usercontribs']['ucstart']; return $x['query']['usercontribs']; }

function revisions ($page,$count = 1,$dir = 'older',$content = false,$revid = null,$wait = true,$getrbtok = false,$dieonerror = true,$redirects = false) { $x = $this->http->get($this->apiurl.'?action=query&prop=revisions&titles='.urlencode($page).'&rvlimit='.urlencode($count).'&rvprop=timestamp|ids|user|comment'.(($content)?'|content':).'&format=php&meta=userinfo&rvdir='.urlencode($dir).(($revid !== null)?'&rvstartid='.urlencode($revid):).(($getrbtok == true)?'&rvtoken=rollback':).(($redirects == true)?'&redirects':)); $x = unserialize($x); if ($revid !== null) { $found = false; if (!isset($x['query']['pages']) or !is_array($x['query']['pages'])) { if ($dieonerror == true) die('No such page.'."\n"); else return false; }                               foreach ($x['query']['pages'] as $data) { if (!isset($data['revisions']) or !is_array($data['revisions'])) { if ($dieonerror == true) die('No such page.'."\n"); else return false; }                                       foreach ($data['revisions'] as $data2) if ($data2['revid'] == $revid) $found = true; unset($data,$data2); break; }

if ($found == false) { if ($wait == true) { sleep(1); return $this->revisions($page,$count,$dir,$content,$revid,false,$getrbtok,$dieonerror); } else { if ($dieonerror == true) die('Revision error.'."\n"); }                               }                        }                        foreach ($x['query']['pages'] as $data) { $data['revisions']['ns'] = $data['ns']; $data['revisions']['title'] = $data['title']; $data['revisions']['currentuser'] = $x['query']['userinfo']['name']; //                             $data['revisions']['currentuser'] = $x['query']['userinfo']['currentuser']['name']; $data['revisions']['continue'] = $x['query-continue']['revisions']['rvstartid']; return $data['revisions']; }               }

function users ($start = null,$limit = 1,$group = null,$reqirestart = false,&$continue = null) { $append = ''; if ($start != null) $append .= '&aufrom='.urlencode($start); if ($group != null) $append .= '&augroup='.urlencode($group); $x = $this->http->get($this->apiurl.'?action=query&list=allusers&format=php&auprop=blockinfo|editcount|registration|groups&aulimit='.urlencode($limit).$append); $x = unserialize($x); $continue = $x['query-continue']['allusers']['aufrom']; if (($requirestart == true) and ($x['query']['allusers'][0]['name'] != $start)) return false; return $x['query']['allusers']; }

function categorymembers ($category,$count = 500,&$continue = null) { if ($continue != null) { $append = '&cmcontinue='.urlencode($continue); } else { $append = ''; }                       $category = 'Category:'.str_ireplace('category:','',$category); $x = $this->http->get($this->apiurl.'?action=query&list=categorymembers&cmtitle='.urlencode($category).'&format=php&cmlimit='.$count.$append); $x = unserialize($x); $continue = $x['query-continue']['categorymembers']['cmcontinue']; return $x['query']['categorymembers']; }

function listcategories (&$start = null,$limit = 50,$dir = 'ascending',$prefix = null) { $append = ''; if ($start != null) $append .= '&acfrom='.urlencode($start); if ($limit != null) $append .= '&aclimit='.urlencode($limit); if ($dir != null) $append .= '&acdir='.urlencode($dir); if ($prefix != null) $append .= '&acprefix='.urlencode($prefix);

$x = $this->http->get($this->apiurl.'?action=query&list=allcategories&acprop=size&format=php'.$append); $x = unserialize($x);

$start = $x['query-continue']['allcategories']['acfrom'];

return $x['query']['allcategories']; }

function backlinks ($page,$count = 500,&$continue = null,$filter = null) { if ($continue != null) { $append = '&blcontinue='.urlencode($continue); } else { $append = ''; }                       if ($filter != null) { $append .= '&blfilterredir='.urlencode($filter); }

$x = $this->http->get($this->apiurl.'?action=query&list=backlinks&bltitle='.urlencode($page).'&format=php&bllimit='.$count.$append); $x = unserialize($x); $continue = $x['query-continue']['backlinks']['blcontinue']; return $x['query']['backlinks']; }

function embeddedin ($page,$count = 500,&$continue = null) { if ($continue != null) { $append = '&eicontinue='.urlencode($continue); } else { $append = ''; }                       $x = $this->http->get($this->apiurl.'?action=query&list=embeddedin&eititle='.urlencode($page).'&format=php&eilimit='.$count.$append); $x = unserialize($x); $continue = $x['query-continue']['embeddedin']['eicontinue']; return $x['query']['embeddedin']; }

function listprefix ($prefix,$namespace = 0,$count = 500,&$continue = null) { $append = '&apnamespace='.urlencode($namespace); if ($continue != null) { $append .= '&apfrom='.urlencode($continue); }                       $x = $this->http->get($this->apiurl.'?action=query&list=allpages&apprefix='.urlencode($prefix).'&format=php&aplimit='.$count.$append); $x = unserialize($x); $continue = $x['query-continue']['allpages']['apfrom']; return $x['query']['allpages']; }       }

class wiktionaryindex { private $http; public $indexurl = 'http://en.wiktionary.org/w/index.php'; private $postinterval = 0; private $lastpost; private $edittoken;

function __construct { global $__wp__http; if (!isset($__wp__http)) { $__wp__http = new http; }                       $this->http = &$__wp__http; }

function post ($page,$data,$summery = '',$minor = false,$rv = null,$bot = true) { global $user; global $maxlag; global $irc; global $irctechchannel; global $run; global $maxlagkeepgoing;

$wpq = new wiktionaryquery; $wpq->queryurl = str_replace('index.php','query.php',$this->indexurl); $wpapi = new wiktionaryapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl);

if ((!$this->edittoken) or ($this->edittoken == '')) $this->edittoken = $wpapi->getedittoken; if ($rv == null) $rv = $wpapi->revisions($page,1,'older',true); if (!$rv[0]['*']) $rv[0]['*'] = $wpq->getpage($page);

//Fake the edit form. $now = gmdate('YmdHis', time); $token = htmlspecialchars($this->edittoken); $tmp = date_parse($rv[0]['timestamp']); $edittime = gmdate('YmdHis', gmmktime($tmp['hour'],$tmp['minute'],$tmp['second'],$tmp['month'],$tmp['day'],$tmp['year'])); $html = "\n"; $html.= "\n"; $html.= "\n"; $html.= ''."\n";

if (preg_match('/'.preg_quote('','/').'/iS',$rv[0]['*'])) { return false; }          /* Honor the bots flags */ if (preg_match('/'.preg_quote('','/').'/iS',$rv[0]['*'])) { return false; } if (preg_match('/'.preg_quote('','/').'/iS',$rv[0]['*'])) { return false; } if (preg_match('/'.preg_quote('','/').'/iS',$rv[0]['*'],$m)) { if (in_array(explode(',',$m[1]),$user)) { return false; } } /* /Honor the bots flags */ if (!preg_match('/'.preg_quote($user,'/').'/iS',$rv['currentuser'])) { return false; } /* We need to be logged in */ //                     if (preg_match('/'.preg_quote('You have new messages','/').'/iS',$rv[0]['*'])) { return false; } /* Check talk page */ if (!preg_match('/(yes|enable|true)/iS',((isset($run))?$run:$wpq->getpage('User:'.$user.'/Run')))) { return false; } /* Check /Run page */

$x = $this->forcepost($page,$data,$summery,$minor,$html,$maxlag,$maxlagkeepgoing,$bot); /* Go ahead and post. */                       $this->lastpost = time; return $x; }

function forcepost ($page,$data,$summery = '',$minor = false,$edithtml = null,$maxlag = null,$mlkg = null,$bot = true) { $post['wpSection'] = ''; $post['wpScrolltop'] = ''; if ($minor == true) { $post['wpMinoredit'] = 1; } $post['wpTextbox1'] = $data; $post['wpSummary'] = $summery; if ($edithtml == null) { $html = $this->http->get($this->indexurl.'?title='.urlencode($page).'&action=edit'); } else { $html = $edithtml; }                       preg_match('|\|U',$html,$m); $post['wpStarttime'] = $m[1]; preg_match('|\|U',$html,$m); $post['wpEdittime'] = $m[1]; preg_match('|\|U',$html,$m); $post['wpEditToken'] = $m[1]; preg_match('|\|U',$html,$m); $post['wpAutoSummary'] = $m[1]; if ($maxlag != null) { $x = $this->http->post($this->indexurl.'?title='.urlencode($page).'&action=submit&maxlag='.urlencode($maxlag).'&bot='.(($bot == true)?'1':'0'),$post); if (preg_match('/Waiting for ([^ ]*): ([0-9.-]+) seconds lagged/S',$x,$lagged)) { global $irc; if (is_resource($irc)) { global $irctechchannel; foreach(explode(',',$irctechchannel) as $y) { fwrite($irc,'PRIVMSG '.$y.' :'.$lagged[1].' is lagged out by '.$lagged[2].' seconds. ('.$lagged[0].')'."\n"); }                                       }                                        sleep(10); if ($mlkg != true) { return false; } else { $x = $this->http->post($this->indexurl.'?title='.urlencode($page).'&action=submit&bot='.(($bot == true)?'1':'0'),$post); } }                               return $x; } else { return $this->http->post($this->indexurl.'?title='.urlencode($page).'&action=submit&bot='.(($bot == true)?'1':'0'),$post); }               }

function diff ($title,$oldid,$id,$wait = true) { $deleted = ''; $added = '';

$html = $this->http->get($this->indexurl.'?title='.urlencode($title).'&action=render&diff='.urlencode($id).'&oldid='.urlencode($oldid).'&diffonly=1');

if (preg_match_all('/\&amp\;(oldid\=|undo=)(\d*)\\\'\>(Revision as of|undo)/USs', $html, $m, PREG_SET_ORDER)) { //print_r($m); if ((($oldid != $m[0][2]) and (is_numeric($oldid))) or (($id != $m[1][2]) and (is_numeric($id)))) { if ($wait == true) { sleep(1); return $this->diff($title,$oldid,$id,false); } else { die('Revision error.'."\n"); }                               }                        }                        if (preg_match_all('/\\(.*)\<\/div\>\<\/td\>/USs', $html, $m, PREG_SET_ORDER)) {                                //print_r($m);                                foreach ($m as $x) {                                        $added .= htmlspecialchars_decode(strip_tags($x[2]))."\n";                                }                        }

if (preg_match_all('/\\(.*)\<\/div\>\<\/td\>/USs', $html, $m, PREG_SET_ORDER)) {                               //print_r($m);                                foreach ($m as $x) {                                        $deleted .= htmlspecialchars_decode(strip_tags($x[2]))."\n";                                }                        }

//echo $added."\n".$deleted."\n";

if (preg_match('/action\=rollback\&amp\;from\=.*\&amp\;token\=(.*)\"/US', $html, $m)) {                               $rbtoken = urldecode($rbtoken);                                return array($added,$deleted,$rbtoken);                        }

return array($added,$deleted); }

function rollback ($title,$user,$reason = null,$token = null,$bot = true) { if (($token == null) or (!$token)) { $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl); $token = $wpapi->revisions($title,1,'older',false,null,true,true); if ($token[0]['user'] == $user) { $token = $token[0]['rollbacktoken']; } else { return false; }                       }                        $x = $this->http->get($this->indexurl.'?title='.urlencode($title).'&action=rollback&from='.urlencode($user).'&token='.urlencode($token).(($reason != null)?'&summary='.urlencode($reason):'').'&bot='.(($bot == true)?'1':'0')); if (!preg_match('/action complete/iS',$x)) return false; return $x; }

function move ($old,$new,$reason) { $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl); if ((!$this->edittoken) or ($this->edittoken == '')) $this->edittoken = $wpapi->getedittoken;

$token = htmlspecialchars($this->edittoken);

$post = array (                                       'wtOldTitle'    => $old,                                        'wtNewTitle'    => $new,                                        'wtReason'      => $reason,                                        'wtWatch'       => '0',                                        'wtEditToken'   => $token,                                        'wtMove'        => 'Move page'                                ); return $this->http->post($this->indexurl.'?title=Special:Movepage&action=submit',$post); }

function upload ($page,$file,$desc) { $post = array (                                       'wtUploadFile'          => '@'.$file,                                        'wtSourceType'          => 'file',                                        'wtDestFile'            => $page,                                        'wtUploadDescription'   => $desc,                                        'wtLicense'             => '',                                        'wtWatchthis'           => '0',                                        'wtIgnoreWarning'       => '1',                                        'wtUpload'              => 'Upload file'                                ); return $this->http->post($this->indexurl.'?title=Special:Upload&action=submit',$post); }

function hasemail ($user) { $tmp = $this->http->get($this->indexurl.'?title=Special:EmailUser&target='.urlencode($user)); if (stripos($tmp,"No e-mail address") !== false) return false; return true; }               function email ($user,$subject,$body) { $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl); if ((!$this->edittoken) or ($this->edittoken == '')) $this->edittoken = $wpapi->getedittoken;

$post = array (                                       'wtSubject'     => $subject,                                        'wtText'        => $body,                                        'wtCCMe'        => 0,                                        'wtSend'        => 'Send',                                        'wtEditToken'   => $this->edittoken                                );

return $this->http->post($this->indexurl.'?title=Special:EmailUser&target='.urlencode($user).'&action=submit',$post); }       } ?>

[edit] Diff function (diff.function.php) <?PHP function diff ($old,$new,$nret = true,$inline = false) { //             if ($inline) { //                     return str_replace(array("\n",chr(92).chr(92),'\n'),array(' ',chr(92),"\n"),diff(implode("\n",explode(' ',str_replace(array(chr(92),"\n"),array(chr(92).chr(92),'\n'),$old))),implode("\n",explode(' ',str_replace(array(chr(92),"\n"),array(chr(92).chr(92),'\n'),$new))),$nret,false)); //             }                $file1 = tempnam('/tmp','diff_'); $file2 = tempnam('/tmp','diff_'); file_put_contents($file1,$old); file_put_contents($file2,$new); $out = array; if ($inline) { //                     echo 'EXEC: wdiff -3'.(($nret)?'1':'2').' '.escapeshellarg($file1).' '.escapeshellarg($file2)."\n"; @exec('wdiff -3'.(($nret)?'1':'2').' '.escapeshellarg($file1).' '.escapeshellarg($file2),$out); foreach ($out as $key => $line) { if ($line == '======================================================================') unset($out[$key]); elseif ($nret) $out[$key] = '> '.$line; else $out[$key] = '< '.$line; }               } else { @exec('diff -d --suppress-common-lines '.escapeshellarg($file1).' '.escapeshellarg($file2),$out); }               $out2 = array; foreach ($out as $line) { if (                               ( ($nret) and (preg_match('/^\> .*$/',$line)) )                               or ( (!$nret) and (preg_match('/^\< .*$/',$line)) )                       ) {                                $out2[] = substr($line,2); }               }                $out = $out2; unset($out2); unlink($file1); unlink($file2); return implode("\n",$out); } ?> 

diff.function.php

<tt> <?PHP function diff ($old,$new,$nret = true,$inline = false) { //             if ($inline) { //                     return str_replace(array("\n",chr(92).chr(92),'\n'),array(' ',chr(92),"\n"),diff(implode("\n",explode(' ',str_replace(array(chr(92),"\n"),array(chr(92).chr(92),'\n'),$old))),implode("\n",explode(' ',str_replace(array(chr(92),"\n"),array(chr(92).chr(92),'\n'),$new))),$nret,false)); //             }                $file1 = tempnam('/tmp','diff_'); $file2 = tempnam('/tmp','diff_'); file_put_contents($file1,$old); file_put_contents($file2,$new); $out = array; if ($inline) { //                     echo 'EXEC: wdiff -3'.(($nret)?'1':'2').' '.escapeshellarg($file1).' '.escapeshellarg($file2)."\n"; @exec('wdiff -3'.(($nret)?'1':'2').' '.escapeshellarg($file1).' '.escapeshellarg($file2),$out); foreach ($out as $key => $line) { if ($line == '======================================================================') unset($out[$key]); elseif ($nret) $out[$key] = '> '.$line; else $out[$key] = '< '.$line; }               } else { @exec('diff -d --suppress-common-lines '.escapeshellarg($file1).' '.escapeshellarg($file2),$out); }               $out2 = array; foreach ($out as $line) { if (                               ( ($nret) and (preg_match('/^\> .*$/',$line)) )                               or ( (!$nret) and (preg_match('/^\< .*$/',$line)) )                       ) {                                $out2[] = substr($line,2); }               }                $out = $out2; unset($out2); unlink($file1); unlink($file2); return implode("\n",$out); } ?>

</tt>

Source to SinBot

<tt> <?PHP declare(ticks = 1);

function sig_handler($signo) { switch ($signo) { case SIGCHLD: while (($x = pcntl_waitpid(0, $status, WNOHANG)) != -1) { if ($x == 0) break; $status = pcntl_wexitstatus($status); }                               break; }       }

pcntl_signal(SIGCHLD,  "sig_handler");

function score ($list,$data,&$matches = null) { $ret = 0; foreach ($list as $preg => $pts) { if ($x = preg_match_all($preg.'S',$data,$m)) { //                             echo $x.'*'.$pts.' ('.$preg.')'."\n"; $matches[$preg] = $x; $ret += $pts * $x; }               } //              echo 'Score: '.$ret."\n"; return $ret; }

include '../diff.function.php'; /* The diff function. */       include '../wikibot.classes.php'; /* The wiktionary classes. */       include 'cluebot.config.php'; /* This file is very simple, but it contains sensitive information, we just define $user, $ircserver, $ircport, $ircchannel, $pass, $owner, and $status. */       include 'cluebot.scorelist.php'; /* This file is uploaded as well as the main file. */

$wpapi = new wiktionaryapi; $wpq   = new wiktionaryquery; $wpi   = new wiktionaryindex; $wpapi->login($user,$pass);

$mysql = mysql_pconnect($mysqlhost.':'.$mysqlport,$mysqluser,$mysqlpass); if (!$mysql) { die('Could not connect: ' . mysql_error); } if (!mysql_select_db($mysqldb, $mysql)) { die ('Can\'t use database : ' . mysql_error); }

$ircconfig = explode("\n",$wpq->getpage('User:'.$owner.'/CBChannels.js')); $tmp = array; foreach($ircconfig as $tmpline) { if (substr($tmpline,0,1) != '#') { $tmpline = explode('=',$tmpline,2); $tmp[trim($tmpline[0])] = trim($tmpline[1]); } }

$ircchannel = $tmp['ircchannel']; $ircdebugchannel = $tmp['ircdebugchannel']; $ircreportchannel = $tmp['ircreportchannel']; $ircvandalismchannel = $tmp['ircvandalismchannel']; $ircaivchannel = $tmp['ircaivchannel']; $irctechchannel = $tmp['irctechchannel']; $ircproxychannels = $tmp['ircproxychannels']; $ircunrevertedchannels = $tmp['ircunrevertedchannels']; $ircbagtrialchannels = $tmp['ircbagtrialchannels']; $ircotherchannels = $tmp['ircotherchannels'];

unset($tmp,$tmpline);

$stalkbots = array; $trialbots = explode("\n",$wpq->getpage('Wiktionary:Bots/Requests for approval')); foreach ($trialbots as $trialbot) if (preg_match('/\{\{BRFA\|(.*)\|.*\|Trial\}\}/',str_replace(array("\n","\r"),'',$trialbot),$m)) $stalkbots[$m[1]] = 1;

$irc = fsockopen($ircserver,$ircport,$ircerrno,$ircerrstr,15); $ircpid = pcntl_fork; if ($ircpid == 0) { fwrite($irc,'PASS '.$ircpass."\n"); fwrite($irc,'USER '.$user.' "1" "1" :Sinbot Wiktionary Bot.'."\n"); fwrite($irc,'NICK '.$user."\n"); while (!feof($irc)) { $data = str_replace(array("\n","\r"),'',fgets($irc,1024)); //                     echo 'IRC: '.$data."\n"; $d = explode(' ',$data); if (strtolower($d[0]) == 'ping') { fwrite($irc,'PONG '.$d[1]."\n"); } elseif (($d[1] == '376') or ($d[1] == '422')) { //                             fwrite($irc,'PRIVMSG NickServ :identify '.$pass."\n"); //                             sleep(2); fwrite($irc,'JOIN '.$ircchannel.','.$ircdebugchannel.','.$ircreportchannel.','.$ircvandalismchannel.','.$ircaivchannel.','.$irctechchannel.','.$ircproxychannels.','.$ircunrevertedchannels.','.$ircbagtrialchannels.','.$ircotherchannels."\n"); foreach (explode(',',$ircchannel) as $y) { fwrite($irc,'PRIVMSG '.$y.' :IRC logging enabled.'."\n"); }                       } elseif (strtolower($d[1]) == 'privmsg') { if (substr($d[3],0,2) == ':!') { if (strtolower($d[2]) == '#wiktionary-en') { $tmp = explode('!',substr($d[0],1)); $cmd = 'NOTICE '.$tmp[0]; } elseif (strtolower($d[2]) == strtolower($user)) { $tmp = explode('!',substr($d[0],1)); $cmd = 'NOTICE '.$tmp[0]; } else { $cmd = 'PRIVMSG '.$d[2]; } switch (substr(strtolower($d[3]),2)) { case 'edit': if (preg_match("/\[\[(.*)\]\]/",$data,$m)) { $rv = $wpapi->revisions($m[1],1,'older'); fwrite($irc,$cmd.' :'.$m[1].' http://en.wikipedia.org/w/index.php?title='.urlencode($m[1]).'&diff=prev' .                                                                       '&oldid='.urlencode($rv[0]['revid']).' * '.$rv[0]['user'].' * '.$rv[0]['comment']."\n"); } else { fwrite($irc,$cmd.' :Couldn\'t find link.'."\n"); }                                                       break; case 'stalk': if (preg_match("/\[\[User:(.*)\]\]/",$data,$m)) { $uc = $wpapi->usercontribs($m[1],1); fwrite($irc,$cmd.' :'.$uc[0]['title'].' http://en.wikipedia.org/w/index.php?title='.urlencode($uc[0]['title']).'&diff=prev' .                                                                       '&oldid='.urlencode($uc[0]['revid']).' * '.$m[1].' * '.$uc[0]['comment']."\n"); } else { fwrite($irc,$cmd.' :Couldn\'t find link.'."\n"); }                                                       break; case 'beaten': if (preg_match("/\[\[User:(.*)\]\]/",$data,$m)) { if (!mysql_ping($mysql)) { $mysql = mysql_pconnect($mysqlhost.':'.$mysqlport,$mysqluser,$mysqlpass); mysql_select_db($mysqldb, $mysql); } $x = mysql_fetch_assoc(mysql_query('SELECT COUNT(`id`) AS `count` FROM `beaten` WHERE `user` = \''.mysql_real_escape_string($m[1]).'\' GROUP BY `user`')); $y = mysql_fetch_assoc(mysql_query('SELECT SQL_CALC_FOUND_ROWS COUNT(`id`) AS `count2` FROM `beaten` GROUP BY `user` HAVING `count2` > \''.mysql_real_escape_string($x['count']).'\' LIMIT 1')); $z = mysql_fetch_assoc(mysql_query('SELECT FOUND_ROWS as `ahead`')); fwrite($irc,$cmd.' :User:'.$m[1].' has beaten me '.(($x['count'] != '')?$x['count']:'0').' times. There are '.$z['ahead'].' users who have beaten me more times.'."\n"); unset($x,$y); } else { fwrite($irc,$cmd.' :Couldn\'t find link.'."\n"); }                                                       break; case 'vandalcount': if (preg_match("/\[\[(.*)\]\]/",$data,$m)) { $tmp = unserialize(file_get_contents('oftenvandalized.txt')); if (isset($tmp[$m[1]])) { fwrite($irc,$cmd.' :'.$m[1].' has been vandalized '.count($tmp[$m[1]]).' time(s) in the last 48 hours.'."\n"); } else { fwrite($irc,$cmd.' :'.$m[1].' has not been vandalized in the last 48 hours.'."\n"); }                                                       } else { fwrite($irc,$cmd.' :Couldn\'t find link.'."\n"); }                                                       break; case 'heuristics': include 'cluebot.heuristics.config.php'; $stats = unserialize(file_get_contents('cluebot.heuristics.stats.txt')); fwrite($irc,$cmd.' :I have the following heuristics enabled: '.implode(', ',$heuristics).".\n"); foreach ($stats as $heuristic => $count) { fwrite($irc,$cmd.' :The '.$heuristic.' heuristic has been matched '.$count.' times.'."\n"); }                                                       unset($count,$heuristic,$stats,$heuristics); break; case 'status': $ov = unserialize(file_get_contents('oftenvandalized.txt')); foreach ($ov as $title => $array) { if (count($array) == 0) unset($ov[$title]); }                                                       file_put_contents('oftenvandalized.txt',serialize($ov)); $count = count($ov);

$titles = unserialize(file_get_contents('titles.txt')); foreach ($titles as $title => $time) { if ((time - $time) > (24*60*60)) { unset($titles[$title]); }                                                       }                                                        file_put_contents('titles.txt',serialize($titles)); $tcount = count($titles);

foreach ($ov as $x => $y) { $ocount[$x] = count($y); }                                                       arsort($ocount); foreach ($ocount as $x => $y) { $mova = $x; $movacount = $y; break; }

preg_match('/\(\'\'\'\[\[([^|]*)\|more...\]\]\'\'\'\)/iU',$wpq->getpage('Wikipedia:Today\'s featured article/'.date('F j, Y')),$tfa); $tfa = $tfa[1]; if (!preg_match('/(yes|enable|true)/i',$wpq->getpage('User:'.$user.'/Run'))) { $run = false; } else { $run = true; }

$top5beat = array;

if (!mysql_ping($mysql)) { $mysql = mysql_pconnect($mysqlhost.':'.$mysqlport,$mysqluser,$mysqlpass); mysql_select_db($mysqldb, $mysql); } $q = mysql_query('SELECT `user`,COUNT(`id`) AS `count` FROM `cluebot_enwiki`.`beaten` WHERE `user` != \'\' GROUP BY `user` HAVING `count` > 1 ORDER BY `count` DESC LIMIT 5'); while ($x = mysql_fetch_assoc($q)) { $top5beat[] = $x['user'].' ('.$x['count'].')'; }                                                       unset($x,$q); $top5beat = implode(' - ',$top5beat);

fwrite($irc,$cmd.' :I am '.$user.'. I am currently '.($run?'enabled':'disabled').'.  I currently have '.$wpq->contribcount($user).' contributions.'."\n");

fwrite($irc,$cmd.' :I have attempted to revert '.$tcount.' unique article/user combinations in the last 24 hours. ' .                                                                'I know of '.$count.' different articles that have been vandalized in the last 48 hours.'."\n"                                                                );

fwrite($irc,$cmd.' :'.$mova.' is the most vandalized page with a total of '.$movacount.' vandalisms in the last 48 hours. ' .                                                                'Today\'s featured article is: '.$tfa.'.'."\n"                                                                );

fwrite($irc,$cmd.' :The following users have beat me to the revert the most: '.$top5beat."\n");

fwrite($irc,$cmd.' :I log all information to '.$ircchannel.'. This channel is '.$d[2].'.'."\n");

unset($x,$y,$count,$ov,$tcount,$ocount,$mova,$movacount,$tfa,$run,$title,$titles,$time,$top5beat); break; case 'warninglevel': if (preg_match("/\[\[User:(.*)\]\]/",$data,$n)) { $warning = 0; if (preg_match_all('/.*(\d{2}):(\d{2}), (\d+) ([a-zA-Z]+) (\d{4}) \(UTC\)/iU', $wpq->getpage('User talk:'.$n[1]), $match,PREG_SET_ORDER)                                                               ) { foreach ($match as $m) { $month = array('January' => 1, 'February' => 2, 'March' => 3,                                                                                       'April' => 4, 'May' => 5, 'June' => 6, 'July' => 7,                                                                                        'August' => 8, 'September' => 9, 'October' => 10,                                                                                        'November' => 11, 'December' => 12                                                                                ); if ($m[1] == 'Blatantvandal (serious warning)') $m[2] = 4; if ((time - gmmktime($m[4],$m[5],0,$month[$m[7]],$m[6],$m[8])) <= (2*24*60*60)) { if ($m[2] > $warning) { $warning = $m[2]; } }                                                                       }                                                                }                                                                fwrite($irc,$cmd.' :User:'.$n[1].' is at warning level '.$warning.".\n"); } else { fwrite($irc,$cmd.' :Couldn\'t find link.'."\n"); }                                                       break; case 'count': if (preg_match("/\[\[User:(.*)\]\]/",$data,$n)) { fwrite($irc,$cmd.' :User:'.$n[1].' has '.$wpq->contribcount($n[1])." contributions.\n"); } else { fwrite($irc,$cmd.' :Couldn\'t find link.'."\n"); }                                                       break; case 'help': fwrite($irc,$cmd.' :Please see User:'.$user.'.'."\n"); break; case 'eval': $tmp = explode(' ',$data,6); $tmp1 = explode('!',substr($d[0],1)); if ($d[4] == md5($thesecret.$tmp1[0].$tmp[5])) { eval($tmp[5]); } else { fwrite($irc,$cmd.' :Code incorrect.'."\n"); }                                                       break; case 'cbproxy': $tmp = explode(' ',$data,6); $tmp1 = explode('!',substr($d[0],1)); if ($tmp1[0] == 'ClueBot-Bopm') { foreach (explode(',',$ircproxychannels) as $y) { fwrite($irc,'PRIVMSG '.$y.' :!admin '.$tmp[5]."\n"); }                                                               $data = $wpq->getpage('Wikipedia:WikiProject on open proxies'); if (strpos($data,$tmp[4]) === false) { $header = explode(' || Example',$data,2); $header[0] .= ' || Example '; $footer = $header[1]; $header = $header[0]; $data = "\n".' || '.$tmp[5].' ~'."\n"; $data = $header.$data.$footer; unset($header,$footer); $wpi->post('Wikipedia:WikiProject on open proxies',$data,'Adding '.$tmp[4].'.'); unset($data); }                                                       }                                                        break; }                               }                        }                }                die; }

$heuristics = "==Heuristics==\n\n===Config (cluebot.heuristics.config.php)===\n\n ".htmlentities(file_get_contents('cluebot.heuristics.config.php'))." \n\n"; foreach (glob('heuristics/cluebot.*.heuristic.php') as $heuristic) $heuristics .= '==='.$heuristic."===\n\n ".htmlentities(file_get_contents($heuristic))." \n\n"; unset($heuristic);

$wpi->forcepost('User:'.$user.'/Source',               'The following is automatically generated by '.$user.".\n\n\n\n==Classes (wikibot.classes.php)==\n\n " .                htmlentities(file_get_contents('../wikibot.classes.php'))." \n\n\n\n==Diff function (diff.function.php)==\n\n " .                htmlentities(file_get_contents('../diff.function.php'))." \n\n\n\n==Source to ".$user .                "==\n\n".' '.htmlentities(file_get_contents(__FILE__))." \n\n\n\n" .                $heuristics .                "==Score list==\n\n".' '.htmlentities(file_get_contents('cluebot.scorelist.php'))." \n\n\n\n<em style="font-family:Andalus;color:black">The7 <em style="font-family:Andalus;color:red">DeadlySins  02:55, 2 July 2008 (UTC)",                'Automated source upload.'); /* Our source code, we force post this because this is *our* page, and it triggers the nobots. */

unset($heuristics);

$wpi->forcepost('User:'.$user,               "\n",                'Automated bot userpage set.'); /* Our page, we force post this because this is *our* page. */

$tfas = 0; $pipe = fopen('thepipe','w'); $stdin = fopen('php://stdin','r'); $run = $wpq->getpage('User:'.$user.'/Run'); $wl = $wpq->getpage('User:'.$user.'/Whitelist'); $optin = $wpq->getpage('User:'.$user.'/Optin'); $aoptin = $wpq->getpage('User:'.$user.'/AngryOptin');

unset($tmp,$tmp2,$tmp3);

$tmp = explode("\n",$wpq->getpage('User:'.$owner.'/CBAutostalk.js')); foreach ($tmp as $tmp2) { if (substr($tmp2,0,1) != '#') { $tmp3 = explode('|',$tmp2,2); $stalk[$tmp3[0]] = trim($tmp3[1]); } } $tmp = explode("\n",$wpq->getpage('User:'.$owner.'/CBAutoedit.js')); foreach ($tmp as $tmp2) { if (substr($tmp2,0,1) != '#') { $tmp3 = explode('|',$tmp2,2); $edit[$tmp3[0]] = trim($tmp3[1]); } } unset($tmp,$tmp2,$tmp3);

print_r($stalk); print_r($edit);

while (1) { $feed = fsockopen($feedhost,$feedport,$feederrno,$feederrstr,30);

if (!$feed) { sleep(10); $feed = fsockopen($feedhost,$feedport,$feederrno,$feederrstr,30); if (!$feed) die($feederrstr.' ('.$feederrno.')'); }

fwrite($feed,'USER '.$user.' "1" "1" :SinBot Wiktionary Bot.'."\n"); fwrite($feed,'NICK '.$user."\n");

while (!feof($feed)) { $rawline = fgets($feed,1024); $line = str_replace(array("\n","\r","\002"),'',$rawline); $line = preg_replace('/\003(\d\d?(,\d\d?)?)?/','',$line); //                     echo 'FEED: '.$line."\n"; if (!$line) { fclose($feed); break; } $linea= explode(' ',$line,4);

if (strtolower($linea[0]) == 'ping') { fwrite($feed,'PONG '.$linea[1]."\n"); } elseif (($linea[1] == '376') or ($linea[1] == '422')) { fwrite($feed,'JOIN '.$feedchannel."\n"); } elseif ((strtolower($linea[1]) == 'privmsg') and (strtolower($linea[2]) == strtolower($feedchannel))) { $message = substr($linea[3],1); if (preg_match('/^\[\[((Talk|User|Wikipedia|Image|MediaWiki|Template|Help|Category|Portal|Special)(( |_)talk)?:)?([^\x5d]*)\]\] (\S*) (http:\/\/en\.wiktionary\.org\/w\/index\.php\?title=[^&]*&diff=(\d*)&oldid=(\d*)|http:\/\/en\.wikipedia\.org\/wiki\/\S+)? \* ([^*]*) \* (\(([^)]*)\))? (.*)$/S',$message,$m)) {                                       $messagereceived = microtime(1);                                        $change['namespace'] = $m[1];                                        $change['title'] = $m[5];                                        $change['flags'] = $m[6];                                        $change['url'] = $m[7];                                        $change['revid'] = $m[8];                                        $change['old_revid'] = $m[9];                                        $change['user'] = $m[10];                                        $change['length'] = $m[12];                                        $change['comment'] = $m[13];

//                                     include 'cluebot.stalk.config.php';

$stalkchannel = array; foreach ($stalk as $key => $value) if (fnmatch(str_replace('_',' ',$key),str_replace('_',' ',$change['user']))) $stalkchannel = array_merge($stalkchannel,explode(',',$value)); foreach ($stalkbots as $key => $value) if (fnmatch(str_replace('_',' ',$key),str_replace('_',' ',$change['user']))) $stalkchannel = array_merge($stalkchannel,explode(',',$ircbagtrialchannels)); foreach ($edit as $key => $value) if (fnmatch(str_replace('_',' ',$key),str_replace('_',' ',$change['namespace'].$change['title']))) $stalkchannel = array_merge($stalkchannel,explode(',',$value)); //                                     if ($change['user'] == $owner) $stalkchannel[] = $ircchannel;

$stalkchannel = array_unique($stalkchannel);

foreach ($stalkchannel as $y) { fwrite($irc,'PRIVMSG '.$y.' :New edit: '.$change['namespace'].$change['title'].' http://en.wikipedia.org/w/index.php?title=' .                                                       urlencode($change['namespace'].$change['title']).'&diff=prev'.'&oldid='.urlencode($change['revid']).' * '.$change['user'] .                                                        ' * '.$change['comment']."\n"); }                                       if (($change['namespace'] == 'User:') or ($change['namespace'] == 'User talk:')) { if (strtolower($change['title']) == strtolower($user.'/Run')) { $run = $wpq->getpage('User:'.$user.'/Run'); } if (strtolower($change['title']) == strtolower($user.'/Whitelist')) { $wl = $wpq->getpage('User:'.$user.'/Whitelist'); } if (strtolower($change['title']) == strtolower($user.'/Optin')) { $optin = $wpq->getpage('User:'.$user.'/Optin'); } if (strtolower($change['title']) == strtolower($user.'/AngryOptin')) { $aoptin = $wpq->getpage('User:'.$user.'/AngryOptin'); } if (strtolower($change['title']) == strtolower($owner.'/CBAutostalk.js')) { unset($stalk); $tmp = explode("\n",$wpq->getpage('User:'.$owner.'/CBAutostalk.js')); foreach ($tmp as $tmp2) { if (substr($tmp2,0,1) != '#') { $tmp3 = explode('|',$tmp2,2); $stalk[$tmp3[0]] = trim($tmp3[1]); } } unset($tmp,$tmp2,$tmp3); print_r($stalk); }                                               if (strtolower($change['title']) == strtolower($owner.'/CBAutoedit.js')) { unset($edit); $tmp = explode("\n",$wpq->getpage('User:'.$owner.'/CBAutoedit.js')); foreach ($tmp as $tmp2) { if (substr($tmp2,0,1) != '#') { $tmp3 = explode('|',$tmp2,2); $edit[$tmp3[0]] = trim($tmp3[1]); } } unset($tmp,$tmp2,$tmp3); print_r($edit); }                                               if (strtolower($change['title']) == strtolower($owner.'/CBChannels.js')) { $ircconfig = explode("\n",$wpq->getpage('User:'.$owner.'/CBChannels.js')); $tmp = array; foreach($ircconfig as $tmpline) { if (substr($tmpline,0,1) != '#') { $tmpline = explode('=',$tmpline,2); $tmp[trim($tmpline[0])] = trim($tmpline[1]); } } print_r($tmp);

$tmpold = array; $tmpnew = array; foreach ($tmp as $tmp2) foreach (explode(',',$tmp2) as $tmp3) $tmpnew[$tmp3] = 1; foreach (explode(',',$ircchannel.','.$ircdebugchannel.','.$ircreportchannel.','.$ircvandalismchannel.','.$ircaivchannel.','.$irctechchannel.','.$ircproxychannels.','.$ircunrevertedchannels.','.$ircbagtrialchannels.','.$ircotherchannels) as $tmp3) $tmpold[$tmp3] = 1;

foreach ($tmpold as $tmp2 => $tmp3) if (isset($tmpnew[$tmp2])) unset($tmpold[$tmp2],$tmpnew[$tmp2]); foreach ($tmpnew as $tmp2 => $tmp3) $tmpnew1[] = $tmp2; foreach ($tmpold as $tmp2 => $tmp3) $tmpold1[] = $tmp2;

$tmpold = $tmpold1; $tmpnew = $tmpnew1; unset($tmpold1,$tmpnew1);

fwrite($irc,'JOIN '.implode(',',$tmpnew)."\n"); fwrite($irc,'PART '.implode(',',$tmpold)."\n");

$ircchannel = $tmp['ircchannel']; $ircdebugchannel = $tmp['ircdebugchannel']; $ircreportchannel = $tmp['ircreportchannel']; $ircvandalismchannel = $tmp['ircvandalismchannel']; $ircaivchannel = $tmp['ircaivchannel']; $irctechchannel = $tmp['irctechchannel']; $ircproxychannels = $tmp['ircproxychannels']; $ircunrevertedchannels = $tmp['ircunrevertedchannels']; $ircbagtrialchannels = $tmp['ircbagtrialchannels']; $ircotherchannels = $tmp['ircotherchannels'];

unset($tmp,$tmpline,$tmpold,$tmpnew,$tmp2,$tmp3); }                                       }                                        if ($change['namespace'].$change['title'] == 'Wiktionary:Bots/Requests for approval') { $stalkbots = array; $trialbots = explode("\n",$wpq->getpage('Wiktionary:Bots/Requests for approval')); foreach ($trialbots as $trialbot) if (preg_match('/\{\{BRFA\|(.*)\|.*\|Trial\}\}/',str_replace(array("\n","\r"),'',$trialbot),$m)) $stalkbots[$m[1]] = 1; }

if (($change['namespace'] != '') and ((!preg_match('/\* \[\[('.preg_quote($change['namespace'].$change['title'],'/').')\]\] \- .*/i',$optin))) and ($change['flags'] != 'move')) continue;

$change['justtitle'] = $change['title']; $change['title'] = $change['namespace'].$change['title'];

if ($change['flags'] == 'move') { if (preg_match('/moved \[\[(.*)\]\] to \[\[(.*)\]\]( over redirect)?: (.*)$/',$change['comment'],$m)) { $change['title'] = $m[1]; $change['newtitle'] = $m[2]; $change['realcomment'] = $change['comment']; $change['comment'] = $m[4]; echo "\n\n\n".'Move!'."\n\n\n"; print_r($change); echo "\n\n\n".'Move!'."\n\n\n"; }                                       }

if (                                               ((time - $tfas) >= 1800)                                                and (preg_match('/\(\'\'\'\[\[([^|]*)\|more...\]\]\'\'\'\)/iU',$wpq->getpage('Wiktionary:Today\'s featured article/'.date('F j, Y')),$tfam))                                        ) { $tfas = time; $tfa = $tfam[1]; //echo "TFA: ".$tfa."\n"; }                                       $s = null; $pid = @pcntl_fork; if ($pid != 0) continue;

$hutime = microtime(1);

include 'cluebot.heuristics.config.php'; foreach ($heuristics as $heuristic) { $heuristicret = false; include 'heuristics/cluebot.'.$heuristic.'.heuristic.php'; if ($heuristicret == true) { $stats = unserialize(file_get_contents('cluebot.heuristics.stats.txt')); $stats[$heuristic]++; print_r($log); file_put_contents('cluebot.heuristics.stats.txt',serialize($stats)); unset($stats); break; }                                       }

if ($heuristicret == true) { echo 'Heuristics time: '.(microtime(1) - $hutime)."\n"; file_put_contents('trainingdata.txt',$change['title']."\0".$change['revid']."\0".'1'."\n",FILE_APPEND); } else { $tmp = explode(' ',$rawline,4); $tmp = $tmp[3]; $udp = fsockopen('udp://localhost',3333); fwrite($udp,substr(str_replace(array("\n","\r"),'',$tmp),1)."\n"); fclose($udp); unset($tmp,$udp); $d = $wpi->diff($change['title'],$change['old_revid'],$change['revid']); $s = score($obscenelist,$d[0],$log); $s -= score($obscenelist,$d[1],$log); if ($s > 15) file_put_contents('trainingdata.txt',$change['title']."\0".$change['revid']."\0".'0'."\n",FILE_APPEND); }                                       unset($hutime);

if (                                               ($heuristicret == true)                                        ) { if (                                                       ( ( /* IP users with 250 contributions are fine .. */                                                                       (long2ip(ip2long($change['user'])) == $change['user'])                                                                        /* and ($uc = $wpapi->usercontribs($change['user'],250))                                                                        and (!isset($uc[249])) */                                                                ) or ( /* Users with 50 contributions are fine .. */                                                                       (long2ip(ip2long($change['user'])) != $change['user'])                                                                        and ($wpq->contribcount($change['user']) < 50)                                                                ) )                                                       and ( /* Whitelisted users are ok. */                                                               /* ($wl = $wpq->getpage('User:'.$user.'/Whitelist')) and */ (!preg_match('/^\* \[\[User:('.preg_quote($change['user'],'/').')|\1\]\] \- .*/',$wl)) )                                               ) { //                                                      $vandalpage = $wpq->getpage('User:'.$user.'/PossibleVandalism'); //                                                     $x = explode("\n\n",$vandalpage); //                                                     foreach ($x as $k => $y) { //                                                             if (preg_match('/(\d+)\-(\d+)\-(\d+)T(\d+):(\d+):(\d+)/',$y,$m)) { //                                                                     if ((time - gmmktime($m[4],$m[5],$m[6],$m[2],$m[3],$m[1])) > (5*60*60)) { //                                                                             unset($x[$k]); //                                                                     } //                                                              } //                                                      } //                                                      $vandalpage = implode("\n\n",$x); $diff = 'http://en.wikipedia.org/w/index.php'. '?title='.urlencode($change['title']). '&diff='.urlencode($change['revid']). '&oldid='.urlencode($change['old_revid']);

$report = ''.$change['title'].' was '. (($change['flags'] != 'move')?'['.$diff.' changed] by ':'moved to '.$change['newtitle'].' by '). ''.$change['user'].' '. '(u) '. '(t) '. $reason.' on '.gmdate('c'); //                                                     $datatopost = $vandalpage."\n\n".'Possible vandalism: '.$report." <em style="font-family:Andalus;color:black">The7 <em style="font-family:Andalus;color:red">DeadlySins  02:55, 2 July 2008 (UTC)\n";

if ($s == null) { //                                                             $rv = $wpapi->revisions($change['title'],2,'older',true,$change['revid']); //                                                             $s = score($scorelist,diff($rv[1]['*'],$rv[0]['*'])); //                                                             $s += (score($scorelist,diff($rv[1]['*'],$rv[0]['*'],false))) * -1; $s = 'N/A'; }

$tmp = unserialize(file_get_contents('oftenvandalized.txt')); foreach ($tmp as $key1 => $tmp2) { foreach ($tmp2 as $key2 => $time) { if ((time - $time) > (2*24*60*60)) { unset($tmp[$key1][$key2]); } }                                                       }                                                        $tmp[$change['title']][] = time; if (count($tmp[$change['title']]) >= 30) { foreach (explode(',',$ircreportchannel) as $y) { fwrite($irc,'PRIVMSG '.$y.' :!admin '.$change['title'].' has been vandalized '.(count($tmp[$change['title']])).' times in the last 2 days.'."\n"); }                                                       }                                                        file_put_contents('oftenvandalized.txt',serialize($tmp));

if (                                                               ( ($rv1 = $wpapi->revisions($change['title'],1,'older')) and ($rv1[0]['revid'] == $change['revid']) )                                                               or ($change['flags'] == 'move')                                                        ) { /* No need to continue further if it has been reverted */ echo 'Possible vandalism: '.$change['title'].' changed by '.$change['user'].' '.$reason.' on '.$rv[0]['timestamp'].'('.$s.").\n"; foreach (explode(',',$ircdebugchannel) as $y) { fwrite($irc,'PRIVMSG '.$y.' :Possible vandalism: '.$change['title'].' changed by '.$change['user'].' '.$reason.' on '.$rv[0]['timestamp'].'('.$s.").\n"); fwrite($irc,'PRIVMSG '.$y.' :( http://en.wikipedia.org/w/index.php?title='.urlencode($change['title']).'&action=history | '.$change['url'].' )'."\n"); }                                                               fwrite($pipe,'http://en.wikipedia.org/w/index.php?title='.urlencode($change['title']).'&action=history'."\n"); /* Tell owner */

$mqtime = microtime(1);

if (is_array($log)) { $logt = ''; foreach ($log as $k => $v) { $logt .= '* '.$v.' * "'.$k.'"'."\n"; }                                                               }

$query = 'INSERT INTO `vandalism` '. '(`id`,`user`,`article`,`heuristic`'.((is_array($log))?',`regex`':'').',`reason`,`diff`,`old_id`,`new_id`,`reverted`) '. 'VALUES '. '(NULL,\.mysql_real_escape_string($change['user']).'\',' .                                                                       '\.mysql_real_escape_string($change['title']).'\',' .                                                                        '\.mysql_real_escape_string($heuristic).'\',' .                                                                        ((is_array($log))?'\.mysql_real_escape_string($logt).'\',':) .                                                                        '\.mysql_real_escape_string($reason).'\',' .                                                                        '\.mysql_real_escape_string($change['url']).'\',' .                                                                        '\.mysql_real_escape_string($change['old_revid']).'\',' .                                                                        '\''.mysql_real_escape_string($change['revid']).'\',0)'; //echo 'Mysql query: '.$query."\n"; if (!mysql_ping($mysql)) { $mysql = mysql_pconnect($mysqlhost.':'.$mysqlport,$mysqluser,$mysqlpass); if (!$mysql) { die('Could not connect: ' . mysql_error); } if (!mysql_select_db($mysqldb, $mysql)) { die ('Can\'t use database : ' . mysql_error); } }                                                               mysql_query($query); //echo 'Mysql error: '.mysql_error."\n"; $mysqlid = mysql_insert_id; echo 'MySQL time: '.(microtime(1) - $mqtime).' MySQL id: '.$mysqlid."\n"; unset($mqtime);

if (                                                                       ( (                                                                                       (preg_match('/(assisted|manual)/iS',$status))                                                                                        and (print('Revert [y/N]? '))                                                                                        and (strtolower(substr(fgets($stdin,3),0,1)) == 'y')                                                                                ) or (                                                                                       (preg_match('/(read-write|rw|go|approved|trial)/iS',$status))                                                                                ) )                                                                       and ( (                                                                                       (                                                                                                ((time - $tfas) < 1800) or (                                                                                                       (preg_match('/\(\'\'\'\[\[([^|]*)\|more...\]\]\'\'\'\)/iU',$wpq->getpage('Wikipedia:Today\'s featured article/'.date('F j, Y')),$tfam))                                                                                                        and ($tfas = time)                                                                                                        and ($tfa = $tfam[1])                                                                                                        and ((print("TFA: ".$tfa."\n")) or (true))                                                                                                ) )                                                                                       and ($tfa == $change['title'])                                                                                ) or (                                                                                       (preg_match('/\* \[\[('.preg_quote($change['title'],'/').')\]\] \- .*/i',$aoptin))                                                                                        and ((fwrite($irc,'PRIVMSG '.$ircdebugchannel.' :Angry-reverting '.$change['title'].'.'."\n")) or (true))                                                                                ) or (                                                                                       (($tmp = unserialize(file_get_contents('titles.txt'))) !== false)                                                                                        and ((!isset($tmp[$change['title'].$change['user']])) or ((time - $tmp[$change['title'].$change['user']]) > (24*60*60)))                                                                                        and ($tmp[$change['title'].$change['user']] = time)                                                                                        and ((file_put_contents('titles.txt',serialize($tmp))) !== false)                                                                                ) )                                                               ) {                                                                        echo 'Reverting ...'."\n"; if ($change['flags'] != 'move') { $rev = $wpapi->revisions($change['title'],5,'older',false,null,true,true); $revid = 0; $rbtok = $rev[0]['rollbacktoken']; foreach ($rev as $revdata) { if ($revdata['user'] != $change['user']) { $revid = $revdata['revid']; break; }                                                                               }                                                                                if (($revdata['user'] == $user) or (in_array($revdata['user'],explode(',',$botfriends)))) { die; /* Do not revert to us. */ }                                                                       } //                                                                      if ($revid == 0) { die; } foreach (explode(',',$ircdebugchannel) as $y) { fwrite($irc,'PRIVMSG '.$y.' :Reverting ...'."\n"); } //                                                                     $revisiondata = $wpapi->revisions($change['title'],1,'older',true,$revid); //                                                                     if (!$revisiondata[0]['*']) die; //                                                                     if (!$rv1[0]['*']) $rv1[0]['*'] = $rv[0]['*']; //                                                                     $wpi->post( //                                                                              $change['title'], //                                                                              $revisiondata[0]['*'], //                                                                              'Reverting possible vandalism by '.$change['user'].' ' . //                                                                              'to version by '.$revisiondata[0]['user'].'. ' . //                                                                              'False positive? Report it. '. //                                                                              'Thanks, '.$user.'. ('.$mysqlid.') (Bot)', //                                                                              false, //                                                                             $rv1 //                                                                     ); /* Revert the page */                                                                        if ($change['flags'] != 'move') {                                                                                $rbret = $wpi->rollback( $change['title'], $change['user'], 'Reverting possible vandalism by '.$change['user'].' '. 'to '.(($revid == 0)?'older version':'version by '.$revdata['user']).'. ' .                                                                                       'False positive? Report it. '.                                                                                       'Thanks, User:'.$user.'. ('.$mysqlid.') (Bot)', $rbtok, false );                                                                       } else {                                                                                $rbret = $wpi->move( $change['newtitle'], $change['title'], 'Reverting possible vandalism by '.$change['user'].' '. 'to '.(($revid == 0)?'older version':'version by '.$revdata['user']).'. ' .                                                                                       'False positive? Report it. '.                                                                                       'Thanks, User:'.$user.'. ('.$mysqlid.') (Bot)' );                                                                       } // //                                                                      $rv2 = $wpapi->revisions($change['title'],1); //                                                                      if ($rv2[0]['user'] == $user) {                                                                        if ($rbret !== false) {                                                                                foreach (explode(',',$ircdebugchannel) as $y) {                                                                                        fwrite($irc,'PRIVMSG '.$y.' :Reverted. ('.(microtime(1) - $messagereceived).' s)'."\n");                                                                               }                                                                                $warning = 0;                                                                                $tpcontent = $wpq->getpage('User talk:'.$change['user']);                                                                                if (preg_match_all('/.*(\d{2}):(\d{2}), (\d+) ([a-zA-Z]+) (\d{4}) \(UTC\)/iU',                                                                                        $tpcontent,                                                                                        $match,PREG_SET_ORDER) ) {                                                                                       foreach ($match as $m) {                                                                                                $month = array('January' => 1, 'February' => 2, 'March' => 3, 'April' => 4, 'May' => 5, 'June' => 6, 'July' => 7, 'August' => 8, 'September' => 9, 'October' => 10, 'November' => 11, 'December' => 12 );                                                                                               if ($m[1] == 'Blatantvandal (serious warning)') $m[2] = 4;                                                                                                if ((time - gmmktime($m[4],$m[5],0,$month[$m[7]],$m[6],$m[8])) <= (2*24*60*60)) {                                                                                                        if ($m[2] > $warning) { $warning = $m[2]; }                                                                                                }                                                                                        }                                                                                }                                                                                $warning++; if ($warning == 5) { /* Report them if they have been warned 4 times. */                                                                                       $aivdata = $wpq->getpage('User talk:Iamthe7DeadlySins'); if (!preg_match('/'.preg_quote($change['user'],'/').'/i',$aivdata)) { foreach(explode(',',$ircaivchannel) as $y) { fwrite($irc,'PRIVMSG '.$y.' :!admin Reporting User:'.$change['user'].' to WP:AIV. Contributions: Special:Contributions/'.$change['user'].' Block: Special:Blockip/'.$change['user'].''."\n"); }                                                                                               foreach (explode(',',$ircvandalismchannel) as $y) { fwrite($irc,'PRIVMSG '.$y.' :computer bl add '.$change['user'].' x='.(24*$warning).' r=Vandalism to '.$change['title'].' (#'.$warning.").\n"); }                                                                                               $wpi->post(                                                                                                        'Wikipedia:Administrator_intervention_against_vandalism/TB2',                                                                                                        $aivdata .                                                                                                        "\n\n* ' .                                                                                                        ' - '.$report." (Automated) <em style="font-family:Andalus;color:black">The7 <em style="font-family:Andalus;color:red">DeadlySins  02:55, 2 July 2008 (UTC)\n", 'Automatically reporting Special:Contributions/'.$change['user'].'. (bot)', false, null, false );                                                                                       } else {                                                                                                foreach (explode(',',$ircreportchannel) as $y) {                                                                                                        fwrite($irc,'PRIVMSG '.$y.' :!admin User:'.$change['user'].' has vandalized at least one time while being listed on WP:AIV. Contributions: Special:Contributions/'.$change['user'].' Block: Special:Blockip/'.$change['user'].''."\n");                                                                                               }                                                                                        }                                                                                } elseif ($warning < 5) { /* Warn them if they haven't been warned 4 times. */                                                                                        foreach (explode(',',$ircvandalismchannel) as $y) {                                                                                                fwrite($irc,'PRIVMSG '.$y.' :computer bl add '.$change['user'].' x='.(24*$warning).' r=Vandalism to '.$change['title'].' (#'.$warning.').'."\n");                                                                                        } $wpi->post(                                                                                               'User talk:'.$change['user'],                                                                                                $tpcontent."\n\n" .                                                                                                ''.$warning.' <em style="font-family:Andalus;color:black">The7 <em style="font-family:Andalus;color:red">DeadlySins  02:55, 2 July 2008 (UTC)'."\n",                                                                                                'Warning '.$change['user'].' - #'.$warning,                                                                                                false, null, false ); /* Warn the user */                                                                               } else { /* They have already been reported ... do nothing */

}                                                                               if (!mysql_ping($mysql)) { $mysql = mysql_pconnect($mysqlhost.':'.$mysqlport,$mysqluser,$mysqlpass); if (!$mysql) { die('Could not connect: ' . mysql_error); } if (!mysql_select_db($mysqldb, $mysql)) { die ('Can\'t use database : ' . mysql_error); } }                                                                               mysql_query('UPDATE `vandalism` SET `reverted` = 1 WHERE `id` = \.mysql_real_escape_string($mysqlid).'\); } else { $rv2 = $wpapi->revisions($change['title'],1); if ($change['user'] != $rv2[0]['user']) { echo 'Grr! Beaten by '.$rv2[0]['user'].".\n"; foreach(explode(',',$ircdebugchannel) as $y) { fwrite($irc,'PRIVMSG '.$y.' :Grr! Beaten by '.$rv2[0]['user'].".\n"); }                                                                                       if (!mysql_ping($mysql)) { $mysql = mysql_pconnect($mysqlhost.':'.$mysqlport,$mysqluser,$mysqlpass); mysql_select_db($mysqldb, $mysql); } mysql_query('INSERT INTO `beaten` (`id`,`article`,`diff`,`user`) VALUES (NULL,\.mysql_real_escape_string($change['title']).'\',\.mysql_real_escape_string($change['url']).'\',\''.mysql_real_escape_string($rv2[0]['user']).'\')'); }                                                                       }                                                                } else { foreach (explode(',',$ircunrevertedchannels) as $y) { fwrite($irc,'PRIVMSG '.$y.' :'."\002\00304Possible ignored vandalism: \002\003\00312".$change['title']."\003\00304 changed by \003\00312User:".$change['user']."\003 \00303".$reason."\00304 on \00307".$rv[0]['timestamp']."\003(\002\00313".$s."\003).\n"); fwrite($irc,'PRIVMSG '.$y.' :'."\002(\002\00312 http://en.wikipedia.org/w/index.php?title=".urlencode($change['title'])."&action=history \003\002|\002\00312 ".$change['url']." \003\002)\002"."\n"); }                                                               }

} else { $rev = $wpapi->revisions($change['title'],1); $rev = $rev[0];

echo 'Possible corrected vandalism: '.$change['title'].' changed by '.$change['user'].' '.$reason.'('.$s.")\n\tReverted by ".$rev['user']." before I saw it.\n"; foreach (explode(',',$ircdebugchannel) as $y) { fwrite($irc,'PRIVMSG '.$y.' :Possible corrected vandalism: '.$change['title'].' changed by '.$change['user'].' '.$reason.'('.$s.")\n"); fwrite($irc,'PRIVMSG '.$y.' :Reverted by '.$rev['user']." before I saw it.\n"); }                                                               if (($rev['user'] != $user) and ($rev['user'] != $change['user'])) { if (!mysql_ping($mysql)) { $mysql = mysql_pconnect($mysqlhost.':'.$mysqlport,$mysqluser,$mysqlpass); mysql_select_db($mysqldb, $mysql); } mysql_query('INSERT INTO `beaten` (`id`,`article`,`diff`,`user`) VALUES (NULL,\.mysql_real_escape_string($change['title']).'\',\.mysql_real_escape_string($change['url']).'\',\''.mysql_real_escape_string($rev['user']).'\')'); }                                                       }                                                }                                        }                                        die; }                       }                }        } ?>

</tt>

Heuristics

<tt> <?PHP $heuristics[] = 'grawp'; $heuristics[] = 'evolution'; $heuristics[] = 'pagereplace'; $heuristics[] = 'pageblank'; $heuristics[] = 'massdelete'; $heuristics[] = 'massadd'; $heuristics[] = 'smallchange'; $heuristics[] = 'claimjumperpete'; $heuristics[] = 'redirect'; ?> </tt>

Config (sinbot.heuristics.config.php)

<tt> <?PHP $heuristics[] = 'grawp'; $heuristics[] = 'evolution'; $heuristics[] = 'pagereplace'; $heuristics[] = 'pageblank'; $heuristics[] = 'massdelete'; $heuristics[] = 'massadd'; $heuristics[] = 'smallchange'; $heuristics[] = 'claimjumperpete'; $heuristics[] = 'redirect'; ?> </tt>

heuristics/sinbot.claimjumperpete.heuristic.php

<tt> <?PHP if ( /* The ClaimJumperPete vandal */               (($change['length'] >= 100) and ($change['length'] <= 400))                and ( ($change['length'] <= 200) or ($d = $wpi->diff($change['title'],$change['old_revid'],$change['revid'])) )               and ( (fnmatch("*",trim(strtolower($d[0])))) or (fnmatch("*",trim(strtolower($d[0])))) or (fnmatch("*",trim(strtolower($d[0])))) )               and ($reason = 'ClaimJumperPete?')        ) { $heuristicret = true; fwrite($irc,'PRIVMSG #cvn-wp-en :!admin ClaimJumperPete vandal? http://en.wikipedia.org/w/index.php?title='.urlencode($change['title']).'&diff=prev'.'&oldid='.urlencode($change['revid'])." .\n");

} ?> </tt>

heuristics/sinbot.grawp.heuristic.php <tt>

<?PHP if ( /* The Grawp vandal */               ( (fnmatch('*epic*lulz*on*nimp*org*',strtolower($change['comment']))) or (fnmatch('*on*nimp*org*epic*lulz*',strtolower($change['comment']))) or (fnmatch('*punishing*wikipedia*',strtolower($change['comment']))) or (fnmatch('*anti*avril*hate*campaign*',strtolower($change['comment']))) or (fnmatch('*hagger*',strtolower($change['comment']))) or (fnmatch('*h?a?g?g?e?r*',strtolower($change['comment']))) )               and ($reason = 'Grawp?')        ) { $heuristicret = true; fwrite($irc,'PRIVMSG #cvn-wp-en :!admin Grawp vandal? http://en.wikipedia.org/wiki/Special:Contributions/'.$change['user']." .\n"); } ?> </tt> heuristics/sinbot.massadd.heuristic.php

<tt>

<?PHP if ( /* Massive additions */               ($change['length'] >= 7500)                and ($rv = $wpapi->revisions($change['title'],2,'older',true,$change['revid']))                and ($pagedata = $wpq->getpage($change['title']))                and ($s = score($scorelist,$rv[0]['*']))                and ($s += (score($scorelist,$rv[1]['*'])) * -1)                and ($s < -1000)                and ($reason = 'score equals '.$s)        ) $heuristicret = true; ?>

</tt.

heuristics/sinbot.massdelete.heuristic.php <tt>

<?PHP if ( /* Massive deletes */               ($change['length'] <= -7500)                and ($pagedata = $wpq->getpage($change['title']))                and (!fnmatch('*#REDIRECT*',strtoupper(substr($pagedata,0,9))))                and ($rv = $wpapi->revisions($change['title'],2,'older',true,$change['revid']))                and ($s = score($scorelist,$rv[0]['*']))                and ($s += (score($scorelist,$rv[1]['*'])) * -1)                and ($s < -50) /* There are times when massive deletes are ok. */                and ($reason = 'deleting '.($change['length'] * -1).' characters')        ) $heuristicret = true; ?> </tt>

heuristics/sinbot.pageblank.heuristic.php

<tt>

<?PHP if ( /* Page blanks */               (preg_match('/\[\[WP:.*Blanked.*page/',$change['comment'],$m))                and (($pagedata = $wpq->getpage($change['title'])) or true)                and ($fc = $wpapi->revisions($change['title'],1,'newer'))                and ($fc[0]['user'] != $change['user']) /* The creator is allowed to blank the page. */                and ($reason = 'blanking the page')        ) $heuristicret = true; ?> </tt>

heuristics/sinbot.pagereplace.heuristic.php

<tt>

<?PHP if ( /* Page replaces */               (preg_match('/\[\[WP:.*\]\]Replaced page with (.*)$/',$change['comment'],$m))                and ($pagedata = $wpq->getpage($change['title']))                and ($fc = $wpapi->revisions($change['title'],1,'newer'))                and ($fc[0]['user'] != $change['user']) /* The creator is allowed to replace the page. */                and ($reason = 'replacing entire content with something else')        ) $heuristicret = true; ?> </tt>

heuristics/sinbot.redirect.heuristic.php

<tt> <?PHP if ( /* The Redirect vandals */               ( ($tfa == $change['title']) and (fnmatch('*#redirect *',strtolower($wpq->getpage($change['title'])))) and ($reason = 'redirecting featured article to new title') )               or ( ($pagedata = $wpq->getpage($change['title'])) and (fnmatch('*#redirect *',strtolower($pagedata))) and (preg_match('/\[\[(.*)\]\]/',$pagedata,$m)) and (!$wpq->getpage($m[1])) and ($reason = 'redirecting article to non-existant page') )       ) {                $heuristicret = true; //             fwrite($irc,'PRIVMSG #cvn-wp-en :!admin Grawp vandal? http://en.wiktionary.org/wiki/Special:Contributions/'.$change['user']." .\n"); } ?>

</tt>

heuristics/sinbot.smallchange.heuristic.php

<tt>

unset($log,$log2); if ( /* Small changes with obscenities. */               (($change['length'] >= -200) and ($change['length'] <= 200))                and (($d = $wpi->diff($change['title'],$change['old_revid'],$change['revid'])) or true)                and ((($change['title'] == 'User:SinBot/Sandbox') and print_r($rv)) or true)                and (($s = score($obscenelist,$d[0],$log)) or true)                and (($s -= score($obscenelist,$d[1],$log2)) or true)                and ( (                               ($s < -5) /* There are times when small changes are ok. */                                and (($rv = $wpapi->revisions($change['title'],2,'older',true,$change['revid'])) or true)                                and (!fnmatch('*#REDIRECT*',strtoupper(substr($rv[0]['*'],0,9))))                                and (!fnmatch('*SEX*',strtoupper($rv[1]['*'])))                                and (!fnmatch('*BDSM*',strtoupper($rv[1]['*'])))                                and (score($obscenelist,$change['title']) >= 0)                                and (score($obscenelist,$rv[1]['*']) >= 0)                                and (!preg_match('/(^|\s)([a-z]{1,2}(\*+|\-{3,})[a-z]{0,2}|\*{4}|\-{4}|(\<|\?censored(\>|\))?)(ing?|ed)?(\s|$)/iS',$rv[1]['*']))                                and ($heuristic .= '/obscenities')                                and ($reason = 'making a minor change with obscenities') )                       or ( ($s > 5) and (($rv = $wpapi->revisions($change['title'],2,'older',true,$change['revid'])) or true) and (!fnmatch('*#REDIRECT*',strtoupper(substr($rv[0]['*'],0,9)))) and (!preg_match('/(^|\s)([a-z]{1,2}(\*+|\-{3,})[a-z]{0,2}|\*{4}|\-{4}|(\<|\?censored(\>|\))?)(ing?|ed)?(\s|$)/iS',$rv[1]['*'])) and (preg_match('/(^|\s)([a-z]{1,2}(\*+|\-{3,})[a-z]{0,2}|\*{4}|\-{4}|(\<|\?censored(\>|\))?)(ing?|ed)?(\s|$)/iS',$rv[0]['*'])) and ($heuristic .= '/censor') and ($reason = 'making a minor change censoring content (Wiktionary is not censored)') )                       or ( (preg_match('/\!\!\!/S',$d[0])) and (($rv = $wpapi->revisions($change['title'],2,'older',true,$change['revid'])) or true) and (!preg_match('/\!\!\!/S',$rv[1]['*'])) and (!fnmatch('*#REDIRECT*',strtoupper(substr($rv[0]['*'],0,9)))) and ($heuristic .= '/exclamation') and ($reason = 'making a minor change adding "!!!"') )               )        ) { $heuristicret = true; if (isset($log2) and is_array($log2)) foreach ($log2 as $k => $v) $log[$k] -= $v; if (isset($log) and is_array($log)) foreach ($log as $k => $v) if ($v == 0) unset($log[$k]); unset($log2); /* fwrite($irc,'PRIVMSG #wikipedia-BAG/ClueBot :Would revert http://en.wikipedia.org/w/index.php?title='.urlencode($change['namespace'].$change['title']).'&diff=prev'.'&oldid='.urlencode($change['revid'])." .\n"); */ } ?>

[edit] Score list <?PHP /*        * This page contains bad words out of necessity. * Here is 50 lines of whitespace before the actual list: * (scroll down to see the list) *        *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         *         * Here is the list: */       $obscenelist = Array (                       /* 'preg'                               => points, */                        '/suck/i'                               => -5,   /* Usually bad words */                        '/stupid/i'                             => -3,                        '/haha/i'                               => -5,                        '/\bomg/i'                              => -3,                        '/\bpimp\b/i'                           => -7,                        '/1337/i'                               => -5,                        '/leet/i'                               => -5,                        '/dumb/i'                               => -5,                        '/\bputa\b/i'                           => -7,                        '/\bhomo\b/i'                           => -7,                        '/\bGAY\b/'                             => -10,                        '/\bslut/i'                             => -5, '/damn/i'                              => -5, '/\bass\b/i'                           => -10, '/\brape\b/i'                          => -7, '/\bpoop\b/i'                          => -10, '/\bcock\b/i'                          => -10, '/\blol\b/i'                           => -7, '/\bcrap\b/i'                          => -5, '/\bsex\b/i'                           => -5, '/noob/i'                              => -5, '/\bnazi\b/i'                          => -3, '/\bneo-nazi\b/i'                      => +3,   /* False-positive */ '/fuck/i'                              => -20,  /* Stronger bad words */ '/\[\[Fucked\ Up\]\]/'                 => +20,  /* This one is a false positive */ '/bitch/i'                             => -20, '/\bpussy\b/i'                         => -20, '/penis/i'                             => -20, '/vagina/i'                            => -20, '/whore/i'                             => -15, '/\bshit\b/i'                          => -20, '/nigger/i'                            => -20, '/\bnigga\b/i'                         => -20, '/cocksucker/i'                        => -20, '/assrape/i'                           => -15, '/motherfucker/i'                      => -20, '/wanker/i'                            => -20, '/\bcunt\b/i'                          => -20, '/faggot/i'                            => -20, '/fags/i'                              => -20, '/asshole/i'                           => -15, '/fuck ((yo)?u|h(er|im)|them|it)/i'    => -100, /* This looks like a personal attack */ '/((yo)?u|s?he|we|they|it) sucks?/i'   => -100, /* This looks like a personal attack */ '/666+\b/i'                            => -50   /* Though this has uses, it is commonly used by vandals */ );       $grammarlist = Array                ( '/(.{1,4})\1{30}/'                     => -10,  /* Ugg .. the same letter(s) several times in a row. */                       '/\b[A-Z].*[.!?]\b/U'                   => +2,   /* This looks to be a correct sentence */ '/\b[A-Z][^a-z]{30,}\b/U'              => -10,  /* All capitals? Looks like vandal activity */ '/\b[^A-Z]{1500,}\b/U'                 => -10,  /* No capitals? Looks like vandal activity */ '/!{5,}/i'                             => -10,  /* No wikipedia article needs '!!!!!' in it */ '/!!+1+(one)*/i'                       => -30,  /* No wikipedia article needs '!!!11one' in it */ '/\[\[.*\]\]/U'                        => +1,   /* Wiki links are good. */                       '/\{\{.*\}\}/U'                         => +5,   /* Wiki transcludes are good. */                       '/\{\{[iI]nfobox .*\}\}/U'              => +20,  /* Wiki infoboxes are good. */                       '/\[\[Category\:.*\]\]/iU'              => +3    /* Wiki categories are good. */               );        $scorelist = array_merge($obscenelist,$grammarlist); ?> </tt>