All pastes #138621 Raw Edit

PHP IRC Bot

public text v1 · immutable
#138621 ·published 2006-08-19 10:13 UTC
rendered paste body
<?php

/* CONFIG */

set_time_limit(0);
$shutdown = 0;
$config = array();
$config['init'] = 1;
$config['network'] = 'Netgamers';
$config['server'] = 'irc.netgamers.org';
$config['port'] = '6667';
$config['usernick'] = 'Tommeh';
$config['altnick'] = 'Tommmeh';
$config['username'] = 'Tommeh';
$config['channels'] =
	array(
		'#melons',
	);
$config['owner'] = array();
$config['owner']['usernick'] = "";
$config['owner']['identd'] = "";
$config['owner']['hostname'] = "Tommy.users.netgamers.org";

if (!is_resource($logfile = fopen($config['network'] . ".log",a+t))) {
	print("Unable to open / create log file.\n");
}
else {
	fputs($logfile,"\n\n-" . str_repeat("=",48) . "-\n-= Logging commenced at " . date("[d/m/y - H:i:s]") . " =-\n-" . str_repeat("=",48) . "-\n\n");
}


/* CONNECTION LOOP */

while (!$shutdown) {
	print('Connecting to ' . $config['server'] . ' on port ' . $config['port'] . "\n");
	$connection = array();
	$connection['buffer'] = array();
	$connection['settings'] = array();
	$connection['server'] = array();
	$connection['channels'] = array();

	while (!is_resource($connection['socket'] = fsockopen($config['server'],$config['port']))) {
		print("Unable to connect to server.\n");
	}

	if (is_resource($connection['socket'])) {
		raw('USER ' . $config['usernick'] . ' localhost localhost :' . $config['username']);
		raw('NICK ' . $config['usernick']);
		$connection['settings']['nick'] = $config['usernick'];
	}

	/* DATA LOOP */

	while (!feof($connection['socket'])) {
		if ($connection['buffer']['read'] = fgets($connection['socket'],4096)) {
			if ($connection['buffer']['read'] != $oldbuffer) {
				if (substr($connection['buffer']['read'],0,6) == 'PING :') {
					raw('PONG :' . substr($connection['buffer']['read'],6));
					if ($config['init'] == 1) {
						$config['init'] = 0;
						init();
					}
				}
				else {
					$connection['buffer']['all'] .= $connection['buffer']['read'];
					if (strpos($connection['buffer']['all'],"\r\n") !== false) {
						parsebuffer();
						checkbuffer();
						unset($connection['buffer']['all']);
					}
				}
			}
			$oldbuffer = $connection['buffer']['read'];
		}
		else {
			print("Connection terminated.");
			break;
		}
	}
}

if (is_resource($logfile)) {
	fclose($logfile);
}

?>

<?php

/* COMMON FUNCTIONS */

function init() {
	global $connection, $config;
	foreach ($config['channels'] as $channel) {
		raw('JOIN ' . $channel);
	}
}

function raw($what) {
	global $connection, $config;
	fputs($connection['socket'],$what . "\r\n");
	print(date("[d/m - H:i:s]") . " -> " . $what . "\n");
	if (is_resource($logfile)) {
		fputs($logfile,date("[d/m - H:i:s]") . " -> " . $what . "\n");
	}
}

/* BUFFER PARSING */

function parsebuffer() {
	global $connection, $config;
	print(date("[d/m - H:i:s]") . " <- " . $connection['buffer']['all'] . "\n");
	if (is_resource($logfile)) {
		fputs($logfile,date("[d/m - H:i:s]") . " <- " . $connection['buffer']['all'] . "\n");
	}
	$buffer = explode(' ',$connection['buffer']['all'],4);
	foreach ($buffer as $i => $j) {
		if (substr($j,0,1) == ":") {
			$buffer[$i] = substr($j,1);
		}
	}

	$posex = strpos($buffer[0],'!');
	$posat = strpos($buffer[0],'@');

	$connection['buffer']['usernick'] = substr($buffer[0],1,$posex-1);
	$connection['buffer']['identd'] = substr($buffer[0],$posex+1,$posat-$posex-1);
	$connection['buffer']['hostname'] = substr($buffer[0],$posat+1);
	
	$connection['buffer']['command'] = $buffer[1];
	$connection['buffer']['target'] = $buffer[2];
	$connection['buffer']['arguments'] = $buffer[3];
}

/* COMMAND SWITCHING / RESPONSE */

