AutoVerify and Chat Compact

AutoVerify StumbleChat and chat compact style

  1. // ==UserScript==
  2. // @name AutoVerify and Chat Compact
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description AutoVerify StumbleChat and chat compact style
  6. // @author MeKLiN
  7. // @match https://stumblechat.com/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=stumblechat.com
  9. // @grant none
  10. // @run-at document-end
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. let css = `
  16. .message .nickname ~ .content {
  17. display: inline-block;
  18. top: -7px;
  19. position: relative;
  20. margin-left: 2px;
  21. margin-right: 1em;
  22. }
  23. .content + .content {
  24. display: inline-block!important;
  25. margin-right: 1em;
  26. }
  27. .message .nickname ~ .content span {
  28. line-height: 1.5em;
  29. }
  30. `;
  31. if (typeof GM_addStyle !== "undefined") {
  32. GM_addStyle(css);
  33. } else {
  34. let styleNode = document.createElement("style");
  35. styleNode.appendChild(document.createTextNode(css));
  36. (document.querySelector("head") || document.documentElement).appendChild(styleNode);
  37. }
  38. })();
  39.  
  40. var scripts = document.getElementsByTagName("script");
  41. var script = null;
  42. var found = false;
  43.  
  44. for (var i = 0; i < scripts.length; i++) {
  45. script = scripts[i];
  46. if (/^jQuery.*\.js$/i.test(script.src)) {
  47. found = true;
  48. break;
  49. }
  50. }
  51.  
  52. if (!found) {
  53. try {
  54. $ || jQuery || $ === jQuery;
  55. found = true;
  56. } catch (err) {
  57.  
  58. }
  59. }
  60.  
  61. if (!found) {
  62. // inject jQuery.
  63. script = document.createElement("script");
  64. script.type = "text/javascript";
  65.  
  66. var protocol = /^https:/i.test(document.location) ? "https" : "http";
  67. script.src = protocol + "://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
  68. document.getElementsByTagName("body")[0].appendChild(script);
  69. }
  70.  
  71. // Define App globally
  72. window.App = {
  73. Init: () => {
  74. // Define the behavior of App.Init() here
  75. console.log('App.Init() called');
  76. }
  77. };
  78.  
  79. class VerifyScript {
  80. constructor() {
  81. this.observeDOM();
  82. this.setupConsoleOverlay();
  83. this.clickCount = 0;
  84. }
  85.  
  86. clickVerifyButton = (verifyButton) => {
  87. this.clickCount++;
  88. this.logToOverlay(`Attempting to click VERIFY button ${this.clickCount} time(s)...`);
  89. if (verifyButton) {
  90. this.logToOverlay('VERIFY button found.');
  91. // Remove any existing event listeners on the button
  92. verifyButton.removeEventListener('click', this.clickVerifyButton);
  93. // Manually create and dispatch a click event
  94. const clickEvent = new MouseEvent('click', {
  95. bubbles: true,
  96. cancelable: true,
  97. view: window
  98. });
  99. this.logToOverlay('Before dispatchEvent');
  100. verifyButton.dispatchEvent(clickEvent);
  101. this.logToOverlay('After dispatchEvent');
  102.  
  103. if (this.clickCount < 3) {
  104. setTimeout(() => {
  105. if (this.isMouseLocked()) {
  106. this.sendMouseUp();
  107. }
  108. this.clickVerifyButton(verifyButton);
  109. }, 500); // Delay between clicks
  110. } else if (this.clickCount === 3) {
  111. // After the third click, call App.Init()
  112. this.logToOverlay('Third click completed, calling App.Init()...');
  113. setTimeout(() => {
  114. this.logToOverlay('Calling App.Init()...');
  115. App.Init();
  116. }, 500); // Adjust the delay as needed
  117. }
  118. } else {
  119. this.logToOverlay('VERIFY button not found.');
  120. }
  121. }
  122.  
  123. isMouseLocked = () => {
  124. return document.pointerLockElement === document.body ||
  125. document.mozPointerLockElement === document.body ||
  126. document.webkitPointerLockElement === document.body;
  127. }
  128.  
  129. sendMouseUp = () => {
  130. this.logToOverlay('Mouse is locked, sending mouseup command...');
  131. const mouseUpEvent = new MouseEvent('mouseup', {
  132. bubbles: true,
  133. cancelable: true,
  134. view: window
  135. });
  136. document.body.dispatchEvent(mouseUpEvent);
  137. }
  138.  
  139. observeDOM = () => {
  140. this.logToOverlay('Setting up MutationObserver...');
  141. const observer = new MutationObserver((mutationsList) => {
  142. this.logToOverlay(`Mutation observed... ${mutationsList.length} mutation(s) in total.`);
  143. for (const mutation of mutationsList) {
  144. this.logToOverlay(`Mutation type: ${mutation.type}`);
  145. this.logToOverlay(`Mutation target: ${mutation.target.outerHTML}`);
  146. this.logToOverlay(`Added nodes: ${mutation.addedNodes.length}`);
  147. mutation.addedNodes.forEach((node) => {
  148. if (node instanceof HTMLElement) {
  149. this.logToOverlay(`Added node: ${node.nodeName}`);
  150. // Check if the added node is the VERIFY button
  151. if (node.id === 'interact') {
  152. // Add a slight delay to ensure modal visibility
  153. setTimeout(() => {
  154. // If so, click the button without scrolling
  155. this.clickVerifyButton(node);
  156. // Attempt other ways to click the button
  157. document.querySelector('#modal #interact').click(); // First attempt
  158. document.querySelector('#modal button#interact').click(); // Second attempt
  159.  
  160. // Additional attempts
  161. node.click(); // Third attempt
  162. const customClickEvent = new CustomEvent('click', { bubbles: true });
  163. node.dispatchEvent(customClickEvent); // Fourth attempt
  164. const mouseDownEvent = new MouseEvent('mousedown', { bubbles: true });
  165. node.dispatchEvent(mouseDownEvent);
  166. const mouseUpEvent = new MouseEvent('mouseup', { bubbles: true });
  167. node.dispatchEvent(mouseUpEvent); // Fifth attempt
  168. node.parentElement.click(); // Sixth attempt
  169. console.log(`Attempt ${this.clickCount + 6}: jQuery click`);
  170. $(node).trigger('click'); // Seventh attempt
  171. console.log(`Attempt ${this.clickCount + 7}: Focus and simulate Enter key`);
  172. node.focus();
  173. const keyboardEvent = new KeyboardEvent('keydown', { key: 'Enter' });
  174. node.dispatchEvent(keyboardEvent); // Eighth attempt
  175. const pointerDownEvent = new PointerEvent('pointerdown', { bubbles: true });
  176. node.dispatchEvent(pointerDownEvent);
  177. const pointerUpEvent = new PointerEvent('pointerup', { bubbles: true });
  178. node.dispatchEvent(pointerUpEvent); // Ninth attempt
  179. const touchEvent = new TouchEvent('touchstart', { bubbles: true });
  180. node.dispatchEvent(touchEvent); // Tenth attempt
  181. }, 500); // Adjust the delay as needed
  182. }
  183. }
  184. });
  185. this.logToOverlay(`Removed nodes: ${mutation.removedNodes.length}`);
  186. mutation.removedNodes.forEach((node) => {
  187. this.logToOverlay(`Removed node: ${node.nodeName}`);
  188. });
  189. }
  190. });
  191.  
  192. // Start observing changes in the sc-modal element
  193. this.logToOverlay('Attempting to observe sc-modal element...');
  194. const scModal = document.querySelector('#modal');
  195. if (scModal) {
  196. this.logToOverlay('sc-modal element found. Starting observation...');
  197. observer.observe(scModal, { childList: true, subtree: true });
  198. } else {
  199. this.logToOverlay('sc-modal element not found.');
  200. }
  201. }
  202.  
  203. setupConsoleOverlay = () => {
  204. const consoleOverlay = document.createElement('div');
  205. consoleOverlay.setAttribute('id', 'console-overlay');
  206. consoleOverlay.style.position = 'fixed';
  207. consoleOverlay.style.top = '10px';
  208. consoleOverlay.style.left = '10px';
  209. consoleOverlay.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
  210. consoleOverlay.style.padding = '10px';
  211. consoleOverlay.style.border = '1px solid #ccc';
  212. consoleOverlay.style.zIndex = '9999';
  213.  
  214. // Minimize button
  215. const minimizeButton = document.createElement('button');
  216. minimizeButton.textContent = 'Minimize';
  217. minimizeButton.style.position = 'absolute';
  218. minimizeButton.style.top = '5px';
  219. minimizeButton.style.right = '5px';
  220. minimizeButton.addEventListener('click', () => {
  221. consoleOverlay.style.display = 'none';
  222. });
  223. consoleOverlay.appendChild(minimizeButton);
  224.  
  225. document.body.appendChild(consoleOverlay);
  226. this.consoleOverlay = consoleOverlay;
  227. }
  228.  
  229. logToOverlay = (message) => {
  230. const logEntry = document.createElement('div');
  231. logEntry.textContent = message;
  232. if (this.consoleOverlay) {
  233. this.consoleOverlay.appendChild(logEntry);
  234. }
  235. console.log(message);
  236. }
  237. }
  238.  
  239. // Start the script
  240. new VerifyScript();