networking.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. var logging = require("./logging");
  2. var request = require("request");
  3. var config = require("./config");
  4. var skins = require("./skins");
  5. var fs = require("fs");
  6. var session_url = "https://sessionserver.mojang.com/session/minecraft/profile/";
  7. var skins_url = "https://skins.minecraft.net/MinecraftSkins/";
  8. // exracts the skin url of a +profile+ object
  9. // returns null when no url found (user has no skin)
  10. function extract_skin_url(profile) {
  11. var url = null;
  12. if (profile && profile.properties) {
  13. profile.properties.forEach(function(prop) {
  14. if (prop.name == "textures") {
  15. var json = Buffer(prop.value, "base64").toString();
  16. var props = JSON.parse(json);
  17. url = props && props.textures && props.textures.SKIN && props.textures.SKIN.url || null;
  18. }
  19. });
  20. }
  21. return url;
  22. }
  23. // make a request to skins.miencraft.net
  24. // the skin url is taken from the HTTP redirect
  25. var get_username_url = function(name, callback) {
  26. request.get({
  27. url: skins_url + name + ".png",
  28. timeout: config.http_timeout,
  29. followRedirect: false
  30. }, function(error, response, body) {
  31. if (!error && response.statusCode == 301) {
  32. // skin_url received successfully
  33. logging.log(name + " skin url received");
  34. callback(null, response.headers.location);
  35. } else if (error) {
  36. callback(error, null);
  37. } else if (response.statusCode == 404) {
  38. // skin (or user) doesn't exist
  39. logging.log(name + " has no skin");
  40. callback(null, null);
  41. } else if (response.statusCode == 429) {
  42. // Too Many Requests
  43. // Never got this, seems like skins aren't limited
  44. logging.warn(body || "Too many requests");
  45. callback(null, null);
  46. } else {
  47. logging.error(name + " Unknown error:");
  48. logging.error(response);
  49. callback(body || "Unknown error", null);
  50. }
  51. });
  52. };
  53. // make a request to sessionserver
  54. // the skin_url is taken from the profile
  55. var get_uuid_url = function(uuid, callback) {
  56. request.get({
  57. url: session_url + uuid,
  58. timeout: config.http_timeout // ms
  59. }, function (error, response, body) {
  60. if (!error && response.statusCode == 200) {
  61. // profile downloaded successfully
  62. logging.log(uuid + " profile downloaded");
  63. callback(null, extract_skin_url(JSON.parse(body)));
  64. } else if (error) {
  65. callback(error, null);
  66. } else if (response.statusCode == 204 || response.statusCode == 404) {
  67. // we get 204 No Content when UUID doesn't exist (including 404 in case they change that)
  68. logging.log(uuid + " uuid does not exist");
  69. callback(null, null);
  70. } else if (response.statusCode == 429) {
  71. // Too Many Requests
  72. callback(body || "Too many requests", null);
  73. } else {
  74. logging.error(uuid + " Unknown error:");
  75. logging.error(response);
  76. callback(body || "Unknown error", null);
  77. }
  78. });
  79. };
  80. var exp = {};
  81. // download skin_url for +uuid+ (name or uuid)
  82. // callback contains error, skin_url
  83. exp.get_skin_url = function(uuid, callback) {
  84. if (uuid.length <= 16) {
  85. get_username_url(uuid, function(err, url) {
  86. callback(err, url);
  87. });
  88. } else {
  89. get_uuid_url(uuid, function(err, url) {
  90. callback(err, url);
  91. });
  92. }
  93. };
  94. // downloads skin file from +url+
  95. // callback contains error, image
  96. exp.get_skin = function(url, callback) {
  97. request.get({
  98. url: url,
  99. encoding: null, // encoding must be null so we get a buffer
  100. timeout: config.http_timeout // ms
  101. }, function (error, response, body) {
  102. if (!error && response.statusCode == 200) {
  103. // skin downloaded successfully
  104. logging.log("downloaded skin");
  105. logging.debug(url);
  106. callback(null, body);
  107. } else {
  108. if (error) {
  109. logging.error("Error downloading '" + url + "': " + error);
  110. } else if (response.statusCode == 404) {
  111. logging.warn("texture not found (404): " + url);
  112. } else if (response.statusCode == 429) {
  113. // Too Many Requests
  114. // Never got this, seems like textures aren't limited
  115. logging.warn("too many requests for " + url);
  116. logging.warn(body);
  117. } else {
  118. logging.error("unknown error for " + url);
  119. logging.error(response);
  120. logging.error(body);
  121. error = "unknown error"; // Error needs to be set, otherwise null in callback
  122. }
  123. callback(error, null);
  124. }
  125. });
  126. };
  127. module.exports = exp;