Location: PHPKode > projects > Zitro-Stats > update.php
<?php

	$starttime = time();

	header("Pragma: no-cache");
	header("Expires: 0");
	header("Content-type: text/plain");

	define('INSTATS',true);
	define('UPDATE',true);
	require('include/global.inc.php');

	fechoheader();

	@set_time_limit(0);
	ignore_user_abort(1);
 
	////////////////////////////////////////////////////////////////
	// PLAYER'S CLASS
	class Player {
		var $opponents		= array();
		var $killweapons	= array();
		var $deathweapons	= array();

		function Player($name) {
			global
				$sql,
				$options,
				$players,
				$opponents,
				$clantags,
				$clantagsdel;
			// IF PLAYER INFO IN DB
			if(list($this->clan, $this->points, $this->kills, $this->deaths, $this->selfkills, $this->last) = $sql->fetchrow($sql->query("
				SELECT
					`clan`,
					`points`,
					`kills`,
					`deaths`,
					`selfkills`,
					`last`
				FROM `$options[SQL_TABPREFIX]players`
				WHERE `player`='".$sql->escape($name)."'
				LIMIT 1
				"))) {

				// IF OPPONENTS GET ALL KILLER-VICTIM-RELATIONS WHERE PLAYER AND OPPONENT ARE KNOWN
				if(count($opponents)) {
					$result = $sql->query("
						SELECT
							`player`,
							`opponent`,
							`kills`,
							`last`
						FROM `$options[SQL_TABPREFIX]playeropponents`
						WHERE (`player`='".$sql->escape($name)."' AND `opponent` IN('".implode("','",$opponents)."'))
						OR (`opponent`='".$sql->escape($name)."' AND `player` IN('".implode("','",$opponents)."'))
						");
					while($row = $sql->fetchrow($result))
						$players[$row[0]]->opponents[$row[1]] = array($row[2],$row[3]);
				}

				// GET PLAYER'S KILLWEAPONS
				$result = $sql->query("
					SELECT `weapon`,`kills`,`last`
					FROM `$options[SQL_TABPREFIX]playerkillweapons`
					WHERE `player`='".$sql->escape($name)."'
					");
				while($row = $sql->fetchrow($result))
					$this->killweapons[$row[0]] = array($row[1],$row[2]);

				// GET PLAYER'S DEATHWEAPONS
				$result = $sql->query("
					SELECT `weapon`,`deaths`,`last`
					FROM `$options[SQL_TABPREFIX]playerdeathweapons`
					WHERE `player`='".$sql->escape($name)."'
					");
				while($row = $sql->fetchrow($result))
					$this->deathweapons[$row[0]] = array($row[1],$row[2]);
			// CREATE NEW PLAYER
			} else {
				if($clantagsdel==-1) load_clantags();
				$this->clan			= '';
				$this->points		= 1000;
				$this->kills		= 0;
				$this->deaths		= 0;
				$this->selfkills	= 0;
				$this->last			= '0000-00-00 00:00:00';
				foreach($clantags as $index=>$regex) {
					if(preg_match($regex,$name,$matches)) {
						$this->clan = $index<$clantagsdel ? '' : $matches[1];
						break;
					}
				}
			}

			// ADD PLAYER TO OPPONENTS LIST
			$opponents[] = $sql->escape($name);
		}
	}

	////////////////////////////////////////////////////////////////
	// WEAPON'S CLASS
	class Weapon {
		var $kills;
		var $last;
		var $type;

		function Weapon($kills=0,$last='0000-00-00 00:00:00',$type=4) {
			$this->kills	= $kills;
			$this->last		= $last;
			$this->type		= $type;
		}
	}

	// KILLLOG: MAX BYTES OF A KILL IN LOG (23B DATE + 2x 24B PLAYERS + 14B WEAPON + 4x 1B NEWLINE)
	define("KILLLOG_MAXBYTES",89);
	// KILLLOG: READ-BUFFER
	define("KILLLOG_BUFFER",1024);
	// KILLLOG: REGEX PATTERN FOR PARSING
	define("KILLLOG_PREG",'/'.
		'--- ((\d{2,4}[\-\/](?:0[1-9]|1[0-2])[\-\/](?:0[1-9]|[1-2][0-9]|3[0-1])) ((?:[0-1][0-9]|2[0-3]))[:\.](?:[0-5][0-9])[:\.](?:[0-5][0-9]))(?:\r?\n)+'.
		'((?!--- \d{2,4}[\-\/]\d{2}[\-\/]\d{2} \d{2}[:\.]\d{2}[:\.]\d{2})(?U)[^\r\n]{1,24})(?:(?<!\s)\([1-9][0-9]*\))?(?:\r?\n)+'.
		'((?!--- \d{2,4}[\-\/]\d{2}[\-\/]\d{2} \d{2}[:\.]\d{2}[:\.]\d{2})(?U)[^\r\n]{1,24})(?:(?<!\s)\([1-9][0-9]*\))?(?:\r?\n)+'.
		'(Ak\-74|Barret M82A1|Barrett M82A1|Bow|Chainsaw|Clusters|Combat Knife|Desert Eagles|FN Minimi|Flame Bow|Flamer|Grenade|HK MP5|Hands|LAW|M79|Ruger 77|Spas\-12|Stationary gun|Steyr AUG|USSOCOM|XM214 Minigun|Selfkill)?(?:\r?\n)+'.
		'/');

	////////////////////////////////////////////////////////////////
	// KILLLOG'S CLASS
	class Killlog {
		function Killlog($server,$log,$file,$offset=0,$http=0) {
			$this->server	= $server;			// SERVER
			$this->log		= $log;				// NAME OF LOG
			$this->file		= $file;			// LOCAL PATH AND NAME OF FILE
			$this->size		= filesize($file);	// FILE SIZE
			$this->offset	= $offset;			// PARSING OFFSET
			$this->complete	= $offset;			// PARSING COMPLETED OFFSET
			$this->http		= $http;			// TIMESTAMP FOR HTTP FILES
			$this->actions	= 0;
			$this->buffer	= '';

			$this->fp =  fopen($this->file,'rb');
			if($offset) fseek($this->fp,$offset);

			$this->buffer();
			$this->parsenext();
		}

		function buffer() {
			// CURRENT SIZE OF BUFFER
			$buffsize = strlen($this->buffer);

			// BYTES OF OLD BUFFER TO REUSE IN NEW BUFFER:
			// NUMBER OF BYTES THAT LONGEST POSSIBLE KILL OCCUPIES OR
			// BYTES BETWEEN LAST PARSED KILL AND END OF OLD BUFFER
			$buffre = min(KILLLOG_MAXBYTES, $buffsize);

			// SET PARSING OFFSET
			$this->complete = $this->offset += $buffsize - $buffre;

			// BUFFER NOT MORE BYTES THAN SPECIFIED AS BUFFER SIZE LIMIT OR FILE SIZE
			$buffnew = min(KILLLOG_BUFFER - $buffre, $this->size - $this->offset + $buffre);
			if($buffnew<=0) return false;

			// READ AND STOP ON ERROR
			if(!$read = fread($this->fp, $buffnew)) return false;

			// SET NEW BUFFER
			$this->buffer =
				// UNPARSED BYTES OF OLD BUFFER
				($buffsize ? substr($this->buffer, $buffsize - $buffre) : '').
				// CONCATED WITH NEW BYTES FROM FILE
				$read;

			return true;
		}

		function parsenext() {
			// SAVE CURRENT OFFSET AS OLD OFFSET
			$this->complete = $this->offset;
			// READ ON WHILE NO KILLS PARSEABLE IN BUFFER
			while(!preg_match(KILLLOG_PREG, $this->buffer, $matches) || count($matches)<6) {
				// STOP WHEN FILE IS READ OUT COMPLETELY
				if(!$this->buffer()) {
					unset($this->current);
					return false;
				}
			}
			$this->actions++;
			// BUFFER AND OFFSET
			$this->offset = strpos($this->buffer, $matches[0]) + strlen($matches[0]);	// FIND MATCH IN BUFFER
			$this->buffer = substr($this->buffer, $this->offset);						// TRIM BUFFER
			$this->offset += $this->complete;											// CALC NEW OFFSET
			// SET FOUR DIGIT YEAR
			if(strlen($matches[2])==8) {
				$matches[1]	= "20".$matches[1];
			}
			// TRIM NAMES
			$matches[4] = trim($matches[4]);
			$matches[5] = trim($matches[5]);
			$matches[6] = trim($matches[6]);
			// FIX BEFORE SOLDAT 1.4 BARET(T) SINGLE T
			if($matches[6]=='Barret M82A1') {
				$matches[6]	= 'Barrett M82A1';
			}
			// FIX SOLDAT 1.4 USSCOM SELFKILL BUG
			if(($matches[6]=='Selfkill' || $matches[6]=='') && $matches[4]!=$matches[5]) {
				$matches[6]	= 'USSOCOM';
			}
			$matches[1] = substr($matches[1],0,4).'-'.substr($matches[1],5,2).'-'.substr($matches[1],8,2).' '.substr($matches[1],11,2).':'.substr($matches[1],14,2).':'.substr($matches[1],17,2);
			$matches[2] = substr($matches[1],0,10);
			// SET CURRENT KILL
			$this->current = array_slice($matches,1);
			return true;
		}

		function replace($pause=false) {
			global $options,$sql;
			// CLOSE FILE HANDLE
			fclose($this->fp);
			// DELETE TEMP FILE
			if(substr($this->file,0,5)=='temp/') {
				@unlink($this->file);
			}
			// RETURN SQL
			return $this->server.",'".$sql->escape($this->log)."',".($this->http?$this->http-($pause?1:0):($pause?$this->complete:$this->size)).",".$this->complete;
		}
	}

	// LOAD WEAPONS
	function load_weapons() {
		global
			$sql,
			$options,
			$weapons;
		$result = $sql->query("
			SELECT
				`weapon`,
				`kills`,
				`last`,
				`type`
			FROM `$options[SQL_TABPREFIX]weapons`
			");
		while($row = $sql->fetchrow($result))
			$weapons[$row[0]] = new Weapon($row[1],$row[2],$row[3]);
	}

	// LOAD CLANTAGS
	function load_clantags() {
		global
			$sql,
			$options,
			$clantags,
			$clantagsdel;
		$result = $sql->query("
			SELECT
				`tag`,
				`position`,
				`order`
			FROM `$options[SQL_TABPREFIX]clantags`
			ORDER BY
				`order` ASC,
				`position` ASC,
				`tag` ASC
			");
		$clantagsdel = 0;
		while(list($tag,$position,$order) = $sql->fetchrow($result)) {
			if(!$order) $clantagsdel++;
			$regex = '('.str_replace(array("A","X"),array("[\w-]","[\w-]?"),preg_quote($tag)).')';
			// REGEX FOR START-TAG
			if($position!='END')	$clantags[] = "((?i)^$regex.+$)";
			// REGEX FOR END-TAG
			if($position!='START')	$clantags[] = "((?i)^.+$regex$)";
		}
	}

	// CREATE PLAYER IF UNKNOWN
	function checkplayer($name) {
		global $players;
		if(!isset($players[$name]))
			$players[$name] = new Player($name);
	}

	////////////////////////////////////////////////////////////////
	// MEMORY SAVING
	// KILLLOG LIMIT BEFORE PERFORM CLEANUP
	define('MEMORY_KILLLOG_MAX',250);
	// PLAYERS LIMIT BEFORE PERFORM CLEANUP
	define('MEMORY_PLAYERS_MAX',250);
	// PLAYERS TO KEEP AFTER CLEAUP
	define('MEMORY_PLAYERS',50);
	function cleanmem(&$events) {
		global
			$sql,
			$options,
			$players,
			$opponents;
		// IF TO MUCH PLAYERS IN MEMORY
		if(count($events)>MEMORY_PLAYERS_MAX) {
			// GENERATE LIST OF PLAYERS MOST RECENT
			arsort($events);
			$names = array_keys($events);

			$replaceplayers				= array();
			$replaceplayeropponents		= array();
			$replaceplayerkillweapons	= array();
			$replaceplayerdeathweapons	= array();

			// COLLECT DATA OF UNRECENT PLAYERS
			for($i=MEMORY_PLAYERS; $i<count($names); $i++) {
				// UNSET ON I-LIST
				unset($events[$name=$names[$i]]);
				$replaceplayers[] = "'".$sql->escape($name)."','".$sql->escape($players[$name]->clan)."',".$players[$name]->points.",".$players[$name]->kills.",".$players[$name]->deaths.",".$players[$name]->selfkills.",'".$players[$name]->last."'";
				// COLLECT PLAYEROPPONENTS
				foreach($players[$name]->opponents as $opponent=>$stats)
					$replaceplayeropponents[] = "'".$sql->escape($name)."','".$sql->escape($opponent)."',$stats[0],'$stats[1]'";
				// COLLECT PLAYERKILLWEAPONS
				foreach($players[$name]->killweapons as $weapon=>$stats)
					$replaceplayerkillweapons[] = "'".$sql->escape($name)."','".$sql->escape($weapon)."',$stats[0],'$stats[1]'";
				// COLLECT PLAYERDEATHWEAPONS
				foreach($players[$name]->deathweapons as $weapon=>$stats)
					$replaceplayerdeathweapons[] = "'".$sql->escape($name)."','".$sql->escape($weapon)."',$stats[0],'$stats[1]'";
				// UNSET PLAYER'S DATA
				unset($players[$name]);
				// SEARCH PLAYER ON OPPONENTS LIST OF RECENT PLAYERS
				for($j=0; $j<MEMORY_PLAYERS; $j++) {
					$opponent = $names[$j];
					if(isset($players[$opponent]->opponents[$name])) {
						$replaceplayeropponents[] = "'".$sql->escape($opponent)."','".$sql->escape($name)."',".$players[$opponent]->opponents[$name][0].",'".$players[$opponent]->opponents[$name][1]."'";
						unset($players[$opponent]->opponents[$name]);
					}
				}
			}
			// STORE PLAYERS
			if(count($replaceplayers))
				$sql->query("REPLACE INTO `$options[SQL_TABPREFIX]players`
					(`player`,`clan`,`points`,`kills`,`deaths`,`selfkills`,`last`)
					VALUES (".implode("),(",$replaceplayers).")");
			unset($replaceplayers);
			// STORE PLAYEROPPONENTS
			if(count($replaceplayeropponents))
				$sql->query("REPLACE INTO `$options[SQL_TABPREFIX]playeropponents`
					(`player`,`opponent`,`kills`,`last`)
					VALUES (".implode("),(",$replaceplayeropponents).")");
			unset($replaceplayeropponents);
			// STORE PLAYERKILLWEAPONS
			if(count($replaceplayerkillweapons))
				$sql->query("REPLACE INTO `$options[SQL_TABPREFIX]playerkillweapons`
					(`player`,`weapon`,`kills`,`last`)
					VALUES (".implode("),(",$replaceplayerkillweapons).")");
			unset($replaceplayerkillweapons);
			// STORE PLAYERDEATHWEAPONS
			if(count($replaceplayerdeathweapons))
				$sql->query("REPLACE INTO `$options[SQL_TABPREFIX]playerdeathweapons`
					(`player`,`weapon`,`deaths`,`last`)
					VALUES (".implode("),(",$replaceplayerdeathweapons).")");
			unset($replaceplayerdeathweapons);
			// REGENERATE OPPONENTS LIST
			$opponents = array_keys($players);
			for($i=0; $i<count($opponents); $i++)
				$opponents[$i] = $sql->escape($opponents[$i]);
		}
	}

	////////////////////////////////////////////////////////////////
	// ARRAYS
	$killlogs		= array();
	$players		= array();
	$weapons		= array();
	$serverdays		= array();
	$serverhours	= array();
	$opponents		= array();
	$clantags		= array();
	$clantagsdel	= -1;

	////////////////////////////////////////////////////////////////
	// UPDATE-OPTIONS
	$options['UPDATE_START'] = explode(' ',microtime());
	$options['UPDATE_OLD_KILLS'] =
	$options['UPDATE_OLD_SELFKILLS'] =
	$options['UPDATE_NEW_KILLS'] =
	$options['UPDATE_NEW_SELFKILLS'] = 0;

	require('include/update_sync.inc.php');
	require('include/update_expire.inc.php');
	require('include/update_calc.inc.php');
	require('include/update_store.inc.php');
	require('include/update_plugins.inc.php');

?>
Return current item: Zitro-Stats