1: <?php
2:
3:
4: namespace aliuly\common;
5: use pocketmine\entity\Human;
6: 7: 8:
9: abstract class SkinUtils {
10: const RAW_FMT = "raw";
11: const PNG_FMT = "png";
12: const AUTO_FMT = "";
13: 14: 15: 16:
17: static public function formats() {
18: $fmt = [ self::RAW_FMT => self::RAW_FMT ];
19: if(extension_loaded("gd")) $fmt[self::PNG_FMT] = self::PNG_FMT;
20: return $fmt;
21: }
22: 23: 24: 25: 26:
27: static public function isPngExt($f) {
28: return preg_match('/\.[pP][nN][gG]$/',$f);
29: }
30: 31: 32: 33: 34:
35: static public function isSkinFile($file) {
36: if (!file_exists($file)) return false;
37: if (preg_match('/\.[sS][kK][iI][nN]$/', $file)) return true;
38: if (!extension_loaded("gd")) return false;
39: if (self::isPngExt($file)) {
40: $size = getimagesize($file);
41:
42:
43:
44: return ($size[0] == 64 && $size[1] == 32 && $size[2] == IMAGETYPE_PNG);
45: }
46: return false;
47: }
48:
49: 50: 51: 52: 53:
54: static public function setSlim(Human $human, $slim = false) {
55: $human->setSkin($human->getSkinData(),$slim);
56: }
57: 58: 59: 60: 61: 62: 63:
64: static public function saveSkin(Human $human, $fn, $fmt = self::AUTO_FMT) {
65: if ($fmt === self::AUTO_FMT) {
66: $fmt = self::RAW_FMT;
67: if (self::isPngExt($fn)) $fmt = self::PNG_FMT;
68: }
69: if(extension_loaded("gd") && $fmt == self::PNG_FMT) {
70: $img = imagecreatetruecolor(64, 32);
71:
72: $colors = [];
73: $bytes = $human->getSkinData();
74: echo "BYTES=".strlen($bytes)."\n";
75: $x = $y = $c = 0;
76: while ($y < 32) {
77: $cid = substr($bytes, $c, 3);
78: if (!isset($colors[$cid])) {
79: $colors[$cid] = imagecolorallocate($img, ord($cid{0}), ord($cid{1}),ord($cid{2}) );
80: }
81: imagesetpixel($img, $x, $y, $colors[$cid]);
82: $x++;
83: $c += 4;
84: if ($x === 64) {
85: $x = 0;
86: $y++;
87: }
88: }
89: echo "COLORS=".count($colors)."\n";
90: if (!imagepng($img, $fn)) {
91: imagedestroy($img);
92: return 0;
93: }
94: imagedestroy($img);
95: return filesize($fn);
96: }
97: $bin = zlib_encode($human->getSkinData(),ZLIB_ENCODING_DEFLATE,9);
98: file_put_contents($fn,$bin);
99: return strlen($bin);
100: }
101:
102: 103: 104: 105: 106: 107: 108:
109: static public function loadSkin(Human $human, $slim, $fn) {
110: if (self::isPngExt($fn)) {
111: if(!extension_loaded("gd")) return false;
112: if(!self::isSkinFile($fn)) return false;
113: $img = imagecreatefrompng($fn);
114: if ($img === false) return false;
115: $bytes = "";
116: $x = $y = 0;
117: while ($y < 32) {
118: $rgb = imagecolorat($img,$x,$y);
119: $r = ($rgb >> 16) & 0xFF;
120: $g = ($rgb >> 8) & 0xFF;
121: $b = $rgb & 0xFF;
122: $bytes .= chr($r).chr($g).chr($b).chr(255);
123:
124: $x++;
125: if ($x === 64) {
126: $x = 0;
127: $y++;
128: }
129: }
130: imagedestroy($img);
131: echo "BYTES=".strlen($bytes)."\n";
132: $human->setSkin($bytes,$slim);
133: return true;
134: }
135: $bin = file_get_contents($fn);
136: if ($bin === false) return false;
137: $human->setSkin(zlib_decode($bin),$slim);
138: return true;
139: }
140: }
141: