IdlePixel+ New Card Interface

Improved interface for opening new cards & receiving cards in trade

当前为 2024-04-17 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name IdlePixel+ New Card Interface
  3. // @namespace lbtechnology.info
  4. // @version 1.1.4
  5. // @description Improved interface for opening new cards & receiving cards in trade
  6. // @author Zlef
  7. // @license MIT
  8. // @match *://idle-pixel.com/login/play*
  9. // @grant none
  10. // @icon https://d1xsc8x7nc5q8t.cloudfront.net/images/tcg_back_50.png
  11. // @require https://greasyfork.org/scripts/441206-idlepixel/code/IdlePixel+.js?anticache=20220905
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. class NewCard extends IdlePixelPlusPlugin {
  18. constructor() {
  19. super("newcard", {
  20. about: {
  21. name: GM_info.script.name,
  22. version: GM_info.script.version,
  23. author: GM_info.script.author,
  24. description: GM_info.script.description
  25. }
  26. });
  27.  
  28. this.showPopup = false;
  29. this.messageStart = "You got a"
  30. this.trade = false;
  31. this.card = "";
  32. }
  33.  
  34. onLogin() {
  35. if (!CardData.data) {
  36. CardData.fetchData();
  37. }
  38. this.monitorRevealTCG();
  39. }
  40.  
  41. monitorRevealTCG() {
  42. const originalWebSocketSend = WebSocket.prototype.send;
  43. const self = this;
  44. WebSocket.prototype.send = function(data) {
  45. try {
  46. originalWebSocketSend.call(this, data);
  47. if (data === 'REVEAL_TCG_CARD') {
  48. self.showPopup = true;
  49. }
  50. } catch (error) {
  51. console.error('Error in overridden WebSocket send:', error);
  52. }
  53. };
  54. }
  55.  
  56. onMessageReceived(data){
  57. const originalOpenImageModal = Modals.open_image_modal;
  58. const self = this;
  59.  
  60. if (data.includes("OPEN_DIALOGUE")){
  61. Modals.open_image_modal = function(title, imgUrl, description, footerText, closeBtnText, anotherBtnText, isModalDismissible) {
  62. // console.log(`title: ${title}, imgUrl: ${imgUrl}, description: ${description}, footerText: ${footerText}, closeBtnText: ${closeBtnText}, anotherBtnText: ${anotherBtnText}, isModalDismissible: ${isModalDismissible}`);
  63.  
  64. if (description.includes("You were given a card from")) {
  65. // console.log("Found trade received modal call, blocking");
  66.  
  67. const usernameRegex = /You were given a card from (.*?)<br \/>/;
  68. const cardRegex = /<span class='color-grey'>(.*?)<\/span>/;
  69.  
  70. const usernameMatch = description.match(usernameRegex);
  71. const cardMatch = description.match(cardRegex);
  72.  
  73. let username = "";
  74. let card = "";
  75.  
  76. if (usernameMatch && usernameMatch.length > 1) {
  77. username = usernameMatch[1];
  78. }
  79.  
  80. if (cardMatch && cardMatch.length > 1) {
  81. self.card = cardMatch[1]
  82. }
  83.  
  84.  
  85. self.messageStart = `${username} sent you a`
  86. self.trade = true;
  87. self.showPopup = true;
  88. // console.log(`username: ${username}, card: ${self.card}, showPopup ${self.showPopup}, trade: ${self.trade}, messageStart: ${self.messageStart}`);
  89. } else {
  90. originalOpenImageModal.call(this, title, imgUrl, description, footerText, closeBtnText, anotherBtnText, isModalDismissible);
  91. }
  92. }
  93. }
  94.  
  95. if (data.includes("REFRESH_TCG")){
  96. if (this.showPopup){
  97. if (this.trade){
  98. this.getCardInfo(data);
  99. // this.trade = false;
  100. this.card = "";
  101. } else {
  102. this.getCardInfo(data);
  103. }
  104. this.showPopup = false;
  105. this.messageStart = "You got a "
  106. }
  107. }
  108. }
  109.  
  110. chunks(array, chunkSize) {
  111. const result = [];
  112. for (let i = 0; i < array.length; i += chunkSize) {
  113. const chunk = array.slice(i, i + chunkSize);
  114. result.push(chunk);
  115. }
  116. return result;
  117. }
  118.  
  119. getCardInfo(data) {
  120. const cardData = data.split('~');
  121. const chunkedData = this.chunks(cardData, 3); // id, nameKey, holo
  122.  
  123. let relevantCard = chunkedData[0]; // Default to the first card for non-trade
  124. let isHolo = relevantCard[2];
  125. if (this.trade) {
  126. for (let i = 0; i < chunkedData.length; i++) {
  127. const [id, nameKey, holo] = chunkedData[i];
  128. if (this.card.includes("(holo)")){
  129. isHolo = 'true';
  130. this.card = this.card.replace(/ \(holo\)$/, '');
  131. }
  132. if (this.card === nameKey) {
  133. console.log("Matching card found in trade:", chunkedData[i]);
  134. relevantCard = chunkedData[i];
  135. break;
  136. }
  137. }
  138. }
  139.  
  140. this.displayNewCard(relevantCard[0], relevantCard[1], isHolo);
  141. }
  142.  
  143.  
  144. displayNewCard(cardId, cardNameKey, holo) {
  145. const cardName = cardNameKey.replace('tcg_', '').replace(/_/g, ' ').replace(" icon", "");
  146. const isHolo = holo === 'true';
  147. let bloodyVowels = "";
  148.  
  149. const vowels = ['a', 'e', 'i', 'o', 'u'];
  150. if (vowels.some(vowel => cardName.toLowerCase().startsWith(vowel))) {
  151. bloodyVowels = "n";
  152. }
  153.  
  154. const message = isHolo ? `${this.messageStart} holo ${cardName} card!` : `${this.messageStart}${bloodyVowels} ${cardName} card!`;
  155.  
  156. const cardHTML = CardData.getCardHTML(cardId, cardNameKey, isHolo);
  157.  
  158. this.createPopup(message, cardHTML);
  159.  
  160. }
  161.  
  162. createPopup(message, cardHTML) {
  163. // Check and remove existing newCardOverlay
  164. const existingOverlay = document.getElementById('newCardOverlay');
  165.  
  166. if (existingOverlay) {
  167. document.body.removeChild(existingOverlay);
  168. }
  169.  
  170. // Element setup
  171. const overlay = document.createElement('div');
  172. overlay.id = 'newCardOverlay';
  173. overlay.style.position = 'fixed';
  174. overlay.style.top = '0';
  175. overlay.style.left = '0';
  176. overlay.style.width = '100%';
  177. overlay.style.height = '100%';
  178. overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  179. overlay.style.zIndex = '1000';
  180. overlay.style.display = 'flex';
  181. overlay.style.justifyContent = 'center';
  182. overlay.style.alignItems = 'center';
  183.  
  184. const popupBox = document.createElement('div');
  185. popupBox.id = 'newCardPopupBox';
  186. popupBox.style.width = '300px';
  187. popupBox.style.margin = '0 auto';
  188. popupBox.style.backgroundColor = '#fff';
  189. popupBox.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.5)';
  190. popupBox.style.borderRadius = '8px';
  191. popupBox.style.padding = '20px';
  192. popupBox.style.textAlign = 'center';
  193.  
  194. const messageP = document.createElement('p');
  195. messageP.textContent = message;
  196. messageP.style.fontSize = '18px';
  197. messageP.style.fontWeight = 'bold';
  198.  
  199. const cardContainer = document.createElement('div');
  200. cardContainer.innerHTML = cardHTML;
  201. cardContainer.firstChild.style.marginTop = '0px';
  202.  
  203. const cardTitle = cardContainer.querySelector('.tcg-card-title');
  204. const cardInnerText = cardContainer.querySelector('.tcg-card-inner-text');
  205. if (cardTitle) {
  206. cardTitle.style.textAlign = 'left';
  207. }
  208. if (cardInnerText) {
  209. cardInnerText.style.textAlign = 'left';
  210. }
  211.  
  212. const openAnotherButton = document.createElement('button');
  213. openAnotherButton.textContent = 'OPEN ANOTHER';
  214. openAnotherButton.style.padding = '10px 20px';
  215. openAnotherButton.style.fontSize = '16px';
  216. openAnotherButton.style.cursor = 'pointer';
  217. openAnotherButton.style.marginRight = '10px';
  218.  
  219. const closeButton = document.createElement('button');
  220. closeButton.textContent = 'CLOSE';
  221. closeButton.style.padding = '10px 20px';
  222. closeButton.style.fontSize = '16px';
  223. closeButton.style.cursor = 'pointer';
  224.  
  225. // Append elements
  226. popupBox.appendChild(messageP);
  227. popupBox.appendChild(cardContainer);
  228. if (!this.trade) {
  229. popupBox.appendChild(openAnotherButton);
  230. }
  231. popupBox.appendChild(closeButton);
  232. overlay.appendChild(popupBox);
  233. document.body.appendChild(overlay);
  234.  
  235. this.trade = false;
  236.  
  237. // Event listeners
  238. openAnotherButton.addEventListener('click', () => {
  239. IdlePixelPlus.sendMessage("REVEAL_TCG_CARD");
  240. document.body.removeChild(overlay);
  241. });
  242.  
  243. const tcg_unknown = IdlePixelPlus.getVarOrDefault("tcg_unknown", 0, "int");
  244. openAnotherButton.disabled = tcg_unknown <= 1;
  245.  
  246. closeButton.addEventListener('click', () => {
  247. document.body.removeChild(overlay);
  248. window.removeEventListener('resize', adjustPopupPosition);
  249. });
  250.  
  251. const adjustPopupPosition = () => {
  252. const viewportHeight = window.innerHeight;
  253. const popupHeight = popupBox.offsetHeight;
  254. const topPosition = (viewportHeight - popupHeight) / 2;
  255. popupBox.style.position = 'absolute';
  256. popupBox.style.top = `${topPosition > 0 ? topPosition : 0}px`;
  257. };
  258. adjustPopupPosition();
  259.  
  260. window.addEventListener('resize', adjustPopupPosition);
  261.  
  262. overlay.addEventListener('click', (event) => {
  263. if (event.target === overlay) {
  264. document.body.removeChild(overlay);
  265. window.removeEventListener('resize', adjustPopupPosition);
  266. }
  267. });
  268.  
  269. popupBox.addEventListener('click', (event) => {
  270. event.stopPropagation();
  271. });
  272. }
  273.  
  274.  
  275. }
  276.  
  277. const plugin = new NewCard();
  278. IdlePixelPlus.registerPlugin(plugin);
  279.  
  280. })();