diff --git a/modules/cache.js b/modules/cache.js index 5838a80..8d0bb42 100644 --- a/modules/cache.js +++ b/modules/cache.js @@ -92,41 +92,41 @@ exp.info = function(callback) { }); }; -// sets the timestamp for +uuid+ and its face file's date to now -exp.update_timestamp = function(rid, uuid, hash) { +// sets the timestamp for +userId+ and its face file's date to now +exp.update_timestamp = function(rid, userId, hash) { logging.log(rid + "cache: updating timestamp"); var time = new Date().getTime(); - // store uuid in lower case if not null - uuid = uuid && uuid.toLowerCase(); - redis.hmset(uuid, "t", time); + // store userId in lower case if not null + userId = userId && userId.toLowerCase(); + redis.hmset(userId, "t", time); update_file_date(rid, hash); }; -// create the key +uuid+, store +skin+ hash, +cape+ hash and time -exp.save_hash = function(rid, uuid, skin, cape) { +// create the key +userId+, store +skin+ hash, +cape+ hash and time +exp.save_hash = function(rid, userId, skin, cape) { logging.log(rid + "cache: saving hash"); logging.log(rid + "skin:" + skin + " cape:" + cape); var time = new Date().getTime(); // store shorter null byte instead of "null" skin = skin || "."; cape = cape || "."; - // store uuid in lower case if not null - uuid = uuid && uuid.toLowerCase(); - redis.hmset(uuid, "s", skin, "c", cape, "t", time); + // store userId in lower case if not null + userId = userId && userId.toLowerCase(); + redis.hmset(userId, "s", skin, "c", cape, "t", time); }; -exp.remove_hash = function(rid, uuid) { +exp.remove_hash = function(rid, userId) { logging.log(rid + "cache: deleting hash"); - redis.del(uuid.toLowerCase(), "h", "t"); + redis.del(userId.toLowerCase(), "h", "t"); }; -// get a details object for +uuid+ +// get a details object for +userId+ // {skin: "0123456789abcdef", cape: "gs1gds1g5d1g5ds1", time: 1414881524512} -// null when uuid unkown -exp.get_details = function(uuid, callback) { - // get uuid in lower case if not null - uuid = uuid && uuid.toLowerCase(); - redis.hgetall(uuid, function(err, data) { +// null when userId unkown +exp.get_details = function(userId, callback) { + // get userId in lower case if not null + userId = userId && userId.toLowerCase(); + redis.hgetall(userId, function(err, data) { var details = null; if (data) { details = { diff --git a/modules/helpers.js b/modules/helpers.js index 78c98d6..5338372 100644 --- a/modules/helpers.js +++ b/modules/helpers.js @@ -7,7 +7,7 @@ var renders = require("./renders"); var fs = require("fs"); // 0098cb60-fa8e-427c-b299-793cbd302c9a -var valid_uuid = /^([0-9a-f-A-F-]{32,36}|[a-zA-Z0-9_]{1,16})$/; // uuid|username +var valid_user_id = /^([0-9a-f-A-F-]{32,36}|[a-zA-Z0-9_]{1,16})$/; // uuid|username var hash_pattern = /[0-9a-f]+$/; // gets the hash from the textures.minecraft.net +url+ @@ -15,12 +15,12 @@ function get_hash(url) { return hash_pattern.exec(url)[0].toLowerCase(); } -function store_skin(rid, uuid, profile, details, callback) { - networking.get_skin_url(rid, uuid, profile, function(url) { +function store_skin(rid, userId, profile, details, callback) { + networking.get_skin_url(rid, userId, profile, function(url) { if (url) { var hash = get_hash(url); if (details && details.skin === hash) { - cache.update_timestamp(rid, uuid, hash); + cache.update_timestamp(rid, userId, hash); callback(null, hash); } else { logging.log(rid + "new skin hash: " + hash); @@ -59,12 +59,12 @@ function store_skin(rid, uuid, profile, details, callback) { }); } -function store_cape(rid, uuid, profile, details, callback) { - networking.get_cape_url(rid, uuid, profile, function(url) { +function store_cape(rid, userId, profile, details, callback) { + networking.get_cape_url(rid, userId, profile, function(url) { if (url) { var hash = get_hash(url); if (details && details.cape === hash) { - cache.update_timestamp(rid, uuid, hash); + cache.update_timestamp(rid, userId, hash); callback(null, hash); } else { logging.log(rid + "new cape hash: " + hash); @@ -94,15 +94,15 @@ function store_cape(rid, uuid, profile, details, callback) { }); } -// used by store_images to queue simultaneous requests for identical uuid +// used by store_images to queue simultaneous requests for identical userId // the first request has to be completed until all others are continued var currently_running = []; -// calls back all queued requests that match uuid and type -function callback_for(uuid, type, err, hash) { +// calls back all queued requests that match userId and type +function callback_for(userId, type, err, hash) { var req_count = 0; for (var i = 0; i < currently_running.length; i++) { var current = currently_running[i]; - if (current.uuid === uuid && current.type === type) { + if (current.userid === userId && current.type === type) { req_count++; if (req_count !== 1) { // otherwise this would show up on single/first requests, too @@ -114,7 +114,7 @@ function callback_for(uuid, type, err, hash) { } } if (req_count > 1) { - logging.debug(req_count + " simultaneous requests for " + uuid); + logging.debug(req_count + " simultaneous requests for " + userId); } } @@ -128,30 +128,30 @@ function deep_property_check(arr, property, value) { return false; } -// downloads the images for +uuid+ while checking the cache +// downloads the images for +userId+ while checking the cache // status based on +details+. +type+ specifies which // image type should be called back on // +callback+ contains the error buffer and image hash -function store_images(rid, uuid, details, type, callback) { - var is_uuid = uuid.length > 16; +function store_images(rid, userId, details, type, callback) { + var is_uuid = userId.length > 16; var new_hash = { rid: rid, - uuid: uuid, + userid: userId, type: type, callback: callback }; - if (!deep_property_check(currently_running, "uuid", uuid)) { + if (!deep_property_check(currently_running, "userid", userId)) { currently_running.push(new_hash); - networking.get_profile(rid, (is_uuid ? uuid : null), function(err, profile) { + networking.get_profile(rid, (is_uuid ? userId : null), function(err, profile) { if (err || (is_uuid && !profile)) { - callback_for(uuid, type, err, null); + callback_for(userId, type, err, null); } else { - store_skin(rid, uuid, profile, details, function(err, skin_hash) { - cache.save_hash(rid, uuid, skin_hash, null); - callback_for(uuid, "skin", err, skin_hash); - store_cape(rid, uuid, profile, details, function(err, cape_hash) { - cache.save_hash(rid, uuid, skin_hash, cape_hash); - callback_for(uuid, "cape", err, cape_hash); + store_skin(rid, userId, profile, details, function(err, skin_hash) { + cache.save_hash(rid, userId, skin_hash, null); + callback_for(userId, "skin", err, skin_hash); + store_cape(rid, userId, profile, details, function(err, cape_hash) { + cache.save_hash(rid, userId, skin_hash, cape_hash); + callback_for(userId, "cape", err, cape_hash); }); }); } @@ -164,10 +164,10 @@ function store_images(rid, uuid, details, type, callback) { var exp = {}; -// returns true if the +uuid+ is a valid uuid or username -// the uuid may be not exist, however -exp.uuid_valid = function(uuid) { - return valid_uuid.test(uuid); +// returns true if the +userId+ is a valid userId or username +// the userId may be not exist, however +exp.id_valid = function(userId) { + return valid_user_id.test(userId); }; // decides whether to get an image from disk or to download it @@ -178,22 +178,22 @@ exp.uuid_valid = function(uuid) { // 1: "cached" - found on disk // 2: "downloaded" - profile downloaded, skin downloaded from mojang servers // 3: "checked" - profile re-downloaded (was too old), but it has either not changed or has no skin -exp.get_image_hash = function(rid, uuid, raw_type, callback) { - cache.get_details(uuid, function(err, details) { +exp.get_image_hash = function(rid, userId, raw_type, callback) { + cache.get_details(userId, function(err, details) { var type = (details !== null ? (raw_type === "skin" ? details.skin : details.cape) : null); if (err) { callback(err, -1, null); } else { if (details && details.time + config.local_cache_time * 1000 >= new Date().getTime()) { - logging.log(rid + "uuid cached & recently updated"); + logging.log(rid + "userId cached & recently updated"); callback(null, (type ? 1 : 0), type); } else { if (details) { - logging.log(rid + "uuid cached, but too old"); + logging.log(rid + "userId cached, but too old"); } else { - logging.log(rid + "uuid not cached"); + logging.log(rid + "userId not cached"); } - store_images(rid, uuid, details, raw_type, function(err, hash) { + store_images(rid, userId, details, raw_type, function(err, hash) { if (err) { callback(err, -1, details && type); } else { @@ -209,12 +209,12 @@ exp.get_image_hash = function(rid, uuid, raw_type, callback) { }; -// handles requests for +uuid+ avatars with +size+ +// handles requests for +userId+ avatars with +size+ // callback contains error, status, image buffer, hash // image is the user's face+helm when helm is true, or the face otherwise // for status, see get_image_hash -exp.get_avatar = function(rid, uuid, helm, size, callback) { - exp.get_image_hash(rid, uuid, "skin", function(err, status, hash) { +exp.get_avatar = function(rid, userId, helm, size, callback) { + exp.get_image_hash(rid, userId, "skin", function(err, status, hash) { if (hash) { var facepath = __dirname + "/../" + config.faces_dir + hash + ".png"; var helmpath = __dirname + "/../" + config.helms_dir + hash + ".png"; @@ -234,17 +234,17 @@ exp.get_avatar = function(rid, uuid, helm, size, callback) { }); }); } else { - // hash is null when uuid has no skin + // hash is null when userId has no skin callback(err, status, null, null); } }); }; -// handles requests for +uuid+ skins +// handles requests for +userId+ skins // callback contains error, hash, image buffer -exp.get_skin = function(rid, uuid, callback) { +exp.get_skin = function(rid, userId, callback) { logging.log(rid + "skin request"); - exp.get_image_hash(rid, uuid, "skin", function(err, status, hash) { + exp.get_image_hash(rid, userId, "skin", function(err, status, hash) { var skinpath = __dirname + "/../" + config.skins_dir + hash + ".png"; fs.exists(skinpath, function(exists) { if (exists) { @@ -268,8 +268,8 @@ function get_type(helm, body) { // handles creations of skin renders // callback contanis error, hash, image buffer -exp.get_render = function(rid, uuid, scale, helm, body, callback) { - exp.get_skin(rid, uuid, function(err, hash, img) { +exp.get_render = function(rid, userId, scale, helm, body, callback) { + exp.get_skin(rid, userId, function(err, hash, img) { if (!hash) { callback(err, -1, hash, null); return; @@ -305,11 +305,11 @@ exp.get_render = function(rid, uuid, scale, helm, body, callback) { }); }; -// handles requests for +uuid+ capes +// handles requests for +userId+ capes // callback contains error, hash, image buffer -exp.get_cape = function(rid, uuid, callback) { +exp.get_cape = function(rid, userId, callback) { logging.log(rid + "cape request"); - exp.get_image_hash(rid, uuid, "cape", function(err, status, hash) { + exp.get_image_hash(rid, userId, "cape", function(err, status, hash) { if (!hash) { callback(err, null, null); return; diff --git a/modules/networking.js b/modules/networking.js index 8972936..3f776f6 100644 --- a/modules/networking.js +++ b/modules/networking.js @@ -119,28 +119,28 @@ exp.get_profile = function(rid, uuid, callback) { } }; -// +uuid+ is likely a username and if so -// +uuid+ is used to get the url, otherwise +// +userId+ is likely a username and if so +// +userId+ is used to get the url, otherwise // +profile+ will be used to get the url -exp.get_skin_url = function(rid, uuid, profile, callback) { - get_url(rid, uuid, profile, 0, function(url) { +exp.get_skin_url = function(rid, userId, profile, callback) { + get_url(rid, userId, profile, 0, function(url) { callback(url); }); }; -// +uuid+ is likely a username and if so -// +uuid+ is used to get the url, otherwise +// +userId+ is likely a username and if so +// +userId+ is used to get the url, otherwise // +profile+ will be used to get the url -exp.get_cape_url = function(rid, uuid, profile, callback) { - get_url(rid, uuid, profile, 1, function(url) { +exp.get_cape_url = function(rid, userId, profile, callback) { + get_url(rid, userId, profile, 1, function(url) { callback(url); }); }; -function get_url(rid, uuid, profile, type, callback) { - if (uuid.length <= 16) { +function get_url(rid, userId, profile, type, callback) { + if (userId.length <= 16) { //username - exp.get_username_url(rid, uuid, type, function(err, url) { + exp.get_username_url(rid, userId, type, function(err, url) { callback(url || null); }); } else { diff --git a/modules/skins.js b/modules/skins.js index 73119b3..d2b31ea 100644 --- a/modules/skins.js +++ b/modules/skins.js @@ -84,9 +84,9 @@ exp.resize_img = function(inname, size, callback) { }); }; -// returns "alex" or "steve" calculated by the +uuid+ -exp.default_skin = function(uuid) { - if (Number("0x" + uuid[31]) % 2 === 0) { +// returns "alex" or "steve" calculated by the +userId+ +exp.default_skin = function(userId) { + if (Number("0x" + userId[31]) % 2 === 0) { return "alex"; } else { return "steve"; diff --git a/routes/avatars.js b/routes/avatars.js index d8ccf99..09f0561 100644 --- a/routes/avatars.js +++ b/routes/avatars.js @@ -15,7 +15,7 @@ var human_status = { // GET avatar request module.exports = function(req, res) { var start = new Date(); - var uuid = (req.url.path_list[2] || "").split(".")[0]; + var userId = (req.url.path_list[2] || "").split(".")[0]; var size = parseInt(req.url.query.size) || config.default_size; var def = req.url.query.default; var helm = req.url.query.hasOwnProperty("helm"); @@ -32,27 +32,27 @@ module.exports = function(req, res) { }); res.end("Invalid Size"); return; - } else if (!helpers.uuid_valid(uuid)) { + } else if (!helpers.id_valid(userId)) { res.writeHead(422, { "Content-Type": "text/plain", "Response-Time": new Date() - start }); - res.end("Invalid UUID"); + res.end("Invalid ID"); return; } // strip dashes - uuid = uuid.replace(/-/g, ""); - logging.log(rid + "uuid: " + uuid); + userId = userId.replace(/-/g, ""); + logging.log(rid + "userid: " + userId); try { - helpers.get_avatar(rid, uuid, helm, size, function(err, status, image, hash) { + helpers.get_avatar(rid, userId, helm, size, function(err, status, image, hash) { logging.log(rid + "storage type: " + human_status[status]); if (err) { logging.error(rid + err); if (err.code === "ENOENT") { // no such file - cache.remove_hash(rid, uuid); + cache.remove_hash(rid, userId); } } etag = image && hash && hash.substr(0, 32) || "none"; @@ -68,15 +68,15 @@ module.exports = function(req, res) { logging.debug(rid + "matches: " + matches); sendimage(rid, http_status, status, image); } else { - handle_default(rid, 404, status, uuid); + handle_default(rid, 404, status, userId); } }); } catch(e) { logging.error(rid + "error: " + e.stack); - handle_default(rid, 500, -1, uuid); + handle_default(rid, 500, -1, userId); } - function handle_default(rid, http_status, img_status, uuid) { + function handle_default(rid, http_status, img_status, userId) { if (def && def !== "steve" && def !== "alex") { logging.log(rid + "status: 301"); res.writeHead(301, { @@ -89,7 +89,7 @@ module.exports = function(req, res) { }); res.end(); } else { - def = def || skins.default_skin(uuid); + def = def || skins.default_skin(userId); skins.resize_img("public/images/" + def + ".png", size, function(err, image) { sendimage(rid, http_status, img_status, image); }); diff --git a/routes/capes.js b/routes/capes.js index 9070fa9..ae97911 100644 --- a/routes/capes.js +++ b/routes/capes.js @@ -13,11 +13,11 @@ var human_status = { // GET cape request module.exports = function(req, res) { var start = new Date(); - var uuid = (req.url.pathname.split("/")[2] || "").split(".")[0]; + var userId = (req.url.pathname.split("/")[2] || "").split(".")[0]; var etag = null; var rid = req.id; - if (!helpers.uuid_valid(uuid)) { + if (!helpers.id_valid(userId)) { res.writeHead(422, { "Content-Type": "text/plain", "Response-Time": new Date() - start @@ -27,17 +27,17 @@ module.exports = function(req, res) { } // strip dashes - uuid = uuid.replace(/-/g, ""); - logging.log(rid + "uuid: " + uuid); + userId = userId.replace(/-/g, ""); + logging.log(rid + "userid: " + userId); try { - helpers.get_cape(rid, uuid, function(err, status, image, hash) { + helpers.get_cape(rid, userId, function(err, status, image, hash) { logging.log(rid + "storage type: " + human_status[status]); if (err) { logging.error(rid + err); if (err.code == "ENOENT") { // no such file - cache.remove_hash(rid, uuid); + cache.remove_hash(rid, userId); } } etag = hash && hash.substr(0, 32) || "none"; diff --git a/routes/renders.js b/routes/renders.js index 712fb7a..930758c 100644 --- a/routes/renders.js +++ b/routes/renders.js @@ -34,7 +34,7 @@ module.exports = function(req, res) { } var body = raw_type === "body"; - var uuid = (req.url.path_list[3] || "").split(".")[0]; + var userId = (req.url.path_list[3] || "").split(".")[0]; var def = req.url.query.default; var scale = parseInt(req.url.query.scale) || config.default_scale; var helm = req.url.query.hasOwnProperty("helm"); @@ -47,27 +47,27 @@ module.exports = function(req, res) { }); res.end("422 Invalid Scale"); return; - } else if (!helpers.uuid_valid(uuid)) { + } else if (!helpers.id_valid(userId)) { res.writeHead(422, { "Content-Type": "text/plain", "Response-Time": new Date() - start }); - res.end("422 Invalid UUID"); + res.end("422 Invalid ID"); return; } // strip dashes - uuid = uuid.replace(/-/g, ""); - logging.log(rid + "uuid: " + uuid); + userId = userId.replace(/-/g, ""); + logging.log(rid + "userId: " + userId); try { - helpers.get_render(rid, uuid, scale, helm, body, function(err, status, hash, image) { + helpers.get_render(rid, userId, scale, helm, body, function(err, status, hash, image) { logging.log(rid + "storage type: " + human_status[status]); if (err) { logging.error(rid + err); if (err.code == "ENOENT") { // no such file - cache.remove_hash(rid, uuid); + cache.remove_hash(rid, userId); } } etag = hash && hash.substr(0, 32) || "none"; @@ -84,18 +84,18 @@ module.exports = function(req, res) { sendimage(rid, http_status, status, image); } else { logging.log(rid + "image not found, using default."); - handle_default(rid, 404, status, uuid); + handle_default(rid, 404, status, userId); } }); } catch(e) { logging.error(rid + "error: " + e.stack); - handle_default(rid, 500, -1, uuid); + handle_default(rid, 500, -1, userId); } // default alex/steve images can be rendered, but // custom images will not be - function handle_default(rid, http_status, img_status, uuid) { + function handle_default(rid, http_status, img_status, userId) { if (def && def !== "steve" && def !== "alex") { logging.log(rid + "status: 301"); res.writeHead(301, { @@ -108,7 +108,7 @@ module.exports = function(req, res) { }); res.end(); } else { - def = def || skins.default_skin(uuid); + def = def || skins.default_skin(userId); fs.readFile("public/images/" + def + "_skin.png", function (err, buf) { if (err) { // errored while loading the default image, continuing with null image diff --git a/routes/skins.js b/routes/skins.js index 8563d8e..0268855 100644 --- a/routes/skins.js +++ b/routes/skins.js @@ -7,26 +7,26 @@ var lwip = require("lwip"); // GET skin request module.exports = function(req, res) { var start = new Date(); - var uuid = (req.url.path_list[2] || "").split(".")[0]; + var userId = (req.url.path_list[2] || "").split(".")[0]; var def = req.url.query.default; var etag = null; var rid = req.id; - if (!helpers.uuid_valid(uuid)) { + if (!helpers.id_valid(userId)) { res.writeHead(422, { "Content-Type": "text/plain", "Response-Time": new Date() - start }); - res.end("Invalid UUID"); + res.end("Invalid ID"); return; } // strip dashes - uuid = uuid.replace(/-/g, ""); - logging.log(rid + "uuid: " + uuid); + userId = userId.replace(/-/g, ""); + logging.log(rid + "userid: " + userId); try { - helpers.get_skin(rid, uuid, function(err, hash, image) { + helpers.get_skin(rid, userId, function(err, hash, image) { if (err) { logging.error(rid + err); } @@ -43,15 +43,15 @@ module.exports = function(req, res) { logging.debug(rid + "matches: " + matches); sendimage(rid, http_status, image); } else { - handle_default(rid, 404, uuid); + handle_default(rid, 404, userId); } }); } catch(e) { logging.error(rid + "error: " + e.stack); - handle_default(rid, 500, uuid); + handle_default(rid, 500, userId); } - function handle_default(rid, http_status, uuid) { + function handle_default(rid, http_status, userId) { if (def && def !== "steve" && def !== "alex") { logging.log(rid + "status: 301"); res.writeHead(301, { @@ -64,7 +64,7 @@ module.exports = function(req, res) { }); res.end(); } else { - def = def || skins.default_skin(uuid); + def = def || skins.default_skin(userId); lwip.open("public/images/" + def + "_skin.png", function(err, image) { image.toBuffer("png", function(err, buffer) { sendimage(rid, http_status, buffer); diff --git a/test/test.js b/test/test.js index de079e4..c6aa8fe 100644 --- a/test/test.js +++ b/test/test.js @@ -47,43 +47,43 @@ describe("Crafatar", function() { describe("UUID/username", function() { it("non-hex uuid is invalid", function(done) { - assert.strictEqual(helpers.uuid_valid("g098cb60fa8e427cb299793cbd302c9a"), false); + assert.strictEqual(helpers.id_valid("g098cb60fa8e427cb299793cbd302c9a"), false); done(); }); it("empty id is invalid", function(done) { - assert.strictEqual(helpers.uuid_valid(""), false); + assert.strictEqual(helpers.id_valid(""), false); done(); }); it("non-alphanumeric username is invalid", function(done) { - assert.strictEqual(helpers.uuid_valid("usernäme"), false); + assert.strictEqual(helpers.id_valid("usernäme"), false); done(); }); it("dashed username is invalid", function(done) { - assert.strictEqual(helpers.uuid_valid("user-name"), false); + assert.strictEqual(helpers.id_valid("user-name"), false); done(); }); it(">16 length username is invalid", function(done) { - assert.strictEqual(helpers.uuid_valid("ThisNameIsTooLong"), false); + assert.strictEqual(helpers.id_valid("ThisNameIsTooLong"), false); done(); }); it("lowercase uuid is valid", function(done) { - assert.strictEqual(helpers.uuid_valid("0098cb60fa8e427cb299793cbd302c9a"), true); + assert.strictEqual(helpers.id_valid("0098cb60fa8e427cb299793cbd302c9a"), true); done(); }); it("uppercase uuid is valid", function(done) { - assert.strictEqual(helpers.uuid_valid("1DCEF164FF0A47F2B9A691385C774EE7"), true); + assert.strictEqual(helpers.id_valid("1DCEF164FF0A47F2B9A691385C774EE7"), true); done(); }); it("dashed uuid is valid", function(done) { - assert.strictEqual(helpers.uuid_valid("0098cb60-fa8e-427c-b299-793cbd302c9a"), true); + assert.strictEqual(helpers.id_valid("0098cb60-fa8e-427c-b299-793cbd302c9a"), true); done(); }); it("16 chars, underscored, capital, numbered username is valid", function(done) { - assert.strictEqual(helpers.uuid_valid("__niceUs3rname__"), true); + assert.strictEqual(helpers.id_valid("__niceUs3rname__"), true); done(); }); it("1 char username is valid", function(done) { - assert.strictEqual(helpers.uuid_valid("a"), true); + assert.strictEqual(helpers.id_valid("a"), true); done(); }); it("should not exist (uuid)", function(done) {