2013-12-31 17:31:05 +01:00
< ? php
2014-01-01 18:37:32 +01:00
namespace ManiaControl\Statistics ;
2014-01-01 17:59:29 +01:00
use ManiaControl\ManiaControl ;
2014-01-01 18:29:28 +01:00
use ManiaControl\Players\Player ;
2013-12-31 17:31:05 +01:00
/**
* Statistic Manager Class
*
* @ author steeffeen & kremsy
*/
2014-01-05 14:41:19 +01:00
// TODO db reference between player index and statsitics playerId
// TODO db reference between metadata statId and statistics statId
2013-12-31 17:31:05 +01:00
class StatisticManager {
2013-12-31 17:59:01 +01:00
/**
* Constants
*/
const TABLE_STATMETADATA = 'mc_statmetadata' ;
2014-01-19 00:09:15 +01:00
const TABLE_STATISTICS = 'mc_statistics' ;
const STAT_TYPE_INT = '0' ;
const STAT_TYPE_TIME = '1' ;
2014-01-28 22:59:18 +01:00
const STAT_TYPE_FLOAT = '2' ;
const SPECIAL_STAT_KD_RATIO = 'Kill Death Ratio' ; //TODO dynamic later
2014-01-19 00:09:15 +01:00
2014-01-01 18:29:28 +01:00
/**
* Public Properties
*/
public $statisticCollector = null ;
2014-01-19 00:09:15 +01:00
public $simpleStatsList = null ;
2013-12-31 17:59:01 +01:00
/**
* Private Properties
*/
private $maniaControl = null ;
2014-01-01 18:29:28 +01:00
private $stats = array ();
2014-01-28 22:59:18 +01:00
private $specialStats = array ();
2013-12-31 17:59:01 +01:00
/**
* Construct player manager
*
2014-01-01 18:29:28 +01:00
* @ param \ManiaControl\ManiaControl $maniaControl
2013-12-31 17:59:01 +01:00
*/
public function __construct ( ManiaControl $maniaControl ) {
$this -> maniaControl = $maniaControl ;
$this -> initTables ();
2014-01-19 00:09:15 +01:00
2014-01-01 18:29:28 +01:00
$this -> statisticCollector = new StatisticCollector ( $maniaControl );
2014-01-19 00:09:15 +01:00
$this -> simpleStatsList = new SimpleStatsList ( $maniaControl );
2014-01-05 14:41:19 +01:00
// Store Stats MetaData
2014-01-01 18:29:28 +01:00
$this -> storeStatMetaData ();
}
/**
* Get the value of an statistic
*
2014-01-19 00:09:15 +01:00
* @ param $statName
* @ param $playerId
2014-01-05 14:41:19 +01:00
* @ param int $serverIndex
2014-01-01 18:29:28 +01:00
* @ return int
*/
2014-01-05 14:41:19 +01:00
public function getStatisticData ( $statName , $playerId , $serverIndex = - 1 ) {
2014-01-03 21:06:24 +01:00
$mysqli = $this -> maniaControl -> database -> mysqli ;
$statId = $this -> getStatId ( $statName );
2014-01-19 00:09:15 +01:00
2014-01-28 22:59:18 +01:00
if ( $statId == null ) {
2014-01-01 18:29:28 +01:00
return - 1 ;
}
2014-01-19 00:09:15 +01:00
2014-01-28 22:59:18 +01:00
if ( $serverIndex == - 1 ) {
2014-01-19 00:09:15 +01:00
$query = " SELECT SUM(value) as value FROM ` " . self :: TABLE_STATISTICS . " ` WHERE `statId` = " . $statId . " AND `playerId` = " . $playerId . " ; " ;
} else {
$query = " SELECT value FROM ` " . self :: TABLE_STATISTICS . " ` WHERE `statId` = " . $statId . " AND `playerId` = " . $playerId . " AND `serverIndex` = ' " . $serverIndex . " '; " ;
2014-01-05 14:41:19 +01:00
}
2014-01-19 00:09:15 +01:00
2014-01-02 11:19:26 +01:00
$result = $mysqli -> query ( $query );
2014-01-28 22:59:18 +01:00
if ( ! $result ) {
2014-01-02 11:19:26 +01:00
trigger_error ( $mysqli -> error );
2014-01-05 19:15:27 +01:00
return null ;
2014-01-01 18:29:28 +01:00
}
2014-01-19 00:09:15 +01:00
2014-01-01 18:29:28 +01:00
$row = $result -> fetch_object ();
2014-01-19 00:09:15 +01:00
2014-01-01 18:29:28 +01:00
$result -> close ();
return $row -> value ;
}
2014-01-21 21:58:39 +01:00
/**
* Get All statistics orderd by an given name
*
* @ param $orderedBy
* @ param $serverIndex
* @ return object
*/
public function getStatsRanking ( $statName = '' , $serverIndex = - 1 ) {
$mysqli = $this -> maniaControl -> database -> mysqli ;
$statId = $this -> getStatId ( $statName );
$query = " SELECT playerId, serverIndex, value FROM ` " . self :: TABLE_STATISTICS . " ` WHERE statId = " . $statId . " ORDER BY value DESC; " ;
$result = $mysqli -> query ( $query );
2014-01-28 22:59:18 +01:00
if ( ! $result ) {
2014-01-21 21:58:39 +01:00
trigger_error ( $mysqli -> error );
return null ;
}
$stats = array ();
while ( $row = $result -> fetch_object ()) {
2014-01-28 22:59:18 +01:00
if ( $serverIndex == - 1 ) {
if ( ! isset ( $stats [ $row -> playerId ])) {
2014-01-21 21:58:39 +01:00
$stats [ $row -> playerId ] = $row -> value ;
} else {
$stats [ $row -> playerId ] += $row -> value ;
}
2014-01-28 22:59:18 +01:00
} else if ( $serverIndex == $row -> serverIndex ) {
2014-01-21 21:58:39 +01:00
$stats [ $row -> playerId ] = $row -> value ;
}
}
$result -> close ();
return $stats ;
}
2014-01-28 22:59:18 +01:00
/**
* Gets The Ranking of an Special Stat
*
* @ param string $statName
*/
public function getStatsRankingOfSpecialStat ( $statName = '' ) {
$statsArray = array ();
switch ( $statName ) {
case self :: SPECIAL_STAT_KD_RATIO :
$kills = $this -> getStatsRanking ( StatisticCollector :: STAT_ON_KILL );
$deaths = $this -> getStatsRanking ( StatisticCollector :: STAT_ON_DEATH );
foreach ( $deaths as $key => $death ) {
if ( $death == 0 || ! isset ( $kills [ $key ])) {
continue ;
}
$statsArray [ $key ] = intval ( $kills [ $key ]) / intval ( $death );
}
}
return $statsArray ;
}
2014-01-01 18:29:28 +01:00
/**
* Store Stats Meta Data from the Database
*/
private function storeStatMetaData () {
2014-01-02 11:19:26 +01:00
$mysqli = $this -> maniaControl -> database -> mysqli ;
2014-01-19 00:09:15 +01:00
$query = " SELECT * FROM ` " . self :: TABLE_STATMETADATA . " `; " ;
2014-01-02 11:19:26 +01:00
$result = $mysqli -> query ( $query );
2014-01-28 22:59:18 +01:00
if ( ! $result ) {
2014-01-02 11:19:26 +01:00
trigger_error ( $mysqli -> error );
2014-01-05 19:15:27 +01:00
return ;
2014-01-01 18:29:28 +01:00
}
2014-01-19 00:09:15 +01:00
while ( $row = $result -> fetch_object ()) {
2014-01-01 18:29:28 +01:00
$this -> stats [ $row -> name ] = $row ;
}
$result -> close ();
2014-01-28 22:59:18 +01:00
$stat = new \stdClass ();
$stat -> name = self :: SPECIAL_STAT_KD_RATIO ;
$stat -> type = self :: STAT_TYPE_FLOAT ;
$this -> specialStats [ self :: SPECIAL_STAT_KD_RATIO ] = $stat ;
2014-01-01 18:29:28 +01:00
}
/**
2014-01-05 19:15:27 +01:00
* Return the Stat Id
2014-01-01 18:29:28 +01:00
*
* @ param $statName
* @ return int
*/
private function getStatId ( $statName ) {
2014-01-28 22:59:18 +01:00
if ( isset ( $this -> stats [ $statName ])) {
2014-01-01 18:29:28 +01:00
$stat = $this -> stats [ $statName ];
2014-01-19 00:09:15 +01:00
return ( int ) $stat -> index ;
2014-01-05 14:41:19 +01:00
}
2014-01-05 19:15:27 +01:00
return null ;
2014-01-01 18:29:28 +01:00
}
2014-01-03 18:37:51 +01:00
/**
* Get all statistics of a certain palyer
*
* @ param Player $player
2014-01-19 00:09:15 +01:00
* @ param int $serverIndex
2014-01-03 18:37:51 +01:00
* @ return array
*/
2014-01-05 14:41:19 +01:00
public function getAllPlayerStats ( Player $player , $serverIndex = - 1 ) {
2014-01-05 19:15:27 +01:00
// TODO improve performance
$playerStats = array ();
2014-01-19 00:09:15 +01:00
foreach ( $this -> stats as $stat ) {
$value = $this -> getStatisticData ( $stat -> name , $player -> index , $serverIndex );
2014-01-03 18:37:51 +01:00
$playerStats [ $stat -> name ] = array ( $stat , $value );
2014-01-03 17:36:10 +01:00
}
2014-01-19 00:09:15 +01:00
2014-01-28 22:59:18 +01:00
foreach ( $this -> specialStats as $stat ){
switch ( $stat -> name ){
case self :: SPECIAL_STAT_KD_RATIO :
if ( ! isset ( $playerStats [ StatisticCollector :: STAT_ON_KILL ]) || ! isset ( $playerStats [ StatisticCollector :: STAT_ON_DEATH ]))
continue ;
$kills = intval ( $playerStats [ StatisticCollector :: STAT_ON_KILL ]);
$deaths = intval ( $playerStats [ StatisticCollector :: STAT_ON_DEATH ]);
if ( $deaths == 0 )
continue ;
$playerStats [ $stat -> name ] = array ( $stat , $kills / $deaths );
}
}
return $playerStats ;
}
2014-01-01 18:29:28 +01:00
/**
* Inserts a Stat into the database
*
2014-01-05 14:41:19 +01:00
* @ param string $statName
2014-01-01 18:29:28 +01:00
* @ param Player $player
2014-01-19 00:09:15 +01:00
* @ param int $serverIndex
* @ param mixed $value , value to Add
2014-01-01 18:29:28 +01:00
* @ param string $statType
2014-01-02 11:19:26 +01:00
* @ return bool
2014-01-01 18:29:28 +01:00
*/
2014-01-05 19:15:27 +01:00
public function insertStat ( $statName , Player $player , $serverIndex = - 1 , $value , $statType = self :: STAT_TYPE_INT ) {
2014-01-28 22:59:18 +01:00
if ( ! $player ) {
2014-01-19 00:09:15 +01:00
return false ;
}
2014-01-28 22:59:18 +01:00
if ( $player -> isFakePlayer ()) {
2014-01-19 00:09:15 +01:00
return true ;
}
2014-01-03 21:06:24 +01:00
$statId = $this -> getStatId ( $statName );
2014-01-28 22:59:18 +01:00
if ( ! $statId ) {
2014-01-19 00:09:15 +01:00
return false ;
}
2014-01-28 22:59:18 +01:00
if ( $serverIndex == - 1 ) {
2014-01-06 16:14:49 +01:00
$serverIndex = $this -> maniaControl -> server -> index ;
2014-01-02 11:19:26 +01:00
}
2014-01-19 00:09:15 +01:00
$mysqli = $this -> maniaControl -> database -> mysqli ;
$query = " INSERT INTO ` " . self :: TABLE_STATISTICS . " ` (
2014-01-05 19:15:27 +01:00
`serverIndex` ,
`playerId` ,
`statId` ,
`value`
2014-01-01 18:29:28 +01:00
) VALUES (
? , ? , ? , ?
) ON DUPLICATE KEY UPDATE
`value` = `value` + VALUES ( `value` ); " ;
2014-01-02 11:19:26 +01:00
$statement = $mysqli -> prepare ( $query );
2014-01-28 22:59:18 +01:00
if ( $mysqli -> error ) {
2014-01-02 11:19:26 +01:00
trigger_error ( $mysqli -> error );
2014-01-01 18:29:28 +01:00
return false ;
}
2014-01-05 14:41:19 +01:00
$statement -> bind_param ( 'iiii' , $serverIndex , $player -> index , $statId , $value );
2014-01-01 18:29:28 +01:00
$statement -> execute ();
2014-01-28 22:59:18 +01:00
if ( $statement -> error ) {
2014-01-01 18:29:28 +01:00
trigger_error ( $statement -> error );
$statement -> close ();
return false ;
}
$statement -> close ();
return true ;
}
/**
* Increments a Statistic by one
*
2014-01-05 14:41:19 +01:00
* @ param string $statName
* @ param Player $player
2014-01-19 00:09:15 +01:00
* @ param int $serverIndex
2014-01-01 18:29:28 +01:00
* @ return bool
*/
2014-01-05 14:41:19 +01:00
public function incrementStat ( $statName , Player $player , $serverIndex = - 1 ) {
return $this -> insertStat ( $statName , $player , $serverIndex , 1 );
2013-12-31 17:59:01 +01:00
}
2013-12-31 18:15:45 +01:00
/**
* Defines a Stat
*
2014-01-19 00:09:15 +01:00
* @ param $statName
2014-01-03 18:37:51 +01:00
* @ param string $type
2014-01-03 19:14:07 +01:00
* @ param string $statDescription
2014-01-02 11:19:26 +01:00
* @ return bool
2013-12-31 18:15:45 +01:00
*/
2014-01-03 19:14:07 +01:00
public function defineStatMetaData ( $statName , $type = self :: STAT_TYPE_INT , $statDescription = '' ) {
2014-01-19 00:09:15 +01:00
$mysqli = $this -> maniaControl -> database -> mysqli ;
$query = " INSERT INTO ` " . self :: TABLE_STATMETADATA . " ` (
2014-01-05 19:15:27 +01:00
`name` ,
`type` ,
`description`
2013-12-31 18:15:45 +01:00
) VALUES (
2014-01-05 19:15:27 +01:00
? , ? , ?
2014-01-03 19:14:07 +01:00
) ON DUPLICATE KEY UPDATE
`type` = VALUES ( `type` ),
`description` = VALUES ( `description` ); " ;
2014-01-02 11:19:26 +01:00
$statement = $mysqli -> prepare ( $query );
2014-01-28 22:59:18 +01:00
if ( $mysqli -> error ) {
2014-01-02 11:19:26 +01:00
trigger_error ( $mysqli -> error );
2013-12-31 18:15:45 +01:00
return false ;
}
2014-01-03 19:14:07 +01:00
$statement -> bind_param ( 'sis' , $statName , $type , $statDescription );
2013-12-31 18:15:45 +01:00
$statement -> execute ();
2014-01-28 22:59:18 +01:00
if ( $statement -> error ) {
2013-12-31 18:15:45 +01:00
trigger_error ( $statement -> error );
$statement -> close ();
return false ;
}
$statement -> close ();
2014-01-02 11:19:26 +01:00
return true ;
2013-12-31 18:15:45 +01:00
}
2013-12-31 17:59:01 +01:00
/**
2014-01-01 18:29:28 +01:00
* Initialize necessary database tables
2013-12-31 17:59:01 +01:00
*
* @ return bool
*/
private function initTables () {
2014-01-19 00:09:15 +01:00
$mysqli = $this -> maniaControl -> database -> mysqli ;
$query = " CREATE TABLE IF NOT EXISTS ` " . self :: TABLE_STATMETADATA . " ` (
2013-12-31 17:59:01 +01:00
`index` int ( 11 ) NOT NULL AUTO_INCREMENT ,
`name` varchar ( 100 ) COLLATE utf8_unicode_ci NOT NULL ,
2014-01-03 19:14:07 +01:00
`type` int ( 5 ) NOT NULL ,
2013-12-31 18:15:45 +01:00
`description` varchar ( 150 ) COLLATE utf8_unicode_ci ,
2013-12-31 17:59:01 +01:00
PRIMARY KEY ( `index` ),
UNIQUE KEY `name` ( `name` )
) ENGINE = MyISAM DEFAULT CHARSET = utf8 COLLATE = utf8_unicode_ci COMMENT = 'Statistics Meta Data' AUTO_INCREMENT = 1 ; " ;
2014-01-02 11:19:26 +01:00
$statement = $mysqli -> prepare ( $query );
2014-01-28 22:59:18 +01:00
if ( $mysqli -> error ) {
2014-01-02 11:19:26 +01:00
trigger_error ( $mysqli -> error , E_USER_ERROR );
2013-12-31 17:59:01 +01:00
return false ;
}
$statement -> execute ();
2014-01-28 22:59:18 +01:00
if ( $statement -> error ) {
2013-12-31 17:59:01 +01:00
trigger_error ( $statement -> error , E_USER_ERROR );
return false ;
}
$statement -> close ();
2014-01-19 00:09:15 +01:00
$query = " CREATE TABLE IF NOT EXISTS ` " . self :: TABLE_STATISTICS . " ` (
2014-01-01 18:29:28 +01:00
`index` int ( 11 ) NOT NULL AUTO_INCREMENT ,
2014-01-05 14:41:19 +01:00
`serverIndex` int ( 11 ) NOT NULL ,
2013-12-31 17:59:01 +01:00
`playerId` int ( 11 ) NOT NULL ,
2014-01-01 18:29:28 +01:00
`statId` int ( 11 ) NOT NULL ,
2014-01-21 21:58:39 +01:00
`value` int ( 20 ) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0' ,
2014-01-01 18:29:28 +01:00
PRIMARY KEY ( `index` ),
2014-01-05 14:41:19 +01:00
UNIQUE KEY `unique` ( `statId` , `playerId` , `serverIndex` )
2014-01-01 18:29:28 +01:00
) ENGINE = MyISAM DEFAULT CHARSET = utf8 COLLATE = utf8_unicode_ci COMMENT = 'Statistics' AUTO_INCREMENT = 1 ; " ;
2014-01-02 11:19:26 +01:00
$statement = $mysqli -> prepare ( $query );
2014-01-28 22:59:18 +01:00
if ( $mysqli -> error ) {
2014-01-02 11:19:26 +01:00
trigger_error ( $mysqli -> error , E_USER_ERROR );
2013-12-31 17:59:01 +01:00
return false ;
}
$statement -> execute ();
2014-01-28 22:59:18 +01:00
if ( $statement -> error ) {
2013-12-31 17:59:01 +01:00
trigger_error ( $statement -> error , E_USER_ERROR );
return false ;
}
$statement -> close ();
2014-01-02 11:19:26 +01:00
return true ;
2013-12-31 17:59:01 +01:00
}
2014-01-05 19:15:27 +01:00
}