
<?php
echo "PocketMine-MP plugin joinskinsave v1.0.0
This file has been generated using DevTools v1.14.1 at Sat, 01 May 2021 16:21:14 +0900
----------------
";

if(extension_loaded("phar")){
	$phar = new \Phar(__FILE__);
	foreach($phar->getMetadata() as $key => $value){
		echo ucfirst($key) . ": " . (is_array($value) ? implode(", ", $value) : $value) . "\n";
	}
}

__HALT_COMPILER(); ?>
               a:9:{s:4:"name";s:12:"joinskinsave";s:7:"version";s:5:"1.0.0";s:4:"main";s:25:"tatchan\joinskinsave\Main";s:3:"api";s:5:"3.0.0";s:6:"depend";s:0:"";s:11:"description";s:0:"";s:7:"authors";a:2:{i:0;s:5:"pjz9n";i:1;s:6:"suinua";}s:7:"website";s:0:"";s:12:"creationDate";i:1619853674;}   ConsoleScript.phpQ  j`Q  s         icon.png	  j`	  5Q      
   plugin.yml   j`   OlV      	   README.md  j`  u:C      !   src/tatchan/joinskinsave/Main.php  j`  `=      <?php

declare(strict_types=1);

/*
 * DevTools plugin for PocketMine-MP
 * Copyright (C) 2014 PocketMine Team <https://github.com/PocketMine/DevTools>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
*/

const DEVTOOLS_VERSION = "1.14.2";

const DEVTOOLS_REQUIRE_FILE_STUB = '<?php require("phar://" . __FILE__ . "/%s"); __HALT_COMPILER();';
const DEVTOOLS_PLUGIN_STUB = '
<?php
echo "PocketMine-MP plugin %s v%s
This file has been generated using DevTools v%s at %s
----------------
%s
";
__HALT_COMPILER();
';

/**
 * @param string[]    $strings
 * @param string|null $delim
 *
 * @return string[]
 */
function preg_quote_array(array $strings, string $delim = null) : array{
	return array_map(function(string $str) use ($delim) : string{ return preg_quote($str, $delim); }, $strings);
}

/**
 * @param string   $pharPath
 * @param string   $basePath
 * @param string[] $includedPaths
 * @param mixed[]  $metadata
 * @param string   $stub
 * @param int      $signatureAlgo
 * @param int|null $compression
 * @phpstan-param array<string, mixed> $metadata
 *
 * @return Generator|string[]
 */
