Chess.com Stockfish Bot

Chess.com Stockfish Bot design to defeat chess

当前为 2025-02-22 提交的版本,查看 最新版本

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

QingJ © 2025

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