skins.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. var http = require('http');
  2. var https = require('https');
  3. var fs = require('fs');
  4. var lwip = require('lwip');
  5. var urlparse = require('url').parse;
  6. /*
  7. * Skin retrieval methods are based on @jomo's CLI Crafatar implementation.
  8. * https://github.com/jomo/Crafatar
  9. */
  10. function extract_face(inname, outname, callback) {
  11. var outfile = fs.createWriteStream(outname);
  12. lwip.open(inname, function(err, image) {
  13. if (err) throw err;
  14. image.batch()
  15. .crop(8, 8, 15, 15)
  16. .writeFile(outname, function(err) {
  17. if (err) throw err;
  18. callback();
  19. });
  20. });
  21. }
  22. module.exports = {
  23. get_profile: function(uuid, callback) {
  24. https.get("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid, function(res) {
  25. if (res.statusCode == "204") {
  26. callback(null);
  27. return null;
  28. }
  29. res.on('data', function(d) {
  30. var profile = JSON.parse(d);
  31. if (profile.error) {
  32. // usually this is something like TooManyRequestsException
  33. console.error(profile.error);
  34. callback(null);
  35. } else {
  36. callback(profile);
  37. }
  38. });
  39. }).on('error', function(err) {
  40. throw err;
  41. });
  42. },
  43. skin_url: function(profile) {
  44. var url = null;
  45. if (profile && profile.properties) {
  46. profile.properties.forEach(function(prop) {
  47. if (prop.name == 'textures') {
  48. var json = Buffer(prop.value, 'base64').toString();
  49. var props = JSON.parse(json);
  50. url = props && props.textures && props.textures.SKIN && props.textures.SKIN.url;
  51. }
  52. });
  53. }
  54. return url;
  55. },
  56. skin_file: function(url, filename, callback) {
  57. var tmpname = "skins/tmp/" + filename;
  58. var outname = "skins/" + filename;
  59. var tmpfile = fs.createWriteStream(tmpname);
  60. var prot = http;
  61. if (urlparse(url).protocol == "https") prot = https;
  62. prot.get(url, function(res) {
  63. res.on('data', function(data) {
  64. tmpfile.write(data);
  65. }).on('end', function() {
  66. tmpfile.end();
  67. extract_face(tmpname, outname, function() {
  68. fs.unlink(tmpname, function(err) { // unlink = delete
  69. if (err) console.error(err);
  70. });
  71. callback(); // outside unlink callback cause we don't have to wait until it's deleted
  72. });
  73. });
  74. }).on('error', function(err) {
  75. throw err;
  76. });
  77. },
  78. resize_img: function(inname, size, callback) {
  79. lwip.open(inname, function(err, image) {
  80. if (err) throw err;
  81. image.batch()
  82. .resize(size, size, "nearest-neighbor") // nearest-neighbor doesn't blur
  83. .toBuffer('png', function(err, buffer) {
  84. callback(buffer);
  85. });
  86. });
  87. }
  88. };