missed one file
This commit is contained in:
parent
e23d25bcd2
commit
0bad97e119
@ -1,36 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Configure authentication for players -->
|
|
||||||
<authentication-config>
|
|
||||||
|
|
||||||
<!-- SuperAdmins with full access -->
|
|
||||||
<superadmin>
|
|
||||||
<!-- <login>login1</login> <login>login2</login> -->
|
|
||||||
<login>steeffeen</login>
|
|
||||||
</superadmin>
|
|
||||||
|
|
||||||
<!-- Admins with almost full access -->
|
|
||||||
<admin>
|
|
||||||
<!-- <login>login1</login> <login>login2</login> -->
|
|
||||||
<login>gorby</login>
|
|
||||||
<login>canyondrive</login>
|
|
||||||
</admin>
|
|
||||||
|
|
||||||
<!-- Operators with only moderating access -->
|
|
||||||
<operator>
|
|
||||||
<!-- <login>login1</login> <login>login2</login> -->
|
|
||||||
<login>eyebo</login>
|
|
||||||
<login>jojo95183</login>
|
|
||||||
<login>xanashea</login>
|
|
||||||
<login>ardid</login>
|
|
||||||
<login>gugli</login>
|
|
||||||
<login>phil13hebert</login>
|
|
||||||
<login>xcaliber</login>
|
|
||||||
<login>eole</login>
|
|
||||||
<login>fix</login>
|
|
||||||
<login>kremsy</login>
|
|
||||||
<login>papychampy</login>
|
|
||||||
<login>titishu</login>
|
|
||||||
<login>wurstigewurst</login>
|
|
||||||
</operator>
|
|
||||||
|
|
||||||
</authentication-config>
|
|
@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Configure how iControl sends chat message -->
|
|
||||||
<chat-config>
|
|
||||||
|
|
||||||
<!-- Set which codes should be used to compose chat messages -->
|
|
||||||
<messages>
|
|
||||||
<information>$fff</information>
|
|
||||||
<success>$0f0</success>
|
|
||||||
<error>$f00</error>
|
|
||||||
</messages>
|
|
||||||
|
|
||||||
</chat-config>
|
|
@ -1,44 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Enable/Disable chat commands -->
|
|
||||||
<!-- Authentication levels: superadmin, admin, operator, all, none -->
|
|
||||||
<!-- 'Operator' means that you have to be at least Operator to perform the command -->
|
|
||||||
<!-- 'None' means that nobody is able to use the command (disabled) -->
|
|
||||||
<commands-config>
|
|
||||||
|
|
||||||
<!-- SuperAdmin commands -->
|
|
||||||
<superadmin>
|
|
||||||
<shutdown />
|
|
||||||
<shutdownserver />
|
|
||||||
<networkstats />
|
|
||||||
<systeminfo />
|
|
||||||
<pay />
|
|
||||||
</superadmin>
|
|
||||||
|
|
||||||
<!-- Admin commands -->
|
|
||||||
<admin>
|
|
||||||
<getplanets />
|
|
||||||
<setservername />
|
|
||||||
<getservername />
|
|
||||||
</admin>
|
|
||||||
|
|
||||||
<!-- Operator commands -->
|
|
||||||
<operator>
|
|
||||||
<kick />
|
|
||||||
<nextmap />
|
|
||||||
<addmap />
|
|
||||||
<removemap />
|
|
||||||
<startwarmup />
|
|
||||||
<stopwarmup />
|
|
||||||
</operator>
|
|
||||||
|
|
||||||
<!-- Everybody commands -->
|
|
||||||
<all>
|
|
||||||
<help />
|
|
||||||
<donate />
|
|
||||||
</all>
|
|
||||||
|
|
||||||
<!-- Nobody commands -->
|
|
||||||
<none>
|
|
||||||
</none>
|
|
||||||
|
|
||||||
</commands-config>
|
|
@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Core configuration for iControl -->
|
|
||||||
<core-config>
|
|
||||||
|
|
||||||
<!-- Connection timeout -->
|
|
||||||
<timeout>20</timeout>
|
|
||||||
|
|
||||||
<!-- Define the file name for automatically saving the match settings after each map (relative from /Maps/MatchSettings/) -->
|
|
||||||
<!-- (leave empty for not saving) -->
|
|
||||||
<autosave_matchsettings>tracklist.txt</autosave_matchsettings>
|
|
||||||
|
|
||||||
<!-- Directory for downloaded maps (relative from /Maps/) -->
|
|
||||||
<maps_dir>mx</maps_dir>
|
|
||||||
|
|
||||||
</core-config>
|
|
@ -1,16 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Configure the mysql database used by iControl -->
|
|
||||||
<database-config>
|
|
||||||
|
|
||||||
<!-- MySQL Server -->
|
|
||||||
<host>localhost</host>
|
|
||||||
<port>3306</port>
|
|
||||||
|
|
||||||
<!-- MySQL User -->
|
|
||||||
<user>steff</user>
|
|
||||||
<pass>kjhgvhbjnfih2394ugnjk</pass>
|
|
||||||
|
|
||||||
<!-- Database Name -->
|
|
||||||
<database>steff_united</database>
|
|
||||||
|
|
||||||
</database-config>
|
|
@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Configure which plugins should be loaded -->
|
|
||||||
<plugins-config>
|
|
||||||
<!-- <plugin>FILENAME1</plugin> <plugin>FILENAME2</plugin> -->
|
|
||||||
|
|
||||||
<plugin>chatlog.plugin.php</plugin>
|
|
||||||
<plugin>karma.plugin.php</plugin>
|
|
||||||
<plugin>records.plugin.php</plugin>
|
|
||||||
<plugin>united.plugin.php</plugin>
|
|
||||||
|
|
||||||
<!-- <plugin>obstacle.plugin.php</plugin> -->
|
|
||||||
|
|
||||||
</plugins-config>
|
|
@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Configure your maniaplanet server -->
|
|
||||||
<server-config>
|
|
||||||
|
|
||||||
<!-- Enable to use only one static server (default behavior) -->
|
|
||||||
<enable>true</enable>
|
|
||||||
|
|
||||||
<!-- Server connection details (Make sure that the firewall and the server config are properly configured!) -->
|
|
||||||
<host>144.76.158.111</host>
|
|
||||||
<host>localhost</host>
|
|
||||||
<port>21003</port>
|
|
||||||
|
|
||||||
<!-- XmlRpc login details -->
|
|
||||||
<login>SuperAdmin</login>
|
|
||||||
<pass>dtcfvgubhnjomkjnbhv</pass>
|
|
||||||
|
|
||||||
</server-config>
|
|
@ -1,43 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Configure the stats manager and enable/disable specific stats -->
|
|
||||||
<stats-config>
|
|
||||||
|
|
||||||
<stats>
|
|
||||||
|
|
||||||
<!-- Server stats -->
|
|
||||||
<server>
|
|
||||||
|
|
||||||
<!-- Track how many players connected on the server -->
|
|
||||||
<track_server_connects>true</track_server_connects>
|
|
||||||
|
|
||||||
<!-- Track how many players have been on the server at max -->
|
|
||||||
<track_server_max_players>true</track_server_max_players>
|
|
||||||
|
|
||||||
<!-- Track how many maps have been played during the day -->
|
|
||||||
<track_server_played_maps>true</track_server_played_maps>
|
|
||||||
|
|
||||||
<!-- Track how many times players finished during the day -->
|
|
||||||
<track_server_finishes>true</track_server_finishes>
|
|
||||||
|
|
||||||
</server>
|
|
||||||
|
|
||||||
<!-- Player stats -->
|
|
||||||
<player>
|
|
||||||
|
|
||||||
<!-- Track player connect counts -->
|
|
||||||
<track_player_connects>true</track_player_connects>
|
|
||||||
|
|
||||||
<!-- Track player play time -->
|
|
||||||
<track_player_playtime>true</track_player_playtime>
|
|
||||||
|
|
||||||
<!-- Track how many chat message players have sent -->
|
|
||||||
<track_player_chats>true</track_player_chats>
|
|
||||||
|
|
||||||
<!-- Track player finishes -->
|
|
||||||
<track_player_finishes>true</track_player_finishes>
|
|
||||||
|
|
||||||
</player>
|
|
||||||
|
|
||||||
</stats>
|
|
||||||
|
|
||||||
</stats-config>
|
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Configure the United plugin -->
|
<!-- Configure the United plugin -->
|
||||||
<!-- Note: You should disable the config server.iControl.xml while using this plugin -->
|
<!-- Note: You should disable the config server.mControl.xml while using this plugin -->
|
||||||
<united-config>
|
<united-config>
|
||||||
|
|
||||||
<!-- Enable the whole plugin -->
|
<!-- Enable the whole plugin -->
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace iControl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class handling authentication levels
|
|
||||||
*
|
|
||||||
* @author steeffeen
|
|
||||||
*/
|
|
||||||
class Authentication {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
public $RIGHTS_LEVELS = array(-1 => 'none', 0 => 'superadmin', 1 => 'admin', 2 => 'operator', 3 => 'all');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private properties
|
|
||||||
*/
|
|
||||||
private $iControl = null;
|
|
||||||
|
|
||||||
private $config = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct authentication manager
|
|
||||||
*/
|
|
||||||
public function __construct($iControl) {
|
|
||||||
$this->iControl = $iControl;
|
|
||||||
|
|
||||||
// Load config
|
|
||||||
$this->config = Tools::loadConfig('authentication.iControl.xml');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the player has enough rights
|
|
||||||
*
|
|
||||||
* @param string $login
|
|
||||||
* @param string $defaultRight
|
|
||||||
* @param string $neededRight
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function checkRight($login, $neededRight) {
|
|
||||||
$right = $this->getRights($login);
|
|
||||||
return $this->compareRights($right, $neededRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare if the rights are enough
|
|
||||||
*
|
|
||||||
* @param string $hasRight
|
|
||||||
* @param string $neededRight
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function compareRights($hasRight, $neededRight) {
|
|
||||||
if (!in_array($hasRight, $this->RIGHTS_LEVELS) || !in_array($neededRight, $this->RIGHTS_LEVELS)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$hasLevel = array_search($hasRight, $this->RIGHTS_LEVELS);
|
|
||||||
$neededLevel = array_search($neededRight, $this->RIGHTS_LEVELS);
|
|
||||||
if ($hasLevel > $neededLevel) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get rights of the given login
|
|
||||||
*
|
|
||||||
* @param string $login
|
|
||||||
* @param string $defaultRights
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getRights($login, $defaultRight = 'all') {
|
|
||||||
$groups = $this->config->xpath('//login[text()="' . $login . '"]/..');
|
|
||||||
if (empty($groups)) return $defaultRight;
|
|
||||||
$right = $defaultRight;
|
|
||||||
$rightLevel = array_search($right, $this->RIGHTS_LEVELS);
|
|
||||||
foreach ($groups as $group) {
|
|
||||||
$level = array_search($group->getName(), $this->RIGHTS_LEVELS);
|
|
||||||
if ($level === false) continue;
|
|
||||||
if ($level < $rightLevel || $rightLevel === false) {
|
|
||||||
$right = $group->getName();
|
|
||||||
$rightLevel = $level;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends an error message to the login
|
|
||||||
*
|
|
||||||
* @param string $login
|
|
||||||
*/
|
|
||||||
public function sendNotAllowed($login) {
|
|
||||||
if (!$this->iControl->chat->sendError('You do not have the required rights to perform this command!', $login)) {
|
|
||||||
trigger_error("Couldn't send forbidden message to login '" . $login . "'. " . $this->iControl->getClientErrorText());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@ -1,191 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace iControl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for handling server callbacks
|
|
||||||
*
|
|
||||||
* @author steeffeen
|
|
||||||
*/
|
|
||||||
class Callbacks {
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
// iControl callbacks
|
|
||||||
const CB_IC_1_SECOND = 'iControl.1Second';
|
|
||||||
const CB_IC_5_SECOND = 'iControl.5Second';
|
|
||||||
const CB_IC_1_MINUTE = 'iControl.1Minute';
|
|
||||||
const CB_IC_3_MINUTE = 'iControl.3Minute';
|
|
||||||
const CB_IC_ONINIT = 'iControl.OnInit';
|
|
||||||
const CB_IC_CLIENTUPDATED = 'iControl.ClientUpdated';
|
|
||||||
const CB_IC_BEGINMAP = 'iControl.BeginMap';
|
|
||||||
const CB_IC_ENDMAP = 'iControl.EndMap';
|
|
||||||
// ManiaPlanet callbacks
|
|
||||||
const CB_MP_SERVERSTART = 'ManiaPlanet.ServerStart';
|
|
||||||
const CB_MP_SERVERSTOP = 'ManiaPlanet.ServerStop';
|
|
||||||
const CB_MP_BEGINMAP = 'ManiaPlanet.BeginMap';
|
|
||||||
const CB_MP_BEGINMATCH = 'ManiaPlanet.BeginMatch';
|
|
||||||
const CB_MP_ENDMATCH = 'ManiaPlanet.EndMatch';
|
|
||||||
const CB_MP_ENDMAP = 'ManiaPlanet.EndMap';
|
|
||||||
const CB_MP_MAPLISTMODIFIED = 'ManiaPlanet.MapListModified';
|
|
||||||
const CB_MP_ECHO = 'ManiaPlanet.Echo';
|
|
||||||
const CB_MP_BILLUPDATED = 'ManiaPlanet.BillUpdated';
|
|
||||||
const CB_MP_PLAYERCHAT = 'ManiaPlanet.PlayerChat';
|
|
||||||
const CB_MP_PLAYERCONNECT = 'ManiaPlanet.PlayerConnect';
|
|
||||||
const CB_MP_PLAYERDISCONNECT = 'ManiaPlanet.PlayerDisconnect';
|
|
||||||
const CB_MP_PLAYERMANIALINKPAGEANSWER = 'ManiaPlanet.PlayerManialinkPageAnswer';
|
|
||||||
const CB_MP_PLAYERINFOCHANGED = 'ManiaPlanet.PlayerInfoChanged';
|
|
||||||
const CB_MP_PLAYERALLIESCHANGED = 'ManiaPlanet.PlayerAlliesChanged';
|
|
||||||
const CB_MP_VOTEUPDATED = 'ManiaPlanet.VoteUpdated';
|
|
||||||
const CB_MP_STATUSCHANGED = 'ManiaPlanet.StatusChanged';
|
|
||||||
const CB_MP_MODESCRIPTCALLBACK = 'ManiaPlanet.ModeScriptCallback';
|
|
||||||
const CB_MP_MODESCRIPTCALLBACKARRAY = 'ManiaPlanet.ModeScriptCallbackArray';
|
|
||||||
const CB_MP_TUNNELDATARECEIVED = 'ManiaPlanet.TunnelDataReceived';
|
|
||||||
// TrackMania callbacks
|
|
||||||
const CB_TM_PLAYERCHECKPOINT = 'TrackMania.PlayerCheckpoint';
|
|
||||||
const CB_TM_PLAYERFINISH = 'TrackMania.PlayerFinish';
|
|
||||||
const CB_TM_PLAYERINCOHERENCE = 'TrackMania.PlayerIncoherence';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private properties
|
|
||||||
*/
|
|
||||||
private $iControl = null;
|
|
||||||
|
|
||||||
private $callbackHandlers = array();
|
|
||||||
|
|
||||||
private $last1Second = -1;
|
|
||||||
|
|
||||||
private $last5Second = -1;
|
|
||||||
|
|
||||||
private $last1Minute = -1;
|
|
||||||
|
|
||||||
private $last3Minute = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct callbacks handler
|
|
||||||
*/
|
|
||||||
public function __construct($iControl) {
|
|
||||||
$this->iControl = $iControl;
|
|
||||||
|
|
||||||
// Init values
|
|
||||||
$this->last1Second = time();
|
|
||||||
$this->last5Second = time();
|
|
||||||
$this->last1Minute = time();
|
|
||||||
$this->last3Minute = time();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform OnInit callback
|
|
||||||
*/
|
|
||||||
public function onInit() {
|
|
||||||
// On init callback
|
|
||||||
$this->triggerCallback(self::CB_IC_ONINIT, array(self::CB_IC_ONINIT));
|
|
||||||
|
|
||||||
// Simulate begin map
|
|
||||||
$map = $this->iControl->server->getMap();
|
|
||||||
if ($map) {
|
|
||||||
$this->triggerCallback(self::CB_IC_BEGINMAP, array(self::CB_IC_BEGINMAP, array($map)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the given array of callbacks
|
|
||||||
*/
|
|
||||||
public function handleCallbacks() {
|
|
||||||
// Perform iControl callbacks
|
|
||||||
if ($this->last1Second <= time() - 1) {
|
|
||||||
$this->last1Second = time();
|
|
||||||
|
|
||||||
// 1 second
|
|
||||||
$this->triggerCallback(self::CB_IC_1_SECOND, array(self::CB_IC_1_SECOND));
|
|
||||||
|
|
||||||
if ($this->last5Second <= time() - 5) {
|
|
||||||
$this->last5Second = time();
|
|
||||||
|
|
||||||
// 5 second
|
|
||||||
$this->triggerCallback(self::CB_IC_5_SECOND, array(self::CB_IC_5_SECOND));
|
|
||||||
|
|
||||||
if ($this->last1Minute <= time() - 60) {
|
|
||||||
$this->last1Minute = time();
|
|
||||||
|
|
||||||
// 1 minute
|
|
||||||
$this->triggerCallback(self::CB_IC_1_MINUTE, array(self::CB_IC_1_MINUTE));
|
|
||||||
|
|
||||||
if ($this->last3Minute <= time() - 180) {
|
|
||||||
$this->last3Minute = time();
|
|
||||||
|
|
||||||
// 3 minute
|
|
||||||
$this->triggerCallback(self::CB_IC_3_MINUTE, array(self::CB_IC_3_MINUTE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get server callbacks
|
|
||||||
if (!$this->iControl->client) return;
|
|
||||||
$this->iControl->client->resetError();
|
|
||||||
$this->iControl->client->readCB();
|
|
||||||
$callbacks = $this->iControl->client->getCBResponses();
|
|
||||||
if (!is_array($callbacks) || $this->iControl->client->isError()) {
|
|
||||||
trigger_error("Error reading server callbacks. " . $this->iControl->getClientErrorText());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle callbacks
|
|
||||||
foreach ($callbacks as $index => $callback) {
|
|
||||||
$callbackName = $callback[0];
|
|
||||||
switch ($callbackName) {
|
|
||||||
case self::CB_MP_BEGINMAP:
|
|
||||||
{
|
|
||||||
// Map begin
|
|
||||||
$this->triggerCallback($callbackName, $callback);
|
|
||||||
$this->triggerCallback(self::CB_IC_BEGINMAP, $callback);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case self::CB_MP_ENDMAP:
|
|
||||||
{
|
|
||||||
// Map end
|
|
||||||
$this->triggerCallback($callbackName, $callback);
|
|
||||||
$this->triggerCallback(self::CB_IC_ENDMAP, $callback);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
$this->triggerCallback($callbackName, $callback);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trigger a specific callback
|
|
||||||
*
|
|
||||||
* @param string $callbackName
|
|
||||||
* @param mixed $data
|
|
||||||
*/
|
|
||||||
public function triggerCallback($callbackName, $data) {
|
|
||||||
if (!array_key_exists($callbackName, $this->callbackHandlers) || !is_array($this->callbackHandlers[$callbackName])) return;
|
|
||||||
foreach ($this->callbackHandlers[$callbackName] as $handler) {
|
|
||||||
call_user_func(array($handler[0], $handler[1]), $data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new callback handler
|
|
||||||
*/
|
|
||||||
public function registerCallbackHandler($callback, $handler, $method) {
|
|
||||||
if (!is_object($handler) || !method_exists($handler, $method)) {
|
|
||||||
trigger_error("Given handler can't handle callback '" . $callback . "' (no method '" . $method . "')!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!array_key_exists($callback, $this->callbackHandlers) || !is_array($this->callbackHandlers[$callback])) {
|
|
||||||
// Init callback handler array
|
|
||||||
$this->callbackHandlers[$callback] = array();
|
|
||||||
}
|
|
||||||
// Register callback handler
|
|
||||||
array_push($this->callbackHandlers[$callback], array($handler, $method));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@ -1,85 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace iControl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for chat methods
|
|
||||||
*
|
|
||||||
* @author steeffeen
|
|
||||||
*/
|
|
||||||
class Chat {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private properties
|
|
||||||
*/
|
|
||||||
private $iControl = null;
|
|
||||||
|
|
||||||
private $config = null;
|
|
||||||
|
|
||||||
private $prefix = 'iControl>';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct iControl chat
|
|
||||||
*/
|
|
||||||
public function __construct($iControl) {
|
|
||||||
$this->iControl = $iControl;
|
|
||||||
|
|
||||||
// Load config
|
|
||||||
$this->config = Tools::loadConfig('chat.iControl.xml');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a chat message to the given login
|
|
||||||
*
|
|
||||||
* @param string $login
|
|
||||||
* @param string $message
|
|
||||||
* @param bool $prefix
|
|
||||||
*/
|
|
||||||
public function sendChat($message, $login = null, $prefix = false) {
|
|
||||||
if (!$this->iControl->client) return false;
|
|
||||||
if ($login === null) {
|
|
||||||
return $this->iControl->client->query('ChatSendServerMessage', ($prefix ? $this->prefix : '') . $message);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return $this->iControl->client->query('ChatSendServerMessageToLogin', ($prefix ? $this->prefix : '') . $message, $login);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an information message to the given login
|
|
||||||
*
|
|
||||||
* @param string $login
|
|
||||||
* @param string $message
|
|
||||||
* @param bool $prefix
|
|
||||||
*/
|
|
||||||
public function sendInformation($message, $login = null, $prefix = false) {
|
|
||||||
$format = (string) $this->config->messages->information;
|
|
||||||
return $this->sendChat($format . $message, $login);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a success message to the given login
|
|
||||||
*
|
|
||||||
* @param string $message
|
|
||||||
* @param string $login
|
|
||||||
* @param bool $prefix
|
|
||||||
*/
|
|
||||||
public function sendSuccess($message, $login = null, $prefix = false) {
|
|
||||||
$format = (string) $this->config->messages->success;
|
|
||||||
return $this->sendChat($format . $message, $login);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an error message to the given login
|
|
||||||
*
|
|
||||||
* @param string $login
|
|
||||||
* @param string $message
|
|
||||||
* @param bool $prefix
|
|
||||||
*/
|
|
||||||
public function sendError($message, $login = null, $prefix = false) {
|
|
||||||
$format = (string) $this->config->messages->error;
|
|
||||||
return $this->sendChat($format . $message, $login);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@ -1,348 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace iControl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Needed includes
|
|
||||||
*/
|
|
||||||
require_once __DIR__ . '/authentication.iControl.php';
|
|
||||||
require_once __DIR__ . '/callbacks.iControl.php';
|
|
||||||
require_once __DIR__ . '/chat.iControl.php';
|
|
||||||
require_once __DIR__ . '/commands.iControl.php';
|
|
||||||
require_once __DIR__ . '/database.iControl.php';
|
|
||||||
require_once __DIR__ . '/server.iControl.php';
|
|
||||||
require_once __DIR__ . '/stats.iControl.php';
|
|
||||||
require_once __DIR__ . '/tools.iControl.php';
|
|
||||||
list($endiantest) = array_values(unpack('L1L', pack('V', 1)));
|
|
||||||
if ($endiantest == 1) {
|
|
||||||
require_once __DIR__ . '/PhpRemote/GbxRemote.inc.php';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
require_once __DIR__ . '/PhpRemote/GbxRemote.bem.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* iControl Server Controller for ManiaPlanet Server
|
|
||||||
*
|
|
||||||
* @author steeffeen
|
|
||||||
*/
|
|
||||||
class iControl {
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
const VERSION = '0.1';
|
|
||||||
const API_VERSION = '2013-04-16';
|
|
||||||
const DATE = 'd-m-y h:i:sa T';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public properties
|
|
||||||
*/
|
|
||||||
public $authentication = null;
|
|
||||||
|
|
||||||
public $callbacks = null;
|
|
||||||
|
|
||||||
public $client = null;
|
|
||||||
|
|
||||||
public $chat = null;
|
|
||||||
|
|
||||||
public $config = null;
|
|
||||||
|
|
||||||
public $commands = null;
|
|
||||||
|
|
||||||
public $database = null;
|
|
||||||
|
|
||||||
public $debug = false;
|
|
||||||
|
|
||||||
public $server = null;
|
|
||||||
|
|
||||||
public $startTime = -1;
|
|
||||||
|
|
||||||
public $stats = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private properties
|
|
||||||
*/
|
|
||||||
private $plugins = array();
|
|
||||||
|
|
||||||
private $shutdownRequested = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct iControl
|
|
||||||
*/
|
|
||||||
public function __construct() {
|
|
||||||
// Load core
|
|
||||||
$this->config = Tools::loadConfig('core.iControl.xml');
|
|
||||||
$this->startTime = time();
|
|
||||||
|
|
||||||
// Load chat tool
|
|
||||||
$this->chat = new Chat($this);
|
|
||||||
|
|
||||||
// Load callbacks handler
|
|
||||||
$this->callbacks = new Callbacks($this);
|
|
||||||
|
|
||||||
// Load database
|
|
||||||
$this->database = new Database($this);
|
|
||||||
|
|
||||||
// Load server
|
|
||||||
$this->server = new Server($this);
|
|
||||||
|
|
||||||
// Load authentication
|
|
||||||
$this->authentication = new Authentication($this);
|
|
||||||
|
|
||||||
// Load commands handler
|
|
||||||
$this->commands = new Commands($this);
|
|
||||||
|
|
||||||
// Load stats manager
|
|
||||||
$this->stats = new Stats($this);
|
|
||||||
|
|
||||||
// Register for core callbacks
|
|
||||||
$this->callbacks->registerCallbackHandler(Callbacks::CB_MP_ENDMAP, $this, 'handleEndMap');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return message composed of client error message and error code
|
|
||||||
*
|
|
||||||
* @param object $client
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getClientErrorText($client = null) {
|
|
||||||
if (is_object($client)) {
|
|
||||||
return $client->getErrorMessage() . ' (' . $client->getErrorCode() . ')';
|
|
||||||
}
|
|
||||||
return $this->client->getErrorMessage() . ' (' . $this->client->getErrorCode() . ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Quit iControl and log the given message
|
|
||||||
*/
|
|
||||||
public function quit($message = false) {
|
|
||||||
if ($this->shutdownRequested) return;
|
|
||||||
|
|
||||||
if ($this->client) {
|
|
||||||
// Announce quit
|
|
||||||
$this->chat->sendInformation('iControl shutting down.');
|
|
||||||
|
|
||||||
// Hide manialinks
|
|
||||||
$this->client->query('SendHideManialinkPage');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log quit reason
|
|
||||||
if ($message) {
|
|
||||||
error_log($message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shutdown
|
|
||||||
if ($this->client) $this->client->Terminate();
|
|
||||||
|
|
||||||
error_log("Quitting iControl!");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run iControl
|
|
||||||
*/
|
|
||||||
public function run($debug = false) {
|
|
||||||
error_log('Starting iControl v' . self::VERSION . '!');
|
|
||||||
$this->debug = (bool) $debug;
|
|
||||||
|
|
||||||
// Load plugins
|
|
||||||
$this->loadPlugins();
|
|
||||||
|
|
||||||
// Connect to server
|
|
||||||
$this->connect();
|
|
||||||
|
|
||||||
// Loading finished
|
|
||||||
error_log("Loading completed!");
|
|
||||||
|
|
||||||
// Announce iControl
|
|
||||||
if (!$this->chat->sendInformation('iControl v' . self::VERSION . ' successfully started!')) {
|
|
||||||
trigger_error("Couldn't announce iControl. " . $this->iControl->getClientErrorText());
|
|
||||||
}
|
|
||||||
|
|
||||||
// OnInit
|
|
||||||
$this->callbacks->onInit();
|
|
||||||
|
|
||||||
// Main loop
|
|
||||||
while (!$this->shutdownRequested) {
|
|
||||||
$loopStart = microtime(true);
|
|
||||||
|
|
||||||
// Disable script timeout
|
|
||||||
set_time_limit(30);
|
|
||||||
|
|
||||||
// Handle server callbacks
|
|
||||||
$this->callbacks->handleCallbacks();
|
|
||||||
|
|
||||||
// Loop plugins
|
|
||||||
foreach ($this->plugins as $plugin) {
|
|
||||||
if (!method_exists($plugin, 'loop')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$plugin->loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Yield for next tick
|
|
||||||
$loopEnd = microtime(true);
|
|
||||||
$sleepTime = 300000 - $loopEnd + $loopStart;
|
|
||||||
if ($sleepTime > 0) {
|
|
||||||
usleep($sleepTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shutdown
|
|
||||||
$this->client->Terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connect to ManiaPlanet server
|
|
||||||
*/
|
|
||||||
private function connect() {
|
|
||||||
$enable = $this->server->config->xpath('enable');
|
|
||||||
$enable = Tools::toBool($enable[0]);
|
|
||||||
if (!$enable) return;
|
|
||||||
|
|
||||||
// Load remote client
|
|
||||||
$this->client = new \IXR_ClientMulticall_Gbx();
|
|
||||||
|
|
||||||
$host = $this->server->config->xpath('host');
|
|
||||||
if (!$host) trigger_error("Invalid server configuration (host).", E_USER_ERROR);
|
|
||||||
$host = (string) $host[0];
|
|
||||||
$port = $this->server->config->xpath('port');
|
|
||||||
if (!$host) trigger_error("Invalid server configuration (port).", E_USER_ERROR);
|
|
||||||
$port = (string) $port[0];
|
|
||||||
$timeout = $this->config->xpath('timeout');
|
|
||||||
if (!$timeout) trigger_error("Invalid core configuration (timeout).", E_USER_ERROR);
|
|
||||||
$timeout = (int) $timeout[0];
|
|
||||||
|
|
||||||
error_log("Connecting to server at " . $host . ":" . $port . "...");
|
|
||||||
|
|
||||||
// Connect
|
|
||||||
if (!$this->client->InitWithIp($host, $port, $timeout)) {
|
|
||||||
trigger_error(
|
|
||||||
"Couldn't connect to server! " . $this->client->getErrorMessage() . "(" . $this->client->getErrorCode() . ")",
|
|
||||||
E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
$login = $this->server->config->xpath('login');
|
|
||||||
if (!$login) trigger_error("Invalid server configuration (login).", E_USER_ERROR);
|
|
||||||
$login = (string) $login[0];
|
|
||||||
$pass = $this->server->config->xpath('pass');
|
|
||||||
if (!$pass) trigger_error("Invalid server configuration (password).", E_USER_ERROR);
|
|
||||||
$pass = (string) $pass[0];
|
|
||||||
|
|
||||||
// Authenticate
|
|
||||||
if (!$this->client->query('Authenticate', $login, $pass)) {
|
|
||||||
trigger_error(
|
|
||||||
"Couldn't authenticate on server with user '" . $login . "'! " . $this->client->getErrorMessage() . "(" .
|
|
||||||
$this->client->getErrorCode() . ")", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable callback system
|
|
||||||
if (!$this->client->query('EnableCallbacks', true)) {
|
|
||||||
trigger_error("Couldn't enable callbacks! " . $this->client->getErrorMessage() . "(" . $this->client->getErrorCode() . ")",
|
|
||||||
E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for server to be ready
|
|
||||||
if (!$this->server->waitForStatus($this->client, 4)) {
|
|
||||||
trigger_error("Server couldn't get ready!", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set api version
|
|
||||||
if (!$this->client->query('SetApiVersion', self::API_VERSION)) {
|
|
||||||
trigger_error(
|
|
||||||
"Couldn't set API version '" . self::API_VERSION . "'! This might cause problems. " .
|
|
||||||
$this->iControl->getClientErrorText());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect finished
|
|
||||||
error_log("Server connection succesfully established!");
|
|
||||||
|
|
||||||
// Enable service announces
|
|
||||||
if (!$this->client->query("DisableServiceAnnounces", false)) {
|
|
||||||
trigger_error("Couldn't enable service announces. " . $this->iControl->getClientErrorText());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable script callbacks if needed
|
|
||||||
if ($this->server->getGameMode() === 0) {
|
|
||||||
if (!$this->client->query('GetModeScriptSettings')) {
|
|
||||||
trigger_error("Couldn't get mode script settings. " . $this->iControl->getClientErrorText());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$scriptSettings = $this->client->getResponse();
|
|
||||||
if (array_key_exists('S_UseScriptCallbacks', $scriptSettings)) {
|
|
||||||
$scriptSettings['S_UseScriptCallbacks'] = true;
|
|
||||||
if (!$this->client->query('SetModeScriptSettings', $scriptSettings)) {
|
|
||||||
trigger_error(
|
|
||||||
"Couldn't set mode script settings to enable script callbacks. " . $this->iControl->getClientErrorText());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error_log("Script callbacks successfully enabled.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load iControl plugins
|
|
||||||
*/
|
|
||||||
private function loadPlugins() {
|
|
||||||
$pluginsConfig = Tools::loadConfig('plugins.iControl.xml');
|
|
||||||
if (!$pluginsConfig || !isset($pluginsConfig->plugin)) {
|
|
||||||
trigger_error('Invalid plugins config.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load plugin classes
|
|
||||||
$classes = get_declared_classes();
|
|
||||||
foreach ($pluginsConfig->xpath('plugin') as $plugin) {
|
|
||||||
$fileName = ICONTROL . '/plugins/' . $plugin;
|
|
||||||
if (!file_exists($fileName)) {
|
|
||||||
trigger_error("Couldn't load plugin '" . $plugin . "'! File doesn't exist. (/plugins/" . $plugin . ")");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
require_once $fileName;
|
|
||||||
error_log("Loading plugin: " . $plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$plugins = array_diff(get_declared_classes(), $classes);
|
|
||||||
|
|
||||||
// Create plugins
|
|
||||||
foreach ($plugins as $plugin) {
|
|
||||||
$nameIndex = stripos($plugin, 'plugin');
|
|
||||||
if ($nameIndex === false) continue;
|
|
||||||
array_push($this->plugins, new $plugin($this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle EndMap callback
|
|
||||||
*/
|
|
||||||
public function handleEndMap($callback) {
|
|
||||||
// Autosave match settings
|
|
||||||
$autosaveMatchsettings = $this->config->xpath('autosave_matchsettings');
|
|
||||||
if ($autosaveMatchsettings) {
|
|
||||||
$autosaveMatchsettings = (string) $autosaveMatchsettings[0];
|
|
||||||
if ($autosaveMatchsettings) {
|
|
||||||
if (!$this->client->query('SaveMatchSettings', 'MatchSettings/' . $autosaveMatchsettings)) {
|
|
||||||
trigger_error("Couldn't autosave match settings. " . $this->iControl->getClientErrorText());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check config settings
|
|
||||||
*/
|
|
||||||
public function checkConfig($config, $settings, $name = 'Config XML') {
|
|
||||||
if (!is_array($settings)) $settings = array($settings);
|
|
||||||
foreach ($settings as $setting) {
|
|
||||||
$settingTags = $config->xpath('//' . $setting);
|
|
||||||
if (empty($settingTags)) {
|
|
||||||
trigger_error("Missing property '" . $setting . "' in config '" . $name . "'!", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@ -1,401 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace iControl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for database connection
|
|
||||||
*
|
|
||||||
* @author steeffeen
|
|
||||||
*/
|
|
||||||
class Database {
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
const TABLE_PLAYERS = 'ic_players';
|
|
||||||
const TABLE_MAPS = 'ic_maps';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public properties
|
|
||||||
*/
|
|
||||||
public $mysqli = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private properties
|
|
||||||
*/
|
|
||||||
private $iControl = null;
|
|
||||||
|
|
||||||
private $config = null;
|
|
||||||
|
|
||||||
private $multiQueries = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct database connection
|
|
||||||
*/
|
|
||||||
public function __construct($iControl) {
|
|
||||||
$this->iControl = $iControl;
|
|
||||||
|
|
||||||
// Load config
|
|
||||||
$this->config = Tools::loadConfig('database.iControl.xml');
|
|
||||||
$this->iControl->checkConfig($this->config, array("host", "user"), 'database.iControl.xml');
|
|
||||||
|
|
||||||
// Get mysql server information
|
|
||||||
$host = $this->config->xpath('host');
|
|
||||||
if (!$host) trigger_error("Invalid database configuration (host).", E_USER_ERROR);
|
|
||||||
$host = (string) $host[0];
|
|
||||||
|
|
||||||
$port = $this->config->xpath('port');
|
|
||||||
if (!$port) trigger_error("Invalid database configuration (port).", E_USER_ERROR);
|
|
||||||
$port = (int) $port[0];
|
|
||||||
|
|
||||||
$user = $this->config->xpath('user');
|
|
||||||
if (!$user) trigger_error("Invalid database configuration (user).", E_USER_ERROR);
|
|
||||||
$user = (string) $user[0];
|
|
||||||
|
|
||||||
$pass = $this->config->xpath('pass');
|
|
||||||
if (!$pass) trigger_error("Invalid database configuration (pass).", E_USER_ERROR);
|
|
||||||
$pass = (string) $pass[0];
|
|
||||||
|
|
||||||
// Open database connection
|
|
||||||
$this->mysqli = new \mysqli($host, $user, $pass, null, $port);
|
|
||||||
if ($this->mysqli->connect_error) {
|
|
||||||
// Connection error
|
|
||||||
throw new \Exception(
|
|
||||||
"Error on connecting to mysql server. " . $this->mysqli->connect_error . " (" . $this->mysqli->connect_errno . ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set charset
|
|
||||||
$this->mysqli->set_charset("utf8");
|
|
||||||
|
|
||||||
// Create/Connect database
|
|
||||||
$this->initDatabase();
|
|
||||||
|
|
||||||
// Init tables
|
|
||||||
$this->initTables();
|
|
||||||
|
|
||||||
// Register for callbacks
|
|
||||||
$this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_5_SECOND, $this, 'handle5Second');
|
|
||||||
$this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_BEGINMAP, $this, 'handleBeginMap');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destruct database connection
|
|
||||||
*/
|
|
||||||
public function __destruct() {
|
|
||||||
$this->mysqli->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connect to the defined database (create it if needed)
|
|
||||||
*/
|
|
||||||
private function initDatabase() {
|
|
||||||
$dbname = $this->config->xpath('database');
|
|
||||||
if (!$dbname) trigger_error("Invalid database configuration (database).", E_USER_ERROR);
|
|
||||||
$dbname = (string) $dbname[0];
|
|
||||||
|
|
||||||
// Try to connect
|
|
||||||
$result = $this->mysqli->select_db($dbname);
|
|
||||||
if (!$result) {
|
|
||||||
// Create database
|
|
||||||
$query = "CREATE DATABASE `" . $this->escape($dbname) . "`;";
|
|
||||||
$result = $this->mysqli->query($query);
|
|
||||||
if (!$result) {
|
|
||||||
trigger_error(
|
|
||||||
"Couldn't create database '" . $dbname . "'. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')',
|
|
||||||
E_USER_ERROR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Connect to database
|
|
||||||
$result = $this->mysqli->select_db($dbname);
|
|
||||||
if (!$result) {
|
|
||||||
trigger_error(
|
|
||||||
"Couldn't select database '" . $dbname . "'. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')',
|
|
||||||
E_USER_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the needed tables
|
|
||||||
*/
|
|
||||||
private function initTables() {
|
|
||||||
$query = "";
|
|
||||||
|
|
||||||
// Players table
|
|
||||||
$query .= "CREATE TABLE IF NOT EXISTS `" . self::TABLE_PLAYERS . "` (
|
|
||||||
`index` int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`Login` varchar(100) NOT NULL,
|
|
||||||
`NickName` varchar(250) NOT NULL,
|
|
||||||
`PlayerId` int(11) NOT NULL,
|
|
||||||
`LadderRanking` int(11) NOT NULL,
|
|
||||||
`Flags` varchar(50) NOT NULL,
|
|
||||||
`changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
||||||
PRIMARY KEY (`index`),
|
|
||||||
UNIQUE KEY `Login` (`Login`)
|
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Store player metadata' AUTO_INCREMENT=1;";
|
|
||||||
|
|
||||||
// Maps table
|
|
||||||
$query .= "CREATE TABLE IF NOT EXISTS `ic_maps` (
|
|
||||||
`index` int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`UId` varchar(100) NOT NULL,
|
|
||||||
`Name` varchar(100) NOT NULL,
|
|
||||||
`FileName` varchar(200) NOT NULL,
|
|
||||||
`Author` varchar(150) NOT NULL,
|
|
||||||
`Environnement` varchar(50) NOT NULL,
|
|
||||||
`Mood` varchar(50) NOT NULL,
|
|
||||||
`BronzeTime` int(11) NOT NULL DEFAULT '-1',
|
|
||||||
`SilverTime` int(11) NOT NULL DEFAULT '-1',
|
|
||||||
`GoldTime` int(11) NOT NULL DEFAULT '-1',
|
|
||||||
`AuthorTime` int(11) NOT NULL DEFAULT '-1',
|
|
||||||
`CopperPrice` int(11) NOT NULL DEFAULT '-1',
|
|
||||||
`LapRace` tinyint(1) NOT NULL,
|
|
||||||
`NbLaps` int(11) NOT NULL DEFAULT '-1',
|
|
||||||
`NbCheckpoints` int(11) NOT NULL DEFAULT '-1',
|
|
||||||
`MapType` varchar(100) NOT NULL,
|
|
||||||
`MapStyle` varchar(100) NOT NULL,
|
|
||||||
`changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
||||||
PRIMARY KEY (`index`),
|
|
||||||
UNIQUE KEY `UId` (`UId`)
|
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Store map metadata' AUTO_INCREMENT=1;";
|
|
||||||
|
|
||||||
// Perform queries
|
|
||||||
if (!$this->multiQuery($query)) {
|
|
||||||
trigger_error("Creating basic tables failed. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')', E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimize all existing tables
|
|
||||||
$query = "SHOW TABLES;";
|
|
||||||
$result = $this->query($query);
|
|
||||||
if (!$result || !is_object($result)) {
|
|
||||||
trigger_error("Couldn't select tables. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$query = "OPTIMIZE TABLE ";
|
|
||||||
$count = $result->num_rows;
|
|
||||||
$index = 0;
|
|
||||||
while ($row = $result->fetch_row()) {
|
|
||||||
$query .= "`" . $row[0] . "`";
|
|
||||||
if ($index < $count - 1) $query .= ", ";
|
|
||||||
$index++;
|
|
||||||
}
|
|
||||||
$query .= ";";
|
|
||||||
if (!$this->query($query)) {
|
|
||||||
trigger_error("Couldn't optimize tables. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for performing a simple query
|
|
||||||
*
|
|
||||||
* @param string $query
|
|
||||||
* @return mixed query result
|
|
||||||
*/
|
|
||||||
public function query($query) {
|
|
||||||
if (!is_string($query)) return false;
|
|
||||||
if (strlen($query) <= 0) return true;
|
|
||||||
return $this->mysqli->query($query);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform multi query
|
|
||||||
*
|
|
||||||
* @param
|
|
||||||
* string multi_query
|
|
||||||
* @return bool whether no error occured during executing the multi query
|
|
||||||
*/
|
|
||||||
public function multiQuery($query) {
|
|
||||||
if (!is_string($query)) return false;
|
|
||||||
if (strlen($query) <= 0) return true;
|
|
||||||
$noError = true;
|
|
||||||
$this->mysqli->multi_query($query);
|
|
||||||
if ($this->mysqli->error) {
|
|
||||||
trigger_error("Executing multi query failed. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
|
|
||||||
$noError = false;
|
|
||||||
}
|
|
||||||
while ($this->mysqli->more_results() && $this->mysqli->next_result()) {
|
|
||||||
if ($this->mysqli->error) {
|
|
||||||
trigger_error("Executing multi query failed. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
|
|
||||||
$noError = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $noError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle 5Second callback
|
|
||||||
*/
|
|
||||||
public function handle5Second($callback = null) {
|
|
||||||
// Save current players in database
|
|
||||||
$players = $this->iControl->server->getPlayers();
|
|
||||||
if ($players) {
|
|
||||||
$query = "";
|
|
||||||
foreach ($players as $player) {
|
|
||||||
if (!Tools::isPlayer($player)) continue;
|
|
||||||
$query .= $this->composeInsertPlayer($player);
|
|
||||||
}
|
|
||||||
$this->multiQuery($query);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle BeginMap callback
|
|
||||||
*/
|
|
||||||
public function handleBeginMap($callback) {
|
|
||||||
$map = $callback[1][0];
|
|
||||||
$query = $this->composeInsertMap($map);
|
|
||||||
$result = $this->query($query);
|
|
||||||
if ($this->mysqli->error) {
|
|
||||||
trigger_error("Couldn't save map. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the player index for the given login
|
|
||||||
*
|
|
||||||
* @param string $login
|
|
||||||
* @return int null
|
|
||||||
*/
|
|
||||||
public function getPlayerIndex($login) {
|
|
||||||
$query = "SELECT `index` FROM `" . self::TABLE_PLAYERS . "` WHERE `Login` = '" . $this->escape($login) . "';";
|
|
||||||
$result = $this->query($query);
|
|
||||||
$result = $result->fetch_assoc();
|
|
||||||
if ($result) {
|
|
||||||
return $result['index'];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the map index for the given UId
|
|
||||||
*
|
|
||||||
* @param string $uid
|
|
||||||
* @return int null
|
|
||||||
*/
|
|
||||||
public function getMapIndex($uid) {
|
|
||||||
$query = "SELECT `index` FROM `" . self::TABLE_MAPS . "` WHERE `UId` = '" . $this->escape($uid) . "';";
|
|
||||||
$result = $this->query($query);
|
|
||||||
$result = $result->fetch_assoc();
|
|
||||||
if ($result) {
|
|
||||||
return $result['index'];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compose a query string for inserting the given player
|
|
||||||
*
|
|
||||||
* @param array $player
|
|
||||||
*/
|
|
||||||
private function composeInsertPlayer($player) {
|
|
||||||
if (!Tools::isPlayer($player)) return "";
|
|
||||||
return "INSERT INTO `" . self::TABLE_PLAYERS . "` (
|
|
||||||
`Login`,
|
|
||||||
`NickName`,
|
|
||||||
`PlayerId`,
|
|
||||||
`LadderRanking`,
|
|
||||||
`Flags`
|
|
||||||
) VALUES (
|
|
||||||
'" . $this->escape($player['Login']) . "',
|
|
||||||
'" . $this->escape($player['NickName']) . "',
|
|
||||||
" . $player['PlayerId'] . ",
|
|
||||||
" . $player['LadderRanking'] . ",
|
|
||||||
'" . $this->escape($player['Flags']) . "'
|
|
||||||
) ON DUPLICATE KEY UPDATE
|
|
||||||
`NickName` = VALUES(`NickName`),
|
|
||||||
`PlayerId` = VALUES(`PlayerId`),
|
|
||||||
`LadderRanking` = VALUES(`LadderRanking`),
|
|
||||||
`Flags` = VALUES(`Flags`);";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compose a query string for inserting the given map
|
|
||||||
*
|
|
||||||
* @param array $map
|
|
||||||
*/
|
|
||||||
private function composeInsertMap($map) {
|
|
||||||
if (!$map) return "";
|
|
||||||
return "INSERT INTO `" . self::TABLE_MAPS . "` (
|
|
||||||
`UId`,
|
|
||||||
`Name`,
|
|
||||||
`FileName`,
|
|
||||||
`Author`,
|
|
||||||
`Environnement`,
|
|
||||||
`Mood`,
|
|
||||||
`BronzeTime`,
|
|
||||||
`SilverTime`,
|
|
||||||
`GoldTime`,
|
|
||||||
`AuthorTime`,
|
|
||||||
`CopperPrice`,
|
|
||||||
`LapRace`,
|
|
||||||
`NbLaps`,
|
|
||||||
`NbCheckpoints`,
|
|
||||||
`MapType`,
|
|
||||||
`MapStyle`
|
|
||||||
) VALUES (
|
|
||||||
'" . $this->escape($map['UId']) . "',
|
|
||||||
'" . $this->escape($map['Name']) . "',
|
|
||||||
'" . $this->escape($map['FileName']) . "',
|
|
||||||
'" . $this->escape($map['Author']) . "',
|
|
||||||
'" . $this->escape($map['Environnement']) . "',
|
|
||||||
'" . $this->escape($map['Mood']) . "',
|
|
||||||
" . $map['BronzeTime'] . ",
|
|
||||||
" . $map['SilverTime'] . ",
|
|
||||||
" . $map['GoldTime'] . ",
|
|
||||||
" . $map['AuthorTime'] . ",
|
|
||||||
" . $map['CopperPrice'] . ",
|
|
||||||
" . Tools::boolToInt($map['LapRace']) . ",
|
|
||||||
" . $map['NbLaps'] . ",
|
|
||||||
" . $map['NbCheckpoints'] . ",
|
|
||||||
'" . $this->escape($map['MapType']) . "',
|
|
||||||
'" . $this->escape($map['MapStyle']) . "'
|
|
||||||
) ON DUPLICATE KEY UPDATE
|
|
||||||
`Name` = VALUES(`Name`),
|
|
||||||
`FileName` = VALUES(`FileName`),
|
|
||||||
`Author` = VALUES(`Author`),
|
|
||||||
`Environnement` = VALUES(`Environnement`),
|
|
||||||
`Mood` = VALUES(`Mood`),
|
|
||||||
`BronzeTime` = VALUES(`BronzeTime`),
|
|
||||||
`SilverTime` = VALUES(`SilverTime`),
|
|
||||||
`GoldTime` = VALUES(`GoldTime`),
|
|
||||||
`AuthorTime` = VALUES(`AuthorTime`),
|
|
||||||
`CopperPrice` = VALUES(`CopperPrice`),
|
|
||||||
`LapRace` = VALUES(`LapRace`),
|
|
||||||
`NbLaps` = VALUES(`NbLaps`),
|
|
||||||
`NbCheckpoints` = VALUES(`NbCheckpoints`),
|
|
||||||
`MapType` = VALUES(`MapType`),
|
|
||||||
`MapStyle` = VALUES(`MapStyle`);";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve all information about the player with the given login
|
|
||||||
*/
|
|
||||||
public function getPlayer($login) {
|
|
||||||
if (!$login) return null;
|
|
||||||
$query = "SELECT * FROM `" . self::TABLE_PLAYERS . "` WHERE `Login` = '" . $this->escape($login) . "';";
|
|
||||||
$result = $this->mysqli->query($query);
|
|
||||||
if ($this->mysqli->error || !$result) {
|
|
||||||
trigger_error(
|
|
||||||
"Couldn't select player with login '" . $login . "'. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
while ($player = $result->fetch_assoc()) {
|
|
||||||
return $player;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Escapes the given string for a mysql query
|
|
||||||
*
|
|
||||||
* @param string $string
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function escape($string) {
|
|
||||||
return $this->mysqli->escape_string($string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@ -1,381 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace iControl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class providing information and commands for the connected maniaplanet server
|
|
||||||
*
|
|
||||||
* @author steeffeen
|
|
||||||
*/
|
|
||||||
class Server {
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
const VALIDATIONREPLAYDIR = 'ValidationReplays/';
|
|
||||||
const GHOSTREPLAYDIR = 'GhostReplays/';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public properties
|
|
||||||
*/
|
|
||||||
public $config = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private properties
|
|
||||||
*/
|
|
||||||
private $iControl = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct server
|
|
||||||
*/
|
|
||||||
public function __construct($iControl) {
|
|
||||||
$this->iControl = $iControl;
|
|
||||||
|
|
||||||
// Load config
|
|
||||||
$this->config = Tools::loadConfig('server.iControl.xml');
|
|
||||||
$this->iControl->checkConfig($this->config, array('host', 'port', 'login', 'pass'), 'server');
|
|
||||||
|
|
||||||
// Register for callbacks
|
|
||||||
$this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_1_SECOND, $this, 'eachSecond');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform actions every second
|
|
||||||
*/
|
|
||||||
public function eachSecond() {
|
|
||||||
// Delete cached information
|
|
||||||
$this->players = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch game directory of the server
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getDataDirectory() {
|
|
||||||
if (!$this->iControl->client->query('GameDataDirectory')) {
|
|
||||||
trigger_error("Couldn't get data directory. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $this->iControl->client->getResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if iControl has access to the given directory (server data directory if no param)
|
|
||||||
*
|
|
||||||
* @param string $directory
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function checkAccess($directory = null) {
|
|
||||||
if (!$directory) {
|
|
||||||
$directory = $this->getDataDirectory();
|
|
||||||
}
|
|
||||||
return is_dir($directory) && is_writable($directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch server login
|
|
||||||
*/
|
|
||||||
public function getLogin($client = null) {
|
|
||||||
$systemInfo = $this->getSystemInfo(false, $client);
|
|
||||||
if (!$systemInfo) return null;
|
|
||||||
return $systemInfo['ServerLogin'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get detailed server info
|
|
||||||
*/
|
|
||||||
public function getInfo($detailed = false) {
|
|
||||||
if ($detailed) {
|
|
||||||
$login = $this->getLogin();
|
|
||||||
if (!$this->iControl->client->query('GetDetailedPlayerInfo', $login)) {
|
|
||||||
trigger_error("Couldn't fetch detailed server player info. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!$this->iControl->client->query('GetMainServerPlayerInfo')) {
|
|
||||||
trigger_error("Couldn't fetch server player info. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $this->iControl->client->getResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get server options
|
|
||||||
*/
|
|
||||||
public function getOptions() {
|
|
||||||
if (!$this->iControl->client->query('GetServerOptions')) {
|
|
||||||
trigger_error("Couldn't fetch server options. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $this->iControl->client->getResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch server name
|
|
||||||
*/
|
|
||||||
public function getName() {
|
|
||||||
if (!$this->iControl->client->query('GetServerName')) {
|
|
||||||
trigger_error("Couldn't fetch server name. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $this->iControl->client->getResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch server version
|
|
||||||
*/
|
|
||||||
public function getVersion($forceRefresh = false) {
|
|
||||||
if (isset($this->iControl->client->version) && !$forceRefresh) return $this->iControl->client->version;
|
|
||||||
if (!$this->iControl->client->query('GetVersion')) {
|
|
||||||
trigger_error("Couldn't fetch server version. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->iControl->client->version = $this->iControl->client->getResponse();
|
|
||||||
return $this->iControl->client->version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch server system info
|
|
||||||
*/
|
|
||||||
public function getSystemInfo($forceRefresh = false, &$client = null) {
|
|
||||||
if (!$this->iControl->client && !$client) return null;
|
|
||||||
if (!$client) $client = $this->iControl->client;
|
|
||||||
if (isset($client->systemInfo) && !$forceRefresh) return $client->systemInfo;
|
|
||||||
if (!$client->query('GetSystemInfo')) {
|
|
||||||
trigger_error("Couldn't fetch server system info. " . $this->iControl->getClientErrorText($client));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$client->systemInfo = $client->getResponse();
|
|
||||||
return $client->systemInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch network status
|
|
||||||
*/
|
|
||||||
public function getNetworkStats($forceRefresh = false) {
|
|
||||||
if (isset($this->iControl->client->networkStats) && !$forceRefresh) return $this->iControl->client->networkStats;
|
|
||||||
if (!$this->iControl->client->query('GetNetworkStats')) {
|
|
||||||
trigger_error("Couldn't fetch network stats. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->iControl->client->networkStats = $this->iControl->client->getResponse();
|
|
||||||
return $this->iControl->client->networkStats;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch current game mode
|
|
||||||
*
|
|
||||||
* @param bool $stringValue
|
|
||||||
* @param int $parseValue
|
|
||||||
* @return int | string
|
|
||||||
*/
|
|
||||||
public function getGameMode($stringValue = false, $parseValue = null) {
|
|
||||||
if (is_int($parseValue)) {
|
|
||||||
$gameMode = $parseValue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!$this->iControl->client->query('GetGameMode')) {
|
|
||||||
trigger_error("Couldn't fetch current game mode. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$gameMode = $this->iControl->client->getResponse();
|
|
||||||
}
|
|
||||||
if ($stringValue) {
|
|
||||||
switch ($gameMode) {
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
return 'Script';
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
return 'Rounds';
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
return 'TimeAttack';
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
return 'Team';
|
|
||||||
}
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
return 'Laps';
|
|
||||||
}
|
|
||||||
case 5:
|
|
||||||
{
|
|
||||||
return 'Cup';
|
|
||||||
}
|
|
||||||
case 6:
|
|
||||||
{
|
|
||||||
return 'Stunts';
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return 'Unknown';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $gameMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch player info
|
|
||||||
*
|
|
||||||
* @param string $login
|
|
||||||
* @return struct
|
|
||||||
*/
|
|
||||||
public function getPlayer($login, $detailed = false) {
|
|
||||||
if (!$login) return null;
|
|
||||||
$command = ($detailed ? 'GetDetailedPlayerInfo' : 'GetPlayerInfo');
|
|
||||||
if (!$this->iControl->client->query($command, $login)) {
|
|
||||||
trigger_error("Couldn't player info for '" . $login . "'. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $this->iControl->client->getResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch all players
|
|
||||||
*/
|
|
||||||
public function getPlayers(&$client = null, &$purePlayers = null, &$pureSpectators = null) {
|
|
||||||
if (!$this->iControl->client && !$client) return null;
|
|
||||||
if (!$client) $client = $this->iControl->client;
|
|
||||||
$fetchLength = 30;
|
|
||||||
$offset = 0;
|
|
||||||
$players = array();
|
|
||||||
if (!is_array($purePlayers)) $purePlayers = array();
|
|
||||||
if (!is_array($pureSpectators)) $pureSpectators = array();
|
|
||||||
$tries = 0;
|
|
||||||
while ($tries < 10) {
|
|
||||||
if (!$client->query('GetPlayerList', $fetchLength, $offset)) {
|
|
||||||
trigger_error("Couldn't get player list. " . $this->iControl->getClientErrorText($client));
|
|
||||||
$tries++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$chunk = $client->getResponse();
|
|
||||||
$count = count($chunk);
|
|
||||||
$serverLogin = $this->getLogin($client);
|
|
||||||
for ($index = 0; $index < $count; $index++) {
|
|
||||||
$login = $chunk[$index]['Login'];
|
|
||||||
if ($login === $serverLogin) {
|
|
||||||
// Ignore server
|
|
||||||
unset($chunk[$index]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ($chunk[$index]['SpectatorStatus'] > 0) {
|
|
||||||
// Pure spectator
|
|
||||||
array_push($pureSpectators, $chunk[$index]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Pure player
|
|
||||||
array_push($purePlayers, $chunk[$index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$players = array_merge($players, $chunk);
|
|
||||||
$offset += $count;
|
|
||||||
if ($count < $fetchLength) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $players;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve validation replay for given login
|
|
||||||
*
|
|
||||||
* @param string $login
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getValidationReplay($login) {
|
|
||||||
if (!$login) return null;
|
|
||||||
if (!$this->iControl->client->query('GetValidationReplay', $login)) {
|
|
||||||
trigger_error("Couldn't get validation replay of '" . $login . "'. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $this->iControl->client->getResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getGhostReplay($login) {
|
|
||||||
$dataDir = $this->getDataDirectory();
|
|
||||||
if (!$this->checkAccess($dataDir)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build file name
|
|
||||||
$map = $this->getMap();
|
|
||||||
$gameMode = $this->getGameMode();
|
|
||||||
$time = time();
|
|
||||||
$fileName = 'Ghost.' . $login . '.' . $gameMode . '.' . $time . '.' . $map['UId'] . '.Replay.Gbx';
|
|
||||||
|
|
||||||
// Save ghost replay
|
|
||||||
if (!$this->iControl->client->query('SaveBestGhostsReplay', $login, self::GHOSTREPLAYDIR . $fileName)) {
|
|
||||||
trigger_error("Couldn't save ghost replay. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load replay file
|
|
||||||
$ghostReplay = file_get_contents($dataDir . 'Replays/' . self::GHOSTREPLAYDIR . $fileName);
|
|
||||||
if (!$ghostReplay) {
|
|
||||||
trigger_error("Couldn't retrieve saved ghost replay.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $ghostReplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch current map
|
|
||||||
*/
|
|
||||||
public function getMap() {
|
|
||||||
if (!$this->iControl->client) return null;
|
|
||||||
if (!$this->iControl->client->query('GetCurrentMapInfo')) {
|
|
||||||
trigger_error("Couldn't fetch map info. " . $this->iControl->getClientErrorText());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $this->iControl->client->getResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Waits for the server to have the given status
|
|
||||||
*/
|
|
||||||
public function waitForStatus($client, $statusCode = 4) {
|
|
||||||
$client->query('GetStatus');
|
|
||||||
$response = $client->getResponse();
|
|
||||||
// Check if server reached given status
|
|
||||||
if ($response['Code'] === 4) return true;
|
|
||||||
// Server not yet in given status -> Wait for it...
|
|
||||||
$waitBegin = time();
|
|
||||||
$timeoutTags = $this->iControl->config->xpath('timeout');
|
|
||||||
$maxWaitTime = (!empty($timeoutTags) ? (int) $timeoutTags[0] : 20);
|
|
||||||
$lastStatus = $response['Name'];
|
|
||||||
error_log("Waiting for server to reach status " . $statusCode . "...");
|
|
||||||
error_log("Current Status: " . $lastStatus);
|
|
||||||
while ($response['Code'] !== 4) {
|
|
||||||
sleep(1);
|
|
||||||
$client->query('GetStatus');
|
|
||||||
$response = $client->getResponse();
|
|
||||||
if ($lastStatus !== $response['Name']) {
|
|
||||||
error_log("New Status: " . $response['Name']);
|
|
||||||
$lastStatus = $response['Name'];
|
|
||||||
}
|
|
||||||
if (time() - $maxWaitTime > $waitBegin) {
|
|
||||||
// It took too long to reach the status
|
|
||||||
trigger_error(
|
|
||||||
"Server couldn't reach status " . $statusCode . " after " . $maxWaitTime . " seconds! " .
|
|
||||||
$this->iControl->getClientErrorText());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@ -1,297 +0,0 @@
|
|||||||
<?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.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@ -1,240 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace iControl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for basic tools
|
|
||||||
*
|
|
||||||
* @author steeffeen
|
|
||||||
*/
|
|
||||||
class Tools {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the given setting is enabled
|
|
||||||
*
|
|
||||||
* @param simple_xml_element $config
|
|
||||||
* @param string $setting
|
|
||||||
*/
|
|
||||||
public static function checkSetting($config, $setting) {
|
|
||||||
$settings = $config->xpath('//' . $setting);
|
|
||||||
if (empty($settings)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
foreach ($settings as $setting) {
|
|
||||||
return self::toBool((string) $setting[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the given data describes a player
|
|
||||||
*
|
|
||||||
* @param array $player
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function isPlayer($player) {
|
|
||||||
if (!$player || !is_array($player)) return false;
|
|
||||||
if (!array_key_exists('PlayerId', $player) || !is_int($player['PlayerId']) || $player['PlayerId'] <= 0) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the given time int to mysql timestamp
|
|
||||||
*
|
|
||||||
* @param int $time
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function timeToTimestamp($time) {
|
|
||||||
return date("Y-m-d H:i:s", $time);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add alignment attributes to an xml element
|
|
||||||
*
|
|
||||||
* @param simple_xml_element $xml
|
|
||||||
* @param string $halign
|
|
||||||
* @param string $valign
|
|
||||||
*/
|
|
||||||
public static function addAlignment($xml, $halign = 'center', $valign = 'center2') {
|
|
||||||
if (!is_object($xml) || !method_exists($xml, 'addAttribute')) return;
|
|
||||||
if (!property_exists($xml, 'halign')) $xml->addAttribute('halign', $halign);
|
|
||||||
if (!property_exists($xml, 'valign')) $xml->addAttribute('valign', $valign);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add translate attribute to an xml element
|
|
||||||
*
|
|
||||||
* @param simple_xml_element $xml
|
|
||||||
* @param bool $translate
|
|
||||||
*/
|
|
||||||
public static function addTranslate($xml, $translate = true) {
|
|
||||||
if (!is_object($xml) || !method_exists($xml, 'addAttribute')) return;
|
|
||||||
if (!property_exists($xml, 'translate')) $xml->addAttribute('translate', ($translate ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load a remote file
|
|
||||||
*
|
|
||||||
* @param string $url
|
|
||||||
* @return string || null
|
|
||||||
*/
|
|
||||||
public static function loadFile($url) {
|
|
||||||
if (!$url) return false;
|
|
||||||
$urlData = parse_url($url);
|
|
||||||
$port = (isset($urlData['port']) ? $urlData['port'] : 80);
|
|
||||||
|
|
||||||
$fsock = fsockopen($urlData['host'], $port);
|
|
||||||
stream_set_timeout($fsock, 3);
|
|
||||||
|
|
||||||
$query = 'GET ' . $urlData['path'] . ' HTTP/1.0' . PHP_EOL;
|
|
||||||
$query .= 'Host: ' . $urlData['host'] . PHP_EOL;
|
|
||||||
$query .= 'Content-Type: UTF-8' . PHP_EOL;
|
|
||||||
$query .= 'User-Agent: iControl v' . iControl::VERSION . PHP_EOL;
|
|
||||||
$query .= PHP_EOL;
|
|
||||||
|
|
||||||
fwrite($fsock, $query);
|
|
||||||
|
|
||||||
$buffer = '';
|
|
||||||
$info = array('timed_out' => false);
|
|
||||||
while (!feof($fsock) && !$info['timed_out']) {
|
|
||||||
$buffer .= fread($fsock, 1024);
|
|
||||||
$info = stream_get_meta_data($fsock);
|
|
||||||
}
|
|
||||||
fclose($fsock);
|
|
||||||
|
|
||||||
if ($info['timed_out'] || !$buffer) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (substr($buffer, 9, 3) != "200") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = explode("\r\n\r\n", $buffer, 2);
|
|
||||||
|
|
||||||
if (count($result) < 2) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats the given time (milliseconds)
|
|
||||||
*
|
|
||||||
* @param int $time
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function formatTime($time) {
|
|
||||||
if (!is_int($time)) $time = (int) $time;
|
|
||||||
$milliseconds = $time % 1000;
|
|
||||||
$seconds = floor($time / 1000);
|
|
||||||
$minutes = floor($seconds / 60);
|
|
||||||
$hours = floor($minutes / 60);
|
|
||||||
$minutes -= $hours * 60;
|
|
||||||
$seconds -= $hours * 60 + $minutes * 60;
|
|
||||||
$format = ($hours > 0 ? $hours . ':' : '');
|
|
||||||
$format .= ($hours > 0 && $minutes < 10 ? '0' : '') . $minutes . ':';
|
|
||||||
$format .= ($seconds < 10 ? '0' : '') . $seconds . ':';
|
|
||||||
$format .= ($milliseconds < 100 ? '0' : '') . ($milliseconds < 10 ? '0' : '') . $milliseconds;
|
|
||||||
return $format;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert given data to real boolean
|
|
||||||
*
|
|
||||||
* @param
|
|
||||||
* mixed data
|
|
||||||
*/
|
|
||||||
public static function toBool($var) {
|
|
||||||
if ($var === true) return true;
|
|
||||||
if ($var === false) return false;
|
|
||||||
if ($var === null) return false;
|
|
||||||
if (is_object($var)) {
|
|
||||||
$var = (string) $var;
|
|
||||||
}
|
|
||||||
if (is_int($var)) {
|
|
||||||
return ($var > 0);
|
|
||||||
}
|
|
||||||
else if (is_string($var)) {
|
|
||||||
$text = strtolower($var);
|
|
||||||
if ($text === 'true' || $text === 'yes') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if ($text === 'false' || $text === 'no') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return ((int) $text > 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return (bool) $var;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the given boolean to an int representation
|
|
||||||
*
|
|
||||||
* @param bool $bool
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public static function boolToInt($bool) {
|
|
||||||
return ($bool ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build new simple xml element
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @param string $id
|
|
||||||
* @return \SimpleXMLElement
|
|
||||||
*/
|
|
||||||
public static function newManialinkXml($id = null) {
|
|
||||||
$xml = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" standalone="yes"?><manialink/>');
|
|
||||||
$xml->addAttribute('version', '1');
|
|
||||||
if ($id) $xml->addAttribute('id', $id);
|
|
||||||
return $xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load config xml-file
|
|
||||||
*
|
|
||||||
* @param string $fileName
|
|
||||||
* @return \SimpleXMLElement
|
|
||||||
*/
|
|
||||||
public static function loadConfig($fileName) {
|
|
||||||
// Load config file from configs folder
|
|
||||||
$fileLocation = ICONTROL . '/configs/' . $fileName;
|
|
||||||
if (!file_exists($fileLocation)) {
|
|
||||||
trigger_error("Config file doesn't exist! (" . $fileName . ")", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
return simplexml_load_file($fileLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the given manialink to players
|
|
||||||
*
|
|
||||||
* @param string $manialink
|
|
||||||
* @param array $logins
|
|
||||||
*/
|
|
||||||
public static function sendManialinkPage($client, $manialink, $logins = null, $timeout = 0, $hideOnClick = false) {
|
|
||||||
if (!$client || !$manialink) return;
|
|
||||||
if (!$logins) {
|
|
||||||
// Send manialink to all players
|
|
||||||
$client->query('SendDisplayManialinkPage', $manialink, $timeout, $hideOnClick);
|
|
||||||
}
|
|
||||||
else if (is_array($logins)) {
|
|
||||||
// Send manialink to players
|
|
||||||
foreach ($logins as $login) {
|
|
||||||
$client->query('SendDisplayManialinkPageToLogin', $login, $manialink, $timeout, $hideOnClick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (is_string($logins)) {
|
|
||||||
// Send manialink to player
|
|
||||||
$client->query('SendDisplayManialinkPageToLogin', $logins, $manialink, $timeout, $hideOnClick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@ -1,2 +0,0 @@
|
|||||||
REM set the path to your php.exe here
|
|
||||||
START "" /B "D:\Programme\xampp\php\php.exe" -f "iControl.php" 2>&1
|
|
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace iControl;
|
|
||||||
|
|
||||||
define('ICONTROL', __DIR__);
|
|
||||||
|
|
||||||
require_once __DIR__ . '/core/core.iControl.php';
|
|
||||||
|
|
||||||
// Set process settings
|
|
||||||
ini_set('memory_limit', '128M');
|
|
||||||
if (function_exists('date_default_timezone_get') && function_exists('date_default_timezone_set')) {
|
|
||||||
date_default_timezone_set(@date_default_timezone_get());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error handling
|
|
||||||
ini_set('log_errors', 1);
|
|
||||||
ini_set('error_reporting', -1);
|
|
||||||
ini_set('error_log', 'iControl_' . getmypid() . '.log');
|
|
||||||
|
|
||||||
// Start iControl
|
|
||||||
error_log('Loading iControl v' . iControl::VERSION . '!');
|
|
||||||
|
|
||||||
$iControl = new iControl();
|
|
||||||
$iControl->run(true);
|
|
||||||
|
|
||||||
?>
|
|
@ -1,3 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
php iControl.php 2>&1 &
|
|
||||||
echo $! > iControl.pid
|
|
@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace iControl;
|
namespace mControl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iControl Chatlog Plugin
|
* mControl Chatlog Plugin
|
||||||
*
|
*
|
||||||
* @author steeffeen
|
* @author steeffeen
|
||||||
*/
|
*/
|
||||||
@ -16,7 +16,7 @@ class Plugin_Chatlog {
|
|||||||
/**
|
/**
|
||||||
* Private properties
|
* Private properties
|
||||||
*/
|
*/
|
||||||
private $iControl = null;
|
private $mControl = null;
|
||||||
|
|
||||||
private $config = null;
|
private $config = null;
|
||||||
|
|
||||||
@ -25,8 +25,8 @@ class Plugin_Chatlog {
|
|||||||
/**
|
/**
|
||||||
* Constuct chatlog plugin
|
* Constuct chatlog plugin
|
||||||
*/
|
*/
|
||||||
public function __construct($iControl) {
|
public function __construct($mControl) {
|
||||||
$this->iControl = $iControl;
|
$this->mControl = $mControl;
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
$this->config = Tools::loadConfig('chatlog.plugin.xml');
|
$this->config = Tools::loadConfig('chatlog.plugin.xml');
|
||||||
@ -51,7 +51,7 @@ class Plugin_Chatlog {
|
|||||||
|
|
||||||
// File name
|
// File name
|
||||||
$fileName = (string) $this->config->filename;
|
$fileName = (string) $this->config->filename;
|
||||||
$this->settings->fileName = ICONTROL . '/' . $fileName;
|
$this->settings->fileName = mControl . '/' . $fileName;
|
||||||
|
|
||||||
// log_server_messages
|
// log_server_messages
|
||||||
$log_server_messages = $this->config->xpath('log_server_messages');
|
$log_server_messages = $this->config->xpath('log_server_messages');
|
||||||
@ -77,7 +77,7 @@ class Plugin_Chatlog {
|
|||||||
* @param string $login
|
* @param string $login
|
||||||
*/
|
*/
|
||||||
private function logText($text, $login = null) {
|
private function logText($text, $login = null) {
|
||||||
$message = date(iControl::DATE) . '>> ' . ($login ? $login . ': ' : '') . $text . PHP_EOL;
|
$message = date(mControl::DATE) . '>> ' . ($login ? $login . ': ' : '') . $text . PHP_EOL;
|
||||||
file_put_contents($this->settings->fileName, $message, FILE_APPEND);
|
file_put_contents($this->settings->fileName, $message, FILE_APPEND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace iControl;
|
namespace mControl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iControl Karma Plugin
|
* mControl Karma Plugin
|
||||||
*
|
*
|
||||||
* @author : steeffeen
|
* @author : steeffeen
|
||||||
*/
|
*/
|
||||||
@ -18,7 +18,7 @@ class Plugin_Karma {
|
|||||||
/**
|
/**
|
||||||
* Private properties
|
* Private properties
|
||||||
*/
|
*/
|
||||||
private $iControl = null;
|
private $mControl = null;
|
||||||
|
|
||||||
private $config = null;
|
private $config = null;
|
||||||
|
|
||||||
@ -27,10 +27,10 @@ class Plugin_Karma {
|
|||||||
/**
|
/**
|
||||||
* Construct plugin
|
* Construct plugin
|
||||||
*
|
*
|
||||||
* @param object $iControl
|
* @param object $mControl
|
||||||
*/
|
*/
|
||||||
public function __construct($iControl) {
|
public function __construct($mControl) {
|
||||||
$this->iControl = $iControl;
|
$this->mControl = $mControl;
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
$this->config = Tools::loadConfig('karma.plugin.xml');
|
$this->config = Tools::loadConfig('karma.plugin.xml');
|
||||||
@ -72,7 +72,7 @@ class Plugin_Karma {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle OnInit iControl callback
|
* Handle OnInit mControl callback
|
||||||
*
|
*
|
||||||
* @param array $callback
|
* @param array $callback
|
||||||
*/
|
*/
|
||||||
@ -82,7 +82,7 @@ class Plugin_Karma {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle iControl BeginMap callback
|
* Handle mControl BeginMap callback
|
||||||
*
|
*
|
||||||
* @param array $callback
|
* @param array $callback
|
||||||
*/
|
*/
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace iControl;
|
namespace mControl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iControl Obstacle Plugin
|
* mControl Obstacle Plugin
|
||||||
*
|
*
|
||||||
* @author steeffeen
|
* @author steeffeen
|
||||||
*/
|
*/
|
||||||
@ -17,15 +17,15 @@ class Plugin_Obstacle extends Plugin {
|
|||||||
/**
|
/**
|
||||||
* Private properties
|
* Private properties
|
||||||
*/
|
*/
|
||||||
private $iControl = null;
|
private $mControl = null;
|
||||||
|
|
||||||
private $config = null;
|
private $config = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constuct obstacle plugin
|
* Constuct obstacle plugin
|
||||||
*/
|
*/
|
||||||
public function __construct($iControl) {
|
public function __construct($mControl) {
|
||||||
$this->iControl = $iControl;
|
$this->mControl = $mControl;
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
$this->config = Tools::loadConfig('obstacle.plugin.xml');
|
$this->config = Tools::loadConfig('obstacle.plugin.xml');
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace iControl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract iControl plugin class
|
|
||||||
*/
|
|
||||||
abstract class Plugin_Name {
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
const VERSION = '0.1';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private properties
|
|
||||||
*/
|
|
||||||
private $iControl = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct plugin
|
|
||||||
*
|
|
||||||
* @param object $iControl
|
|
||||||
*/
|
|
||||||
public function __construct($iControl) {
|
|
||||||
$this->iControl = $iControl;
|
|
||||||
|
|
||||||
error_log('Pugin v' . self::VERSION . ' ready!');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform actions during each loop
|
|
||||||
*/
|
|
||||||
public function loop() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace iControl;
|
namespace mControl;
|
||||||
|
|
||||||
// TODO: show mix of best and next records (depending on own one)
|
// TODO: show mix of best and next records (depending on own one)
|
||||||
// TODO: enable keep-alive
|
// TODO: enable keep-alive
|
||||||
@ -11,7 +11,7 @@ namespace iControl;
|
|||||||
// TODO: threaded requests
|
// TODO: threaded requests
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iControl Records Plugin
|
* mControl Records Plugin
|
||||||
*
|
*
|
||||||
* @author steeffeen
|
* @author steeffeen
|
||||||
*/
|
*/
|
||||||
@ -37,7 +37,7 @@ class Plugin_Records {
|
|||||||
/**
|
/**
|
||||||
* Private properties
|
* Private properties
|
||||||
*/
|
*/
|
||||||
private $iControl = null;
|
private $mControl = null;
|
||||||
|
|
||||||
private $settings = null;
|
private $settings = null;
|
||||||
|
|
||||||
@ -58,8 +58,8 @@ class Plugin_Records {
|
|||||||
/**
|
/**
|
||||||
* Constuct plugin
|
* Constuct plugin
|
||||||
*/
|
*/
|
||||||
public function __construct($iControl) {
|
public function __construct($mControl) {
|
||||||
$this->iControl = $iControl;
|
$this->mControl = $mControl;
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
$this->config = Tools::loadConfig('records.plugin.xml');
|
$this->config = Tools::loadConfig('records.plugin.xml');
|
||||||
@ -123,7 +123,7 @@ class Plugin_Records {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle iControl init
|
* Handle mControl init
|
||||||
*/
|
*/
|
||||||
public function handleOnInit($callback = null) {
|
public function handleOnInit($callback = null) {
|
||||||
// Let manialinks update
|
// Let manialinks update
|
||||||
@ -255,8 +255,8 @@ class Plugin_Records {
|
|||||||
$serverVersion = $this->iControl->server->getVersion();
|
$serverVersion = $this->iControl->server->getVersion();
|
||||||
$serverData['ServerVersion'] = $serverVersion['Version'];
|
$serverData['ServerVersion'] = $serverVersion['Version'];
|
||||||
$serverData['ServerBuild'] = $serverVersion['Build'];
|
$serverData['ServerBuild'] = $serverVersion['Build'];
|
||||||
$serverData['Tool'] = 'iControl';
|
$serverData['Tool'] = 'mControl';
|
||||||
$serverData['Version'] = iControl::VERSION;
|
$serverData['Version'] = mControl::VERSION;
|
||||||
$this->dedimaniaData['serverData'] = $serverData;
|
$this->dedimaniaData['serverData'] = $serverData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +267,7 @@ class Plugin_Records {
|
|||||||
$header .= 'Accept-Encoding: gzip;' . PHP_EOL;
|
$header .= 'Accept-Encoding: gzip;' . PHP_EOL;
|
||||||
$header .= 'Content-Type: text/xml; charset=utf-8;' . PHP_EOL;
|
$header .= 'Content-Type: text/xml; charset=utf-8;' . PHP_EOL;
|
||||||
$header .= 'Keep-Alive: 300;' . PHP_EOL;
|
$header .= 'Keep-Alive: 300;' . PHP_EOL;
|
||||||
$header .= 'User-Agent: iControl v' . iControl::VERSION . ';' . PHP_EOL;
|
$header .= 'User-Agent: mControl v' . mControl::VERSION . ';' . PHP_EOL;
|
||||||
$this->dedimaniaData['header'] = $header;
|
$this->dedimaniaData['header'] = $header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace iControl;
|
namespace mControl;
|
||||||
|
|
||||||
// TODO: Jump message "now playing stadium"
|
// TODO: Jump message "now playing stadium"
|
||||||
// TODO: put inactive server in idle (keeping same map)
|
// TODO: put inactive server in idle (keeping same map)
|
||||||
@ -9,7 +9,7 @@ namespace iControl;
|
|||||||
// TODO: max players setting
|
// TODO: max players setting
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iControl United Plugin
|
* mControl United Plugin
|
||||||
*
|
*
|
||||||
* @author steeffeen
|
* @author steeffeen
|
||||||
*/
|
*/
|
||||||
@ -23,7 +23,7 @@ class Plugin_United {
|
|||||||
/**
|
/**
|
||||||
* Private properties
|
* Private properties
|
||||||
*/
|
*/
|
||||||
private $iControl = null;
|
private $mControl = null;
|
||||||
|
|
||||||
private $config = null;
|
private $config = null;
|
||||||
|
|
||||||
@ -46,8 +46,8 @@ class Plugin_United {
|
|||||||
/**
|
/**
|
||||||
* Constuct plugin
|
* Constuct plugin
|
||||||
*/
|
*/
|
||||||
public function __construct($iControl) {
|
public function __construct($mControl) {
|
||||||
$this->iControl = $iControl;
|
$this->mControl = $mControl;
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
$this->config = Tools::loadConfig('united.plugin.xml');
|
$this->config = Tools::loadConfig('united.plugin.xml');
|
||||||
@ -78,7 +78,7 @@ class Plugin_United {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle iControl OnInit callback
|
* Handle mControl OnInit callback
|
||||||
*
|
*
|
||||||
* @param array $callback
|
* @param array $callback
|
||||||
*/
|
*/
|
||||||
@ -303,7 +303,7 @@ class Plugin_United {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build manialink url
|
// Build manialink url
|
||||||
$manialink = 'icontrol?favorite';
|
$manialink = 'mControl?favorite';
|
||||||
foreach ($serverLogins as $serverLogin) {
|
foreach ($serverLogins as $serverLogin) {
|
||||||
$manialink .= '&' . $serverLogin;
|
$manialink .= '&' . $serverLogin;
|
||||||
}
|
}
|
||||||
@ -478,9 +478,9 @@ class Plugin_United {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set api version
|
// Set api version
|
||||||
if (!$client->query('SetApiVersion', iControl::API_VERSION)) {
|
if (!$client->query('SetApiVersion', mControl::API_VERSION)) {
|
||||||
trigger_error(
|
trigger_error(
|
||||||
"Couldn't set API version '" . iControl::API_VERSION . "'! This might cause problems. " .
|
"Couldn't set API version '" . mControl::API_VERSION . "'! This might cause problems. " .
|
||||||
$this->iControl->getClientErrorText($client));
|
$this->iControl->getClientErrorText($client));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
**********************************************
|
**********************************************
|
||||||
* *
|
* *
|
||||||
* iControl ManiaPlanet Server Control *
|
* mControl ManiaPlanet Server Control *
|
||||||
* Written by steeffeen *
|
* Written by steeffeen *
|
||||||
* Contact: mail@steeffeen.com *
|
* Contact: mail@steeffeen.com *
|
||||||
* *
|
* *
|
||||||
@ -12,30 +12,30 @@ SETUP:
|
|||||||
|
|
||||||
2. Configure the needed settings:
|
2. Configure the needed settings:
|
||||||
|
|
||||||
2.1 Open the file 'configs/server.iControl.xml'.
|
2.1 Open the file 'configs/server.mControl.xml'.
|
||||||
Enter your maniaplanet server information.
|
Enter your maniaplanet server information.
|
||||||
|
|
||||||
2.2 Open the file 'configs/database.iControl.xml'
|
2.2 Open the file 'configs/database.mControl.xml'
|
||||||
Enter your mysql server information or disable database usage if you don't have a mysql server available.
|
Enter your mysql server information or disable database usage if you don't have a mysql server available.
|
||||||
|
|
||||||
2.3 Open the file 'configs/authentication.iControl.xml'.
|
2.3 Open the file 'configs/authentication.mControl.xml'.
|
||||||
Add the player logins who should have access to the commands of iControl.
|
Add the player logins who should have access to the commands of mControl.
|
||||||
|
|
||||||
3. (Optional) Enable or disable the available plugins in the file 'configs/plugins.iControl.xml'.
|
3. (Optional) Enable or disable the available plugins in the file 'configs/plugins.mControl.xml'.
|
||||||
|
|
||||||
4. (Optional) Edit the other config files in 'configs/' in order to customize your iControl to fit your needs.
|
4. (Optional) Edit the other config files in 'configs/' in order to customize your mControl to fit your needs.
|
||||||
|
|
||||||
5. Run the tool via the shell script 'iControl.sh' (UNIX) or the batch file 'iControl.bat' (Windows)
|
5. Run the tool via the shell script 'mControl.sh' (UNIX) or the batch file 'mControl.bat' (Windows)
|
||||||
|
|
||||||
6. Enjoy!
|
6. Enjoy!
|
||||||
|
|
||||||
|
|
||||||
INFORMATION:
|
INFORMATION:
|
||||||
|
|
||||||
- iControl is only tested on UNIX machines
|
- mControl is only tested on UNIX machines
|
||||||
- even though it might run properly on Windows I can't promise it will work all the time
|
- even though it might run properly on Windows I can't promise it will work all the time
|
||||||
- furthermore I can't promise that there won't be a feature in the future that makes it impossible to run iControl under Windows
|
- furthermore I can't promise that there won't be a feature in the future that makes it impossible to run mControl under Windows
|
||||||
- in order to run iControl under Windows you have to alter the file iControl.bat and enter the path to your php.exe
|
- in order to run mControl under Windows you have to alter the file mControl.bat and enter the path to your php.exe
|
||||||
|
|
||||||
- Tests were performed using PHP Version 5.4
|
- Tests were performed using PHP Version 5.4
|
||||||
- If you notice problems with other version please let me know
|
- If you notice problems with other version please let me know
|
||||||
|
Loading…
Reference in New Issue
Block a user