swdb.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. const dateFormat = require('/usr/local/lib/node_modules/dateformat');
  2. module.exports = {
  3. defaultConfig: {
  4. enabled: true,
  5. debug: true,
  6. runs: true,
  7. apiKey: ''
  8. },
  9. defaultConfigDetails: {
  10. debug: { label: 'Print debug messages' },
  11. runs: { label: 'Also log runs' },
  12. apiKey: { label: 'SWDB instance API key', type: 'textarea' }
  13. },
  14. pluginName: 'SWDB',
  15. pluginDescription: 'Uploads data to SWDB.',
  16. target_host: 'localhost',
  17. target_port: '80',
  18. target_url_run: '/API/v1/log-run',
  19. target_url_profile: '/API/v1/log-profile',
  20. temp: {},
  21. proxy: null,
  22. config: null,
  23. /**
  24. * Initializes he plugin.
  25. *
  26. * @param proxy The proxy.
  27. * @param Global configurations.
  28. */
  29. init(proxy, config) {
  30. this.proxy = proxy;
  31. this.config = config;
  32. proxy.on('apiCommand', (req, resp) => {
  33. try {
  34. wizardID = '';
  35. command = '';
  36. apiKey = config.Config.Plugins[this.pluginName].apiKey;
  37. if (config.Config.Plugins[this.pluginName].enabled) {
  38. command = req["command"];
  39. wizardID = req["wizard_id"];
  40. }
  41. if (!this.temp[wizardID]) {
  42. this.temp[wizardID] = {};
  43. }
  44. // USER LOGIN: Upload profile
  45. if (command === 'HubUserLogin') {
  46. // Check that API key is filled in
  47. if (!apiKey) {
  48. this.log('error', `Profile upload is enabled, but missing API key. Check ${this.pluginName} settings.`);
  49. return;
  50. }
  51. this.log('info', 'Uploading profile to SWDB...')
  52. var request = require('/usr/local/lib/node_modules/request')
  53. var querystring = require('/usr/local/lib/node_modules/querystring');
  54. //var http = require('/usr/local/lib/node_modules/http');
  55. var http = require('http');
  56. //var fs = require('/usr/local/lib/node_modules/fs');
  57. var post_data = querystring.stringify({
  58. 'data' : JSON.stringify(resp),
  59. 'key' : apiKey
  60. });
  61. // An object of options to indicate where to post to
  62. var post_options = {
  63. host: this.target_host,
  64. port: this.target_port,
  65. path: this.target_url_profile,
  66. method: 'POST',
  67. headers: {
  68. 'Content-Type': 'application/x-www-form-urlencoded',
  69. 'Content-Length': Buffer.byteLength(post_data)
  70. }
  71. };
  72. // Set up the request
  73. var resp = ""
  74. var post_req = http.request(post_options, function(res) {
  75. res.setEncoding('utf8');
  76. res.on('data', function (chunk) {
  77. resp = chunk;
  78. });
  79. });
  80. // post the data
  81. post_req.write(post_data);
  82. post_req.end();
  83. }
  84. if (command === 'BattleScenarioStart') {
  85. //for (var key in req) {
  86. // this.log('DEBUG', `IVV SCE START: ${key}: ${req[key]}`);
  87. //}
  88. if (req["helper_list"] != null || req["mentor_helper_list"] != null || req["npc_friend_helper_list"] != null ){
  89. this.temp[wizardID].helper = 1;
  90. }
  91. else{
  92. this.temp[wizardID].helper = 0;
  93. }
  94. this.temp[wizardID].area = req.region_id;
  95. this.temp[wizardID].stage = req.stage_no;
  96. this.temp[wizardID].difficulty = req.difficulty;
  97. }
  98. if (command === 'BattleScenarioResult' || command === 'BattleDungeonResult' || command === 'BattleDimensionHoleDungeonResult') {
  99. //proxy.log({ type: 'info', source: 'plugin', name: this.pluginName, message: `IVV RUN RESULT: ${resp}` })
  100. for (var key in req) {
  101. this.log("info", `IVV REQ: ${key}: ${req[key]}`);
  102. }
  103. for (var key in resp) {
  104. this.log("info", `IVV RES: ${key}: ${resp[key]}`);
  105. }
  106. this.parse_normal(req, resp);
  107. }
  108. if (command === 'BattleRiftOfWorldsRaidResult') {
  109. this.parse_raid_rift(req, resp);
  110. }
  111. if (command === 'BattleRiftDungeonResult') {
  112. this.parse_elemental_rift(req, resp);
  113. }
  114. }
  115. catch (e) {
  116. proxy.log({ type: 'error', source: 'plugin', name: this.pluginName, message: `An unexpected error occured: ${e.message}` });
  117. }
  118. });
  119. },
  120. /**
  121. * Parses a reward item (no runes!).
  122. *
  123. * @param crate The crate object.
  124. * @return array of {item, unit, pieces, quantity, shapeshifting}
  125. */
  126. getItem(crate) {
  127. item = 0;
  128. unit = 0;
  129. pieces = 0;
  130. quantity = 0;
  131. shapeshifting = 0;
  132. if (crate.random_scroll && (crate.random_scroll.item_master_id === 1 || crate.random_scroll.item_master_id === 8 || crate.random_scroll.item_master_id === 2)){
  133. // 1: Unknown scroll
  134. // 2: Mystical Scroll
  135. // 8: Summoning Stones
  136. item = crate.random_scroll.item_master_id;
  137. quantity = crate.random_scroll.item_quantity;
  138. }
  139. if (crate.costume_point) {
  140. shapeshifting = crate.costume_point;
  141. }
  142. if (crate.rune_upgrade_stone) {
  143. item = 'Power Stone'; // TODO: Do they exist?
  144. quantity = crate.rune_upgrade_stone.item_quantity;
  145. }
  146. if (crate.unit_info) {
  147. unit = crate.unit_info.unit_master_id;
  148. }
  149. if (crate.material) {
  150. item = crate.material.item_master_id;
  151. quantity = crate.material.item_quantity;
  152. }
  153. if (crate.summon_pieces) {
  154. pieces = crate.summon_pieces.item_master_id;
  155. quantity = crate.summon_pieces.item_quantity;
  156. }
  157. if (crate.craft_stuff) {
  158. item = crate.craft_stuff.item_master_id;
  159. quantity = crate.craft_stuff.item_quantity;
  160. }
  161. drop = {item, unit, pieces, quantity, shapeshifting}
  162. return drop;
  163. },
  164. /**
  165. * TODO! Unaddapted.
  166. * Parses a rift reward item (no runes!).
  167. *
  168. * @param crate The crate object.
  169. * @return array of {item, unit, pieces, quantity}
  170. */
  171. getItemRift(item, entry) {
  172. if (item.type === 8) {
  173. const rune = item.info;
  174. entry.drop = 'Rune';
  175. entry.grade = `${rune.class}*`;
  176. entry.sell_value = rune.sell_value;
  177. entry.set = gMapping.rune.sets[rune.set_id];
  178. entry.slot = rune.slot_no;
  179. entry.efficiency = gMapping.getRuneEfficiency(rune).current;
  180. entry.rarity = gMapping.rune.class[rune.sec_eff.length];
  181. entry.main_stat = gMapping.getRuneEffect(rune.pri_eff);
  182. entry.prefix_stat = gMapping.getRuneEffect(rune.prefix_eff);
  183. rune.sec_eff.forEach((substat, i) => {
  184. entry[`sub${i + 1}`] = gMapping.getRuneEffect(substat);
  185. });
  186. }
  187. if (item.info.craft_type_id) {
  188. enhancement = this.getEnchantVals(item.info.craft_type_id, item.info.craft_type);
  189. entry.drop = enhancement.drop;
  190. entry.sell_value = item.sell_value;
  191. entry.set = enhancement.set;
  192. entry.main_stat = enhancement.type;
  193. entry.sub1 = enhancement.min;
  194. entry.sub2 = enhancement.max;
  195. }
  196. return entry;
  197. },
  198. /**
  199. * TODO! Will I need this.
  200. * Saves run data to a file in CSV format.
  201. *
  202. */
  203. saveToFile(entry, filename, headers, proxy) {
  204. const csvData = [];
  205. const self = this;
  206. fs.ensureFile(path.join(config.Config.App.filesPath, filename), err => {
  207. if (err) {
  208. return;
  209. }
  210. csv
  211. .fromPath(path.join(config.Config.App.filesPath, filename), { ignoreEmpty: true, headers, renameHeaders: true })
  212. .on('data', data => {
  213. csvData.push(data);
  214. })
  215. .on('end', () => {
  216. csvData.push(entry);
  217. csv.writeToPath(path.join(config.Config.App.filesPath, filename), csvData, { headers }).on('finish', () => {
  218. proxy.log({ type: 'success', source: 'plugin', name: self.pluginName, message: `Saved run data to ${filename}` });
  219. });
  220. });
  221. });
  222. },
  223. /**
  224. * Parses a battle data.
  225. * Valid for scenario, dungeons and Dimensional Hole.
  226. *
  227. * @param req The request
  228. * @param resp The response.
  229. */
  230. parse_normal(req, resp) {
  231. const { command } = req;
  232. const { wizard_id: wizardID, wizard_name: wizardName } = resp.wizard_info;
  233. const run = {};
  234. const run_party = {};
  235. const run_k_party = {};
  236. log = true;
  237. if (command === 'BattleDungeonResult') {
  238. //for (var key in req) {
  239. // this.log("DEBUG", `IVV DUNGEON REQ: ${key}: ${req[key]}`);
  240. //}
  241. if (req.dungeon_id > 10000){
  242. // Hall of Heroes or unknown
  243. log = false;
  244. }
  245. run.area = req.dungeon_id;
  246. run.stage = req.stage_id;
  247. run.difficulty = 0
  248. // TODO: Read request
  249. run.helper = 0;
  250. }
  251. if (command === 'BattleScenarioResult') {
  252. //for (var key in this.temp[wizardID]) {
  253. // this.log("DEBUG", `IVV TEMP: ${key}: ${this.temp[wizardID][key]}`);
  254. //}
  255. //for (var key in req) {
  256. // this.log("DEBUG", `IVV REQ: ${key}: ${req[key]}`);
  257. //}
  258. run.helper = this.temp[wizardID].helper;
  259. run.area = this.temp[wizardID].area;
  260. run.stage = this.temp[wizardID].stage;
  261. run.difficulty = this.temp[wizardID].difficulty;
  262. }
  263. if (command === 'BattleDimensionHoleDungeonResult') {
  264. //if (gMapping.dungeon[resp.dungeon_id]) {
  265. // run.dungeon = `${gMapping.dungeon[resp.dungeon_id]} Level ${resp.difficulty}`;
  266. //}
  267. //for (var key in req) {
  268. // this.log("DEBUG", `IVV DIMENSONALE REQ: ${key}: ${req[key]}`);
  269. //}
  270. run.area = resp.dungeon_id;
  271. run.stage = resp.difficulty;
  272. run.difficulty = 0
  273. run.helper = 0;
  274. }
  275. run.uid = wizardID;
  276. run.win = resp.win_lose; // 1/0 2 is lost in scenario
  277. run.dtime = dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss');
  278. const reward = resp.reward ? resp.reward : {};
  279. run.time = req.clear_time ? req.clear_time : 0;
  280. run.mana = reward.mana ? reward.mana : 0;
  281. run.energy = reward.energy ? reward.energy : 0;
  282. run.crystal = reward.crystal ? reward.crystal : 0;
  283. // TODO: GET
  284. //run.helper = 0;
  285. run.rune = {};
  286. run.unit = 0;
  287. run.unit_pieces = {};
  288. run.sd = 0;
  289. run.item = {};
  290. run.shapeshifting = 0;
  291. if (reward.crate) {
  292. run.mana = reward.crate.mana ? run.mana + reward.crate.mana : run.mana;
  293. run.energy = reward.crate.energy ? run.energy + reward.crate.energy : run.energy;
  294. run.crystal = reward.crate.crystal ? run.crystal + reward.crate.crystal : run.crystal;
  295. if (reward.crate.rune) {
  296. const rune = reward.crate.rune;
  297. //for (var key in rune) {
  298. // this.proxy.log({ type: 'info', source: 'plugin', name: this.pluginName, message: `IVV RUNE: ${key}: ${rune[key]}` })
  299. //}
  300. run.rune.id = rune.rune_id;
  301. run.rune.grade = rune.class;
  302. run.rune.value = rune.sell_value;
  303. run.rune.set = rune.set_id;
  304. run.rune.slot = rune.slot_no;
  305. run.rune.efficiency = gMapping.getRuneEfficiency(rune).current;
  306. run.rune.quality = rune.rank;
  307. run.rune.main = rune.pri_eff[0];
  308. run.rune.main_value = rune.pri_eff[1];
  309. if (rune.prefix_eff){
  310. run.rune.innate = rune.prefix_eff[0];
  311. run.rune.innate_value = rune.prefix_eff[1];
  312. }
  313. run.rune['substat_1'] = 0;
  314. run.rune['substat_1_value'] = 0;
  315. run.rune['substat_2'] = 0;
  316. run.rune['substat_2_value'] = 0;
  317. run.rune['substat_3'] = 0;
  318. run.rune['substat_3_value'] = 0;
  319. run.rune['substat_4'] = 0;
  320. run.rune['substat_4_value'] = 0;
  321. rune.sec_eff.forEach((substat, i) => {
  322. run.rune[`substat_${i + 1}`] = substat[0];
  323. run.rune[`substat_${i + 1}_value`] = substat[1];
  324. });
  325. }
  326. else {
  327. for (var key in reward.crate) {
  328. this.proxy.log({ type: 'info', source: 'plugin', name: this.pluginName, message: `IVV ITEM: ${key}: ${reward.crate[key]}` })
  329. }
  330. drop = this.getItem(reward.crate);
  331. if (drop.unit){
  332. run.unit.id = drop.unit;
  333. }
  334. if (drop.pieces){
  335. run.unit_pieces.id = drop.pieces;
  336. run.unit_pieces.quantity = drop.quantity;
  337. }
  338. if (drop.item){
  339. run.item.id = drop.item;
  340. run.item.quantity = drop.quantity;
  341. }
  342. run.shapeshifting = drop.shapeshifting;
  343. }
  344. }
  345. if (resp.instance_info) {
  346. run.sd = resp.instance_info;
  347. }
  348. if (resp.unit_list && resp.unit_list.length > 0) {
  349. resp.unit_list.forEach((unit, i) => {
  350. run_party[i] = unit.unit_master_id;
  351. run_k_party[i] = unit.unit_id;
  352. });
  353. }
  354. json_rune = '[';
  355. if (run.rune.id != undefined){
  356. json_rune += '{';
  357. json_rune += `"id": "${run.rune.id}", `;
  358. json_rune += `"stars": "${run.rune.grade}", `;
  359. json_rune += `"type": "${run.rune.set}", `;
  360. json_rune += `"slot": "${run.rune.slot}", `;
  361. json_rune += `"efficiency": "${run.rune.efficiency}", `;
  362. json_rune += `"quality": "${run.rune.quality}", `;
  363. // TODO: Get
  364. json_rune += `"ancient": 0, `;
  365. json_rune += `"value": "${run.rune.value}", `;
  366. json_rune += `"main_stat": "${run.rune.main}", `;
  367. json_rune += `"main_stat_value": "${run.rune.main_value}", `;
  368. json_rune += `"innate_stat": "${run.rune.innate}", `;
  369. json_rune += `"innate_stat_value": "${run.rune.innate_value}", `;
  370. json_rune += `"substat_1": "${run.rune.substat_1}", `;
  371. json_rune += `"substat_1_value": "${run.rune.substat_1_value}", `;
  372. json_rune += `"substat_2": "${run.rune.substat_2}", `;
  373. json_rune += `"substat_2_value": "${run.rune.substat_2_value}", `;
  374. json_rune += `"substat_3": "${run.rune.substat_3}", `;
  375. json_rune += `"substat_3_value": "${run.rune.substat_3_value}", `;
  376. json_rune += `"substat_4": "${run.rune.substat_4}", `;
  377. json_rune += `"substat_4_value": "${run.rune.substat_4_value}"`;
  378. json_rune += '}';
  379. }
  380. json_rune = json_rune + "]";
  381. json_item = '[';
  382. if (run.item.id != undefined){
  383. json_item += '{';
  384. json_item += `"id": "${run.item.id}", `;
  385. json_item += `"quantity": "${run.item.quantity}"`;
  386. json_item += '}';
  387. }
  388. json_item = json_item + "]";
  389. json_unit_pieces = '[';
  390. if (run.unit_pieces.length > 0){
  391. json_unit_pieces += '{';
  392. json_unit_pieces += `"id": "${run.unit_pieces.id}", `;
  393. json_unit_pieces += `"quantity": "${run.unit_pieces.quantity}"`;
  394. json_unit_pieces += '}';
  395. }
  396. json_unit_pieces = json_unit_pieces + "]";
  397. json_party = '[';
  398. resp.unit_list.forEach((unit, i) => {
  399. json_party = json_party + '{"unit_id": ' + run_party[i] + ', "unit_master_id": ' + run_k_party[i] + '},';
  400. });
  401. json_party = json_party.slice(0, -1) + "]";
  402. json = `{`;
  403. json += `"uid": "${run.uid}", `;
  404. json += `"dtime": "${run.dtime}", `;
  405. json += `"area": "${run.area}", `;
  406. json += `"stage": "${run.stage}", `;
  407. json += `"difficulty": "${run.difficulty}", `;
  408. json += `"win": "${run.win}", `;
  409. json += `"time": "${run.time}", `;
  410. json += `"mana": "${run.mana}", `;
  411. json += `"energy": "${run.energy}", `;
  412. json += `"crystal": "${run.crystal}", `;
  413. json += `"rune": ${json_rune}, `;
  414. json += `"sd": ${run.sd}, `;
  415. json += `"item": ${json_item}, `;
  416. json += `"unit": ${run.unit}, `;
  417. json += `"unit_pieces": ${json_unit_pieces}, `;
  418. json += `"shapeshifting": ${run.shapeshifting}, `;
  419. json += `"party": ${json_party}, `;
  420. json += `"helper": "${run.helper}"`;
  421. json += `}`;
  422. this.log('DEBUG', `json: ${json}`)
  423. //const filename = sanitize(`${wizardName}-${wizardID}-runs.csv`);
  424. //const filename = sanitize(`IVV-${wizardName}-${wizardID}-runs.csv`);
  425. //this.saveToFile(entry, filename, headers, proxy);
  426. // Make the request
  427. //var inspect = require('/usr/local/lib/node_modules/eyespect').inspector();
  428. var request = require('/usr/local/lib/node_modules/request')
  429. var querystring = require('/usr/local/lib/node_modules/querystring');
  430. //var http = require('/usr/local/lib/node_modules/http');
  431. var http = require('http');
  432. //var fs = require('/usr/local/lib/node_modules/fs');
  433. var post_data = querystring.stringify({
  434. 'data' : json,
  435. 'key' : apiKey
  436. });
  437. // An object of options to indicate where to post to
  438. var post_options = {
  439. host: this.target_host,
  440. port: this.target_port,
  441. path: this.target_url_run,
  442. method: 'POST',
  443. headers: {
  444. 'Content-Type': 'application/x-www-form-urlencoded',
  445. 'Content-Length': Buffer.byteLength(post_data)
  446. }
  447. };
  448. // Set up the request
  449. var resp = ""
  450. var post_req = http.request(post_options, function(res) {
  451. res.setEncoding('utf8');
  452. res.on('data', function (chunk) {
  453. resp = chunk;
  454. });
  455. });
  456. // post the data
  457. post_req.write(post_data);
  458. post_req.end();
  459. },
  460. /**
  461. * TODO Unaddapted.
  462. * Parses a battle data.
  463. * Valid for Rift Raids.
  464. *
  465. * @param req The request
  466. * @param resp The response.
  467. */
  468. parse_raid_rift(req, resp) {
  469. const { wizard_id: wizardID, wizard_name: wizardName } = resp.wizard_info;
  470. let run = {};
  471. if (gMapping.dungeon[req.dungeon_id]) {
  472. run.dungeon = `${gMapping.elemental_rift_dungeon[req.dungeon_id]}`;
  473. isElemental = true;
  474. }
  475. //const winLost = resp.win_lose === 1 ? 'Win' : 'Did not kill';
  476. run.dtime = dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss');
  477. //run.result = winLost;
  478. run.win = resp.win_lose;
  479. run.rune = {};
  480. run.unit = 0;
  481. run.unit_pieces = {};
  482. run.sd = 0;
  483. run.item = {};
  484. run.shapeshifting = 0;
  485. run.time = req.clear_time ? req.clear_time : 0;
  486. const reward = resp.reward ? resp.reward : {};
  487. if (resp.win_lose === 1) {
  488. // No crate: Mana of shapeshifting stones
  489. if (!reward.crate) {
  490. const reward = resp.battle_reward_list.find(value => value.wizard_id === resp.wizard_info.wizard_id).reward_list[0];
  491. if (reward.item_master_id === 6) {
  492. run.shapeshifting = reward.item_quantity;
  493. }
  494. else {
  495. run.mana = reward.item_quantity;
  496. }
  497. }
  498. // Rune craft item
  499. else if (reward.crate.changestones) {
  500. const item = {
  501. info: {
  502. craft_type: reward.crate.changestones[0].craft_type,
  503. craft_type_id: reward.crate.changestones[0].craft_type_id
  504. },
  505. sell_value: reward.crate.changestones[0].sell_value
  506. };
  507. run.drop= this.getItemRift(item, run);
  508. }
  509. // Rune
  510. else if (reward.crate.rune) {
  511. const rune = reward.crate.rune;
  512. //for (var key in rune) {
  513. // this.proxy.log({ type: 'info', source: 'plugin', name: this.pluginName, message: `IVV RUNE: ${key}: ${rune[key]}` })
  514. //}
  515. run.rune.id = rune.rune_id;
  516. run.rune.grade = rune.class;
  517. run.rune.value = rune.sell_value;
  518. run.rune.set = rune.set_id;
  519. run.rune.slot = rune.slot_no;
  520. run.rune.efficiency = gMapping.getRuneEfficiency(rune).current;
  521. run.rune.quality = rune.rank;
  522. run.rune.main = rune.pri_eff[0];
  523. run.rune.main_value = rune.pri_eff[1];
  524. if (rune.prefix_eff){
  525. run.rune.innate = rune.prefix_eff[0];
  526. run.rune.innate_value = rune.prefix_eff[1];
  527. }
  528. rune.sec_eff.forEach((substat, i) => {
  529. run.rune[`substat_${i + 1}`] = substat[0];
  530. run.rune[`substat_${i + 1}_value`] = substat[1];
  531. });
  532. }
  533. // Unit (Rainbowmon)
  534. else if (reward.crate.unit_info && reward.crate.unit_info.unit_master_id > 0) {
  535. run.unit.id = reward.crate.unit_info.unit_master_id;
  536. }
  537. // Item
  538. else if (!run.drop && resp.reward.crate) {
  539. //run.drop = this.getItem(reward.resp.reward.crate);
  540. if (resp.reward.crate.random_scroll && (resp.reward.crate.random_scroll.item_master_id === 1 || resp.reward.crate.random_scroll.item_master_id === 8 || resp.reward.crate.random_scroll.item_master_id === 2)){
  541. // 1: Unknown scroll
  542. // 2: Mystical Scroll
  543. // 8: Summoning Stones
  544. run.item.id = resp.reward.crate.random_scroll.item_master_id;
  545. run.item.quantity = resp.reward.crate.random_scroll.item_quantity;
  546. }
  547. //if (resp.reward.crate.costume_point) {
  548. // shapeshifting = resp.reward.crate.costume_point;
  549. //}
  550. //if (resp.reward.crate.rune_upgrade_stone) {
  551. // item = 'Power Stone'; // TODO: Do they exist?
  552. // quantity = resp.reward.crate.rune_upgrade_stone.item_quantity;
  553. //}
  554. //if (resp.reward.crate.unit_info) {
  555. // unit = resp.reward.crate.unit_info.unit_master_id;
  556. //}
  557. if (resp.reward.crate.material) {
  558. item = resp.reward.crate.material.item_master_id;
  559. quantity = resp.reward.crate.material.item_quantity;
  560. }
  561. //if (resp.reward.crate.summon_pieces) {
  562. // pieces = resp.reward.crate.summon_pieces.item_master_id;
  563. // quantity = resp.reward.crate.summon_pieces.item_quantity;
  564. //}
  565. if (resp.reward.crate.craft_stuff) {
  566. item = resp.reward.crate.craft_stuff.item_master_id;
  567. quantity = resp.reward.crate.craft_stuff.item_quantity;
  568. }
  569. }
  570. else {
  571. run.drop = 'unknown';
  572. }
  573. }
  574. if (resp.unit_list && resp.unit_list.length > 0) {
  575. resp.unit_list.forEach((unit, i) => {
  576. run_party[i] = unit.unit_master_id;
  577. run_k_party[i] = unit.unit_id;
  578. });
  579. }
  580. //const filename = sanitize(`${wizardName}-${wizardID}-raid-runs.csv`);
  581. //this.saveToFile(run. filename, headers, proxy);
  582. },
  583. /**
  584. * TODO Unaddapted.
  585. * Parses a battle data.
  586. * Valid for Rift Dungeons.
  587. *
  588. * @param req The request
  589. * @param resp The response.
  590. */
  591. parse_elemental_rift(req, resp) {
  592. const { wizard_id: wizardID, wizard_name: wizardName } = resp.wizard_info;
  593. let entry = {};
  594. if (gMapping.dungeon[req.dungeon_id]) {
  595. entry.dungeon = `${gMapping.elemental_rift_dungeon[req.dungeon_id]}`;
  596. isElemental = true;
  597. }
  598. const winLost = req.battle_result === 1 ? 'Win' : 'Did not kill';
  599. entry.date = dateFormat(new Date(), 'yyyy-mm-dd HH:MM');
  600. entry.result = winLost;
  601. if (resp.item_list && resp.item_list.length > 0) {
  602. resp.item_list.forEach((item, i) => {
  603. if (item.is_boxing !== 1 || item.id === 2001) {
  604. entry[`item${i + 1}`] = `${gMapping.craftMaterial[item.id]} x${item.quantity}`;
  605. } else {
  606. if (item.id === 2) {
  607. entry.drop = 'Mystical Scroll';
  608. }
  609. if (item.id === 8) {
  610. entry.drop = `Summoning Stones x${item.item_quantity}`;
  611. }
  612. if (item.info && item.info.unit_master_id > 0) {
  613. entry.drop = `${gMapping.getMonsterName(item.info.unit_master_id)} ${item.class}`;
  614. }
  615. if ((item.info && item.info.craft_type_id) || item.type === 8) {
  616. entry = this.getItemRift(item, entry);
  617. }
  618. }
  619. });
  620. }
  621. if (resp.unit_list && resp.unit_list.length > 0) {
  622. resp.unit_list.forEach((unit, i) => {
  623. entry[`team${i + 1}`] = gMapping.getMonsterName(unit.unit_master_id);
  624. });
  625. }
  626. json_rune = '[';
  627. if (run.rune.length() > 0){
  628. json_rune += `"id": "${run.rune.id}", `;
  629. json_rune += `"grade": "${run.rune.grade}", `;
  630. json_rune += `"set": "${run.rune.set}", `;
  631. json_rune += `"slot": "${run.rune.slot}", `;
  632. json_rune += `"efficiency": "${run.rune.efficiency}", `;
  633. json_rune += `"quality": "${run.rune.quality}", `;
  634. json_rune += `"value": "${run.rune.value}", `;
  635. json_rune += `"main_stat": "${run.rune.main}", `;
  636. json_rune += `"main_stat_value": "${run.rune.main_value}", `;
  637. json_rune += `"innate_stat": "${run.rune.innate}", `;
  638. json_rune += `"innate_stat_value": "${run.rune.innate_value}", `;
  639. json_rune += `"substat_1": "${run.rune.substat_1}", `;
  640. json_rune += `"substat_1_value": "${run.rune.substat_1_value}", `;
  641. json_rune += `"substat_2": "${run.rune.substat_2}", `;
  642. json_rune += `"substat_2_value": "${run.rune.substat_2_value}", `;
  643. json_rune += `"substat_3": "${run.rune.substat_3}", `;
  644. json_rune += `"substat_4_value": "${run.rune.substat_3_value}", `;
  645. json_rune += `"substat_4": "${run.rune.substat_4}", `;
  646. json_rune += `"substat_4_value": "${run.rune.substat_4_value}", `;
  647. }
  648. json_rune = json_party.slice(0, -1) + "]";
  649. json_item = '[';
  650. if (run.item.length() > 0){
  651. json_item += `"id": "${run.item.id}", `;
  652. json_item += `"quantity": "${run.item.quantity}", `;
  653. }
  654. json_item = json_party.slice(0, -1) + "]";
  655. json_unit_pieces = '[';
  656. if (run.unit_pieces.length() > 0){
  657. json_unit_pieces += `"id": "${run.unit_pieces.id}", `;
  658. json_unit_pieces += `"quantity": "${run.unit_pieces.quantity}", `;
  659. }
  660. json_unit_pieces = json_party.slice(0, -1) + "]";
  661. json_party = '[';
  662. resp.unit_list.forEach((unit, i) => {
  663. json_party = json_party + '{"unit_id": ' + run_party[i] + ', "unit_master_id": ' + run_k_party[i] + '},';
  664. });
  665. json_party = json_party.slice(0, -1) + "]";
  666. //this.log('DEBUG', `IVV json_party: ${json_party}`)
  667. json = `{`;
  668. json += `"dtime": "${run.dtime}", `;
  669. json += `"area": "${run.dungeon}", `;
  670. json += `"stage": "${run.stage}", `;
  671. json += `"difficulty": "${run.difficulty}", `;
  672. json += `"win": "${run.win}", `;
  673. json += `"time": "${run.time}", `;
  674. json += `"mana": "${run.mana}", `;
  675. json += `"energy": "${run.energy}", `;
  676. json += `"crystal": "${run.crystal}", `;
  677. json += `"rune": ${json_rune}, `;
  678. json += `"sd": ${run.sd}, `;
  679. json += `"item": ${json_item}, `;
  680. json += `"unit": ${run.unit}, `;
  681. json += `"unit_pieces": ${json_unit_pieces}, `;
  682. json += `"sapeshifting": ${run.sapeshifting}, `;
  683. json += `"party": ${json_party}`;
  684. json += `}`;
  685. this.log('DEBUG', `json: ${json}`)
  686. },
  687. /**
  688. * TODO ???
  689. */
  690. getEnchantVals(craftID, craftType) {
  691. const map = {};
  692. const typeNumber = Number(craftID.toString().slice(-4, -2));
  693. map.set = gMapping.rune.sets[Number(craftID.toString().slice(0, -4))];
  694. map.grade = gMapping.rune.quality[Number(craftID.toString().slice(-1))];
  695. map.type = gMapping.rune.effectTypes[typeNumber];
  696. if (craftType === 2) {
  697. map.min = gMapping.grindstone[typeNumber].range[Number(craftID.toString().slice(-1))].min;
  698. map.max = gMapping.grindstone[typeNumber].range[Number(craftID.toString().slice(-1))].max;
  699. map.drop = 'Grindstone';
  700. } else {
  701. map.min = gMapping.enchanted_gem[typeNumber].range[Number(craftID.toString().slice(-1))].min;
  702. map.max = gMapping.enchanted_gem[typeNumber].range[Number(craftID.toString().slice(-1))].max;
  703. map.drop = 'Enchanted Gem';
  704. }
  705. return map;
  706. },
  707. /**
  708. * Prints a messageto the SWEX output.
  709. *
  710. * @param type Log type. Debug type will be printed depending on config.
  711. * @param msg The message to log.
  712. */
  713. log(type, msg){
  714. //if (type != "debug" || this.config.Config.Plugins[this.pluginName].debug == true){
  715. this.proxy.log({ type: type, source: 'plugin', name: this.pluginName, message: msg });
  716. //}
  717. }
  718. };