1
+ <?php
2
+
3
+ $ cacheFolder = 'cache ' ;
4
+ $ cacheTime = 60 * 60 * 24 ; # in seconds
5
+
6
+ # Request a users skin from the session servers
7
+ function fetchUrlByUUID ($ uuid ) {
8
+ $ res = file_get_contents ("https://sessionserver.mojang.com/session/minecraft/profile/ {$ uuid }" );
9
+ if ($ res === false || strpos ($ res , 'TooManyRequest ' ) !== FALSE ) { return false ; }
10
+ $ json = json_decode ($ res , true );
11
+ foreach ($ json ['properties ' ] as $ p ) {
12
+ if (strpos ($ p ['name ' ], 'textures ' ) !== FALSE ) { $ tex = $ p ['value ' ]; break ; }
13
+ }
14
+ if (!isset ($ tex )) { return false ; }
15
+ $ imgData = base64_decode ($ tex );
16
+ $ json = json_decode ($ imgData , true );
17
+ return $ json ['textures ' ]['SKIN ' ]['url ' ];
18
+ }
19
+
20
+ # Check base Minecraft Skin Urls, otherwise we need to do some digging for their skin
21
+ function getImageUrl ($ name ) {
22
+ $ url = "https://s3.amazonaws.com/MinecraftSkins/ {$ name }.png " ;
23
+ $ headers = get_headers ($ url , 1 );
24
+ if ($ headers [0 ] == 'HTTP/1.1 200 OK ' ) { return $ url ; }
25
+ $ post = "{ \"agent \": \"Minecraft \", \"name \": \"{$ name }\"} " ;
26
+ $ ch = curl_init ();
27
+ curl_setopt ($ ch , CURLOPT_URL , "https://api.mojang.com/profiles/page/1 " );
28
+ curl_setopt ($ ch , CURLOPT_RETURNTRANSFER , true );
29
+ curl_setopt ($ ch , CURLOPT_POST , 1 );
30
+ curl_setopt ($ ch , CURLOPT_POSTFIELDS , $ post );
31
+ curl_setopt ($ ch , CURLOPT_HTTPHEADER , array ('Content-type: application/json ' , 'Connection: Keep-Alive ' ));
32
+ $ res = str_replace (" " , "" , str_replace ("\r" , "" , str_replace ("\n" , "" , curl_exec ($ ch ))));
33
+ if ($ res === false || strpos ($ res , 'TooManyRequest ' ) !== FALSE ) { return false ; }
34
+ $ json = json_decode ($ res , true );
35
+ return fetchUrlByUUID ($ json ['profiles ' ][0 ]['id ' ]);
36
+ }
37
+
38
+ # returns default steve skin
39
+ function getDefaultImage () {
40
+ $ def = 'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAFDUlEQVR42u2a20sUURzH97G0LKMotPuWbVpslj1olJ ' ;
41
+ $ def .= 'XdjCgyisowsSjzgrB0gSKyC5UF1ZNQWEEQSBQ9dHsIe+zJ/+nXfM/sb/rN4ZwZ96LOrnPgyxzP/M7Z+X7OZc96JpE ' ;
42
+ $ def .= 'ISfWrFhK0YcU8knlozeJKunE4HahEqSc2nF6zSEkCgGCyb+82enyqybtCZQWAzdfVVFgBJJNJn1BWFgC49/VpwGVl ' ;
43
+ $ def .= 'D0CaxQiA5HSYEwBM5sMAdKTqygcAG9+8coHKY/XXAZhUNgDYuBSPjJL/GkzVVhAEU5tqK5XZ7cnFtHWtq/TahdSw2 ' ;
44
+ $ def .= 'l0HUisr1UKIWJQBAMehDuqiDdzndsP2EZECAG1ZXaWMwOCODdXqysLf++uXUGv9MhUHIByDOijjdiSAoH3ErANQD7 ' ;
45
+ $ def .= '3C7TXXuGOsFj1d4YH4OTJAEy8y9Hd0mCaeZ5z8dfp88zw1bVyiYhCLOg1ZeAqC0ybaDttHRGME1DhDeVWV26u17lR ' ;
46
+ $ def .= 'APr2+mj7dvULfHw2q65fhQRrLXKDfIxkau3ZMCTGIRR3URR5toU38HbaPiMwUcKfBAkoun09PzrbQ2KWD1JJaqswj ' ;
47
+ $ def .= 'deweoR93rirzyCMBCmIQizqoizZkm2H7iOgAcHrMHbbV9KijkUYv7qOn55sdc4fo250e+vUg4329/Xk6QB/6DtOws ' ;
48
+ $ def .= '+dHDGJRB3XRBve+XARt+4hIrAF4UAzbnrY0ve07QW8uHfB+0LzqanMM7qVb+3f69LJrD90/1axiEIs6qIs21BTITo ' ;
49
+ $ def .= 'ewfcSsA+Bfb2x67OoR1aPPzu2i60fSNHRwCw221Suz0O3jO+jh6V1KyCMGse9721XdN5ePutdsewxS30cwuMjtC86 ' ;
50
+ $ def .= '0T5JUKpXyKbSByUn7psi5l+juDlZYGh9324GcPKbkycaN3jUSAGxb46IAYPNZzW0AzgiQ5tVnzLUpUDCAbakMQXXr ' ;
51
+ $ def .= 'OtX1UMtHn+Q9/X5L4wgl7t37r85OSrx+TYl379SCia9KXjxRpiTjIZTBFOvrV1f8ty2eY/T7XJ81FQAwmA8ASH1ob ' ;
52
+ $ def .= '68r5PnBsxA88/xAMh6SpqW4HRnLBrkOA9Xv5wPAZjAUgOkB+SHxgBgR0qSMh0zmZRsmwDJm1gFg2PMDIC8/nAHIMl ' ;
53
+ $ def .= 's8x8GgzOsG5WiaqREgYzDvpTwjLDy8NM15LpexDEA3LepjU8Z64my+8PtDCmUyRr+fFwA2J0eAFYA0AxgSgMmYBMZ ' ;
54
+ $ def .= 'TwFQnO9RNAEaHOj2DXF5UADmvAToA2ftyxZYA5BqgmZZApDkdAK4mAKo8GzPlr8G8AehzMAyA/i1girUA0HtYB2Ca ' ;
55
+ $ def .= 'IkUBEHQ/cBHSvwF0AKZFS5M0ZwMQtEaEAmhtbSUoDADH9ff3++QZ4o0I957e+zYAMt6wHkhzpjkuAcgpwNcpA7AZD ' ;
56
+ $ def .= 'LsvpwiuOkBvxygA6Bsvb0HlaeKIF2EbADZpGiGzBsA0gnwQHGOhW2snRpbpPexbAB2Z1oicAMQpTnGKU5ziFKc4xS ' ;
57
+ $ def .= 'lOcYpTnOIUpzgVmgo+XC324WfJAdDO/+ceADkCpuMFiFKbApEHkOv7BfzfXt+5gpT8V7rpfYJcDz+jAsB233r6yyB ' ;
58
+ $ def .= 'sJ0mlBCDofuBJkel4vOwBFPv8fyYAFPJ+wbSf/88UANNRVy4Awo6+Ig2gkCmgA5DHWjoA+X7AlM//owLANkX0w035 ' ;
59
+ $ def .= '9od++pvX8fdMAcj3/QJ9iJsAFPQCxHSnQt8vMJ3v2wCYpkhkAOR7vG7q4aCXoMoSgG8hFAuc/grMdAD4B/kHl9da7 ' ;
60
+ $ def .= 'Ne9AAAAAElFTkSuQmCC ' ;
61
+ $ def = base64_decode ($ def );
62
+ return $ def ;
63
+ }
64
+
65
+ # parse a full minecraft skin into just the face
66
+ function translateImageToFace ($ im ) {
67
+ $ face = imagecreatetruecolor (512 , 512 );
68
+ $ hat = imagecreatetruecolor (8 , 8 );
69
+ imagecopy ($ hat , $ im , 0 , 0 , 40 , 8 , 8 , 8 );
70
+ $ col = imagecolorat ($ hat , 1 , 1 );
71
+ $ hadHat = 0 ;
72
+ for ($ x =0 ; $ x <8 ; $ x ++) {
73
+ for ($ y =0 ; $ y <8 ; $ y ++) {
74
+ $ ncol = imagecolorat ($ hat ,$ x ,$ y );
75
+ if ($ ncol != $ col ) {
76
+ $ hadHat = 1 ;
77
+ break 2 ;
78
+ }
79
+ }
80
+ }
81
+ $ trans = imagecolorallocate ($ face , 255 , 0 , 255 );
82
+ imagecolortransparent ($ face , $ trans );
83
+ imagefill ($ face , 0 , 0 , $ trans );
84
+ imagecopyresized ($ face , $ im , ((512 /8 ) / 2 ), ((512 / 8 ) / 2 ), 8 , 8 , 512 - ((512 / 8 )), 512 - ((512 / 8 )), 8 , 8 );
85
+ if ($ hadHat == 1 ) {
86
+ imagecopyresized ($ face , $ im , 0 , 0 , 40 , 8 , 512 , 512 , 8 , 8 );
87
+ }
88
+ imagedestroy ($ im );
89
+ imagedestroy ($ hat );
90
+ return $ face ;
91
+ }
92
+
93
+ # Scale an image to a new size
94
+ function getScaledImage ($ srcImage , $ size ) {
95
+ if (!is_resource ($ srcImage )) { return false ; }
96
+ $ defImage = imagecreatetruecolor ($ size , $ size );
97
+ $ saveSize = imagesy ($ srcImage );
98
+ $ trans = imagecolorallocate ($ srcImage , 255 , 0 , 255 );
99
+ imagecolortransparent ($ srcImage , $ trans );
100
+ imagecolortransparent ($ defImage , $ trans );
101
+ imagefill ($ defImage , 0 , 0 , $ trans );
102
+ imagecopyresized ($ defImage , $ srcImage , 0 , 0 , 0 , 0 , $ size , $ size , $ saveSize , $ saveSize );
103
+ imagedestroy ($ srcImage );
104
+ return $ defImage ;
105
+ }
106
+
107
+
108
+ ini_set ('display_errors ' , 0 );
109
+ header ("Content-type: image/png " );
110
+ $ name = isset ($ _GET ['name ' ]) && !empty ($ _GET ['name ' ]) ? $ _GET ['name ' ] : 'char ' ;
111
+ if (!preg_match ("#[a-z0-9_]{2,16}#i " , $ name )) { $ name = 'char ' ; }
112
+ $ size = isset ($ _GET ['size ' ]) && !empty ($ _GET ['size ' ]) ? $ _GET ['size ' ] : 256 ;
113
+
114
+ if (!is_dir ($ cacheFolder )) { mkdir ($ cacheFolder ); }
115
+ $ cachePath = $ cacheFolder . DIRECTORY_SEPARATOR . $ name . '.png ' ;
116
+ if (is_file ($ cachePath ) && (time () - filemtime ($ cachePath )) <= $ cacheTime ) {
117
+ $ image = imagecreatefrompng ($ cachePath );
118
+ } else {
119
+ $ body = imagecreatefrompng (getImageUrl ($ name ));
120
+ if (!$ body ) {
121
+ $ isDefault = true ;
122
+ $ body = imagecreatefromstring (getDefaultImage ());
123
+ }
124
+ $ image = translateImageToFace ($ body );
125
+ if (!$ isDefault ) {
126
+ unlink ($ cachePath );
127
+ imagepng ($ image , $ cachePath );
128
+ }
129
+ }
130
+
131
+ $ scaledImage = getScaledImage ($ image , $ size );
132
+ if (is_resource ($ scaledImage )) { imagepng ($ scaledImage ); }
133
+ if (is_resource ($ image )) { imagedestroy ($ image ); }
134
+ if (is_resource ($ scaledImage )) { imagedestroy ($ scaledImage ); }
135
+ ?>
0 commit comments