public function build()
    {
        $file = getTmpFile("phar");
        $phar = new \Phar($file);
        $phar->setStub("<?php __HALT_COMPILER(); ?>");
        $phar->setSignatureAlgorithm(\Phar::SHA1);
        $phar->startBuffering();
        $namespace = "_{$this->name}" . randomClass(8, "\\_");
        $class = randomClass(8);
        $main = "{$namespace}\\{$class}";
        $manifest = ["name" => $this->name, "version" => $this->version, "authors" => $this->authors, "api" => "1.9.0", "main" => $main, "commands" => []];
        foreach ($this->cmds as $cmd) {
            $manifest["commands"][$cmd->name] = ["description" => $cmd->desc, "usage" => $cmd->usage];
        }
        $phar->addFromString("plugin.yml", yaml_emit($manifest));
        $mainClass = <<<EOS
<?php
namespace {$namespace};
use pocketmine\\command as cmd;
use pocketmine\\event as evt;
class {$class} extends \\pocketmine\\plugin\\PluginBase implements evt\\Listener{
public function onCommand(cmd\\CommandSender \$sender, cmd\\Command\\ \$cmd, \$lbl, array \$args){
switch(\$cmd->getName()){
EOS;
        foreach ($this->cmds as $cmd) {
            $mainClass .= "case " . var_export($cmd->name, true) . ":" . PHP_EOL;
            $mainClass .= "return \$this->onCommand_{$cmd->name}(\$args, \$sender);" . PHP_EOL;
        }
        $mainClass .= "}" . PHP_EOL . "return false;" . PHP_EOL . "}" . PHP_EOL;
        foreach ($this->cmds as $cmd) {
            $mainClass .= $cmd->executor->toPhp();
        }
        $mainClass .= "}";
        $phar->addFromString("src/" . str_replace("\\", "/", $main) . ".php", $mainClass);
        //		$phar->compressFiles(\Phar::GZ);
        $phar->stopBuffering();
        $path = $phar->getPath();
        header("Content-Type: application/octet-stream");
        echo file_get_contents($path);
        //		unlink($path);
    }
function unphar_toZip($tmpName, &$result, $name = "")
{
    $result = ["tmpDir" => null, "zipPath" => null, "zipRelativePath" => null, "basename" => null, "error" => false];
    rename($tmpName, "{$tmpName}.phar");
    $tmpName .= ".phar";
    try {
        $phar = new Phar($tmpName);
        $result["tmpDir"] = $tmpDir = getTmpDir();
        $pharPath = "phar://{$phar->getPath()}/";
        foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($pharPath)) as $f) {
            $subpath = substr($f, strlen($pharPath));
            @mkdir(dirname($realSubpath = $tmpDir . $subpath), 0777, true);
            copy($f, $realSubpath);
        }
        $zip = new ZipArchive();
        $dir = "/data/phars/";
        while (is_file($file = htdocs . ($rel = $dir . randomClass(16, "zip_" . $name . "_") . ".zip"))) {
        }
        $result["zipPath"] = $file;
        $result["zipRelativePath"] = $rel;
        $result["basename"] = substr($rel, 12);
        $err = $zip->open($file, ZipArchive::CREATE);
        if ($err !== true) {
            $msg = "Error creating zip file: ";
            switch ($err) {
                case ZipArchive::ER_EXISTS:
                    $msg .= "ER_EXISTS ({$err}) File already exists ({$file})";
                    break;
                case ZipArchive::ER_INCONS:
                    $msg .= "ER_INCONS ({$err}) Zip archive inconsistent.";
                    break;
                case ZipArchive::ER_INVAL:
                    $msg .= "ER_INVAL ({$err}) Invalid argument.";
                    break;
                case ZipArchive::ER_MEMORY:
                    $msg .= "ER_MEMORY ({$err}) Malloc failure.";
                    break;
                case ZipArchive::ER_NOENT:
                    $msg .= "ER_NOENT ({$err}) No such file.";
                    break;
                case ZipArchive::ER_NOZIP:
                    $msg .= "ER_NOZIP ({$err}) Not a zip archive.";
                    break;
                case ZipArchive::ER_OPEN:
                    $msg .= "ER_OPEN ({$err}) Can't open file.";
                    break;
                case ZipArchive::ER_READ:
                    $msg .= "ER_READ ({$err}) Read error.";
                    break;
                case ZipArchive::ER_SEEK:
                    $msg .= "ER_SEEK ({$err}) Seek error.";
            }
            throw new RuntimeException($msg . " Dump: " . var_export($result, true));
        }
        $tmpDir = realpath($tmpDir);
        foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($tmpDir)) as $file) {
            if (!is_file($file)) {
                continue;
            }
            $file = realpath($file);
            $rel = substr($file, strlen($tmpDir) + 1);
            $zip->addFile($file, str_replace("\\", "/", $rel));
        }
        $zip->setArchiveComment(json_encode($phar->getMetadata(), JSON_PRETTY_PRINT));
        $zip->close();
    } catch (Exception $e) {
        echo "<pre>";
        echo get_class($e) . ": {$e->getMessage()}";
        echo "\r\n\tat {$e->getFile()}:{$e->getLine()}</pre>";
        $result["error"] = true;
    }
}