TC Bootlegging Plus v2

Tools to help with Bootlegging

当前为 2025-03-28 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name TC Bootlegging Plus v2
  3. // @namespace DieselBladeScripts
  4. // @version 0.93
  5. // @description Tools to help with Bootlegging
  6. // @license GPLv3
  7. // @author DieselBlade [1701621]
  8. // @match *https://www.torn.com/loader.php?sid=crimes*
  9. // @grant unsafeWindow
  10. // @run-at document-start
  11. // ==/UserScript==
  12.  
  13.  
  14. const originalFetch = fetch;
  15.  
  16. unsafeWindow.fetch = async (input, init) => {
  17. const response = await originalFetch(input, init);
  18. if (input.includes('crimesData')) {
  19. crimesMain(response.clone()).catch(console.error);
  20. }
  21. return response;
  22. };
  23.  
  24. async function crimesMain(res) {
  25. const crimesData = await res.json();
  26. const crimeType = crimesData?.DB?.currentUserStatistics?.[1]?.value;
  27.  
  28. if (crimeType === 'Counterfeiting') {
  29. counterfeiting(crimesData.DB);
  30. } else {
  31. console.log(crimesData);
  32. }
  33. }
  34.  
  35. async function counterfeiting(db) {
  36. const { generalInfo, currentUserStats, crimesByType } = db;
  37. const CDs = {
  38. have: generalInfo.CDs,
  39. sold: {
  40. 1: currentUserStats.CDType1Sold,
  41. 2: currentUserStats.CDType2Sold,
  42. 3: currentUserStats.CDType3Sold,
  43. 4: currentUserStats.CDType4Sold,
  44. 5: currentUserStats.CDType5Sold,
  45. 6: currentUserStats.CDType6Sold,
  46. 7: currentUserStats.CDType7Sold,
  47. 8: currentUserStats.CDType8Sold
  48. },
  49. genres: {
  50. 'Action': '1',
  51. 'Comedy': '2',
  52. 'Drama': '3',
  53. 'Fantasy': '4',
  54. 'Horror': '5',
  55. 'Romance': '6',
  56. 'Thriller': '7',
  57. 'Sci-Fi': '8'
  58. }
  59. };
  60.  
  61. const currentQueue = crimesByType?.['0']?.additionalInfo?.currentQueue || [];
  62. currentQueue.forEach(cdID => CDs.have[cdID] += 1);
  63.  
  64. const observer = new MutationObserver(() => {
  65. const genreButtons = document.querySelectorAll('button[class^=genreStock]');
  66. if (genreButtons.length > 0) {
  67. updateGenreButtons(CDs);
  68. addGuideBox();
  69. observer.disconnect();
  70. }
  71. });
  72.  
  73. observer.observe(document, { childList: true, subtree: true });
  74. }
  75.  
  76. function updateGenreButtons(CDs) {
  77. const GREEN_HSL = 120; // Green for excess copies
  78. const RED_HSL = 0; // Red for biggest shortages
  79.  
  80. const totalHave = sumValues(CDs.have);
  81. const totalSold = sumValues(CDs.sold);
  82.  
  83. let maxShortage = 0; // Track the worst shortage
  84.  
  85. // First pass: Determine the maximum shortage
  86. document.querySelectorAll('button[class^=genreStock]').forEach((genreButton) => {
  87. const genre = genreButton.getAttribute('aria-label').split(' - ')[0].replace('Copying ', '');
  88. const typeID = CDs.genres[genre];
  89. const target = Math.floor((CDs.sold[typeID] / totalSold) * totalHave);
  90. const diff = target - CDs.have[typeID]; // Positive means more are needed, negative means excess
  91. if (diff > maxShortage) {
  92. maxShortage = diff; // Store the highest shortage
  93. }
  94. });
  95.  
  96. // Second pass: Apply colors based on shortage severity
  97. document.querySelectorAll('button[class^=genreStock]').forEach((genreButton) => {
  98. const genre = genreButton.getAttribute('aria-label').split(' - ')[0].replace('Copying ', '');
  99. const typeID = CDs.genres[genre];
  100. const target = Math.floor((CDs.sold[typeID] / totalSold) * totalHave);
  101. const diff = target - CDs.have[typeID]; // Positive means more are needed, negative means excess
  102.  
  103. let h;
  104. if (diff > 0) {
  105. // Shortage: scale from red (0) to neutral
  106. h = RED_HSL + (1 - diff / maxShortage) * (GREEN_HSL - RED_HSL);
  107. } else {
  108. // Excess: Make it green
  109. h = GREEN_HSL;
  110. }
  111.  
  112. genreButton.style.backgroundColor = `hsl(${h}, 100%, 90%)`;
  113.  
  114. // Ensure text remains readable
  115. genreButton.style.color = "#888"; // Ensure button text is dark grey
  116.  
  117. // Update the "copying" text color
  118. const statusText = genreButton.querySelector('.statusText___fRZso');
  119. if (statusText) {
  120. statusText.style.color = "#888";
  121. }
  122.  
  123. // Update the text for how many more are needed or if there are excess copies
  124. const existingDiffText = genreButton.querySelector('.diffText');
  125. if (existingDiffText) {
  126. existingDiffText.remove();
  127. }
  128.  
  129. const diffText = document.createElement('div');
  130. diffText.className = 'diffText';
  131. diffText.textContent = diff > 0 ? `${diff} more needed` : 'Excess copies';
  132. diffText.style.color = "#888"; // Ensure text remains readable
  133. genreButton.appendChild(diffText);
  134. });
  135. }
  136.  
  137.  
  138.  
  139.  
  140.  
  141. function sumValues(obj) {
  142. return Object.values(obj).reduce((a, b) => a + b, 0);
  143. }
  144.  
  145. function addGuideBox() {
  146. const guideBox = document.createElement("div");
  147. guideBox.style.position = "fixed";
  148. guideBox.style.top = "10px";
  149. guideBox.style.right = "10px";
  150. guideBox.style.backgroundColor = "#333";
  151. guideBox.style.padding = "10px";
  152. guideBox.style.border = "2px solid gold";
  153. guideBox.style.zIndex = "9999";
  154. guideBox.style.borderRadius = "5px";
  155.  
  156. const title = document.createElement("h2");
  157. title.textContent = "Phantom Scripting";
  158. title.style.color = "gold";
  159. title.style.marginBottom = "10px";
  160. guideBox.appendChild(title);
  161.  
  162. const explanation = document.createElement("p");
  163. explanation.innerHTML = `
  164. <strong>Color Guide:</strong>
  165. <br><span style="background-color:hsl(120, 100%, 90%); display:inline-block; width:16px; height:16px; margin-right:4px;"></span> Perfect quantity.
  166. <br><span style="background-color:hsl(0, 100%, 90%); display:inline-block; width:16px; height:16px; margin-right:4px;"></span> Too few or too many of this genre.
  167. `;
  168. explanation.style.color = "white";
  169. guideBox.appendChild(explanation);
  170.  
  171. document.body.appendChild(guideBox);
  172. }
  173.  

QingJ © 2025

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