helpers.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. var networking = require('./networking');
  2. var config = require('./config');
  3. var cache = require('./cache');
  4. var skins = require('./skins');
  5. var valid_uuid = /^[0-9a-f]{32}$/;
  6. var hash_pattern = /[0-9a-f]+$/;
  7. function get_hash(url) {
  8. return hash_pattern.exec(url)[0].toLowerCase();
  9. }
  10. // requests skin for +uuid+ and extracts face/helm if image hash in +details+ changed
  11. // callback contains error, image hash
  12. function store_images(uuid, details, callback) {
  13. // get profile for +uuid+
  14. networking.get_profile(uuid, function(err, profile) {
  15. if (err) {
  16. callback(err, null);
  17. } else {
  18. var skinurl = skin_url(profile);
  19. if (skinurl) {
  20. console.log(uuid + " " + skinurl);
  21. // set file paths
  22. var hash = get_hash(skinurl);
  23. if (details && details.h == hash) {
  24. // hash hasn't changed
  25. console.log(uuid + " hash has not changed");
  26. cache.update_timestamp(uuid);
  27. callback(null, hash);
  28. } else {
  29. // hash has changed
  30. console.log(uuid + "new hash: " + hash);
  31. var facepath = __dirname + '/../' + config.faces_dir + hash + ".png";
  32. var helmpath = __dirname + '/../' + config.helms_dir + hash + ".png";
  33. // download skin, extract face/helm
  34. networking.skin_file(skinurl, facepath, helmpath, function(err) {
  35. if (err) {
  36. callback(err, null);
  37. } else {
  38. cache.save_hash(uuid, hash);
  39. callback(null, hash);
  40. }
  41. });
  42. }
  43. } else {
  44. // profile found, but has no skin
  45. callback(null, null);
  46. }
  47. }
  48. });
  49. }
  50. // exracts the skin url of a +profile+ object
  51. // returns null when no url found (user has no skin)
  52. function skin_url(profile) {
  53. var url = null;
  54. if (profile && profile.properties) {
  55. profile.properties.forEach(function(prop) {
  56. if (prop.name == 'textures') {
  57. var json = Buffer(prop.value, 'base64').toString();
  58. var props = JSON.parse(json);
  59. url = props && props.textures && props.textures.SKIN && props.textures.SKIN.url || null;
  60. }
  61. });
  62. }
  63. return url;
  64. }
  65. // decides whether to get an image from disk or to download it
  66. // callback contains error, status, hash
  67. // the status gives information about how the image was received
  68. // -1: error
  69. // 1: found on disk
  70. // 2: profile requested/found, skin downloaded from mojang servers
  71. // 3: profile requested/found, but it has no skin
  72. function get_image_hash(uuid, callback) {
  73. cache.get_details(uuid, function(err, details) {
  74. if (err) {
  75. callback(err, -1, null);
  76. } else {
  77. if (details && details.t + config.local_cache_time >= new Date().getTime()) {
  78. // uuid known + recently updated
  79. console.log(uuid + " uuid known & recently updated");
  80. callback(null, 1, details.h);
  81. } else {
  82. console.log(uuid + " uuid not known or too old");
  83. store_images(uuid, details, function(err, hash) {
  84. if (err) {
  85. callback(err, -1, details && details.h);
  86. } else {
  87. console.log(uuid + " hash: " + hash);
  88. callback(null, (hash ? 2 : 3), hash);
  89. }
  90. });
  91. }
  92. }
  93. });
  94. }
  95. var exp = {};
  96. // returns true if the +uuid+ is a valid uuid
  97. // the uuid may be not exist, however
  98. exp.uuid_valid = function(uuid) {
  99. return valid_uuid.test(uuid);
  100. };
  101. // handles requests for +uuid+ images with +size+
  102. // callback contains error, status, image buffer
  103. // image is the user's face+helm when helm is true, or the face otherwise
  104. // for status, see get_image_hash
  105. exp.get_avatar = function(uuid, helm, size, callback) {
  106. console.log("\nrequest: " + uuid);
  107. get_image_hash(uuid, function(err, status, hash) {
  108. if (hash) {
  109. var filepath = __dirname + '/../' + (helm ? config.helms_dir : config.faces_dir) + hash + ".png";
  110. skins.resize_img(filepath, size, function(img_err, result) {
  111. if (img_err) {
  112. callback(img_err, -1, null);
  113. } else {
  114. // we might have a hash although an error occured
  115. // (e.g. Mojang servers not reachable, using outdated hash)
  116. callback(err, (err ? -1 : status), result);
  117. }
  118. });
  119. } else {
  120. // hash is null when uuid has no skin
  121. callback(err, status, null);
  122. }
  123. });
  124. };
  125. module.exports = exp;