Location: PHPKode > projects > Kbot > kbot_1.3/rconBots/includes/cssRconBot.class.php
<?PHP 
/**
 *
 * $Id: cssRconBot.class.php 121 2006-11-24 12:59:43Z khaless $
 * $Revision: 121 $
 * $Author: khaless $
 * $Date: 2006-11-24 23:59:43 +1100 (Fri, 24 Nov 2006) $
 * 
 * Copyright (c) 2005 Mathew Rodley <hide@address.com>
 * 
 * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 * 
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
class cssRconBot
{
	public $dataArray;
	public $coreFuncs;
	public $matchAdminSteamID;
	public $pugLive;
	public $halfCount;
	public $roundsPlayed;
	public $roundsToBePlayed;
	public $countTillEnd;
	public $endingProc;
	public $playerCount;
	public $playerInfoArray;
	public $timeout;

	private $adminAuthDetails = array();

	private $usingAuthPlugin;
	private $usingAuth;
	private $authPlayers;
	private $pendingAuth;
	private $authPendingTimeout;
	private $serverStartTime;
	private $startupGraceTime;
	private $graceTimeCheck;

	private $scoreCTFirstHalf = 0;
	private $scoreTFirstHalf = 0;
	private $scoreCT = 0;
	private $scoreT = 0;

	private static $TIME_TO_AUTH = 45;
	private static $TIME_TO_JOIN = 300;

	function cssRconBot($dataArray, $coreFuncs)
	{
		$this->dataArray = &$dataArray;
		$this->coreFuncs = &$coreFuncs;
		$this->matchAdminSteamID = NULL;
		$this->pugLive = FALSE;
		$this->halfCount = 0;
		$this->roundsPlayed = 0;
		$this->hitTheCount = FALSE;
		$this->roundsToBePlayed = $this->dataArray['rounds'];
		$this->countTillEnd = 0;
		$this->endingProc = FALSE;
		$this->playerCount = 0;
		$this->playerInfoArray = array();
		$this->usingAuth = $this->dataArray['usingAuth'];
		$this->authPlayers = $this->dataArray['authPlayers'];
		$this->pendingAuth = $this->dataArray['pendingAuth'];
		$this->adminAuthDetails = $this->dataArray['adminAuthDetails'];
		$this->serverStartTime = time();
		$this->startupGraceTime = 180;
		$this->graceTimeCheck = false;
		$this->usingAuthPlugin = ($this->dataArray['usingAuthPlugin'] === true);

		// process the team string so we can display it adhearing to rcon say length limits.
		$teams = $this->dataArray['teams'];
		$members = $this->dataArray['teamMembers'];

		$this->teamRemindLines = array();
		foreach($teams as $index => $team)
		{
			array_push($this->teamRemindLines, $team.':');
			$lineString = '';
			foreach($members[$index] as $member)
			{
				if(strlen($lineString . $member) > 64)
				{
					array_push($this->teamRemindLines, substr($lineString,0,-2));
					$lineString = '';
				}
				$lineString .= $member .', ';
			}
			if($lineString != '') array_push($this->teamRemindLines, substr($lineString,0,-2));
		}
	}

	/**
	 * Called once when the bot starts and is connected.
	 *
	 */
	function init() {

		// set the number of people joined.
		if($this->usingAuth === true) {
			$count = count($this->authPlayers) + count($this->pendingAuth);
			$this->coreFuncs->sendToIRC('SETAUTH:'.$count);
		}

		if($this->usingAuth === true && $this->usingAuthPlugin === true) {

			$this->coreFuncs->rconCommand('kbot_auth 1');
			$this->coreFuncs->rconCommand('kbot_resetauth');

			// add authorised steam ID's and Authcodes..
			foreach($this->authPlayers as $player) {
				$this->coreFuncs->rconCommand('kbot_addid "'.$player['steamid'].'"');
			}
			foreach($this->pendingAuth as $k => $e) {
				$this->coreFuncs->rconCommand('kbot_addauth '.$e['key']);
			}
		}
	}

	function cleanUp() {
		if($this->usingAuth === true && $this->usingAuthPlugin === true) {
			$this->coreFuncs->rconCommand('kbot_resetauth');
			$this->coreFuncs->rconCommand('kbot_auth 0');
		}
		if($this->usingAuth === true) {
			$this->coreFuncs->sendToIRC('RSTAUTH');
		}
	}

	function kbotAuthValidCode($data) {
		if($this->usingAuth === true && $this->usingAuthPlugin === true) {
			$code = $data[1];
			$steamid = $data[2];
			$name = $data[3];

			foreach($this->pendingAuth as $k => $e) {
				if(strcasecmp($e['key'], $code) === 0) {
					$this->coreFuncs->sendToIRC('CMDAUTH:'.serialize(array('hostmask' => $e['host'], 'steamid' => $steamid)));
					$this->coreFuncs->rconCommand('say '.$name.' Auth\'ed to '. $e['nick']);
					unset($this->pendingAuth[$k]);
					$this->authPlayers[] = array('host' => $e['host'], 'steamid' => $steamid, 'nick'=> $e['nick'], 'initialTime' => $e['initialTime']);
					$this->coreFuncs->rconCommand('kbot_addid "'.$steamid.'"');
					$this->coreFuncs->rconCommand('kbot_delcode '.$code);

					if($this->adminAuthDetails['type'] == 'code') {
						if(strcmp($code, $this->adminAuthDetails['code']) == 0) {
							$this->matchAdminSteamID = $steamid;
							$this->coreFuncs->rconCommand('say "PUG Admin given to '.$name.'"');
						}
					}
				}
			}
		}
	}

	function kbotAuthValidSteamID($data) {
		if($this->usingAuth === true && $this->usingAuthPlugin === true) {
			$steamid = $data[1];
			$name = $data[2];

			foreach($this->authPlayers as $player) {
				// found steamid :D
				if($player['steamid'] == $steamid) {
					$this->coreFuncs->rconCommand('say '.$name.' Auth\'ed to '. $player['nick']);

					if($this->adminAuthDetails['type'] == 'steamid') {
						if(strcmp($steamid, $this->adminAuthDetails['steamid']) == 0) {
							$this->matchAdminSteamID = $steamid;
							$this->coreFuncs->rconCommand('say "PUG Admin given to '.$name.'"');
						}
					}
					return;
				}
			}
		}
	}

	// use this to get their IP to report it to connect2
	function connection1($data)
	{
		$this->tempIPHold[$data[2]] = $data[4];
	}
	// handle when they connect to the server...
	function connection2($data)
	{
		if($data[3] == 'BOT') {
			return; // Ignore Bots
		}
		if(defined('SW_CONNECTED')) {
			$str = buildSWSwting(SW_CONNECTED, array($data[1]));
			$this->coreFuncs->sendToIRC('MSG:'.$str);
		}
		$this->playerCount++;

		// add this name to the player info array
		$this->playerInfoArray[$data[3]]['name'] = $data[1];
		$this->playerInfoArray[$data[3]]['ip'] = $this->tempIPHold[$data[2]];


		//
		// Take care of non full pugs!
		// -- Player Count stuff
		//
		if($this->timeout != 0 && $this->countTillEnd == 0 && $this->endingProcess !== TRUE) {
			// This means we need people to join as the pug is soon going to
			// be shut down coz of not enough players
			$val = $this->getLowerPlayerLimit();
			if($this->playerCount >= $val) {
				$this->timeout = 0;
				$this->timeoutNotice = array(false, false, false, false);
				$this->coreFuncs->rconCommand('say "Player Limit Reached, Shutdown aborted."');
			}
		}
		//
		//
		//

		//
		// Auth Stuff.
		//
		if($this->usingAuth === true && $this->usingAuthPlugin !== true) {
			foreach($this->authPlayers as $player) {
				// found steamid :D
				if($player['steamid'] == $data[3]) {
					$this->coreFuncs->rconCommand('say '.$data[1].' Auth\'ed to '. $player['nick']);

					if($this->adminAuthDetails['type'] == 'steamid') {
						if(strcmp($data[3], $this->adminAuthDetails['steamid']) == 0) {
							$this->matchAdminSteamID = $data[3];
							$this->coreFuncs->rconCommand('say "PUG Admin given to '.$data[1].'"');
						}
					}
					return;
				}
			}
			$this->coreFuncs->rconCommand('say "'.$data[1].' you have '.self::$TIME_TO_AUTH.' seconds to perform your !auth"');
			$this->authPendingTimeout[$data[3]] = array(time(), $data[1]);
		}

		//
		//
		//
	}

	function getLowerPlayerLimit() {
		// This $val will be even
		$val = ceil($this->dataArray['playerCount'] / 2);
		if($val&1 == 1) $val++;
		return $val;
	}

	function changeName($data)
	{
		// account for a change of name and update the player info array
		//DEFINE('CHANGE_NAME',           '"(.*)<([0-9]+)><(.*)><([A-Za-z]{0,20})>" changed name to "(.*)"');
		if($this->playerInfoArray[$data[3]]) $this->playerInfoArray[$data[3]]['name'] = $data[5];
	}

	function disconnection($data)
	{
		if($data[3] == 'BOT' || $data[3] == 'STEAM_ID_PENDING' || !$this->playerInfoArray[$data[3]]) {
			return; // Ignore Bots, STEAM_ID_PENDING's and clients we dont know about
		}

		if(defined('SW_DISCONNECTION')) {
			$str = buildSWSwting(SW_DISCONNECTION, array($data[1]));
			$this->coreFuncs->sendToIRC('MSG:'.$str);
		}

		$this->playerCount--;

		// unset the player info array for this player
		unset($this->playerInfoArray[$data[3]]);

		//
		// Take care of non full pugs! (3 mins of grace time)
		//
		if(time() - $this->serverStartTime > $this->startupGraceTime && $this->countTillEnd == 0 && $this->endingProcess !== TRUE) {

			// if we have reached the grace time and this disconnect
			// means there are 0 players in the server, kill the pug.
			if($this->playerCount == 0) {
				$this->coreFuncs->rconCommand('say "PUG Ending, All players left the server."');
				// ok we want to end the game here..
				$this->endingProcess = TRUE;
				$this->coreFuncs->sendToIRC('CMD:ENDPUG');
			}

			$val = $this->getLowerPlayerLimit();
			if($this->timeout == 0 && $this->playerCount < $val) {
				// we have issues as there are not enough players, give them 90 seconds
				// to fill the spot
				$this->timeout = time() + 90;
				$this->timeoutNotice = array(false, false, false, false);
				$this->coreFuncs->rconCommand('say "Not enough players in server. PUG will end in 90 seconds!"');
			}

			// only send messages after grace time check.
			if($this->graceTimeCheck === true) {
				$needMore = $this->dataArray['playerCount'] - $this->playerCount;
				if($this->usingAuth === true) {
					if(defined('SW_PLAYERLEFT_AUTH')) {
						$str = buildSWSwting(SW_PLAYERLEFT_AUTH, array($needMore));
						$this->coreFuncs->sendToIRC('MSG:'.$str);
					}
				}
				else {
					if(defined('SW_PLAYERLEFT')) {
						$str = buildSWSwting(SW_PLAYERLEFT, array($needMore, $this->dataArray['sv_password']));
						$this->coreFuncs->sendToIRC('MSG:'.$str);
					}
				}
			}
		}
		//
		//
		//

		// auth shit //
		// *note* ignore disconnecting players if pug is shutting down
		if($this->usingAuth === true && $this->endingProc !== true) {
			// only remove disconecters after the grace period...
			// if they leave before the grace anyway it doesnt matter
			// as the grace will get them and remove them.
			if($this->graceTimeCheck === true) {
				foreach($this->authPlayers as $key => $player) {
					if($data[3] == $player['steamid']) {

						// find channel.
						$chan = unserialize($this->dataArray['msgTargetChannels']);
						$chan = $chan[0];

						$this->coreFuncs->sendToIRC('DECAUTH');
						$this->coreFuncs->sendToIRC('RMPLAYER:'.serialize(array($player['nick'], $chan)));

						if($this->usingAuthPlugin === true) {
							// if we are using auth plugin, and they disconnect
							// remove their id from the auth list
							$this->coreFuncs->rconCommand('kbot_delid "'.$player['steamid'].'"');
						}

						unset($this->authPlayers[$key]);
					}
				}
			}
		}
		//
	}

	function maintinence() {
		if($this->endingProc === true) return; // dont do anything if were in our dying stage

		// check No. players in server
		if($this->graceTimeCheck === false && time() >= $this->serverStartTime + $this->startupGraceTime) {
			$this->graceTimeCheck = true;

			$val = $this->getLowerPlayerLimit();
			if($this->timeout == 0 && $this->playerCount < $val) {
				// we have issues as there are not enough players, give them 90 seconds
				// to fill the spot
				$this->timeout = time() + 90;
				$this->timeoutNotice = array(false, false, false, false);
				$this->coreFuncs->rconCommand('say "Not enough players in server. PUG will end in 90 seconds!"');
			}
		}

		//
		// Take care of non full pugs
		//
		if($this->timeout != 0) {
			if(time() > $this->timeout && $this->timeoutNotice[3] !== true) {
				$this->timeoutNotice[3] = true;
				if(defined('SW_PUGENDING_PLAYERS')) {
					$val = $this->getLowerPlayerLimit();
					$str = buildSWSwting(SW_PUGENDING_PLAYERS, array($this->playerCount, $val));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}
				// give report on all players.
				//$this->playerReport();
				$this->coreFuncs->rconCommand('say "PUG Ending due to insufficient active players in server."');
				// ok we want to end the game here..
				$this->endingProcess = TRUE;
				$this->coreFuncs->sendToIRC('CMD:ENDPUG');
			}
			else {
				$secondsLeft = $this->timeout - time();
				if($secondsLeft < 60 && $this->timeoutNotice[0] !== true) {
					$this->timeoutNotice[0] = true;
					$this->coreFuncs->rconCommand('say "Not enough players in server. PUG will end in 60 seconds!"');
				} if($secondsLeft < 30 && $this->timeoutNotice[1] !== true) {
					$this->timeoutNotice[1] = true;
					$this->coreFuncs->rconCommand('say "Not enough players in server. PUG will end in 30 seconds!"');
				} if($secondsLeft < 15 && $this->timeoutNotice[2] !== true) {
					$this->timeoutNotice[2] = true;
					$this->coreFuncs->rconCommand('say "Not enough players in server. PUG will end in 15 seconds!"');
				}
			}
		}
		//
		//
		//

		// auth shit //
		if($this->usingAuth === true) {

			$removedPlayers = false;

			// join timelimits
			// find channel.
			$chan = unserialize($this->dataArray['msgTargetChannels']);
			$chan = $chan[0];

			// now check for players that should be in the PUG but failed to join
			// and issue them with a 2 hour ban
			foreach($this->authPlayers as $key => $player) {
				if(!isset($this->playerInfoArray[$player['steamid']])) {
					if(time() - $player['initialTime'] > self::$TIME_TO_JOIN) {
						// they are not in the pug after set join time and must DIE!
						$this->coreFuncs->rconCommand('banid 120 '.$player['steamid']);
						list($ident, $host) = explode('@', $player['host']);
						$this->coreFuncs->sendToIRC('CMDBAN:'.serialize(array('host' => '*!*@'.$host, 'length' => 7200, 'time' => time(), 'channel' => $chan, 'reason' => 'Failed to join PUG')));
						unset($this->authPlayers[$key]);
						$this->coreFuncs->rconCommand('say "'.$player['nick'].' Failed to join!"');

						$this->coreFuncs->sendToIRC('DECAUTH');

						if($this->usingAuthPlugin === true) {
							$this->coreFuncs->rconCommand('kbot_delid "'.$player['steamid'].'"');
						}

						$removedPlayers = true;
					}
				}
			}

			foreach($this->pendingAuth as $key => $player) {
				if(time() - $player['initialTime'] > self::$TIME_TO_JOIN) {
					// these people are NOT in the pug after set join time and must DIE!
					list($ident, $host) = explode('@', $player['host']);
					$this->coreFuncs->sendToIRC('CMDBAN:'.serialize(array('host' => '*!*@'.$host, 'length' => 7200, 'time' => time(), 'channel' => $chan, 'reason' => 'Failed to join/auth PUG')));
					$this->coreFuncs->rconCommand('say "'.$player['nick'].' Failed to join!"');
					unset($this->pendingAuth[$key]);

					$this->coreFuncs->sendToIRC('DECAUTH');

					if($this->usingAuthPlugin === true) {
						$this->coreFuncs->rconCommand('kbot_delauth '.$player['key']);
					}

					$removedPlayers = true;
				}
			}
			//

			// Shoud always be empty if using authPlugin...
			foreach($this->authPendingTimeout as $id => $data) {
				list($time, $name) = $data;
				if(time() - $time > self::$TIME_TO_AUTH) {
					$this->coreFuncs->rconCommand('kickid '.$id.' Failed to Auth!');
					//$this->coreFuncs->rconCommand('banid 1 '.$id);
					$this->coreFuncs->rconCommand('say "'.$name.' Failed to !auth"');
					unset($this->authPendingTimeout[$id]);

					$removedPlayers = true;
				}
			}

			// some players got perged, ask irc for some more players
			if($removedPlayers === true) {
				if(count($this->authPlayers) < $this->dataArray['playerCount']) {
					$needMore = $this->dataArray['playerCount'] - count($this->authPlayers);
					if(defined('SW_PLAYERNEEDED_AUTH')) {
						$str = buildSWSwting(SW_PLAYERNEEDED_AUTH, array($needMore));
						$this->coreFuncs->sendToIRC('MSG:'.$str);
					}
				}
			}
		}
		//
	}

	// handle when they change teams...
	function teamSelection($data)
	{
		if($data[3] == 'BOT') {
			return; // Ignore Bots
		}

		$from = chr(3).'05 from the Spectators';
		$team = chr(3).'05Spectators';

		if($data[4] == 'TERRORIST') $from = chr(3).'5 from the '.chr(3).'4Ts';
		elseif($data[4] == 'CT') $from = chr(3).'5 from the '.chr(3).'12CTs';

		if($data[5] == 'TERRORIST') $team = chr(3).'4Ts';
		elseif($data[5] == 'CT') $team = chr(3).'12CTs';

		if(defined('SW_PLAYERJOINTEAM')) {
			$str = buildSWSwting(SW_PLAYERJOINTEAM, array($data[1], $team, $from));
			$this->coreFuncs->sendToIRC('MSG:'.$str);
		}

		// set team
		$this->playerInfoArray[$data[3]]['team'] = $data[5];
	}


	function damageCount($data)
	{
		// only track damage if PUG is live.
		if($this->pugLive !== TRUE) return;

		// this will be the amount of damage done.
		$damage = $data[10];
		$attacker = $data[3];
		$target = $data[7];

		$this->playerInfoArray[$attacker]['dmgInflicted'] += $damage;
		$this->playerInfoArray[$target]['dmgRecived']   += $damage;
	}
	function kill($data)
	{
		// only track kills if the PUG is live
		if($this->pugLive !== TRUE) return;

		// keep track of kill's / Deaths here...
		$this->playerInfoArray[$data[3]]['kills']++;
		$this->playerInfoArray[$data[7]]['deaths']++;

		$gunArray = array('glock18'   => 'Glock',
		'usp'	  => 'USP',
		'p228'	  => 'Sig p228',
		'deagle'  => 'Desert Eagle',
		'elite'	  => 'Beretta Elites',
		'fiveseven' => 'Five Seven',
		'm3'	  => 'M3 Super ',
		'xm1014'  => 'XM Shotgun',
		'tmp'	  => 'Steyr TMP',
		'mac10'	  => 'Mac10',
		'mp5navy' => 'MP5 Navy',
		'ump45'	  => 'UMP',
		'p90'	  => 'FN P90',
		'm4a1'	  => 'Colt M4A1',
		'aug'	  => 'Steyr AUG',
		'famas'	  => 'Famas',
		'sg550'	  => 'Sig 550 Sniper',
		'galil'	  => 'Galil',
		'ak47'	  => 'AK-47',
		'scout'	  => 'Steyr Scout Sniper',
		'sg552'	  => 'SG552 Commando',
		'awp'	  => 'AWP Sniper',
		'g3sg1'	  => 'G3 SG-1 Sniper',
		'm249'	  => 'FN M249 PARA',
		'grenade' => 'HE Grenade',
		'knife'	  => 'Knife');

		// do TK stuff here.
		if($data[4] == $data[8]) $tk = TRUE;
		else $tk = FALSE;

		if($data[10] == ' (headshot)') $hs = TRUE;
		else $hs = FALSE;


		if($data[4] == 'CT') $killer = chr(3).'12'.$data[1] . chr(3).'05';
		elseif($data[4] == 'TERRORIST') $killer = chr(3).'04'.$data[1] . chr(3).'05';

		if($data[8] == 'CT') $target = chr(3).'12'.$data[5] . chr(3).'5';
		elseif($data[8] == 'TERRORIST') $target = chr(3).'04'.$data[5] . chr(3).'05';

		if(!$tk)
		{
			// find gun.
			if(!$gun = $gunArray[$data[9]]) $gun = $data[9];

			if($data[9] == 'knife' && defined('SW_KILL_KNIFED')) {
				$str = buildSWSwting(SW_KILL_KNIFED, array($killer, $target));
				$this->coreFuncs->sendToIRC('MSG:'.$str);
			}

			elseif($hs === TRUE && defined('SW_KILL_HEADSHOT')) {
				$str = buildSWSwting(SW_KILL_HEADSHOT, array($killer, $target, $gun));
				$this->coreFuncs->sendToIRC('MSG:'.$str);
			}
			elseif(defined('SW_KILL')) {
				$str = buildSWSwting(SW_KILL, array($killer, $target, $gun));
				$this->coreFuncs->sendToIRC('MSG:'.$str);
			}

			// send a message to the IRC bot if we are using AUTH to update each person's
			// K / D ratio
			if($this->usingAuth === true) {
				$this->coreFuncs->sendToIRC('ADDKILL:'.$data[3]);
				$this->coreFuncs->sendToIRC('ADDDEATH:'.$data[7]);
			}

		}
		else
		{
			$additional = '';
			// ok count the Team Kills! give them 3
			$this->teamKillCount[trim(strtoupper($data[3]))]++;
			if($this->teamKillCount[trim(strtoupper($data[3]))] == 1)
			{
				$this->coreFuncs->rconCommand('Say "'.$data[1].' Do Not Team Kill!"');
				$this->coreFuncs->rconCommand('Say "If you do this three more times you will be banned for 2 days"');
			}
			if($this->teamKillCount[trim(strtoupper($data[3]))] == 2)
			{
				$this->coreFuncs->rconCommand('Say "'.$data[1].' Do Not Team Kill!"');
				$this->coreFuncs->rconCommand('Say "If you do this two more times you will be banned for 2 days"');
			}
			if($this->teamKillCount[trim(strtoupper($data[3]))] == 3)
			{
				$this->coreFuncs->rconCommand('Say "'.$data[1].' Do Not Team Kill!"');
				$this->coreFuncs->rconCommand('Say "Last warning. If you do this Once more you will be banned for 2 days"');
			}
			if($this->teamKillCount[trim(strtoupper($data[3]))] == 4)
			{
				$additional = chr(2). ' Player has now been gifted a 2 day BAN!!!';
				$chan = unserialize($this->dataArray['msgTargetChannels']);
				$chan = $chan[0];
				// 2 day ban.
				$this->coreFuncs->rconCommand('banid 2880 '.$data[3]);
				$this->coreFuncs->rconCommand('kickid '.$data[3] .' Team killing!');
				$host = '';
				if($this->usingAuth === true) {
					foreach($this->authPlayers as $key => $player) {
						if($player['steamid'] == $data[3]) {
							list($ident, $host) = explode('@', $player['host']);
							break;
						}
					}
				}
				if($host =='') {
					$host = gethostbyaddr($this->playerInfoArray[$data[3]]['ip']);
				}
				// double check host is set.
				if($host != '') $this->coreFuncs->sendToIRC('CMDBAN:'.serialize(array('host' => '*!*@'.$host, 'length' => 172800, 'time' => time(), 'channel' => $chan, 'reason' => 'You have been banned from Pugging for 2 days by vote')));
			}

			if(defined('SW_TEAMKILL')) {
				$str = buildSWSwting(SW_TEAMKILL, array($killer, $target, $additional));
				$this->coreFuncs->sendToIRC('MSG:'.$str);
			}
		}
	}

	function playerAction($data)
	{
		// only find the action if the PUG is live.
		if($this->pugLive !== TRUE) return;

		// find the action...
		switch($data[5])
		{
			case 'Dropped_The_Bomb':
				if(defined('SW_BOMB_DROP')) {
					$str = buildSWSwting(SW_BOMB_DROP, array($data[1]));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}
				break;
			case 'Got_The_Bomb':
				if(defined('SW_BOMB_GOT')) {
					$str = buildSWSwting(SW_BOMB_GOT, array($data[1]));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}
				break;
			case 'Spawned_With_The_Bomb':
				if(defined('SW_BOMB_SPAWNEDWITH')) {
					$str = buildSWSwting(SW_BOMB_DROP, array($data[1]));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}
				break;
			case 'Planted_The_Bomb':
				if(defined('SW_BOMB_PLANTED')) {
					$str = buildSWSwting(SW_BOMB_PLANTED, array($data[1]));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}
				break;
			case 'Begin_Bomb_Defuse_With_Kit':
				if(defined('SW_BOMB_DEFUSEWKIT')) {
					$str = buildSWSwting(SW_BOMB_DEFUSEWKIT, array($data[1]));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}
				break;
			case 'Defused_The_Bomb':
				if(defined('SW_BOMB_DEFUSED')) {
					$str = buildSWSwting(SW_BOMB_DEFUSED, array($data[1]));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}
				break;
			case 'Begin_Bomb_Defuse_Without_Kit':
				if(defined('SW_BOMB_DEFUSE')) {
					$str = buildSWSwting(SW_BOMB_DEFUSE, array($data[1]));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}
				break;
		}
	}

	function say($data)
	{
		// get the details.
		$name    = 	$data[1];
		$uid     =	$data[2];
		$steamID = 	$data[3];
		$team    = 	$data[4];
		$message = 	trim($data[5]);
		if(!$this->matchAdminSteamID)
		{
			if($message == '!admin '.$this->dataArray['adminPassword'])
			{
				$this->matchAdminSteamID = $steamID;
				$this->coreFuncs->rconCommand('say "PUG Admin given to '.$name.'"');
			}
		}
		elseif($steamID == $this->matchAdminSteamID)
		{
			//admin access here
			// lo3 command :o
			if($message == '!lo3' || $message == '!restart')
			{
				if($this->pugLive !== TRUE && $this->halfCount < 2)
				{

					if(count($this->pendingAuth) > 0) {
						$this->coreFuncs->rconCommand('say "Ignoring !lo3, Not all players Authed!"');
					}

					// reset now.
					$this->resetPlayerInfoArray();


					$this->pugLive = TRUE;
					$this->halfCount++;
					$this->roundsPlayed = 0;

					if($this->halfCount == 1) {
						$this->coreFuncs->rconCommand('say "Starting first half"');
						$this->scoreT = 0;
						$this->scoreCT = 0;
					}
					if($this->halfCount == 2) {
						$this->coreFuncs->rconCommand('say "Starting second half"');
						$this->scoreT = $this->scoreTFirstHalf;
						$this->scoreCT = $this->scoreCTFirstHalf;
					}

					$this->coreFuncs->rconCommand('mp_restartgame 1');
					sleep(1);
					$this->coreFuncs->rconCommand('mp_restartgame 1');
					sleep(1);
					$this->coreFuncs->rconCommand('mp_restartgame 3');
					$this->coreFuncs->rconCommand('say "PUG live, GL HF"');

					if($this->halfCount == 1 && defined('SW_FIRSTHALF_START')) {
						$str = buildSWSwting(SW_FIRSTHALF_START, array());
						$this->coreFuncs->sendToIRC('MSG:'.$str);
					}
					if($this->halfCount == 2 && defined('SW_SECONDHALF_START')) {
						$str = buildSWSwting(SW_SECONDHALF_START, array());
						$this->coreFuncs->sendToIRC('MSG:'.$str);
					}
				}

				elseif($this->halfCount <= 2)
				{
					// reset now.
					$this->resetPlayerInfoArray();

					// restart this half.
					$this->roundsPlayed = 0;

					if($this->halfCount == 1) {
						$this->coreFuncs->rconCommand('say "Restarting the first half"');
						$this->scoreT = 0;
						$this->scoreCT = 0;
					}
					if($this->halfCount == 2) {
						$this->coreFuncs->rconCommand('say "Restarting the second half"');
						$this->scoreT = $this->scoreTFirstHalf;
						$this->scoreCT = $this->scoreCTFirstHalf;
					}

					$this->coreFuncs->rconCommand('mp_restartgame 1');
					sleep(1);
					$this->coreFuncs->rconCommand('mp_restartgame 1');
					sleep(1);
					$this->coreFuncs->rconCommand('mp_restartgame 3');
					$this->coreFuncs->rconCommand('say "PUG live, GL HF"');

					if($this->halfCount == 1 && defined('SW_FIRSTHALF_RESTART')) {
						$str = buildSWSwting(SW_FIRSTHALF_START, array());
						$this->coreFuncs->sendToIRC('MSG:'.$str);
					}
					if($this->halfCount == 2 && defined('SW_SECONDHALF_RESTART')) {
						$str = buildSWSwting(SW_SECONDHALF_START, array());
						$this->coreFuncs->sendToIRC('MSG:'.$str);
					}
				}
			}

			else if(substr($message,0,4) == '!irc') {
				if(defined('SW_IRCMESSAGE')) {
					$str = buildSWSwting(SW_IRCMESSAGE, array(substr($message,5)));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}
			}
			else if(substr($message,0,9) == '!password')
			{
				// change pass
				$this->dataArray['sv_password'] = substr($message,10);
				$this->coreFuncs->rconCommand('say "'.$name.' Has changed the server\'s password to '.$this->dataArray['sv_password'].'"');
				$this->coreFuncs->rconCommand('sv_password '.$this->dataArray['sv_password']);
				$this->coreFuncs->sendToIRC('PASSWD:'.$this->dataArray['sv_password']);

			}
			else if(substr($message,0,5) == '!kick') $this->coreFuncs->rconCommand('kick "'.substr($message,6).'"');
			else if($message == '!killpug' || $message == '!endpug')
			{
				if($this->endingProc === true) return; // we are already ending, 2nd round has finished

				if(defined('SW_END_ADMINCOMMAND')) {
					$str = buildSWSwting(SW_END_ADMINCOMMAND, array());
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}

				$this->coreFuncs->rconCommand('say "PUG Ending due to admin command."');
				// ok we want to end the game here..
				$this->endingProcess = TRUE;

				// give report on all players.
				$this->playerReport();

				$this->coreFuncs->sendToIRC('CMD:ENDPUG');
			}
			else if(substr($message,0,4) == '!say')
			{
				$this->coreFuncs->rconCommand('say " Message From '.$name.':"');
				$this->coreFuncs->rconCommand('say "'.substr($message,5).'"');
			}
			else if(substr($message,0,4) == '!map')
			{
				// ok check that this is a valid map...
				if(in_array(substr($message,5),$this->dataArray['maps']))
				{
					// ok lets change the map
					$this->coreFuncs->rconCommand('say "'.$name.' is changing map to '.substr($message,5).'"');
					$this->coreFuncs->rconCommand('changelevel '.substr($message,5));
					// reset the players count, because everyone will become disconnected
					$this->playerCount = 0;
					$this->serverStartTime = time();
					$this->graceTimeCheck = false;
					$this->playerInfoArray = array();
					sleep(2);
					// make sure the password is set..
					$this->coreFuncs->rconCommand('sv_password "'.$this->dataArray['sv_password'].'"');

					// ok reset rounds and everything!
					$this->pugLive = FALSE;
					$this->halfCount = 0;
					$this->roundsPlayed = 0;

					// set hit the count to false, as the server has to fill up again
					$this->hitTheCount = FALSE;

					// also exec to irc making the bot change the topic with the new map and
					// also the info in the variables..
					// and also notify the ppl in channel of the change :)
					$this->coreFuncs->sendToIRC('CMD:CNGMAP:'.trim(substr($message,5)));

					// reset the initial times of everyone!
					// so they dont get kicked for non join :)
					foreach($this->authPlayers as $key => $player) {
						$this->authPlayers[$key]['initialTime'] = time();
					}

					foreach($this->pendingAuth as $key => $player) {
						$this->pendingAuth[$key]['initialTime'] = time();
					}

				}
				else $this->coreFuncs->rconCommand('say "'.substr($message,5) .' Is an invalid map!"');
			}
			else if(substr($message,0,4) == '!get')
			{
				if ($this->playerCount < $this->dataArray['playerCount'])
				{
					$needMore = $this->dataArray['playerCount'] - $this->playerCount;
					$this->coreFuncs->rconCommand('say "Requested '.$needMore.' more player'.(($needMore > 1) ? 's':'').' on irc."');

					if($this->usingAuth === true) {
						if(defined('SW_REQUESTPLAYERS_AUTH')) {
							$str = buildSWSwting(SW_REQUESTPLAYERS_AUTH, array($needMore));
							$this->coreFuncs->sendToIRC('MSG:'.$str);
						}
					}
					else {
						if(defined('SW_REQUESTPLAYERS')) {
							$str = buildSWSwting(SW_REQUESTPLAYERS, array($needMore, $this->dataArray['sv_password']));
							$this->coreFuncs->sendToIRC('MSG:'.$str);
						}
					}
				}
				else $this->coreFuncs->rconCommand('say "PUG is full, not requesting players."');
			}
		}

		// normal commands.
		if(substr($message,0,8) == '!voteban')
		{
			$voterSteamID = $steamID;
			$tmp = trim(strtoupper(substr($message,9))); // what the user supplied.
			// if this is a steam id (STEAM_0:1:1234567)
			if(preg_match('/^STEAM_[0-9]{1}:[0-9]{1}:[0-9]+$/', $tmp))
			$voteTargetsteamID = $tmp;
			else {
				// try and find them.
				// if we come out with one match we can match them.. otherwise complain they need to be more specific.
				$matched = 0;
				foreach($this->playerInfoArray as $steamID => $playerData)
				{
					if(stristr($playerData['name'], $tmp))
					{
						// found a match
						$voteTargetsteamID = $steamID;
						$matched++;
					}
				}
				if($matched == 0)
				{
					$this->coreFuncs->rconCommand('say "Sorry no match found for that name"');
					return;
				} else if($matched > 1)
				{
					$this->coreFuncs->rconCommand('say "Sorry you will have to be more specific"');
					return;
				}
			}

			// general purpose voting commands...
			if(!$this->voters[$voteTargetsteamID][$voterSteamID] && $this->playerInfoArray[$voteTargetsteamID])
			{
				// we have it, add a vote to this STEAM ID and IP
				$this->votes[$voteTargetsteamID]++;
				$this->voters[$voteTargetsteamID][$voterSteamID] = TRUE;
				$this->coreFuncs->rconCommand('say "'.$this->votes[$voteTargetsteamID].'/'.(ceil($this->dataArray['playerCount'] / 2)) .' votes lodged for '.$this->playerInfoArray[$voteTargetsteamID]['name'].'"');
				if($this->votes[$voteTargetsteamID] >= ceil($this->dataArray['playerCount'] / 2))
				{
					// find channel.
					$chan = unserialize($this->dataArray['msgTargetChannels']);
					$chan = $chan[0];
					// 2 day ban.
					$this->coreFuncs->rconCommand('banid 2880 '.$voteTargetsteamID);
					$this->coreFuncs->rconCommand('kickid '. $voteTargetsteamID .' !voteban Succeeded');

					$host = '';
					if($this->usingAuth === true) {
						foreach($this->authPlayers as $key => $player) {
							if($player['steamid'] == $voteTargetsteamID) {
								list($ident, $host) = explode('@', $player['host']);
								break;
							}
						}
					}
					if($host == '') {
						$host = gethostbyaddr($this->playerInfoArray[$voteTargetsteamID]['ip']);
					}

					// double check host is set.
					if($host != '') $this->coreFuncs->sendToIRC('CMDBAN:'.serialize(array('host' => '*!*@'.$host, 'length' => 172800, 'time' => time(), 'channel' => $chan, 'reason' => 'You have been banned from Pugging for 2 days by vote')));
					// ok ban on server, kick, and irc
					//array('host' => '*!*@'.$data->host, 'time' => time(), 'channel' => $data->channel)
				}
			}
		}
		else if($message == '!teams')
		{
			// display the teams CT's and T's
			foreach($this->teamRemindLines as $element)
			{
				$this->coreFuncs->rconCommand('say "'.$element.'"');
			}
		}
		else if($this->usingAuth && substr($message,0,6) == '!auth ') {
			$key = trim(strtolower(substr($message,6)));

			// trim aint killling the carrige return, so do it
			// here so we can paste straight into console!
			$key = str_replace(chr(15), '', $key);

			//$this->coreFuncs->rconCommand('say "Authing to \''.$key.'\'"');

			foreach($this->pendingAuth as $k => $e) {
				//$this->coreFuncs->rconCommand('say "Cmp to \''.$e['key'].'\'"');
				if(strcasecmp($e['key'], $key) === 0) {
					$this->coreFuncs->sendToIRC('CMDAUTH:'.serialize(array('hostmask' => $e['host'], 'steamid' => $steamID)));
					$this->coreFuncs->rconCommand('say '.$name.' Auth\'ed to '. $e['nick']);
					unset($this->pendingAuth[$k]);
					unset($this->authPendingTimeout[$steamID]);
					$this->authPlayers[] = array('host' => $e['host'], 'steamid' => $steamID, 'nick'=> $e['nick'], 'initialTime' => $e['initialTime']);

					if($this->adminAuthDetails['type'] == 'code') {
						if(strcmp($key, $this->adminAuthDetails['code']) == 0) {
							$this->matchAdminSteamID = $steamID;
							$this->coreFuncs->rconCommand('say "PUG Admin given to '.$name.'"');
						}
					}
				}
			}
		}
		else if(substr($message, 0, 7) == '!whois ') {
			$tmp = trim(substr($message, 7));
			$matchedName = $tmp;
			if(preg_match('/^STEAM_[0-9]{1}:[0-9]{1}:[0-9]+$/', $tmp)) {
				$targetsteamID = $tmp;
				$matchedName = $tmp;
			}
			else {
				$matched = 0;
				$matchedName = $tmp;
				foreach($this->playerInfoArray as $steamID => $playerData)
				{
					if(stristr($playerData['name'], $tmp))
					{
						// found a match
						$matchedName = $playerData['name'];
						$targetsteamID = $steamID;
						$matched++;
						if(strcasecmp($playerData['name'], $tmp) == 0) {
							// always match an exact match
							$matched = 1;
							$matchedName = $playerData['name'];
							break;
						}
					}
				}
				if($matched == 0)
				{
					$this->coreFuncs->rconCommand('say "Sorry no match found for that name"');
					return;
				} else if($matched > 1)
				{
					$this->coreFuncs->rconCommand('say "Sorry you will have to be more specific"');
					return;
				}
			}
			foreach($this->authPlayers as $player) {
				if($player['steamid'] == $targetsteamID) {
					$this->coreFuncs->rconCommand('say "'.$matchedName.' is '.$player['nick'].' in irc."');
					return;
				}
			}
			$this->coreFuncs->rconCommand('say "Player not yet Authed!"');
			return;
		}
		else if(strcasecmp($message, '!whoisadmin') === 0) {
			if($this->matchAdminSteamID != null) {
				if(isset($this->playerInfoArray[$this->matchAdminSteamID])) {
					$this->coreFuncs->rconCommand('say "PUG Admin is '.$this->playerInfoArray[$this->matchAdminSteamID]['name'].'"');
					return;
				}
			}
			$this->coreFuncs->rconCommand('say "No Admin Identified"');
		}
		else if(strcasecmp($message, '!scores') === 0) {
			$this->coreFuncs->rconCommand('say "CT\'s have '.$this->scoreCT.' need '. ($this->roundsToBePlayed - $this->scoreCT + 1) .' to win!"');
			$this->coreFuncs->rconCommand('say "T\'s have '.$this->scoreT.' need '. ($this->roundsToBePlayed - $this->scoreT + 1) .' to win!"');
		}
	}

	function roundEnd($data)
	{
		// ok only go further if we are in a LIVE half :)
		if($this->pugLive === TRUE)
		{
			if($data[4] != '') {
				// ok this means a team one its not a WORLD action, so get our info
				$team = $data[1];
				$triggered = $data[2];
				$ctScore = $data[3];
				$tScore = $data[4];
			}
			else
			{
				// its a WORLD action, so get our indo
				$team = NULL;
				$triggered = $data[1];
				$ctScore = $data[2];
				$tScore = $data[3];

				if($triggered == 'Game_Commencing') break;
			}

			// increment values
			$this->roundsPlayed++;

			// ok were goin to report the details about this round back to irc :o
			switch($triggered) {
				case 'Terrorists_Win':
					$winner = chr(3).'4Ts won'.chr(3);
					$this->scoreT++;
					break;
				case 'Target_Bombed':
					$winner = chr(3).'4Ts Bombed Target'.chr(3);
					$this->scoreT++;
					break;
				case 'CTs_Win':
					$winner = chr(3).'12CTs won'.chr(3);
					$this->scoreCT++;
					break;
				case 'Bomb_Defused':
					$winner = chr(3).'12CTs Defused Bomb'.chr(3);
					$this->scoreCT++;
					break;
				case 'Round_Draw':
					$winner = 'Round Drawn';
					break;
				case 'Target_Saved':
					$winner = 'CTs Saved Target';
					$this->scoreCT++;
					break;
				default:
					$winner = ' ('.$triggered.')';
					break;
			}

			if(defined('SW_ROUND_END')) {
				$str = buildSWSwting(SW_ROUND_END, array($this->roundsPlayed, $this->roundsToBePlayed, $winner, $ctScore, $tScore));
				$this->coreFuncs->sendToIRC('MSG:'.$str);
			}

			// in the rounds played for the BOT's stats :)
			$this->coreFuncs->sendToIRC('CMD:RNDREP');

			// scores takes integers as paramaters in the form of team1 team2...
			// it will then report on progress on irc on a !scores command
			$this->coreFuncs->sendToIRC('CMD:SCORES '.$this->scoreT.' '.$this->scoreCT);

			// check if this is a swap round, if so enforce the mutha fucka! :)
			if($this->roundsPlayed == $this->roundsToBePlayed && $this->endingProc !== TRUE && $this->halfCount < 2)
			{

				// save it for lo3!
				// - Remember this is the SWAPED Version!!! Because teams swap :)
				$this->scoreTFirstHalf = $this->scoreCT;
				$this->scoreCTFirstHalf = $this->scoreT;

				$results = '';

				if($this->scoreCT > $this->scoreT)
				{
					$this->coreFuncs->rconCommand('say "First Half Completed. Counter-Terrorists Win '.$this->scoreCT.' to '.$this->scoreT.'"');
					$this->coreFuncs->rconCommand('say "Please switch to the opposite team"');
					$results = chr(2).'First half completed. '.chr(3).'12Counter-Terrorists'.chr(3).'05 Win'.chr(3).'12 '.$this->scoreCT . chr(3) .'05 to'. chr(3) .'4 '. $this->scoreT. chr(3);
				}
				elseif($this->scoreT > $this->scoreCT)
				{
					$this->coreFuncs->rconCommand('say "First Half Completed. Terrorists Win '.$this->scoreT.' to '.$this->scoreCT.'"');
					$this->coreFuncs->rconCommand('say "Please switch to the opposite team"');
					$results = chr(2).'First half completed. '.chr(3).'4Terrorists'.chr(3).'05 Win'.chr(3).'4 '.$this->scoreT . chr(3) .'05 to'. chr(3) .'12 '. $this->scoreCT. chr(3);
				}
				else {
					$this->coreFuncs->rconCommand('say "First Half Completed. Teams Drawn '.$this->scoreCT.' to '.$this->scoreT.'"');
					$this->coreFuncs->rconCommand('say "switch to the opposite team"');
					$results = chr(2).'First half completed. Teams Drawn'.chr(3).'12 '.$this->scoreCT . chr(3) .'05 to'. chr(3) .'4 '. $this->scoreT. chr(3);
				}

				if(defined('SW_HALFCOMPLETED') && $results) {
					$str = buildSWSwting(SW_HALFCOMPLETED, array($results));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}

				// give report on all players.
				$this->playerReport();

				$this->pugLive = FALSE;
				$this->coreFuncs->rconCommand('say "When eveyone has swapped the PUG admin should type !lo3"');
			}
			// check if that was final round.
			else if(($this->scoreCT > $this->roundsToBePlayed || $this->scoreT > $this->roundsToBePlayed || $this->roundsPlayed >= $this->roundsToBePlayed) && $this->halfCount >= 2 && $this->endingProc !== TRUE)
			{
				$this->countTillEnd = time();
				$this->endingProc = TRUE;
				$this->pugLive = FALSE;

				// increment over 3 so we cant !lo3
				$this->halfCount++;

				$results = '';

				// find and report on winning side for Half.
				if($this->scoreCT > $this->scoreT)
				{
					$this->coreFuncs->rconCommand('say "Second half completed. Counter-Terrorists Win '.$this->scoreCT.' to '.$this->scoreT.'"');
					$results = chr(2).'Second half completed. '.chr(3).'12Counter-Terrorists'.chr(3).'05 Win'.chr(3).'12 '.$this->scoreCT .chr(3).'05 to'. chr(3) .'4 '. $this->scoreT. chr(3);
				}
				elseif($tScore > $ctScore)
				{
					$this->coreFuncs->rconCommand('say "Second half completed. Terrorists Win '.$this->scoreT.' to '.$this->scoreCT.'"');
					$results = chr(2).'Second half completed. '.chr(3).'4Terrorists'.chr(3).'05 Win'.chr(3).'4 '.$this->scoreT . chr(3) .'05 to'. chr(3) .'12 '. $this->scoreCT. chr(3);
				}
				else {
					$this->coreFuncs->rconCommand('say "Second half completed. Teams Drawn '.$this->scoreCT.' to '.$this->scoreT.'"');
					$results = chr(2).'Second half completed. Teams Drawn'.chr(3).'12 '.$this->scoreCT . chr(3) .'05 to'. chr(3) .'4 '. $this->scoreT. chr(3);
				}

				if(defined('SW_HALFCOMPLETED') && $results) {
					$str = buildSWSwting(SW_HALFCOMPLETED, array($results));
					$this->coreFuncs->sendToIRC('MSG:'.$str);
				}

				// ok, done that.

				// give report on all players.
				$this->playerReport();

				// server will end in 30 seconds :o
				$this->coreFuncs->rconCommand('say "PUG Finished, Closing Down in 10 seconds..."');
				$this->coreFuncs->rconCommand('sv_restart 1');
				sleep(1);
				$this->coreFuncs->rconCommand('sv_restart 1');
				sleep(1);
				$this->coreFuncs->rconCommand('sv_restart 3');
			}
			else {
				$this->coreFuncs->rconCommand('say "CT\'s have '.$this->scoreCT.' need '. ($this->roundsToBePlayed - $this->scoreCT + 1) .' to win!"');
				$this->coreFuncs->rconCommand('say "T\'s have '.$this->scoreT.' need '. ($this->roundsToBePlayed - $this->scoreT + 1) .' to win!"');
			}
		}
	}

	function playerReport()
	{
		// this array will contain the maximum length of each field for the purpose of tabbing.
		$maxLengthArray = array('name' => 4, 'killsDeathsRatioStr' => 10, 'damage' => 6,);

		foreach($this->playerInfoArray as $steamID => $array)
		{
			$name = $array['name'];
			$team = $array['team'];
			$kills = $array['kills'] ? $array['kills'] : 0;
			$deaths = $array['deaths'] ? $array['deaths'] : 0;
			$damageInflicted = $array['dmgInflicted'] ? $array['dmgInflicted'] : 0;
			$damageRecived   = $array['dmgRecived'] ? $array['dmgRecived'] : 0;
			if($deaths > 0) $ratio = round($kills/$deaths,2).':1';
			else $ratio = $kills.':0';


			// now formulate this into a nice block.
			$presentationArray[$steamID]['team'] = $array['team'];

			// truncate the name if over 15
			if(strlen($name) > 15) {
				$name = substr($name, 0, 12).'...';
			}

			$presentationArray[$steamID]['name'] = $name;
			if(strlen($name) > $maxLengthArray['name']) $maxLengthArray['name'] = strlen($name);

			$presentationArray[$steamID]['killsDeathsRatioStr'] = $kills.'-'.$deaths.' ('.$ratio.')';

			if(strlen($presentationArray[$steamID]['killsDeathsRatioStr']) > $maxLengthArray['killsDeathsRatioStr'])
			$maxLengthArray['killsDeathsRatioStr'] = strlen($presentationArray[$steamID]['killsDeathsRatioStr']);

			$presentationArray[$steamID]['damage'] = $damageInflicted.'-'.$damageRecived;
			if(strlen($presentationArray[$steamID]['damage']) > $maxLengthArray['damage'])
			$maxLengthArray['damage'] = strlen($presentationArray[$steamID]['damage']);
		}

		if(defined('SW_PLAYERREPORT')) {
			$str = buildSWSwting(SW_PLAYERREPORT, array(sprintf('%-'.($maxLengthArray['name']).'s', 'Name'),
			sprintf('%-'.$maxLengthArray['killsDeathsRatioStr'].'s',  'Score(K/D)'),
			sprintf('%-'.$maxLengthArray['damage'].'s',  'Damage')));
			$this->coreFuncs->sendToIRC('MSG:'.$str);
		}

		foreach($presentationArray as $array)
		{
			if($array['team'] == 'CT') $colour = chr(3).'12';
			elseif($array['team'] == 'TERRORIST') $colour = chr(3).'04';
			else $colour = chr(3).'01';

			if(defined('SW_PLAYERREPORT')) {
				$str = buildSWSwting(SW_PLAYERREPORT, array($colour .  sprintf('%-'.($maxLengthArray['name']).'s', $array['name']),
				sprintf('%-'.$maxLengthArray['killsDeathsRatioStr'].'s',  $array['killsDeathsRatioStr']),
				sprintf('%-'.$maxLengthArray['damage'].'s',  $array['damage'])));
				$this->coreFuncs->sendToIRC('MSG:'.$str);
			}
		}
	}

	function resetPlayerInfoArray()
	{
		$keys = array_keys($this->playerInfoArray);

		for($i=0;$i<count($keys);$i++)
		{
			$this->playerInfoArray[$keys[$i]]['kills'] = 0;
			$this->playerInfoArray[$keys[$i]]['deaths'] = 0;
			$this->playerInfoArray[$keys[$i]]['dmgInflicted'] = 0;
			$this->playerInfoArray[$keys[$i]]['dmgRecived'] = 0;
		}
	}

	public function authChangeNick($to, $from) {

		foreach($this->authPlayers as $key => $player) {
			if(strcasecmp($player['nick'], $from) === 0) {
				$this->authPlayers[$key]['nick'] = $to;
			}

		}

		foreach($this->pendingAuth as $key => $player) {
			if(strcasecmp($player['nick'], $from) === 0) {
				$this->pendingAuth[$key]['nick'] = $to;
			}
		}
	}

	public function addPendingAuthPlayer($array) {
		$this->pendingAuth[] = $array;
		if($this->usingAuth === true) {
			$this->coreFuncs->sendToIRC('INCAUTH');
		}
		if($this->usingAuth === true && $this->usingAuthPlugin === true) {
			$this->coreFuncs->rconCommand('kbot_addauth '.$array['key']);
		}
	}

	public function addAuthedPlayer($array) {
		$this->authPlayers[] = $array;
		if($this->usingAuth === true) {
			$this->coreFuncs->sendToIRC('INCAUTH');
		}
		if($this->usingAuth === true && $this->usingAuthPlugin === true) {
			$this->coreFuncs->rconCommand('kbot_addid "'.$array['steamid'].'"');
		}
	}
}
?>
Return current item: Kbot