removed 'application' folder to have everything in the root directory

This commit is contained in:
Steffen Schröder
2014-09-29 18:20:09 +02:00
parent 1569fd5488
commit 9642433363
284 changed files with 4 additions and 50 deletions

360
core/Players/Player.php Normal file
View File

@ -0,0 +1,360 @@
<?php
namespace ManiaControl\Players;
use ManiaControl\ManiaControl;
use ManiaControl\Utils\ClassUtil;
use ManiaControl\Utils\Formatter;
/**
* Player Model Class
*
* @author ManiaControl Team <mail@maniacontrol.com>
* @copyright 2014 ManiaControl Team
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class Player {
/*
* Public Properties
*/
public $index = -1;
public $pid = -1;
public $login = null;
public $nickname = null;
public $rawNickname = null;
public $path = null;
public $authLevel = 0;
public $language = null;
public $avatar = null;
public $allies = array();
public $clubLink = null;
public $teamId = -1;
public $isOfficial = null;
public $ladderScore = -1.;
public $ladderRank = -1;
public $ladderStats = null;
public $joinTime = -1;
public $ipAddress = null;
public $isConnected = true;
public $clientVersion = null;
public $downloadRate = -1;
public $uploadRate = -1;
public $skins = null;
public $daysSinceZoneInscription = -1;
//Flags details
public $forcedSpectatorState = 0;
public $isReferee = false;
public $isPodiumReady = false;
public $isUsingStereoscopy = false;
public $isManagedByAnOtherServer = false;
public $isServer = false;
public $hasPlayerSlot = false;
public $isBroadcasting = false;
public $hasJoinedGame = false;
//SpectatorStatus details
public $isSpectator = false;
public $isTemporarySpectator = false;
public $isPureSpectator = false;
public $autoTarget = false;
public $currentTargetId = 0;
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
private $cache = array();
/**
* Construct a new Player
*
* @param ManiaControl $maniaControl
* @param bool $connected
*/
public function __construct(ManiaControl $maniaControl, $connected) {
$this->maniaControl = $maniaControl;
$this->isConnected = (bool)$connected;
if ($connected) {
$this->joinTime = time();
}
}
/**
* Get the Login of the Player
*
* @param mixed $player
* @return string
*/
public static function parseLogin($player) {
if (is_object($player) && property_exists($player, 'login')) {
return (string)$player->login;
}
return (string)$player;
}
/**
* Get the Escaped Nickname
*
* @return string
*/
public function getEscapedNickname() {
$nickname = $this->nickname;
if (!$nickname) {
$nickname = $this->login;
}
return Formatter::escapeText($nickname);
}
/**
* Update from ManiaPlanet PlayerInfo structure
*
* @param \Maniaplanet\DedicatedServer\Structures\PlayerInfo $mpPlayer
*/
public function setInfo($mpPlayer) {
$this->pid = $mpPlayer->playerId;
$this->login = $mpPlayer->login;
$this->nickname = Formatter::stripDirtyCodes($mpPlayer->nickName);
$this->rawNickname = $mpPlayer->nickName;
$this->teamId = $mpPlayer->teamId;
$this->isOfficial = $mpPlayer->isInOfficialMode;
//Flag Details
$this->forcedSpectatorState = $mpPlayer->forceSpectator;
$this->isReferee = $mpPlayer->isReferee;
$this->isPodiumReady = $mpPlayer->isPodiumReady;
$this->isUsingStereoscopy = $mpPlayer->isUsingStereoscopy;
$this->isServer = $mpPlayer->isServer;
$this->isManagedByAnOtherServer = $mpPlayer->isManagedByAnOtherServer;
$this->hasPlayerSlot = $mpPlayer->hasPlayerSlot;
$this->hasJoinedGame = $mpPlayer->hasJoinedGame;
$this->isBroadcasting = $mpPlayer->isBroadcasting;
//Spectator Status
$this->isSpectator = $mpPlayer->spectator;
$this->isTemporarySpectator = $mpPlayer->temporarySpectator;
$this->isPureSpectator = $mpPlayer->pureSpectator;
$this->autoTarget = $mpPlayer->autoTarget;
$this->currentTargetId = $mpPlayer->currentTargetId;
if (!$this->nickname) {
$this->nickname = $this->login;
}
}
/**
* Update from ManiaPlanet PlayerDetailedInfo structure
*
* @param \Maniaplanet\DedicatedServer\Structures\PlayerDetailedInfo $mpPlayer
*/
public function setDetailedInfo($mpPlayer) {
$this->pid = $mpPlayer->playerId;
$this->login = $mpPlayer->login;
$this->nickname = Formatter::stripDirtyCodes($mpPlayer->nickName);
$this->rawNickname = $mpPlayer->nickName;
$this->path = $mpPlayer->path;
$this->language = $mpPlayer->language;
$this->avatar = $mpPlayer->avatar->fileName;
$this->allies = $mpPlayer->allies;
$this->clubLink = $mpPlayer->clubLink;
$this->teamId = $mpPlayer->teamId;
$this->isOfficial = $mpPlayer->isInOfficialMode;
$this->ladderScore = $mpPlayer->ladderStats->playerRankings[0]->score;
$this->ladderRank = $mpPlayer->ladderStats->playerRankings[0]->ranking;
$this->ladderStats = $mpPlayer->ladderStats;
$this->daysSinceZoneInscription = $mpPlayer->hoursSinceZoneInscription / 24;
$this->ipAddress = $mpPlayer->iPAddress;
$this->clientVersion = $mpPlayer->clientVersion;
$this->downloadRate = $mpPlayer->downloadRate;
$this->uploadRate = $mpPlayer->uploadRate;
$this->skins = $mpPlayer->skins;
if (!$this->nickname) {
$this->nickname = $this->login;
}
}
/**
* Check if player is not a real player
*
* @return bool
*/
public function isFakePlayer() {
return ($this->pid <= 0 || substr($this->login, 0, 1) === '*');
}
/**
* Get province
*
* @return string
*/
public function getProvince() {
return $this->getPathPart(3);
}
/**
* Get the specified Part of the Path
*
* @param int $partNumber
* @return string
*/
public function getPathPart($partNumber) {
$pathParts = explode('|', $this->path);
for ($partIndex = $partNumber; $partIndex >= 0; $partIndex--) {
if (isset($pathParts[$partIndex])) {
return $pathParts[$partIndex];
}
}
return $this->path;
}
/**
* Get Country
*
* @return string
*/
public function getCountry() {
return $this->getPathPart(2);
}
/**
* Get Continent
*
* @return string
*/
public function getContinent() {
return $this->getPathPart(1);
}
/**
* Update the Flags of the Player
*
* @param $flags
*/
public function updatePlayerFlags($flags) {
//Detail flags
$this->forcedSpectatorState = $flags % 10; // 0, 1 or 2
$this->isReferee = (bool)(intval($flags / 10) % 10);
$this->isPodiumReady = (bool)(intval($flags / 100) % 10);
$this->isUsingStereoscopy = (bool)(intval($flags / 1000) % 10);
$this->isManagedByAnOtherServer = (bool)(intval($flags / 10000) % 10);
$this->isServer = (bool)(intval($flags / 100000) % 10);
$this->hasPlayerSlot = (bool)(intval($flags / 1000000) % 10);
$this->isBroadcasting = (bool)(intval($flags / 10000000) % 10);
$this->hasJoinedGame = (bool)(intval($flags / 100000000) % 10);
}
/**
* Update the Spectator Status of the player
*
* @param $spectatorStatus
*/
public function updateSpectatorStatus($spectatorStatus) {
//Details spectatorStatus
$this->isSpectator = (bool)($spectatorStatus % 10);
$this->isTemporarySpectator = (bool)(intval($spectatorStatus / 10) % 10);
$this->isPureSpectator = (bool)(intval($spectatorStatus / 100) % 10);
$this->autoTarget = (bool)(intval($spectatorStatus / 1000) % 10);
$this->currentTargetId = intval($spectatorStatus / 10000);
}
/**
* Get the Cache with the given Name
*
* @param $object
* @param string $cacheName
* @return mixed
*/
public function getCache($object, $cacheName) {
$className = ClassUtil::getClass($object);
if (isset($this->cache[$className . $cacheName])) {
return $this->cache[$className . $cacheName];
}
return null;
}
/**
* Set the Cache Data for the given Name
*
* @param mixed $object
* @param string $cacheName
* @param mixed $data
*/
public function setCache($object, $cacheName, $data) {
$className = ClassUtil::getClass($object);
$this->cache[$className . $cacheName] = $data;
}
/**
* Destroy a Cache
*
* @param mixed $object
* @param string $cacheName
*/
public function destroyCache($object, $cacheName) {
$className = ClassUtil::getClass($object);
unset($this->cache[$className . $cacheName]);
}
/**
* Clear the Player's Temporary Data
*/
public function clearCache() {
$this->cache = array();
}
/**
* Gets the Player Data
*
* @param mixed $object
* @param string $dataName
* @param int $serverIndex
* @return mixed
*/
public function getPlayerData($object, $dataName, $serverIndex = -1) {
return $this->maniaControl->getPlayerManager()->getPlayerDataManager()->getPlayerData($object, $dataName, $this, $serverIndex);
}
/**
* Sets the Player Data and stores it in the Database
*
* @param mixed $object
* @param string $dataName
* @param mixed $value
* @param int $serverIndex
* @return bool
*/
public function setPlayerData($object, $dataName, $value, $serverIndex = -1) {
return $this->maniaControl->getPlayerManager()->getPlayerDataManager()->setPlayerData($object, $dataName, $this, $value, $serverIndex);
}
/*
* Check if a Player is muted
*
* @return bool
*/
public function isMuted() {
$ignoreList = $this->maniaControl->getClient()->getIgnoreList(100, 0);
foreach ($ignoreList as $ignoredPlayers) {
if ($ignoredPlayers->login === $this->login) {
return true;
}
}
return false;
}
/**
* Var_Dump the Player
*/
public function dump() {
var_dump(json_decode(json_encode($this)));
}
/**
* Var_Dump the Players Cache
*/
public function dumpCache() {
var_dump($this->cache);
}
}

View File

