Hero Wars CSV Export

A script for intercepting data for the Hero Wars game and converting it to csv.

目前为 2024-06-27 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Hero Wars CSV Export
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.0.9
  5. // @description A script for intercepting data for the Hero Wars game and converting it to csv.
  6. // @description:zh 一个脚本,用于截取英雄战争游戏的数据并将其转换为csv。
  7. // @description:ja Hero Warsゲームのデータを傍受してcsvに変換するためのスクリプト。
  8. // @description:ru Скрипт для перехвата данных для игры Hero Wars и преобразования их в csv.
  9. // @description:es Un script para interceptar datos para el juego Hero Wars y convertirlos a csv.
  10. // @description:pt Um script para interceptar dados para o jogo Hero Wars e convertê-los em csv.
  11. // @author EnterBrain42
  12. // @match https://www.hero-wars.com/*
  13. // @require https://openuserjs.org/src/libs/sizzle/GM_config.js
  14. // @icon https://www.google.com/s2/favicons?sz=64&domain=www.hero-wars.com
  15. // @grant GM.setValue
  16. // @grant GM.getValue
  17. // @grant GM_registerMenuCommand
  18. // @grant GM_setClipboard
  19. // @license MIT
  20. // ==/UserScript==
  21.  
  22. (function() {
  23. 'use strict';
  24.  
  25. (function(open) {
  26. function jsonResponseHandler(jsonResponse) {
  27. //console.log(typeof jsonResponse);
  28. //var jsonResponse = JSON.parse(jsonResponseText);
  29. if (Array.isArray(jsonResponse.results)){
  30. jsonResponse.results.forEach(function(item, i, arr) {
  31. //console.log( item );
  32. if ("result" in item && typeof item.result === 'object' && item.result !== null){
  33. if ("response" in item.result && typeof item.result.response === 'object' && item.result.response !== null){
  34. //console.log( item.result.response );
  35. //guild teams
  36. if ("teams" in item.result.response && typeof item.result.response.teams === 'object' && item.result.response.teams !== null){
  37. console.log("Guild Teams");
  38. var clanTeams = JSON.stringify(item.result.response.teams);
  39. clanTeams = clanTeams.replace(/^\{/g,'[');
  40. clanTeams = clanTeams.replace(/\}$/g,']');
  41. clanTeams = clanTeams.replace(/,"userId":\d+/g,'');
  42. clanTeams = clanTeams.replace(/"(\d+)":\{"clanDefence_titans"(.*?)\},"clanDefence_heroes"/g,'{"userId":$1,"clanDefence_titans"$2,"totems":[],"clanDefence_heroes"');
  43. clanTeams = clanTeams.replace(/\},"clanDefence_heroes"/g,',"totems":[],"clanDefence_heroes"');
  44. clanTeams = clanTeams.replace(/("element":"(light)","elementSpiritLevel":\d+,"elementSpiritStar":[^0])(,.*?\}\},"totems":\[)/g,'$1$3"$2",');
  45. clanTeams = clanTeams.replace(/("element":"(dark)","elementSpiritLevel":\d+,"elementSpiritStar":[^0])(,.*?\}\},"totems":\[)/g,'$1$3"$2",');
  46. clanTeams = clanTeams.replace(/("element":"(earth)","elementSpiritLevel":\d+,"elementSpiritStar":[^0])(,.*?\}\},"totems":\[)/g,'$1$3"$2",');
  47. clanTeams = clanTeams.replace(/("element":"(fire)","elementSpiritLevel":\d+,"elementSpiritStar":[^0])(,.*?\}\},"totems":\[)/g,'$1$3"$2",');
  48. clanTeams = clanTeams.replace(/("element":"(water)","elementSpiritLevel":\d+,"elementSpiritStar":[^0])(,.*?\}\},"totems":\[)/g,'$1$3"$2",');
  49. clanTeams = clanTeams.replace(/,\],"clanDefence_heroes"/g,'],"clanDefence_heroes"');
  50. clanTeams = clanTeams.replace(/"\d+":\{"id":\d+,"level":\d+,"star":\d+,"element":"\w+","elementSpiritLevel":\d+,"elementSpiritStar":\d+,"power":(\d+)\}/g,'$1');
  51. clanTeams = clanTeams.replace(/\{"units":\{(.*?)\}/g,'[$1]');
  52. clanTeams = clanTeams.replace(/"banner":null\}/g,'"pet":0,"banner":[0,0,0]');
  53. clanTeams = clanTeams.replace(/"banner":\{"id":\d+,"slots":[\[\{](.*?)[\]\}]\}\}/g,function (match, p1, offset, string) {
  54. var resultString = p1.replace(/"\d+":/g,'');
  55. if (resultString == '') { resultString = "0"; }
  56. var resultStringArr = resultString.split(',');
  57. while (resultStringArr.length < 3) { // выводит 0, затем 1, затем 2
  58. resultStringArr.push(0);
  59. }
  60. resultString = resultStringArr.join();
  61. return '"pet":0,"banner":['+resultString+']';
  62. });
  63. clanTeams = clanTeams.replace(/"\d+":\{"id":\d+,"level":\d+,"color":\d+,"star":\d+,"power":(\d+)[\]\}]/g,'$1');
  64. clanTeams = clanTeams.replace(/,"\d+":\{"id":\d+,"level":\d+,"color":\d+,"star":\d+,"type":"pet","power":(\d+)\}\},"pet":0/g,'],"pet":$1');
  65. clanTeams = clanTeams.replace(/\},"pet":0/g,'],"pet":0');
  66. GM.setValue("clanTeams", clanTeams);
  67. //console.log(clanTeams);
  68. }
  69. //My Heroes
  70. if (item.ident == 'heroGetAll'){
  71. console.log("My Heroes");
  72. var heroGetAll = JSON.stringify(item.result.response);
  73. heroGetAll = heroGetAll.replace(/^\{/g,'[');
  74. heroGetAll = heroGetAll.replace(/\}$/g,']');
  75. heroGetAll = heroGetAll.replace(/"\d+":\{"id"/g,'{"id"');
  76. heroGetAll = heroGetAll.replace(/"slots":[\{\[].*?[\}\]],/g,'');
  77. heroGetAll = heroGetAll.replace(/"skills":\{(.*?)\}/g,function (match, p1, offset, string) {
  78. var resultString = p1.replace(/"\d+":(\d+)/g,'$1');
  79. return '"skills":"'+resultString+'"';
  80. });
  81. heroGetAll = heroGetAll.replace(/"skins":\{(.*?)\}/g,function (match, p1, offset, string) {
  82. var resultString = p1.replace(/"(\d+)":(\d+)/g,'$1-$2');
  83. return '"skins":"'+resultString+'"';
  84. });
  85. heroGetAll = heroGetAll.replace(/"skins":\[\]/g,'"skins":""');
  86. heroGetAll = heroGetAll.replace(/\{"level":(\d+),"star":(\d+)\}/g,'"$2-$1"');
  87. heroGetAll = heroGetAll.replace(/"ascensions":\{"\d+":(.*?)\}/g,'"ascensions":$1');
  88. heroGetAll = heroGetAll.replace(/"titanCoinsSpent":.*?,/g,'');
  89. heroGetAll = heroGetAll.replace(/"currentSkin":\d+,/g,'');
  90. heroGetAll = heroGetAll.replace(/"scale":\d+,/g,'');
  91. heroGetAll = heroGetAll.replace(/"petId":\d+,/g,'');
  92. GM.setValue("heroGetAll", heroGetAll);
  93. //console.log(heroGetAll);
  94. }
  95. //clanGetInfo
  96. if (item.ident == 'clanGetInfo'){
  97. console.log("Guild Members clanGetInfo");
  98. var guild_members = {};
  99. for (const [key, value] of Object.entries(item.result.response.clan.members)) {
  100. guild_members[key] = {'id':value.id,'name':value.name,'level':value.level,'lastLoginTime':value.lastLoginTime};
  101. }
  102. //console.log(JSON.stringify(guild_members));
  103. GM.setValue("guild_members", JSON.stringify(guild_members));
  104. var clanMembers = JSON.stringify(item.result.response.clan.members);
  105. clanMembers = clanMembers.replace(/^\{/g,'[');
  106. clanMembers = clanMembers.replace(/\}$/g,']');
  107. clanMembers = clanMembers.replace(/"\d+":\{"id"/g,'{"id"');
  108. GM.setValue("clanMembers", clanMembers);
  109. //console.log(clanMembers);
  110. }
  111. //guild war enemySlots
  112. if ("enemySlots" in item.result.response && typeof item.result.response.enemySlots === 'object' && item.result.response.enemySlots !== null){
  113. console.log("Guild War Enemy Slots");
  114. var enemySlots = JSON.stringify(item.result.response.enemySlots);
  115. enemySlots = enemySlots.replace(/^\{/g,'[');
  116. enemySlots = enemySlots.replace(/\}$/g,']');
  117. enemySlots = enemySlots.replace(/"(\d+)":\{"team":\[\],"attackerId":.*?\}/g,'{"idSlot":"$1","typeSlot":"null","team":[0,0,0,0,0,0],"id":"null","name":"null"}');
  118. enemySlots = enemySlots.replace(/\{*?"\d+":\{"state":.*?"power":(\d+),"type":"(.*?)".*?\}+/g,'{"power":$1,"type":"$2"}');
  119. enemySlots = enemySlots.replace(/"(\d+)":\{"team":\[\{"power":(\d+),"type":"(.*?)"\}(.*?\]),"attackerId":.*?"id":"(\d+)","name":"(.*?)".*?pointsFarmed":(\d+),.*?\}/g,'{"idSlot":"$1","typeSlot":"$3","team":[{"power":$2,"type":"$3"}$4,"id":"$5","name":"$6","pointsFarmed":"$7"}');
  120. enemySlots = enemySlots.replace(/\{"power":(.*?),"type":".*?"\}/g,'$1');
  121. GM.setValue("enemySlots", enemySlots);
  122. //console.log(enemySlots);
  123. }
  124. //guild war ourSlots
  125. if ("ourSlots" in item.result.response && typeof item.result.response.ourSlots === 'object' && item.result.response.ourSlots !== null){
  126. console.log("Guild War Enemy Slots");
  127. var ourSlots = JSON.stringify(item.result.response.ourSlots);
  128. ourSlots = ourSlots.replace(/^\{/g,'[');
  129. ourSlots = ourSlots.replace(/\}$/g,']');
  130. ourSlots = ourSlots.replace(/"(\d+)":\{"team":\[\],"attackerId":.*?\}/g,'{"idSlot":"$1","typeSlot":"null","team":[0,0,0,0,0,0],"id":"null","name":"null"}');
  131. ourSlots = ourSlots.replace(/\{*?"\d+":\{"state":.*?"power":(\d+),"type":"(.*?)".*?\}+/g,'{"power":$1,"type":"$2"}');
  132. ourSlots = ourSlots.replace(/"(\d+)":\{"team":\[\{"power":(\d+),"type":"(.*?)"\}(.*?\]),"attackerId":.*?"id":"(\d+)","name":"(.*?)".*?pointsFarmed":(\d+),.*?\}/g,'{"idSlot":"$1","typeSlot":"$3","team":[{"power":$2,"type":"$3"}$4,"id":"$5","name":"$6","pointsFarmed":"$7"}');
  133. ourSlots = ourSlots.replace(/\{"power":(.*?),"type":".*?"\}/g,'$1');
  134. GM.setValue("ourSlots", ourSlots);
  135. //console.log(ourSlots);
  136. }
  137. //guild members
  138. //if ("clan" in item.result.response && typeof item.result.response.clan === 'object' && item.result.response.clan !== null && "members" in item.result.response.clan){
  139. // console.log("Guild Members");
  140. // var clanMembers = JSON.stringify(item.result.response.clan.members);
  141. // clanMembers = clanMembers.replace(/^\{/g,'[');
  142. // clanMembers = clanMembers.replace(/\}$/g,']');
  143. // clanMembers = clanMembers.replace(/"\d+":\{"id"/g,'{"id"');
  144. // GM.setValue("clanMembers", clanMembers);
  145. // //console.log(clanMembers);
  146. //}
  147. //guild stat
  148. if ("stat" in item.result.response && Array.isArray(item.result.response.stat)){
  149. console.log("Guild Stats");
  150. var clanStats = JSON.stringify(item.result.response.stat);
  151. GM.setValue("clanStats", clanStats);
  152. //console.log(clanStats);
  153. }
  154. //console.log(item.result);
  155. }
  156. }
  157. });
  158. //console.log(this.responseText);
  159. }
  160. }
  161. XMLHttpRequest.prototype.open = function() {
  162. this.addEventListener("readystatechange", function() {
  163. if (this.readyState == 4 && (this.responseType == 'json' || this.responseType == '') && this.status == 200 && this.responseURL == "https://heroes-wb.nextersglobal.com/api/") {
  164. let jsonResponse = this.response;
  165. if (typeof jsonResponse === 'string'){
  166. jsonResponse = JSON.parse(jsonResponse);
  167. }
  168. setTimeout(jsonResponseHandler, 1, jsonResponse);
  169. }
  170. }, false);
  171. open.apply(this, arguments);
  172. };
  173. })(XMLHttpRequest.prototype.open);
  174. function jsonToCSV(data){
  175. const replacer = (key, value) => value === null ? '' : value; // specify how you want to handle null values here
  176. const header = Object.keys(data[0]);
  177. function replacerArrayCSV(match, p1, offset, string) {
  178. var resultArrayCSV = p1.replace(/"/g,'');
  179. //console.log(resultArrayCSV);
  180. return '"'+resultArrayCSV+'"';
  181. }
  182. var csv = [
  183. header.join(','), // header row first
  184. ...data.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
  185. ].join('\r\n');
  186.  
  187. csv = csv.replace(/\[(.*?)\]/g,replacerArrayCSV);
  188. csv = csv.replace(/\{(.*?)\}/g,replacerArrayCSV);
  189. return csv;
  190. };
  191. GM_registerMenuCommand('Copy Last clanTeamsGW', async () => {
  192. let count_after = await GM.getValue('clanTeams');
  193. GM_setClipboard(jsonToCSV(JSON.parse(count_after)));
  194. });
  195. GM_registerMenuCommand('Copy Last clanMembersInfo', async () => {
  196. let guild_members = JSON.parse(await GM.getValue('guild_members'));
  197. let clanStats = JSON.parse(await GM.getValue('clanStats'));
  198. let newGuildMembers = [];
  199. for (const [key, value] of Object.entries(clanStats)) {
  200. newGuildMembers.push ({
  201. 'id':guild_members[value.id].id,
  202. 'name':guild_members[value.id].name,
  203. 'level':guild_members[value.id].level,
  204. 'lastLoginTime':guild_members[value.id].lastLoginTime,
  205. 'activity':value.activity,
  206. 'dungeonActivity':value.dungeonActivity,
  207. 'adventureStat':value.adventureStat,
  208. 'clanWarStat':value.clanWarStat,
  209. 'clanGifts':value.clanGifts,
  210. 'prestigeStat':value.prestigeStat
  211. });
  212. }
  213. //console.log(JSON.stringify(newGuildMembers));
  214. //console.log(clanMembers);
  215. GM_setClipboard(jsonToCSV(newGuildMembers));
  216. });
  217. //GM_registerMenuCommand('Copy Last clanStatsGifts', async () => {
  218. // let count_after = await GM.getValue('clanStats');
  219. // GM_setClipboard(jsonToCSV(JSON.parse(count_after)));
  220. //});
  221. GM_registerMenuCommand('Copy Last enemySlotsGW', async () => {
  222. let count_after = await GM.getValue('enemySlots');
  223. GM_setClipboard(jsonToCSV(JSON.parse(count_after)));
  224. });
  225. GM_registerMenuCommand('Copy Last ourSlotsGW', async () => {
  226. let count_after = await GM.getValue('ourSlots');
  227. GM_setClipboard(jsonToCSV(JSON.parse(count_after)));
  228. });
  229. GM_registerMenuCommand('Copy Last heroGetAll', async () => {
  230. let count_after = await GM.getValue('heroGetAll');
  231. GM_setClipboard(jsonToCSV(JSON.parse(count_after)));
  232. });
  233. })();