From cb69bc686be683a24b9dca0e3613a1c432670b32 Mon Sep 17 00:00:00 2001 From: Max Klaversma Date: Sun, 4 May 2014 15:43:16 +0200 Subject: [PATCH] Moved Queue + TeamSpeak to TheM\ --- application/plugins/QueuePlugin.php | 571 +----------------- application/plugins/TeamSpeakPlugin.php | 515 +---------------- application/plugins/TheM/QueuePlugin.php | 572 +++++++++++++++++++ application/plugins/TheM/TeamSpeakPlugin.php | 516 +++++++++++++++++ 4 files changed, 1090 insertions(+), 1084 deletions(-) create mode 100644 application/plugins/TheM/QueuePlugin.php create mode 100644 application/plugins/TheM/TeamSpeakPlugin.php diff --git a/application/plugins/QueuePlugin.php b/application/plugins/QueuePlugin.php index 91806859..79189305 100644 --- a/application/plugins/QueuePlugin.php +++ b/application/plugins/QueuePlugin.php @@ -1,570 +1 @@ -maniaControl = $maniaControl; - - $this->maniaControl->timerManager->registerTimerListening($this, 'handleEverySecond', 1000); - $this->maniaControl->callbackManager->registerCallbackListener(PlayerManager::CB_PLAYERCONNECT, $this, 'handlePlayerConnect'); - $this->maniaControl->callbackManager->registerCallbackListener(PlayerManager::CB_PLAYERDISCONNECT, $this, 'handlePlayerDisconnect'); - $this->maniaControl->callbackManager->registerCallbackListener(CallbackManager::CB_MP_PLAYERINFOCHANGED, $this, 'handlePlayerInfoChanged'); - $this->maniaControl->callbackManager->registerCallbackListener(Callbacks::BEGINMAP, $this, 'handleBeginMap'); - $this->maniaControl->manialinkManager->registerManialinkPageAnswerListener(self::ML_ADDTOQUEUE, $this, 'handleManiaLinkAnswerAdd'); - $this->maniaControl->manialinkManager->registerManialinkPageAnswerListener(self::ML_REMOVEFROMQUEUE, $this, 'handleManiaLinkAnswerRemove'); - - $this->maniaControl->settingManager->initSetting($this, self::QUEUE_MAX, 8); - $this->maniaControl->settingManager->initSetting($this, self::QUEUE_WIDGET_POS_X, 0); - $this->maniaControl->settingManager->initSetting($this, self::QUEUE_WIDGET_POS_Y, -46); - $this->maniaControl->settingManager->initSetting($this, self::QUEUE_ACTIVE_ON_PASS, false); - $this->maniaControl->settingManager->initSetting($this, self::QUEUE_CHATMESSAGES, true); - - $maxPlayers = $this->maniaControl->client->getMaxPlayers(); - $this->maxPlayers = $maxPlayers['CurrentValue']; - - foreach($this->maniaControl->playerManager->getPlayers() as $player) { - if ($player->isSpectator) { - $this->spectators[$player->login] = $player->login; - $this->maniaControl->client->forceSpectator($player->login, 1); - $this->showJoinQueueWidget($player); - } - } - } - - /** - * Unload the plugin and its resources - */ - public function unload() { - $this->maniaControl->manialinkManager->unregisterManialinkPageAnswerListener($this); - $this->maniaControl->callbackManager->unregisterCallbackListener($this); - $this->maniaControl->timerManager->unregisterTimerListenings($this); - - foreach($this->spectators as $spectator) { - $this->maniaControl->client->forceSpectator($spectator, 3); - $this->maniaControl->client->forceSpectator($spectator, 0); - } - - foreach($this->maniaControl->playerManager->getPlayers() as $player) { - $this->hideQueueWidget($player); - } - - $this->queue = array(); - $this->spectators = array(); - $this->showPlay = array(); - unset($this->maniaControl); - } - - /** - * Get plugin id - * - * @return int - */ - public static function getId() { - return self::ID; - } - - /** - * Get Plugin Name - * - * @return string - */ - public static function getName() { - return 'Queue Plugin'; - } - - /** - * Get Plugin Version - * - * @return float - */ - public static function getVersion() { - return self::VERSION; - } - - /** - * Get Plugin Author - * - * @return string - */ - public static function getAuthor() { - return 'TheM'; - } - - /** - * Get Plugin Description - * - * @return string - */ - public static function getDescription() { - return 'Plugin offers the known AutoQueue/SpecJam options.'; - } - - /** - * Function handling on the connection of a player. - * - * @param Player $player - */ - public function handlePlayerConnect(Player $player) { - $maxPlayers = $this->maniaControl->client->getMaxPlayers(); - $this->maxPlayers = $maxPlayers['CurrentValue']; - - if ($player->isSpectator) { - $this->spectators[$player->login] = $player->login; - $this->maniaControl->client->forceSpectator($player->login, 1); - $this->showJoinQueueWidget($player); - } else { - if (count($this->queue) != 0) { - $this->maniaControl->client->forceSpectator($player->login, 1); - $this->spectators[$player->login] = $player->login; - $this->showJoinQueueWidget($player); - } - } - } - - /** - * Function handling on the disconnection of a player. - * - * @param Player $player - */ - public function handlePlayerDisconnect(Player $player) { - $maxPlayers = $this->maniaControl->client->getMaxPlayers(); - $this->maxPlayers = $maxPlayers['CurrentValue']; - - if (isset($this->spectators[$player->login])) { - unset($this->spectators[$player->login]); - } - $this->removePlayerFromQueue($player->login); - $this->moveFirstPlayerToPlay(); - } - - /** - * Function handling the change of player information. - * - * @param array $callback - */ - public function handlePlayerInfoChanged(array $callback) { - $login = $callback[1][0]['Login']; - $player = $this->maniaControl->playerManager->getPlayer($login); - - if (!is_null($player)) { - if ($player->isSpectator) { - if (!isset($this->spectators[$player->login])) { - $this->maniaControl->client->forceSpectator($player->login, 1); - $this->spectators[$player->login] = $player->login; - $this->showJoinQueueWidget($player); - $this->showQueueWidgetSpectators(); - } - } else { - $this->removePlayerFromQueue($player->login); - if (isset($this->spectators[$player->login])) { - unset($this->spectators[$player->login]); - } - - $found = false; - foreach($this->showPlay as $showPlay) { - if ($showPlay['player']->login == $player->login) { - $found = true; - } - } - - if (!$found) { - $this->hideQueueWidget($player); - } - } - } - } - - public function showQueueWidgetSpectators() { - foreach($this->spectators as $login) { - $player = $this->maniaControl->playerManager->getPlayer($login); - $this->showJoinQueueWidget($player); - } - } - - /** - * Function called on every second. - */ - public function handleEverySecond() { - if ($this->maxPlayers > (count($this->maniaControl->playerManager->players) - count($this->spectators))) { - $this->moveFirstPlayerToPlay(); - $this->showQueueWidgetSpectators(); - } - - foreach($this->showPlay as $showPlay) { - if (($showPlay['time'] + 5) < time()) { - $this->hideQueueWidget($showPlay['player']); - unset($this->showPlay[$showPlay['player']->login]); - } - } - } - - /** - * Checks for being of new map to retrieve maximum number of players. - * - * @param $currentMap - */ - public function handleBeginMap($currentMap) { - $maxPlayers = $this->maniaControl->client->getMaxPlayers(); - $this->maxPlayers = $maxPlayers['CurrentValue']; - } - - /** - * Function handling the click of the widget to add them to the queue. - * - * @param array $chatCallback - * @param Player $player - */ - public function handleManiaLinkAnswerAdd(array $chatCallback, Player $player) { - $this->addPlayerToQueue($player); - } - - /** - * Function handling the click of the widget to remove them from the queue. - * - * @param array $chatCallback - * @param Player $player - */ - public function handleManiaLinkAnswerRemove(array $chatCallback, Player $player) { - $this->removePlayerFromQueue($player->login); - $this->showJoinQueueWidget($player); - $this->sendChatMessage('$<$fff' . $player->nickname . '$> has left the queue!'); - } - - /** - * Function used to move the first queued player to the - */ - private function moveFirstPlayerToPlay() { - if (count($this->queue) > 0) { - $firstPlayer = $this->maniaControl->playerManager->getPlayer($this->queue[0]->login); - $this->forcePlayerToPlay($firstPlayer); - $this->showQueueWidgetSpectators(); - } - } - - /** - * Function to force a player to play status. - * - * @param Player $player - */ - private function forcePlayerToPlay(Player $player) { - if ($this->maniaControl->client->getServerPassword() != false && $this->maniaControl->settingManager->getSetting($this, self::QUEUE_ACTIVE_ON_PASS) == false) { - return; - } - - if ($this->maxPlayers > (count($this->maniaControl->playerManager->players) - count($this->spectators))) { - try { - $this->maniaControl->client->forceSpectator($player->login, 2); - } catch(Exception $e) { - // TODO: only possible valid exception should be "wrong login" - throw others (like connection error) - $this->maniaControl->chat->sendError("Error while leaving the Queue", $player->login); - return; - } - - try { - $this->maniaControl->client->forceSpectator($player->login, 0); - } catch(Exception $e) { - // TODO: only possible valid exception should be "wrong login" - throw others (like connection error) - } - - $teams = array(); - /** @var Player $playerObj */ - foreach($this->maniaControl->playerManager->players as $playerObj) { - if (!isset($teams[$playerObj->teamId])) { - $teams[$playerObj->teamId] = 1; - } else { - $teams[$playerObj->teamId]++; - } - } - - $smallestTeam = null; - $smallestSize = 999; - foreach($teams as $team => $size) { - if ($size < $smallestSize) { - $smallestTeam = $team; - $smallestSize = $size; - } - } - - try { - if ($smallestTeam != -1) { - $this->maniaControl->client->forcePlayerTeam($player->login, $smallestTeam); - } - } catch(Exception $e) { - // TODO: only possible valid exceptions should be "wrong login" or "not in team mode" - throw others (like connection error) - } - - if (isset($this->spectators[$player->login])) { - unset($this->spectators[$player->login]); - } - $this->removePlayerFromQueue($player->login); - $this->showPlayWidget($player); - $this->sendChatMessage('$<$fff' . $player->nickname . '$> has a free spot and is now playing!'); - } - - } - - /** - * Function adds a player to the queue. - * - * @param Player $player - * @return bool - */ - private function addPlayerToQueue(Player $player) { - if ($this->maniaControl->client->getServerPassword() != false && $this->maniaControl->settingManager->getSetting($this, self::QUEUE_ACTIVE_ON_PASS) == false) { - return false; - } - - foreach($this->queue as $queuedPlayer) { - if ($queuedPlayer->login == $player->login) { - $this->maniaControl->chat->sendError('You\'re already in the queue!', $player->login); - return false; - } - } - - if ($this->maniaControl->settingManager->getSetting($this, self::QUEUE_MAX) > count($this->queue)) { - $this->queue[count($this->queue)] = $player; - $this->sendChatMessage('$<$fff' . $player->nickname . '$> just joined the queue!'); - } - - $this->showQueueWidgetSpectators(); - - return true; - } - - /** - * Function removes a player from the queue. - * - * @param $login - */ - private function removePlayerFromQueue($login) { - $count = 0; - $newQueue = array(); - foreach($this->queue as $queuePlayer) { - if ($queuePlayer->login != $login) { - $newQueue[$count] = $queuePlayer; - $count++; - } - } - - $this->queue = $newQueue; - $this->showQueueWidgetSpectators(); - } - - /** - * Function sends (or not depending on setting) chatmessages for the queue. - * - * @param $message - */ - private function sendChatMessage($message) { - if ($this->maniaControl->settingManager->getSetting($this, self::QUEUE_CHATMESSAGES)) { - $this->maniaControl->chat->sendChat('$090[Queue] ' . $message); - } - } - - /** - * Function shows the join queue widget to a player. - * - * @param Player $player - */ - private function showJoinQueueWidget(Player $player) { - $maniaLink = new ManiaLink(self::ML_ID); - - $quadStyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowStyle(); - $quadSubstyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowSubStyle(); - $max_queue = $this->maniaControl->settingManager->getSetting($this, self::QUEUE_MAX); - - // Main frame - $frame = new Frame(); - $maniaLink->add($frame); - $frame->setSize(60, 6); - $frame->setPosition($this->maniaControl->settingManager->getSetting($this, self::QUEUE_WIDGET_POS_X), $this->maniaControl->settingManager->getSetting($this, self::QUEUE_WIDGET_POS_Y), 0); - - // Background - $backgroundQuad = new Quad(); - $frame->add($backgroundQuad); - $backgroundQuad->setPosition(0, 0, 0); - $backgroundQuad->setSize(70, 10); - $backgroundQuad->setStyles($quadStyle, $quadSubstyle); - - $cameraQuad = new Quad_Icons64x64_1(); - $frame->add($cameraQuad); - $cameraQuad->setPosition(-29, 0.4, 2); - $cameraQuad->setSize(9, 9); - $cameraQuad->setSubStyle(Quad_Icons64x64_1::SUBSTYLE_Camera); - - $statusLabel = new Label_Text(); - $frame->add($statusLabel); - $statusLabel->setPosition(4.5, 2.8, 1); - $statusLabel->setSize(66, 4); - $statusLabel->setAlign('center', 'center'); - $statusLabel->setScale(0.8); - $statusLabel->setStyle(Label_Text::STYLE_TextStaticSmall); - - $messageLabel = new Label_Button(); - $frame->add($messageLabel); - $messageLabel->setPosition(4.5, -1.6, 1); - $messageLabel->setSize(56, 4); - $messageLabel->setAlign('center', 'center'); - $messageLabel->setScale(1.0); - - $inQueue = false; - foreach($this->queue as $queuedPlayer) { - if ($queuedPlayer->login == $player->login) { - $inQueue = true; - } - } - - if ($inQueue) { - $message = '$fff$sYou\'re in the queue (click to unqueue).'; - - $position = 0; - foreach(array_values($this->queue) as $i => $queuePlayer) { - if ($player->login == $queuePlayer->login) { - $position = ($i + 1); - } - } - - $statusLabel->setText('$aaaStatus: In queue (' . $position . '/' . count($this->queue) . ') Waiting: ' . count($this->queue) . '/' . $max_queue . ''); - $messageLabel->setAction(self::ML_REMOVEFROMQUEUE); - $backgroundQuad->setAction(self::ML_REMOVEFROMQUEUE); - $statusLabel->setAction(self::ML_REMOVEFROMQUEUE); - $cameraQuad->setAction(self::ML_REMOVEFROMQUEUE); - } else { - if (count($this->queue) < $max_queue) { - $message = '$0ff$sClick to join spectator waiting list.'; - $messageLabel->setAction(self::ML_ADDTOQUEUE); - $backgroundQuad->setAction(self::ML_ADDTOQUEUE); - $statusLabel->setAction(self::ML_ADDTOQUEUE); - $cameraQuad->setAction(self::ML_ADDTOQUEUE); - } else { - $message = '$f00The waiting list is full!'; - } - - $statusLabel->setText('$aaaStatus: Not queued spectator Waiting: ' . count($this->queue) . '/' . $max_queue . ''); - } - - $messageLabel->setText($message); - $messageLabel->setStyle(Label_Text::STYLE_TextStaticSmall); - - $this->maniaControl->manialinkManager->sendManialink($maniaLink, $player->login); - } - - /** - * Function shows the "You got a free spot, enjoy playing!" widget. - * - * @param Player $player - */ - private function showPlayWidget(Player $player) { - $maniaLink = new ManiaLink(self::ML_ID); - - $quadStyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowStyle(); - $quadSubstyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowSubStyle(); - - // Main frame - $frame = new Frame(); - $maniaLink->add($frame); - $frame->setSize(60, 6); - $frame->setPosition($this->maniaControl->settingManager->getSetting($this, self::QUEUE_WIDGET_POS_X), $this->maniaControl->settingManager->getSetting($this, self::QUEUE_WIDGET_POS_Y), 0); - - // Background - $backgroundQuad = new Quad(); - $frame->add($backgroundQuad); - $backgroundQuad->setPosition(0, 0, 0); - $backgroundQuad->setSize(70, 10); - $backgroundQuad->setStyles($quadStyle, $quadSubstyle); - - $cameraQuad = new Quad_Icons64x64_1(); - $frame->add($cameraQuad); - $cameraQuad->setPosition(-29, 0.4, 2); - $cameraQuad->setSize(9, 9); - $cameraQuad->setSubStyle(Quad_Icons64x64_1::SUBSTYLE_Camera); - - $messageLabel = new Label_Button(); - $frame->add($messageLabel); - $messageLabel->setPosition(4.5, 0.6, 1); - $messageLabel->setSize(56, 4); - $messageLabel->setAlign('center', 'center'); - $messageLabel->setScale(1.0); - $messageLabel->setText('$090You got a free spot, enjoy playing!'); - $messageLabel->setStyle(Label_Text::STYLE_TextStaticSmall); - - $this->maniaControl->manialinkManager->sendManialink($maniaLink, $player->login); - $this->showPlay[$player->login] = array('time' => time(), 'player' => $player); - } - - /** - * Function hides the queue widget from the player. - * - * @param Player $player - */ - private function hideQueueWidget(Player $player) { - $maniaLink = new ManiaLink(self::ML_ID); - $this->maniaControl->manialinkManager->sendManialink($maniaLink, $player->login); - } -} \ No newline at end of file + \ No newline at end of file diff --git a/application/plugins/TeamSpeakPlugin.php b/application/plugins/TeamSpeakPlugin.php index 8c9db17b..79189305 100644 --- a/application/plugins/TeamSpeakPlugin.php +++ b/application/plugins/TeamSpeakPlugin.php @@ -1,514 +1 @@ -settingManager->initSetting(get_class(), self::TEAMSPEAK_SID, 1); - $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_SERVERHOST, 'ts3.somehoster.com'); - $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_SERVERPORT, 9987); - $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_QUERYHOST, ''); - $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_QUERYPORT, 10011); - $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_QUERYUSER, ''); - $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_QUERYPASS, ''); - } - - /** - * Load the plugin - * - * @param \ManiaControl\ManiaControl $maniaControl - * @return bool - */ - public function load(ManiaControl $maniaControl) { - $this->maniaControl = $maniaControl; - $this->checkConfig(); - - $this->refreshTime = time(); - - $this->maniaControl->manialinkManager->iconManager->addIcon(self::TS_ICON); - $this->maniaControl->manialinkManager->iconManager->addIcon(self::TS_ICON_MOVER); - - $this->maniaControl->timerManager->registerTimerListening($this, 'ts3_queryServer', 1000); - - $this->addToMenu(); - } - - - /** - * Function used to check certain configuration options to check if they can be used. - * - * @throws Exception - */ - private function checkConfig() { - if ($this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERHOST) == 'ts3.somehoster.com') { - $error = 'Missing the required serverhost, please set it up before enabling the TeamSpeak plugin!'; - throw new Exception($error); - } - - $this->ts3_queryServer(); // Get latest information from the TeamSpeak server - if (!isset($this->serverData['channels']) || count($this->serverData['channels']) == 0) { - $error = 'Could not make proper connections with the server!'; - throw new Exception($error); - } - } - - /** - * Function used insert the icon into the menu. - */ - private function addToMenu() { - $this->maniaControl->manialinkManager->registerManialinkPageAnswerListener(self::ACTION_OPEN_TSVIEWER, $this, 'command_tsViewer'); - $itemQuad = new Quad(); - $itemQuad->setImage($this->maniaControl->manialinkManager->iconManager->getIcon(self::TS_ICON)); - $itemQuad->setImageFocus($this->maniaControl->manialinkManager->iconManager->getIcon(self::TS_ICON_MOVER)); - $itemQuad->setAction(self::ACTION_OPEN_TSVIEWER); - $this->maniaControl->actionsMenu->addMenuItem($itemQuad, true, 1, 'Open TeamSpeak Viewer'); - } - - /** - * Unload the plugin and its resources - */ - public function unload() { - $this->serverData = array(); - - $this->maniaControl->actionsMenu->removeMenuItem(1, true); - $this->maniaControl->manialinkManager->unregisterManialinkPageAnswerListener($this); - $this->maniaControl->callbackManager->unregisterCallbackListener($this); - $this->maniaControl->commandManager->unregisterCommandListener($this); - $this->maniaControl->timerManager->unregisterTimerListenings($this); - unset($this->maniaControl); - } - - /** - * Get plugin id - * - * @return int - */ - public static function getId() { - return self::ID; - } - - /** - * Get Plugin Name - * - * @return string - */ - public static function getName() { - return 'TeamSpeak Plugin'; - } - - /** - * Get Plugin Version - * - * @return float - */ - public static function getVersion() { - return self::VERSION; - } - - /** - * Get Plugin Author - * - * @return string - */ - public static function getAuthor() { - return 'TheM'; - } - - /** - * Get Plugin Description - * - * @return string - */ - public static function getDescription() { - return 'Plugin offers a connection with a TeamSpeak server (via widgets).'; - } - - /** - * Function handling the pressing of the icon. - * - * @param array $chatCallback - * @param Player $player - */ - public function command_tsViewer(array $chatCallback, Player $player) { - $this->showWidget($player); - } - - /** - * Function showing the TeamSpeak widget to the player. - * - * @param $player - */ - private function showWidget($player) { - $width = $this->maniaControl->manialinkManager->styleManager->getListWidgetsWidth(); - $height = $this->maniaControl->manialinkManager->styleManager->getListWidgetsHeight(); - $quadStyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowStyle(); - $quadSubstyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowSubStyle(); - - $maniaLink = new ManiaLink(ManialinkManager::MAIN_MLID); - - // Main frame - $frame = new Frame(); - $maniaLink->add($frame); - $frame->setSize($width, $height); - $frame->setPosition(0, 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.483, $height * 0.467, 3); - $closeQuad->setSize(6, 6); - $closeQuad->setSubStyle(Quad_Icons64x64_1::SUBSTYLE_QuitRace); - $closeQuad->setAction(ManialinkManager::ACTION_CLOSEWIDGET); - - $servername = new Label_Text(); - $frame->add($servername); - $servername->setY($height / 2 - 4); - $servername->setX(-70); - $servername->setStyle($servername::STYLE_TextCardMedium); - $servername->setHAlign('left'); - $servername->setTextSize(1); - $servername->setText('$oServername:$o ' . $this->serverData['server']['virtualserver_name']); - $servername->setTextColor('fff'); - - $serverversion = new Label_Text(); - $frame->add($serverversion); - $serverversion->setY($height / 2 - 4); - $serverversion->setX(2); - $serverversion->setStyle($serverversion::STYLE_TextCardMedium); - $serverversion->setHAlign('left'); - $serverversion->setTextSize(1); - $serverversion->setText('$oServerversion:$o ' . $this->serverData['server']['virtualserver_version']); - $serverversion->setTextColor('fff'); - - $clients = new Label_Text(); - $frame->add($clients); - $clients->setY($height / 2 - 7); - $clients->setX(-70); - $clients->setStyle($clients::STYLE_TextCardMedium); - $clients->setHAlign('left'); - $clients->setTextSize(1); - $clients->setText('$oConnected clients:$o ' . $this->serverData['server']['virtualserver_clientsonline'] . '/' . $this->serverData['server']['virtualserver_maxclients']); - $clients->setTextColor('fff'); - - $channels = new Label_Text(); - $frame->add($channels); - $channels->setY($height / 2 - 7); - $channels->setX(2); - $channels->setStyle($channels::STYLE_TextCardMedium); - $channels->setHAlign('left'); - $channels->setTextSize(1); - $nochannels = 0; - foreach($this->serverData['channels'] as $channel) { - if ($channel['channel_maxclients'] == 0 || strpos($channel['channel_name'], 'spacer') > 0) { - continue; - } - $nochannels++; - } - $channels->setText('$oChannels:$o ' . $nochannels); - $channels->setTextColor('fff'); - - // Join button - $joinbutton = new Label_Button(); - $frame->add($joinbutton); - $joinbutton->setWidth(150); - $joinbutton->setY($height / 2 - 11.5); - $joinbutton->setStyle($joinbutton::STYLE_CardButtonSmallWide); - $joinbutton->setText('Join TeamSpeak: ' . $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERHOST) . ':' . $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERPORT)); - $joinbutton->setTextColor('fff'); - $url = 'ts3server://' . $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERHOST) . '/?port=' . $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERPORT) . '&nickname=' . rawurlencode(\ManiaControl\Formatter::stripCodes($player->nickname)); - $joinbutton->setUrl($url); - - $leftlistQuad = new Quad(); - $frame->add($leftlistQuad); - $leftlistQuad->setSize((($width / 2) - 5), ($height - 18)); - $leftlistQuad->setX(-36); - $leftlistQuad->setY($height / 2 - 46); - $leftlistQuad->setStyles($quadStyle, $quadSubstyle); - - $channels = array(); - $users = array(); - $userid = 0; - $i = 0; - $startx = -69.5; - foreach($this->serverData['channels'] as $channel) { - if ($channel['channel_maxclients'] == 0 || strpos($channel['channel_name'], 'spacer') > 0) { - continue; - } - $channelLabel = new Label_Text(); - $frame->add($channelLabel); - $y = 17.5 + ($i * 2.5); - $channelLabel->setY($height / 2 - $y); - $x = $startx; - if ($channel['pid'] != 0) { - $x = $startx + 5; - } - $channelLabel->setX($x); - $channelLabel->setStyle($channelLabel::STYLE_TextCardMedium); - $channelLabel->setHAlign('left'); - $channelLabel->setTextSize(1); - $channelLabel->setScale(0.9); - if ($channel['channel_flag_default'] == 1) { - $channel['total_clients'] = ($channel['total_clients'] - 1); - } // remove query client - $channelLabel->setText('$o' . $channel['channel_name'] . '$o (' . $channel['total_clients'] . ')'); - $channelLabel->setTextColor('fff'); - - $channels[$i] = $channelLabel; - - $i++; - foreach($this->serverData['users'] as $user) { - if ($user['cid'] == $channel['cid']) { - $userLabel = new Label_Text(); - $frame->add($userLabel); - $y = 17.5 + ($i * 2.5); - $userLabel->setY($height / 2 - $y); - if ($channel['pid'] != 0) { - $x = $startx + 7; - } else { - $x = $startx + 2; - } - $userLabel->setX($x); - $userLabel->setStyle($userLabel::STYLE_TextCardMedium); - $userLabel->setHAlign('left'); - $userLabel->setTextSize(1); - $userLabel->setScale(0.9); - $userLabel->setText($user['client_nickname']); - $userLabel->setTextColor('fff'); - $users[$userid] = $userLabel; - - $userid++; - $i++; - - if ($i > 22) { - $i = 0; - $startx = 2.5; - } - } - } - - if ($i > 22) { - $i = 0; - $startx = 2.5; - } - } - - $rightlistQuad = new Quad(); - $frame->add($rightlistQuad); - $rightlistQuad->setSize((($width / 2) - 5), ($height - 18)); - $rightlistQuad->setX(36); - $rightlistQuad->setY($height / 2 - 46); - $rightlistQuad->setStyles($quadStyle, $quadSubstyle); - - $this->maniaControl->manialinkManager->displayWidget($maniaLink, $player, 'TSViewer'); - } - - /** - * TeamSpeak related functions - * The functions are based upon tsstatus.php from http://tsstatus.sebastien.me/ - * and were optimized by SilentStorm. - * Functions originally from the TeamSpeakInfo plugin made by undef.de for XAseco(2) and MPAseco. - */ - - public function ts3_queryServer() { - if (time() >= $this->refreshTime) { - $this->refreshTime = (time() + $this->refreshInterval); - - $queryhost = $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_QUERYHOST); - $host = $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERHOST); - - $host = ($queryhost != '') ? $queryhost : $host; - - $socket = fsockopen(@$host, $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_QUERYPORT), $errno, $errstr, 2); - if ($socket) { - socket_set_timeout($socket, 2); - $is_ts3 = trim(fgets($socket)) == 'TS3'; - if (!$is_ts3) { - trigger_error('[TeamSpeakPlugin] Server at "' . $host . '" is not a Teamspeak3-Server or you have setup a bad query-port!', E_USER_WARNING); - } - - $queryuser = $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_QUERYUSER); - $querypass = $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_QUERYPASS); - if (($queryuser != '') && !is_numeric($queryuser) && $queryuser != false && ($querypass != '') && !is_numeric($querypass) && $querypass != false) { - $ret = $this->ts3_sendCommand($socket, 'login client_login_name=' . $this->ts3_escape($queryuser) . ' client_login_password=' . $this->ts3_escape($querypass)); - if (stripos($ret, "error id=0") === false) { - trigger_error("[TeamSpeakPlugin] Failed to authenticate with TS3 Server! Make sure you put the correct username & password in teamspeak.xml", E_USER_WARNING); - return; - } - } - - $response = ''; - $response .= $this->ts3_sendCommand($socket, 'use sid=' . $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SID)); - $this->ts3_sendCommand($socket, 'clientupdate client_nickname=' . $this->ts3_escape('ManiaControl Viewer')); - $response .= $this->ts3_sendCommand($socket, 'serverinfo'); - $response .= $this->ts3_sendCommand($socket, 'channellist -topic -flags -voice -limits'); - $response .= $this->ts3_sendCommand($socket, 'clientlist -uid -away -voice -groups'); - - fputs($socket, "quit\n"); - fclose($socket); - - $lines = explode("error id=0 msg=ok\n\r", $response); - if (count($lines) == 5) { - $serverdata = $this->ts3_parseLine($lines[1]); - $this->serverData['server'] = $serverdata[0]; - $this->serverData['channels'] = $this->ts3_parseLine($lines[2]); - - $users = $this->ts3_parseLine($lines[3]); - $this->serverData['users'] = array(); // reset userslist - foreach($users as $user) { - if ($user['client_nickname'] != 'ManiaControl Viewer') { - $this->serverData['users'][] = $user; - } - } - - // Subtract reserved slots - $this->serverData['server']['virtualserver_maxclients'] -= $this->serverData['server']['virtualserver_reserved_slots']; - - // Make ping value int - $this->serverData['server']['virtualserver_total_ping'] = intval($this->serverData['server']['virtualserver_total_ping']); - - // Format the Date of server startup - $this->serverData['server']['virtualserver_uptime'] = date('Y-m-d H:i:s', (time() - $this->serverData['server']['virtualserver_uptime'])); - - // Always subtract all Query Clients - $this->serverData['server']['virtualserver_clientsonline'] -= $this->serverData['server']['virtualserver_queryclientsonline']; - } - } else { - trigger_error("[TeamSpeakPlugin] Failed to connect with TS3 server; socket error: " . $errstr . " [" . $errno . "]", E_USER_WARNING); - } - } - } - - /** - * TS Function to send a command to the TeamSpeak server. - * - * @param $socket - * @param $cmd - * @return string - */ - private function ts3_sendCommand($socket, $cmd) { - - fputs($socket, "$cmd\n"); - - $response = ''; - /*while(strpos($response, 'error id=') === false) { - $response .= fread($socket, 8096); - }*/ - - /*while (!feof($socket)) { - $response .= fread($socket, 8192); - }*/ - - $info = array('timed_out' => false); - while(!feof($socket) && !$info['timed_out'] && strpos($response, 'error id=') === false) { - $response .= fread($socket, 1024); - $info = stream_get_meta_data($socket); - } - - return $response; - } - - /** - * TS Function used to parse lines in the serverresponse. - * - * @param $rawLine - * @return array - */ - private function ts3_parseLine($rawLine) { - - $datas = array(); - $rawItems = explode('|', $rawLine); - - foreach($rawItems as &$rawItem) { - $rawDatas = explode(' ', $rawItem); - $tempDatas = array(); - foreach($rawDatas as &$rawData) { - $ar = explode("=", $rawData, 2); - $tempDatas[$ar[0]] = isset($ar[1]) ? $this->ts3_unescape($ar[1]) : ''; - } - $datas[] = $tempDatas; - } - unset($rawItem, $rawData); - - return $datas; - } - - /** - * TS Function used to escape characters in channelnames. - * - * @param $str - * @return mixed - */ - private function ts3_escape($str) { - return str_replace(array(chr(92), chr(47), chr(32), chr(124), chr(7), chr(8), chr(12), chr(10), chr(3), chr(9), chr(11)), array('\\\\', "\/", "\s", "\p", "\a", "\b", "\f", "\n", "\r", "\t", "\v"), $str); - } - - /** - * TS Function used to unescape characters in channelnames. - * - * @param $str - * @return mixed - */ - private function ts3_unescape($str) { - return str_replace(array('\\\\', "\/", "\s", "\p", "\a", "\b", "\f", "\n", "\r", "\t", "\v"), array(chr(92), chr(47), chr(32), chr(124), chr(7), chr(8), chr(12), chr(10), chr(3), chr(9), chr(11)), $str); - } - -} \ No newline at end of file + \ No newline at end of file diff --git a/application/plugins/TheM/QueuePlugin.php b/application/plugins/TheM/QueuePlugin.php new file mode 100644 index 00000000..7d25e310 --- /dev/null +++ b/application/plugins/TheM/QueuePlugin.php @@ -0,0 +1,572 @@ +maniaControl = $maniaControl; + + $this->maniaControl->timerManager->registerTimerListening($this, 'handleEverySecond', 1000); + $this->maniaControl->callbackManager->registerCallbackListener(PlayerManager::CB_PLAYERCONNECT, $this, 'handlePlayerConnect'); + $this->maniaControl->callbackManager->registerCallbackListener(PlayerManager::CB_PLAYERDISCONNECT, $this, 'handlePlayerDisconnect'); + $this->maniaControl->callbackManager->registerCallbackListener(CallbackManager::CB_MP_PLAYERINFOCHANGED, $this, 'handlePlayerInfoChanged'); + $this->maniaControl->callbackManager->registerCallbackListener(Callbacks::BEGINMAP, $this, 'handleBeginMap'); + $this->maniaControl->manialinkManager->registerManialinkPageAnswerListener(self::ML_ADDTOQUEUE, $this, 'handleManiaLinkAnswerAdd'); + $this->maniaControl->manialinkManager->registerManialinkPageAnswerListener(self::ML_REMOVEFROMQUEUE, $this, 'handleManiaLinkAnswerRemove'); + + $this->maniaControl->settingManager->initSetting($this, self::QUEUE_MAX, 8); + $this->maniaControl->settingManager->initSetting($this, self::QUEUE_WIDGET_POS_X, 0); + $this->maniaControl->settingManager->initSetting($this, self::QUEUE_WIDGET_POS_Y, -46); + $this->maniaControl->settingManager->initSetting($this, self::QUEUE_ACTIVE_ON_PASS, false); + $this->maniaControl->settingManager->initSetting($this, self::QUEUE_CHATMESSAGES, true); + + $maxPlayers = $this->maniaControl->client->getMaxPlayers(); + $this->maxPlayers = $maxPlayers['CurrentValue']; + + foreach($this->maniaControl->playerManager->getPlayers() as $player) { + if ($player->isSpectator) { + $this->spectators[$player->login] = $player->login; + $this->maniaControl->client->forceSpectator($player->login, 1); + $this->showJoinQueueWidget($player); + } + } + } + + /** + * Unload the plugin and its resources + */ + public function unload() { + $this->maniaControl->manialinkManager->unregisterManialinkPageAnswerListener($this); + $this->maniaControl->callbackManager->unregisterCallbackListener($this); + $this->maniaControl->timerManager->unregisterTimerListenings($this); + + foreach($this->spectators as $spectator) { + $this->maniaControl->client->forceSpectator($spectator, 3); + $this->maniaControl->client->forceSpectator($spectator, 0); + } + + foreach($this->maniaControl->playerManager->getPlayers() as $player) { + $this->hideQueueWidget($player); + } + + $this->queue = array(); + $this->spectators = array(); + $this->showPlay = array(); + unset($this->maniaControl); + } + + /** + * Get plugin id + * + * @return int + */ + public static function getId() { + return self::ID; + } + + /** + * Get Plugin Name + * + * @return string + */ + public static function getName() { + return 'Queue Plugin'; + } + + /** + * Get Plugin Version + * + * @return float + */ + public static function getVersion() { + return self::VERSION; + } + + /** + * Get Plugin Author + * + * @return string + */ + public static function getAuthor() { + return 'TheM'; + } + + /** + * Get Plugin Description + * + * @return string + */ + public static function getDescription() { + return 'Plugin offers the known AutoQueue/SpecJam options.'; + } + + /** + * Function handling on the connection of a player. + * + * @param Player $player + */ + public function handlePlayerConnect(Player $player) { + $maxPlayers = $this->maniaControl->client->getMaxPlayers(); + $this->maxPlayers = $maxPlayers['CurrentValue']; + + if ($player->isSpectator) { + $this->spectators[$player->login] = $player->login; + $this->maniaControl->client->forceSpectator($player->login, 1); + $this->showJoinQueueWidget($player); + } else { + if (count($this->queue) != 0) { + $this->maniaControl->client->forceSpectator($player->login, 1); + $this->spectators[$player->login] = $player->login; + $this->showJoinQueueWidget($player); + } + } + } + + /** + * Function handling on the disconnection of a player. + * + * @param Player $player + */ + public function handlePlayerDisconnect(Player $player) { + $maxPlayers = $this->maniaControl->client->getMaxPlayers(); + $this->maxPlayers = $maxPlayers['CurrentValue']; + + if (isset($this->spectators[$player->login])) { + unset($this->spectators[$player->login]); + } + $this->removePlayerFromQueue($player->login); + $this->moveFirstPlayerToPlay(); + } + + /** + * Function handling the change of player information. + * + * @param array $callback + */ + public function handlePlayerInfoChanged(array $callback) { + $login = $callback[1][0]['Login']; + $player = $this->maniaControl->playerManager->getPlayer($login); + + if (!is_null($player)) { + if ($player->isSpectator) { + if (!isset($this->spectators[$player->login])) { + $this->maniaControl->client->forceSpectator($player->login, 1); + $this->spectators[$player->login] = $player->login; + $this->showJoinQueueWidget($player); + $this->showQueueWidgetSpectators(); + } + } else { + $this->removePlayerFromQueue($player->login); + if (isset($this->spectators[$player->login])) { + unset($this->spectators[$player->login]); + } + + $found = false; + foreach($this->showPlay as $showPlay) { + if ($showPlay['player']->login == $player->login) { + $found = true; + } + } + + if (!$found) { + $this->hideQueueWidget($player); + } + } + } + } + + public function showQueueWidgetSpectators() { + foreach($this->spectators as $login) { + $player = $this->maniaControl->playerManager->getPlayer($login); + $this->showJoinQueueWidget($player); + } + } + + /** + * Function called on every second. + */ + public function handleEverySecond() { + if ($this->maxPlayers > (count($this->maniaControl->playerManager->players) - count($this->spectators))) { + $this->moveFirstPlayerToPlay(); + $this->showQueueWidgetSpectators(); + } + + foreach($this->showPlay as $showPlay) { + if (($showPlay['time'] + 5) < time()) { + $this->hideQueueWidget($showPlay['player']); + unset($this->showPlay[$showPlay['player']->login]); + } + } + } + + /** + * Checks for being of new map to retrieve maximum number of players. + * + * @param $currentMap + */ + public function handleBeginMap($currentMap) { + $maxPlayers = $this->maniaControl->client->getMaxPlayers(); + $this->maxPlayers = $maxPlayers['CurrentValue']; + } + + /** + * Function handling the click of the widget to add them to the queue. + * + * @param array $chatCallback + * @param Player $player + */ + public function handleManiaLinkAnswerAdd(array $chatCallback, Player $player) { + $this->addPlayerToQueue($player); + } + + /** + * Function handling the click of the widget to remove them from the queue. + * + * @param array $chatCallback + * @param Player $player + */ + public function handleManiaLinkAnswerRemove(array $chatCallback, Player $player) { + $this->removePlayerFromQueue($player->login); + $this->showJoinQueueWidget($player); + $this->sendChatMessage('$<$fff' . $player->nickname . '$> has left the queue!'); + } + + /** + * Function used to move the first queued player to the + */ + private function moveFirstPlayerToPlay() { + if (count($this->queue) > 0) { + $firstPlayer = $this->maniaControl->playerManager->getPlayer($this->queue[0]->login); + $this->forcePlayerToPlay($firstPlayer); + $this->showQueueWidgetSpectators(); + } + } + + /** + * Function to force a player to play status. + * + * @param Player $player + */ + private function forcePlayerToPlay(Player $player) { + if ($this->maniaControl->client->getServerPassword() != false && $this->maniaControl->settingManager->getSetting($this, self::QUEUE_ACTIVE_ON_PASS) == false) { + return; + } + + if ($this->maxPlayers > (count($this->maniaControl->playerManager->players) - count($this->spectators))) { + try { + $this->maniaControl->client->forceSpectator($player->login, 2); + } catch(Exception $e) { + // TODO: only possible valid exception should be "wrong login" - throw others (like connection error) + $this->maniaControl->chat->sendError("Error while leaving the Queue", $player->login); + return; + } + + try { + $this->maniaControl->client->forceSpectator($player->login, 0); + } catch(Exception $e) { + // TODO: only possible valid exception should be "wrong login" - throw others (like connection error) + } + + $teams = array(); + /** @var Player $playerObj */ + foreach($this->maniaControl->playerManager->players as $playerObj) { + if (!isset($teams[$playerObj->teamId])) { + $teams[$playerObj->teamId] = 1; + } else { + $teams[$playerObj->teamId]++; + } + } + + $smallestTeam = null; + $smallestSize = 999; + foreach($teams as $team => $size) { + if ($size < $smallestSize) { + $smallestTeam = $team; + $smallestSize = $size; + } + } + + try { + if ($smallestTeam != -1) { + $this->maniaControl->client->forcePlayerTeam($player->login, $smallestTeam); + } + } catch(Exception $e) { + // TODO: only possible valid exceptions should be "wrong login" or "not in team mode" - throw others (like connection error) + } + + if (isset($this->spectators[$player->login])) { + unset($this->spectators[$player->login]); + } + $this->removePlayerFromQueue($player->login); + $this->showPlayWidget($player); + $this->sendChatMessage('$<$fff' . $player->nickname . '$> has a free spot and is now playing!'); + } + + } + + /** + * Function adds a player to the queue. + * + * @param Player $player + * @return bool + */ + private function addPlayerToQueue(Player $player) { + if ($this->maniaControl->client->getServerPassword() != false && $this->maniaControl->settingManager->getSetting($this, self::QUEUE_ACTIVE_ON_PASS) == false) { + return false; + } + + foreach($this->queue as $queuedPlayer) { + if ($queuedPlayer->login == $player->login) { + $this->maniaControl->chat->sendError('You\'re already in the queue!', $player->login); + return false; + } + } + + if ($this->maniaControl->settingManager->getSetting($this, self::QUEUE_MAX) > count($this->queue)) { + $this->queue[count($this->queue)] = $player; + $this->sendChatMessage('$<$fff' . $player->nickname . '$> just joined the queue!'); + } + + $this->showQueueWidgetSpectators(); + + return true; + } + + /** + * Function removes a player from the queue. + * + * @param $login + */ + private function removePlayerFromQueue($login) { + $count = 0; + $newQueue = array(); + foreach($this->queue as $queuePlayer) { + if ($queuePlayer->login != $login) { + $newQueue[$count] = $queuePlayer; + $count++; + } + } + + $this->queue = $newQueue; + $this->showQueueWidgetSpectators(); + } + + /** + * Function sends (or not depending on setting) chatmessages for the queue. + * + * @param $message + */ + private function sendChatMessage($message) { + if ($this->maniaControl->settingManager->getSetting($this, self::QUEUE_CHATMESSAGES)) { + $this->maniaControl->chat->sendChat('$090[Queue] ' . $message); + } + } + + /** + * Function shows the join queue widget to a player. + * + * @param Player $player + */ + private function showJoinQueueWidget(Player $player) { + $maniaLink = new ManiaLink(self::ML_ID); + + $quadStyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowStyle(); + $quadSubstyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowSubStyle(); + $max_queue = $this->maniaControl->settingManager->getSetting($this, self::QUEUE_MAX); + + // Main frame + $frame = new Frame(); + $maniaLink->add($frame); + $frame->setSize(60, 6); + $frame->setPosition($this->maniaControl->settingManager->getSetting($this, self::QUEUE_WIDGET_POS_X), $this->maniaControl->settingManager->getSetting($this, self::QUEUE_WIDGET_POS_Y), 0); + + // Background + $backgroundQuad = new Quad(); + $frame->add($backgroundQuad); + $backgroundQuad->setPosition(0, 0, 0); + $backgroundQuad->setSize(70, 10); + $backgroundQuad->setStyles($quadStyle, $quadSubstyle); + + $cameraQuad = new Quad_Icons64x64_1(); + $frame->add($cameraQuad); + $cameraQuad->setPosition(-29, 0.4, 2); + $cameraQuad->setSize(9, 9); + $cameraQuad->setSubStyle(Quad_Icons64x64_1::SUBSTYLE_Camera); + + $statusLabel = new Label_Text(); + $frame->add($statusLabel); + $statusLabel->setPosition(4.5, 2.8, 1); + $statusLabel->setSize(66, 4); + $statusLabel->setAlign('center', 'center'); + $statusLabel->setScale(0.8); + $statusLabel->setStyle(Label_Text::STYLE_TextStaticSmall); + + $messageLabel = new Label_Button(); + $frame->add($messageLabel); + $messageLabel->setPosition(4.5, -1.6, 1); + $messageLabel->setSize(56, 4); + $messageLabel->setAlign('center', 'center'); + $messageLabel->setScale(1.0); + + $inQueue = false; + foreach($this->queue as $queuedPlayer) { + if ($queuedPlayer->login == $player->login) { + $inQueue = true; + } + } + + if ($inQueue) { + $message = '$fff$sYou\'re in the queue (click to unqueue).'; + + $position = 0; + foreach(array_values($this->queue) as $i => $queuePlayer) { + if ($player->login == $queuePlayer->login) { + $position = ($i + 1); + } + } + + $statusLabel->setText('$aaaStatus: In queue (' . $position . '/' . count($this->queue) . ') Waiting: ' . count($this->queue) . '/' . $max_queue . ''); + $messageLabel->setAction(self::ML_REMOVEFROMQUEUE); + $backgroundQuad->setAction(self::ML_REMOVEFROMQUEUE); + $statusLabel->setAction(self::ML_REMOVEFROMQUEUE); + $cameraQuad->setAction(self::ML_REMOVEFROMQUEUE); + } else { + if (count($this->queue) < $max_queue) { + $message = '$0ff$sClick to join spectator waiting list.'; + $messageLabel->setAction(self::ML_ADDTOQUEUE); + $backgroundQuad->setAction(self::ML_ADDTOQUEUE); + $statusLabel->setAction(self::ML_ADDTOQUEUE); + $cameraQuad->setAction(self::ML_ADDTOQUEUE); + } else { + $message = '$f00The waiting list is full!'; + } + + $statusLabel->setText('$aaaStatus: Not queued spectator Waiting: ' . count($this->queue) . '/' . $max_queue . ''); + } + + $messageLabel->setText($message); + $messageLabel->setStyle(Label_Text::STYLE_TextStaticSmall); + + $this->maniaControl->manialinkManager->sendManialink($maniaLink, $player->login); + } + + /** + * Function shows the "You got a free spot, enjoy playing!" widget. + * + * @param Player $player + */ + private function showPlayWidget(Player $player) { + $maniaLink = new ManiaLink(self::ML_ID); + + $quadStyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowStyle(); + $quadSubstyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowSubStyle(); + + // Main frame + $frame = new Frame(); + $maniaLink->add($frame); + $frame->setSize(60, 6); + $frame->setPosition($this->maniaControl->settingManager->getSetting($this, self::QUEUE_WIDGET_POS_X), $this->maniaControl->settingManager->getSetting($this, self::QUEUE_WIDGET_POS_Y), 0); + + // Background + $backgroundQuad = new Quad(); + $frame->add($backgroundQuad); + $backgroundQuad->setPosition(0, 0, 0); + $backgroundQuad->setSize(70, 10); + $backgroundQuad->setStyles($quadStyle, $quadSubstyle); + + $cameraQuad = new Quad_Icons64x64_1(); + $frame->add($cameraQuad); + $cameraQuad->setPosition(-29, 0.4, 2); + $cameraQuad->setSize(9, 9); + $cameraQuad->setSubStyle(Quad_Icons64x64_1::SUBSTYLE_Camera); + + $messageLabel = new Label_Button(); + $frame->add($messageLabel); + $messageLabel->setPosition(4.5, 0.6, 1); + $messageLabel->setSize(56, 4); + $messageLabel->setAlign('center', 'center'); + $messageLabel->setScale(1.0); + $messageLabel->setText('$090You got a free spot, enjoy playing!'); + $messageLabel->setStyle(Label_Text::STYLE_TextStaticSmall); + + $this->maniaControl->manialinkManager->sendManialink($maniaLink, $player->login); + $this->showPlay[$player->login] = array('time' => time(), 'player' => $player); + } + + /** + * Function hides the queue widget from the player. + * + * @param Player $player + */ + private function hideQueueWidget(Player $player) { + $maniaLink = new ManiaLink(self::ML_ID); + $this->maniaControl->manialinkManager->sendManialink($maniaLink, $player->login); + } +} \ No newline at end of file diff --git a/application/plugins/TheM/TeamSpeakPlugin.php b/application/plugins/TheM/TeamSpeakPlugin.php new file mode 100644 index 00000000..7a8dcca6 --- /dev/null +++ b/application/plugins/TheM/TeamSpeakPlugin.php @@ -0,0 +1,516 @@ +settingManager->initSetting(get_class(), self::TEAMSPEAK_SID, 1); + $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_SERVERHOST, 'ts3.somehoster.com'); + $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_SERVERPORT, 9987); + $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_QUERYHOST, ''); + $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_QUERYPORT, 10011); + $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_QUERYUSER, ''); + $maniaControl->settingManager->initSetting(get_class(), self::TEAMSPEAK_QUERYPASS, ''); + } + + /** + * Load the plugin + * + * @param \ManiaControl\ManiaControl $maniaControl + * @return bool + */ + public function load(ManiaControl $maniaControl) { + $this->maniaControl = $maniaControl; + $this->checkConfig(); + + $this->refreshTime = time(); + + $this->maniaControl->manialinkManager->iconManager->addIcon(self::TS_ICON); + $this->maniaControl->manialinkManager->iconManager->addIcon(self::TS_ICON_MOVER); + + $this->maniaControl->timerManager->registerTimerListening($this, 'ts3_queryServer', 1000); + + $this->addToMenu(); + } + + + /** + * Function used to check certain configuration options to check if they can be used. + * + * @throws \Exception + */ + private function checkConfig() { + if ($this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERHOST) == 'ts3.somehoster.com') { + $error = 'Missing the required serverhost, please set it up before enabling the TeamSpeak plugin!'; + throw new \Exception($error); + } + + $this->ts3_queryServer(); // Get latest information from the TeamSpeak server + if (!isset($this->serverData['channels']) || count($this->serverData['channels']) == 0) { + $error = 'Could not make proper connections with the server!'; + throw new \Exception($error); + } + } + + /** + * Function used insert the icon into the menu. + */ + private function addToMenu() { + $this->maniaControl->manialinkManager->registerManialinkPageAnswerListener(self::ACTION_OPEN_TSVIEWER, $this, 'command_tsViewer'); + $itemQuad = new Quad(); + $itemQuad->setImage($this->maniaControl->manialinkManager->iconManager->getIcon(self::TS_ICON)); + $itemQuad->setImageFocus($this->maniaControl->manialinkManager->iconManager->getIcon(self::TS_ICON_MOVER)); + $itemQuad->setAction(self::ACTION_OPEN_TSVIEWER); + $this->maniaControl->actionsMenu->addMenuItem($itemQuad, true, 1, 'Open TeamSpeak Viewer'); + } + + /** + * Unload the plugin and its resources + */ + public function unload() { + $this->serverData = array(); + + $this->maniaControl->actionsMenu->removeMenuItem(1, true); + $this->maniaControl->manialinkManager->unregisterManialinkPageAnswerListener($this); + $this->maniaControl->callbackManager->unregisterCallbackListener($this); + $this->maniaControl->commandManager->unregisterCommandListener($this); + $this->maniaControl->timerManager->unregisterTimerListenings($this); + unset($this->maniaControl); + } + + /** + * Get plugin id + * + * @return int + */ + public static function getId() { + return self::ID; + } + + /** + * Get Plugin Name + * + * @return string + */ + public static function getName() { + return 'TeamSpeak Plugin'; + } + + /** + * Get Plugin Version + * + * @return float + */ + public static function getVersion() { + return self::VERSION; + } + + /** + * Get Plugin Author + * + * @return string + */ + public static function getAuthor() { + return 'TheM'; + } + + /** + * Get Plugin Description + * + * @return string + */ + public static function getDescription() { + return 'Plugin offers a connection with a TeamSpeak server (via widgets).'; + } + + /** + * Function handling the pressing of the icon. + * + * @param array $chatCallback + * @param Player $player + */ + public function command_tsViewer(array $chatCallback, Player $player) { + $this->showWidget($player); + } + + /** + * Function showing the TeamSpeak widget to the player. + * + * @param $player + */ + private function showWidget($player) { + $width = $this->maniaControl->manialinkManager->styleManager->getListWidgetsWidth(); + $height = $this->maniaControl->manialinkManager->styleManager->getListWidgetsHeight(); + $quadStyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowStyle(); + $quadSubstyle = $this->maniaControl->manialinkManager->styleManager->getDefaultMainWindowSubStyle(); + + $maniaLink = new ManiaLink(ManialinkManager::MAIN_MLID); + + // Main frame + $frame = new Frame(); + $maniaLink->add($frame); + $frame->setSize($width, $height); + $frame->setPosition(0, 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.483, $height * 0.467, 3); + $closeQuad->setSize(6, 6); + $closeQuad->setSubStyle(Quad_Icons64x64_1::SUBSTYLE_QuitRace); + $closeQuad->setAction(ManialinkManager::ACTION_CLOSEWIDGET); + + $servername = new Label_Text(); + $frame->add($servername); + $servername->setY($height / 2 - 4); + $servername->setX(-70); + $servername->setStyle($servername::STYLE_TextCardMedium); + $servername->setHAlign('left'); + $servername->setTextSize(1); + $servername->setText('$oServername:$o ' . $this->serverData['server']['virtualserver_name']); + $servername->setTextColor('fff'); + + $serverversion = new Label_Text(); + $frame->add($serverversion); + $serverversion->setY($height / 2 - 4); + $serverversion->setX(2); + $serverversion->setStyle($serverversion::STYLE_TextCardMedium); + $serverversion->setHAlign('left'); + $serverversion->setTextSize(1); + $serverversion->setText('$oServerversion:$o ' . $this->serverData['server']['virtualserver_version']); + $serverversion->setTextColor('fff'); + + $clients = new Label_Text(); + $frame->add($clients); + $clients->setY($height / 2 - 7); + $clients->setX(-70); + $clients->setStyle($clients::STYLE_TextCardMedium); + $clients->setHAlign('left'); + $clients->setTextSize(1); + $clients->setText('$oConnected clients:$o ' . $this->serverData['server']['virtualserver_clientsonline'] . '/' . $this->serverData['server']['virtualserver_maxclients']); + $clients->setTextColor('fff'); + + $channels = new Label_Text(); + $frame->add($channels); + $channels->setY($height / 2 - 7); + $channels->setX(2); + $channels->setStyle($channels::STYLE_TextCardMedium); + $channels->setHAlign('left'); + $channels->setTextSize(1); + $nochannels = 0; + foreach($this->serverData['channels'] as $channel) { + if ($channel['channel_maxclients'] == 0 || strpos($channel['channel_name'], 'spacer') > 0) { + continue; + } + $nochannels++; + } + $channels->setText('$oChannels:$o ' . $nochannels); + $channels->setTextColor('fff'); + + // Join button + $joinbutton = new Label_Button(); + $frame->add($joinbutton); + $joinbutton->setWidth(150); + $joinbutton->setY($height / 2 - 11.5); + $joinbutton->setStyle($joinbutton::STYLE_CardButtonSmallWide); + $joinbutton->setText('Join TeamSpeak: ' . $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERHOST) . ':' . $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERPORT)); + $joinbutton->setTextColor('fff'); + $url = 'ts3server://' . $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERHOST) . '/?port=' . $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERPORT) . '&nickname=' . rawurlencode(\ManiaControl\Formatter::stripCodes($player->nickname)); + $joinbutton->setUrl($url); + + $leftlistQuad = new Quad(); + $frame->add($leftlistQuad); + $leftlistQuad->setSize((($width / 2) - 5), ($height - 18)); + $leftlistQuad->setX(-36); + $leftlistQuad->setY($height / 2 - 46); + $leftlistQuad->setStyles($quadStyle, $quadSubstyle); + + $channels = array(); + $users = array(); + $userid = 0; + $i = 0; + $startx = -69.5; + foreach($this->serverData['channels'] as $channel) { + if ($channel['channel_maxclients'] == 0 || strpos($channel['channel_name'], 'spacer') > 0) { + continue; + } + $channelLabel = new Label_Text(); + $frame->add($channelLabel); + $y = 17.5 + ($i * 2.5); + $channelLabel->setY($height / 2 - $y); + $x = $startx; + if ($channel['pid'] != 0) { + $x = $startx + 5; + } + $channelLabel->setX($x); + $channelLabel->setStyle($channelLabel::STYLE_TextCardMedium); + $channelLabel->setHAlign('left'); + $channelLabel->setTextSize(1); + $channelLabel->setScale(0.9); + if ($channel['channel_flag_default'] == 1) { + $channel['total_clients'] = ($channel['total_clients'] - 1); + } // remove query client + $channelLabel->setText('$o' . $channel['channel_name'] . '$o (' . $channel['total_clients'] . ')'); + $channelLabel->setTextColor('fff'); + + $channels[$i] = $channelLabel; + + $i++; + foreach($this->serverData['users'] as $user) { + if ($user['cid'] == $channel['cid']) { + $userLabel = new Label_Text(); + $frame->add($userLabel); + $y = 17.5 + ($i * 2.5); + $userLabel->setY($height / 2 - $y); + if ($channel['pid'] != 0) { + $x = $startx + 7; + } else { + $x = $startx + 2; + } + $userLabel->setX($x); + $userLabel->setStyle($userLabel::STYLE_TextCardMedium); + $userLabel->setHAlign('left'); + $userLabel->setTextSize(1); + $userLabel->setScale(0.9); + $userLabel->setText($user['client_nickname']); + $userLabel->setTextColor('fff'); + $users[$userid] = $userLabel; + + $userid++; + $i++; + + if ($i > 22) { + $i = 0; + $startx = 2.5; + } + } + } + + if ($i > 22) { + $i = 0; + $startx = 2.5; + } + } + + $rightlistQuad = new Quad(); + $frame->add($rightlistQuad); + $rightlistQuad->setSize((($width / 2) - 5), ($height - 18)); + $rightlistQuad->setX(36); + $rightlistQuad->setY($height / 2 - 46); + $rightlistQuad->setStyles($quadStyle, $quadSubstyle); + + $this->maniaControl->manialinkManager->displayWidget($maniaLink, $player, 'TSViewer'); + } + + /** + * TeamSpeak related functions + * The functions are based upon tsstatus.php from http://tsstatus.sebastien.me/ + * and were optimized by SilentStorm. + * Functions originally from the TeamSpeakInfo plugin made by undef.de for XAseco(2) and MPAseco. + */ + + public function ts3_queryServer() { + if (time() >= $this->refreshTime) { + $this->refreshTime = (time() + $this->refreshInterval); + + $queryhost = $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_QUERYHOST); + $host = $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SERVERHOST); + + $host = ($queryhost != '') ? $queryhost : $host; + + $socket = fsockopen(@$host, $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_QUERYPORT), $errno, $errstr, 2); + if ($socket) { + socket_set_timeout($socket, 2); + $is_ts3 = trim(fgets($socket)) == 'TS3'; + if (!$is_ts3) { + trigger_error('[TeamSpeakPlugin] Server at "' . $host . '" is not a Teamspeak3-Server or you have setup a bad query-port!', E_USER_WARNING); + } + + $queryuser = $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_QUERYUSER); + $querypass = $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_QUERYPASS); + if (($queryuser != '') && !is_numeric($queryuser) && $queryuser != false && ($querypass != '') && !is_numeric($querypass) && $querypass != false) { + $ret = $this->ts3_sendCommand($socket, 'login client_login_name=' . $this->ts3_escape($queryuser) . ' client_login_password=' . $this->ts3_escape($querypass)); + if (stripos($ret, "error id=0") === false) { + trigger_error("[TeamSpeakPlugin] Failed to authenticate with TS3 Server! Make sure you put the correct username & password in teamspeak.xml", E_USER_WARNING); + return; + } + } + + $response = ''; + $response .= $this->ts3_sendCommand($socket, 'use sid=' . $this->maniaControl->settingManager->getSetting($this, self::TEAMSPEAK_SID)); + $this->ts3_sendCommand($socket, 'clientupdate client_nickname=' . $this->ts3_escape('ManiaControl Viewer')); + $response .= $this->ts3_sendCommand($socket, 'serverinfo'); + $response .= $this->ts3_sendCommand($socket, 'channellist -topic -flags -voice -limits'); + $response .= $this->ts3_sendCommand($socket, 'clientlist -uid -away -voice -groups'); + + fputs($socket, "quit\n"); + fclose($socket); + + $lines = explode("error id=0 msg=ok\n\r", $response); + if (count($lines) == 5) { + $serverdata = $this->ts3_parseLine($lines[1]); + $this->serverData['server'] = $serverdata[0]; + $this->serverData['channels'] = $this->ts3_parseLine($lines[2]); + + $users = $this->ts3_parseLine($lines[3]); + $this->serverData['users'] = array(); // reset userslist + foreach($users as $user) { + if ($user['client_nickname'] != 'ManiaControl Viewer') { + $this->serverData['users'][] = $user; + } + } + + // Subtract reserved slots + $this->serverData['server']['virtualserver_maxclients'] -= $this->serverData['server']['virtualserver_reserved_slots']; + + // Make ping value int + $this->serverData['server']['virtualserver_total_ping'] = intval($this->serverData['server']['virtualserver_total_ping']); + + // Format the Date of server startup + $this->serverData['server']['virtualserver_uptime'] = date('Y-m-d H:i:s', (time() - $this->serverData['server']['virtualserver_uptime'])); + + // Always subtract all Query Clients + $this->serverData['server']['virtualserver_clientsonline'] -= $this->serverData['server']['virtualserver_queryclientsonline']; + } + } else { + trigger_error("[TeamSpeakPlugin] Failed to connect with TS3 server; socket error: " . $errstr . " [" . $errno . "]", E_USER_WARNING); + } + } + } + + /** + * TS Function to send a command to the TeamSpeak server. + * + * @param $socket + * @param $cmd + * @return string + */ + private function ts3_sendCommand($socket, $cmd) { + + fputs($socket, "$cmd\n"); + + $response = ''; + /*while(strpos($response, 'error id=') === false) { + $response .= fread($socket, 8096); + }*/ + + /*while (!feof($socket)) { + $response .= fread($socket, 8192); + }*/ + + $info = array('timed_out' => false); + while(!feof($socket) && !$info['timed_out'] && strpos($response, 'error id=') === false) { + $response .= fread($socket, 1024); + $info = stream_get_meta_data($socket); + } + + return $response; + } + + /** + * TS Function used to parse lines in the serverresponse. + * + * @param $rawLine + * @return array + */ + private function ts3_parseLine($rawLine) { + + $datas = array(); + $rawItems = explode('|', $rawLine); + + foreach($rawItems as &$rawItem) { + $rawDatas = explode(' ', $rawItem); + $tempDatas = array(); + foreach($rawDatas as &$rawData) { + $ar = explode("=", $rawData, 2); + $tempDatas[$ar[0]] = isset($ar[1]) ? $this->ts3_unescape($ar[1]) : ''; + } + $datas[] = $tempDatas; + } + unset($rawItem, $rawData); + + return $datas; + } + + /** + * TS Function used to escape characters in channelnames. + * + * @param $str + * @return mixed + */ + private function ts3_escape($str) { + return str_replace(array(chr(92), chr(47), chr(32), chr(124), chr(7), chr(8), chr(12), chr(10), chr(3), chr(9), chr(11)), array('\\\\', "\/", "\s", "\p", "\a", "\b", "\f", "\n", "\r", "\t", "\v"), $str); + } + + /** + * TS Function used to unescape characters in channelnames. + * + * @param $str + * @return mixed + */ + private function ts3_unescape($str) { + return str_replace(array('\\\\', "\/", "\s", "\p", "\a", "\b", "\f", "\n", "\r", "\t", "\v"), array(chr(92), chr(47), chr(32), chr(124), chr(7), chr(8), chr(12), chr(10), chr(3), chr(9), chr(11)), $str); + } + +} \ No newline at end of file