TI/XP Transfer List

Transfer List: Show Routine (always) and Training Intensity (from Tuesday to Saturday)

  1. // ==UserScript==
  2. // @name TI/XP Transfer List
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Transfer List: Show Routine (always) and Training Intensity (from Tuesday to Saturday)
  6. // @match https://trophymanager.com/transfer/
  7. // @grant none
  8. // ==/UserScript==
  9.  
  10. (function() {
  11. 'use strict';
  12.  
  13. const APPLICATION_CONST = {
  14. TRANSFER_LIST_SELECTOR: 'div#transfer_list',
  15. TI_HEADER_NAME: 'TI',
  16. XP_HEADER_NAME: 'XP',
  17. TI_COLUMN_POSITION: 6, // Counted from left, 0-indexed
  18. XP_COLUMN_POSITION: 11, // Counted from left, 0-indexed
  19. TI_PRECISION: 0,
  20. XP_PRECISION: 1
  21. };
  22.  
  23. const PositionNames = {
  24. GOALKEEPER_STRING: 'GK'
  25. };
  26.  
  27. /**
  28. * Gets players' IDs from page
  29. * @returns {string[]}
  30. */
  31. function getAllIDs() {
  32. let rows = document.querySelectorAll(APPLICATION_CONST.TRANSFER_LIST_SELECTOR + ' tr[id^=player_row]');
  33. let ids = [];
  34. for(let row of rows) {
  35. ids.push(row.id.split('_')[2]);
  36. }
  37.  
  38. return ids;
  39. }
  40.  
  41. /**
  42. * @param {string} playerID
  43. */
  44. function getOldASI(playerID) {
  45. let playerRow = document.querySelector(APPLICATION_CONST.TRANSFER_LIST_SELECTOR + ' tr[id=player_row_' + playerID + ']');
  46. let asiCell = playerRow.childNodes[5];
  47. let asi = asiCell.innerHTML.match(/[0-9]+/)[0];
  48. return Number(asi);
  49. }
  50.  
  51. /**
  52. * @param {string} playerID
  53. * @returns {Promise<number>}
  54. */
  55. function requestPlayerASI(playerID) {
  56. return new Promise((resolve, reject) => {
  57. $.post("/ajax/tooltip.ajax.php", { "player_id": playerID, minigame: undefined })
  58. .done((data) => {
  59. data = JSON.parse(data);
  60. resolve({
  61. id: data.player.player_id,
  62. position: data.player.fp,
  63. ASI: Number(data.player.skill_index.split(',').join('')),
  64. xp: Number(data.player.routine.split(',').join(''))
  65. });
  66. }).fail((error) => {
  67. reject(error);
  68. });
  69. });
  70. }
  71.  
  72. /**
  73. * @param {number} columnPosition
  74. * @param {string} headerName
  75. */
  76. function addColumnToTable(columnPosition, headerName) {
  77. let headerRow = document.querySelector(APPLICATION_CONST.TRANSFER_LIST_SELECTOR + ' tr.header');
  78. let columns = headerRow.querySelectorAll('th');
  79. let columnsCount = columns.length;
  80. let headerCell = document.createElement('th');
  81. headerCell.style.width = '60px';
  82. headerCell.innerHTML = headerName;
  83.  
  84. if(columnsCount > columnPosition + 1) {
  85. headerRow.insertBefore(headerCell, columns[columnPosition]);
  86. } else {
  87. headerRow.appendChild(headerCell);
  88. }
  89.  
  90. let rows = document.querySelectorAll(APPLICATION_CONST.TRANSFER_LIST_SELECTOR + ' tr[id^=player_row]');
  91. for(let row of rows) {
  92. if(row.childElementCount === 0) {
  93. continue;
  94. }
  95.  
  96. let cell = document.createElement('td');
  97. cell.classList.add('align_center');
  98. cell.innerHTML = '-';
  99. if(columnsCount > columnPosition + 1) {
  100. row.insertBefore(cell, row.querySelectorAll('td')[columnPosition]);
  101. } else {
  102. row.appendChild(cell);
  103. }
  104. }
  105. }
  106.  
  107. /**
  108. * @param {number} rowIndex
  109. * @param {number} columnIndex
  110. * @param {*} innerHTML Anything printable
  111. */
  112. function changeTransferTableCellInnerHTML(rowIndex, columnIndex, innerHTML) {
  113. let row = document.querySelectorAll(APPLICATION_CONST.TRANSFER_LIST_SELECTOR + ' tr[id]');
  114. if(row[rowIndex].childElementCount === 0) {
  115. return;
  116. }
  117.  
  118. row[rowIndex].childNodes[columnIndex].innerHTML = innerHTML;
  119. }
  120.  
  121. let TI = {
  122. /**
  123. * @param {number} asiNew
  124. * @param {number} asiOld
  125. * @param {string} position
  126. * @returns {number} calculated TI
  127. */
  128. compute: function(asiNew, asiOld, position) {
  129. let pow = Math.pow;
  130. if(position === PositionNames.GOALKEEPER_STRING) {
  131. return (pow(asiNew * pow(2, 9) * pow(5, 4) * pow(7, 7), 1/7) - pow(asiOld * pow(2, 9) * pow(5, 4) * pow(7, 7), 1/7)) / 14 * 11 * 10;
  132. } else {
  133. return (pow(asiNew * pow(2, 9) * pow(5, 4) * pow(7, 7), 1/7) - pow(asiOld * pow(2, 9) * pow(5, 4) * pow(7, 7), 1/7)) * 10;
  134. }
  135. }
  136. };
  137.  
  138. /**
  139. * Requests necessary data and displays current ASI
  140. * @param {MutationRecord[]} mutationRecords
  141. */
  142. function init(mutationRecords) {
  143. if(document.querySelector(APPLICATION_CONST.TRANSFER_LIST_SELECTOR + ' table') === null) {
  144. return;
  145. }
  146.  
  147. let playersIDs = getAllIDs();
  148.  
  149. addColumnToTable(APPLICATION_CONST.TI_COLUMN_POSITION, APPLICATION_CONST.TI_HEADER_NAME);
  150. addColumnToTable(APPLICATION_CONST.XP_COLUMN_POSITION, APPLICATION_CONST.XP_HEADER_NAME);
  151. // Request in parallel
  152. playersIDs.map(requestPlayerASI).map((promise, index) => {
  153. promise.then((player) => {
  154. let oldASI = getOldASI(player.id);
  155. let ti = TI.compute(player.ASI, oldASI, player.position).toFixed(APPLICATION_CONST.TI_PRECISION);
  156. let xp = player.xp.toFixed(APPLICATION_CONST.XP_PRECISION);
  157. changeTransferTableCellInnerHTML(index, APPLICATION_CONST.TI_COLUMN_POSITION, ti);
  158. changeTransferTableCellInnerHTML(index, APPLICATION_CONST.XP_COLUMN_POSITION, xp);
  159. }).catch((error) => {
  160. changeTransferTableCellInnerHTML(index, APPLICATION_CONST.TI_COLUMN_POSITION, "Error");
  161. changeTransferTableCellInnerHTML(index, APPLICATION_CONST.XP_COLUMN_POSITION, "Error");
  162. });
  163. });
  164. }
  165.  
  166. let observer = new MutationObserver(init);
  167. observer.observe(document.querySelector(APPLICATION_CONST.TRANSFER_LIST_SELECTOR), { childList: true });
  168. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址