mirror of
https://github.com/azures04/crafatar.git
synced 2026-03-21 23:41:18 +01:00
add support for helmets (?helm), closes #2. changed '/:uuid/123' to '/:uuid?size=123', closes #10. Bugfixes
This commit is contained in:
parent
a61ac9b6a4
commit
1606fac89b
@ -2,9 +2,10 @@ var config = {
|
||||
min_size: 0, // < 0 will (obviously) cause crash
|
||||
max_size: 512, // too big values might lead to slow response time or DoS
|
||||
default_size: 180, // size to be used when no size given
|
||||
browser_cache_time: 3600,// seconds until browser will request image again
|
||||
browser_cache_time: 3600, // seconds until browser will request image again
|
||||
http_timeout: 1000, // ms until connection to mojang is dropped
|
||||
skins_dir: 'skins/' // directory where skins are kept. should have trailing '/'
|
||||
faces_dir: 'skins/faces/', // directory where faces are kept. should have trailing '/'
|
||||
helms_dir: 'skins/helms/' // directory where helms are kept. should have trailing '/'
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
@ -8,7 +8,7 @@ var valid_uuid = /^[0-9a-f]{32}$/;
|
||||
var exp = {};
|
||||
|
||||
// exracts the skin url of a +profile+ object
|
||||
// returns null when no url found
|
||||
// returns null when no url found (user has no skin)
|
||||
exp.skin_url = function(profile) {
|
||||
var url = null;
|
||||
if (profile && profile.properties) {
|
||||
@ -16,7 +16,7 @@ exp.skin_url = function(profile) {
|
||||
if (prop.name == 'textures') {
|
||||
var json = Buffer(prop.value, 'base64').toString();
|
||||
var props = JSON.parse(json);
|
||||
url = props && props.textures && props.textures.SKIN && props.textures.SKIN.url;
|
||||
url = props && props.textures && props.textures.SKIN && props.textures.SKIN.url || null;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -31,22 +31,27 @@ exp.uuid_valid = function(uuid) {
|
||||
};
|
||||
|
||||
// handles requests for +uuid+ images with +size+
|
||||
//
|
||||
// callback is a function with 3 parameters:
|
||||
// error, status, image buffer
|
||||
// image is the user's face+helm when helm is true, or the face otherwise
|
||||
//
|
||||
// the status gives information about how the image was received
|
||||
// -1: error
|
||||
// 1: found on disk
|
||||
// 2: profile requested/found, skin downloaded from mojang servers
|
||||
// 3: profile requested/found, but it has no skin
|
||||
exp.get_avatar = function(uuid, size, callback) {
|
||||
var filepath = config.skins_dir + uuid + ".png";
|
||||
exp.get_avatar = function(uuid, helm, size, callback) {
|
||||
var facepath = config.faces_dir + uuid + ".png";
|
||||
var helmpath = config.helms_dir + uuid + ".png";
|
||||
var filepath = helm ? helmpath : facepath;
|
||||
|
||||
if (fs.existsSync(filepath)) {
|
||||
// file found on disk
|
||||
skins.resize_img(filepath, size, function(err, result) {
|
||||
callback(err, 1, result);
|
||||
});
|
||||
} else {
|
||||
// download skin
|
||||
networking.get_profile(uuid, function(err, profile) {
|
||||
if (err) {
|
||||
callback(err, -1, profile);
|
||||
@ -55,7 +60,7 @@ exp.get_avatar = function(uuid, size, callback) {
|
||||
var skinurl = exp.skin_url(profile);
|
||||
|
||||
if (skinurl) {
|
||||
networking.skin_file(skinurl, filepath, function(err) {
|
||||
networking.skin_file(skinurl, facepath, helmpath, function(err) {
|
||||
if (err) {
|
||||
callback(err, -1, null);
|
||||
} else {
|
||||
|
||||
@ -6,12 +6,15 @@ var session_url = "https://sessionserver.mojang.com/session/minecraft/profile/";
|
||||
|
||||
var exp = {};
|
||||
|
||||
// download the Mojang profile for +uuid+
|
||||
// callback contains error, profile object
|
||||
exp.get_profile = function(uuid, callback) {
|
||||
request.get({
|
||||
url: session_url + uuid,
|
||||
timeout: config.http_timeout // ms
|
||||
}, function (error, response, body) {
|
||||
if (!error && response.statusCode == 200) {
|
||||
// profile downloaded successfully
|
||||
callback(null, JSON.parse(body));
|
||||
} else {
|
||||
if (error) {
|
||||
@ -33,15 +36,26 @@ exp.get_profile = function(uuid, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
exp.skin_file = function(url, outname, callback) {
|
||||
// downloads skin file from +url+
|
||||
// stores face image as +facename+
|
||||
// stores helm image as +helmname+
|
||||
// callback is forwarded from skins/extract_face or skins/extract_helm
|
||||
exp.skin_file = function(url, facename, helmname, callback) {
|
||||
request.get({
|
||||
url: url,
|
||||
encoding: null, // encoding must be null so we get a buffer
|
||||
timeout: config.http_timeout // ms
|
||||
}, function (error, response, body) {
|
||||
if (!error && response.statusCode == 200) {
|
||||
skins.extract_face(body, outname, function(err) {
|
||||
// skin downloaded successfully
|
||||
skins.extract_face(body, facename, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
skins.extract_helm(facename, body, helmname, function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (error) {
|
||||
|
||||
@ -3,15 +3,15 @@ var lwip = require('lwip');
|
||||
var exp = {};
|
||||
|
||||
// extracts the face from an image +buffer+
|
||||
// save it to a file called +outname+
|
||||
// callback has an error parameter which can be null
|
||||
// result is saved to a file called +outname+
|
||||
// +callback+ contains error
|
||||
exp.extract_face = function(buffer, outname, callback) {
|
||||
lwip.open(buffer, "png", function(err, image) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
image.batch()
|
||||
.crop(8, 8, 15, 15)
|
||||
.crop(8, 8, 15, 15) // face
|
||||
.writeFile(outname, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
@ -23,8 +23,47 @@ exp.extract_face = function(buffer, outname, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
// extracts the helm from an image +buffer+ and lays it over a +facefile+
|
||||
// +facefile+ is the filename of an image produced by extract_face
|
||||
// result is saved to a file called +outname+
|
||||
// +callback+ contains error
|
||||
exp.extract_helm = function(facefile, buffer, outname, callback) {
|
||||
lwip.open(buffer, "png", function(err, skin) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
lwip.open(facefile, function(err, face_img) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
skin.crop(42, 8, 49, 15, function(err, helm_img) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
face_img.paste(0, 0, helm_img, function(err, face_helm_img) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
face_helm_img.writeFile(outname, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
callback(null);
|
||||
// JavaScript callback hell <3
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// resizes the image file +inname+ to +size+ by +size+ pixels
|
||||
// +callback+ is a buffer of the resized image
|
||||
// +callback+ contains error, image buffer
|
||||
exp.resize_img = function(inname, size, callback) {
|
||||
lwip.open(inname, function(err, image) {
|
||||
if (err) {
|
||||
|
||||
@ -6,10 +6,11 @@ var skins = require('../modules/skins');
|
||||
var fs = require('fs');
|
||||
|
||||
/* GET avatar request. */
|
||||
router.get('/:uuid/:size?', function(req, res) {
|
||||
var uuid = req.param('uuid');
|
||||
var size = req.param('size') || config.default_size;
|
||||
router.get('/:uuid', function(req, res) {
|
||||
var uuid = req.params.uuid;
|
||||
var size = req.query.size || config.default_size;
|
||||
var def = req.query.default;
|
||||
var helm = req.query.hasOwnProperty('helm');
|
||||
var start = new Date();
|
||||
|
||||
// Prevent app from crashing/freezing
|
||||
@ -24,13 +25,12 @@ router.get('/:uuid/:size?', function(req, res) {
|
||||
}
|
||||
|
||||
try {
|
||||
helpers.get_avatar(uuid, size, function(err, status, image) {
|
||||
helpers.get_avatar(uuid, helm, size, function(err, status, image) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
handle_404(def);
|
||||
} else if (status == 1 || status == 2) {
|
||||
var time = new Date() - start;
|
||||
sendimage(200, time, image);
|
||||
sendimage(200, image);
|
||||
} else if (status == 3) {
|
||||
handle_404(def);
|
||||
}
|
||||
@ -44,19 +44,18 @@ router.get('/:uuid/:size?', function(req, res) {
|
||||
function handle_404(def) {
|
||||
if (def == "alex" || def == "steve") {
|
||||
skins.resize_img("public/images/" + def + ".png", size, function(image) {
|
||||
var time = new Date() - start;
|
||||
sendimage(404, time, image);
|
||||
sendimage(404, image);
|
||||
});
|
||||
} else {
|
||||
res.status(404).send('404 Not found');
|
||||
}
|
||||
}
|
||||
|
||||
function sendimage(status, time, image) {
|
||||
function sendimage(status, image) {
|
||||
res.writeHead(status, {
|
||||
'Content-Type': 'image/png',
|
||||
'Cache-Control': 'max-age=' + config.browser_cache_time + ', public',
|
||||
'Response-Time': time,
|
||||
'Response-Time': new Date() - start,
|
||||
'X-Storage-Type': 'local'
|
||||
});
|
||||
res.end(image);
|
||||
|
||||
0
skins/helms/.gitkeep
Normal file
0
skins/helms/.gitkeep
Normal file
@ -32,8 +32,8 @@ block content
|
||||
p(style="margin-top: 10px;") By default, a 404 text is returned when the avatar was not found. You can change that to the avatar of steve or alex:
|
||||
.well <img src="#{domain}/avatars/ae795aa86327408e92ab25c8a59f3ba1/250?default=alex">
|
||||
.col-md-2
|
||||
img(src="/avatars/2d5aa9cdaeb049189930461fc9b91cc5?default=steve", title="Jake0oo0")
|
||||
img(src="/avatars/ae795aa86327408e92ab25c8a59f3ba1?default=steve", title="redstone_sheep")
|
||||
img(src="/avatars/069a79f444e94726a5befca90e38aaf5?default=steve", title="Notch")
|
||||
img(src="/avatars/0ea8eca3dbf647cc9d1ac64551ca975c?default=steve", title="sk89q")
|
||||
img(src="/avatars/af74a02d19cb445bb07f6866a861f783?default=steve", title="md_5")
|
||||
img(src="/avatars/2d5aa9cdaeb049189930461fc9b91cc5?default=alex&helm", title="Jake0oo0")
|
||||
img(src="/avatars/ae795aa86327408e92ab25c8a59f3ba1?default=alex&helm", title="redstone_sheep")
|
||||
img(src="/avatars/069a79f444e94726a5befca90e38aaf5?default=alex&helm", title="Notch")
|
||||
img(src="/avatars/0ea8eca3dbf647cc9d1ac64551ca975c?default=alex&helm", title="sk89q")
|
||||
img(src="/avatars/af74a02d19cb445bb07f6866a861f783?default=alex&helm", title="md_5")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user