Add support of Zip archive + Create folder button

This commit is contained in:
Beu 2024-07-14 16:02:48 +02:00
parent 40c33de0c8
commit 39db992394

View File

@ -2,6 +2,8 @@
namespace ManiaControl\Maps; namespace ManiaControl\Maps;
use finfo;
use ZipArchive;
use FML\Controls\Frame; use FML\Controls\Frame;
use FML\Controls\Label; use FML\Controls\Label;
use FML\Controls\Entry; use FML\Controls\Entry;
@ -42,6 +44,7 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
const ACTION_INSPECT_FILE = 'MapsDirBrowser.InspectFile.'; const ACTION_INSPECT_FILE = 'MapsDirBrowser.InspectFile.';
const ACTION_ADD_FILE = 'MapsDirBrowser.AddFile.'; const ACTION_ADD_FILE = 'MapsDirBrowser.AddFile.';
const ACTION_ERASE_FILE = 'MapsDirBrowser.EraseFile.'; const ACTION_ERASE_FILE = 'MapsDirBrowser.EraseFile.';
const ACTION_CREATE_FOLDER = 'MapsDirBrowser.CreateFolder';
const ACTION_DOWNLOAD_FILE = 'MapsDirBrowser.DownloadFile'; const ACTION_DOWNLOAD_FILE = 'MapsDirBrowser.DownloadFile';
const WIDGET_NAME = 'MapsDirBrowser.Widget'; const WIDGET_NAME = 'MapsDirBrowser.Widget';
const CACHE_FOLDER_PATH = 'FolderPath'; const CACHE_FOLDER_PATH = 'FolderPath';
@ -68,6 +71,7 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener($this->buildActionRegex(self::ACTION_INSPECT_FILE), $this, 'handleInspectFile'); $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_ADD_FILE), $this, 'handleAddFile');
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener($this->buildActionRegex(self::ACTION_ERASE_FILE), $this, 'handleEraseFile'); $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'); $this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener($this->buildActionRegex(self::ACTION_DOWNLOAD_FILE), $this, 'handleDownloadFile');
} }
@ -140,7 +144,7 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
$height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight(); $height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight();
$innerWidth = $width - 2; $innerWidth = $width - 2;
$innerHeigth = $height - 22; $innerHeigth = $height - 27;
$lineHeight = 4.; $lineHeight = 4.;
@ -181,12 +185,12 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
$tooltipLabel = new Label(); $tooltipLabel = new Label();
$repositionnedFrame->addChild($tooltipLabel); $repositionnedFrame->addChild($tooltipLabel);
$tooltipLabel->setPosition(3, $height * -1 + 10); $tooltipLabel->setPosition(3, $height * -1 + 15);
$tooltipLabel->setSize($width * 0.8, 5); $tooltipLabel->setSize($width * 0.8, 5);
$tooltipLabel->setHorizontalAlign($tooltipLabel::LEFT); $tooltipLabel->setHorizontalAlign($tooltipLabel::LEFT);
$tooltipLabel->setTextSize(1); $tooltipLabel->setTextSize(1);
// Download button // Back button
$backButton = new Label_Button(); $backButton = new Label_Button();
$repositionnedFrame->addChild($backButton); $repositionnedFrame->addChild($backButton);
$backButton->setStyle($backButton::STYLE_CardMain_Quit); $backButton->setStyle($backButton::STYLE_CardMain_Quit);
@ -194,23 +198,59 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
$backButton->setScale(0.5); $backButton->setScale(0.5);
$backButton->setText('Back'); $backButton->setText('Back');
$backButton->setPosition(3, $height * -1 + 5); $backButton->setPosition(3, $height * -1 + 5);
$backButton->setSize(5, 10);
$backButton->setAction(MapCommands::ACTION_OPEN_MAPLIST); $backButton->setAction(MapCommands::ACTION_OPEN_MAPLIST);
// Create folder button
$label = new Label_Text(); $label = new Label_Text();
$repositionnedFrame->addChild($label); $repositionnedFrame->addChild($label);
$label->setPosition(25, $height * -1 + 5); $label->setPosition(54, $height * -1 + 10);
$label->setSize(25, 5);
$label->setHorizontalAlign($label::LEFT); $label->setHorizontalAlign($label::LEFT);
$label->setTextSize(1); $label->setTextSize(1);
$label->setText('Download from URL: '); $label->setText('Create folder: ');
$label->setAreaFocusColor("00000000");
$label->setAreaColor("00000000");
$entry = new Entry(); $entry = new Entry();
$repositionnedFrame->addChild($entry); $repositionnedFrame->addChild($entry);
$entry->setStyle(Label_Text::STYLE_TextValueSmall); $entry->setStyle(Label_Text::STYLE_TextValueSmall);
$entry->setHorizontalAlign($entry::LEFT); $entry->setHorizontalAlign($entry::LEFT);
$entry->setPosition(53, $height * -1 + 5); $entry->setPosition(72, $height * -1 + 10);
$entry->setTextSize(1); $entry->setTextSize(1);
$entry->setSize($width * 0.35, 4); $entry->setSize(50, 4);
$entry->setName("Value"); $entry->setName("Name");
//Search for Map-Name
$createFolderButton = $this->maniaControl->getManialinkManager()->getElementBuilder()->buildRoundTextButton(
'Create',
18,
5,
self::ACTION_CREATE_FOLDER
);
$repositionnedFrame->addChild($createFolderButton);
$createFolderButton->setPosition(123 + 18/2, $height * -1 + 10);
// Download button
$label = new Label_Text();
$repositionnedFrame->addChild($label);
$label->setPosition(45, $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);
$entry->setPosition(72, $height * -1 + 5);
$entry->setTextSize(1);
$entry->setSize(50, 4);
$entry->setName("URL");
//Search for Map-Name //Search for Map-Name
$downloadButton = $this->maniaControl->getManialinkManager()->getElementBuilder()->buildRoundTextButton( $downloadButton = $this->maniaControl->getManialinkManager()->getElementBuilder()->buildRoundTextButton(
@ -220,7 +260,7 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
self::ACTION_DOWNLOAD_FILE self::ACTION_DOWNLOAD_FILE
); );
$repositionnedFrame->addChild($downloadButton); $repositionnedFrame->addChild($downloadButton);
$downloadButton->setPosition(53 + 18 / 2 + $width * 0.35, $height * -1 + 5); $downloadButton->setPosition(123 + 18/2, $height * -1 + 5);
$mapFiles = $this->scanMapFiles($folderPath); $mapFiles = $this->scanMapFiles($folderPath);
@ -508,7 +548,33 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
} }
} }
/**
* 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 * Handle 'handleDownloadFile' page action
@ -517,7 +583,8 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
* @param Player $player * @param Player $player
*/ */
public function handleDownloadFile(array $actionCallback, Player $player) { public function handleDownloadFile(array $actionCallback, Player $player) {
$url = trim($actionCallback[1][3][0]["Value"]); $url = trim($actionCallback[1][3][1]["Value"]);
if ($url === "") return;
$folderPath = $player->getCache($this, self::CACHE_FOLDER_PATH); $folderPath = $player->getCache($this, self::CACHE_FOLDER_PATH);
if (filter_var($url, FILTER_VALIDATE_URL)) { if (filter_var($url, FILTER_VALIDATE_URL)) {
@ -531,6 +598,32 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
} }
$filePath = ""; $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 = ""; $contentdispositionheader = "";
foreach ($headers as $key => $value) { foreach ($headers as $key => $value) {
if (strtolower($key) === "content-disposition") { if (strtolower($key) === "content-disposition") {
@ -564,26 +657,26 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
$isUtf8 = false; $isUtf8 = false;
foreach ($attrNames as $attrName => $utf8) { foreach ($attrNames as $attrName => $utf8) {
if (!empty($attributes[$attrName])) { if (!empty($attributes[$attrName])) {
$filename = trim($attributes[$attrName]); $fileName = trim($attributes[$attrName]);
$isUtf8 = $utf8; $isUtf8 = $utf8;
break; break;
} }
} }
if ($filename !== null) { if ($fileName !== null) {
if ($isUtf8 && strpos(strtolower($filename), "utf-8''") === 0 && $filename = substr($filename, strlen("utf-8''"))) { if ($isUtf8 && strpos(strtolower($fileName), "utf-8''") === 0 && $fileName = substr($fileName, strlen("utf-8''"))) {
$filePath = $folderPath . FileUtil::getClearedFileName(rawurldecode($filename)); $filePath = $folderPath . FileUtil::getClearedFileName(rawurldecode($fileName));
} }
if (substr($filename, 0, 1) === '"' && substr($filename, -1, 1) === '"') { if (substr($fileName, 0, 1) === '"' && substr($fileName, -1, 1) === '"') {
$filePath = $folderPath . substr($filename, 1, -1); $filePath = $folderPath . substr($fileName, 1, -1);
} else { } else {
$filePath = $folderPath . $filename; $filePath = $folderPath . $fileName;
} }
} }
} }
if (!$this->isMapFileName($filePath)) { if (!$this->isMapFileName($filePath)) {
$message = "File is not a map: " . $filename; $message = "File is not a map: " . $fileName;
$this->maniaControl->getChat()->sendError($message, $player); $this->maniaControl->getChat()->sendError($message, $player);
Logger::logError($message); Logger::logError($message);
return; return;
@ -592,11 +685,12 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
$path = parse_url($url, PHP_URL_PATH); $path = parse_url($url, PHP_URL_PATH);
// extracted basename // extracted basename
$filePath = $folderPath . basename($path); $fileName = basename($path);
if (!$this->isMapFileName($filePath)) { if (!$this->isMapFileName($fileName)) {
$filePath .= ".Map.Gbx"; $fileName .= ".Map.Gbx";
} }
$filePath = $folderPath . $fileName;
} }
if ($filePath != "") { if ($filePath != "") {
@ -609,13 +703,19 @@ class DirectoryBrowser implements ManialinkPageAnswerListener {
} }
$bytes = file_put_contents($filePath, $file); $bytes = file_put_contents($filePath, $file);
if (!$bytes || $bytes <= 0) { if (!$bytes || $bytes <= 0) {
$message = "Impossible to determine filename"; $message = "Failed to write file " . $filePath;
$this->maniaControl->getChat()->sendError($message, $player); $this->maniaControl->getChat()->sendError($message, $player);
Logger::logError($message); Logger::logError($message . " by " . $player->nickname);
return; return;
} }
$message = "Succesfully downloaded the map ". $fileName;
$this->maniaControl->getChat()->sendSuccess($message, $player);
Logger::log($message . " by " . $player->nickname);
} }
$this->showManiaLink($player, $folderPath); }
$this->showManiaLink($player);
}); });
$asyncHttpRequest->getData(); $asyncHttpRequest->getData();