[银河奶牛]强化工具(血压工具)

在线统计强化成功/失败次数

当前为 2024-09-06 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name [MWI]Enhancement Tool
  3. // @name:zh-CN [银河奶牛]强化工具(血压工具)
  4. // @name:zh-TW [銀河奶牛]強化工具
  5. // @namespace http://tampermonkey.net/
  6. // @version 1.05
  7. // @description Track the number of enhancement successes and failures
  8. // @description:zh-CN 在线统计强化成功/失败次数
  9. // @description:zh-TW 統計強化成功/失敗次數
  10. // @author Truth_Light
  11. // @license Truth_Light
  12. // @match https://www.milkywayidle.com/*
  13. // @match https://test.milkywayidle.com/*
  14. // @icon https://www.google.com/s2/favicons?sz=64&domain=milkywayidle.com
  15. // @grant GM.xmlHttpRequest
  16. // @grant GM_registerMenuCommand
  17. // ==/UserScript==
  18.  
  19. (function() {
  20. 'use strict';
  21. let enhancementLevel;
  22. let currentEnhancingIndex = 1;
  23. let enhancementData = {
  24. [currentEnhancingIndex]: { "强化数据": {}, "其他数据": {} }
  25. };
  26. const userLanguage = navigator.language || navigator.userLanguage;
  27. const isZH = userLanguage.startsWith("zh");
  28.  
  29. function hookWS() {
  30. const dataProperty = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "data");
  31. const oriGet = dataProperty.get;
  32.  
  33. dataProperty.get = hookedGet;
  34. Object.defineProperty(MessageEvent.prototype, "data", dataProperty);
  35.  
  36. function hookedGet() {
  37. const socket = this.currentTarget;
  38. if (!(socket instanceof WebSocket)) {
  39. return oriGet.call(this);
  40. }
  41. if (socket.url.indexOf("api.milkywayidle.com/ws") <= -1 && socket.url.indexOf("api-test.milkywayidle.com/ws") <= -1) {
  42. return oriGet.call(this);
  43. }
  44.  
  45. const message = oriGet.call(this);
  46. Object.defineProperty(this, "data", { value: message });
  47.  
  48. return handleMessage(message);
  49. }
  50. }
  51.  
  52. function handleMessage(message) {
  53. try {
  54. let obj = JSON.parse(message);
  55. if (obj && obj.type === "action_completed" && obj.endCharacterAction && obj.endCharacterAction.actionHrid === "/actions/enhancing/enhance") {
  56. const now_enhancementLevel = parseInt(obj.endCharacterAction.upgradeItemHash.match(/::(\d+)$/)[1]);
  57. const currentCount = obj.endCharacterAction.currentCount;
  58.  
  59. if (enhancementLevel !== undefined) {
  60. // 开始新的物品的强化
  61. if (currentCount < enhancementData[currentEnhancingIndex]["强化次数"]) {
  62. currentEnhancingIndex++;
  63. enhancementData[currentEnhancingIndex] = { "强化数据": {}, "其他数据": {} };
  64. enhancementLevel = undefined;
  65. return message
  66. }
  67.  
  68. const currentItem = enhancementData[currentEnhancingIndex]["强化数据"];
  69.  
  70.  
  71. if (!currentItem[enhancementLevel]) {
  72. currentItem[enhancementLevel] = { "成功次数": 0, "失败次数": 0, "成功率": 0 };
  73. }
  74.  
  75. if (enhancementLevel < now_enhancementLevel) {
  76. currentItem[enhancementLevel]["成功次数"]++;
  77. } else {
  78. currentItem[enhancementLevel]["失败次数"]++;
  79. }
  80.  
  81. const success = currentItem[enhancementLevel]["成功次数"];
  82. const failure = currentItem[enhancementLevel]["失败次数"];
  83. currentItem[enhancementLevel]["成功率"] = success / (success + failure);
  84.  
  85. // 计算强化状态
  86. const highestSuccessLevel = Math.max(...Object.keys(currentItem).filter(level => currentItem[level]["成功次数"] > 0));
  87. const enhancementState = (highestSuccessLevel + 1 >= enhancementData[currentEnhancingIndex]["其他数据"]["目标强化等级"]) ? "强化成功" : "强化失败";
  88. enhancementData[currentEnhancingIndex]["强化状态"] = enhancementState;
  89. enhancementLevel = now_enhancementLevel;
  90. } else {
  91. // 初始化数据
  92. enhancementLevel = now_enhancementLevel;
  93. const itemName = formatItemName(obj.endCharacterAction.upgradeItemHash);
  94. enhancementData[currentEnhancingIndex]["其他数据"] = {
  95. "物品名称": itemName,
  96. "目标强化等级": obj.endCharacterAction.enhancingMaxLevel
  97. };
  98. }
  99.  
  100. enhancementData[currentEnhancingIndex]["强化次数"] = currentCount;
  101. updateDisplay();
  102. } else {
  103. return message;
  104. }
  105. } catch (error) {
  106. console.error("Error processing message:", error);
  107. }
  108. return message;
  109. }
  110.  
  111. function updateDisplay() {
  112. const targetElement = document.querySelector(".SkillActionDetail_enhancingComponent__17bOx");
  113. if (!targetElement) return;
  114.  
  115. let enhancementStatsContainer = document.querySelector("#enhancementStatsContainer");
  116.  
  117. if (!enhancementStatsContainer) {
  118. enhancementStatsContainer = document.createElement("div");
  119. enhancementStatsContainer.id = "enhancementStatsContainer";
  120. enhancementStatsContainer.style.display = "grid";
  121. enhancementStatsContainer.style.gridTemplateColumns = "repeat(4, 1fr)";
  122. enhancementStatsContainer.style.gap = "10px";
  123. enhancementStatsContainer.style.textAlign = "center";
  124. enhancementStatsContainer.style.marginTop = "10px";
  125.  
  126. // 添加下拉框
  127. const dropdown = document.createElement("select");
  128. dropdown.id = "enhancementDropdown";
  129. dropdown.style.marginBottom = "10px";
  130. dropdown.addEventListener("change", function () {
  131. renderStats(this.value);
  132. });
  133. targetElement.appendChild(dropdown);
  134. targetElement.appendChild(enhancementStatsContainer);
  135. }
  136.  
  137. // 获取当前选中的选项
  138. const dropdown = document.querySelector("#enhancementDropdown");
  139. const previousSelectedValue = dropdown.value;
  140.  
  141. dropdown.innerHTML = "";
  142.  
  143. Object.keys(enhancementData).forEach(key => {
  144. const item = enhancementData[key];
  145. const option = document.createElement("option");
  146. const itemName = item["其他数据"]["物品名称"];
  147. const targetLevel = item["其他数据"]["目标强化等级"];
  148. const currentLevel = Math.max(...Object.keys(item["强化数据"]));
  149. const enhancementState = item["强化状态"];
  150.  
  151. option.text = `${itemName} (目标: ${targetLevel})`;
  152. option.value = key;
  153.  
  154. option.style.color = enhancementState === "强化成功" ? "green" : (currentLevel < targetLevel && Object.keys(enhancementData).indexOf(key) === Object.keys(enhancementData).length - 1) ? "Orange" : "red";
  155. dropdown.appendChild(option);
  156. });
  157.  
  158. if (Object.keys(enhancementData).length > 0) {
  159. dropdown.value = previousSelectedValue || Object.keys(enhancementData)[0];
  160. renderStats(dropdown.value);
  161. }
  162. }
  163.  
  164. function formatItemName(upgradeItemHash) {
  165. const namePartMatch = upgradeItemHash.match(/\/([^\/]+?)::[^:]+$/);
  166. if (namePartMatch && namePartMatch[1]) {
  167. const namePart = namePartMatch[1];
  168. const formattedName = namePart.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
  169. return formattedName;
  170. }
  171. return "Unknown Item";
  172. }
  173.  
  174.  
  175. function renderStats(selectedKey) {
  176. const enhancementStatsContainer = document.querySelector("#enhancementStatsContainer");
  177. enhancementStatsContainer.innerHTML = "";
  178.  
  179. const item = enhancementData[selectedKey];
  180.  
  181. // 表头
  182. const headers = ["等级", "成功次数", "失败次数", "成功率"];
  183. headers.forEach(headerText => {
  184. const headerDiv = document.createElement("div");
  185. headerDiv.style.fontWeight = "bold";
  186. headerDiv.textContent = isZH ? headerText : (headerText === "等级" ? "Level" : headerText === "成功次数" ? "Success" : headerText === "失败次数" ? "Failure" : "Success Rate");
  187. enhancementStatsContainer.appendChild(headerDiv);
  188. });
  189.  
  190. // 总计信息
  191. const totalSuccess = Object.values(item["强化数据"]).reduce((acc, val) => acc + val["成功次数"], 0);
  192. const totalFailure = Object.values(item["强化数据"]).reduce((acc, val) => acc + val["失败次数"], 0);
  193. const totalCount = totalSuccess + totalFailure;
  194. const totalRate = totalCount > 0 ? (totalSuccess / totalCount * 100).toFixed(2) : "0.00";
  195.  
  196. ["总计", totalSuccess, totalFailure, `${totalRate}%`].forEach((totalText, index) => {
  197. const totalDiv = document.createElement("div");
  198. totalDiv.textContent = isZH ? totalText : index === 0 ? "Total" : totalText;
  199. enhancementStatsContainer.appendChild(totalDiv);
  200. });
  201.  
  202. Object.keys(item["强化数据"]).sort((a, b) => b - a).forEach(level => {
  203. [level, item["强化数据"][level]["成功次数"], item["强化数据"][level]["失败次数"], `${(item["强化数据"][level]["成功率"] * 100).toFixed(2)}%`].forEach(data => {
  204. const dataDiv = document.createElement("div");
  205. dataDiv.textContent = data;
  206. enhancementStatsContainer.appendChild(dataDiv);
  207. });
  208. });
  209. }
  210.  
  211.  
  212.  
  213.  
  214. hookWS();
  215. })();