swdb.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /**
  2. *
  3. * List of processed commands:
  4. *
  5. * - HubUserLogin
  6. * - BattleDungeonResult
  7. * - BattleScenarioResult
  8. * - BattleDimensionHoleDungeonResult
  9. * - BattleTrialTowerResult_v2
  10. *
  11. */
  12. const dateFormat = require('/usr/local/lib/node_modules/dateformat');
  13. var querystring = require('querystring');
  14. var http = require('http');
  15. module.exports = {
  16. defaultConfig: {
  17. enabled: true,
  18. debug: true,
  19. runs: true,
  20. apiKey: '',
  21. //host: 'http://localhost',
  22. host: 'localhost',
  23. port: '80',
  24. },
  25. defaultConfigDetails: {
  26. debug: { label: 'Print debug messages' },
  27. runs: { label: 'Also log runs' },
  28. apiKey: { label: 'SWDB instance API key', type: 'textarea' },
  29. host: { label: 'Host running the SWDB instance', type: 'textarea' },
  30. port: { label: 'Port', type: 'textarea' }
  31. },
  32. pluginName: 'SWDB',
  33. pluginDescription: 'Uploads data to SWDB.',
  34. temp: {},
  35. proxy: null,
  36. config: null,
  37. request: null,
  38. eventStartReq: null,
  39. eventStartRes: null,
  40. /**
  41. * Initializes he plugin.
  42. *
  43. * @param proxy The proxy.
  44. * @param config Global configurations.
  45. */
  46. init(proxy, config) {
  47. this.proxy = proxy;
  48. this.config = config;
  49. proxy.on('apiCommand', (req, resp) => {
  50. try {
  51. wizardID = '';
  52. command = '';
  53. apiKey = config.Config.Plugins[this.pluginName].apiKey;
  54. if (config.Config.Plugins[this.pluginName].enabled) {
  55. command = req["command"];
  56. // Check the API key.
  57. if (!apiKey) {
  58. this.log('error', `Profile upload is enabled, but missing API key. Check ${this.pluginName} settings.`);
  59. return;
  60. }
  61. this.processCommand(command, req, resp);
  62. }
  63. }
  64. catch (e) {
  65. this.log('error', `An unexpected error occured: ${e.message}`);
  66. }
  67. });
  68. },
  69. /**
  70. * Switches the command and calls the appropiate function.
  71. *
  72. * @param command The command nade.
  73. * @param req The full request data.
  74. * @param res The full response.
  75. */
  76. processCommand(command, req, res){
  77. // Process the command
  78. var apiCommand = "";
  79. var success = null;
  80. var start = false;
  81. switch (command){
  82. // Start events. Save in case they are needed.
  83. case 'BattleDungeonStart':
  84. case 'BattleScenarioStart':
  85. case 'BattleDimensionHoleDungeonStart':
  86. case 'BattleTrialTowerStart_v2':
  87. case 'BattleRiftDungeonStart':
  88. this.eventStartReq = req;
  89. this.eventStartRes = res;
  90. break;
  91. // Profile login
  92. case 'HubUserLogin':
  93. apiCommand = "upload_profile";
  94. success = "Profile uploaded sucesfully!"
  95. break;
  96. // Catalog status
  97. case 'GetUnitCollection':
  98. apiCommand = "update_collection";
  99. success = "Collection updated sucesfully!"
  100. break;
  101. // Profile logbook
  102. case 'GetLobbyWizardLog':
  103. apiCommand = "update_logbook";
  104. success = "Logbook updated succesfully!";
  105. break;
  106. // Battle runs
  107. case 'BattleDungeonResult':
  108. apiCommand = "upload_run_dungeon";
  109. success = "Cairos run logged sucesfully!"
  110. break;
  111. case 'BattleScenarioResult':
  112. apiCommand = "upload_run_scenario";
  113. success = "Scenario run logged sucesfully!"
  114. break;
  115. case 'BattleDimensionHoleDungeonResult':
  116. apiCommand = "upload_run_dimension";
  117. success = "Dimension Hole run logged sucesfully!"
  118. break;
  119. case 'BattleTrialTowerResult_v2':
  120. apiCommand = "upload_run_toa";
  121. success = "TOA run logged sucesfully!"
  122. break;
  123. case 'BattleRiftDungeonResult':
  124. apiCommand = "upload_run_rift";
  125. success = "Rift Dungeon run logged sucesfully!"
  126. start = true;
  127. break;
  128. }
  129. if (apiCommand != ""){
  130. this.command(apiCommand, req, res, start, success);
  131. }
  132. },
  133. /**
  134. * Calls an arbitrary command on the SWDB APIv2.
  135. *
  136. * @param command Command nade.
  137. * @param req The full request data.
  138. * @param res The full response data.
  139. * @param start Indicates if event start request and response are needed.
  140. * @param success Optional. Message to show on success.
  141. */
  142. command(command, req, res, start = false, success = null){
  143. // Override success message if empty
  144. if (success == null || success == ""){
  145. sucess = `Command ${command} succesfully executed!`
  146. }
  147. this.log('debug', `Starting ${command}...`);
  148. // Generate POST data
  149. var post_data;
  150. if (start == false){
  151. post_data = querystring.stringify({
  152. 'request' : JSON.stringify(req),
  153. 'response' : JSON.stringify(res),
  154. 'key' : config.Config.Plugins[this.pluginName].apiKey
  155. });
  156. }
  157. else{
  158. post_data = querystring.stringify({
  159. 'request' : JSON.stringify(req),
  160. 'response' : JSON.stringify(res),
  161. 'start_request' : JSON.stringify(this.eventStartReq),
  162. 'start_response' : JSON.stringify(this.eventStartRes),
  163. 'key' : config.Config.Plugins[this.pluginName].apiKey
  164. });
  165. }
  166. // Configure POST requets
  167. var post_options = {
  168. host: config.Config.Plugins[this.pluginName].host,
  169. port: config.Config.Plugins[this.pluginName].port,
  170. path: '/API/v2/' + command,
  171. method: 'POST',
  172. headers: {
  173. 'Content-Type': 'application/x-www-form-urlencoded',
  174. 'Content-Length': Buffer.byteLength(post_data)
  175. }
  176. };
  177. // Set up the request
  178. var post_req = http.request(post_options, (function(post_res) {
  179. post_res.setEncoding('utf8');
  180. post_res.on('data', (function (body) {
  181. switch (post_res.statusCode){
  182. case 200:
  183. case 201:
  184. this.log('success', `${success} [${post_res.statusCode}]`);
  185. break;
  186. case 400:
  187. this.log('error', `[HTTP/1.1 400] There were errors importing the data: ${JSON.stringify(body)}`);
  188. break;
  189. case 404:
  190. this.log('error', '[HTTP/1.1 404] URL not found.');
  191. break;
  192. case 500:
  193. this.log('error', '[HTTP/1.1 500] The server returned an error.');
  194. break;
  195. default:
  196. this.log('error', `[HTTP/1.1 ${post_res.statusCode}] Unexpected error.`);
  197. }
  198. }).bind(this));
  199. }).bind(this));
  200. // Perform the request
  201. post_req.write(post_data);
  202. post_req.end();
  203. },
  204. /**
  205. * Prints a message to the SWEX output and to the console.
  206. *
  207. * @param type Log type. Debug type will be printed depending on config.
  208. * @param msg The message to log.
  209. */
  210. log(type, msg){
  211. if (type != "debug" || this.config.Config.Plugins[this.pluginName].debug == true){
  212. this.proxy.log({ type: type, source: 'plugin', name: this.pluginName, message: msg });
  213. pad_type = type.substring(0, 5).padEnd(5, ' ');
  214. pad_plugin = this.pluginName.substring(0, 4).padEnd(4, ' ');
  215. console.log(`[${pad_plugin}][${pad_type}] ${msg}`);
  216. }
  217. }
  218. };