
<?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�`›	  5°¯Q¶      
   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  Ã  ÃÇo¨d  	0IDATx^íœ;¶Ô8†;$$$œŒm@Öç�²ƒY!K dI,¡Ã™ºþ[§ºô´ü�í«:_pQ•e¹~=,µg.ÿÞÞ:2èÌ 3C€ÎìT€?þüó°_¿~9×ÉØ© HýåaoÞ¼q®“±S~üø!Àð·óž‰ý®ß¿Î=ö+Àý~GêEç:“ŸmËåQ&¢oß¾¹ò31Y€×³<nÃdìòè\ƒZ’øf†Í½¸3C€Î:3èL£ Ø|øðáô'eÐ(À»wïð"4¶óià±øß\ùâœ~¨í] jgÕ %ƒè•’}˜s-ŽžÇ�uºkÉ ôJ1çZœÓŸ|´<ó±Õio6P˜�­2Â›æc°C€Î:3èÌ8ônùz·¼® ò	£Ÿå?þtñQxAúv‡Þ-¯( úãÛ·oš¶â.ŒKßÎî–3zïs|¬% z7ƒ*,ßs”½#²†»TŽ¹-YE Ì<¶ï‡'÷ûýë×¯t?ÌX1[ 1wm_VÀžÖ!×ÎkÑé;“	€¹r#êmç¨½­«@wÅi]Í¸ såF<Ì¹û¥é®Áº¸òä…¡—Kj‘¤{ž `ŸŸ[w hÇLåE¼0WnaÄÃœK±b;WGZšÂ‡XH ;A;—@_¶6F”&=Z û~é\
ÝÕÏÉè%påU7lžšRs¨¢o8_¾|q.E`•{F—ÈÔÆˆ£ ‡*¶Ð! Ë¼_§uKñ'þšÚ$ æÊÚ­ l]¶}ŒÈÆ§uÅmÙœW¨©�îÒíT
Û’§¦°uéö{«Â ì¼QÜ0+ŒÔ�’™7�÷ðÈlæÛÝG@³v»Ýl¹"^Xq‹kç=‰Œ¦V¬�qó6k€A»@÷Š°èù-}u rŠ¡Âèét1û 3žñÂ\¹ƒA» /6×ë•m|1ÛYT÷ v„V“we‘Í`Ðn ÐÀGÍ]•!”ÁTÂ‹—ëÁíœË"10WÞ‘xSì¼‚VØp­ )vå‚=h«Ù ¸òŽš*ÑœÁ™HKRwGÒ±3G †¯sYò•taG}a>ÿþu%ûçT‘!@g† �tfÐ™!@g† �Y]€ð4zÌ÷jY] û‚³�•�®P¼)Â¶ü¯V€ÉNXêx9ÊÌÔ õzÓL%5?Œ/ÈvÈ?ÃÃ%”hpž™©±·ÎTÂˆËÅMžÅ¡ÓÆºd>"ª<¿´H<Ì•×c5He“îË%úóÑâ2¬+€. áGD•ç—©
æÊ'½¥’Ô Ð€”!`AÖ€MND4éü’uÍ@AêPÚþ.“07s.¨ÁF¸ò6´oºecÙ÷ô¹‹˜uU®"“8’ ÑïË‘}™¬—Ê�»ˆ9—ÕÀõƒ6Ž$€í›R¢ÙÓÈ™°ºÄ4íÍl$Àb3æ‹É?í.oÁYcBQôƒÔdØÀºhCñÇ"Hm0ümßq—ý™—•¦‡Ô‚ƒ`]_µX×cHéä“ùP>JqÑ–ja®\	'ÃfÖ XæïbXÑ³¥ÞqSwÔR-Ì•[±€}³ž9±c?~t1Exe:wtg“‹‘˜™ËÀ ‡Ú¯íÐôæÿb�U<LRÐ ¨\så
ÝY–Z¶@°s,õvÌÝ¼ø±êj„MšÜxÍ<–Z¶ 8¦.	ˆç•�gvµÕ÷D^�Hœ•Ù¹:�  Ç~€=i±K`•Š2:‘8»·p.ƒŽ% —��×<?³]äaE—H}{ÆN !ìÎ5ð‚çKœ¢°üÀbPI WÂ¸ƒ
 ØüÙá’�Ò€C 6!+Cjr£û•Pÿ²aáÙÓ=Õ 5‰C	@¤sqÁ\yãŽ(@ó1²æ.Õ»kÈï¡Äså!Œ;œ .û“2Û–nG~EÇ¡@Ší¦)cÇÈ¼ræc¿˜+tZ€õ²trå“�`®Ð1E€šÝ_ŠUpo„QkË>�Ê›/¤0Wè¨`‘iö�$æÊAý[dAz¥d²<i„ÍŽ¯T€Eæ±Ex¥ì‡!@g† �tfÐ™!@g† UÈélÎ©C”½�:¿k{æ°¶T=ˆ¬ùoô—úðÔ!òXlÿ.À3ØêÐ*eÈç¹+)~¦2_[®–z„]`¿IY>G �WÌEX	JÄ…½±s)Ú¼ð+àš–«E{@2ýËžvå�l%jz‰­Ç¥ ø…áív“ Øýù+àâ÷ñö¾bá]ú�é_õØ™'šíé.ù_ÇlŠ3Ý¿Ør«„jý`»¦en‘~úùóçT%6ÎÅÒ˜ šâëõÖ,.XMËSCmG¸ò©ÿ‹WÞ&¸‘×7m÷�¦˜¾º–ÿþý›ÑÏñýÐçoø^zr˜+�öMûz�a Þ³õôÀ~ÙYùºÙï€Þûzíþ“Þ¬¹%ª¿ x<÷?¬†þ.l>¬=6c„ƒ@þ	K½}Ñ=ÑÂÚú  �ûºÖÙ"#ƒuÅ@è{yOå?bÁÝé€Jv!€`_T¢V#ƒÝÛx;ek°Eg!ò7ÌÆXè>“ B~4Øu2$z0 2Ø)Û]%Xùíû�Sèž÷QØ� !nd8¯%µ0jï†¥æt`�ü‘ÙaÙ`çšÄäia®ÜÂˆG–Sš»ÄbßÇÄ¢ï?‚­;o=Ç fN Œ01¶ï‹©+Ä.Åb.Àaß�š'¢PÜ)Óé§Ÿ>}’r˜º¢0èÅœ×Á¬Àm¯j{À­«™90(H\qVlB‹GlÀMt¸|êf¿ØJ±Ìú)0.È2K+j°	Í‹­8`hv½�@–Ã_ÃÔÃŠ¹ÚÝª(…0[˜‚¡—ÖPµüÔÔY€Ê•šìƒð5ÆYÍ4­*âçÊƒ“ÙÁ¤nÝY ;çF­2õ‚[£VL«öåëõê\5ddˆÞº³ ™‘;)õJ¦B±¶j›±í‰Þº³ ƒ!@g† �tfÐ™!@Wnïÿ ÀJ¶ŸÁ    IEND®B`‚---
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