Skip to content

Commit 9d6eb95

Browse files
committed
Initial Upload
0 parents  commit 9d6eb95

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

.htaccess

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<IfModule mod_headers.c>
2+
Header add Access-Control-Allow-Origin "*"
3+
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
4+
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
5+
</IfModule>
6+
7+
<IfModule mod_rewrite.c>
8+
RewriteEngine on
9+
RewriteCond $1 !^(index\.php)
10+
RewriteCond %{REQUEST_FILENAME} !-f
11+
RewriteCond %{REQUEST_FILENAME} !-d
12+
RewriteRule ^([^/]*)/([0-9]+)$ /index.php?name=$1&size=$2 [L,QSA]
13+
RewriteRule ^([^/]*)/([0-9]+)/$ /index.php?name=$1&size=$2 [L,QSA]
14+
15+
RewriteCond $1 !^(index\.php)
16+
RewriteCond %{REQUEST_FILENAME} !-f
17+
RewriteCond %{REQUEST_FILENAME} !-d
18+
RewriteRule ^([^/]*)$ /index.php?name=$1 [L,QSA]
19+
RewriteRule ^([^/]*)/$ /index.php?name=$1 [L,QSA]
20+
</IfModule>

index.php

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
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

Comments
 (0)