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.3
  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.  
  148. const message = isHolo ? `${this.messageStart} holo ${cardName} card!` : `${this.messageStart} ${cardName} card!`;
  149. const cardHTML = CardData.getCardHTML(cardId, cardNameKey, isHolo);
  150.  
  151. this.createPopup(message, cardHTML);
  152.  
  153. }
  154.  
  155. createPopup(message, cardHTML) {
  156. // Check and remove existing newCardOverlay
  157. const existingOverlay = document.getElementById('newCardOverlay');
  158.  
  159. if (existingOverlay) {
  160. document.body.removeChild(existingOverlay);
  161. }
  162.  
  163. // Element setup
  164. const overlay = document.createElement('div');
  165. overlay.id = 'newCardOverlay';
  166. overlay.style.position = 'fixed';
  167. overlay.style.top = '0';
  168. overlay.style.left = '0';
  169. overlay.style.width = '100%';
  170. overlay.style.height = '100%';
  171. overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  172. overlay.style.zIndex = '1000';
  173. overlay.style.display = 'flex';
  174. overlay.style.justifyContent = 'center';
  175. overlay.style.alignItems = 'center';
  176.  
  177. const popupBox = document.createElement('div');
  178. popupBox.id = 'newCardPopupBox';
  179. popupBox.style.width = '300px';
  180. popupBox.style.margin = '0 auto';
  181. popupBox.style.backgroundColor = '#fff';
  182. popupBox.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.5)';
  183. popupBox.style.borderRadius = '8px';
  184. popupBox.style.padding = '20px';
  185. popupBox.style.textAlign = 'center';
  186.  
  187. const messageP = document.createElement('p');
  188. messageP.textContent = message;
  189. messageP.style.fontSize = '18px';
  190. messageP.style.fontWeight = 'bold';
  191.  
  192. const cardContainer = document.createElement('div');
  193. cardContainer.innerHTML = cardHTML;
  194. cardContainer.firstChild.style.marginTop = '0px';
  195.  
  196. const cardTitle = cardContainer.querySelector('.tcg-card-title');
  197. const cardInnerText = cardContainer.querySelector('.tcg-card-inner-text');
  198. if (cardTitle) {
  199. cardTitle.style.textAlign = 'left';
  200. }
  201. if (cardInnerText) {
  202. cardInnerText.style.textAlign = 'left';
  203. }
  204.  
  205. const openAnotherButton = document.createElement('button');
  206. openAnotherButton.textContent = 'OPEN ANOTHER';
  207. openAnotherButton.style.padding = '10px 20px';
  208. openAnotherButton.style.fontSize = '16px';
  209. openAnotherButton.style.cursor = 'pointer';
  210. openAnotherButton.style.marginRight = '10px';
  211.  
  212. const closeButton = document.createElement('button');
  213. closeButton.textContent = 'CLOSE';
  214. closeButton.style.padding = '10px 20px';
  215. closeButton.style.fontSize = '16px';
  216. closeButton.style.cursor = 'pointer';
  217.  
  218. // Append elements
  219. popupBox.appendChild(messageP);
  220. popupBox.appendChild(cardContainer);
  221. if (!this.trade) {
  222. popupBox.appendChild(openAnotherButton);
  223. }
  224. popupBox.appendChild(closeButton);
  225. overlay.appendChild(popupBox);
  226. document.body.appendChild(overlay);
  227. this.trade = false;
  228.  
  229. // Event listeners
  230. openAnotherButton.addEventListener('click', () => {
  231. IdlePixelPlus.sendMessage("REVEAL_TCG_CARD");
  232. document.body.removeChild(overlay);
  233. });
  234.  
  235. const tcg_unknown = IdlePixelPlus.getVarOrDefault("tcg_unknown", 0, "int");
  236. openAnotherButton.disabled = tcg_unknown <= 1;
  237.  
  238. closeButton.addEventListener('click', () => {
  239. document.body.removeChild(overlay);
  240. window.removeEventListener('resize', adjustPopupPosition);
  241. });
  242.  
  243. const adjustPopupPosition = () => {
  244. const viewportHeight = window.innerHeight;
  245. const popupHeight = popupBox.offsetHeight;
  246. const topPosition = (viewportHeight - popupHeight) / 2;
  247. popupBox.style.position = 'absolute';
  248. popupBox.style.top = `${topPosition > 0 ? topPosition : 0}px`;
  249. };
  250. adjustPopupPosition();
  251.  
  252. window.addEventListener('resize', adjustPopupPosition);
  253.  
  254. overlay.addEventListener('click', (event) => {
  255. if (event.target === overlay) {
  256. document.body.removeChild(overlay);
  257. window.removeEventListener('resize', adjustPopupPosition);
  258. }
  259. });
  260.  
  261. popupBox.addEventListener('click', (event) => {
  262. event.stopPropagation();
  263. });
  264. }
  265.  
  266.  
  267. }
  268.  
  269. const plugin = new NewCard();
  270. IdlePixelPlus.registerPlugin(plugin);
  271.  
  272. })();