function checkbuffer() {
	global $connection, $config;
	switch($connection['buffer']['command']) {

		/* ### Nick in use ###
		If first nick in use, re-send NICK command with alternate nick and change settings to match */

		case '433':
			raw('NICK ' . $config['altnick']);
			$connection['settings']['nick'] = $config['altnick'];
			break;
		
		/* ### Server info / modes ###
		Get server cmodes, umodes, settings */

		case '005':
			$settings = $connection['buffer']['argument'];
			if (preg_match('/^.*PREFIX=\(([a-zA-Z]+)\)([^\s]+).*$/',$settings,$matches)) {
				$connection['server']['modes']['umodes'] = str_split($matches[1]);
				$connection['server']['modes']['prefixes'] = str_split($matches[2]);
				foreach ($connection['server']['modes']['prefixes'] as $pr) {
					$connection['server']['modes']['prefixlist'] .= '\\' . $pr;
				}
			}
			if (preg_match('/^.*CHANMODES=([^\s]+).*$/',$settings,$matches)) {
				$connection['server']['modes']['cmodes'] = str_split($matches[1]);
			}
			break;


		/* ### JOIN ###
		On JOIN, check for self: if so, create arrays for channel; if someone else, add them to the channel userlist */

		case 'JOIN':
			$channel = $connection['buffer']['target'];
			$nick = $connection['buffer']['usernick'];
			if ($nick == $connection['settings']['nick']) {
				$connection['channels'][$channel] = array();
				$connection['channels'][$channel]['topic'] = array();
				$connection['channels'][$channel]['modes'] = array();
				$connection['channels'][$channel]['names'] = 0;
			}
			else {
				$connection['channels'][$channel]['users'][$nick] = "1";
			}
			break;

		/* ### PART, KICK and QUIT ###
		On PART, unset nick value in channel; On QUIT, unset nick value in all channels */

		case 'PART':
			$channel = $connection['buffer']['target'];
			$nick = $connection['buffer']['usernick'];
			if ($nick == $connection['settings']['nick']) {
				unset($connection['channels'][$channel]);
			}
			else {
				unset($connection['channels'][$channel]['users'][$nick]);
			}
			break;

		case 'KICK':
			$channel = $connection['buffer']['target'];
			$args = explode(" ",$connection['buffer']['arguments'],2);
			$nick = $args[0];
			if ($nick == $connection['settings']['nick']) {
				unset($connection['channels'][$channel]);
			}
			else {
				unset($connection['channels'][$channel]['users'][$nick]);
			}
			if (array_search($channel,$config['channels'])) {
				raw('JOIN ' . $channel);
			}
			break;

		case 'QUIT':
			$nick = $connection['buffer']['usernick'];
			if ($nick != $connection['settings']['nick']) {
				foreach ($connection['channels'] as $channel) {
					if (isset($connection['channels'][$channel][$nick])) {
						unset($connection['channels'][$channel][$nick]);
					}
				}
			}
			break;

		/* ### NICK ###
		On NICK, if self, change settings; if someone else, copy and unset nick value in all channels */

		case 'NICK':
			$nick = $connection['buffer']['usernick'];
			$newnick = $connection['buffer']['target'];
			if ($nick = $connection['settings']['nick']) {
				$connection['settings']['nick'] = $newnick;
			}
			foreach ($connection['channels'] as $channel) {
				if (isset($connection['channels'][$channel][$nick])) {
					$connection['channels'][$channel][$newnick] = $connection['channels'][$channel][$nick];
					unset($connection['channels'][$channel][$nick]);
				}
			}
			break;

		/* ### /NAMES list ###
		When given /NAMES list, mark channel as compiling list and clear if first list, add nicks to channel, add umodes to users */

		case '353':
			$list = substr($connection['buffer']['arguments'],strpos($connection['buffer']['arguments'],"#"));
			$channel = substr($list,0,strpos($list," ") - 1);
			if ($connection['channels'][$channel]['names'] = 0) {
				$connection['channels'][$channel]['users'] = array();
				$connection['channels'][$channel]['names'] = 1;
			}
			$nicks = substr($list,strpos($list,":"));
			$nicks = explode(" ",$nicks);
			foreach ($nicks as $nick) {
				$umode = "1";
				if (preg_match('/^[' . $connection['server']['modes']['prefixlist'] . '].*$/',$nick)) {
					$umode = substr($nick,0,1);
					$nick = substr($nick,1);
				}
				$connection['channels'][$channel]['users'][$nick] = $umode;
			}
			break;

		/* ### End of /NAMES list ###
		Mark channel as not compiling list */

		case '356':
			$channel = $connection['buffer']['target'];
			$connection['channels'][$channel]['names'] = 0;			
			break;
	}
}

?>