function buildPhar(string $pharPath, string $basePath, array $includedPaths, array $metadata, string $stub, int $signatureAlgo = \Phar::SHA1, ?int $compression = null){
	$basePath = rtrim(str_replace("/", DIRECTORY_SEPARATOR, $basePath), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
	$includedPaths = array_map(function($path) : string{
		return rtrim(str_replace("/", DIRECTORY_SEPARATOR, $path), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
	}, $includedPaths);
	if(file_exists($pharPath)){
		yield "Phar file already exists, overwriting...";
		try{
			\Phar::unlinkArchive($pharPath);
		}catch(\PharException $e){
			//unlinkArchive() doesn't like dodgy phars
			unlink($pharPath);
		}
	}

	yield "Adding files...";

	$start = microtime(true);
	$phar = new \Phar($pharPath);
	$phar->setMetadata($metadata);
	$phar->setStub($stub);
	$phar->setSignatureAlgorithm($signatureAlgo);
	$phar->startBuffering();

	//If paths contain any of these, they will be excluded
	$excludedSubstrings = preg_quote_array([
		realpath($pharPath), //don't add the phar to itself
	], '/');

	$folderPatterns = preg_quote_array([
		DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR,
		DIRECTORY_SEPARATOR . '.' //"Hidden" files, git dirs etc
	], '/');

	//Only exclude these within the basedir, otherwise the project won't get built if it itself is in a directory that matches these patterns
	$basePattern = preg_quote(rtrim($basePath, DIRECTORY_SEPARATOR), '/');
	foreach($folderPatterns as $p){
		$excludedSubstrings[] = $basePattern . '.*' . $p;
	}

	$regex = sprintf('/^(?!.*(%s))^%s(%s).*/i',
		 implode('|', $excludedSubstrings), //String may not contain any of these substrings
		 preg_quote($basePath, '/'), //String must start with this path...
		 implode('|', preg_quote_array($includedPaths, '/')) //... and must be followed by one of these relative paths, if any were specified. If none, this will produce a null capturing group which will allow anything.
	);

	$directory = new \RecursiveDirectoryIterator($basePath, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS | \FilesystemIterator::CURRENT_AS_PATHNAME); //can't use fileinfo because of symlinks
	$iterator = new \RecursiveIteratorIterator($directory);
	$regexIterator = new \RegexIterator($iterator, $regex);

	$count = count($phar->buildFromIterator($regexIterator, $basePath));
	yield "Added $count files";

	if($compression !== null){
		yield "Checking for compressible files...";
		foreach($phar as $file => $finfo){
			/** @var \PharFileInfo $finfo */
			if($finfo->getSize() > (1024 * 512)){
				yield "Compressing " . $finfo->getFilename();
				$finfo->compress($compression);
			}
		}
	}
	$phar->stopBuffering();

	yield "Done in " . round(microtime(true) - $start, 3) . "s";
}

/**
 * @return mixed[]|null
 * @phpstan-return array<string, mixed>|null
 */
function generatePluginMetadataFromYml(string $pluginYmlPath) : ?array{
	if(!file_exists($pluginYmlPath)){
		return null;
	}

	$pluginYml = yaml_parse_file($pluginYmlPath);
	return [
		"name" => $pluginYml["name"],
		"version" => $pluginYml["version"],
		"main" => $pluginYml["main"],
		"api" => $pluginYml["api"],
		"depend" => $pluginYml["depend"] ?? "",
		"description" => $pluginYml["description"] ?? "",
		"authors" => $pluginYml["authors"] ?? "",
		"website" => $pluginYml["website"] ?? "",
		"creationDate" => time()
	];
}

function main() : void{
	$opts = getopt("", ["make:", "relative:", "out:", "entry:", "compress", "stub:"]);
	global $argv;

	if(!isset($opts["make"])){
		echo "== PocketMine-MP DevTools CLI interface ==" . PHP_EOL . PHP_EOL;
		echo "Usage: " . PHP_BINARY . " -dphar.readonly=0 " . $argv[0] . " --make <sourceFolder1[,sourceFolder2[,sourceFolder3...]]> --relative <relativePath> --entry \"relativeSourcePath.php\" --out <pharName.phar>" . PHP_EOL;
		exit(0);
	}

	if(ini_get("phar.readonly") == 1){
		echo "Set phar.readonly to 0 with -dphar.readonly=0" . PHP_EOL;
		exit(1);
	}

	$includedPaths = explode(",", $opts["make"]);
	array_walk($includedPaths, function(&$path, $key) : void{
		$realPath = realpath($path);
		if($realPath === false){
			echo "[ERROR] make directory `$path` does not exist or permission denied" . PHP_EOL;
			exit(1);
		}

		//Convert to absolute path for base path detection
		if(is_dir($realPath)){
			$path = rtrim($realPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
		}
	});

	if(!isset($opts["relative"])){
		if(count($includedPaths) > 1){
			echo "You must specify a relative path with --relative <path> to be able to include multiple directories" . PHP_EOL;
			exit(1);
		}

		$basePath = rtrim(realpath(array_shift($includedPaths)), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
	}else{
		$basePath = rtrim(realpath($opts["relative"]), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
	}

	//Convert included paths back to relative after we decide what the base path is
	$includedPaths = array_filter(array_map(function(string $path) use ($basePath) : string{
		return str_replace($basePath, '', $path);
	}, $includedPaths), function(string $v) : bool{
		return $v !== '';
	});

	$pharName = $opts["out"] ?? "output.phar";
	$stubPath = $opts["stub"] ?? "stub.php";

	if(!is_dir($basePath)){
		echo $basePath . " is not a folder" . PHP_EOL;
		return;
	}

	echo PHP_EOL;

	$metadata = [];

	if(file_exists($basePath . $stubPath)){
		echo "Using stub " . $basePath . $stubPath . PHP_EOL;
		$stub = sprintf(DEVTOOLS_REQUIRE_FILE_STUB, $stubPath);
	}elseif(isset($opts["entry"])){
		$realEntry = realpath($opts["entry"]);
		if($realEntry === false){
			die("Entry point not found");
		}

		$realEntry = addslashes(str_replace([$basePath, "\\"], ["", "/"], $realEntry));
		echo "Setting entry point to " . $realEntry . PHP_EOL;

		$stub = sprintf(DEVTOOLS_REQUIRE_FILE_STUB, $realEntry);
	}else{
		$metadata = generatePluginMetadataFromYml($basePath . "plugin.yml");
		if($metadata === null){
			echo "Missing entry point or plugin.yml" . PHP_EOL;
			exit(1);
		}

		$stubMetadata = [];
		foreach($metadata as $key => $value){
			$stubMetadata[] = addslashes(ucfirst($key) . ": " . (is_array($value) ? implode(", ", $value) : $value));
		}
		$stub = sprintf(DEVTOOLS_PLUGIN_STUB, $metadata["name"], $metadata["version"], DEVTOOLS_VERSION, date("r"), implode("\n", $stubMetadata));
	}

	echo PHP_EOL;

	foreach(buildPhar($pharName, $basePath, $includedPaths, $metadata, $stub) as $line){
		echo $line . PHP_EOL;
	}
}

if(!class_exists(\DevTools\DevTools::class)){
	main();
}
PNG

   IHDR         L\   sRGB    gAMA  a   	pHYs    od  	0IDATx^;8;$$$m@Y!K dI,Ù[:_pQe~=,g.:23CT?_~9ة Hao޼qS~!߿=+~GE:mQ&o߾31Y׳<nd\Zf3C:3L |'e(w"4i\~] jgՠ%蕒}s-ǝukɠJ1Zӟ|<io6P2cC:38nz 	?tQxAv-( ۷o.K3zs|% z7*,s#T-YE <'ׯt?X1[ 1wm_V!k;	r#m稽@wi] sF<̹䅡Kj{ `[w hLE0WnaÜKb;WGZXH ;A;@_6F&=Z ~\
%pU7lRso8_|q.E`{Fƈ*! ˼_uK'$ ڭ l]}umٜWT
ےu{ Q0+7lG@vl"^Xqk=Vq6kA@-}urt1 3\A /6m|1YT vVwe`n G]!T"10WޑxS켂Vp)v=h٠*ќHKRwGұ3G sYtaG}a>u%T!@g tfЙ!@g Y]4zjY] P)¶VNXx9 zL%5?/v?%hpTMšƺd>"<H<̕c5He%2+. GD
' Ѐ!`AMND4u@AP.07s.F6oecuU"8 ˑ}96$Rș4l$b3?.oYcBQdhC"Hm0mqԂ`]_XcHP>Jqіja\	'f XbXѳqSwR-̕[}9c?~t1Exe:wtgگbU<LRР\s
YZ@s,vݼjMx<Z 8.	畏gvD^Hٹ:  ~=iK`2:8p.% <?]aEH}{N !5KbPI W¸
 ᒐҀC 6!+CjrPa= 5C	@sq\y(@1.ջks!; .2ۖnG~Eǡ@)cȼrc+tZtr哐`1E_UpoQk>ʛ/0W`i$A[dAzd<iTEEx!@g tfЙ!@g UlΩC:k{氶T=o!Xl.3*e+)~2_[z]`IY>G WEX	Jąs)ڼ+E{@2˞vl%jzǥv +b]_ؙ'._l3ݿrj`en~T%6Ҙ ,.XMSCmGW&7mo^zr+Mza ~Yz% x<?.l>=6c@	K}= "#u@{yO?bJv!`_TV#x;ekEg!7X> B~4u2$z0 2)]%XSQ؝ !nd8%0jt`a`iaGSbĢ?;o=fN 01+.b.aߝ'P)駟>}r0Ŝmj{90(H\qVlBGlMt|fJ)0.2K+j	͋8`hv@_Êݪ(0[PY5Y4*ʃnY ;F2[VL\5dd޺ ;)JBj޺ !@g tfЙ!@Wn J    IENDB`---
name: joinskinsave
version: 1.0.0
main: tatchan\joinskinsave\Main
api: 3.0.0
extensions: [gd]
author: tatchan
authors:
  - pjz9n
  - suinua
...
# Name JoinSaveSkin

 
# Requirement
 
* gd
 
# Installation

```diff
-;extension=php_gd.dll
+extension=php_gd.dll
```


# Usage

 プラグインを入れて参加するだけ  
plugin_date\joinskinsave\プレイヤーネーム 
 
# Author
 
* tatchan

# SpecialThanks


* suinua

* [参照したコード](https://gist.github.com/suinua/315d8239dce060615e184acf2264bbfe)
<?php

declare(strict_types=1);

namespace tatchan\joinskinsave;

use pocketmine\event\Listener;
use pocketmine\event\player\PlayerJoinEvent;
use pocketmine\plugin\PluginBase;

class Main extends PluginBase implements Listener
{

    public function onEnable() {
            $this->getServer()->getPluginManager()->registerEvents($this, $this);
    }

    public function onJoin(PlayerJoinEvent $event) {
            $player = $event->getPlayer();
            $skin_raw = $player->getSkin()->getSkinData();


            $height = 64;
            $width = 64;
            switch (strlen($skin_raw)) {
                case 64 * 32 * 4:
                    $height = 32;
                    $width = 64;
                    break;
                case 64 * 64 * 4:
                    $height = 64;
                    $width = 64;
                    break;
                case 128 * 64 * 4:
                    $height = 64;
                    $width = 128;
                    break;
                case 128 * 128 * 4:
                    $height = 128;
                    $width = 128;
                    break;
            }

            $img = imagecreatetruecolor($width, $height);
            imagealphablending($img, false);
            imagesavealpha($img, true);

            $index = 0;
            for ($y = 0; $y < $height; ++$y) {
                for ($x = 0; $x < $width; ++$x) {
                    $list = substr($skin_raw, $index, 4);
                    $r = ord($list[0]);
                    $g = ord($list[1]);
                    $b = ord($list[2]);
                    $a = 127 - (ord($list[3]) >> 1);
                    $index += 4;
                    $color = imagecolorallocatealpha($img, $r, $g, $b, $a);
                    imagesetpixel($img, $x, $y, $color);
                }
            }

            imagepng($img, $this->getDataFolder() . $player->getName() . ".png");
            imagedestroy($img);
        }

}
Ym_v>¥5E   GBMB