TrackManiaControl/core/Maps/DirectoryBrowser.php

725 lines
24 KiB
PHP
Raw Permalink Normal View History

2014-06-29 23:51:01 +02:00
<?php
namespace ManiaControl\Maps;
use finfo;
use ZipArchive;
2014-06-30 00:57:29 +02:00
use FML\Controls\Frame;
use FML\Controls\Label;
use FML\Controls\Entry;
use FML\Controls\Labels\Label_Button;
2014-06-30 00:57:29 +02:00
use FML\Controls\Labels\Label_Text;
use FML\Controls\Quads\Quad_BgsPlayerCard;
use FML\Controls\Quads\Quad_Icons64x64_1;
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;
use ManiaControl\Files\AsyncHttpRequest;
use ManiaControl\Files\FileUtil;
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
*/
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.';
const ACTION_CREATE_FOLDER = 'MapsDirBrowser.CreateFolder';
const ACTION_DOWNLOAD_FILE = 'MapsDirBrowser.DownloadFile';
const WIDGET_NAME = 'MapsDirBrowser.Widget';
const CACHE_FOLDER_PATH = 'FolderPath';
2014-06-30 00:18:57 +02:00
2014-06-29 23:51:01 +02:00
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
2014-06-29 23:51:01 +02:00
private $maniaControl = null;
/**
* 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
// 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');
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener($this->buildActionRegex(self::ACTION_CREATE_FOLDER), $this, 'handleCreateFolder');
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener($this->buildActionRegex(self::ACTION_DOWNLOAD_FILE), $this, 'handleDownloadFile');
2014-06-30 00:18:57 +02:00
}
/**
* Build the regex to register for the given action
*
* @param string $actionName
* @return string
*/
private function buildActionRegex($actionName) {
return '/' . $actionName . '*/';
}
/**
* 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
* @param mixed $nextFolder
2014-06-29 23:51:01 +02:00
*/
public function showManiaLink(Player $player, $nextFolder = null) {
$oldFolderPath = $player->getCache($this, self::CACHE_FOLDER_PATH);
$isInMapsFolder = false;
if (!$oldFolderPath) {
2014-08-13 11:05:52 +02:00
$oldFolderPath = $this->maniaControl->getServer()->getDirectory()->getMapsFolder();
$isInMapsFolder = true;
}
$folderPath = $oldFolderPath;
if (is_string($nextFolder)) {
$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());
$folderDir = dirname($folderPath);
$isInMapsFolder = ($mapsDir === $folderDir);
break;
case 'UserData':
2017-05-15 19:30:22 +02:00
$dataDir = dirname($this->maniaControl->getServer()->getDirectory()->getUserDataFolder());
$folderDir = dirname($folderPath);
if ($dataDir === $folderDir) {
// Prevent navigation out of maps directory
return;
}
break;
}
}
}
$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();
$innerWidth = $width - 2;
$innerHeigth = $height - 27;
$lineHeight = 4.;
2014-06-30 00:57:29 +02:00
$index = 0;
$pageFrame = null;
$pageMaxCount = floor($innerHeigth / 4);
$repositionnedFrame = new Frame();
$frame->addChild($repositionnedFrame);
$repositionnedFrame->setPosition($width * -0.5, $height * 0.5);
2014-06-30 00:57:29 +02:00
$navigateRootQuad = new Quad_Icons64x64_1();
$repositionnedFrame->addChild($navigateRootQuad);
$navigateRootQuad->setPosition(5, -5);
$navigateRootQuad->setSize(4, 4);
$navigateRootQuad->setSubStyle($navigateRootQuad::SUBSTYLE_ToolRoot);
2014-06-30 00:57:29 +02:00
$navigateUpQuad = new Quad_Icons64x64_1();
$repositionnedFrame->addChild($navigateUpQuad);
$navigateUpQuad->setPosition(9, -5);
$navigateUpQuad->setSize(4, 4);
$navigateUpQuad->setSubStyle($navigateUpQuad::SUBSTYLE_ToolUp);
if (!$isInMapsFolder) {
$navigateRootQuad->setAction(self::ACTION_NAVIGATE_ROOT);
$navigateUpQuad->setAction(self::ACTION_NAVIGATE_UP);
}
2014-06-30 00:57:29 +02:00
$directoryLabel = new Label_Text();
$repositionnedFrame->addChild($directoryLabel);
2017-05-15 19:30:22 +02:00
$dataFolder = $this->maniaControl->getServer()->getDirectory()->getUserDataFolder();
$directoryText = substr($folderPath, strlen($dataFolder));
$directoryLabel->setPosition(12, -5);
$directoryLabel->setSize($width * 0.85, 4);
$directoryLabel->setHorizontalAlign($directoryLabel::LEFT);
$directoryLabel->setText($directoryText);
$directoryLabel->setTextSize(2);
2014-06-30 00:57:29 +02:00
$tooltipLabel = new Label();
$repositionnedFrame->addChild($tooltipLabel);
$tooltipLabel->setPosition(3, $height * -1 + 15);
$tooltipLabel->setSize($width * 0.8, 5);
$tooltipLabel->setHorizontalAlign($tooltipLabel::LEFT);
$tooltipLabel->setTextSize(1);
// Back button
$backButton = new Label_Button();
$repositionnedFrame->addChild($backButton);
$backButton->setStyle($backButton::STYLE_CardMain_Quit);
$backButton->setHorizontalAlign($backButton::LEFT);
$backButton->setScale(0.5);
$backButton->setText('Back');
$backButton->setPosition(3, $height * -1 + 5);
$backButton->setSize(5, 10);
$backButton->setAction(MapCommands::ACTION_OPEN_MAPLIST);
// Create folder button
$label = new Label_Text();
$repositionnedFrame->addChild($label);
2024-07-23 18:16:30 +02:00
$label->setPosition($width - 113, $height * -1 + 10);
$label->setSize(25, 5);
$label->setHorizontalAlign($label::LEFT);
$label->setTextSize(1);
$label->setText('Create folder: ');
$label->setAreaFocusColor("00000000");
$label->setAreaColor("00000000");
$entry = new Entry();
$repositionnedFrame->addChild($entry);
$entry->setStyle(Label_Text::STYLE_TextValueSmall);
$entry->setHorizontalAlign($entry::LEFT);
2024-07-23 18:16:30 +02:00
$entry->setPosition($width - 95, $height * -1 + 10);
$entry->setTextSize(1);
$entry->setSize(50, 4);
$entry->setName("Name");
//Search for Map-Name
$createFolderButton = $this->maniaControl->getManialinkManager()->getElementBuilder()->buildRoundTextButton(
'Create',
18,
5,
self::ACTION_CREATE_FOLDER
);
$repositionnedFrame->addChild($createFolderButton);
2024-07-23 18:16:30 +02:00
$createFolderButton->setPosition($width - 27 - 18/2, $height * -1 + 10);
// Download button
$label = new Label_Text();
$repositionnedFrame->addChild($label);
2024-07-23 18:16:30 +02:00
$label->setPosition($width - 122, $height * -1 + 5);
$label->setSize(27, 5);
$label->setHorizontalAlign($label::LEFT);
$label->setTextSize(1);
$label->setText('Download from URL: ');
$label->setAreaFocusColor("00000000");
$label->setAreaColor("00000000");
$label->addTooltipLabelFeature($tooltipLabel, 'Support Map.Gbx and Zip files');
$entry = new Entry();
$repositionnedFrame->addChild($entry);
$entry->setStyle(Label_Text::STYLE_TextValueSmall);
$entry->setHorizontalAlign($entry::LEFT);
2024-07-23 18:16:30 +02:00
$entry->setPosition($width - 95, $height * -1 + 5);
$entry->setTextSize(1);
$entry->setSize(50, 4);
$entry->setName("URL");
//Search for Map-Name
$downloadButton = $this->maniaControl->getManialinkManager()->getElementBuilder()->buildRoundTextButton(
'Download',
18,
5,
self::ACTION_DOWNLOAD_FILE
);
$repositionnedFrame->addChild($downloadButton);
2024-07-23 18:16:30 +02:00
$downloadButton->setPosition($width - 27 - 18/2, $height * -1 + 5);
$mapFiles = $this->scanMapFiles($folderPath);
2014-06-30 00:57:29 +02:00
if (is_array($mapFiles)) {
if (empty($mapFiles)) {
$emptyLabel = new Label();
$repositionnedFrame->addChild($emptyLabel);
$emptyLabel->setPosition($innerWidth * 0.5, $innerHeigth * -0.5);
$emptyLabel->setTextColor('aaa');
$emptyLabel->setText('No files found.');
$emptyLabel->setTranslate(true);
} 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
$pagesFrame = new Frame();
$repositionnedFrame->addChild($pagesFrame);
$pagesFrame->setPosition(1, -10);
foreach ($mapFiles as $filePath => $fileName) {
$shortFilePath = substr($filePath, strlen($folderPath));
2014-06-30 00:57:29 +02:00
if ($index % $pageMaxCount === 0) {
// New Page
$pageFrame = new Frame();
$pagesFrame->addChild($pageFrame);
$paging->addPageControl($pageFrame);
$index = 1;
}
2014-06-30 00:18:57 +02:00
// Map Frame
$mapFrame = new Frame();
2017-03-25 19:15:50 +01:00
$pageFrame->addChild($mapFrame);
$mapFrame->setY($lineHeight * $index * -1);
if ($index % 2 === 0) {
// Striped background line
$lineQuad = new Quad_BgsPlayerCard();
2017-03-25 19:15:50 +01:00
$mapFrame->addChild($lineQuad);
$lineQuad->setX($innerWidth / 2);
$lineQuad->setZ(-1);
$lineQuad->setSize($width, $lineHeight);
$lineQuad->setSubStyle($lineQuad::SUBSTYLE_BgPlayerCardBig);
}
// File name Label
$nameLabel = new Label_Text();
2017-03-25 19:15:50 +01:00
$mapFrame->addChild($nameLabel);
$nameLabel->setX(2);
$nameLabel->setSize($innerWidth - 20, $lineHeight);
$nameLabel->setHorizontalAlign($nameLabel::LEFT);
$nameLabel->setStyle($nameLabel::STYLE_TextCardRaceRank);
$nameLabel->setTextSize(1);
$nameLabel->setText($fileName);
if (substr($fileName, -1) === DIRECTORY_SEPARATOR) $nameLabel->setTextPrefix(' ');
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);
} 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 12:50:26 +02:00
if ($canAddMaps) {
// 'Add' button
$addButton = new Quad_UIConstructionBullet_Buttons();
2017-03-25 19:15:50 +01:00
$mapFrame->addChild($addButton);
$addButton->setX($width - 5);
$addButton->setSize(4, 4);
$addButton->setSubStyle($addButton::SUBSTYLE_NewBullet);
$addButton->setAction(self::ACTION_ADD_FILE . $fileName);
$addButton->addTooltipLabelFeature($tooltipLabel, 'Add map ' . $fileName);
}
2014-07-05 12:50:26 +02:00
if ($canEraseMaps) {
// 'Erase' button
$eraseButton = new Quad_UIConstruction_Buttons();
2017-03-25 19:15:50 +01:00
$mapFrame->addChild($eraseButton);
$eraseButton->setX($width - 10);
$eraseButton->setSize(4, 4);
$eraseButton->setSubStyle($eraseButton::SUBSTYLE_Erase);
$eraseButton->setAction(self::ACTION_ERASE_FILE . $fileName);
$eraseButton->addTooltipLabelFeature($tooltipLabel, 'Erase file ' . $fileName);
}
}
$index++;
}
}
} else {
$errorLabel = new Label();
$repositionnedFrame->addChild($errorLabel);
$errorLabel->setPosition($innerWidth * 0.5, $innerHeigth * -0.5);
$errorLabel->setTextColor('f30');
$errorLabel->setText('No access to the directory.');
$errorLabel->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) {
if (FileUtil::isHiddenFile($fileName)) {
2014-06-30 00:57:29 +02:00
continue;
}
$fullFileName = $directory . $fileName;
if (!is_readable($fullFileName)) {
continue;
}
2014-06-30 00:57:29 +02:00
if (is_dir($fullFileName)) {
$mapFiles[$fullFileName . DIRECTORY_SEPARATOR] = $fileName . DIRECTORY_SEPARATOR;
continue;
2014-06-30 00:18:57 +02:00
} else {
if ($this->isMapFileName($fileName)) {
$mapFiles[$fullFileName] = $fileName;
2014-06-30 00:18:57 +02:00
}
}
}
uasort($mapFiles, function ($a, $b) {
$aIsDir = (substr($a, -1) === DIRECTORY_SEPARATOR);
$bIsDir = (substr($b, -1) === DIRECTORY_SEPARATOR);
if ($aIsDir && !$bIsDir) return -1;
else if (!$aIsDir && $bIsDir) return 1;
return 0;
});
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);
}
/**
* 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, '..');
}
/**
* Handle 'OpenFolder' page action
*
* @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);
}
/**
* 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;
}
//Update MX Data and ID
$this->maniaControl->getMapManager()->getMXManager()->fetchManiaExchangeMapInformation($map);
$map->lastUpdate = time();
//Update Map Timestamp in Database
$this->maniaControl->getMapManager()->updateMapTimestamp($map->uid);
2014-07-05 13:58:35 +02:00
// Message
$message = $this->maniaControl->getChat()->formatMessage(
'%s added %s!',
$player,
$map
);
2014-08-13 11:05:52 +02:00
$this->maniaControl->getChat()->sendSuccess($message);
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);
}
/**
* 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)) {
$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 {
$message = $this->maniaControl->getChat()->formatMessage(
'Could not erase %s!',
$fileName
);
$this->maniaControl->getChat()->sendError($message, $player);
2014-07-05 14:05:23 +02:00
}
}
/**
* Handle 'CreateFolder' page action
*
* @param array $actionCallback
* @param Player $player
*/
public function handleCreateFolder(array $actionCallback, Player $player) {
$name = trim($actionCallback[1][3][0]["Value"]);
var_dump($actionCallback);
if ($name === "") return;
$folderPath = $player->getCache($this, self::CACHE_FOLDER_PATH);
if (mkdir($folderPath . $name, 755, true)) {
$message = "Successfully created directory ". $name;
$this->maniaControl->getChat()->sendSuccess($message, $player);
Logger::log($message . " by " . $player->nickname);
$this->showManiaLink($player, $name);
} else {
$message = "Failed to create directory ". $name;
$this->maniaControl->getChat()->sendError($message, $player);
Logger::logError($message . " by " . $player->nickname);
$this->showManiaLink($player);
}
}
/**
* Handle 'handleDownloadFile' page action
*
* @param array $actionCallback
* @param Player $player
*/
public function handleDownloadFile(array $actionCallback, Player $player) {
$url = trim($actionCallback[1][3][1]["Value"]);
if ($url === "") return;
$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 = "";
$finfo = new finfo(FILEINFO_MIME_TYPE);
if ($finfo->buffer($file) === "application/zip") {
$zip = new ZipArchive();
// Create a temporary file
$tempFile = tempnam(sys_get_temp_dir(), 'zip');
file_put_contents($tempFile, $file);
$open = $zip->open($tempFile);
if ($open === true) {
$zip->extractTo($folderPath);
$zip->close();
$message = "Succesfully extracted zip archive from ". $url;
$this->maniaControl->getChat()->sendSuccess($message, $player);
Logger::log($message . " by " . $player->nickname);
} else {
$message = "Cannot extract archive from ". $url;
$this->maniaControl->getChat()->sendError($message, $player);
Logger::logError($message . " by " . $player->nickname);
}
// Clean up the temporary file
unlink($tempFile);
} else {
$fileName = "";
$contentdispositionheader = "";
foreach ($headers as $key => $value) {
if (strtolower($key) === "content-disposition") {
$contentdispositionheader = urldecode($value);
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(strtolower($fileName), "utf-8''") === 0 && $fileName = substr($fileName, strlen("utf-8''"))) {
$filePath = $folderPath . FileUtil::getClearedFileName(rawurldecode($fileName));
}
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
$fileName = basename($path);
if (!$this->isMapFileName($fileName)) {
$fileName .= ".Map.Gbx";
}
$filePath = $folderPath . $fileName;
}
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 = "Failed to write file " . $filePath;
$this->maniaControl->getChat()->sendError($message, $player);
Logger::logError($message . " by " . $player->nickname);
return;
}
$message = "Succesfully downloaded the map ". $fileName;
$this->maniaControl->getChat()->sendSuccess($message, $player);
Logger::log($message . " by " . $player->nickname);
}
}
$this->showManiaLink($player);
});
$asyncHttpRequest->getData();
}
}
2014-06-29 23:51:01 +02:00
}