Jump to content

User:SoxBot III/Source

From Wikipedia, the free encyclopedia

The following is automatically generated by SoxBot III. It uses ClueBot classes for interacting with the wiki, and also uses some of ClueBot's code for interacting with IRC.

<?PHP
 
/* 
 * SoxBot Anti Testing Bot
 * Copyright (C) 2009 X! (soxred93 _at_ gmail _dot_ com)
 *
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
 	//INCLUDES
	require('/home/soxred93/bots/soxbot-test/wikibot.classes.php');
	require('/home/soxred93/bots/soxbot-test/bot.config.php');
	require('/home/soxred93/bots/soxbot-test/scorelist.php');
	require('/home/soxred93/bots/soxbot-test/functions.php');
 
 
	//DEFINES
	$version = '2.2';
	$pids = array();
	define( 'SIGNATURE', '[[User:SoxBot III|SoxBot III]] ([[User talk:SoxBot III|talk]] | [[User:X!|owner]])' );
	define( 'SCORELIMIT', -10 );
	declare(ticks = 1);
	
	if( $argv[1] == "debug" ) { define( 'DEBUG', 1 ); } else { define( 'DEBUG', '0' ); }
	$http   = new http;
	$wpapi	= new wikipediaapi;
	$wpq	= new wikipediaquery;
	$wpi	= new wikipediaindex;
	$wpapi->login($user,$pass);
 
	$simplewpapi	= new wikipediaapi;
	$simplewpapi->apiurl = 'http://simple.wikipedia.org/w/api.php';
	$simplewpq	= new wikipediaquery;
	$simplewpq->queryurl = 'http://simple.wikipedia.org/w/query.php';
	$simplewpapi->login($user,$pass);
 
	$whitelist = $wpq->getpage('User:'.$user.'/Whitelist');
 
	$trustedusers = array(
		'wikipedia/Juliancolton',
		'wikimedia/PeterSymonds',
		'wikipedia/Soxred93',
		'wikipedia/FastLizard4',
		'wikimedia/Thehelpfulone',
		'wikipedia/Stwalkerster',
	);
	
	$badtemplates = array(
 		'sofixit',
 		'done',
 	);
 	
 	$triggercharacters = array( '!', '@', '~', '.', '#', '$', '%', '^', '&', '*', '?' );
 
	pcntl_signal(SIGINT,   "sig_handler");
	pcntl_signal(SIGCHLD,   "sig_handler");
	pcntl_signal(SIGTERM,   "sig_handler");
 
 
	//PARSE CHANNELS
	$ircconfig = explode("\n",$wpq->getpage('User:'.$owner.'/Channels.js'));
	
	$tmp = array();
	foreach ( $ircconfig as $tmpline ) { 
		if ( substr( $tmpline,0,1 ) != '#' ) { //Ignore comments
			$tmpline = explode( '=',$tmpline,2 ); 
			$tmp[trim( $tmpline[0] )] = trim($tmpline[1]); 
		}
	}
	
	$ircchannel = $tmp['ircchannel'];
	$irctechchannel = $tmp['irctechchannel'];
	$ircverbosechannel = $tmp['ircverbosechannel'];
	$ircotherchannels = $tmp['ircotherchannels'];
	$ircvandalismchannel = $tmp['ircvandalismchannel'];
	$ircaivchannel = $tmp['ircaivchannel'];
	$irclogchannels = $tmp['irclogchannels'];
	$ircwikilinkchannels = $tmp['ircwikilinkchannels'];
	$ircpeakchannels = $tmp['ircpeakchannels'];
	
	$channels = array($ircchannel,$irctechchannel,$ircotherchannels,$ircverbosechannel,$ircvandalismchannel,$ircaivchannel,$irclogchannels,$ircwikilinkchannels,$ircpeakchannels);
	unset($tmp,$tmpline);
	
	//PARSE STALKING
	$stalk = array();
	$edit = array();
	
	//Start with stalking users...
	$tmp = explode("\n",$wpq->getpage('User:'.$user.'/Autostalk.js'));
	foreach ( $tmp as $tmp2 ) { 
		if (substr($tmp2,0,1) != '#') { 
			$tmp3 = explode('|',$tmp2,2); 
			$stalk[$tmp3[0]] = trim($tmp3[1]); 
		} 
	}
	
	//Now with stalking pages...
	$tmp = explode("\n",$wpq->getpage('User:'.$user.'/Autoedit.js'));
	foreach ( $tmp as $tmp2 ) { 
		if (substr($tmp2,0,1) != '#') { 
			$tmp3 = explode('|',$tmp2,2); 
			$edit[$tmp3[0]] = trim($tmp3[1]); 
		} 
	}
	
	//And finish with an unset...
	unset($tmp,$tmp2,$tmp3);
	
	//FILTER
	//We use array_unique and filter here because there are often duplicate entries
	$channels = array_filter(array_unique(array_merge($channels,$stalk,$edit)));
	
	//Now to split out commas in leftover channels
	$c = array();
	foreach( $channels as $chan ) {
		$chan = explode(',',$chan);
		foreach( $chan as $ch ) {
			$c[] = strtolower($ch);
		}
	}
	
	$channels = array_filter(array_unique($c));
	echo implode(', ', $channels);
	
	//DEBUGGING, so it doesn't take 30 seconds when I'm starting and stopping the bot constantly
	if( DEBUG == 1 ) {
		$channels = array( '##juliancolton' );
	}
 

	//CONNECT TO MYSQL
	$enwiki_mysql = mysql_connect( "enwiki-p.db.toolserver.org",$databaseuser,$databasepass,/* Force reconnect --> */ true );
	@mysql_select_db( "enwiki_p", $enwiki_mysql ) or die( "MySQL error: " .mysql_error() );

	$mysql = mysql_connect( "sql:3306",$mysqluser,$mysqlpass );
	@mysql_select_db( $mysqldb, $mysql ) or die( "MySQL error: " .mysql_error() );
 
 
	//CONNECT TO PROXY
	$irc = fsockopen($ircserver,$ircport,$ircerrno,$ircerrstr,15);
 
	//FIRST FORK
	$ircpid = pcntl_fork();
	$pids[$ircpid] = $ircpid;
	
	if ($ircpid == 0) {
 
		//SET CONFIGS
		fwrite( $irc,'PASS '.$ircpass."\n" ); 
		fwrite( $irc,'USER '.$user.' "1" :SoxBot III (version '.$version.')'."\n" ); 
		fwrite( $irc,'NICK '.$user."\n" ); 
 
		//Do we still have the connection?
		while (!feof($irc)) {
		
			//Get the data
			$data = str_replace(array("\n","\r"),'',fgets($irc,1024));
 
			//Strip colors, it screws up the bot
			$data = preg_replace('/'.chr(3).'.{2,}/i','',$data);		
 
			echo 'IRC: '.$data."\n\n";
 
			/*
				Data for a privmsg:
				$d[0] = Nick!User@Host format.
				$d[1] = Action, e.g. "PRIVMSG", "MODE", etc. If it's a message from the server, it's the numerial code
				$d[2] = The channel somethign was spoken in
				$d[3] = The text that was spoken
			*/
			$d = $me = explode(' ',$data);
 
			//Get the plain text of the message
			//Why not use $me[3] here? Because $me[3] is only the text up to the first space
			unset($me[0], $me[1], $me[2]);
			$me = substr(implode(' ', $me),1);
 
			//Get the nick of the user
			$nick = substr($d[0],1);
			$nick = explode( '!', $nick );
			$nick = $nick[0];
 
			//Get the user's cloak
			$cloak = explode('@',$d[0]);
			$cloak = $cloak[1];
			if( !empty($cloak) ) echo "Cloak is $cloak.\n";
			
			//Because there's more than one SoxBot, it reads its own posts, causing endless loops
			if( $cloak == "wikipedia/soxred93/bot/SoxBot" ) continue;
 
			//Easier to recognize variable
			$chan = strtolower($d[2]);
 
			//Playing a game of ping pong with the server
			if (strtolower($d[0]) == 'ping') {
				fwrite( $irc,'PONG '.$d[1]."\n" ); 
			} 
			
			//Time to join the channels
			elseif ( ( $d[1] == '376' ) or ( $d[1] == '422' ) ) {
				foreach ($channels as $joinchan) {
					echo "\n\nJOINING $joinchan...\n\n";
					fwrite( $irc,'JOIN '.$joinchan."\n" ); 
					sleep(1);
				}
				unset( $joinchan );

				foreach (explode(',',$ircchannel) as $y) {
					fwrite( $irc,'PRIVMSG '.$y.' :IRC logging enabled.'."\n" ); 
				}
			}
			
			//Main message parser
			elseif ($d[1] == 'PRIVMSG') {
 
				//Wikilinker function
				if (preg_match_all('/\[\[(.*?)\]\]/', $me, $l) && !preg_match('/(\!shortpath|\!link)/i',$data)) { 
 
					if( !in_arrayi( $chan, explode( ',',$ircwikilinkchannels ) ) ) { 
						echo "Message in $chan is not in a channel I am allowed to wikilink.\n";
						continue; 
					}
 
					$i = 1;
					$links = array(); //Will store the full urls
					foreach($l[1] as $link) {
						if($i >= 5) break;
 
						//Deal with piped links
						if( strpos( $link, '|' ) !== false ) { 
							$link = explode('|', $link);
							$link = $link[0];
						}
 						
 						$link = str_replace('$1',$link,'http://en.wikipedia.org/wiki/$1');//Append url
						$link = str_replace(' ','_',$link);//Prevent encoding spaces
						$link = str_replace(array('[',']'),'',$link);//Remove illegal characters
						$link = urlencode($link);//Urlencode it
						$link = str_replace('%2F','/',$link);//Handle subpages cleanly
						$link = str_replace('%3A',':',$link);//Handle subpages cleanly
						
						$links[] = $link;
						$i++;
					}
					
					$links = implode( ', ', $links);
					
					if( stripos($chan, "##juliancolton") !== false && 1 == 2 ) {//Disabled... 1 is never equal to 2
						fwrite( $irc,'PRIVMSG '.$d[2].' :Yeah, bitches, here\'s the links! '.$links."\n" );
					}
					else {
						fwrite( $irc,'PRIVMSG '.$d[2].' :'.$nick.': '.$links."\n" );
					}
				}
 
				//Template linker function
				if (preg_match_all('/\{\{(.*?)\}\}/', $me, $l) && !preg_match('/(\!shortpath|\!link)/i',$data)) { 
 
					if( !in_arrayi( $chan, explode( ',',$ircwikilinkchannels ) ) ) { 
						echo "Message in $chan is not in a channel I am allowed to templatelink.\n";
						continue; 
					}
 
					$i = 1;
					$links = array(); //Will store the full urls
					foreach($l[1] as $link) {
						if($i >= 5) break;
 
						//Deal with piped links
						if( strpos( $link, '|' ) !== false ) { 
							$link = explode('|', $link);
							$link = $link[0];
						}
 						
 						$link = str_replace('$1',$link,'http://en.wikipedia.org/wiki/Template:$1');//Append url
 						$link = str_replace('subst:', '', $link);//Remove subst
						$link = str_replace(' ','_',$link);//Prevent encoding spaces
						$link = str_replace(array('[',']'),'',$link);//Remove illegal characters
						$link = urlencode($link);//Urlencode it
						$link = str_replace('%2F','/',$link);//Handle subpages cleanly
						$link = str_replace('%3A',':',$link);//Handle subpages cleanly
						
						$links[] = $link;
						$i++;
					}
					
					$links = implode( ', ', $links);
					
					if( stripos($chan, "##juliancolton") !== false && 1 == 2 ) {//Disabled... 1 is never equal to 2
						fwrite( $irc,'PRIVMSG '.$d[2].' :Yeah, bitches, here\'s the links! '.$links."\n" );
					}
					else {
						fwrite( $irc,'PRIVMSG '.$d[2].' :'.$nick.': '.$links."\n" );
					}
				}
 
				//Main function parser
				if ( in_array( substr($me,0,1), $triggercharacters ) ) {
					$command = explode(' ',substr(strtolower($me),1));
					$command = $command[0];
 
					echo "Got a command! The command is: ".$command."\n";
 
					//List of accepted commands
					$commands = array( 
						'lastedit', 
						'stalk', 
						'status', 
						'c',
						'count', 
						'eval', 
						'amsg', 
						/* 'die', */
						/*'restart', */ //die and restart are broken right now
						'maxlag', 
						'replag', 
						'setspeak',
						'speak',
						'soxbotcounts', 
						'cluebotcounts',
						'commands', 
						'version',
						'shortpath',
						'link',
						'h',
						'hits',
						'staff',
						'namesadd',
						'namesdel',
						'rfxupdate',
						'ip2name',
						'name2ip',
						'dns',
						'rdns',
						'rand',
					);
 
					//Don't do anything if the command doesn't even exist
					if( !in_arrayi( $command, $commands ) ) {
						echo "Command not allowed.\n";
						continue;
					}			
 
 					//PRIVMSG command, just a shortcut
					$cmd = 'PRIVMSG '.$chan;
 
					//Get the parameters
					$param = explode(' ', $me);
					unset($param[0]);
					$param = implode(' ', $param);
					$param = trim($param);
 
					echo "Params: $param\n";
 
					//Different functions for different commands
					switch ($command) {
						case 'lastedit':
							if( !$param || $param == '' ) { fwrite( $irc,$cmd.' :Required parameter not given.'."\n" );continue; }
							if (preg_match("/\[\[(.*)\]\]/",$param,$m)) {
								$param = $m[1];
								unset($m);
							}
 
							$rv = $wpapi->revisions($param,1,'older');
							if( $rv[0]['user'] ) {
								fwrite($irc,$cmd.' :'.$r2.' http://en.wikipedia.org/w/index.php?title='.urlencode($r2).'&diff=prev' .
									'&oldid='.urlencode($rv[0]['revid']).' * '.$rv[0]['user'].' * '.$rv[0]['comment']."\n");
							}
							unset($rv);
							break;
						case 'stalk':
							if( !$param || $param == '' ) { fwrite( $irc,$cmd.' :Required parameter not given.'."\n" );continue; }
							if (preg_match("/\[\[User:(.*)\]\]/",$param,$m)) {
								$param = $m[1];
								unset($m);
							}
 
							$uc = $wpapi->usercontribs($param,1);
							if( $uc[0]['title'] ) {
								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']).' * '.$r2.' * '.$uc[0]['comment']."\n");
							}
							break;
						case 'status':
							//Get titles bot has reverted, and remove ones older than 24 hours
							$titles = unserialize(file_get_contents('/home/soxred93/bots/soxbot-test/titles.txt'));
							foreach ($titles as $title => $time) {
								if ((time() - $time) > (24*60*60)) {
									unset($titles[$title]);
								}
							}
							file_put_contents('/home/soxred93/bots/soxbot-test/titles.txt',serialize($titles));
							$count = count($titles);
							unset($titles);
 
							//Is bot enabled?							
							if (!preg_match('/(yes|enable|true)/i',$wpq->getpage('User:'.$user.'/Run'))) {
								$run = false;
							} else {
								$run = true;
							}
 
							fwrite( $irc,$cmd.' :I am '.$user.'.  I am currently '.($run?'enabled':'disabled').'.  I currently have '.$wpq->contribcount($user).' contributions.'."\n" ); sleep(1);
							fwrite( $irc,$cmd.' :I am currently running version '.$version.' of SoxBot Anti-Testing Bot.'."\n" ); sleep(1);
							fwrite( $irc,$cmd.' :I have attempted to revert '.$count.' unique article/user combinations in the last 24 hours. '."\n" ); sleep(1);
							fwrite( $irc,$cmd.' :I have attempted to revert '.($wpq->contribcount($user) - 5341).' edits throughout my lifetime. '."\n" ); sleep(1);
							fwrite( $irc,$cmd.' :I log all information to '.$ircchannel.'.  This channel is '.$chan.".\n" ); 
 
							unset($count,$run,$time);
							break;
						case 'c':
						case 'count':
								
							//Reconnect if it has dropped the connection
							if (!mysql_ping($mysql)) { 
								include_once('/home/soxred93/database.inc');
								$mysql = mysql_connect( "sql:3306","soxred93",$toolserver_password );
								@mysql_select_db( "u_soxred93", $mysql ) or die( "MySQL error: " .mysql_error() );
							}
							
							//Get the aliases of certain users
							$result = mysql_query( "SELECT * FROM names" );
							$contents = array();
							while( $row = mysql_fetch_assoc( $result ) ) {
								$contents[ $row['nick'] ] = $row['user'];
							}
 							
 							//First see if there's no param at all, which implies that they want their own count
							if( !$param || $param == '' ) { 
							
								//Check if it's in the known nicks
								if( isset($contents[$nick])) { 
									$param = $contents[$nick];
								}
								
								//Check if it's a valid user, for users who use their WP name as their nick
								elseif( $wpapi->users($nick) ) {
									$param = $nick;
								}
								
								//Don't know? Ignore.
								else {
									fwrite( $irc,$cmd.' :Required parameter not given. Talk to X! if you want .count to work for your nick.'."\n" );continue; 
								}
							}
							
							//Now see if someone passed a nick as a param
							elseif( isset($contents[$param])) { 
								$param = $contents[$param];
							}
							
							$r3 = urlencode($param);
							$r3 = str_replace('+','_',$r3);
							
							if( $chan == "#wikipedia-simple" ) {
								$count = $simplewpq->contribcount($param);
								$r3 .= "/simple";
								fwrite( $irc,$cmd.' :'.$param.' has '.$count." contributions. For more info, see http://toolserver.org/~soxred93/ec/$r3 \n" ); 
								break;
							}
							
							$param = str_replace('_', ' ', $param);
							
							if (!mysql_ping($enwiki_mysql)) { 
								$enwiki_mysql = mysql_connect("enwiki-p.db.toolserver.org",$databaseuser,$databasepass,/* Force reconnect --> */ true);
								@mysql_select_db("enwiki_p", $enwiki_mysql) or die( "MySQL error: " .mysql_error() );
							}
							
							$query = 'SELECT COUNT(*) AS count FROM archive WHERE ar_user_text = \''.mysql_real_escape_string($param).'\';';
							echo $query;
							$result = mysql_query( $query, $enwiki_mysql );
							var_dump($result);
							$row = mysql_fetch_assoc( $result );
							var_dump($row);
							$edit_count_deleted = $row['count'];
							unset( $row, $query, $result );
							
							if (!mysql_ping($enwiki_mysql)) { 
								$enwiki_mysql = mysql_connect("enwiki-p.db.toolserver.org",$databaseuser,$databasepass,/* Force reconnect --> */ true);
								@mysql_select_db("enwiki_p", $enwiki_mysql) or die( "MySQL error: " .mysql_error() );
							}
							
							$query = 'SELECT COUNT(*) AS count FROM revision WHERE rev_user_text = \''.mysql_real_escape_string($param).'\';';
							echo $query;
							$result = mysql_query( $query, $enwiki_mysql );
							var_dump($result);
							$row = mysql_fetch_assoc( $result );
							var_dump($row);
							$edit_count_live = $row['count'];
							unset( $row, $query, $result );
							
							$edit_count_total = $edit_count_live + $edit_count_deleted;
 							
 							fwrite( $irc,$cmd.' :'.$param.' has '.$edit_count_total." total contributions, $edit_count_live live edits, and $edit_count_deleted deleted edits. For more info, see http://toolserver.org/~soxred93/ec/$r3 \n" ); 
							break;
						case 'soxbotcounts':

							$b = array( 
								'SoxBot',
								'SoxBot II',
								'SoxBot III',
								'SoxBot IV',
								'SoxBot V',
								'SoxBot VI',
								'SoxBot VII',
								'SoxBot VIII',
								'SoxBot IX',
								'SoxBot X',
								'MPUploadBot'
							);
 
							$ms = '';
							$count = 0;
							foreach( $b as $bot ) {
								$count += $wpq->contribcount($bot);
								$ms .= "\002" . $bot . "\002 -> " . $wpq->contribcount($bot) . ". ";
							}
							$ms .= "\002" . 'Total' . "\002 -> " . $count . ". ";
							fwrite( $irc,$cmd.' :'.$ms." \n" ); 
							unset($b, $bots, $bot, $ms);
							break;
						case 'cluebotcounts':

							$b = array( 'ClueBot', 'ClueBot II', 'ClueBot III', 'ClueBot IV', 'ClueBot V', 'ClueBot VI');
 
							$ms = '';
							$count = 0;
							foreach( $b as $bot ) {
								$count += $wpq->contribcount($bot);
								$ms .= "\002" . $bot . "\002 -> " . $wpq->contribcount($bot) . ". ";
							}
							$ms .= "\002" . 'Total' . "\002 -> " . $count . ". ";
							fwrite( $irc,$cmd.' :'.$ms." \n" ); 
							unset($b, $bots, $bot, $ms);
							break;
						case 'maxlag':
							$ml = $wpi->getMaxlag();
							fwrite( $irc,$cmd.' :Current maxlag level: '.$ml[2]." seconds lagged. Server: ".$ml[1].". \n" ); 
							break;
						case 'commands':
							fwrite( $irc,$cmd.' :Allowed commands: '.implode(', ', $commands).". \n" ); 
							break;
						case 'eval':
							if( !$param || $param == '' ) { fwrite( $irc,$cmd.' :Required parameter not given.'."\n" );continue; }
							$code = $param;
							if ($cloak == $ownercloak) {
								$result = eval($code);
								if( $result != '' && !$result ) {
									fwrite( $irc,$cmd.' :Eval result: "'.$result.'"'."\n" ); 
								}
								unset($code,$result);
							} else {
								fwrite( $irc,$cmd.' :eval can only be used by '.$ownercloak.'.'."\n" ); 
							}
							break;
						case 'amsg':
							if( !$param || $param == '' ) { fwrite( $irc,$cmd.' :Required parameter not given.'."\n" );continue; }
							if (in_array($cloak, $trustedusers)) {
								foreach( $channels as $ch ) {
									fwrite( $irc,'PRIVMSG '.$ch.' :Message from '.$nick.': '.$param."\n" );
									sleep(1);
								}
 
							}
							else {
								fwrite( $irc,$cmd.' :amsg can only be used by trusted members.'."\n" ); 
							}
							break;
						case 'die':
							if ($cloak == $ownercloak) {
								//Edit cron to stop the automatic restarting of the bot
								$crontab = shell_exec('crontab -l');
								file_put_contents('/home/soxred93/bots/soxbot-test/crontab', preg_replace('/(.*) (.*) \* \* \* \/usr\/local\/bin\/phoenix/', '#\1 \2 * * * /usr/local/bin/phoenix', $crontab));
								shell_exec('crontab /home/soxred93/bots/soxbot-test/crontab');
								posix_kill(posix_getppid(), SIGTERM);
								if( posix_get_last_error() != 0 ) {
				 					fwrite( $irc,$cmd.' :'.posix_strerror(posix_get_last_error())."\n" );
								}
								else {
									fwrite( $irc,$cmd.' :If you say so.'."\n" );
								}
							}
							else {
								fwrite( $irc,$cmd.' :die can only be used by '.$ownercloak.'.'."\n" );  
							}
							break;
						case 'restart':
							if (in_array($cloak, $trustedusers)) {
								posix_kill(posix_getppid(), SIGTERM);
				 				if( posix_get_last_error() != 0 ) {
				 					fwrite( $irc,$cmd.' :'.posix_strerror(posix_get_last_error())."\n" );
								}
								else {
									fwrite( $irc,$cmd.' :If you say so.'."\n" );
								}
							}
							else {
								fwrite( $irc,$cmd.' :restart can only be used by trusted members.'."\n" );
							}
							break;
						case 'namesadd':
							if (in_array($cloak, $trustedusers)) {
								$param = explode(' ',$param);
								
								//Check if the connection is still there
								if (!mysql_ping($mysql)) { 
									include_once('/home/soxred93/database.inc');
									$mysql = mysql_connect( "sql:3306","soxred93",$toolserver_password );
									@mysql_select_db( "u_soxred93", $mysql ) or die( "MySQL error: " .mysql_error() );
								}

								mysql_query( "INSERT INTO names VALUES ('".mysql_real_escape_string($param[0])."', '".mysql_real_escape_string($param[1])."');", $mysql );
								fwrite( $irc,$cmd.' :Done!'."\n" );
							}
							else {
								fwrite( $irc,$cmd.' :namesadd can only be used by trusted members.'."\n" );
							}
							break;
						case 'namesdel':
							if (in_array($cloak, $trustedusers)) {
								$param = explode(' ',$param);
								
								//Check if the connection is still there
								if (!mysql_ping($mysql)) { 
									include_once('/home/soxred93/database.inc');
									$mysql = mysql_connect( "sql:3306","soxred93",$toolserver_password );
									@mysql_select_db( "u_soxred93", $mysql ) or die( "MySQL error: " .mysql_error() );
								}
								
								mysql_query( "DELETE FROM names WHERE '".mysql_real_escape_string($param[0])."' = nick;", $mysql );
								fwrite( $irc,$cmd.' :Done!'."\n" );
							}
							else {
								fwrite( $irc,$cmd.' :namesdel can only be used by trusted members.'."\n" );
							}
							break;
						case 'replag':
							$servers = array( 
								array( 
									'display' => 's1',
									'serv' => 'sql-s1',
									'db' => 'enwiki_p'
								),
								array( 
									'display' => 's1-c',
									'serv' => 'sql-s1',
									'db' => 'commonswiki_p'
								),
								array( 
									'display' => 's2',
									'serv' => 'sql-s2',
									'db' => 'dewiki_p'
								),
								array( 
									'display' => 's3',
									'serv' => 'sql-s3',
									'db' => 'frwiki_p'
								),
								array( 
									'display' => 's3-c',
									'serv' => 'sql-s3',
									'db' => 'commonswiki_p'
								)
							);
							$r = array();
							$msg = "Replag: ";
							foreach( $servers as $serv ) {
								$display = $serv['display'];
								$domain = $serv['serv'];
								$db = $serv['db'];
								$mysql = mysql_connect($domain.':'.$databaseport,$databaseuser,$databasepass,/* Force reconnect --> */ true);
								mysql_select_db($db, $mysql);
 
        						$result = mysql_query( "SELECT UNIX_TIMESTAMP() - UNIX_TIMESTAMP(rc_timestamp) as replag FROM recentchanges ORDER BY rc_timestamp DESC LIMIT 1" );
        						if( !$result ) fwrite( $irc,$cmd.' :Couldn\'t get a result.'."\n" );
        						$row = mysql_fetch_assoc( $result );
        						$secs = $row['replag'];
 
								$msg .= "\002" . $display . "\002 -> ";
 
								if( $secs > ( 24 * 60 * 60 ) ) {
									$msg .= "\00305"; 
								}
								elseif( $secs > ( 60 * 60 ) ) {
									$msg .= "\00308"; 
								}
								else {
									$msg .= "\00302"; 
								}
								
								$msg .= secs2str($secs);
								$msg .= "\003";
							}
							
							$mysql = mysql_connect( "sql:3306",$mysqluser,$mysqlpass );
							@mysql_select_db( $mysqldb, $mysql );
 
							fwrite( $irc,$cmd.' :'.$msg."\n" );
							unset($msg,$replag,$servers,$row,$minute,$hour,$second,$day,$week,$secs);
							break;
						case 'setspeak':
							if ($cloak == $ownercloak) {
								file_put_contents('/home/soxred93/bots/soxbot-test/channel', trim($param));	
								fwrite( $irc,$cmd.' :Done!'."\n" );
							}
							else {
								fwrite( $irc,$cmd.' :setspeak can only be used by '.$ownercloak.'.'."\n" );
							}
							break;
						case 'speak':
							if ($cloak == $ownercloak) {	
								fwrite( $irc,'PRIVMSG '.file_get_contents('/home/soxred93/bots/soxbot-test/channel').' :'.$param."\n" );
							}
							else {
								fwrite( $irc,$cmd.' :speak can only be used by '.$ownercloak.'.'."\n" );
							}
							break;
						case 'link':
							if( !$param || $param == '' ) { fwrite( $irc,$cmd.' :Required parameter not given.'."\n" );continue; }
							if (preg_match('/\[\[(.*?)\]\]/', $data, $l)) {
								$links = $l[1];
								if( strpos( $links, '|' ) !== false ) { 
									$links = explode('|', $links);
									$links = $links[0];
								}
 
								$links = str_replace(' ','_',$links);//Prevent encoding spaces
								$links = str_replace(array('[',']'),'',$links);//Remove illegal characters
								$links = urlencode($links);
								$links = str_replace('%2F','/',$links);//Handle subpages cleanly
 
								fwrite( $irc,$cmd.' :'.$nick.': http://en.wikipedia.org/wiki/'.$links."\n" );
								usleep(500);
							}
							elseif (preg_match_all('/\{\{(.*?)\}\}/', $data, $l)) {
								$links = $l[1];
								if( strpos( $links, '|' ) !== false ) { 
									$links = explode('|', $links);
									$links = $links[0];
								}
 
								$links = str_replace(' ','_',$links);//Prevent encoding spaces
								$links = str_replace(array('{','}'),'',$links);//Remove illegal characters
								$links = urlencode($links);
								$links = str_replace('%2F','/',$links);//Handle subpages cleanly
 
								fwrite( $irc,$cmd.' :'.$nick.': http://en.wikipedia.org/wiki/Template:'.$links."\n" );
								usleep(500);
							}
							else {
								fwrite( $irc,$cmd.' :Couldn\'t find link.'." \n" ); 
							}
							break;
						case 'version':
							fwrite( $irc,$cmd.' :I am currently running version '.$version.' of SoxBot Anti-Testing Bot.'."\n" ); 
							break;
						case 'shortpath':
							$param = preg_match('/\[\[(.*)\]\] \|\| \[\[(.*)\]\]/', $me, $arts);
							if( count($arts) < 3 ) {
								fwrite( $irc,$cmd.' :Not enough parameters.'."\n" ); 
								continue;
							}
							$results = $http->get('http://www.netsoc.tcd.ie/~mu/cgi-bin/shortpath.cgi?from='.urlencode($arts[1]).'&to='.urlencode($arts[2]));
							$articles = preg_match_all('/\<a href=\"http:\/\/en\.wikipedia\.org\/wiki\/(.*?)\"\>(.*?)\<\/a\>/',$results,$m);
							$articles = $m[2];
							$count = (count($articles)-1);
							if( $count >= 0 ) {
								fwrite( $irc,$cmd.' :It takes '.$count.' clicks to get from '.$arts[1].' to '.$arts[2].'.'."\n" ); 
							}
							else {
								fwrite( $irc,$cmd.' :Article was created before the last database dump.'."\n" ); 
								fwrite( $irc,$cmd.' :Taken from http://www.netsoc.tcd.ie/~mu/cgi-bin/shortpath.cgi?from='.urlencode($arts[1]).'&to='.urlencode($arts[2]).'.'."\n");
								continue;
							}
							if( count($articles) < 9 ) { fwrite( $irc,$cmd.' :Articles: '.implode(" --> ", $articles)."\n" ); } 
							break;
						case 'h':
						case 'hits':
							
							//Reconnect if it has dropped the connection
							if (!mysql_ping($mysql)) { 
								include_once('/home/soxred93/database.inc');
								$mysql = mysql_connect( "sql:3306","soxred93",$toolserver_password );
								@mysql_select_db( "u_soxred93", $mysql ) or die( "MySQL error: " .mysql_error() );
							}
							
							//Get the aliases of certain pages
							$result = mysql_query( "SELECT * FROM names" );
							$contents = array();
							while( $row = mysql_fetch_assoc( $result ) ) {
								$contents[ $row['nick'] ] = $row['user'];
							}
 							
 							//First see if there's no param at all, which implies that they want their own user talk page
							if( !$param || $param == '' ) { 
							
								//Check if it's in the known nicks
								if( isset($contents[$nick])) { 
									$param = "User talk:".$contents[$nick];
								}
								
								//Check if it's a valid user, for users who use their WP name as their nick
								elseif( $wpapi->users($nick) ) {
									$param = "User talk:".$nick;
								}
								
								//Don't know? Ignore.
								else {
									fwrite( $irc,$cmd.' :Required parameter not given. Talk to X! if you want .hits to work for your nick.'."\n" );continue; 
								}
							}
							
							//Now see if someone passed a nick as a param
							elseif( isset($contents[$param])) { 
								$param = "User talk:".$contents[$param];
							}							
							
							if( $chan == "#wikipedia-simple" ) {
								$simplehits = 'simple';
							}
							else {
								$simplehits = 'en';
							}
							
							$r3 = urlencode($param);
							$r3 = str_replace('+','_',$r3);
							$r3 = str_replace('%2F','/',$r3);
							$results = $http->get('http://stats.grok.se/json/'.$simplehits.'/'.date("Ym").'/'.$r3);
							$json = json_decode($results);
							
							if($json) {
								fwrite( $irc,$cmd.' :'.$json->{'title'}.' has been viewed '.$json->{'total_views'}.' times in '.$json->{'month'}.". See ".'http://stats.grok.se/'.$simplehits.'/'.date("Ym").'/'.$r3."\n" ); 
							}
							else {
								fwrite( $irc,$cmd.' :Couldn\'t find hit count.'."\n" );
							}
							unset($r3);
							break;
						case 'rfxupdate':
							if (in_array($cloak, $trustedusers)) {
								echo "Updating...\n";
								echo shell_exec("/usr/bin/php /home/soxred93/bots/rfx-report.php");
								echo shell_exec("/usr/bin/php /home/soxred93/bots/rfx-tally.php");
								fwrite( $irc,$cmd.' :Done!'."\n" );
							}
							else {
								fwrite( $irc,$cmd.' :rfxupdate can only be used by trusted members.'."\n" );
							}
							break;
						case 'ip2host':
						case 'rdns':
							if( !$param || $param == '' ) { fwrite( $irc,$cmd.' :Required parameter not given.'."\n" );continue; }
 
							$rdns = shell_exec("/bin/sh /home/soxred93/rdns.sh $param");
 
							if( !$rdns ) {
								fwrite( $irc,$cmd.' :Not found.'."\n" );continue;
							}
 							
 							$rdns = substr( $rdns, 0, ( strlen( $rdns ) -1 ) );
							fwrite( $irc,$cmd.' :Result: '.$rdns."\n" );continue;
							break;
						case 'host2ip':
						case 'dns':
							if( !$param || $param == '' ) { fwrite( $irc,$cmd.' :Required parameter not given.'."\n" );continue; }
 
							$dns = shell_exec("/bin/sh /home/soxred93/dns.sh $param");
 
							if( !$dns ) {
								fwrite( $irc,$cmd.' :Not found.'."\n" );continue;
							}
 							
							fwrite( $irc,$cmd.' :Result: '.$dns."\n" );continue;
							break;
						case 'rand':
							if( !$param || $param == '' ) { fwrite( $irc,$cmd.' :Required parameter not given.'."\n" );continue; }
							
 							$rand = explode( ' ', $param );
 							$rand = mt_rand($rand[0],$rand[1]);
 							if( $rand[1] > 20 ) break;
 							echo "Random number: $rand\n";
 							fwrite( $irc,$cmd.' :Result: '.$rand."\n" );
 							break;
 						case 'howlong':
 							break;
							if( !$param || $param == '' ) { fwrite( $irc,$cmd.' :Required parameter not given.'."\n" );continue; }
 							$rand = explode( ' ', $param );
 							$rand = mt_rand($rand[0],$rand[1]);
 							if( $rand[1] > 20 ) break;

 							echo "Random number: $rand\n";
 							$randstr = "8";
 							$randstr .= str_repeat( "=", $rand );
 							$randstr .= "D";
 							fwrite( $irc,$cmd.' :'.$randstr."\n" );
 							break;
					}
				}
			}
		}
		posix_kill(posix_getppid(), SIGTERM);
		die("GHGHHAHHAAAAAAAAAA");
	}
 
	$run = $wpq->getpage('User:'.$user.'/Run');
 
	//Don't post source if it is disabled
	if( file_get_contents( '/home/soxred93/bots/soxbot-test/postsource' ) == 1 ) {
		$wpi->forcepost('User:'.$user.'/Source',
		'The following is automatically generated by [[User:'.$user.'|'.$user."]]. It uses [[User:ClueBot/Source|ClueBot classes]] for interacting with the wiki, and also uses some of ClueBot's code for interacting with IRC.\n\n".'<syntaxhighlight lang="php">'.str_replace('</sou<!-- -->rce>','</sou<!-- -->rce>', file_get_contents(__FILE__))."</sou<!-- -->rce>\n\n\n\n",
		'Automated source upload.');
	}
 
	//Get list of articles and users to stalk
	$stalk = array();
	$edit = array();
	$tmp = explode("\n",$wpq->getpage('User:'.$user.'/Autostalk.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:'.$user.'/Autoedit.js'));
	foreach ($tmp as $tmp2) { if (substr($tmp2,0,1) != '#') { $tmp3 = explode('|',$tmp2,2); $edit[$tmp3[0]] = trim($tmp3[1]); } }
	unset($tmp,$tmp2,$tmp3);
 
	//Start IRC feed parser
	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" :SoxBot Wikipedia 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\.wikipedia\.org\/w\/index\.php\?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';
					$pos = strpos($change['flags'], 'B');
 					if ($pos !== false) continue;
 					
					$stalkchannel = array();
					foreach ($stalk as $key => $value) if (fnmatch(str_replace('_',' ',$key),str_replace('_',' ',$change['user']))) $stalkchannel = array_merge($stalkchannel,explode(',',$value));
					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?diff=prev'.'&oldid='.urlencode($change['revid']).' * '.$change['user'] .
							' * '.$change['comment']."\n");
						sleep(1);
					}
 
					//Update $stalk, $edit, and $channels variables
					if (($change['namespace'] == 'User:')) {
						if (strtolower($change['title']) == strtolower($user.'/Run')) { $run = $wpq->getpage('User:'.$user.'/Run'); }
						if (strtolower($change['title']) == strtolower($user.'/Whitelist')) { $whitelist = $wpq->getpage('User:'.$user.'/Whitelist'); }
						if (strtolower($change['title']) == strtolower($user.'/Autostalk.js')) {
							fwrite( $irc,'PART '.implode(',',$stalk)." Parting due to ".$change['user']." editing User:".$user.'/Autostalk.js'."\n" );
							sleep(2);
							unset($stalk);
							$tmp = explode("\n",$wpq->getpage('User:'.$user.'/Autostalk.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);
							fwrite( $irc,'JOIN '.implode(',',$stalk)."\n" );
							sleep(2);
						}
						echo $change['title'];
						if (strtolower($change['title']) == strtolower($user.'/Autoedit.js')) {
							fwrite( $irc,'PART '.implode(',',$edit)." Parting due to ".$change['user']." editing User:".$user.'/Autoedit.js'."\n" );
							sleep(2);
							unset($edit);
							$tmp = explode("\n",$wpq->getpage('User:'.$user.'/Autoedit.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);
							fwrite( $irc,'JOIN '.implode(',',$edit)."\n" );
							sleep(2);
						}
						if (strtolower($change['title']) == strtolower($owner.'/Channels.js')) {
							$ircconfig = explode("\n",$wpq->getpage('User:'.$owner.'/Channels.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.','.$irctechchannel.','.$ircotherchannels.','.$ircvandalismchannel.','.$ircaivchannel.','.$ircverbosechannel.','.$irclogchannels.','.$ircwikilinkchannels.','.$ircpeakchannels) 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)." Parting due to ".$change['user']." editing User:".$owner.'/Channels.js'."\n" ); 
 
							$ircchannel = $tmp['ircchannel'];
							$irctechchannel = $tmp['irctechchannel'];
							$ircverbosechannel = $tmp['ircverbosechannel'];
							$ircotherchannels = $tmp['ircotherchannels'];
							$ircvandalismchannel = $tmp['ircvandalismchannel'];
							$ircaivchannel = $tmp['ircaivchannel'];
							$irclogchannels = $tmp['irclogchannels'];
							$ircwikilinkchannels = $tmp['ircwikilinkchannels'];
							$ircpeakchannels = $tmp['ircpeakchannels'];
 
							unset($tmp,$tmpline,$tmpold,$tmpnew,$tmp2,$tmp3);
						}
					}
 
					if (($change['namespace'] != '') || ($change['flags'] == 'move')) continue; //Ignore moves and nonmainspace edits
 
					//Add namespace to the title
					$change['title'] = $change['namespace'].$change['title'];
 
					//Don't bother with forking if it is disabled
					if (!preg_match('/(yes|enable|true)/i',$run)) {
						continue;
					}
 
					//Start the fork!!!
					$feedpid = @pcntl_fork();
					//$pids[$feedpid] = $feedpid;
					if ($feedpid != 0) continue;
					//echo posix_getpid()."\n";
 
					$diff = $wpi->diff($change['title'],$change['old_revid'],$change['revid']);//Get diff
					$score = score($testlist,$diff[0],$log);//Match edit against $scorelist
					$score -= score($testlist,$diff[1],$log2);//Add points for each instance removed.
					$url = 'http://en.wikipedia.org/w/index.php?title='.urlencode($change['title']).'&diff='.urlencode($change['revid']).'&oldid='.urlencode($change['old_revid']);//Url of the diff
 
					$tmp = unserialize(file_get_contents('/home/soxred93/bots/soxbot-test/titles.txt'));
 
					if (
						($score <= SCORELIMIT)
						&& (!preg_match('/\<code\>/', $wpq->getpage($change['title']))) //Ignore pages with <code>
						&& ((($wpq->contribcount($change['user']) < 50) || preg_match('/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/', $change['user'])))//Ignore accounts with >50 edits
						&& (!preg_match('/^\* \[\[User:('.preg_quote($change['user'],'/').')|\1\]\] \- .*/',$whitelist)) //Ignore users listed on User:SoxBot III/Whitelist 
						&& ((!isset($tmp[$change['title'].$change['user']])) || ((time() - $tmp[$change['title'].$change['user']]) > (24*60*60)))//Ignore users and pages who were reverted in last 24 hours
						&& ($tmp[$change['title'].$change['user']] = time())
						&& ((file_put_contents('/home/soxred93/bots/soxbot-test/titles.txt',serialize($tmp))) !== false)
						&& (($change['length'] < 600) || ($score <= -35))//Make threshold for reverting higher if the changed length is high
					) { 
						//Get maxlag, and don't revert if it is high.
						$curmaxlag = $wpi->getMaxlag();
						if( $curmaxlag[2] > $maxlag ) {
							foreach(explode(',',$irctechchannel) as $y) {
								fwrite( $irc,'PRIVMSG '.$y.' :'.$curmaxlag[1].' is lagged out by '.$curmaxlag[2].' seconds. ('.$curmaxlag[0].')'."\n" ); 
								usleep(500);
							}
							continue;
						}
						unset($curmaxlag);
 
						//Notify in channel
						foreach (explode(',',$ircchannel) as $y) {
							fwrite( $irc,'PRIVMSG '.$y.' :Reverting revision http://en.wikipedia.org/wiki/?diff='.$change['revid'].' by '.$change['user'].'.'."\n" ); usleep(500);
						}
 
						//Remainder of $ircverbosechannel
						foreach (explode(',',$ircverbosechannel) as $y) {
							fwrite( $irc,'PRIVMSG '.$y.' :Reverting revision '.$change['revid'].' by '.$change['user'].'.'."\n" ); usleep(500);
						}
						unset($diff, $revision, $url);
 
						//Were we beaten?
						$currev = $wpapi->revisions($change['title'],3,'newer',false,$change['revid']);
						if (($currev[0]['revid'] != $change['revid']) && ($currev[0]['user'] != $change['user']) && $currev[0]['user']) {
							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($currev[1]['user']).'\')');
							foreach (explode(',',$ircverbosechannel) as $y) {
								fwrite( $irc,'PRIVMSG '.$y.' :Inserting '.$change['revid'].' into `beaten` table.'."\n" ); usleep(500);
							}
						}
						else {
							//Check if user was reverted recently
							$query = 'SELECT date,user,article FROM testing WHERE user=\''.
							mysql_real_escape_string($change['user']).
							'\' AND article=\''.
							mysql_real_escape_string($change['title']).
							'\' AND date=\''.
							date( 'Y-m-d' ).
							'\';';
							echo $query;
							if (!mysql_ping($mysql)) { $mysql = 
								mysql_connect($mysqlhost,$mysqluser,$mysqlpass,/* Force reconnect --> */ true);echo "Ping?\n"; 
								mysql_select_db($mysqldb, $mysql); 
							}
							$result = mysql_query($query);
							if( !$result ) { die( "MySQL error: ".mysql_error() ); }
 
							//Remainder of $ircverbosechannel
							foreach (explode(',',$ircverbosechannel) as $y) {
								fwrite( $irc,'PRIVMSG '.$y.' :Querying if '.$change['user'].' has been reverted recently.'."\n" ); usleep(500);
							}
							echo "Querying if user has been reverted recently.\n";
							if ( mysql_num_rows( $result ) != 0 ) {
								//Remainder of $ircverbosechannel
								foreach (explode(',',$ircverbosechannel) as $y) {
									fwrite( $irc,'PRIVMSG '.$y.' :Yes, not reverting.'."\n" ); usleep(500);
								}
								continue;
							}
							//Remainder of $ircverbosechannel
							foreach (explode(',',$ircverbosechannel) as $y) {
								fwrite( $irc,'PRIVMSG '.$y.' :No, will continue to revert.'."\n" ); usleep(500);
							}
 
							//Insert into table. `reverted` is 0, will be changed to 1 later if the revert succeeded
							$query = 'INSERT INTO `testing` ' .
								'(`id`,`user`,`article`,`diff`,`old_id`,`new_id`,`reverted`,`date`,`score`) ' .								
								'VALUES ' .
								'(NULL,\''.mysql_real_escape_string($change['user']).'\',' .
								'\''.mysql_real_escape_string($change['title']).'\',' .
								'\''.mysql_real_escape_string($change['url']).'\',' .
								'\''.mysql_real_escape_string($change['old_revid']).'\',' .
								'\''.mysql_real_escape_string($change['revid']).'\',0,' .
								'\''.date( 'Y-m-d' ).'\',' .
								'\''.mysql_real_escape_string($score).'\');';
							if (!mysql_ping($mysql)) {
								$mysql = mysql_pconnect($mysqlhost,$mysqluser,$mysqlpass,/* Force reconnect --> */ true);
								if (!$mysql) { die('Could not connect: ' . mysql_error()); }
								if (!mysql_select_db($mysqldb, $mysql)) { die ('Can\'t use database : ' . mysql_error()); }
							}
							mysql_query($query);
 
							//Remainder of $ircverbosechannel
							foreach (explode(',',$ircverbosechannel) as $y) {
								fwrite( $irc,'PRIVMSG '.$y.' :Inserting '.$change['revid'].' into `testing`.'."\n" ); usleep(500);
							}
							if (mysql_affected_rows( $mysql ) == 0) {
								echo "Problem?\n";
								//Remainder of $ircverbosechannel
								foreach (explode(',',$ircverbosechannel) as $y) {
									fwrite( $irc,'PRIVMSG '.$y.' :MySQL error? '.mysql_error()."\n" ); usleep(500);
								}
								continue;
							} 
 
 							$mysqlid = mysql_insert_id();//So we can change `reverted` to 1 later
 
 							//Get rollback token
							$token = $http->get('http://en.wikipedia.org/w/api.php?action=query&prop=revisions&rvtoken=rollback&titles=Main%20Page&format=php');
							$token = unserialize($token);
							$token = $token['query']['pages'][$wpq->getpageid($change['title'])]['revisions'][0]['rollbacktoken'];
							echo "Token: $token\n";
 
							//Remainder of $ircverbosechannel
							foreach (explode(',',$ircverbosechannel) as $y) {
								fwrite( $irc,'PRIVMSG '.$y.' :Getting rollback token.'."\n" ); usleep(500);
							}
							if( $token == '' ) {
								//Remainder of $ircverbosechannel
								foreach (explode(',',$ircverbosechannel) as $y) {
									fwrite( $irc,'PRIVMSG '.$y.' :Error getting token.'."\n" ); usleep(500);
								}
							}
 
							//Do the revert!!!
							$return = $wpi->rollback(
								$change['title'],
								$change['user'],
								'Reverting possible test edit(s) by [[Special:Contributions/'.$change['user'].'|'.$change['user'].']] ' .
								'to '.(($revid == 0)?'older version':'version by '.$revdata['user']).'. ' .
								'[[User talk:'.$owner.'|Was this a mistake?]] (BOT EDIT)',
								$token,
								false
							);
 
							//Remainder of $ircverbosechannel
							foreach (explode(',',$ircverbosechannel) as $y) {
								fwrite( $irc,'PRIVMSG '.$y.' :Rolling back '.$change['revid'].'.'."\n" ); usleep(500);
							}
							echo "Reverting.\n";
 
							//If it returned true, let's warn the user
							if ($return !== false) {
								//Remainder of $ircverbosechannel
								foreach (explode(',',$ircverbosechannel) as $y) {
									fwrite( $irc,'PRIVMSG '.$y.' :Returned true, attempting to warn.'."\n" ); usleep(500);
								}
								$warning = getWarningLevel( $change['user'] );
								$warning++;//Increase warning level
 
								//Max warning is 4
								if ($warning < 5) {
									//Add shared IP notice if the user is an IP, and if it's the first warning
									$append = '';
									if ( 
										$warning == 1 &&
										preg_match('/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/', $change['user'])//*puke* This regex just checks if it is an IP
									) {
										$append = ":''If this is a shared [[IP address]], and you didn't make the edit, consider [[Wikipedia:Why create an account?|creating an account]] for yourself so you can avoid further irrelevant notices.''\n";
									}
									//Tell the CVN bots if it is a repeat vandal/tester
									elseif ($warning > 2) {
										foreach (explode(',',$ircvandalismchannel) as $y) {
											fwrite( $irc,'PRIVMSG '.$y.' :computer bl add '.$change['user'].' x='.(24*$warning).' r=Test edits to [['.$change['title'].']] (#'.$warning.').'."\n" ); usleep(500);
										}
									}
 
									//Get talk page content
									$talk = $wpq->getpage('User talk:'.$change['user']);	
									$wpi->post(
										'User talk:'.$change['user'],$talk."\n\n".'{{subst:User:'.$user.'/warn|1='.$change['title'].'|2='.$warning.'|3='.$mysqlid.'}} '.SIGNATURE.' 12:00, 19 January 2020 (UTC)'."\n".$append,'Warning user of test edits (Warning #'.$warning.')',false,null,false); //This fugly code warns the user
									//Remainder of $ircverbosechannel
									foreach (explode(',',$ircverbosechannel) as $y) {
										fwrite( $irc,'PRIVMSG '.$y.' :Warning '.$change['user'].'.'."\n" ); usleep(500);
									}
								}
								elseif ($warning > 4) {
									//Let's report them to AIV!
									$aiv = $wpq->getpage('Wikipedia:Administrator intervention against vandalism/TB2');	
									if ( preg_match('/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/', $change['user']) ) {
										$template = "IPvandal";
									}
									else {
										$template = "Vandal";
									}
 
									if (!preg_match('/'.preg_quote($change['user'],'/').'/i',$aiv)) {
										//Only report if they haven't aren't already there
										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" ); usleep(500);
										}
										foreach (explode(',',$ircvandalismchannel) as $y) {
											fwrite( $irc,'PRIVMSG '.$y.' :computer bl add '.$change['user'].' x='.(24*$warning).' r=Vandalism to [['.$change['title'].']] (#'.$warning.").\n" ); usleep(500);
										}
										$aiv = $aiv . "\n" .
										"* {{".$template."|1=".$change['user']."}} ".
										"User made possible test edits, such as [http://en.wikipedia.org/wiki/?diff=".$change['revid']." 1]. ".SIGNATURE." 12:00, 19 January 2020 (UTC)";
										$wpi->post('Wikipedia:Administrator intervention against vandalism/TB2',$aiv,'Reporting [[Special:Contributions/'.$change['user']."|".$change['user']."]] (BOT EDIT)");
										foreach (explode(',',$ircverbosechannel) as $y) {
											fwrite( $irc,'PRIVMSG '.$y.' :Warning level is 4, reporting to AIV.'."\n" ); usleep(500);
										} 
									} else {
										foreach (explode(',',$ircaivchannel) 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" ); usleep(500); //Ping the admins!
										}
									}
								}
 
								//Now that it was reverted, let's update the table
								mysql_query('UPDATE `testing` SET `reverted` = 1 WHERE `id` = \''.mysql_real_escape_string($mysqlid).'\'');
							} 
							else {//Somehow, it returned false. Let's figure out why.
								//Remainder of $ircverbosechannel
								foreach (explode(',',$ircverbosechannel) as $y) {
									fwrite( $irc,'PRIVMSG '.$y.' :Returned false, figuring out why.'."\n" ); usleep(500);
								}
								$currev = $wpapi->revisions($change['title']);
								if (($currev[0]['revid'] != $change['revid']) && ($currev[0]['user'] != $change['user'])) {
									//We've been beaten!!!
									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']).'\')');
									//Remainder of $ircverbosechannel
									foreach (explode(',',$ircverbosechannel) as $y) {
										fwrite( $irc,'PRIVMSG '.$y.' :I was beaten by '.$rev['user'].'!'."\n" ); usleep(500);
									}
								}
								else {
									//Remainder of $ircverbosechannel
									foreach (explode(',',$ircverbosechannel) as $y) {
										fwrite( $irc,'PRIVMSG '.$y.' :There was an unknown rollback error.'."\n" ); usleep(500);
									}
									file_put_contents('/home/soxred93/bots/soxbot-test/errors.txt',file_get_contents('/home/soxred93/bots/soxbot-test/errors.txt')."Date: ".date( 'Y-m-d' )."\n".$return."\n----------------------\n") or die('Error');
									foreach (explode(',',$ircverbosechannel) as $y) {
										fwrite( $irc,'PRIVMSG '.$y.' :Rollback result has been posted to errors.txt.'."\n" ); usleep(500);
									}
									echo "ERROR\n";
								}
							}//End if ($return !== FALSE)
						}//End if beaten check
						//Remainder of $ircverbosechannel
						foreach (explode(',',$ircverbosechannel) as $y) {
							fwrite( $irc,'PRIVMSG '.$y.' :-- Done --.'."\n" ); usleep(500);
						}
					}//End check for vandalism
					//unset($pids[$feedpid]);
					//unset($pids[posix_getpid()]);
					die();
				}//End regex for parsing IRC feed
				//unset($pids[$feedpid]);
			}//End checking for privmsg
		}//End while
	}//End while
?>