298 lines
8.5 KiB
PHP
298 lines
8.5 KiB
PHP
<?php
|
|
|
|
namespace iControl;
|
|
|
|
/**
|
|
* Stats class
|
|
*
|
|
* @author steeffeen
|
|
*/
|
|
class Stats {
|
|
/**
|
|
* Constants
|
|
*/
|
|
const TABLE_STATS_SERVER = 'ic_stats_server';
|
|
const TABLE_STATS_PLAYERS = 'ic_stats_players';
|
|
|
|
/**
|
|
* Private properties
|
|
*/
|
|
private $iControl = null;
|
|
|
|
private $config = null;
|
|
|
|
/**
|
|
* Constuct stats manager
|
|
*/
|
|
public function __construct($iControl) {
|
|
$this->iControl = $iControl;
|
|
|
|
// Load config
|
|
$this->config = Tools::loadConfig('stats.iControl.xml');
|
|
$this->loadSettings();
|
|
|
|
// Init database tables
|
|
$this->initTables();
|
|
|
|
// Register for needed callbacks
|
|
$this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_ENDMAP, $this, 'handleEndMap');
|
|
$this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCHAT, $this, 'handlePlayerChat');
|
|
$this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCONNECT, $this, 'handlePlayerConnect');
|
|
$this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERDISCONNECT, $this, 'handlePlayerDisconnect');
|
|
$this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_TM_PLAYERFINISH, $this, 'handlePlayerFinish');
|
|
}
|
|
|
|
/**
|
|
* Create the database tables
|
|
*/
|
|
private function initTables() {
|
|
$query = "";
|
|
|
|
// Server stats
|
|
$query .= "CREATE TABLE IF NOT EXISTS `" . self::TABLE_STATS_SERVER . "` (
|
|
`index` int(11) NOT NULL AUTO_INCREMENT,
|
|
`day` date NOT NULL,
|
|
`connectCount` int(11) NOT NULL DEFAULT '0',
|
|
`maxPlayerCount` int(11) NOT NULL DEFAULT '0',
|
|
`playedMaps` int(11) NOT NULL DEFAULT '0',
|
|
`finishCount` int(11) NOT NULL DEFAULT '0',
|
|
`changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`index`),
|
|
UNIQUE KEY `day` (`day`)
|
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Stores server stats' AUTO_INCREMENT=1;";
|
|
|
|
// Player stats
|
|
$query .= "CREATE TABLE IF NOT EXISTS `" . self::TABLE_STATS_PLAYERS . "` (
|
|
`index` int(11) NOT NULL AUTO_INCREMENT,
|
|
`Login` varchar(100) NOT NULL,
|
|
`playTime` int(11) NOT NULL DEFAULT '0',
|
|
`connectCount` int(11) NOT NULL DEFAULT '0',
|
|
`chatCount` int(11) NOT NULL DEFAULT '0',
|
|
`finishCount` int(11) NOT NULL DEFAULT '0',
|
|
`hitCount` int(11) NOT NULL DEFAULT '0',
|
|
`eliminationCount` int(11) NOT NULL DEFAULT '0',
|
|
`lastJoin` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
`changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`index`),
|
|
UNIQUE KEY `Login` (`Login`)
|
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Tracks player stats' AUTO_INCREMENT=1;";
|
|
|
|
// Perform queries
|
|
if (!$this->iControl->database->multiQuery($query)) {
|
|
trigger_error("Creating stats tables failed.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load settings from config
|
|
*/
|
|
private function loadSettings() {
|
|
$this->settings = new \stdClass();
|
|
|
|
$this->settings->track_server_connects = Tools::checkSetting($this->config, 'track_server_connects');
|
|
$this->settings->track_server_max_players = Tools::checkSetting($this->config, 'track_server_max_players');
|
|
$this->settings->track_server_played_maps = Tools::checkSetting($this->config, 'track_server_played_maps');
|
|
$this->settings->track_server_finishes = Tools::checkSetting($this->config, 'track_server_finishes');
|
|
|
|
$this->settings->track_player_connects = Tools::checkSetting($this->config, 'track_player_connects');
|
|
$this->settings->track_player_playtime = Tools::checkSetting($this->config, 'track_player_playtime');
|
|
$this->settings->track_player_chats = Tools::checkSetting($this->config, 'track_player_chats');
|
|
$this->settings->track_player_finishes = Tools::checkSetting($this->config, 'track_player_finishes');
|
|
}
|
|
|
|
/**
|
|
* Handle EndMap callback
|
|
*/
|
|
public function handleEndMap($callback) {
|
|
$multiquery = "";
|
|
|
|
// Track played server maps
|
|
if ($this->settings->track_server_played_maps) {
|
|
$multiquery .= "INSERT INTO `" . self::TABLE_STATS_SERVER . "` (
|
|
`day`,
|
|
`playedMaps`
|
|
) VALUES (
|
|
CURDATE(),
|
|
1
|
|
) ON DUPLICATE KEY UPDATE
|
|
`playedMaps` = `playedMaps` + VALUES(`playedMaps`)
|
|
;";
|
|
}
|
|
|
|
// Perform query
|
|
if (!$this->iControl->database->multiQuery($multiquery)) {
|
|
trigger_error("Perform queries on end map failed.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle PlayerChat callback
|
|
*/
|
|
public function handlePlayerChat($callback) {
|
|
if ($callback[1][0] <= 0) return;
|
|
$multiquery = "";
|
|
$login = $callback[1][1];
|
|
|
|
// Track chats
|
|
if ($this->settings->track_player_chats) {
|
|
$multiquery .= "INSERT INTO `" . self::TABLE_STATS_PLAYERS . "` (
|
|
`Login`,
|
|
`chatCount`
|
|
) VALUES (
|
|
'" . $this->iControl->database->escape($login) . "',
|
|
1
|
|
) ON DUPLICATE KEY UPDATE
|
|
`chatCount` = `chatCount` + VALUES(`chatCount`)
|
|
;";
|
|
}
|
|
|
|
// Perform query
|
|
if (!$this->iControl->database->multiQuery($multiquery)) {
|
|
trigger_error("Perform queries on player chat failed.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle PlayerConnect callback
|
|
*/
|
|
public function handlePlayerConnect($callback) {
|
|
$multiquery = "";
|
|
$login = $callback[1][0];
|
|
|
|
// Track server connect
|
|
if ($this->settings->track_server_connects) {
|
|
$multiquery .= "INSERT INTO `" . self::TABLE_STATS_SERVER . "` (
|
|
`day`,
|
|
`connectCount`
|
|
) VALUES (
|
|
CURDATE(),
|
|
1
|
|
) ON DUPLICATE KEY UPDATE
|
|
`connectCount` = `connectCount` + VALUES(`connectCount`)
|
|
;";
|
|
}
|
|
|
|
// Track server max players
|
|
if ($this->settings->track_server_max_players) {
|
|
$players = $this->iControl->server->getPlayers();
|
|
$multiquery .= "INSERT INTO `" . self::TABLE_STATS_SERVER . "` (
|
|
`day`,
|
|
`maxPlayerCount`
|
|
) VALUES (
|
|
CURDATE(),
|
|
" . count($players) . "
|
|
) ON DUPLICATE KEY UPDATE
|
|
`maxPlayerCount` = GREATEST(`maxPlayerCount`, VALUES(`maxPlayerCount`))
|
|
;";
|
|
}
|
|
|
|
// Track player connect
|
|
if ($this->settings->track_player_connects) {
|
|
$multiquery .= "INSERT INTO `" . self::TABLE_STATS_PLAYERS . "` (
|
|
`Login`,
|
|
`lastJoin`,
|
|
`connectCount`
|
|
) VALUES (
|
|
'" . $this->iControl->database->escape($login) . "',
|
|
NOW(),
|
|
1
|
|
) ON DUPLICATE KEY UPDATE
|
|
`lastJoin` = VALUES(`lastJoin`),
|
|
`connectCount` = `connectCount` + VALUES(`connectCount`)
|
|
;";
|
|
}
|
|
|
|
// Perform query
|
|
if (!$this->iControl->database->multiQuery($multiquery)) {
|
|
trigger_error("Perform queries on player connect failed.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle PlayerDisconnect callback
|
|
*/
|
|
public function handlePlayerDisconnect($callback) {
|
|
$multiquery = "";
|
|
$login = $callback[1][0];
|
|
|
|
// Track player playtime
|
|
if ($this->settings->track_player_playtime) {
|
|
$query = "SELECT `lastJoin` FROM `" . self::TABLE_STATS_PLAYERS . "`
|
|
WHERE `Login` = '" . $this->iControl->database->escape($login) . "'
|
|
;";
|
|
$result = $this->iControl->database->query($query);
|
|
if (!$result) {
|
|
// Error
|
|
trigger_error("Error selecting player join time from '" . $login . "'.");
|
|
}
|
|
else {
|
|
// Add play time
|
|
while ($row = $result->fetch_object()) {
|
|
if (!property_exists($row, 'lastJoin')) continue;
|
|
$lastJoin = strtotime($row->lastJoin);
|
|
$lastJoin = ($lastJoin > $this->iControl->startTime ? $lastJoin : $this->iControl->startTime);
|
|
$multiquery .= "INSERT INTO `" . self::TABLE_STATS_PLAYERS . "` (
|
|
`Login`,
|
|
`playTime`
|
|
) VALUES (
|
|
'" . $this->iControl->database->escape($login) . "',
|
|
TIMESTAMPDIFF(SECOND, '" . Tools::timeToTimestamp($lastJoin) . "', NOW())
|
|
) ON DUPLICATE KEY UPDATE
|
|
`playTime` = `playTime` + VALUES(`playTime`)
|
|
;";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Perform query
|
|
if (!$this->iControl->database->multiQuery($multiquery)) {
|
|
trigger_error("Perform queries on player connect failed.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle the PlayerFinish callback
|
|
*/
|
|
public function handlePlayerFinish($callback) {
|
|
if ($callback[1][0] <= 0) return;
|
|
if ($callback[1][2] <= 0) return;
|
|
|
|
$multiquery = "";
|
|
$login = $callback[1][1];
|
|
|
|
// Track server finishes
|
|
if ($this->settings->track_server_finishes) {
|
|
$multiquery .= "INSERT INTO `" . self::TABLE_STATS_SERVER . "` (
|
|
`day`,
|
|
`finishCount`
|
|
) VALUES (
|
|
CURDATE(),
|
|
1
|
|
) ON DUPLICATE KEY UPDATE
|
|
`finishCount` = `finishCount` + VALUES(`finishCount`)
|
|
;";
|
|
}
|
|
|
|
// Track player finishes
|
|
if ($this->settings->track_player_finishes) {
|
|
$multiquery .= "INSERT INTO `" . self::TABLE_STATS_PLAYERS . "` (
|
|
`Login`,
|
|
`finishCount`
|
|
) VALUES (
|
|
'" . $this->iControl->database->escape($login) . "',
|
|
1
|
|
) ON DUPLICATE KEY UPDATE
|
|
`finishCount` = `finishCount` + VALUES(`finishCount`)
|
|
;";
|
|
}
|
|
|
|
// Perform query
|
|
if (!$this->iControl->database->multiQuery($multiquery)) {
|
|
trigger_error("Perform queries on player finish failed.");
|
|
}
|
|
}
|
|
}
|
|
|
|
?>
|