@ -0,0 +1,523 @@
<?php
namespace ManiaControl\Players;
use FML\Controls\Frame;
use FML\Controls\Labels\Label_Text;
use FML\Controls\Quad;
use FML\Controls\Quads\Quad_Icons64x64_1;
use FML\ManiaLink;
use ManiaControl\Admin\AuthenticationManager;
use ManiaControl\Logger;
use ManiaControl\ManiaControl;
use ManiaControl\Manialinks\ManialinkManager;
use Maniaplanet\DedicatedServer\Xmlrpc\AlreadyInListException;
use Maniaplanet\DedicatedServer\Xmlrpc\FaultException;
use Maniaplanet\DedicatedServer\Xmlrpc\GameModeException;
use Maniaplanet\DedicatedServer\Xmlrpc\NotInListException;
use Maniaplanet\DedicatedServer\Xmlrpc\PlayerStateException;
use Maniaplanet\DedicatedServer\Xmlrpc\ServerOptionsException;
use Maniaplanet\DedicatedServer\Xmlrpc\UnknownPlayerException;
/**
* Player Actions Class
*
* @author ManiaControl Team <mail@maniacontrol.com>
* @copyright 2014 ManiaControl Team
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class PlayerActions {
/*
* Constants
*/
const TEAM_BLUE = 0;
const TEAM_RED = 1;
const SPECTATOR_USER_SELECTABLE = 0;
const SPECTATOR_SPECTATOR = 1;
const SPECTATOR_PLAYER = 2;
const SPECTATOR_BUT_KEEP_SELECTABLE = 3;
/*
* Permission Setting Constants
*/
const SETTING_PERMISSION_FORCE_PLAYER_PLAY = 'Force Player to Play';
const SETTING_PERMISSION_FORCE_PLAYER_TEAM = 'Force Player to Team';
const SETTING_PERMISSION_FORCE_PLAYER_SPEC = 'Force Player to Spec';
const SETTING_PERMISSION_MUTE_PLAYER = 'Mute Player';
const SETTING_PERMISSION_WARN_PLAYER = 'Warn Player';
const SETTING_PERMISSION_KICK_PLAYER = 'Kick Player';
const SETTING_PERMISSION_BAN_PLAYER = 'Ban Player';
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
/**
* Construct a new PlayerActions instance
*
* @param ManiaControl $maniaControl
*/
public function __construct(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
// Permissions
$this->maniaControl->getAuthenticationManager()->definePermissionLevel(self::SETTING_PERMISSION_BAN_PLAYER, AuthenticationManager::AUTH_LEVEL_ADMIN);
$this->maniaControl->getAuthenticationManager()->definePermissionLevel(self::SETTING_PERMISSION_KICK_PLAYER, AuthenticationManager::AUTH_LEVEL_MODERATOR);
$this->maniaControl->getAuthenticationManager()->definePermissionLevel(self::SETTING_PERMISSION_WARN_PLAYER, AuthenticationManager::AUTH_LEVEL_MODERATOR);
$this->maniaControl->getAuthenticationManager()->definePermissionLevel(self::SETTING_PERMISSION_MUTE_PLAYER, AuthenticationManager::AUTH_LEVEL_MODERATOR);
$this->maniaControl->getAuthenticationManager()->definePermissionLevel(self::SETTING_PERMISSION_FORCE_PLAYER_PLAY, AuthenticationManager::AUTH_LEVEL_MODERATOR);
$this->maniaControl->getAuthenticationManager()->definePermissionLevel(self::SETTING_PERMISSION_FORCE_PLAYER_TEAM, AuthenticationManager::AUTH_LEVEL_MODERATOR);
$this->maniaControl->getAuthenticationManager()->definePermissionLevel(self::SETTING_PERMISSION_FORCE_PLAYER_SPEC, AuthenticationManager::AUTH_LEVEL_MODERATOR);
}
/**
* Force a Player to a certain Team
*
* @param string $adminLogin
* @param string $targetLogin
* @param int $teamId
*/
public function forcePlayerToTeam($adminLogin, $targetLogin, $teamId) {
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($admin, self::SETTING_PERMISSION_FORCE_PLAYER_TEAM)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($admin);
return;
}
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
if (!$target || !$admin) {
return;
}
if ($target->isSpectator) {
try {
if (!$this->forcePlayerToPlay($adminLogin, $targetLogin, true, false)) {
return;
}
} catch (FaultException $exception) {
$this->maniaControl->getChat()->sendException($exception, $admin);
}
}
try {
$this->maniaControl->getClient()->forcePlayerTeam($target->login, $teamId);
} catch (ServerOptionsException $exception) {
$this->forcePlayerToPlay($adminLogin, $targetLogin);
return;
} catch (GameModeException $exception) {
$this->maniaControl->getChat()->sendException($exception, $admin);
return;
}
$chatMessage = false;
$title = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($admin->authLevel);
if ($teamId === self::TEAM_BLUE) {
$chatMessage = $title . ' ' . $admin->getEscapedNickname() . ' forced ' . $target->getEscapedNickname() . ' into the Blue-Team!';
} else if ($teamId === self::TEAM_RED) {
$chatMessage = $title . ' ' . $admin->getEscapedNickname() . ' forced ' . $target->getEscapedNickname() . ' into the Red-Team!';
}
if (!$chatMessage) {
return;
}
$this->maniaControl->getChat()->sendInformation($chatMessage);
Logger::logInfo($chatMessage, true);
}
/**
* Force a Player to Play
*
* @param string $adminLogin
* @param string $targetLogin
* @param bool $userIsAbleToSelect
* @param bool $displayAnnouncement
* @return bool
*/
public function forcePlayerToPlay($adminLogin, $targetLogin, $userIsAbleToSelect = true, $displayAnnouncement = true) {
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($admin, self::SETTING_PERMISSION_FORCE_PLAYER_PLAY)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($admin);
return false;
}
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
if (!$target) {
return false;
}
try {
$this->maniaControl->getClient()->forceSpectator($target->login, self::SPECTATOR_PLAYER);
} catch (ServerOptionsException $exception) {
$this->maniaControl->getChat()->sendException($exception, $admin);
return false;
}
if ($userIsAbleToSelect) {
try {
$this->maniaControl->getClient()->forceSpectator($target->login, self::SPECTATOR_USER_SELECTABLE);
} catch (ServerOptionsException $exception) {
$this->maniaControl->getChat()->sendException($exception, $admin);
return false;
}
}
// Announce force
if ($displayAnnouncement) {
$chatMessage = $admin->getEscapedNickname() . ' forced ' . $target->getEscapedNickname() . ' to Play!';
$this->maniaControl->getChat()->sendInformation($chatMessage);
}
return true;
}
/**
* Force a Player to Spectator
*
* @param string $adminLogin
* @param string $targetLogin
* @param int $spectatorState
* @param bool $releaseSlot
*/
public function forcePlayerToSpectator($adminLogin, $targetLogin, $spectatorState = self::SPECTATOR_BUT_KEEP_SELECTABLE, $releaseSlot = true) {
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($admin, self::SETTING_PERMISSION_FORCE_PLAYER_SPEC)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($admin);
return;
}
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
if (!$admin || !$target || $target->isSpectator) {
return;
}
try {
$this->maniaControl->getClient()->forceSpectator($target->login, $spectatorState);
} catch (ServerOptionsException $exception) {
$this->maniaControl->getChat()->sendException($exception, $admin->login);
return;
}
$title = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($admin->authLevel);
$chatMessage = $title . ' ' . $admin->getEscapedNickname() . ' forced ' . $target->getEscapedNickname() . ' to Spectator!';
$this->maniaControl->getChat()->sendInformation($chatMessage);
Logger::logInfo($chatMessage, true);
if ($releaseSlot) {
// Free player slot
try {
$this->maniaControl->getClient()->spectatorReleasePlayerSlot($target->login);
} catch (PlayerStateException $e) {
} catch (UnknownPlayerException $e) {
}
}
}
/**
* UnMute a Player
*
* @param string $adminLogin
* @param string $targetLogin
*/
public function unMutePlayer($adminLogin, $targetLogin) {
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($admin, self::SETTING_PERMISSION_MUTE_PLAYER)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($admin);
return;
}
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
if (!$target) {
return;
}
try {
$this->maniaControl->getClient()->unIgnore($targetLogin);
} catch (NotInListException $e) {
$this->maniaControl->getChat()->sendError('Player is not ignored!', $adminLogin);
return;
}
$title = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($admin->authLevel);
$chatMessage = $title . ' ' . $admin->getEscapedNickname() . ' un-muted ' . $target->getEscapedNickname() . '!';
$this->maniaControl->getChat()->sendInformation($chatMessage);
Logger::logInfo($chatMessage, true);
}
/**
* Mute a Player
*
* @param string $adminLogin
* @param string $targetLogin
*/
public function mutePlayer($adminLogin, $targetLogin) {
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($admin, self::SETTING_PERMISSION_MUTE_PLAYER)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($admin);
return;
}
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
if (!$target) {
return;
}
try {
$this->maniaControl->getClient()->ignore($targetLogin);
} catch (AlreadyInListException $e) {
$this->maniaControl->getChat()->sendError("Player already ignored!", $adminLogin);
return;
}
$title = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($admin->authLevel);
$chatMessage = $title . ' ' . $admin->getEscapedNickname() . ' muted ' . $target->getEscapedNickname() . '!';
$this->maniaControl->getChat()->sendInformation($chatMessage);
Logger::logInfo($chatMessage, true);
}
/**
* Warn a Player
*
* @param string $adminLogin
* @param string $targetLogin
*/
public function warnPlayer($adminLogin, $targetLogin) {
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($admin, self::SETTING_PERMISSION_WARN_PLAYER)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($admin);
return;
}
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
if (!$target) {
return;
}
// Display warning message
$message = '$s$f00This is an administrative warning.{br}{br}$gWhatever you wrote or you have done is against {br} our server\'s policy.
{br}Not respecting other players, or{br}using offensive language might result in a{br}$f00kick, or ban $ff0the next time.
{br}{br}$gThe server administrators.';
$message = preg_split('/{br}/', $message);
// Build Manialink
$width = 80;
$height = 50;
$quadStyle = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultMainWindowStyle();
$quadSubstyle = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultMainWindowSubStyle();
$maniaLink = new ManiaLink(ManialinkManager::MAIN_MLID);
$frame = new Frame();
$maniaLink->add($frame);
$frame->setPosition(0, 10);
// Background
$backgroundQuad = new Quad();
$frame->add($backgroundQuad);
$backgroundQuad->setSize($width, $height);
$backgroundQuad->setStyles($quadStyle, $quadSubstyle);
// Close Quad (X)
$closeQuad = new Quad_Icons64x64_1();
$frame->add($closeQuad);
$closeQuad->setPosition($width * 0.473, $height * 0.457, 3);
$closeQuad->setSize(6, 6);
$closeQuad->setSubStyle($closeQuad::SUBSTYLE_QuitRace);
$closeQuad->setAction(ManialinkManager::ACTION_CLOSEWIDGET);
// Headline
$label = new Label_Text();
$frame->add($label);
$label->setY($height / 2 - 5);
$label->setStyle($label::STYLE_TextCardMedium);
$label->setTextSize(4);
$label->setText('Administrative Warning');
$label->setTextColor('f00');
$posY = $height / 2 - 15;
foreach ($message as $line) {
// Message lines
$label = new Label_Text();
$frame->add($label);
$label->setY($posY);
$label->setStyle($label::STYLE_TextCardMedium);
$label->setText($line);
$label->setTextColor('ff0');
$label->setTextSize(1.3);
$posY -= 4;
}
// Display manialink
$this->maniaControl->getManialinkManager()->displayWidget($maniaLink, $target);
// Announce warning
$title = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($admin->authLevel);
$chatMessage = $title . ' ' . $admin->getEscapedNickname() . ' warned ' . $target->getEscapedNickname() . '!';
$this->maniaControl->getChat()->sendInformation($chatMessage);
Logger::log($chatMessage, true);
}
/**
* Kick a Player
*
* @param string $adminLogin
* @param string $targetLogin
* @param string $message
*/
public function kickPlayer($adminLogin, $targetLogin, $message = '') {
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($admin, self::SETTING_PERMISSION_KICK_PLAYER)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($admin);
return;
}
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
if (!$target) {
return;
}
try {
if ($target->isFakePlayer()) {
$this->maniaControl->getClient()->disconnectFakePlayer($target->login);
} else {
$this->maniaControl->getClient()->kick($target->login, $message);
}
} catch (UnknownPlayerException $e) {
$this->maniaControl->getChat()->sendException($e, $admin);
return;
}
// Announce kick
$title = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($admin->authLevel);
$chatMessage = $title . ' ' . $admin->getEscapedNickname() . ' kicked ' . $target->getEscapedNickname() . '!';
$this->maniaControl->getChat()->sendInformation($chatMessage);
Logger::logInfo($chatMessage, true);
}
/**
* Ban a Player
*
* @param string $adminLogin
* @param string $targetLogin
* @param string $message
*/
public function banPlayer($adminLogin, $targetLogin, $message = '') {
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($admin, self::SETTING_PERMISSION_BAN_PLAYER)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($admin);
return;
}
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
if (!$target) {
return;
}
if ($target->isFakePlayer()) {
$this->maniaControl->getChat()->sendError('It is not possible to Ban a bot', $admin);
return;
}
$this->maniaControl->getClient()->ban($target->login, $message);
// Announce ban
$title = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($admin->authLevel);
$chatMessage = $title . ' ' . $admin->getEscapedNickname() . ' banned ' . $target->getEscapedNickname() . '!';
$this->maniaControl->getChat()->sendInformation($chatMessage);
Logger::logInfo($chatMessage, true);
}
/**
* Grands the Player an Authorization Level
*
* @param string $adminLogin
* @param string $targetLogin
* @param int $authLevel
*/
public function grandAuthLevel($adminLogin, $targetLogin, $authLevel) {
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
if (!$admin || !$target) {
return;
}
$authLevelName = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($authLevel);
if (!$this->maniaControl->getAuthenticationManager()->checkRight($admin, $authLevel + 1)
) {
$this->maniaControl->getChat()->sendError("You don't have the permission to add a {$authLevelName}!", $admin);
return;
}
if ($this->maniaControl->getAuthenticationManager()->checkRight($target, $authLevel)
) {
$this->maniaControl->getChat()->sendError("This Player is already {$authLevelName}!", $admin);
return;
}
$success = $this->maniaControl->getAuthenticationManager()->grantAuthLevel($target, $authLevel);
if (!$success) {
$this->maniaControl->getChat()->sendError('Error occurred.', $admin);
return;
}
// Announce granting
$title = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($admin->authLevel);
$chatMessage = $title . ' ' . $admin->getEscapedNickname() . ' added ' . $target->getEscapedNickname() . ' as $< ' . $authLevelName . '$>!';
$this->maniaControl->getChat()->sendInformation($chatMessage);
Logger::logInfo($chatMessage, true);
}
/**
* Revokes all Rights from the Player
*
* @param string $adminLogin
* @param string $targetLogin
*/
public function revokeAuthLevel($adminLogin, $targetLogin) {
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
if (!$admin || !$target) {
return;
}
if (!$this->maniaControl->getAuthenticationManager()->checkRight($admin, $target->authLevel + 1)
) {
$title = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($target->authLevel);
$this->maniaControl->getChat()->sendError("You can't revoke the Rights of a {$title}!", $admin);
return;
}
if ($this->maniaControl->getAuthenticationManager()->checkRight($target, AuthenticationManager::AUTH_LEVEL_MASTERADMIN)
) {
$this->maniaControl->getChat()->sendError("MasterAdmins can't be removed!", $admin);
return;
}
$success = $this->maniaControl->getAuthenticationManager()->grantAuthLevel($target, AuthenticationManager::AUTH_LEVEL_PLAYER);
if (!$success) {
$this->maniaControl->getChat()->sendError('Error occurred.', $admin);
return;
}
// Announce revoke
$title = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($admin->authLevel);
$chatMessage = $title . ' ' . $admin->getEscapedNickname() . ' revoked the Rights of ' . $target->getEscapedNickname() . '!';
$this->maniaControl->getChat()->sendInformation($chatMessage);
Logger::logInfo($chatMessage, true);
}
/**
* Check if a Player is muted
*
* @deprecated see Player/isMuted()
*/
public function isPlayerMuted($login) {
return $this->maniaControl->getPlayerManager()->getPlayer($login)->isMuted();
}
}

