Skip to content

Instantly share code, notes, and snippets.

@xxAROX
Created July 14, 2022 16:29
Show Gist options
  • Save xxAROX/6cee587513c4b0b3d4c2a4fe8dd27cec to your computer and use it in GitHub Desktop.
Save xxAROX/6cee587513c4b0b3d4c2a4fe8dd27cec to your computer and use it in GitHub Desktop.
<?php
/*
* Copyright (c) Jan Sohn / xxAROX
* All rights reserved.
* I don't want anyone to use my source code without permission.
*/
namespace WorldCompiler;
use pocketmine\network\mcpe\compression\ZlibCompressor;
use pocketmine\plugin\PluginBase;
use pocketmine\plugin\PluginDescription;
use pocketmine\plugin\PluginLoader;
use pocketmine\plugin\ResourceProvider;
use pocketmine\scheduler\AsyncTask;
use pocketmine\Server;
use pocketmine\utils\SingletonTrait;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use ZipArchive;
/**
* @name WorldCompiler
* @version 1.0.0
* @api 4.0.0
* @author xxAROX
* @description This class is used to compile a world into a tiny file.
* @main WorldCompiler\WorldCompiler
*/
class WorldCompiler extends PluginBase{
use SingletonTrait{
setInstance as private;
reset as private;
}
public function __construct(PluginLoader $loader, Server $server, PluginDescription $description, string $dataFolder, string $file, ResourceProvider $resourceProvider){
self::setInstance($this);
parent::__construct($loader, $server, $description, $dataFolder, $file, $resourceProvider);
}
protected function onLoad(): void{
$this->startCompressing("Lobby-12");
}
private function startCompressing(string $world): void{
$this->getLogger()->info("Compressing world: " . $world);
$this->makeZip($this->getServer()->getDataPath() . "worlds/" . $world . "/", $this->getDataFolder() . $world . ".zip");
}
public function makeZip(string $target, string $output): void{
$this->getLogger()->info("Zipping world: " . $target);
$this->getServer()->getAsyncPool()->submitTask(new class($target, $output) extends AsyncTask{
protected string $target;
protected string $output;
public function __construct(string $target, string $output){
$this->target = str_replace("\\", "/", $target);
$this->output = str_replace("\\", "/", $output);
}
public function onRun(): void{
if ($this->zip($this->target, $this->output)) $this->setResult(null);
else $this->setResult("Could not zip world: " . $this->target);
}
public function onCompletion(): void{
$result = $this->getResult();
if ($result !== null) WorldCompiler::getInstance()->getLogger()->error($result);
else WorldCompiler::getInstance()->getLogger()->info("World zipped: " . $this->output);
WorldCompiler::getInstance()->compress($this->output);
}
private function zip($source, $destination): bool{
if (!extension_loaded('zip') || !file_exists($source)) return false;
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) return false;
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
$file = str_replace('\\', '/', $file);
// Ignore "." and ".." folders
if (in_array(substr($file, strrpos($file, '/') + 1), [ '.', '..' ])) continue;
$file = realpath($file);
if (is_dir($file) === true) $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
else if (is_file($file) === true) $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
else if (is_file($source) === true) {
$zip->addFromString(basename($source), file_get_contents($source));
}
return $zip->close();
}
});
}
public function compress(string $file): void{
$this->getServer()->getAsyncPool()->submitTask(new class($file) extends AsyncTask{
public function __construct(protected string $file){
$this->file = str_replace("\\", "/", $file);
}
public function onRun(): void{
$compressor = new ZlibCompressor(7, 256, 2 * 1024 * 1024);
$this->setResult($compressor->compress(file_get_contents($this->file)));
}
public function onCompletion(): void{
$result = $this->getResult();
if (!is_string($result)) WorldCompiler::getInstance()->getLogger()->error($result);
else WorldCompiler::getInstance()->getLogger()->info("World compressed: " . explode(".", $this->file)[0] . ".zlib");
file_put_contents(explode(".", $this->file)[0] . ".zlib", $result);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment