| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 | 
							- var logging = require("./logging");
 
- var request = require("request");
 
- var config = require("./config");
 
- var skins = require("./skins");
 
- var fs = require("fs");
 
- var session_url = "https://sessionserver.mojang.com/session/minecraft/profile/";
 
- var skins_url = "https://skins.minecraft.net/MinecraftSkins/";
 
- // exracts the skin url of a +profile+ object
 
- // returns null when no url found (user has no skin)
 
- function extract_skin_url(profile) {
 
-   var url = null;
 
-   if (profile && profile.properties) {
 
-     profile.properties.forEach(function(prop) {
 
-       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 || null;
 
-       }
 
-     });
 
-   }
 
-   return url;
 
- }
 
- // make a request to skins.miencraft.net
 
- // the skin url is taken from the HTTP redirect
 
- var get_username_url = function(name, callback) {
 
-   request.get({
 
-     url: skins_url + name + ".png",
 
-     headers: {
 
-       "User-Agent": "https://crafatar.com"
 
-     },
 
-     timeout: config.http_timeout,
 
-     followRedirect: false
 
-   }, function(error, response, body) {
 
-     if (!error && response.statusCode == 301) {
 
-       // skin_url received successfully
 
-       logging.log(name + " skin url received");
 
-       callback(null, response.headers.location);
 
-     } else if (error) {
 
-       callback(error, null);
 
-     } else if (response.statusCode == 404) {
 
-       // skin (or user) doesn't exist
 
-       logging.log(name + " has no skin");
 
-       callback(null, null);
 
-     } else if (response.statusCode == 429) {
 
-       // Too Many Requests
 
-       // Never got this, seems like skins aren't limited
 
-       logging.warn(body || "Too many requests");
 
-       callback(null, null);
 
-     } else {
 
-       logging.error(name + " Unknown error:");
 
-       logging.error(response);
 
-       callback(body || "Unknown error", null);
 
-     }
 
-   });
 
- };
 
- // make a request to sessionserver
 
- // the skin_url is taken from the profile
 
- var get_uuid_url = function(uuid, callback) {
 
-   request.get({
 
-     url: session_url + uuid,
 
-     headers: {
 
-       "User-Agent": "https://crafatar.com"
 
-     },
 
-     timeout: config.http_timeout // ms
 
-   }, function (error, response, body) {
 
-     if (!error && response.statusCode == 200) {
 
-       // profile downloaded successfully
 
-       logging.log(uuid + " profile downloaded");
 
-       callback(null, extract_skin_url(JSON.parse(body)));
 
-     } else if (error) {
 
-       callback(error, null);
 
-     } 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)
 
-       logging.log(uuid + " uuid does not exist");
 
-       callback(null, null);
 
-     } else if (response.statusCode == 429) {
 
-       // Too Many Requests
 
-       callback(body || "Too many requests", null);
 
-     } else {
 
-       logging.error(uuid + " Unknown error:");
 
-       logging.error(response);
 
-       callback(body || "Unknown error", null);
 
-     }
 
-   });
 
- };
 
- var exp = {};
 
- // download skin_url for +uuid+ (name or uuid)
 
- // callback contains error, skin_url
 
- exp.get_skin_url = function(uuid, callback) {
 
-   if (uuid.length <= 16) {
 
-     get_username_url(uuid, function(err, url) {
 
-       callback(err, url);
 
-     });
 
-   } else {
 
-     get_uuid_url(uuid, function(err, url) {
 
-       callback(err, url);
 
-     });
 
-   }
 
- };
 
- // downloads skin file from +url+
 
- // callback contains error, image
 
- exp.get_skin = function(url, callback) {
 
-   request.get({
 
-     url: url,
 
-     headers: {
 
-       "User-Agent": "https://crafatar.com"
 
-     },
 
-     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) {
 
-       // skin downloaded successfully
 
-       logging.log("downloaded skin");
 
-       logging.debug(url);
 
-       callback(null, body);
 
-     } else {
 
-       if (error) {
 
-         logging.error("Error downloading '" + url + "': " + error);
 
-       } else if (response.statusCode == 404) {
 
-         logging.warn("texture not found (404): " + url);
 
-       } else if (response.statusCode == 429) {
 
-         // Too Many Requests
 
-         // Never got this, seems like textures aren't limited
 
-         logging.warn("too many requests for " + url);
 
-         logging.warn(body);
 
-       } else {
 
-         logging.error("unknown error for " + url);
 
-         logging.error(response);
 
-         logging.error(body);
 
-         error = "unknown error"; // Error needs to be set, otherwise null in callback
 
-       }
 
-       callback(error, null);
 
-     }
 
-   });
 
- };
 
- exp.save_skin = function(uuid, hash, outpath, callback) {
 
-   if (hash) {
 
-     var skinurl = "http://textures.minecraft.net/texture/" + hash;
 
-     exp.get_skin(skinurl, function(err, img) {
 
-       if (err) {
 
-         logging.error("error while downloading skin");
 
-         callback(err, null);
 
-       } else {
 
-         fs.writeFile(outpath, img, "binary", function(err){
 
-           if (err) {
 
-             logging.log(err);
 
-           }
 
-           callback(null, img);
 
-         });
 
-       }
 
-     });
 
-   } else {
 
-     callback(null, null);
 
-   }
 
- };
 
- module.exports = exp;
 
 
  |