View File

@ -0,0 +1,368 @@
<?php
namespace ManiaControl\Players;
use FML\Controls\Quads\Quad_Icons128x32_1;
use FML\Controls\Quads\Quad_UIConstruction_Buttons;
use ManiaControl\Admin\AuthenticationManager;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Commands\CommandListener;
use ManiaControl\ManiaControl;
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
use ManiaControl\Server\Server;
use Maniaplanet\DedicatedServer\Xmlrpc\GameModeException;
use Maniaplanet\DedicatedServer\Xmlrpc\UnavailableFeatureException;
/**
* Class offering various Admin Commands related to Players
*
* @author ManiaControl Team <mail@maniacontrol.com>
* @copyright 2014 ManiaControl Team
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class PlayerCommands implements CommandListener, ManialinkPageAnswerListener, CallbackListener {
/*
* Constants
*/
const ACTION_BALANCE_TEAMS = 'PlayerCommands.BalanceTeams';
const ACTION_OPEN_PLAYERLIST = 'PlayerCommands.OpenPlayerList';
const SETTING_PERMISSION_ADD_BOT = 'Add Bot';
const SETTING_PERMISSION_TEAM_BALANCE = 'Balance Teams';
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
/**
* Create a new Player Commands Instance
*
* @param ManiaControl $maniaControl
*/
public function __construct(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
// Admin commands
$this->maniaControl->getCommandManager()->registerCommandListener(array('balance', 'teambalance', 'autoteambalance'), $this, 'command_TeamBalance', true, 'Balances the teams.');
$this->maniaControl->getCommandManager()->registerCommandListener('kick', $this, 'command_Kick', true, 'Kicks player from the server.');
$this->maniaControl->getCommandManager()->registerCommandListener('ban', $this, 'command_Ban', true, 'Bans player from the server.');
$this->maniaControl->getCommandManager()->registerCommandListener(array('forcespec', 'forcespectator'), $this, 'command_ForceSpectator', true, 'Forces player into spectator.');
$this->maniaControl->getCommandManager()->registerCommandListener('forceplay', $this, 'command_ForcePlay', true, 'Forces player into Play mode.');
$this->maniaControl->getCommandManager()->registerCommandListener('forceblue', $this, 'command_ForceBlue', true, 'Forces player into blue team.');
$this->maniaControl->getCommandManager()->registerCommandListener('forcered', $this, 'command_ForceRed', true, 'Forces player into red team.');
$this->maniaControl->getCommandManager()->registerCommandListener(array('addbots', 'addbot'), $this, 'command_AddFakePlayers', true, 'Adds bots to the game.');
$this->maniaControl->getCommandManager()->registerCommandListener(array('removebot', 'removebots'), $this, 'command_RemoveFakePlayers', true, 'Removes bots from the game.');
$this->maniaControl->getCommandManager()->registerCommandListener('mute', $this, 'command_MutePlayer', true, 'Mutes a player (prevents player from chatting).');
$this->maniaControl->getCommandManager()->registerCommandListener('unmute', $this, 'command_UnmutePlayer', true, 'Unmute a player (enables player to chat again).');
// Player commands
$this->maniaControl->getCommandManager()->registerCommandListener(array('player', 'players'), $this, 'command_playerList', false, 'Shows players currently on the server.');
// Permissions
$this->maniaControl->getAuthenticationManager()->definePermissionLevel(self::SETTING_PERMISSION_ADD_BOT, AuthenticationManager::AUTH_LEVEL_MODERATOR);
$this->maniaControl->getAuthenticationManager()->definePermissionLevel(self::SETTING_PERMISSION_TEAM_BALANCE, AuthenticationManager::AUTH_LEVEL_MODERATOR);
// Callbacks
$this->maniaControl->getCallbackManager()->registerCallbackListener(Server::CB_TEAM_MODE_CHANGED, $this, 'teamStatusChanged');
// Action Open PlayerList
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ACTION_OPEN_PLAYERLIST, $this, 'command_playerList');
$itemQuad = new Quad_UIConstruction_Buttons();
$itemQuad->setSubStyle($itemQuad::SUBSTYLE_Author);
$itemQuad->setAction(self::ACTION_OPEN_PLAYERLIST);
$this->maniaControl->getActionsMenu()->addMenuItem($itemQuad, true, 15, 'Open PlayerList');
}
/**
* Handle TeamStatusChanged
*
* @param bool $teamMode
*/
public function teamStatusChanged($teamMode) {
//Add Balance Team Icon if it's a teamMode
if ($teamMode) {
// Action Balance Teams
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ACTION_BALANCE_TEAMS, $this, 'command_TeamBalance');
$itemQuad = new Quad_Icons128x32_1();
$itemQuad->setSubStyle($itemQuad::SUBSTYLE_RT_Team);
$itemQuad->setAction(self::ACTION_BALANCE_TEAMS);
$this->maniaControl->getActionsMenu()->addMenuItem($itemQuad, false, 40, 'Balance Teams');
}
}
/**
* Handle //teambalance command
*
* @param array $chatCallback
* @param Player $player
*/
public function command_TeamBalance(array $chatCallback, Player $player) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($player, self::SETTING_PERMISSION_TEAM_BALANCE)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player);
return;
}
try {
$this->maniaControl->getClient()->autoTeamBalance();
} catch (GameModeException $exception) {
$this->maniaControl->getChat()->sendException($exception, $player);
return;
}
$this->maniaControl->getChat()->sendInformation($player->getEscapedNickname() . ' balanced Teams!');
}
/**
* Handle //kick command
*
* @param array $chat
* @param Player $player
*/
public function command_Kick(array $chat, Player $player) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($player, PlayerActions::SETTING_PERMISSION_KICK_PLAYER)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player);
return;
}
$params = explode(' ', $chat[1][2], 3);
if (count($params) <= 1) {
$this->maniaControl->getChat()->sendUsageInfo("No Login given! Example: '//kick login'", $player->login);
return;
}
$targetLogin = $params[1];
$message = '';
if (isset($params[2])) {
$message = $params[2];
}
$this->maniaControl->getPlayerManager()->getPlayerActions()->kickPlayer($player->login, $targetLogin, $message);
}
/**
* Handle //ban command
*
* @param array $chat
* @param Player $player
*/
public function command_Ban(array $chat, Player $player) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($player, PlayerActions::SETTING_PERMISSION_BAN_PLAYER)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player);
return;
}
$params = explode(' ', $chat[1][2], 3);
if (count($params) <= 1) {
$this->maniaControl->getChat()->sendUsageInfo("No Login given! Example: '//ban login'", $player->login);
return;
}
$targetLogin = $params[1];
$message = '';
if (isset($params[2])) {
$message = $params[2];
}
$this->maniaControl->getPlayerManager()->getPlayerActions()->banPlayer($player->login, $targetLogin, $message);
}
/**
* Handle //warn Command
*
* @param array $chatCallback
* @param Player $player
*/
public function command_Warn(array $chatCallback, Player $player) {
$params = explode(' ', $chatCallback[1][2], 3);
if (count($params) <= 1) {
$this->maniaControl->getChat()->sendUsageInfo("No Login given! Example: '//warn login'", $player->login);
return;
}
$targetLogin = $params[1];
$this->maniaControl->getPlayerManager()->getPlayerActions()->warnPlayer($player->login, $targetLogin);
}
/**
* Handle //forcespec command
*
* @param array $chat
* @param Player $player
*/
public function command_ForceSpectator(array $chat, Player $player) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($player, PlayerActions::SETTING_PERMISSION_FORCE_PLAYER_SPEC)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player);
return;
}
$params = explode(' ', $chat[1][2]);
if (count($params) <= 1) {
$this->maniaControl->getChat()->sendUsageInfo("No Login given! Example: '//forcespec login'", $player->login);
return;
}
$targetLogin = $params[1];
if (isset($params[2]) && is_numeric($params[2])) {
$type = (int)$params[2];
$this->maniaControl->getPlayerManager()->getPlayerActions()->forcePlayerToSpectator($player->login, $targetLogin, $type);
} else {
$this->maniaControl->getPlayerManager()->getPlayerActions()->forcePlayerToSpectator($player->login, $targetLogin);
}
}
/**
* Handle //forceplay command
*
* @param array $chat
* @param Player $player
*/
public function command_ForcePlay(array $chat, Player $player) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($player, PlayerActions::SETTING_PERMISSION_FORCE_PLAYER_PLAY)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player);
return;
}
$params = explode(' ', $chat[1][2]);
if (!isset($params[1])) {
$this->maniaControl->getChat()->sendUsageInfo("No Login given! Example: '//forceplay login'", $player->login);
return;
}
$targetLogin = $params[1];
$type = 2;
if (isset($params[2]) && is_numeric($params[2])) {
$type = (int)$params[2];
}
$selectable = ($type === 2);
$this->maniaControl->getPlayerManager()->getPlayerActions()->forcePlayerToPlay($player->login, $targetLogin, $selectable);
}
/**
* Handle //forceblue command
*
* @param array $chat
* @param Player $player
*/
public function command_ForceBlue(array $chat, Player $player) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($player, PlayerActions::SETTING_PERMISSION_FORCE_PLAYER_TEAM)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player);
return;
}
$params = explode(' ', $chat[1][2]);
if (!isset($params[1])) {
$this->maniaControl->getChat()->sendUsageInfo("No Login given! Example: '//forceblue login'", $player->login);
return;
}
$targetLogin = $params[1];
$this->maniaControl->getPlayerManager()->getPlayerActions()->forcePlayerToTeam($player->login, $targetLogin, PlayerActions::TEAM_BLUE);
}
/**
* Handle //forcered command
*
* @param array $chat
* @param Player $player
*/
public function command_ForceRed(array $chat, Player $player) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($player, PlayerActions::SETTING_PERMISSION_FORCE_PLAYER_TEAM)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player);
return;
}
$params = explode(' ', $chat[1][2]);
if (!isset($params[1])) {
$this->maniaControl->getChat()->sendUsageInfo("No Login given! Example: '//forcered login'", $player->login);
return;
}
$targetLogin = $params[1];
$this->maniaControl->getPlayerManager()->getPlayerActions()->forcePlayerToTeam($player->login, $targetLogin, PlayerActions::TEAM_RED);
}
/**
* Handle //addfakeplayers command
*
* @param array $chatCallback
* @param Player $player
*/
public function command_AddFakePlayers(array $chatCallback, Player $player) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($player, self::SETTING_PERMISSION_ADD_BOT)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player);
return;
}
$amount = 1;
$messageParts = explode(' ', $chatCallback[1][2]);
if (isset($messageParts[1]) && is_numeric($messageParts[1])) {
$amount = intval($messageParts[1]);
}
try {
for ($i = 0; $i < $amount; $i++) {
$this->maniaControl->getClient()->connectFakePlayer();
}
$this->maniaControl->getChat()->sendSuccess('Fake players connected!', $player);
} catch (UnavailableFeatureException $e) {
$this->maniaControl->getChat()->sendSuccess('Error while connecting a Fake-Player.', $player);
}
}
/**
* Handle //removefakeplayers command
*
* @param array $chatCallback
* @param Player $player
*/
public function command_RemoveFakePlayers(array $chatCallback, Player $player) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($player, self::SETTING_PERMISSION_ADD_BOT)
) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player);
return;
}
$this->maniaControl->getClient()->disconnectFakePlayer('*');
$this->maniaControl->getChat()->sendSuccess('Fake players disconnected!', $player);
}
/**
* Handle //mute Command
*
* @param array $chatCallback
* @param Player $admin
*/
public function command_MutePlayer(array $chatCallback, Player $admin) {
$commandParts = explode(' ', $chatCallback[1][2]);
if (count($commandParts) <= 1) {
$this->maniaControl->getChat()->sendUsageInfo("No login specified! Example: '//mute login'", $admin);
return;
}
$targetLogin = $commandParts[1];
$this->maniaControl->getPlayerManager()->getPlayerActions()->mutePlayer($admin->login, $targetLogin);
}
/**
* Handle //unmute Command
*
* @param array $chatCallback
* @param Player $admin
*/
public function command_UnmutePlayer(array $chatCallback, Player $admin) {
$commandParts = explode(' ', $chatCallback[1][2]);
if (count($commandParts) <= 1) {
$this->maniaControl->getChat()->sendUsageInfo("No login specified! Example: '//unmute login'", $admin);
return;
}
$targetLogin = $commandParts[1];
$this->maniaControl->getPlayerManager()->getPlayerActions()->unMutePlayer($admin->login, $targetLogin);
}
/**
* Handle Player list command
*
* @param array $chatCallback
* @param Player $player
*/
public function command_playerList(array $chatCallback, Player $player) {
$this->maniaControl->getPlayerManager()->getPlayerList()->addPlayerToShownList($player, PlayerList::SHOWN_MAIN_WINDOW);
$this->maniaControl->getPlayerManager()->getPlayerList()->showPlayerList($player);
}
}

