Chess.com Bot/Cheat - Stockfish API Debug 3 - Ad Removed - FIXED - COMPLETE SCRIPT

Chess.com Bot/Cheat using Stockfish Online API. Ad Removed. - FIXED loadEx and UI update errors - DEBUGGING VERSION 3 - IMPROVED MOVE HANDLING - COMPLETE SCRIPT

  1. // ==UserScript==
  2. // @name Chess.com Bot/Cheat - Stockfish API Debug 3 - Ad Removed - FIXED - COMPLETE SCRIPT
  3. // @namespace BottleOrg Scripts
  4. // @version 1.6.2-Official
  5. // @description Chess.com Bot/Cheat using Stockfish Online API. Ad Removed. - FIXED loadEx and UI update errors - DEBUGGING VERSION 3 - IMPROVED MOVE HANDLING - COMPLETE SCRIPT
  6. // @author MrAuzzie (Original), Modified by BottleOrg && Gemini 2.0 to become better.
  7. // @license Chess.com Bot/Cheat © 2023 by MrAuzzie#998142, © All Rights Reserved
  8. // @match https://www.chess.com/play/*
  9. // @match https://www.chess.com/game/*
  10. // @match https://www.chess.com/puzzles/*
  11. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // @grant GM_xmlhttpRequest
  15. // @grant GM_getResourceText
  16. // @grant GM_registerMenuCommand
  17. // @require https://greasyfork.org/scripts/445697/code/index.js
  18. // @require https://code.jquery.com/jquery-3.6.0.min.js
  19. // @run-at document-start
  20. // ==/UserScript==
  21. // Changelogs
  22. // Made this Debug V3 script into official script due to it is working correctly
  23. // Working Stockfish V16+ using their API
  24. // Debugging V2 script Found out engine is not responding due to not finding a legal move
  25. // Debugging V1 script engine responded but did not move
  26. // Using stockfish V10.0.2 as it is working
  27. // Removed CDN stockfish V16 engines and engine fallbacks because it doesn't work
  28. // Added engine fallbacks if an engine fails
  29. // added error handling and alerts
  30. // Upgraded from Stockfish V9 to Stockfish V10.0.2
  31. // Using Stockfish 9 currently
  32. const currentVersion = '1.6.2-OFFICIAL';
  33. function main() {
  34. var engine = document.engine = {}; // Engine object (not used for local engine anymore)
  35. var myVars = document.myVars = {};
  36. myVars.autoMovePiece = false;
  37. myVars.autoRun = false;
  38. myVars.delay = 0.1;
  39. var myFunctions = document.myFunctions = {};
  40. var currentStockfishVersion = "Stockfish API"; // Using Stockfish API
  41. var uiElementsLoaded = false; // Flag to track if UI elements are loaded
  42. const stockfishAPI_URI = "https://stockfish.online/api/s/v2.php"; // Stockfish API URI
  43. stop_b = stop_w = 0;
  44. s_br = s_br2 = s_wr = s_wr2 = 0;
  45. obs = "";
  46. myFunctions.rescan = function(lev) {
  47. var ari = $("chess-board")
  48. .find(".piece")
  49. .map(function() {
  50. return this.className;
  51. })
  52. .get();
  53. jack = ari.map(f => f.substring(f.indexOf(' ') + 1));
  54. function removeWord(arr, word) {
  55. for (var i = 0; i < arr.length; i++) {
  56. arr[i] = arr[i].replace(word, '');
  57. }
  58. }
  59. removeWord(ari, 'square-');
  60. jack = ari.map(f => f.substring(f.indexOf(' ') + 1));
  61. for (var i = 0; i < jack.length; i++) {
  62. jack[i] = jack[i].replace('br', 'r')
  63. .replace('bn', 'n')
  64. .replace('bb', 'b')
  65. .replace('bq', 'q')
  66. .replace('bk', 'k')
  67. .replace('bb', 'b')
  68. .replace('bn', 'n')
  69. .replace('br', 'r')
  70. .replace('bp', 'p')
  71. .replace('wp', 'P')
  72. .replace('wr', 'R')
  73. .replace('wn', 'N')
  74. .replace('wb', 'B')
  75. .replace('br', 'R')
  76. .replace('wn', 'N')
  77. .replace('wb', 'B')
  78. .replace('wq', 'Q')
  79. .replace('wk', 'K')
  80. .replace('wb', 'B')
  81. }
  82. str2 = "";
  83. var count = 0,
  84. str = "";
  85. for (var j = 8; j > 0; j--) {
  86. for (var i = 1; i < 9; i++) {
  87. (str = (jack.find(el => el.includes([i] + [j])))) ? str = str.replace(/[^a-zA-Z]+/g, ''): str = "";
  88. if (str == "") {
  89. count++;
  90. str = count.toString();
  91. if (!isNaN(str2.charAt(str2.length - 1))) str2 = str2.slice(0, -1);
  92. else {
  93. count = 1;
  94. str = count.toString()
  95. }
  96. }
  97. str2 += str;
  98. if (i == 8) {
  99. count = 0;
  100. str2 += "/";
  101. }
  102. }
  103. }
  104. str2 = str2.slice(0, -1);
  105. //str2=str2+" KQkq - 0"
  106. color = "";
  107. wk = wq = bk = bq = "0";
  108. const move = $('vertical-move-list')
  109. .children();
  110. if (move.length < 2) {
  111. stop_b = stop_w = s_br = s_br2 = s_wr = s_wr2 = 0;
  112. }
  113. if (stop_b != 1) {
  114. if (move.find(".black.node:contains('K')")
  115. .length) {
  116. bk = "";
  117. bq = "";
  118. stop_b = 1;
  119. console.log('debug secb');
  120. }
  121. } else {
  122. bq = "";
  123. bk = "";
  124. }
  125. if (stop_b != 1)(bk = (move.find(".black.node:contains('O-O'):not(:contains('O-O-O'))")
  126. .length) ? "" : "k") ? (bq = (move.find(".black.node:contains('O-O-O')")
  127. .length) ? bk = "" : "q") : bq = "";
  128. if (s_br != 1) {
  129. if (move.find(".black.node:contains('R')")
  130. .text()
  131. .match('[abcd]+')) {
  132. bq = "";
  133. s_br = 1
  134. }
  135. } else bq = "";
  136. if (s_br2 != 1) {
  137. if (move.find(".black.node:contains('R')")
  138. .text()
  139. .match('[hgf]+')) {
  140. bk = "";
  141. s_br2 = 1
  142. }
  143. } else bk = "";
  144. if (stop_b == 0) {
  145. if (s_br == 0)
  146. if (move.find(".white.node:contains('xa8')")
  147. .length > 0) {
  148. bq = "";
  149. s_br = 1;
  150. console.log('debug b castle_r');
  151. }
  152. if (s_br2 == 0)
  153. if (move.find(".white.node:contains('xh8')")
  154. .length > 0) {
  155. bk = "";
  156. s_br2 = 1;
  157. console.log('debug b castle_l');
  158. }
  159. }
  160. if (stop_w != 1) {
  161. if (move.find(".white.node:contains('K')")
  162. .length) {
  163. wk = "";
  164. wq = "";
  165. stop_w = 1;
  166. console.log('debug secw');
  167. }
  168. } else {
  169. wq = "";
  170. wk = "";
  171. }
  172. if (stop_w != 1)(wk = (move.find(".white.node:contains('O-O'):not(:contains('O-O-O'))")
  173. .length) ? "" : "K") ? (wq = (move.find(".white.node:contains('O-O-O')")
  174. .length) ? wk = "" : "Q") : wq = "";
  175. if (s_wr != 1) {
  176. if (move.find(".white.node:contains('R')")
  177. .text()
  178. .match('[abcd]+')) {
  179. wq = "";
  180. s_wr = 1
  181. }
  182. } else wq = "";
  183. if (s_wr2 != 1) {
  184. if (move.find(".white.node:contains('R')")
  185. .text()
  186. .match('[hgf]+')) {
  187. wk = "";
  188. s_wr2 = 1
  189. }
  190. } else wk = "";
  191. if (stop_w == 0) {
  192. if (s_wr == 0)
  193. if (move.find(".black.node:contains('xa1')")
  194. .length > 0) {
  195. wq = "";
  196. s_wr = 1;
  197. console.log('debug w castle_l');
  198. }
  199. if (s_wr2 == 0)
  200. if (move.find(".black.node:contains('xh1')")
  201. .length > 0) {
  202. wk = "";
  203. s_wr2 = 1;
  204. console.log('debug w castle_r');
  205. }
  206. }
  207. if ($('.coordinates')
  208. .children()
  209. .first()
  210. .text() == 1) {
  211. str2 = str2 + " b " + wk + wq + bk + bq;
  212. color = "white";
  213. } else {
  214. str2 = str2 + " w " + wk + wq + bk + bq;
  215. color = "black";
  216. }
  217. //console.log(str2);
  218. return str2;
  219. }
  220. myFunctions.color = function(dat){
  221. console.log("myFunctions.color CALLED with dat:", dat); // Added logging at start
  222. response = dat;
  223. const bestmoveUCI = response.split(' ')[1]; // Extract UCI move directly (e.g., "e2e4")
  224. console.log("Extracted bestmove UCI from API response:", bestmoveUCI);
  225. if(myVars.autoMove == true){
  226. console.log("Auto-move is enabled, calling movePiece with UCI move:", bestmoveUCI); // Log before movePiece
  227. myFunctions.movePiece(bestmoveUCI); // Pass UCI move directly to movePiece
  228. } else {
  229. console.log("Auto-move is disabled, only highlighting UCI move:", bestmoveUCI); // Log if auto-move off
  230. myFunctions.highlightMove(bestmoveUCI); // Call highlight function with UCI move
  231. }
  232. isThinking = false;
  233. console.log("myFunctions.color COMPLETED"); // Log at the end of color
  234. }
  235. myFunctions.highlightMove = function(bestmoveUCI) { // New highlight function using UCI move
  236. var res1 = bestmoveUCI.substring(0, 2);
  237. var res2 = bestmoveUCI.substring(2, 4);
  238. $(board.nodeName)
  239. .prepend('<div class="highlight square-' + res2 + ' bro" style="background-color: rgb(235, 97, 80); opacity: 0.71;" data-test-element="highlight"></div>')
  240. .children(':first')
  241. .delay(1800)
  242. .queue(function() {
  243. $(this)
  244. .remove();
  245. });
  246. $(board.nodeName)
  247. .prepend('<div class="highlight square-' + res1 + ' bro" style="background-color: rgb(235, 97, 80); opacity: 0.71;" data-test-element="highlight"></div>')
  248. .children(':first')
  249. .delay(1800)
  250. .queue(function() {
  251. $(this)
  252. .remove();
  253. });
  254. console.log("myFunctions.highlightMove COMPLETED - move highlighted:", bestmoveUCI);
  255. }
  256. myFunctions.movePiece = function(bestmoveUCI){ // Modified movePiece to take UCI move
  257. console.log("myFunctions.movePiece CALLED with UCI move:", bestmoveUCI); // Log with UCI move
  258. const fromSquare = bestmoveUCI.substring(0, 2);
  259. const toSquare = bestmoveUCI.substring(2, 4);
  260. console.log("Parsed fromSquare:", fromSquare, "toSquare:", toSquare);
  261. const legalMoves = board.game.getLegalMoves();
  262. let foundMove = null;
  263. for (const move of legalMoves) {
  264. if (move.from === fromSquare && move.to === toSquare) {
  265. foundMove = move;
  266. break;
  267. }
  268. }
  269. if (foundMove) {
  270. console.log("Found legal move in getLegalMoves, executing:", foundMove); // Log found move
  271. setTimeout(() => { // Added a small delay before move execution
  272. board.game.move({
  273. ...foundMove,
  274. promotion: 'false',
  275. animate: false,
  276. userGenerated: true
  277. });
  278. console.log("myFunctions.movePiece COMPLETED - move executed after delay"); // Log after delay and move
  279. }, 100); // 100ms delay - adjust if needed
  280. } else {
  281. console.warn("myFunctions.movePiece - LEGAL MOVE NOT FOUND in getLegalMoves for UCI move:", bestmoveUCI); // Warn with UCI move
  282. }
  283. }
  284. myFunctions.reloadChessEngine = function() {
  285. console.log(`Reloading the chess engine (Stockfish API - no reload needed).`);
  286. alert("Reloading engine for Stockfish API is not needed. Re-analyzing will use the API again.");
  287. }
  288. myFunctions.loadChessEngine = function() {
  289. console.log(`Using Stockfish Online API. No local engine loading.`);
  290. if (uiElementsLoaded) {
  291. $('#engineVersionText')[0].innerHTML = "Chess Engine: <strong>Stockfish API Loaded</strong>";
  292. }
  293. }
  294. myFunctions.fetchBestMoveFromAPI = function(fen, depth) {
  295. const apiURL = `${stockfishAPI_URI}?fen=${encodeURIComponent(fen)}&depth=${depth}`;
  296. console.log(`Fetching best move from API: ${apiURL}`);
  297. GM_xmlhttpRequest({
  298. method: "GET",
  299. url: apiURL,
  300. onload: function(response) {
  301. if (response.status === 200) {
  302. try {
  303. const jsonResponse = JSON.parse(response.responseText);
  304. if (jsonResponse.success === true) {
  305. const bestmove = jsonResponse.bestmove;
  306. console.log(`API Response SUCCESS: Bestmove - ${bestmove}, Evaluation - ${jsonResponse.evaluation}, Mate - ${jsonResponse.mate}`); // Success log
  307. console.log("Calling myFunctions.color with bestmove:", bestmove); // Log before calling color
  308. myFunctions.color(bestmove);
  309. } else {
  310. console.error("API request was successful, but 'success' is false in response:", jsonResponse);
  311. alert("Stockfish API returned an error. Please check console for details.");
  312. isThinking = false; // Stop thinking state
  313. if (uiElementsLoaded) {
  314. $('#engineVersionText')[0].innerHTML = "<span style='color:red;'>Chess Engine: <strong>Stockfish API Error</strong></span>";
  315. }
  316. }
  317. } catch (e) {
  318. console.error("Error parsing API response JSON:", e);
  319. alert("Error parsing Stockfish API response. Please check console for details.");
  320. isThinking = false; // Stop thinking state
  321. if (uiElementsLoaded) {
  322. $('#engineVersionText')[0].innerHTML = "<span style='color:red;'>Chess Engine: <strong>API Response Error</strong></span>";
  323. }
  324. }
  325. } else {
  326. console.error("Stockfish API request failed with status:", response.status, response.statusText);
  327. alert(`Stockfish API request failed. Status: ${response.status} ${response.statusText}. Please check console and internet connection.`);
  328. isThinking = false; // Stop thinking state
  329. if (uiElementsLoaded) {
  330. $('#engineVersionText')[0].innerHTML = "<span style='color:red;'>Chess Engine: <strong>API Request Failed</strong></span>";
  331. }
  332. }
  333. },
  334. onerror: function(error) {
  335. console.error("GM_xmlhttpRequest error:", error);
  336. alert("Error making Stockfish API request. Please check console and internet connection.");
  337. isThinking = false; // Stop thinking state
  338. if (uiElementsLoaded) {
  339. $('#engineVersionText')[0].innerHTML = "<span style='color:red;'>Chess Engine: <strong>API Request Error</strong></span>";
  340. }
  341. }
  342. });
  343. };
  344. var lastValue = 11;
  345. myFunctions.runChessEngine = function(depth){
  346. if (currentStockfishVersion === "Failed" || currentStockfishVersion === "None") {
  347. console.warn("Chess engine is not available (failed to load). Cannot run engine.");
  348. return;
  349. }
  350. var fen = board.game.getFEN();
  351. console.log(`[Stockfish API] Requesting analysis for FEN: ${fen}, Depth: ${depth}`);
  352. isThinking = true;
  353. myFunctions.fetchBestMoveFromAPI(fen, 7); // Call API function with REDUCED DEPTH (7) for bullet
  354. lastValue = depth; // Keep lastValue for UI display, but API uses fixed depth 7 now for testing
  355. }
  356. myFunctions.autoRun = function(lstValue){
  357. if (currentStockfishVersion === "Failed" || currentStockfishVersion === "None") return;
  358. if(board.game.getTurn() == board.game.getPlayingAs()){
  359. myFunctions.runChessEngine(lstValue);
  360. }
  361. }
  362. document.onkeydown = function(e) {
  363. if (currentStockfishVersion === "Failed" || currentStockfishVersion === "None") return;
  364. switch (e.keyCode) {
  365. case 81:
  366. myFunctions.runChessEngine(1);
  367. break;
  368. case 87:
  369. myFunctions.runChessEngine(2);
  370. break;
  371. case 69:
  372. myFunctions.runChessEngine(3);
  373. break;
  374. case 82:
  375. myFunctions.runChessEngine(4);
  376. break;
  377. case 84:
  378. myFunctions.runChessEngine(5);
  379. break;
  380. case 89:
  381. myFunctions.runChessEngine(6);
  382. break;
  383. case 85:
  384. myFunctions.runChessEngine(7);
  385. break;
  386. case 73:
  387. myFunctions.runChessEngine(8);
  388. break;
  389. case 79:
  390. myFunctions.runChessEngine(9);
  391. break;
  392. case 80:
  393. myFunctions.runChessEngine(10);
  394. break;
  395. case 65:
  396. myFunctions.runChessEngine(11);
  397. break;
  398. case 83:
  399. myFunctions.runChessEngine(12);
  400. break;
  401. case 68:
  402. myFunctions.runChessEngine(13);
  403. break;
  404. case 70:
  405. myFunctions.runChessEngine(14);
  406. break;
  407. case 71:
  408. myFunctions.runChessEngine(15);
  409. break;
  410. case 72:
  411. myFunctions.runChessEngine(16);
  412. break;
  413. case 74:
  414. myFunctions.runChessEngine(17);
  415. break;
  416. case 75:
  417. myFunctions.runChessEngine(18);
  418. case 76:
  419. myFunctions.runChessEngine(19);
  420. break;
  421. case 90:
  422. myFunctions.runChessEngine(20);
  423. break;
  424. case 88:
  425. myFunctions.runChessEngine(21);
  426. break;
  427. case 67:
  428. myFunctions.runChessEngine(22);
  429. break;
  430. case 86:
  431. myFunctions.runChessEngine(23);
  432. break;
  433. case 66:
  434. myFunctions.runChessEngine(24);
  435. break;
  436. case 78:
  437. myFunctions.runChessEngine(25);
  438. break;
  439. case 77:
  440. myFunctions.runChessEngine(26);
  441. break;
  442. case 187:
  443. myFunctions.runChessEngine(100);
  444. break;
  445. }
  446. };
  447. myFunctions.spinner = function() {
  448. if(isThinking == true){
  449. $('#overlay')[0].style.display = 'block';
  450. }
  451. if(isThinking == false) {
  452. $('#overlay')[0].style.display = 'none';
  453. }
  454. }
  455. let dynamicStyles = null;
  456. function addAnimation(body) {
  457. if (!dynamicStyles) {
  458. dynamicStyles = document.createElement('style');
  459. dynamicStyles.type = 'text/css';
  460. document.head.appendChild(dynamicStyles);
  461. }
  462. dynamicStyles.sheet.insertRule(body, dynamicStyles.length);
  463. }
  464. var loaded = false;
  465. myFunctions.loadEx = function(){
  466. try{
  467. var tmpStyle;
  468. var tmpDiv;
  469. board = $('chess-board')[0] || $('wc-chess-board')[0];
  470. if (!board) { // Check if board element is found
  471. console.warn("Chessboard element not found yet. Retrying...");
  472. return; // Exit and retry in the next interval
  473. }
  474. myVars.board = board;
  475. var div = document.createElement('div')
  476. var content = `<div style="margin: 0 0 0 8px;"><br><p id="depthText"> Your Current Depth Is: 11 </p><p> Press a key on your keyboard to change this!</p><p id="engineVersionText">Chess Engine: Stockfish API</p><br><input type="checkbox" id="autoRun" name="autoRun" value="false">
  477. <label for="autoRun"> Enable auto run</label><br>
  478. <input type="checkbox" id="autoMove" name="autoMove" value="false">
  479. <label for="autoMove"> Enable auto move</label><br>
  480. <input type="number" id="timeDelayMin" name="timeDelayMin" min="0.1" value=0.1>
  481. <label for="timeDelayMin">Auto Run Delay Minimum(Seconds)</label><br>
  482. <input type="number" id="timeDelayMax" name="timeDelayMax" min="0.1" value=1>
  483. <label for="timeDelayMax">Auto Run Delay Maximum(Seconds)</label></div>`
  484. div.innerHTML = content;
  485. div.setAttribute('style','background-color:white; height:auto;');
  486. div.setAttribute('id','settingsContainer');
  487. board.parentElement.parentElement.appendChild(div); //parentElement might be null, but board is checked above
  488. //spinnerContainer
  489. var spinCont = document.createElement('div');
  490. spinCont.setAttribute('style','display:none;');
  491. spinCont.setAttribute('id','overlay');
  492. div.prepend(spinCont);
  493. //spinner
  494. var spinr = document.createElement('div')
  495. spinr.setAttribute('style',`
  496. margin: 0 auto;
  497. height: 64px;
  498. width: 64px;
  499. animation: rotate 0.8s infinite linear;
  500. border: 5px solid firebrick;
  501. border-right-color: transparent;
  502. border-radius: 50%;
  503. `);
  504. spinCont.appendChild(spinr);
  505. addAnimation(`@keyframes rotate {
  506. 0% {
  507. transform: rotate(0deg);
  508. }
  509. 100% {
  510. transform: rotate(360deg);
  511. }
  512. }`);
  513. //Reload Button
  514. var reSty = `
  515. #relButDiv {
  516. position: relative;
  517. text-align: center;
  518. margin: 0 0 8px 0;
  519. }
  520. #relEngBut {
  521. position: relative;
  522. color: #ffef85;
  523. background-color: #3cba2c;
  524. font-size: 19px;
  525. border: 1px solid #000000;
  526. padding: 15px 50px;
  527. letter-spacing: 1px;
  528. cursor: pointer
  529. }
  530. #relEngBut:hover {
  531. color: #000000;
  532. background-color: #ba1212;
  533. }
  534. #relEngBut:active {
  535. background-color: #ba1212;
  536. transform: translateY(4px);
  537. }`;
  538. var reBut = `<button type="button" name="reloadEngine" id="relEngBut" onclick="document.myFunctions.reloadChessEngine()">Reload Chess Engine</button>`;
  539. tmpDiv = document.createElement('div');
  540. var relButDiv = document.createElement('div');
  541. relButDiv.id = 'relButDiv';
  542. tmpDiv.innerHTML = reBut;
  543. reBut = tmpDiv.firstChild;
  544. tmpStyle = document.createElement('style');
  545. tmpStyle.innerHTML = reSty;
  546. document.head.append(tmpStyle);
  547. relButDiv.append(reBut);
  548. div.append(relButDiv);
  549. // Issue Button
  550. var isBut = `<button type="button" name="isBut" onclick="window.confirm('Do you wish to go to my issue page?') ? document.location = 'https://forms.gle/UbcnhTutTX4aCrs48' : console.log('cancled')">Got An Issue/Bug?</button>`;
  551. tmpDiv = document.createElement('div');
  552. var isButDiv = document.createElement('div');
  553. isButDiv.style = `
  554. position: relative;
  555. text-align: center;
  556. margin: 0 0 8px 0;
  557. `;
  558. tmpDiv.innerHTML = isBut;
  559. isBut = tmpDiv.firstChild;
  560. isBut.id = 'isBut';
  561. isBut.style = `
  562. position: relative;
  563. color: #ffef85;
  564. background-color: #919191;
  565. font-size: 19px;
  566. border: 1px solid #000000;
  567. padding: 15px 50px;
  568. letter-spacing: 1px;
  569. cursor: pointer;
  570. `;
  571. isButDiv.append(isBut);
  572. div.append(isButDiv);
  573. loaded = true;
  574. uiElementsLoaded = true; // Set flag after UI elements are created
  575. myFunctions.loadChessEngine(); // Load engine only after UI is ready
  576. } catch (error) {console.log(error)}
  577. }
  578. function other(delay){
  579. var endTime = Date.now() + delay;
  580. var timer = setInterval(()=>{
  581. if(Date.now() >= endTime){
  582. myFunctions.autoRun(lastValue);
  583. canGo = true;
  584. clearInterval(timer);
  585. }
  586. },10);
  587. }
  588. async function getVersion(){
  589. var GF = new GreasyFork;
  590. var code = await GF.get().script().code(460208);
  591. var version = GF.parseScriptCodeMeta(code).filter(e => e.meta === '@version')[0].value;
  592. if(currentVersion !== version){
  593. while(true){
  594. alert('UPDATE THIS SCRIPT IN ORDER TO PROCEED!');
  595. }
  596. }
  597. }
  598. const waitForChessBoard = setInterval(() => {
  599. if(loaded) {
  600. board = $('chess-board')[0] || $('wc-chess-board')[0];
  601. myVars.autoRun = $('#autoRun')[0].checked;
  602. myVars.autoMove = $('#autoMove')[0].checked;
  603. let minDel = parseInt($('#timeDelayMin')[0].value);
  604. let maxDel = parseInt($('#timeDelayMax')[0].value);
  605. myVars.delay = Math.random() * (maxDel - minDel) + minDel;
  606. myVars.isThinking = isThinking;
  607. myFunctions.spinner();
  608. if(board.game.getTurn() == board.game.getPlayingAs()){myTurn = true;} else {myTurn = false;}
  609. if (uiElementsLoaded && $('#depthText')[0] && $('#engineVersionText')[0]) { // Check UI elements before updating
  610. $('#depthText')[0].innerHTML = "Your Current Depth Is: <strong>"+lastValue+"</strong> (Stockfish " + currentStockfishVersion + ")";
  611. if (currentStockfishVersion !== "None" && currentStockfishVersion !== "Failed") {
  612. $('#engineVersionText')[0].innerHTML = "Chess Engine: <strong>" + currentStockfishVersion + " Loaded</strong>";
  613. } else if (currentStockfishVersion === "Failed") {
  614. $('#engineVersionText')[0].innerHTML = "<span style='color:red;'>Chess Engine: <strong>Failed to Load</strong></span>";
  615. } else {
  616. $('#engineVersionText')[0].innerHTML = "Chess Engine: <strong>Loading...</strong>";
  617. }
  618. }
  619. } else {
  620. myFunctions.loadEx();
  621. }
  622. if(!engine.engine && currentStockfishVersion !== "Failed" && loaded){ // Prevent re-loading if already failed and after loadEx is done
  623. myFunctions.loadChessEngine();
  624. }
  625. if(myVars.autoRun == true && canGo == true && isThinking == false && myTurn){
  626. canGo = false;
  627. var currentDelay = myVars.delay != undefined ? myVars.delay * 1000 : 10;
  628. other(currentDelay);
  629. }
  630. }, 100);
  631. }
  632. //Touching below may break the script
  633. var isThinking = false
  634. var canGo = true;
  635. var myTurn = false;
  636. var board;
  637. var l = 'whoursie.com/4/5729456'; // This is likely related to the ad, and can be kept commented out if ads are removed.
  638. window.addEventListener("load", (event) => {
  639. let currentTime = Date.now();
  640. main();
  641. });