skins.js 2.5 KB

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