View File

@ -0,0 +1,352 @@
<?php
namespace ManiaControl\Players;
use ManiaControl\ManiaControl;
use ManiaControl\Utils\ClassUtil;
/**
* Player Data Manager
*
* @author ManiaControl Team <mail@maniacontrol.com>
* @copyright 2014 ManiaControl Team
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class PlayerDataManager {
/*
* Constants
*/
const TABLE_PLAYERDATAMETADATA = 'mc_playerdata_metadata';
const TABLE_PLAYERDATA = 'mc_playerdata';
const TYPE_STRING = 'string';
const TYPE_INT = 'int';
const TYPE_REAL = 'real';
const TYPE_BOOL = 'bool';
const TYPE_ARRAY = 'array';
const ARRAY_DELIMITER = ';;';
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
private $metaData = array();
private $storedData = array();
/**
* Construct a new player manager instance
*
* @param ManiaControl $maniaControl
*/
public function __construct(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
$this->initTables();
// Store Stats MetaData
$this->storeMetaData();
}
/**
* Initialize necessary database tables
*
* @return bool
*/
private function initTables() {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$defaultType = "'" . self::TYPE_STRING . "'";
$typeSet = $defaultType . ",'" . self::TYPE_INT . "','" . self::TYPE_REAL . "','" . self::TYPE_BOOL . "','" . self::TYPE_ARRAY . "'";
$query = "CREATE TABLE IF NOT EXISTS `" . self::TABLE_PLAYERDATAMETADATA . "` (
`dataId` int(11) NOT NULL AUTO_INCREMENT,
`class` varchar(100) NOT NULL,
`dataName` varchar(100) NOT NULL,
`type` set({$typeSet}) NOT NULL DEFAULT {$defaultType},
`defaultValue` varchar(150) NOT NULL,
`description` varchar(150) NOT NULL,
PRIMARY KEY (`dataId`),
UNIQUE KEY `name` (`class`, `dataName`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Player-Data MetaData' AUTO_INCREMENT=1;";
$statement = $mysqli->prepare($query);
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
return false;
}
$statement->execute();
if ($statement->error) {
trigger_error($statement->error, E_USER_ERROR);
return false;
}
$statement->close();
$query = "CREATE TABLE IF NOT EXISTS `" . self::TABLE_PLAYERDATA . "` (
`index` int(11) NOT NULL AUTO_INCREMENT,
`serverIndex` int(11) NOT NULL,
`playerId` int(11) NOT NULL,
`dataId` int(11) NOT NULL,
`value` varchar(150) NOT NULL,
`changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`index`),
UNIQUE KEY `unique` (`dataId`,`playerId`,`serverIndex`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Player Data' AUTO_INCREMENT=1;";
$statement = $mysqli->prepare($query);
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
return false;
}
$statement->execute();
if ($statement->error) {
trigger_error($statement->error, E_USER_ERROR);
return false;
}
$statement->close();
return true;
}
/**
* Store Meta Data from the Database in the Ram
*/
private function storeMetaData() {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = "SELECT * FROM `" . self::TABLE_PLAYERDATAMETADATA . "`;";
$result = $mysqli->query($query);
if (!$result) {
trigger_error($mysqli->error);
return;
}
while ($row = $result->fetch_object()) {
$this->metaData[$row->class . $row->dataName] = $row;
}
$result->free();
}
/**
* Destroys the stored PlayerData (Method get called by PlayerManager, so don't call it anywhere else)
*
* @param Player $player
*/
public function destroyPlayerData(Player $player) {
unset($this->storedData[$player->index]);
}
/**
* Defines the Player-Data MetaData
*
* @param mixed $object
* @param string $dataName
* @param mixed $default
* @param string $dataDescription (optional)
* @return bool
*/
public function defineMetaData($object, $dataName, $default, $dataDescription = '') {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$className = ClassUtil::getClass($object);
$query = "INSERT INTO `" . self::TABLE_PLAYERDATAMETADATA . "` (
`class`,
`dataName`,
`type`,
`defaultValue`,
`description`
) VALUES (
?, ?, ?, ?, ?
) ON DUPLICATE KEY UPDATE
`type` = VALUES(`type`),
`defaultValue` = VALUES(`defaultValue`),
`description` = VALUES(`description`);";
$statement = $mysqli->prepare($query);
if ($mysqli->error) {
trigger_error($mysqli->error);
return false;
}
$type = $this->getType($default);
$statement->bind_param('sssss', $className, $dataName, $type, $default, $dataDescription);
$statement->execute();
if ($statement->error) {
trigger_error($statement->error);
$statement->close();
return false;
}
$statement->close();
return true;
}
/**
* Get Type of a Parameter
*
* @param mixed $param
* @return string
*/
private function getType($param) {
if (is_int($param)) {
return self::TYPE_INT;
}
if (is_real($param)) {
return self::TYPE_REAL;
}
if (is_bool($param)) {
return self::TYPE_BOOL;
}
if (is_string($param)) {
return self::TYPE_STRING;
}
if (is_array($param)) {
return self::TYPE_ARRAY;
}
trigger_error('Unsupported data type. ' . print_r($param, true));
return null;
}
/**
* Gets the Player Data
*
* @param mixed $object
* @param string $dataName
* @param Player $player
* @param int $serverIndex
* @return mixed
*/
public function getPlayerData($object, $dataName, Player $player, $serverIndex = -1) {
$className = ClassUtil::getClass($object);
$meta = $this->metaData[$className . $dataName];
// Check if data is already in the ram
if (isset($this->storedData[$player->index]) && isset($this->storedData[$player->index][$meta->dataId])) {
return $this->storedData[$player->index][$meta->dataId];
}
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$dataQuery = "SELECT `value` FROM `" . self::TABLE_PLAYERDATA . "`
WHERE `dataId` = ?
AND `playerId` = ?
AND `serverIndex` = ?;";
$dataStatement = $mysqli->prepare($dataQuery);
if ($mysqli->error) {
trigger_error($mysqli->error);
return null;
}
$dataStatement->bind_param('iii', $meta->dataId, $player->index, $serverIndex);
$dataStatement->execute();
if ($dataStatement->error) {
trigger_error($dataStatement->error);
return null;
}
$dataStatement->store_result();
if ($dataStatement->num_rows <= 0) {
$this->setPlayerData($object, $dataName, $player, $meta->defaultValue, $serverIndex);
return $meta->defaultValue;
}
$dataStatement->bind_result($value);
$dataStatement->fetch();
$dataStatement->free_result();
$dataStatement->close();
$data = $this->castSetting($meta->type, $value);
// Store setting in the ram
if (!isset($this->storedData[$player->index])) {
$this->storedData[$player->index] = array();
}
$this->storedData[$player->index][$meta->dataId] = $data;
return $data;
}
/**
* Set a PlayerData to a specific defined statMetaData
*
* @param mixed $object
* @param string $dataName
* @param Player $player
* @param mixed $value
* @param int $serverIndex (empty if it's global)
* @return bool
*/
public function setPlayerData($object, $dataName, Player $player, $value, $serverIndex = -1) {
$className = ClassUtil::getClass($object);
if (!$player) {
return false;
}
$dataId = $this->getMetaDataId($className, $dataName);
if (!$dataId) {
return false;
}
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = "INSERT INTO `" . self::TABLE_PLAYERDATA . "` (
`serverIndex`,
`playerId`,
`dataId`,
`value`
) VALUES (
?, ?, ?, ?
) ON DUPLICATE KEY UPDATE
`value` = VALUES(`value`);";
$statement = $mysqli->prepare($query);
if ($mysqli->error) {
trigger_error($mysqli->error);
return false;
}
$statement->bind_param('iiis', $serverIndex, $player->index, $dataId, $value);
$statement->execute();
if ($statement->error) {
trigger_error($statement->error);
$statement->close();
return false;
}
$statement->close();
// Store changed value
if (!isset($this->storedData[$player->index])) {
$this->storedData[$player->index] = array();
}
$this->storedData[$player->index][$dataId] = $value;
return true;
}
/**
* Return the Id of the MetaData
*
* @param string $className
* @param string $statName
* @return int
*/
private function getMetaDataId($className, $statName) {
if (isset($this->metaData[$className . $statName])) {
$stat = $this->metaData[$className . $statName];
return (int)$stat->dataId;
}
return null;
}
/**
* Cast a Setting to the given Type
*
* @param string $type
* @param mixed $value
* @return mixed
*/
private function castSetting($type, $value) {
if ($type === self::TYPE_INT) {
return (int)$value;
}
if ($type === self::TYPE_REAL) {
return (float)$value;
}
if ($type === self::TYPE_BOOL) {
return (bool)$value;
}
if ($type === self::TYPE_STRING) {
return (string)$value;
}
if ($type === self::TYPE_ARRAY) {
return explode(self::ARRAY_DELIMITER, $value);
}
trigger_error('Unsupported data type. ' . print_r($type, true));
return $value;
}
}

View File

@ -0,0 +1,278 @@
<?php
namespace ManiaControl\Players;
use FML\Controls\Frame;
use FML\Controls\Labels\Label_Button;
use FML\Controls\Labels\Label_Text;
use FML\Controls\Quad;
use FML\Controls\Quads\Quad_BgsPlayerCard;
use FML\ManiaLink;
use FML\Script\Script;
use ManiaControl\ManiaControl;
use ManiaControl\Manialinks\ManialinkManager;
use ManiaControl\Statistics\StatisticManager;
use ManiaControl\Utils\Formatter;
/**
* Player Detailed Page
*
* @author ManiaControl Team <mail@maniacontrol.com>
* @copyright 2014 ManiaControl Team
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class PlayerDetailed {
/*
* Constants
*/
const STATS_PER_COLUMN = 13;
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
/**
* Create a new Player Detailed Instance
*
* @param ManiaControl $maniaControl
*/
public function __construct(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
// Settings
$this->width = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsWidth();
$this->height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight();
$this->quadStyle = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultMainWindowStyle();
$this->quadSubstyle = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultMainWindowSubStyle();
}
/**
* Show a Frame with detailed Information about the Target Player
*
* @param Player $player
* @param string $targetLogin
*/
public function showPlayerDetailed(Player $player, $targetLogin) {
/** @var Player $target */
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
// Create ManiaLink
$maniaLink = new ManiaLink(ManialinkManager::MAIN_MLID);
$script = $maniaLink->getScript();
// Main frame
$frame = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultListFrame($script);
$maniaLink->add($frame);
// Create script and features
$script = new Script();
$maniaLink->setScript($script);
$posY = $this->height / 2 - 7;
//Nation Quad
$countryQuad = new Quad();
$frame->add($countryQuad);
$countryQuad->setImage("file://ZoneFlags/Login/{$targetLogin}/country");
$countryQuad->setPosition(-$this->width / 2 + 10, $posY);
$countryQuad->setSize(5, 5);
$countryQuad->setZ(-0.1);
$countryQuad->setHAlign($countryQuad::LEFT);
//Nickname
$label = new Label_Text();
$frame->add($label);
$label->setPosition(-$this->width / 2 + 15, $posY);
$label->setText($target->nickname);
$label->setHAlign($label::LEFT);
//Define MainLabel (Login)
$posY -= 8;
$mainLabel = new Label_Text();
$frame->add($mainLabel);
$mainLabel->setPosition(-$this->width / 2 + 10, $posY);
$mainLabel->setTextSize(1.2);
$mainLabel->setHAlign($mainLabel::LEFT);
$mainLabel->setText('Login: ');
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText('Nation: ');
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText('Province: ');
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText('Authorization: ');
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText("Ladder Rank:");
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText('Ladder Score: ');
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText('Inscribed Zone: ');
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText('Avatar');
//Login
$posY = $this->height / 2 - 15;
$mainLabel = new Label_Text();
$frame->add($mainLabel);
$mainLabel->setPosition(-$this->width / 2 + 30, $posY);
$mainLabel->setText($target->login);
$mainLabel->setTextSize(1.2);
$mainLabel->setHAlign($mainLabel::LEFT);
//Country
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText($target->getCountry());
//Province
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText($target->getProvince());
//AuthLevel
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText($this->maniaControl->getAuthenticationManager()->getAuthLevelName($target->authLevel));
//LadderRank
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText($target->ladderRank);
//LadderScore
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText(round($target->ladderScore, 2));
//Played Since
$posY -= 5;
$label = clone $mainLabel;
$frame->add($label);
$label->setY($posY);
$label->setText(date('d M Y', time() - 3600 * 24 * $target->daysSinceZoneInscription));
$quad = new Quad();
$frame->add($quad);
$quad->setImage('file://Avatars/' . $targetLogin . "/default");
$quad->setPosition(-$this->width / 2 + 50, -$this->height / 2 + 34);
$quad->setAlign($quad::RIGHT, $quad::TOP);
$quad->setSize(20, 20);
//Statistics
$frame->add($this->statisticsFrame($target));
$quad = new Label_Button();
$frame->add($quad);
$quad->setStyle($quad::STYLE_CardMain_Quit);
$quad->setHAlign($quad::LEFT);
$quad->setScale(0.75);
$quad->setText('Back');
$quad->setPosition(-$this->width / 2 + 7, -$this->height / 2 + 7);
$quad->setAction(PlayerCommands::ACTION_OPEN_PLAYERLIST);
// render and display xml
$this->maniaControl->getManialinkManager()->displayWidget($maniaLink, $player, 'PlayerDetailed');
}
/**
* Build a Frame with Statistics about the given Player
*
* @param Player $player
* @return Frame
*/
public function statisticsFrame(Player $player) {
$frame = new Frame();
$playerStats = $this->maniaControl->getStatisticManager()->getAllPlayerStats($player);
$posY = $this->height / 2 - 15;
$posX = -$this->width / 2 + 52;
$index = 1;
foreach ($playerStats as $stat) {
$value = (float)$stat[1];
if (!$value) {
continue;
}
$statProperties = $stat[0];
if ($statProperties->type === StatisticManager::STAT_TYPE_TIME) {
$value = Formatter::formatTimeH($value);
} else if ($statProperties->type === StatisticManager::STAT_TYPE_FLOAT) {
$value = round($value, 2);
}
if ($index % 2 !== 0) {
$lineQuad = new Quad_BgsPlayerCard();
$frame->add($lineQuad);
$lineQuad->setSize(49, 4);
$lineQuad->setSubStyle($lineQuad::SUBSTYLE_BgPlayerCardBig);
$lineQuad->setPosition($posX, $posY, 0.001);
$lineQuad->setHAlign($lineQuad::LEFT);
}
$label = new Label_Text();
$frame->add($label);
$label->setPosition($posX + 4, $posY);
$label->setText($statProperties->name);
$label->setHAlign($label::LEFT);
$label->setTextSize(1.5);
$label = new Label_Text();
$frame->add($label);
$label->setPosition($posX + 40, $posY);
$label->setText($value);
$label->setTextSize(1.5);
$posY -= 4;
$index++;
if ($index > self::STATS_PER_COLUMN) {
$posY = $this->height / 2 - 15;
$posX += 47;
$index = 0;
}
}
return $frame;
}
}

788
core/Players/PlayerList.php Normal file
View File

@ -0,0 +1,788 @@
<?php
namespace ManiaControl\Players;
use FML\Controls\Frame;
use FML\Controls\Labels\Label_Text;
use FML\Controls\Quad;
use FML\Controls\Quads\Quad_BgRaceScore2;
use FML\Controls\Quads\Quad_BgsPlayerCard;
use FML\Controls\Quads\Quad_Emblems;
use FML\Controls\Quads\Quad_Icons64x64_1;
use FML\Controls\Quads\Quad_UIConstruction_Buttons;
use FML\ManiaLink;
use FML\Script\Features\Paging;
use ManiaControl\Admin\AuthenticationManager;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Callbacks\CallbackManager;
use ManiaControl\Callbacks\TimerListener;
use ManiaControl\ManiaControl;
use ManiaControl\Manialinks\ManialinkManager;
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
use ManiaControl\Utils\Formatter;
use Maniaplanet\DedicatedServer\Xmlrpc\PlayerStateException;
use Maniaplanet\DedicatedServer\Xmlrpc\UnknownPlayerException;
use MCTeam\CustomVotesPlugin;
/**
* PlayerList Widget Class
*
* @author ManiaControl Team <mail@maniacontrol.com>
* @copyright 2014 ManiaControl Team
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class PlayerList implements ManialinkPageAnswerListener, CallbackListener, TimerListener {
/*
* Constants
*/
const ACTION_FORCE_RED = 'PlayerList.ForceRed';
const ACTION_FORCE_BLUE = 'PlayerList.ForceBlue';
const ACTION_FORCE_SPEC = 'PlayerList.ForceSpec';
const ACTION_FORCE_SPEC_VOTE = 'PlayerList.ForceSpecVote';
const ACTION_FORCE_PLAY = 'PlayerList.ForcePlay';
const ACTION_PLAYER_ADV = 'PlayerList.PlayerAdvancedActions';
const ACTION_CLOSE_PLAYER_ADV = 'PlayerList.ClosePlayerAdvWidget';
const ACTION_MUTE_PLAYER = 'PlayerList.MutePlayer';
const ACTION_UNMUTE_PLAYER = 'PlayerList.UnMutePlayer';
const ACTION_WARN_PLAYER = 'PlayerList.WarnPlayer';
const ACTION_KICK_PLAYER = 'PlayerList.KickPlayer';
const ACTION_KICK_PLAYER_VOTE = 'PlayerList.KickPlayerVote';
const ACTION_BAN_PLAYER = 'PlayerList.BanPlayer';
const ACTION_ADD_AS_MASTER = 'PlayerList.PlayerAddAsMaster';
const ACTION_ADD_AS_ADMIN = 'PlayerList.PlayerAddAsAdmin';
const ACTION_ADD_AS_MOD = 'PlayerList.PlayerAddAsModerator';
const ACTION_REVOKE_RIGHTS = 'PlayerList.RevokeRights';
const ACTION_OPEN_PLAYER_DETAILED = 'PlayerList.OpenPlayerDetailed';
const ACTION_SPECTATE_PLAYER = 'PlayerList.SpectatePlayer';
const DEFAULT_CUSTOM_VOTE_PLUGIN = 'MCTeam\CustomVotesPlugin';
const SHOWN_MAIN_WINDOW = -1;
const MAX_PLAYERS_PER_PAGE = 15;
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
private $playersListShown = array();
/**
* Construct a new PlayerList instance
*
* @param ManiaControl $maniaControl
*/
public function __construct(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
// Callbacks
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ACTION_CLOSE_PLAYER_ADV, $this, 'closePlayerAdvancedWidget');
$this->maniaControl->getCallbackManager()->registerCallbackListener(ManialinkManager::CB_MAIN_WINDOW_CLOSED, $this, 'closeWidget');
$this->maniaControl->getCallbackManager()->registerCallbackListener(ManialinkManager::CB_MAIN_WINDOW_OPENED, $this, 'handleWidgetOpened');
$this->maniaControl->getCallbackManager()->registerCallbackListener(CallbackManager::CB_MP_PLAYERMANIALINKPAGEANSWER, $this, 'handleManialinkPageAnswer');
// Update Widget Events
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERINFOCHANGED, $this, 'updateWidget');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERDISCONNECT, $this, 'updateWidget');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERCONNECT, $this, 'updateWidget');
$this->maniaControl->getCallbackManager()->registerCallbackListener(AuthenticationManager::CB_AUTH_LEVEL_CHANGED, $this, 'updateWidget');
}
/**
* Add Player to Shown List
*
* @param Player $player
* @param int $showStatus
*/
public function addPlayerToShownList(Player $player, $showStatus = self::SHOWN_MAIN_WINDOW) {
$this->playersListShown[$player->login] = $showStatus;
}
/**
* Unset the player if he opened another Main Widget
*
* @param Player $player
* @param $openedWidget
*/
public function handleWidgetOpened(Player $player, $openedWidget) {
//unset when another main widget got opened
if ($openedWidget !== 'PlayerList') {
unset($this->playersListShown[$player->login]);
}
}
/**
* Closes the widget
*
* @param Player $player
*/
public function closeWidget(Player $player) {
unset($this->playersListShown[$player->login]);
}
/**
* Closes the player advanced widget widget
*
* @param array $callback
* @param Player $player
*/
public function closePlayerAdvancedWidget(array $callback, Player $player) {
$this->playersListShown[$player->login] = self::SHOWN_MAIN_WINDOW;
$this->showPlayerList($player); // overwrite the manialink
}
/**
* Show the PlayerList Widget to the Player
*
* @param Player $player
*/
public function showPlayerList(Player $player) {
$width = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsWidth();
$height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight();
// get PlayerList
$players = $this->maniaControl->getPlayerManager()->getPlayers();
//create manialink
$maniaLink = new ManiaLink(ManialinkManager::MAIN_MLID);
$script = $maniaLink->getScript();
$paging = new Paging();
$script->addFeature($paging);
// Main frame
$frame = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultListFrame($script, $paging);
$maniaLink->add($frame);
// Start offsets
$posX = -$width / 2;
$posY = $height / 2;
// Predefine Description Label
$descriptionLabel = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultDescriptionLabel();
$frame->add($descriptionLabel);
// Headline
$headFrame = new Frame();
$frame->add($headFrame);
$headFrame->setY($posY - 5);
$labelLineArray = array('Id' => $posX + 5, 'Nickname' => $posX + 18, 'Login' => $posX + 70, 'Location' => $posX + 101);
if ($this->maniaControl->getAuthenticationManager()->checkRight($player, AuthenticationManager::AUTH_LEVEL_MODERATOR)
) {
$labelLineArray['Actions'] = $posX + 135;
}
$this->maniaControl->getManialinkManager()->labelLine($headFrame, $labelLineArray);
$index = 1;
$posY = $height / 2 - 10;
$pageFrame = null;
foreach ($players as $listPlayer) {
if ($index % self::MAX_PLAYERS_PER_PAGE === 1) {
$pageFrame = new Frame();
$frame->add($pageFrame);
$paging->addPage($pageFrame);
$posY = $height / 2 - 10;
}
$path = $listPlayer->getProvince();
$playerFrame = new Frame();
$pageFrame->add($playerFrame);
if ($index % 2 !== 0) {
$lineQuad = new Quad_BgsPlayerCard();
$playerFrame->add($lineQuad);
$lineQuad->setSize($width, 4);
$lineQuad->setSubStyle($lineQuad::SUBSTYLE_BgPlayerCardBig);
$lineQuad->setZ(0.001);
}
$array = array($index => $posX + 5, $listPlayer->nickname => $posX + 18, $listPlayer->login => $posX + 70, $path => $posX + 101);
$this->maniaControl->getManialinkManager()->labelLine($playerFrame, $array);
$playerFrame->setY($posY);
// Show current Player Arrow
if ($listPlayer->index === $player->index) {
$currentQuad = new Quad_Icons64x64_1();
$playerFrame->add($currentQuad);
$currentQuad->setX($posX + 3.5);
$currentQuad->setZ(0.2);
$currentQuad->setSize(4, 4);
$currentQuad->setSubStyle($currentQuad::SUBSTYLE_ArrowBlue);
}
// Team Emblem
if ($listPlayer->teamId >= 0) {
// Player is in a Team
$teamQuad = new Quad_Emblems();
$playerFrame->add($teamQuad);
$teamQuad->setX($posX + 10);
$teamQuad->setZ(0.1);
$teamQuad->setSize(3.8, 3.8);
switch ($listPlayer->teamId) {
case 0:
$teamQuad->setSubStyle($teamQuad::SUBSTYLE_1);
break;
case 1:
$teamQuad->setSubStyle($teamQuad::SUBSTYLE_2);
break;
}
} else if ($listPlayer->isSpectator) {
// Player is in Spectator Mode
$specQuad = new Quad_BgRaceScore2();
$playerFrame->add($specQuad);
$specQuad->setX($posX + 10);
$specQuad->setZ(0.1);
$specQuad->setSubStyle($specQuad::SUBSTYLE_Spectator);
$specQuad->setSize(3.8, 3.8);
}
$countryCode = Formatter::mapCountry($listPlayer->getCountry());
if ($countryCode !== 'OTH') {
// Nation Quad
$countryQuad = new Quad();
$playerFrame->add($countryQuad);
$countryQuad->setImage("file://ZoneFlags/Login/{$listPlayer->login}/country");
$countryQuad->setX($posX + 98);
$countryQuad->setZ(1);
$countryQuad->setSize(4, 4);
$countryQuad->addTooltipLabelFeature($descriptionLabel, '$<' . $listPlayer->nickname . '$> from ' . $listPlayer->path);
}
// Level Quad
$rightQuad = new Quad_BgRaceScore2();
$playerFrame->add($rightQuad);
$rightQuad->setX($posX + 13);
$rightQuad->setZ(3);
$rightQuad->setSize(7, 3.5);
$rightQuad->setSubStyle($rightQuad::SUBSTYLE_CupFinisher);
$rightLabel = new Label_Text();
$playerFrame->add($rightLabel);
$rightLabel->setX($posX + 13.9);
$rightLabel->setZ(3.1);
$rightLabel->setText($this->maniaControl->getAuthenticationManager()->getAuthLevelAbbreviation($listPlayer->authLevel));
$rightLabel->setTextSize(0.8);
$rightLabel->setTextColor('fff');
$description = $this->maniaControl->getAuthenticationManager()->getAuthLevelName($listPlayer) . ' ' . $listPlayer->nickname;
$rightLabel->addTooltipLabelFeature($descriptionLabel, $description);
// Player Statistics
$playerQuad = new Quad_Icons64x64_1();
$playerFrame->add($playerQuad);
$playerQuad->setX($posX + 61);
$playerQuad->setZ(3);
$playerQuad->setSize(2.7, 2.7);
$playerQuad->setSubStyle($playerQuad::SUBSTYLE_TrackInfo);
$playerQuad->setAction(self::ACTION_OPEN_PLAYER_DETAILED . '.' . $listPlayer->login);
$description = 'View Statistics of $<' . $listPlayer->nickname . '$>';
$playerQuad->addTooltipLabelFeature($descriptionLabel, $description);
// Camera Quad
$playerQuad = new Quad_UIConstruction_Buttons();
$playerFrame->add($playerQuad);
$playerQuad->setX($posX + 64.5);
$playerQuad->setZ(3);
$playerQuad->setSize(3.8, 3.8);
$playerQuad->setSubStyle($playerQuad::SUBSTYLE_Camera);
$description = 'Spectate $<' . $listPlayer->nickname . '$>';
$playerQuad->addTooltipLabelFeature($descriptionLabel, $description);
$playerQuad->setAction(self::ACTION_SPECTATE_PLAYER . '.' . $listPlayer->login);
// Player Profile Quad
$playerQuad = new Quad_UIConstruction_Buttons();
$playerFrame->add($playerQuad);
$playerQuad->setX($posX + 68);
$playerQuad->setZ(3);
$playerQuad->setSize(3.8, 3.8);
$playerQuad->setSubStyle($playerQuad::SUBSTYLE_Author);
$playerQuad->addPlayerProfileFeature($listPlayer->login);
// Description Label
$description = 'View Player Profile of $<' . $listPlayer->nickname . '$>';
$playerQuad->addTooltipLabelFeature($descriptionLabel, $description);
if ($this->maniaControl->getAuthenticationManager()->checkRight($player, AuthenticationManager::AUTH_LEVEL_MODERATOR)
) {
// Further Player actions Quad
$playerQuad = new Quad_Icons64x64_1();
$playerFrame->add($playerQuad);
$playerQuad->setX($posX + 132);
$playerQuad->setZ(0.1);
$playerQuad->setSize(3.8, 3.8);
$playerQuad->setSubStyle($playerQuad::SUBSTYLE_Buddy);
$playerQuad->setAction(self::ACTION_PLAYER_ADV . '.' . $listPlayer->login);
// Description Label
$description = 'Advanced Player Actions for $<' . $listPlayer->nickname . '$>';
$playerQuad->addTooltipLabelFeature($descriptionLabel, $description);
}
if ($this->maniaControl->getServer()->isTeamMode()
) {
if ($this->maniaControl->getAuthenticationManager()->checkPermission($player, PlayerActions::SETTING_PERMISSION_FORCE_PLAYER_TEAM)
) {
// Force to Red-Team Quad
$redQuad = new Quad_Emblems();
$playerFrame->add($redQuad);
$redQuad->setX($posX + 145);
$redQuad->setZ(0.1);
$redQuad->setSize(3.8, 3.8);
$redQuad->setSubStyle($redQuad::SUBSTYLE_2);
$redQuad->setAction(self::ACTION_FORCE_RED . '.' . $listPlayer->login);
// Force to Red-Team Description Label
$description = 'Force $<' . $listPlayer->nickname . '$> to Red Team!';
$redQuad->addTooltipLabelFeature($descriptionLabel, $description);
// Force to Blue-Team Quad
$blueQuad = new Quad_Emblems();
$playerFrame->add($blueQuad);
$blueQuad->setX($posX + 141);
$blueQuad->setZ(0.1);
$blueQuad->setSize(3.8, 3.8);
$blueQuad->setSubStyle($blueQuad::SUBSTYLE_1);
$blueQuad->setAction(self::ACTION_FORCE_BLUE . '.' . $listPlayer->login);
// Force to Blue-Team Description Label
$description = 'Force $<' . $listPlayer->nickname . '$> to Blue Team!';
$blueQuad->addTooltipLabelFeature($descriptionLabel, $description);
} else if ($this->maniaControl->getPluginManager()->isPluginActive(self::DEFAULT_CUSTOM_VOTE_PLUGIN)
) {
// Kick Player Vote
$kickQuad = new Quad_UIConstruction_Buttons();
$playerFrame->add($kickQuad);
$kickQuad->setX($posX + 141);
$kickQuad->setZ(0.1);
$kickQuad->setSize(3.8, 3.8);
$kickQuad->setSubStyle($kickQuad::SUBSTYLE_Validate_Step2);
$kickQuad->setAction(self::ACTION_KICK_PLAYER_VOTE . '.' . $listPlayer->login);
$description = 'Start a Kick Vote on $<' . $listPlayer->nickname . '$>!';
$kickQuad->addTooltipLabelFeature($descriptionLabel, $description);
}
} else {
if ($this->maniaControl->getAuthenticationManager()->checkPermission($player, PlayerActions::SETTING_PERMISSION_FORCE_PLAYER_PLAY)
) {
// Force to Play
$playQuad = new Quad_Emblems();
$playerFrame->add($playQuad);
$playQuad->setX($posX + 143);
$playQuad->setZ(0.1);
$playQuad->setSize(3.8, 3.8);
$playQuad->setSubStyle($playQuad::SUBSTYLE_2);
$playQuad->setAction(self::ACTION_FORCE_PLAY . '.' . $listPlayer->login);
$description = 'Force $<' . $listPlayer->nickname . '$> to Play!';
$playQuad->addTooltipLabelFeature($descriptionLabel, $description);
}
}
if ($this->maniaControl->getAuthenticationManager()->checkPermission($player, PlayerActions::SETTING_PERMISSION_FORCE_PLAYER_SPEC)
) {
// Force to Spectator Quad
$spectatorQuad = new Quad_BgRaceScore2();
$playerFrame->add($spectatorQuad);
$spectatorQuad->setX($posX + 137);
$spectatorQuad->setZ(0.1);
$spectatorQuad->setSize(3.8, 3.8);
$spectatorQuad->setSubStyle($spectatorQuad::SUBSTYLE_Spectator);
$spectatorQuad->setAction(self::ACTION_FORCE_SPEC . '.' . $listPlayer->login);
// Force to Spectator Description Label
$description = 'Force $<' . $listPlayer->nickname . '$> to Spectator!';
$spectatorQuad->addTooltipLabelFeature($descriptionLabel, $description);
} else if ($this->maniaControl->getPluginManager()->isPluginActive(self::DEFAULT_CUSTOM_VOTE_PLUGIN)
) {
// Force to Spectator Quad
$spectatorQuad = new Quad_BgRaceScore2();
$playerFrame->add($spectatorQuad);
$spectatorQuad->setX($posX + 137);
$spectatorQuad->setZ(0.1);
$spectatorQuad->setSize(3.8, 3.8);
$spectatorQuad->setSubStyle($spectatorQuad::SUBSTYLE_Spectator);
$spectatorQuad->setAction(self::ACTION_FORCE_SPEC_VOTE . '.' . $listPlayer->login);
// Force to Spectator Description Label
$description = 'Start a Vote to force $<' . $listPlayer->nickname . '$> to Spectator!';
$spectatorQuad->addTooltipLabelFeature($descriptionLabel, $description);
}
$posY -= 4;
$index++;
}
// Show advanced window
$listShownValue = $this->playersListShown[$player->login];
if ($listShownValue && $listShownValue !== self::SHOWN_MAIN_WINDOW) {
$frame = $this->showAdvancedPlayerWidget($player, $listShownValue);
$maniaLink->add($frame);
}
// Render and display xml
$this->maniaControl->getManialinkManager()->displayWidget($maniaLink, $player, 'PlayerList');
}
/**
* Extra window with special actions on players like warn,kick, ban, authorization levels...
*
* @param Player $admin
* @param string $login
* @return Frame
*/
public function showAdvancedPlayerWidget(Player $admin, $login) {
$player = $this->maniaControl->getPlayerManager()->getPlayer($login);
$width = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsWidth();
$height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight();
$quadStyle = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultMainWindowStyle();
$quadSubstyle = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultMainWindowSubStyle();
//Settings
$posX = $width / 2 + 2.5;
$width = 35;
$height = $height * 0.75;
$textSize = 1.5;
$textColor = 'fff';
$quadWidth = $width - 7;
// mainframe
$frame = new Frame();
$frame->setSize($width, $height);
$frame->setPosition($posX + $width / 2, 0);
// Add Close Quad (X)
$closeQuad = new Quad_Icons64x64_1();
$frame->add($closeQuad);
$closeQuad->setPosition($width * 0.4, $height * 0.43, 3);
$closeQuad->setSize(6, 6);
$closeQuad->setSubStyle($closeQuad::SUBSTYLE_QuitRace);
$closeQuad->setAction(self::ACTION_CLOSE_PLAYER_ADV);
// Background Quad
$backgroundQuad = new Quad();
$frame->add($backgroundQuad);
$backgroundQuad->setSize($width, $height);
$backgroundQuad->setImage('https://dl.dropboxusercontent.com/u/105352981/Stuff/CAM%20SM%20BORDER%20PNG.png'); //TODO just a test
//$backgroundQuad->setStyles($quadStyle, $quadSubstyle);
$backgroundQuad->setZ(0.2);
// Background Quad
$backgroundQuad = new Quad();
$frame->add($backgroundQuad);
$backgroundQuad->setSize($width - 2, $height - 2);
$backgroundQuad->setStyles($quadStyle, $quadSubstyle);
$backgroundQuad->setZ(0.1);
// Show headline
$label = new Label_Text();
$frame->add($label);
$label->setHAlign($label::LEFT);
$label->setX(-$width / 2 + 5);
$label->setY($height / 2 - 5);
$label->setStyle($label::STYLE_TextCardSmall);
$label->setTextSize($textSize);
$label->setText('Advanced Actions');
$label->setTextColor($textColor);
// Show Nickname
$label = new Label_Text();
$frame->add($label);
$label->setHAlign($label::LEFT);
$label->setX(0);
$label->setY($height / 2 - 8);
$label->setStyle($label::STYLE_TextCardSmall);
$label->setTextSize($textSize);
$label->setText($player->nickname);
$label->setTextColor($textColor);
// Mute Player
$posY = $height / 2 - 14;
$quad = new Quad_BgsPlayerCard();
$frame->add($quad);
$quad->setX(0);
$quad->setY($posY);
$quad->setSubStyle($quad::SUBSTYLE_BgPlayerCardBig);
$quad->setSize($quadWidth, 5);
$label = new Label_Text();
$frame->add($label);
$label->setX(0);
$label->setY($posY);
$label->setStyle($label::STYLE_TextCardSmall);
$label->setTextSize($textSize);
$label->setTextColor($textColor);
if (!$player->isMuted()) {
$label->setText('Mute');
$quad->setAction(self::ACTION_MUTE_PLAYER . '.' . $login);
} else {
$label->setText('UnMute');
$quad->setAction(self::ACTION_UNMUTE_PLAYER . '.' . $login);
}
// Warn Player
$posY -= 5;
$quad = clone $quad;
$frame->add($quad);
$quad->setY($posY);
$quad->setAction(self::ACTION_WARN_PLAYER . '.' . $login);
$label = clone $label;
$frame->add($label);
$label->setY($posY);
$label->setText('Warn');
$label->setTextColor($textColor);
$posY -= 5;
// Show Kick
$quad = clone $quad;
$frame->add($quad);
$quad->setY($posY);
$quad->setAction(self::ACTION_KICK_PLAYER . '.' . $login);
$label = clone $label;
$frame->add($label);
$label->setY($posY);
$label->setText('Kick');
$label->setTextColor('f90');
$posY -= 5;
// Show Ban
$quad = clone $quad;
$frame->add($quad);
$quad->setY($posY);
$quad->setAction(self::ACTION_BAN_PLAYER . '.' . $login);
$label = clone $label;
$frame->add($label);
$label->setY($posY);
$label->setText('Ban');
$label->setTextColor('700');
$posY -= 10;
// Show Add as Master-Admin
$quad = clone $quad;
$frame->add($quad);
$quad->setY($posY);
$quad->setAction(self::ACTION_ADD_AS_MASTER . '.' . $login);
$label = clone $label;
$frame->add($label);
$label->setY($posY);
$label->setText('Set SuperAdmin');
$label->setTextColor($textColor);
$posY -= 5;
// Show Add as Admin
$quad = clone $quad;
$frame->add($quad);
$quad->setY($posY);
$quad->setAction(self::ACTION_ADD_AS_ADMIN . '.' . $login);
$label = clone $label;
$frame->add($label);
$label->setY($posY);
$label->setText('Set Admin');
$label->setTextColor($textColor);
$posY -= 5;
// Show Add as Moderator
$quad = clone $quad;
$frame->add($quad);
$quad->setY($posY);
$quad->setAction(self::ACTION_ADD_AS_MOD . '.' . $login);
$label = clone $label;
$frame->add($label);
$label->setY($posY);
$label->setText('Set Moderator');
$label->setTextColor($textColor);
if ($player->authLevel > 0
&& $this->maniaControl->getAuthenticationManager()->checkRight($admin, $player->authLevel + 1)
) {
$posY -= 5;
// Revoke Rights
$quad = clone $quad;
$frame->add($quad);
$quad->setY($posY);
$quad->setAction(self::ACTION_REVOKE_RIGHTS . '.' . $login);
$label = clone $label;
$frame->add($label);
$label->setY($posY);
$label->setText('Revoke Rights');
$label->setTextColor('700');
}
return $frame;
}
/**
* Called on ManialinkPageAnswer
*
* @param array $callback
*/
public function handleManialinkPageAnswer(array $callback) {
$actionId = $callback[1][2];
$actionArray = explode('.', $actionId, 3);
if (count($actionArray) <= 2) {
return;
}
$action = $actionArray[0] . '.' . $actionArray[1];
$adminLogin = $callback[1][1];
$targetLogin = $actionArray[2];
switch ($action) {
case self::ACTION_SPECTATE_PLAYER:
try {
$this->maniaControl->getClient()->forceSpectator($adminLogin, PlayerActions::SPECTATOR_BUT_KEEP_SELECTABLE);
$this->maniaControl->getClient()->forceSpectatorTarget($adminLogin, $targetLogin, 1);
} catch (PlayerStateException $e) {
} catch (UnknownPlayerException $e) {
}
break;
case self::ACTION_OPEN_PLAYER_DETAILED:
$player = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
$this->maniaControl->getPlayerManager()->getPlayerDetailed()->showPlayerDetailed($player, $targetLogin);
unset($this->playersListShown[$player->login]);
break;
case self::ACTION_FORCE_BLUE:
$this->maniaControl->getPlayerManager()->getPlayerActions()->forcePlayerToTeam($adminLogin, $targetLogin, PlayerActions::TEAM_BLUE);
break;
case self::ACTION_FORCE_RED:
$this->maniaControl->getPlayerManager()->getPlayerActions()->forcePlayerToTeam($adminLogin, $targetLogin, PlayerActions::TEAM_RED);
break;
case self::ACTION_FORCE_SPEC:
$this->maniaControl->getPlayerManager()->getPlayerActions()->forcePlayerToSpectator($adminLogin, $targetLogin, PlayerActions::SPECTATOR_BUT_KEEP_SELECTABLE);
break;
case self::ACTION_FORCE_PLAY:
$this->maniaControl->getPlayerManager()->getPlayerActions()->forcePlayerToPlay($adminLogin, $targetLogin);
break;
case self::ACTION_MUTE_PLAYER:
$this->maniaControl->getPlayerManager()->getPlayerActions()->mutePlayer($adminLogin, $targetLogin);
$this->showPlayerList($this->maniaControl->getPlayerManager()->getPlayer($adminLogin));
break;
case self::ACTION_UNMUTE_PLAYER:
$this->maniaControl->getPlayerManager()->getPlayerActions()->unMutePlayer($adminLogin, $targetLogin);
$this->showPlayerList($this->maniaControl->getPlayerManager()->getPlayer($adminLogin));
break;
case self::ACTION_WARN_PLAYER:
$this->maniaControl->getPlayerManager()->getPlayerActions()->warnPlayer($adminLogin, $targetLogin);
break;
case self::ACTION_KICK_PLAYER:
$this->maniaControl->getPlayerManager()->getPlayerActions()->kickPlayer($adminLogin, $targetLogin);
break;
case self::ACTION_BAN_PLAYER:
$this->maniaControl->getPlayerManager()->getPlayerActions()->banPlayer($adminLogin, $targetLogin);
break;
case self::ACTION_PLAYER_ADV:
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
$this->advancedPlayerWidget($admin, $targetLogin);
break;
case self::ACTION_ADD_AS_MASTER:
$this->maniaControl->getPlayerManager()->getPlayerActions()->grandAuthLevel($adminLogin, $targetLogin, AuthenticationManager::AUTH_LEVEL_SUPERADMIN);
break;
case self::ACTION_ADD_AS_ADMIN:
$this->maniaControl->getPlayerManager()->getPlayerActions()->grandAuthLevel($adminLogin, $targetLogin, AuthenticationManager::AUTH_LEVEL_ADMIN);
break;
case self::ACTION_ADD_AS_MOD:
$this->maniaControl->getPlayerManager()->getPlayerActions()->grandAuthLevel($adminLogin, $targetLogin, AuthenticationManager::AUTH_LEVEL_MODERATOR);
break;
case self::ACTION_REVOKE_RIGHTS:
$this->maniaControl->getPlayerManager()->getPlayerActions()->revokeAuthLevel($adminLogin, $targetLogin);
break;
case self::ACTION_FORCE_SPEC_VOTE:
/** @var $votesPlugin CustomVotesPlugin */
$votesPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::DEFAULT_CUSTOM_VOTE_PLUGIN);
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
$startMessage = $admin->getEscapedNickname() . '$s started a vote to force $<' . $target->nickname . '$> into spectator!';
$votesPlugin->defineVote('forcespec', 'Force ' . $target->getEscapedNickname() . ' Spec', true, $startMessage);
$votesPlugin->startVote($admin, 'forcespec', function ($result) use (&$votesPlugin, &$target) {
$this->maniaControl->getChat()->sendInformation('$sVote successful -> Player ' . $target->getEscapedNickname() . ' forced to Spectator!');
$votesPlugin->undefineVote('forcespec');
try {
$this->maniaControl->getClient()->forceSpectator($target->login, PlayerActions::SPECTATOR_BUT_KEEP_SELECTABLE);
$this->maniaControl->getClient()->spectatorReleasePlayerSlot($target->login);
} catch (PlayerStateException $e) {
} catch (UnknownPlayerException $e) {
}
});
break;
case self::ACTION_KICK_PLAYER_VOTE:
/** @var $votesPlugin CustomVotesPlugin */
$votesPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::DEFAULT_CUSTOM_VOTE_PLUGIN);
$admin = $this->maniaControl->getPlayerManager()->getPlayer($adminLogin);
$target = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
$startMessage = $admin->getEscapedNickname() . '$s started a vote to kick $<' . $target->nickname . '$>!';
$votesPlugin->defineVote('kick', 'Kick ' . $target->getEscapedNickname(), true, $startMessage);
$votesPlugin->startVote($admin, 'kick', function ($result) use (&$votesPlugin, &$target) {
$this->maniaControl->getChat()->sendInformation('$sVote successful -> ' . $target->getEscapedNickname() . ' got Kicked!');
$votesPlugin->undefineVote('kick');
$message = '$39F You got kicked due to a Public Vote!$z ';
try {
$this->maniaControl->getClient()->kick($target->login, $message);
} catch (UnknownPlayerException $e) {
}
});
break;
}
}
/**
* Display the Advanced Player Window
*
* @param Player $caller
* @param string $login
*/
public function advancedPlayerWidget(Player $caller, $login) {
// Set status to target player login
$this->playersListShown[$caller->login] = $login;
// Reopen PlayerList
$this->showPlayerList($caller);
}
/**
* Reopen the widget on PlayerInfoChanged / Player Connect and Disconnect
*
* @param Player $player
*/
public function updateWidget(Player $player) {
foreach ($this->playersListShown as $login => $shown) {
if (!$shown) {
continue;
}
// Check if shown player still exists
$player = $this->maniaControl->getPlayerManager()->getPlayer($login);
if (!$player) {
unset($this->playersListShown[$login]);
continue;
}
// Reopen widget
if ($shown !== self::SHOWN_MAIN_WINDOW) {
$this->playersListShown[$login] = false;
}
$this->showPlayerList($player);
}
}
}

View File

@ -0,0 +1,581 @@
<?php
namespace ManiaControl\Players;
use ManiaControl\Admin\AdminLists;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Callbacks\CallbackManager;
use ManiaControl\Callbacks\Callbacks;
use ManiaControl\Callbacks\TimerListener;
use ManiaControl\Logger;
use ManiaControl\ManiaControl;
use ManiaControl\Statistics\StatisticManager;
use ManiaControl\Utils\Formatter;
use Maniaplanet\DedicatedServer\Xmlrpc\UnknownPlayerException;
/**
* Class managing Players
*
* @author ManiaControl Team <mail@maniacontrol.com>
* @copyright 2014 ManiaControl Team
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class PlayerManager implements CallbackListener, TimerListener {
/*
* Constants
*/
const CB_PLAYERCONNECT = 'PlayerManagerCallback.PlayerConnect';
const CB_PLAYERDISCONNECT = 'PlayerManagerCallback.PlayerDisconnect';
const CB_PLAYERINFOCHANGED = 'PlayerManagerCallback.PlayerInfoChanged';
const CB_SERVER_EMPTY = 'PlayerManagerCallback.ServerEmpty';
const TABLE_PLAYERS = 'mc_players';
const SETTING_JOIN_LEAVE_MESSAGES = 'Enable Join & Leave Messages';
const SETTING_JOIN_LEAVE_MESSAGES_SPECTATOR = 'Enable Join & Leave Messages for Spectators';
const STAT_JOIN_COUNT = 'Joins';
const STAT_SERVERTIME = 'Servertime';
/*
* Public properties
*/
/** @var PlayerActions $playerActions */
/** @deprecated see getPlayerActions() */
public $playerActions = null;
/** @var PlayerCommands $playerCommands */
/** @deprecated see getPlayerCommands() */
public $playerCommands = null;
/** @var PlayerDetailed $playerDetailed */
/** @deprecated see getPlayerDetailed() */
public $playerDetailed = null;
/** @var PlayerDataManager $playerDataManager */
/** @deprecated see getPlayerDataManager() */
public $playerDataManager = null;
/** @var PlayerList $playerList */
/** @deprecated see getPlayerList() */
public $playerList = null;
/** @var AdminLists $adminLists */
/** @deprecated see getAdminLists() */
public $adminLists = null;
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
/** @var Player[] $players */
private $players = array();
/**
* Construct a new Player Manager
*
* @param ManiaControl $maniaControl
*/
public function __construct(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
$this->initTables();
$this->playerCommands = new PlayerCommands($maniaControl);
$this->playerActions = new PlayerActions($maniaControl);
$this->playerDetailed = new PlayerDetailed($maniaControl);
$this->playerDataManager = new PlayerDataManager($maniaControl);
$this->playerList = new PlayerList($maniaControl);
$this->adminLists = new AdminLists($maniaControl);
// Settings
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_JOIN_LEAVE_MESSAGES, true);
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_JOIN_LEAVE_MESSAGES_SPECTATOR, true);
// Callbacks
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::ONINIT, $this, 'onInit');
$this->maniaControl->getCallbackManager()->registerCallbackListener(CallbackManager::CB_MP_PLAYERCONNECT, $this, 'playerConnect');
$this->maniaControl->getCallbackManager()->registerCallbackListener(CallbackManager::CB_MP_PLAYERDISCONNECT, $this, 'playerDisconnect');
$this->maniaControl->getCallbackManager()->registerCallbackListener(CallbackManager::CB_MP_PLAYERINFOCHANGED, $this, 'playerInfoChanged');
// Player stats
$this->maniaControl->getStatisticManager()->defineStatMetaData(self::STAT_JOIN_COUNT);
$this->maniaControl->getStatisticManager()->defineStatMetaData(self::STAT_SERVERTIME, StatisticManager::STAT_TYPE_TIME);
}
/**
* Initialize necessary database tables
*
* @return bool
*/
private function initTables() {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$playerTableQuery = "CREATE TABLE IF NOT EXISTS `" . self::TABLE_PLAYERS . "` (
`index` int(11) NOT NULL AUTO_INCREMENT,
`login` varchar(100) NOT NULL,
`nickname` varchar(150) NOT NULL,
`path` varchar(100) NOT NULL,
`authLevel` int(11) NOT NULL DEFAULT '0',
`changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`index`),
UNIQUE KEY `login` (`login`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Player Data' AUTO_INCREMENT=1;";
$playerTableStatement = $mysqli->prepare($playerTableQuery);
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
return false;
}
$playerTableStatement->execute();
if ($playerTableStatement->error) {
trigger_error($playerTableStatement->error, E_USER_ERROR);
$playerTableStatement->close();
return false;
}
$playerTableStatement->close();
return true;
}
/**
* Return the player actions
*
* @return PlayerActions
*/
public function getPlayerActions() {
return $this->playerActions;
}
/**
* Return the player commands
*
* @return PlayerCommands
*/
public function getPlayerCommands() {
return $this->playerCommands;
}
/**
* Return the player detailed
*
* @return PlayerDetailed
*/
public function getPlayerDetailed() {
return $this->playerDetailed;
}
/**
* Return the player data manager
*
* @return PlayerDataManager
*/
public function getPlayerDataManager() {
return $this->playerDataManager;
}
/**
* Return the player list
*
* @return PlayerList
*/
public function getPlayerList() {
return $this->playerList;
}
/**
* Return the admin lists
*
* @return AdminLists
*/
public function getAdminLists() {
return $this->adminLists;
}
/**
* Handle OnInit callback
*/
public function onInit() {
// Add all players
$players = $this->maniaControl->getClient()->getPlayerList(300, 0, 2);
foreach ($players as $playerItem) {
if ($playerItem->playerId <= 0) {
continue;
}
try {
$detailedPlayerInfo = $this->maniaControl->getClient()->getDetailedPlayerInfo($playerItem->login);
} catch (UnknownPlayerException $exception) {
continue;
}
// Check if the Player is in a Team, to notify if its a TeamMode or not
if ($playerItem->teamId >= 0) {
$this->maniaControl->getServer()->setTeamMode(true);
}
$player = new Player($this->maniaControl, true);
$player->setInfo($playerItem);
$player->setDetailedInfo($detailedPlayerInfo);
$player->hasJoinedGame = true;
$this->addPlayer($player);
}
}
/**
* Add a player
*
* @param Player $player
* @return bool
*/
private function addPlayer(Player $player) {
$this->savePlayer($player);
$this->players[$player->login] = $player;
return true;
}
/**
* Save player in database and fill up properties
*
* @param Player $player
* @return bool
*/
private function savePlayer(Player &$player) {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
// Save player
$playerQuery = "INSERT INTO `" . self::TABLE_PLAYERS . "` (
`login`,
`nickname`,
`path`
) VALUES (
?, ?, ?
) ON DUPLICATE KEY UPDATE
`index` = LAST_INSERT_ID(`index`),
`nickname` = VALUES(`nickname`),
`path` = VALUES(`path`);";
$playerStatement = $mysqli->prepare($playerQuery);
if ($mysqli->error) {
trigger_error($mysqli->error);
return false;
}
$playerStatement->bind_param('sss', $player->login, $player->rawNickname, $player->path);
$playerStatement->execute();
if ($playerStatement->error) {
trigger_error($playerStatement->error);
$playerStatement->close();
return false;
}
$player->index = $playerStatement->insert_id;
$playerStatement->close();
// Get Player Auth Level from DB
$playerQuery = "SELECT `authLevel` FROM `" . self::TABLE_PLAYERS . "` WHERE `index` = ?;";
$playerStatement = $mysqli->prepare($playerQuery);
if ($mysqli->error) {
trigger_error($mysqli->error);
return false;
}
$playerStatement->bind_param('i', $player->index);
$playerStatement->execute();
if ($playerStatement->error) {
trigger_error($playerStatement->error);
$playerStatement->close();
return false;
}
$playerStatement->store_result();
$playerStatement->bind_result($player->authLevel);
$playerStatement->fetch();
$playerStatement->free_result();
$playerStatement->close();
return true;
}
/**
* Handle PlayerConnect Callback
*
* @param array $callback
*/
public function playerConnect(array $callback) {
$login = $callback[1][0];
try {
$playerInfo = $this->maniaControl->getClient()->getDetailedPlayerInfo($login);
$player = new Player($this->maniaControl, true);
$player->setDetailedInfo($playerInfo);
$this->addPlayer($player);
} catch (UnknownPlayerException $e) {
}
}
/**
* Handle PlayerDisconnect callback
*
* @param array $callback
*/
public function playerDisconnect(array $callback) {
$login = $callback[1][0];
$player = $this->removePlayer($login);
if (!$player) {
return;
}
// Trigger own callbacks
$this->maniaControl->getCallbackManager()->triggerCallback(self::CB_PLAYERDISCONNECT, $player);
if ($this->getPlayerCount(false) <= 0) {
$this->maniaControl->getCallbackManager()->triggerCallback(self::CB_SERVER_EMPTY);
}
if ($player->isFakePlayer()) {
return;
}
$played = Formatter::formatTimeH(time() - $player->joinTime);
$logMessage = "Player left: {$player->login} / {$player->nickname} Playtime: {$played}";
Logger::logInfo($logMessage, true);
if (!$player->isSpectator && $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_JOIN_LEAVE_MESSAGES) && !$player->isFakePlayer()
|| $player->isSpectator && $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_JOIN_LEAVE_MESSAGES_SPECTATOR)
) {
$this->maniaControl->getChat()->sendChat('$0f0$<$fff' . $player->nickname . '$> has left the game');
}
//Destroys stored PlayerData, after all Disconnect Callbacks got Handled
$this->getPlayerDataManager()->destroyPlayerData($player);
}
/**
* Remove a Player
*
* @param string $login
* @param bool $savePlayedTime
* @return Player $player
*/
private function removePlayer($login, $savePlayedTime = true) {
if (!isset($this->players[$login])) {
return null;
}
$player = $this->players[$login];
unset($this->players[$login]);
if ($savePlayedTime) {
$this->updatePlayedTime($player);
}
return $player;
}
/**
* Update total played time of the player
*
* @param Player $player
* @return bool
*/
private function updatePlayedTime(Player $player) {
if (!$player) {
return false;
}
$playedTime = time() - $player->joinTime;
return $this->maniaControl->getStatisticManager()->insertStat(self::STAT_SERVERTIME, $player, $this->maniaControl->getServer()->index, $playedTime);
}
/**
* Get the count of all Players
*
* @param bool $withoutSpectators
* @return int
*/
public function getPlayerCount($withoutSpectators = true) {
if (!$withoutSpectators) {
return count($this->players);
}
$count = 0;
foreach ($this->players as $player) {
if (!$player->isSpectator) {
$count++;
}
}
return $count;
}
/**
* Update PlayerInfo
*
* @param array $callback
*/
public function playerInfoChanged(array $callback) {
$player = $this->getPlayer($callback[1][0]['Login']);
if (!$player) {
return;
}
$player->ladderRank = $callback[1][0]["LadderRanking"];
$player->teamId = $callback[1][0]["TeamId"];
//Check if the Player is in a Team, to notify if its a TeamMode or not
if ($player->teamId >= 0) {
$this->maniaControl->getServer()->setTeamMode(true);
}
$prevJoinState = $player->hasJoinedGame;
$player->updatePlayerFlags($callback[1][0]["Flags"]);
$player->updateSpectatorStatus($callback[1][0]["SpectatorStatus"]);
//Check if Player finished joining the game
if ($player->hasJoinedGame && !$prevJoinState) {
if (!$player->isSpectator && $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_JOIN_LEAVE_MESSAGES) && !$player->isFakePlayer()
) {
$string = array(0 => '$0f0Player', 1 => '$0f0Moderator', 2 => '$0f0Admin', 3 => '$0f0SuperAdmin', 4 => '$0f0MasterAdmin');
$chatMessage = '$0f0' . $string[$player->authLevel] . ' $<$fff' . $player->nickname . '$> Nation: $<$fff' . $player->getCountry() . '$> joined!';
$this->maniaControl->getChat()->sendChat($chatMessage);
} else if ($player->isSpectator && $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_JOIN_LEAVE_MESSAGES_SPECTATOR)) {
$string = array(0 => '$0f0Player', 1 => '$0f0Moderator', 2 => '$0f0Admin', 3 => '$0f0SuperAdmin', 4 => '$0f0MasterAdmin');
$chatMessage = '$0f0' . $string[$player->authLevel] . ' $<$fff' . $player->nickname . '$> Nation: $<$fff' . $player->getCountry() . '$> joined as Spectator!';
$this->maniaControl->getChat()->sendChat($chatMessage);
}
$this->maniaControl->getChat()->sendInformation('This server uses ManiaControl v' . ManiaControl::VERSION . '!', $player->login);
$logMessage = "Player joined: {$player->login} / {$player->nickname} Nation: " . $player->getCountry() . " IP: {$player->ipAddress}";
Logger::logInfo($logMessage, true);
// Increment the Player Join Count
$this->maniaControl->getStatisticManager()->incrementStat(self::STAT_JOIN_COUNT, $player, $this->maniaControl->getServer()->index);
// Trigger own PlayerJoined callback
$this->maniaControl->getCallbackManager()->triggerCallback(self::CB_PLAYERCONNECT, $player);
}
// Trigger own callback
$this->maniaControl->getCallbackManager()->triggerCallback(self::CB_PLAYERINFOCHANGED, $player);
}
/**
* Get a Player by login
*
* @param mixed $login
* @param bool $connectedPlayersOnly
* @return Player
*/
public function getPlayer($login, $connectedPlayersOnly = false) {
if ($login instanceof Player) {
return $login;
}
if (!isset($this->players[$login])) {
if ($connectedPlayersOnly) {
return null;
}
return $this->getPlayerFromDatabaseByLogin($login);
}
return $this->players[$login];
}
/**
* Get a Player from the database
*
* @param string $playerLogin
* @return Player
*/
private function getPlayerFromDatabaseByLogin($playerLogin) {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = "SELECT * FROM `" . self::TABLE_PLAYERS . "`
WHERE `login` LIKE '" . $mysqli->escape_string($playerLogin) . "';";
$result = $mysqli->query($query);
if (!$result) {
trigger_error($mysqli->error);
return null;
}
$row = $result->fetch_object();
$result->free();
if (!isset($row)) {
return null;
}
$player = new Player($this->maniaControl, false);
$player->index = $row->index;
$player->login = $row->login;
$player->rawNickname = $row->nickname;
$player->nickname = Formatter::stripDirtyCodes($player->rawNickname);
$player->path = $row->path;
$player->authLevel = $row->authLevel;
return $player;
}
/**
* Get all Players
*
* @return Player[]
*/
public function getPlayers() {
return $this->players;
}
/**
* Get the count of all spectators
*
* @return int
*/
public function getSpectatorCount() {
$count = 0;
foreach ($this->players as $player) {
if ($player->isSpectator) {
$count++;
}
}
return $count;
}
/**
* Get a Player by index
*
* @param int $index
* @param bool $connectedPlayersOnly
* @return Player
*/
public function getPlayerByIndex($index, $connectedPlayersOnly = false) {
foreach ($this->players as $player) {
if ($player->index === $index) {
return $player;
}
}
// Player is not online - Get Player from Database
if (!$connectedPlayersOnly) {
return $this->getPlayerFromDatabaseByIndex($index);
}
return null;
}
/**
* Get a Player out of the database
*
* @param int $playerIndex
* @return Player
*/
private function getPlayerFromDatabaseByIndex($playerIndex) {
if (!is_numeric($playerIndex)) {
return null;
}
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = "SELECT * FROM `" . self::TABLE_PLAYERS . "`
WHERE `index` = {$playerIndex};";
$result = $mysqli->query($query);
if (!$result) {
trigger_error($mysqli->error);
return null;
}
$row = $result->fetch_object();
$result->free();
if (!$row) {
return null;
}
$player = new Player($this->maniaControl, false);
$player->index = $playerIndex;
$player->login = $row->login;
$player->rawNickname = $row->nickname;
$player->nickname = Formatter::stripDirtyCodes($player->rawNickname);
$player->path = $row->path;
$player->authLevel = $row->authLevel;
return $player;
}
}