2014-06-29 23:51:01 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace ManiaControl\Maps;
|
|
|
|
|
2014-06-30 00:57:29 +02:00
|
|
|
use FML\Controls\Frame;
|
2014-07-05 12:34:55 +02:00
|
|
|
use FML\Controls\Label;
|
2022-04-14 12:43:34 +02:00
|
|
|
use FML\Controls\Entry;
|
2014-06-30 00:57:29 +02:00
|
|
|
use FML\Controls\Labels\Label_Text;
|
|
|
|
use FML\Controls\Quads\Quad_BgsPlayerCard;
|
2014-07-05 02:47:58 +02:00
|
|
|
use FML\Controls\Quads\Quad_Icons64x64_1;
|
2014-07-05 13:35:51 +02:00
|
|
|
use FML\Controls\Quads\Quad_UIConstruction_Buttons;
|
|
|
|
use FML\Controls\Quads\Quad_UIConstructionBullet_Buttons;
|
2014-06-29 23:51:01 +02:00
|
|
|
use FML\ManiaLink;
|
2014-06-30 00:57:29 +02:00
|
|
|
use FML\Script\Features\Paging;
|
2022-04-14 12:43:34 +02:00
|
|
|
use ManiaControl\Files\AsyncHttpRequest;
|
2017-04-16 16:41:30 +02:00
|
|
|
use ManiaControl\Files\FileUtil;
|
2014-08-05 01:49:13 +02:00
|
|
|
use ManiaControl\Logger;
|
2014-06-29 23:51:01 +02:00
|
|
|
use ManiaControl\ManiaControl;
|
|
|
|
use ManiaControl\Manialinks\ManialinkManager;
|
2014-06-30 00:18:57 +02:00
|
|
|
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
|
2014-06-29 23:51:01 +02:00
|
|
|
use ManiaControl\Players\Player;
|
2014-07-05 13:58:35 +02:00
|
|
|
use Maniaplanet\DedicatedServer\Xmlrpc\AlreadyInListException;
|
|
|
|
use Maniaplanet\DedicatedServer\Xmlrpc\FileException;
|
|
|
|
use Maniaplanet\DedicatedServer\Xmlrpc\InvalidMapException;
|
2014-06-29 23:51:01 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Maps Directory Browser
|
|
|
|
*
|
|
|
|
* @author ManiaControl Team <mail@maniacontrol.com>
|
2020-01-22 10:39:35 +01:00
|
|
|
* @copyright 2014-2020 ManiaControl Team
|
2014-06-29 23:51:01 +02:00
|
|
|
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
|
|
|
|
*/
|
2014-06-30 00:18:57 +02:00
|
|
|
class DirectoryBrowser implements ManialinkPageAnswerListener {
|
|
|
|
/*
|
|
|
|
* Constants
|
|
|
|
*/
|
2014-07-05 13:35:51 +02:00
|
|
|
const ACTION_SHOW = 'MapsDirBrowser.Show';
|
|
|
|
const ACTION_NAVIGATE_UP = 'MapsDirBrowser.NavigateUp';
|
|
|
|
const ACTION_NAVIGATE_ROOT = 'MapsDirBrowser.NavigateRoot';
|
|
|
|
const ACTION_OPEN_FOLDER = 'MapsDirBrowser.OpenFolder.';
|
|
|
|
const ACTION_INSPECT_FILE = 'MapsDirBrowser.InspectFile.';
|
|
|
|
const ACTION_ADD_FILE = 'MapsDirBrowser.AddFile.';
|
|
|
|
const ACTION_ERASE_FILE = 'MapsDirBrowser.EraseFile.';
|
2022-04-14 12:43:34 +02:00
|
|
|
const ACTION_DOWNLOAD_FILE = 'MapsDirBrowser.DownloadFile';
|
2014-07-05 13:35:51 +02:00
|
|
|
const WIDGET_NAME = 'MapsDirBrowser.Widget';
|
2014-07-05 02:47:58 +02:00
|
|
|
const CACHE_FOLDER_PATH = 'FolderPath';
|
2014-06-30 00:18:57 +02:00
|
|
|
|
2014-06-29 23:51:01 +02:00
|
|
|
/*
|
|
|
|
* Private properties
|
|
|
|
*/
|
2014-08-02 22:31:46 +02:00
|
|
|
/** @var ManiaControl $maniaControl */
|
2014-06-29 23:51:01 +02:00
|
|
|
private $maniaControl = null;
|
|
|
|
|
|
|
|
/**
|
2014-08-02 22:31:46 +02:00
|
|
|
* Construct a new directory browser instance
|
2014-06-29 23:51:01 +02:00
|
|
|
*
|
|
|
|
* @param ManiaControl $maniaControl
|
|
|
|
*/
|
|
|
|
public function __construct(ManiaControl $maniaControl) {
|
|
|
|
$this->maniaControl = $maniaControl;
|
2014-06-30 00:18:57 +02:00
|
|
|
|
2014-08-03 01:34:18 +02:00
|
|
|
// ManiaLink Actions
|
2014-08-13 11:05:52 +02:00
|
|
|
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ACTION_SHOW, $this, 'handleActionShow');
|
|
|
|
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ACTION_NAVIGATE_UP, $this, 'handleNavigateUp');
|
|
|
|
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ACTION_NAVIGATE_ROOT, $this, 'handleNavigateRoot');
|
|
|
|
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener($this->buildActionRegex(self::ACTION_OPEN_FOLDER), $this, 'handleOpenFolder');
|
|
|
|
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener($this->buildActionRegex(self::ACTION_INSPECT_FILE), $this, 'handleInspectFile');
|
|
|
|
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener($this->buildActionRegex(self::ACTION_ADD_FILE), $this, 'handleAddFile');
|
|
|
|
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener($this->buildActionRegex(self::ACTION_ERASE_FILE), $this, 'handleEraseFile');
|
2022-04-14 12:43:34 +02:00
|
|
|
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener($this->buildActionRegex(self::ACTION_DOWNLOAD_FILE), $this, 'handleDownloadFile');
|
2014-06-30 00:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-07-05 13:35:51 +02:00
|
|
|
* Build the regex to register for the given action
|
2014-07-05 02:47:58 +02:00
|
|
|
*
|
2014-07-05 13:35:51 +02:00
|
|
|
* @param string $actionName
|
2014-07-05 02:47:58 +02:00
|
|
|
* @return string
|
|
|
|
*/
|
2014-07-05 13:35:51 +02:00
|
|
|
private function buildActionRegex($actionName) {
|
|
|
|
return '/' . $actionName . '*/';
|
2014-07-05 02:47:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle 'Show' action
|
2014-06-30 00:18:57 +02:00
|
|
|
*
|
|
|
|
* @param array $actionCallback
|
|
|
|
* @param Player $player
|
|
|
|
*/
|
|
|
|
public function handleActionShow(array $actionCallback, Player $player) {
|
|
|
|
$this->showManiaLink($player);
|
2014-06-29 23:51:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build and show the Browser ManiaLink to the given Player
|
|
|
|
*
|
|
|
|
* @param Player $player
|
2014-07-05 02:47:58 +02:00
|
|
|
* @param mixed $nextFolder
|
2014-06-29 23:51:01 +02:00
|
|
|
*/
|
2014-07-05 02:47:58 +02:00
|
|
|
public function showManiaLink(Player $player, $nextFolder = null) {
|
2014-07-05 12:06:49 +02:00
|
|
|
$oldFolderPath = $player->getCache($this, self::CACHE_FOLDER_PATH);
|
|
|
|
$isInMapsFolder = false;
|
2014-07-05 02:47:58 +02:00
|
|
|
if (!$oldFolderPath) {
|
2014-08-13 11:05:52 +02:00
|
|
|
$oldFolderPath = $this->maniaControl->getServer()->getDirectory()->getMapsFolder();
|
2014-07-05 12:06:49 +02:00
|
|
|
$isInMapsFolder = true;
|
2014-07-05 02:47:58 +02:00
|
|
|
}
|
|
|
|
$folderPath = $oldFolderPath;
|
|
|
|
if (is_string($nextFolder)) {
|
2014-07-05 12:06:49 +02:00
|
|
|
$newFolderPath = realpath($oldFolderPath . $nextFolder);
|
|
|
|
if ($newFolderPath) {
|
|
|
|
$folderPath = $newFolderPath . DIRECTORY_SEPARATOR;
|
|
|
|
$folderName = basename($newFolderPath);
|
|
|
|
switch ($folderName) {
|
|
|
|
case 'Maps':
|
2014-08-13 11:05:52 +02:00
|
|
|
$mapsDir = dirname($this->maniaControl->getServer()->getDirectory()->getMapsFolder());
|
2014-07-05 12:06:49 +02:00
|
|
|
$folderDir = dirname($folderPath);
|
|
|
|
$isInMapsFolder = ($mapsDir === $folderDir);
|
|
|
|
break;
|
|
|
|
case 'UserData':
|
2017-05-15 19:30:22 +02:00
|
|
|
$dataDir = dirname($this->maniaControl->getServer()->getDirectory()->getUserDataFolder());
|
2014-07-05 12:06:49 +02:00
|
|
|
$folderDir = dirname($folderPath);
|
|
|
|
if ($dataDir === $folderDir) {
|
|
|
|
// Prevent navigation out of maps directory
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2014-07-05 02:47:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
$player->setCache($this, self::CACHE_FOLDER_PATH, $folderPath);
|
|
|
|
|
2014-06-29 23:51:01 +02:00
|
|
|
$maniaLink = new ManiaLink(ManialinkManager::MAIN_MLID);
|
2014-06-30 00:57:29 +02:00
|
|
|
$script = $maniaLink->getScript();
|
|
|
|
$paging = new Paging();
|
|
|
|
$script->addFeature($paging);
|
2014-08-13 11:05:52 +02:00
|
|
|
$frame = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultListFrame($script, $paging);
|
2017-03-25 19:15:50 +01:00
|
|
|
$maniaLink->addChild($frame);
|
2014-06-29 23:51:01 +02:00
|
|
|
|
2014-08-13 11:05:52 +02:00
|
|
|
$width = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsWidth();
|
|
|
|
$height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight();
|
2014-06-30 00:57:29 +02:00
|
|
|
$index = 0;
|
|
|
|
$posY = $height / 2 - 10;
|
|
|
|
$pageFrame = null;
|
2023-09-08 13:06:15 +02:00
|
|
|
$pageMaxCount = floor(($height * 0.78) / 4);
|
2014-06-30 00:57:29 +02:00
|
|
|
|
2014-07-05 02:47:58 +02:00
|
|
|
$navigateRootQuad = new Quad_Icons64x64_1();
|
2017-03-25 19:15:50 +01:00
|
|
|
$frame->addChild($navigateRootQuad);
|
2014-08-13 11:05:52 +02:00
|
|
|
$navigateRootQuad->setPosition($width * -0.47, $height * 0.45)->setSize(4, 4)->setSubStyle($navigateRootQuad::SUBSTYLE_ToolRoot);
|
2014-06-30 00:57:29 +02:00
|
|
|
|
2014-07-05 02:47:58 +02:00
|
|
|
$navigateUpQuad = new Quad_Icons64x64_1();
|
2017-03-25 19:15:50 +01:00
|
|
|
$frame->addChild($navigateUpQuad);
|
2014-08-13 11:05:52 +02:00
|
|
|
$navigateUpQuad->setPosition($width * -0.44, $height * 0.45)->setSize(4, 4)->setSubStyle($navigateUpQuad::SUBSTYLE_ToolUp);
|
2014-07-05 12:06:49 +02:00
|
|
|
|
|
|
|
if (!$isInMapsFolder) {
|
|
|
|
$navigateRootQuad->setAction(self::ACTION_NAVIGATE_ROOT);
|
|
|
|
$navigateUpQuad->setAction(self::ACTION_NAVIGATE_UP);
|
|
|
|
}
|
2014-06-30 00:57:29 +02:00
|
|
|
|
2014-07-05 02:47:58 +02:00
|
|
|
$directoryLabel = new Label_Text();
|
2017-03-25 19:15:50 +01:00
|
|
|
$frame->addChild($directoryLabel);
|
2017-05-15 19:30:22 +02:00
|
|
|
$dataFolder = $this->maniaControl->getServer()->getDirectory()->getUserDataFolder();
|
2014-07-05 02:47:58 +02:00
|
|
|
$directoryText = substr($folderPath, strlen($dataFolder));
|
2017-03-25 19:15:50 +01:00
|
|
|
$directoryLabel->setPosition($width * -0.41, $height * 0.45)->setSize($width * 0.85, 4)->setHorizontalAlign($directoryLabel::LEFT)->setText($directoryText)->setTextSize(2);
|
2014-06-30 00:57:29 +02:00
|
|
|
|
2014-07-05 13:35:51 +02:00
|
|
|
$tooltipLabel = new Label();
|
2017-03-25 19:15:50 +01:00
|
|
|
$frame->addChild($tooltipLabel);
|
2017-03-28 16:44:41 +02:00
|
|
|
$tooltipLabel->setPosition($width * -0.48, $height * -0.44)->setSize($width * 0.8, 5)->setHorizontalAlign($tooltipLabel::LEFT)->setTextSize(1);
|
2014-07-05 13:35:51 +02:00
|
|
|
|
2014-07-05 02:47:58 +02:00
|
|
|
$mapFiles = $this->scanMapFiles($folderPath);
|
2014-06-30 00:57:29 +02:00
|
|
|
|
2014-07-05 02:47:58 +02:00
|
|
|
if (is_array($mapFiles)) {
|
2014-07-05 12:34:55 +02:00
|
|
|
if (empty($mapFiles)) {
|
|
|
|
$emptyLabel = new Label();
|
2017-03-25 19:15:50 +01:00
|
|
|
$frame->addChild($emptyLabel);
|
2014-08-13 11:05:52 +02:00
|
|
|
$emptyLabel->setY(20)->setTextColor('aaa')->setText('No files found.')->setTranslate(true);
|
2014-07-05 12:34:55 +02:00
|
|
|
} else {
|
2014-08-13 11:05:52 +02:00
|
|
|
$canAddMaps = $this->maniaControl->getAuthenticationManager()->checkPermission($player, MapManager::SETTING_PERMISSION_ADD_MAP);
|
|
|
|
$canEraseMaps = $this->maniaControl->getAuthenticationManager()->checkPermission($player, MapManager::SETTING_PERMISSION_ERASE_MAP);
|
2014-07-05 12:50:26 +02:00
|
|
|
|
2014-07-05 12:34:55 +02:00
|
|
|
foreach ($mapFiles as $filePath => $fileName) {
|
|
|
|
$shortFilePath = substr($filePath, strlen($folderPath));
|
2014-06-30 00:57:29 +02:00
|
|
|
|
2023-09-08 12:19:12 +02:00
|
|
|
if ($index % $pageMaxCount === 0) {
|
2014-07-05 12:34:55 +02:00
|
|
|
// New Page
|
|
|
|
$pageFrame = new Frame();
|
2017-03-25 19:15:50 +01:00
|
|
|
$frame->addChild($pageFrame);
|
2014-07-05 12:34:55 +02:00
|
|
|
$posY = $height / 2 - 10;
|
2017-03-28 16:44:41 +02:00
|
|
|
$paging->addPageControl($pageFrame);
|
2014-07-05 12:34:55 +02:00
|
|
|
}
|
2014-06-30 00:18:57 +02:00
|
|
|
|
2014-07-05 12:34:55 +02:00
|
|
|
// Map Frame
|
|
|
|
$mapFrame = new Frame();
|
2017-03-25 19:15:50 +01:00
|
|
|
$pageFrame->addChild($mapFrame);
|
2014-07-05 12:34:55 +02:00
|
|
|
$mapFrame->setY($posY);
|
2014-07-05 02:47:58 +02:00
|
|
|
|
2014-07-05 12:34:55 +02:00
|
|
|
if ($index % 2 === 0) {
|
|
|
|
// Striped background line
|
|
|
|
$lineQuad = new Quad_BgsPlayerCard();
|
2017-03-25 19:15:50 +01:00
|
|
|
$mapFrame->addChild($lineQuad);
|
2014-08-13 11:05:52 +02:00
|
|
|
$lineQuad->setZ(-1)->setSize($width, 4)->setSubStyle($lineQuad::SUBSTYLE_BgPlayerCardBig);
|
2014-07-05 12:34:55 +02:00
|
|
|
}
|
2014-07-05 02:47:58 +02:00
|
|
|
|
2014-07-05 12:34:55 +02:00
|
|
|
// File name Label
|
|
|
|
$nameLabel = new Label_Text();
|
2017-03-25 19:15:50 +01:00
|
|
|
$mapFrame->addChild($nameLabel);
|
|
|
|
$nameLabel->setX($width * -0.48)->setSize($width * 0.79, 4)->setHorizontalAlign($nameLabel::LEFT)->setStyle($nameLabel::STYLE_TextCardRaceRank)->setTextSize(1)->setText($fileName);
|
2014-07-05 02:47:58 +02:00
|
|
|
|
2014-07-05 12:34:55 +02:00
|
|
|
if (is_dir($filePath)) {
|
|
|
|
// Folder
|
2014-08-13 11:05:52 +02:00
|
|
|
$nameLabel->setAction(self::ACTION_OPEN_FOLDER . substr($shortFilePath, 0, -1))->addTooltipLabelFeature($tooltipLabel, 'Open folder ' . $fileName);
|
2014-07-05 12:34:55 +02:00
|
|
|
} else {
|
|
|
|
// File
|
2014-08-13 11:05:52 +02:00
|
|
|
$nameLabel->setAction(self::ACTION_INSPECT_FILE . $fileName)->addTooltipLabelFeature($tooltipLabel, 'Inspect file ' . $fileName);
|
2014-07-05 13:35:51 +02:00
|
|
|
|
2014-07-05 12:50:26 +02:00
|
|
|
if ($canAddMaps) {
|
2014-07-05 12:34:55 +02:00
|
|
|
// 'Add' button
|
2014-07-05 13:35:51 +02:00
|
|
|
$addButton = new Quad_UIConstructionBullet_Buttons();
|
2017-03-25 19:15:50 +01:00
|
|
|
$mapFrame->addChild($addButton);
|
2014-08-13 11:05:52 +02:00
|
|
|
$addButton->setX($width * 0.42)->setSize(4, 4)->setSubStyle($addButton::SUBSTYLE_NewBullet)->setAction(self::ACTION_ADD_FILE . $fileName)->addTooltipLabelFeature($tooltipLabel, 'Add map ' . $fileName);
|
2014-07-05 12:34:55 +02:00
|
|
|
}
|
2014-07-05 02:47:58 +02:00
|
|
|
|
2014-07-05 12:50:26 +02:00
|
|
|
if ($canEraseMaps) {
|
2014-07-05 12:34:55 +02:00
|
|
|
// 'Erase' button
|
2014-07-05 13:35:51 +02:00
|
|
|
$eraseButton = new Quad_UIConstruction_Buttons();
|
2017-03-25 19:15:50 +01:00
|
|
|
$mapFrame->addChild($eraseButton);
|
2014-08-13 11:05:52 +02:00
|
|
|
$eraseButton->setX($width * 0.46)->setSize(4, 4)->setSubStyle($eraseButton::SUBSTYLE_Erase)->setAction(self::ACTION_ERASE_FILE . $fileName)->addTooltipLabelFeature($tooltipLabel, 'Erase file ' . $fileName);
|
2014-07-05 12:34:55 +02:00
|
|
|
}
|
2014-07-05 02:47:58 +02:00
|
|
|
}
|
|
|
|
|
2014-07-05 12:34:55 +02:00
|
|
|
$posY -= 4;
|
|
|
|
$index++;
|
|
|
|
}
|
2014-07-05 02:47:58 +02:00
|
|
|
}
|
2022-04-14 12:43:34 +02:00
|
|
|
|
2023-09-08 13:06:15 +02:00
|
|
|
$downloadPosX = -$width / 2 + 5;
|
|
|
|
|
2022-04-14 12:43:34 +02:00
|
|
|
$label = new Label_Text();
|
|
|
|
$frame->addChild($label);
|
2023-09-08 13:06:15 +02:00
|
|
|
$label->setPosition($downloadPosX, $height * -0.39);
|
2022-04-14 12:43:34 +02:00
|
|
|
$label->setHorizontalAlign($label::LEFT);
|
|
|
|
$label->setTextSize(1);
|
|
|
|
$label->setText('Download from URL: ');
|
2023-09-08 13:06:15 +02:00
|
|
|
|
|
|
|
$downloadPosX += 30;
|
2022-04-14 12:43:34 +02:00
|
|
|
|
|
|
|
$entry = new Entry();
|
|
|
|
$frame->addChild($entry);
|
|
|
|
$entry->setStyle(Label_Text::STYLE_TextValueSmall);
|
|
|
|
$entry->setHorizontalAlign($entry::LEFT);
|
2023-09-08 13:06:15 +02:00
|
|
|
$entry->setPosition($downloadPosX, $height * -0.39);
|
2022-04-14 12:43:34 +02:00
|
|
|
$entry->setTextSize(1);
|
|
|
|
$entry->setSize($width * 0.35, 4);
|
2023-10-02 15:25:05 +02:00
|
|
|
$entry->setName("Value");
|
2023-09-08 13:06:15 +02:00
|
|
|
|
|
|
|
$downloadPosX += $width * 0.35 + 10;
|
2022-04-14 12:43:34 +02:00
|
|
|
|
|
|
|
//Search for Map-Name
|
|
|
|
$mapNameButton = $this->maniaControl->getManialinkManager()->getElementBuilder()->buildRoundTextButton(
|
|
|
|
'Download',
|
|
|
|
18,
|
|
|
|
5,
|
|
|
|
self::ACTION_DOWNLOAD_FILE
|
|
|
|
);
|
|
|
|
$frame->addChild($mapNameButton);
|
2023-09-08 13:06:15 +02:00
|
|
|
$mapNameButton->setPosition($downloadPosX, $height * -0.39);
|
2022-04-14 12:43:34 +02:00
|
|
|
|
2014-07-05 02:47:58 +02:00
|
|
|
} else {
|
2014-07-05 12:34:55 +02:00
|
|
|
$errorLabel = new Label();
|
2017-03-25 19:15:50 +01:00
|
|
|
$frame->addChild($errorLabel);
|
2014-08-13 11:05:52 +02:00
|
|
|
$errorLabel->setY(20)->setTextColor('f30')->setText('No access to the directory.')->setTranslate(true);
|
2014-06-30 00:18:57 +02:00
|
|
|
}
|
|
|
|
|
2014-08-13 11:05:52 +02:00
|
|
|
$this->maniaControl->getManialinkManager()->displayWidget($maniaLink, $player, self::WIDGET_NAME);
|
2014-06-30 00:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Scan the given directory for Map files
|
|
|
|
*
|
|
|
|
* @param string $directory
|
|
|
|
* @return array|bool
|
|
|
|
*/
|
|
|
|
protected function scanMapFiles($directory) {
|
|
|
|
if (!is_readable($directory) || !is_dir($directory)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$mapFiles = array();
|
2022-04-10 22:18:49 +02:00
|
|
|
$dirFiles = scandir($directory, SCANDIR_SORT_NONE);
|
|
|
|
natcasesort($dirFiles);
|
2014-06-30 00:18:57 +02:00
|
|
|
foreach ($dirFiles as $fileName) {
|
2017-04-16 16:41:30 +02:00
|
|
|
if (FileUtil::isHiddenFile($fileName)) {
|
2014-06-30 00:57:29 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$fullFileName = $directory . $fileName;
|
2014-07-05 02:47:58 +02:00
|
|
|
if (!is_readable($fullFileName)) {
|
|
|
|
continue;
|
|
|
|
}
|
2014-06-30 00:57:29 +02:00
|
|
|
if (is_dir($fullFileName)) {
|
2014-07-05 02:47:58 +02:00
|
|
|
$mapFiles[$fullFileName . DIRECTORY_SEPARATOR] = $fileName . DIRECTORY_SEPARATOR;
|
|
|
|
continue;
|
2014-06-30 00:18:57 +02:00
|
|
|
} else {
|
|
|
|
if ($this->isMapFileName($fileName)) {
|
2014-07-05 02:47:58 +02:00
|
|
|
$mapFiles[$fullFileName] = $fileName;
|
2014-06-30 00:18:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $mapFiles;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if the given file name represents a Map file
|
|
|
|
*
|
|
|
|
* @param string $fileName
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
protected function isMapFileName($fileName) {
|
|
|
|
$mapFileNameEnding = '.map.gbx';
|
|
|
|
$fileNameEnding = strtolower(substr($fileName, -strlen($mapFileNameEnding)));
|
|
|
|
return ($fileNameEnding === $mapFileNameEnding);
|
|
|
|
}
|
2014-07-05 02:47:58 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle 'NavigateRoot' action
|
|
|
|
*
|
|
|
|
* @param array $actionCallback
|
|
|
|
* @param Player $player
|
|
|
|
*/
|
|
|
|
public function handleNavigateRoot(array $actionCallback, Player $player) {
|
|
|
|
$player->destroyCache($this, self::CACHE_FOLDER_PATH);
|
|
|
|
$this->showManiaLink($player);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle 'NavigateUp' action
|
|
|
|
*
|
|
|
|
* @param array $actionCallback
|
|
|
|
* @param Player $player
|
|
|
|
*/
|
|
|
|
public function handleNavigateUp(array $actionCallback, Player $player) {
|
|
|
|
$this->showManiaLink($player, '..');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-07-05 13:35:51 +02:00
|
|
|
* Handle 'OpenFolder' page action
|
2014-07-05 02:47:58 +02:00
|
|
|
*
|
|
|
|
* @param array $actionCallback
|
|
|
|
* @param Player $player
|
|
|
|
*/
|
|
|
|
public function handleOpenFolder(array $actionCallback, Player $player) {
|
|
|
|
$actionName = $actionCallback[1][2];
|
|
|
|
$folderName = substr($actionName, strlen(self::ACTION_OPEN_FOLDER));
|
|
|
|
$this->showManiaLink($player, $folderName);
|
|
|
|
}
|
2014-07-05 13:35:51 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle 'InspectFile' page action
|
|
|
|
*
|
|
|
|
* @param array $actionCallback
|
|
|
|
* @param Player $player
|
|
|
|
*/
|
|
|
|
public function handleInspectFile(array $actionCallback, Player $player) {
|
|
|
|
$actionName = $actionCallback[1][2];
|
|
|
|
$fileName = substr($actionName, strlen(self::ACTION_INSPECT_FILE));
|
|
|
|
// TODO: show inspect file view
|
|
|
|
var_dump($fileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle 'AddFile' page action
|
|
|
|
*
|
|
|
|
* @param array $actionCallback
|
|
|
|
* @param Player $player
|
|
|
|
*/
|
|
|
|
public function handleAddFile(array $actionCallback, Player $player) {
|
|
|
|
$actionName = $actionCallback[1][2];
|
|
|
|
$fileName = substr($actionName, strlen(self::ACTION_ADD_FILE));
|
2014-07-05 13:58:35 +02:00
|
|
|
$folderPath = $player->getCache($this, self::CACHE_FOLDER_PATH);
|
|
|
|
$filePath = $folderPath . $fileName;
|
|
|
|
|
2014-08-13 11:05:52 +02:00
|
|
|
$mapsFolder = $this->maniaControl->getServer()->getDirectory()->getMapsFolder();
|
2014-07-05 13:58:35 +02:00
|
|
|
$relativeFilePath = substr($filePath, strlen($mapsFolder));
|
|
|
|
|
|
|
|
// Check for valid map
|
|
|
|
try {
|
2014-08-13 11:05:52 +02:00
|
|
|
$this->maniaControl->getClient()->checkMapForCurrentServerParams($relativeFilePath);
|
2014-07-05 13:58:35 +02:00
|
|
|
} catch (InvalidMapException $exception) {
|
2014-08-13 11:05:52 +02:00
|
|
|
$this->maniaControl->getChat()->sendException($exception, $player);
|
2014-07-05 13:58:35 +02:00
|
|
|
return;
|
|
|
|
} catch (FileException $exception) {
|
2014-08-13 11:05:52 +02:00
|
|
|
$this->maniaControl->getChat()->sendException($exception, $player);
|
2014-07-05 13:58:35 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add map to map list
|
|
|
|
try {
|
2014-08-13 11:05:52 +02:00
|
|
|
$this->maniaControl->getClient()->insertMap($relativeFilePath);
|
2014-07-05 13:58:35 +02:00
|
|
|
} catch (AlreadyInListException $exception) {
|
2014-08-13 11:05:52 +02:00
|
|
|
$this->maniaControl->getChat()->sendException($exception, $player);
|
2014-07-05 13:58:35 +02:00
|
|
|
return;
|
|
|
|
}
|
2014-08-13 11:05:52 +02:00
|
|
|
$map = $this->maniaControl->getMapManager()->fetchMapByFileName($relativeFilePath);
|
2014-07-05 13:58:35 +02:00
|
|
|
if (!$map) {
|
2014-08-13 11:05:52 +02:00
|
|
|
$this->maniaControl->getChat()->sendError('Error occurred.', $player);
|
2014-07-05 13:58:35 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-11 14:58:17 +02:00
|
|
|
//Update MX Data and ID
|
|
|
|
$this->maniaControl->getMapManager()->getMXManager()->fetchManiaExchangeMapInformation($map);
|
|
|
|
|
|
|
|
$map->lastUpdate = time();
|
2017-06-21 19:06:26 +02:00
|
|
|
//Update Map Timestamp in Database
|
|
|
|
$this->maniaControl->getMapManager()->updateMapTimestamp($map->uid);
|
2017-04-11 14:58:17 +02:00
|
|
|
|
2014-07-05 13:58:35 +02:00
|
|
|
// Message
|
2020-05-27 00:01:36 +02:00
|
|
|
$message = $this->maniaControl->getChat()->formatMessage(
|
|
|
|
'%s added %s!',
|
|
|
|
$player,
|
|
|
|
$map
|
|
|
|
);
|
2014-08-13 11:05:52 +02:00
|
|
|
$this->maniaControl->getChat()->sendSuccess($message);
|
2014-08-05 02:08:41 +02:00
|
|
|
Logger::logInfo($message, true);
|
2014-07-05 13:58:35 +02:00
|
|
|
|
|
|
|
// Queue requested Map
|
2014-08-13 11:05:52 +02:00
|
|
|
$this->maniaControl->getMapManager()->getMapQueue()->addMapToMapQueue($player, $map);
|
2014-07-05 13:35:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle 'EraseFile' page action
|
|
|
|
*
|
|
|
|
* @param array $actionCallback
|
|
|
|
* @param Player $player
|
|
|
|
*/
|
|
|
|
public function handleEraseFile(array $actionCallback, Player $player) {
|
|
|
|
$actionName = $actionCallback[1][2];
|
|
|
|
$fileName = substr($actionName, strlen(self::ACTION_ERASE_FILE));
|
2014-07-05 14:05:23 +02:00
|
|
|
$folderPath = $player->getCache($this, self::CACHE_FOLDER_PATH);
|
|
|
|
$filePath = $folderPath . $fileName;
|
|
|
|
if (@unlink($filePath)) {
|
2020-05-27 00:01:36 +02:00
|
|
|
$message = $this->maniaControl->getChat()->formatMessage(
|
|
|
|
'Erased %s!',
|
|
|
|
$fileName
|
|
|
|
);
|
|
|
|
$this->maniaControl->getChat()->sendSuccess($message, $player);
|
2014-07-05 14:05:23 +02:00
|
|
|
$this->showManiaLink($player);
|
|
|
|
} else {
|
2020-05-27 00:01:36 +02:00
|
|
|
$message = $this->maniaControl->getChat()->formatMessage(
|
|
|
|
'Could not erase %s!',
|
|
|
|
$fileName
|
|
|
|
);
|
|
|
|
$this->maniaControl->getChat()->sendError($message, $player);
|
2014-07-05 14:05:23 +02:00
|
|
|
}
|
2014-07-05 13:35:51 +02:00
|
|
|
}
|
2022-04-14 12:43:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle 'handleDownloadFile' page action
|
|
|
|
*
|
|
|
|
* @param array $actionCallback
|
|
|
|
* @param Player $player
|
|
|
|
*/
|
|
|
|
public function handleDownloadFile(array $actionCallback, Player $player) {
|
|
|
|
$url = trim($actionCallback[1][3][0]["Value"]);
|
|
|
|
$folderPath = $player->getCache($this, self::CACHE_FOLDER_PATH);
|
|
|
|
if (filter_var($url, FILTER_VALIDATE_URL)) {
|
|
|
|
|
|
|
|
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, $url);
|
|
|
|
$asyncHttpRequest->setCallable(function ($file, $error, $headers) use ($url, $folderPath, $player) {
|
|
|
|
if (!$file || $error) {
|
|
|
|
$message = "Impossible to download the file: " . $error;
|
|
|
|
$this->maniaControl->getChat()->sendError($message, $player);
|
|
|
|
Logger::logError($message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$filePath = "";
|
|
|
|
|
|
|
|
$contentdispositionheader = "";
|
|
|
|
foreach ($headers as $key => $value) {
|
|
|
|
if (strtolower($key) === "content-disposition") {
|
2022-04-15 20:59:46 +02:00
|
|
|
$contentdispositionheader = urldecode($value);
|
2022-04-14 12:43:34 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($contentdispositionheader !== "") {
|
|
|
|
$value = $contentdispositionheader;
|
|
|
|
|
|
|
|
if (strpos($value, ';') !== false) {
|
|
|
|
|
|
|
|
list($type, $attr_parts) = explode(';', $value, 2);
|
|
|
|
|
|
|
|
$attr_parts = explode(';', $attr_parts);
|
|
|
|
$attributes = array();
|
|
|
|
|
|
|
|
foreach ($attr_parts as $part) {
|
|
|
|
if (strpos($part, '=') === false) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
list($key, $value) = explode('=', $part, 2);
|
|
|
|
|
|
|
|
$attributes[trim($key)] = trim($value);
|
|
|
|
}
|
|
|
|
|
|
|
|
$attrNames = ['filename*' => true, 'filename' => false];
|
|
|
|
$filename = null;
|
|
|
|
$isUtf8 = false;
|
|
|
|
foreach ($attrNames as $attrName => $utf8) {
|
|
|
|
if (!empty($attributes[$attrName])) {
|
|
|
|
$filename = trim($attributes[$attrName]);
|
|
|
|
$isUtf8 = $utf8;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($filename !== null) {
|
|
|
|
if ($isUtf8 && strpos($filename, "utf-8''") === 0 && $filename = substr($filename, strlen("utf-8''"))) {
|
2023-08-14 17:35:02 +02:00
|
|
|
$filePath = $folderPath . FileUtil::getClearedFileName(rawurldecode($filename));
|
2022-04-14 12:43:34 +02:00
|
|
|
}
|
|
|
|
if (substr($filename, 0, 1) === '"' && substr($filename, -1, 1) === '"') {
|
|
|
|
$filePath = $folderPath . substr($filename, 1, -1);
|
|
|
|
} else {
|
|
|
|
$filePath = $folderPath . $filename;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$this->isMapFileName($filePath)) {
|
|
|
|
$message = "File is not a map: " . $filename;
|
|
|
|
$this->maniaControl->getChat()->sendError($message, $player);
|
|
|
|
Logger::logError($message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$path = parse_url($url, PHP_URL_PATH);
|
|
|
|
|
|
|
|
// extracted basename
|
|
|
|
$filePath = $folderPath . basename($path);
|
|
|
|
|
|
|
|
if (!$this->isMapFileName($filePath)) {
|
|
|
|
$filePath .= ".Map.Gbx";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($filePath != "") {
|
|
|
|
if (file_exists($filePath)) {
|
|
|
|
$index = 1;
|
|
|
|
while (file_exists(substr($filePath, 0, -8) . "-" . $index . ".Map.Gbx")) {
|
|
|
|
$index++;
|
|
|
|
}
|
|
|
|
$filePath = substr($filePath, 0, -8) . "-" . $index . ".Map.Gbx";
|
|
|
|
}
|
|
|
|
$bytes = file_put_contents($filePath, $file);
|
|
|
|
if (!$bytes || $bytes <= 0) {
|
|
|
|
$message = "Impossible to determine filename";
|
|
|
|
$this->maniaControl->getChat()->sendError($message, $player);
|
|
|
|
Logger::logError($message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->showManiaLink($player, $folderPath);
|
|
|
|
});
|
|
|
|
|
|
|
|
$asyncHttpRequest->getData();
|
|
|
|
}
|
|
|
|
}
|
2014-06-29 23:51:01 +02:00
|
|
|
}
|