diff --git a/.gitignore b/.gitignore index 1cd3b63..0a8ce98 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ skins/ *.log -node_modules/ \ No newline at end of file +node_modules/ +.DS_Store diff --git a/package.json b/package.json index 0c14cd6..4461329 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "serve-favicon": "~2.1.3", "debug": "~2.0.0", "jade": "~1.6.0", - "lwip": "0.0.5" + "lwip": "0.0.5", + "request": "2.45.0" } } \ No newline at end of file diff --git a/routes/avatars.js b/routes/avatars.js index 69fba25..b37fcee 100644 --- a/routes/avatars.js +++ b/routes/avatars.js @@ -29,12 +29,17 @@ router.get('/:uuid/:size?', function(req, res) { var skinurl = skins.skin_url(profile); if (skinurl) { console.log('got profile, skin url is "' + skinurl + '" downloading..'); - skins.skin_file(skinurl, filename, function() { + skins.skin_file(skinurl, "skins/" + filename, function() { console.log('got skin'); skins.resize_img("skins/" + filename, size, function(data) { // tell browser to cache image locally for 10 minutes var end = new Date() - start; - res.writeHead(200, {'Content-Type': 'image/png', 'Cache-Control': 'max-age=600, public', 'Response-Time': end, 'Storage-Type': 'downloaded'}); + res.writeHead(200, { + 'Content-Type': 'image/png', + 'Cache-Control': 'max-age=600, public', + 'Response-Time': end, + 'Storage-Type': 'downloaded' + }); res.end(data); }); }); diff --git a/skins.js b/skins.js index b57746e..1c4464f 100644 --- a/skins.js +++ b/skins.js @@ -1,19 +1,17 @@ -var http = require('http'); -var https = require('https'); -var fs = require('fs'); +var request = require('request'); var lwip = require('lwip'); -var urlparse = require('url').parse; - /* * Skin retrieval methods are based on @jomo's CLI Crafatar implementation. * https://github.com/jomo/Crafatar */ -function extract_face(inname, outname, callback) { - var outfile = fs.createWriteStream(outname); - lwip.open(inname, function(err, image) { - if (err) throw err; +function extract_face(buffer, outname, callback) { + lwip.open(buffer, "png", function(err, image) { + if (err) { + console.log('c ' + buffer.length); + throw err; + } image.batch() .crop(8, 8, 15, 15) .writeFile(outname, function(err) { @@ -25,24 +23,28 @@ function extract_face(inname, outname, callback) { module.exports = { get_profile: function(uuid, callback) { - https.get("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid, function(res) { - if (res.statusCode == "204") { - callback(null); - return null; - } - res.on('data', function(d) { - var profile = JSON.parse(d); - if (profile.error) { - // usually this is something like TooManyRequestsException - console.error(profile.error); - callback(null); + request.get({ + url: "https://sessionserver.mojang.com/session/minecraft/profile/" + uuid, + timeout: 1000 // ms + }, function (error, response, body) { + if (!error && response.statusCode == 200) { + callback(JSON.parse(body)); + } else { + if (error) { + console.error(error); + } else if (response.statusCode == 204 || response.statusCode == 404) { + // we get 204 No Content when UUID doesn't exist (including 404 in case they change that) + } else if (response.statusCode == 429) { + // Too Many Requests + console.warn("Too many requests for " + uuid); + console.warn(body); } else { - callback(profile); + console.error("Unknown error:"); + console.error(response); + console.error(body); } - }); - - }).on('error', function(err) { - throw err; + callback(null); + } }); }, @@ -60,26 +62,33 @@ module.exports = { return url; }, - skin_file: function(url, filename, callback) { - var tmpname = "skins/tmp/" + filename; - var outname = "skins/" + filename; - var tmpfile = fs.createWriteStream(tmpname); - var prot = http; - if (urlparse(url).protocol == "https") prot = https; - prot.get(url, function(res) { - res.on('data', function(data) { - tmpfile.write(data); - }).on('end', function() { - tmpfile.end(); - extract_face(tmpname, outname, function() { - fs.unlink(tmpname, function(err) { // unlink = delete - if (err) console.error(err); - }); - callback(); // outside unlink callback cause we don't have to wait until it's deleted + skin_file: function(url, outname, callback) { + request.get({ + url: url, + encoding: null, // encoding must be null so we get a buffer + timeout: 1000 // ms + }, function (error, response, body) { + if (!error && response.statusCode == 200) { + extract_face(body, outname, function() { + callback(); }); - }); - }).on('error', function(err) { - throw err; + } else { + if (error) { + console.error(error); + } else if (response.statusCode == 404) { + console.warn("Texture not found: " + url); + } else if (response.statusCode == 429) { + // Too Many Requests + // Never got this, seems like textures aren't limited + console.warn("Too many requests for " + url); + console.warn(body); + } else { + console.error("Unknown error:"); + console.error(response); + console.error(body); + } + callback(null); + } }); }, diff --git a/skins/tmp/.gitkeep b/skins/tmp/.gitkeep deleted file mode 100644 index e69de29..0000000