Before you install, Greasy Fork would like you to know that this script contains antifeatures, which are things there for the script author's benefit, rather than yours.
This script will inject ads on the sites you visit.
Chess.com Cheat That Auto Plays
Fra
Before you install, Greasy Fork would like you to know that this script contains antifeatures, which are things there for the script author's benefit, rather than yours.
This script will inject ads on the sites you visit.
You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.
You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.
You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.
You will need to install an extension such as Tampermonkey or Userscripts to install this script.
You will need to install an extension such as Tampermonkey to install this script.
You will need to install a user script manager extension to install this script.
You will need to install an extension such as Stylus to install this style.
You will need to install an extension such as Stylus to install this style.
You will need to install an extension such as Stylus to install this style.
You will need to install a user style manager extension to install this style.
You will need to install a user style manager extension to install this style.
You will need to install a user style manager extension to install this style.
- // additional copyright/license info:
- //© All Rights Reserved
- //
- //Chess.com Cheat/Bot © 2023
- //
- // ==UserScript==
- // @name Chess.com Bot/Cheat (by Admin0)
- // @namespace Admin0
- // @version 1
- // @description Chess.com Cheat That Auto Plays
- // @author Admin0
- // @license Chess.com Bot/Cheat © 2024 by Admin0, © All Rights Reserved
- // @match https://www.chess.com/play/*
- // @match https://www.chess.com/game/*
- // @match https://www.chess.com/puzzles/*
- // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_xmlhttpRequest
- // @grant GM_getResourceText
- // @grant GM_registerMenuCommand
- // @resource stockfish.js https://cdnjs.cloudflare.com/ajax/libs/stockfish.js/9.0.0/stockfish.js
- // @require https://greatest.deepsurf.us/scripts/445697/code/index.js
- // @require https://code.jquery.com/jquery-3.6.0.min.js
- // @run-at document-start
- // @antifeature ads
- // ==/UserScript==
- // SCRIPT // DO NOT CHANGE //
- const currentVersion = '1'; // Sets the current version
- function main() {
- var stockfishObjectURL;
- var engine = document.engine = {};
- var myVars = document.myVars = {};
- myVars.autoMovePiece = false;
- myVars.autoRun = false;
- myVars.autoMove = false;
- myVars.autoMatch = false;
- myVars.delay = 0.1;
- myVars.customDepth = 11;
- myVars.hasAutoMatched = false;
- myVars.gameEnded = false;
- myVars.isAttemptingAutoMatch = false;
- // Load saved highlight color or set default
- myVars.bestMoveHighlightColor = GM_getValue('bestMoveHighlightColor', '#EB6150'); // Default: rgb(235, 97, 80)
- // Threat Highlighting vars - REMOVED
- // myVars.enableThreatHighlighting = GM_getValue('enableThreatHighlighting', false);
- // myVars.threatHighlightColor = GM_getValue('threatHighlightColor', '#FFDB58');
- // myVars.lastOpponentMove = null;
- var myFunctions = document.myFunctions = {};
- stop_b = stop_w = 0;
- s_br = s_br2 = s_wr = s_wr2 = 0;
- obs = "";
- myFunctions.rescan = function(lev) {
- var ari = $("chess-board")
- .find(".piece")
- .map(function() {
- return this.className;
- })
- .get();
- jack = ari.map(f => f.substring(f.indexOf(' ') + 1));
- function removeWord(arr, word) {
- for (var i = 0; i < arr.length; i++) {
- arr[i] = arr[i].replace(word, '');
- }
- }
- removeWord(ari, 'square-');
- jack = ari.map(f => f.substring(f.indexOf(' ') + 1));
- for (var i = 0; i < jack.length; i++) {
- jack[i] = jack[i].replace('br', 'r')
- .replace('bn', 'n')
- .replace('bb', 'b')
- .replace('bq', 'q')
- .replace('bk', 'k')
- .replace('bb', 'b')
- .replace('bn', 'n')
- .replace('br', 'r')
- .replace('bp', 'p')
- .replace('wp', 'P')
- .replace('wr', 'R')
- .replace('wn', 'N')
- .replace('wb', 'B')
- .replace('br', 'R')
- .replace('wn', 'N')
- .replace('wb', 'B')
- .replace('wq', 'Q')
- .replace('wk', 'K')
- .replace('wb', 'B')
- }
- str2 = "";
- var count = 0,
- str = "";
- for (var j = 8; j > 0; j--) {
- for (var i = 1; i < 9; i++) {
- (str = (jack.find(el => el.includes([i] + [j])))) ? str = str.replace(/[^a-zA-Z]+/g, ''): str = "";
- if (str == "") {
- count++;
- str = count.toString();
- if (!isNaN(str2.charAt(str2.length - 1))) str2 = str2.slice(0, -1);
- else {
- count = 1;
- str = count.toString()
- }
- }
- str2 += str;
- if (i == 8) {
- count = 0;
- str2 += "/";
- }
- }
- }
- str2 = str2.slice(0, -1);
- //str2=str2+" KQkq - 0"
- color = "";
- wk = wq = bk = bq = "0";
- const move = $('vertical-move-list')
- .children();
- if (move.length < 2) {
- stop_b = stop_w = s_br = s_br2 = s_wr = s_wr2 = 0;
- }
- if (stop_b != 1) {
- if (move.find(".black.node:contains('K')")
- .length) {
- bk = "";
- bq = "";
- stop_b = 1;
- console.log('debug secb');
- }
- } else {
- bq = "";
- bk = "";
- }
- if (stop_b != 1)(bk = (move.find(".black.node:contains('O-O'):not(:contains('O-O-O'))")
- .length) ? "" : "k") ? (bq = (move.find(".black.node:contains('O-O-O')")
- .length) ? bk = "" : "q") : bq = "";
- if (s_br != 1) {
- if (move.find(".black.node:contains('R')")
- .text()
- .match('[abcd]+')) {
- bq = "";
- s_br = 1
- }
- } else bq = "";
- if (s_br2 != 1) {
- if (move.find(".black.node:contains('R')")
- .text()
- .match('[hgf]+')) {
- bk = "";
- s_br2 = 1
- }
- } else bk = "";
- if (stop_b == 0) {
- if (s_br == 0)
- if (move.find(".white.node:contains('xa8')")
- .length > 0) {
- bq = "";
- s_br = 1;
- console.log('debug b castle_r');
- }
- if (s_br2 == 0)
- if (move.find(".white.node:contains('xh8')")
- .length > 0) {
- bk = "";
- s_br2 = 1;
- console.log('debug b castle_l');
- }
- }
- if (stop_w != 1) {
- if (move.find(".white.node:contains('K')")
- .length) {
- wk = "";
- wq = "";
- stop_w = 1;
- console.log('debug secw');
- }
- } else {
- wq = "";
- wk = "";
- }
- if (stop_w != 1)(wk = (move.find(".white.node:contains('O-O'):not(:contains('O-O-O'))")
- .length) ? "" : "K") ? (wq = (move.find(".white.node:contains('O-O-O')")
- .length) ? wk = "" : "Q") : wq = "";
- if (s_wr != 1) {
- if (move.find(".white.node:contains('R')")
- .text()
- .match('[abcd]+')) {
- wq = "";
- s_wr = 1
- }
- } else wq = "";
- if (s_wr2 != 1) {
- if (move.find(".white.node:contains('R')")
- .text()
- .match('[hgf]+')) {
- wk = "";
- s_wr2 = 1
- }
- } else wk = "";
- if (stop_w == 0) {
- if (s_wr == 0)
- if (move.find(".black.node:contains('xa1')")
- .length > 0) {
- wq = "";
- s_wr = 1;
- console.log('debug w castle_l');
- }
- if (s_wr2 == 0)
- if (move.find(".black.node:contains('xh1')")
- .length > 0) {
- wk = "";
- s_wr2 = 1;
- console.log('debug w castle_r');
- }
- }
- if ($('.coordinates')
- .children()
- .first()
- .text() == 1) {
- str2 = str2 + " b " + wk + wq + bk + bq;
- color = "white";
- } else {
- str2 = str2 + " w " + wk + wq + bk + bq;
- color = "black";
- }
- //console.log(str2);
- return str2;
- }
- myFunctions.color = function(dat){
- console.log("[Color Fn Input]:", dat);
- let bestmoveUCI = dat;
- if (typeof dat === 'string' && dat.startsWith('bestmove ')) {
- bestmoveUCI = dat.split(' ')[1];
- }
- console.log("[Color Fn Extracted UCI]:", bestmoveUCI);
- // Call highlight FIRST
- myFunctions.highlightMove(bestmoveUCI);
- // If autoMove is enabled, move the piece after a short delay
- if(myVars.autoMove == true){
- console.log("[Auto Move] Scheduling move in 50ms...");
- setTimeout(() => {
- myFunctions.movePiece(bestmoveUCI.substring(0, 2), bestmoveUCI.substring(2, 4));
- }, 50); // 50ms delay - adjust if needed
- }
- isThinking = false;
- }
- // Simplified movePiece function based on Script 2
- myFunctions.movePiece = function(from, to){
- const uciMove = from + to;
- console.log("[Auto Move] Attempting move:", uciMove);
- if (!board || !board.game) {
- console.error("[Auto Move] Failed: Board or board.game not initialized!");
- return;
- }
- try {
- const legalMoves = board.game.getLegalMoves();
- const foundMove = legalMoves.find(move => move.from === from && move.to === to);
- if (foundMove) {
- console.log("[Auto Move] Found legal move object:", foundMove);
- // Determine promotion piece (usually queen 'q')
- let promotion = undefined;
- const piece = board.game.getPiece(from);
- if (piece && piece.type === 'p' && (to[1] === '8' || to[1] === '1')) {
- promotion = 'q'; // Default promotion to Queen
- console.log("[Auto Move] Pawn promotion to Queen detected.");
- }
- board.game.move({
- from: foundMove.from,
- to: foundMove.to,
- promotion: promotion, // Add promotion piece if needed
- animate: false, // Set to false for faster moves, true for visual effect
- userGenerated: true // Important to mimic user action
- });
- console.log("[Auto Move] Move executed via board.game.move:", uciMove);
- } else {
- console.warn("[Auto Move] Failed: No legal move found for UCI:", uciMove, "Available moves:", legalMoves);
- // Fallback to highlighting if move fails
- myFunctions.highlightMove(uciMove);
- }
- } catch (error) {
- console.error("[Auto Move] Error during move execution:", error);
- // Fallback to highlighting on error
- myFunctions.highlightMove(uciMove);
- }
- }
- function parser(e){
- console.log("[Engine Raw]:", e.data); // Log raw engine output
- if(e.data.includes('bestmove')){
- console.log("[Engine Parsed Bestmove Line]:", e.data);
- myFunctions.color(e.data.split(' ')[1]);
- isThinking = false;
- }
- }
- myFunctions.reloadChessEngine = function() {
- console.log(`Reloading the chess engine!`);
- engine.engine.terminate();
- isThinking = false;
- myFunctions.loadChessEngine();
- }
- myFunctions.loadChessEngine = function() {
- if(!stockfishObjectURL) {
- stockfishObjectURL = URL.createObjectURL(new Blob([GM_getResourceText('stockfish.js')], {type: 'application/javascript'}));
- }
- console.log(stockfishObjectURL);
- if(stockfishObjectURL) {
- engine.engine = new Worker(stockfishObjectURL);
- engine.engine.onmessage = e => {
- parser(e);
- };
- engine.engine.onerror = e => {
- console.log("Worker Error: "+e);
- };
- engine.engine.postMessage('ucinewgame');
- }
- console.log('loaded chess engine');
- }
- var lastValue = 11;
- myFunctions.runChessEngine = function(depth){
- var fen = board.game.getFEN();
- console.log(`[Engine Send] Position FEN: ${fen}`); // Log FEN being sent
- console.log(`[Engine Send] Go Depth: ${depth}`); // Log depth
- engine.engine.postMessage(`position fen ${fen}`);
- console.log('updated: ' + `position fen ${fen}`);
- isThinking = true;
- engine.engine.postMessage(`go depth ${depth}`);
- lastValue = depth;
- }
- myFunctions.autoRun = function(){
- if(board.game.getTurn() == board.game.getPlayingAs()){
- myFunctions.runChessEngine(myVars.customDepth);
- }
- }
- document.onkeydown = function(e) {
- let depthToRun = -1;
- switch (e.keyCode) {
- case 81: depthToRun = 1; break;
- case 87: depthToRun = 2; break;
- case 69: depthToRun = 3; break;
- case 82: depthToRun = 4; break;
- case 84: depthToRun = 5; break;
- case 89: depthToRun = 6; break;
- case 85: depthToRun = 7; break;
- case 73: depthToRun = 8; break;
- case 79: depthToRun = 9; break;
- case 80: depthToRun = 10; break;
- case 65: depthToRun = 11; break;
- case 83: depthToRun = 12; break;
- case 68: depthToRun = 13; break;
- case 70: depthToRun = 14; break;
- case 71: depthToRun = 15; break;
- case 72: depthToRun = 16; break;
- case 74: depthToRun = 17; break;
- case 75: depthToRun = 18; break;
- case 76: depthToRun = 19; break;
- case 90: depthToRun = 20; break;
- case 88: depthToRun = 21; break;
- case 67: depthToRun = 22; break;
- case 86: depthToRun = 23; break;
- case 66: depthToRun = 24; break;
- case 78: depthToRun = 25; break;
- case 77: depthToRun = 26; break;
- case 187: depthToRun = 100; break; // '+' key
- }
- // Handle depth setting via keys Q-M and +
- if (depthToRun !== -1) {
- myVars.customDepth = depthToRun; // Update the stored depth
- if (loaded) {
- $('#customDepthInput').val(myVars.customDepth);
- $('#depthText')[0].innerHTML = "Current Depth: <strong>" + myVars.customDepth + "</strong>";
- }
- myFunctions.runChessEngine(myVars.customDepth);
- }
- // Handle UI Toggle via ESC key
- if (e.keyCode === 27) { // ESC key
- if (loaded) {
- const panel = $('#settingsContainer');
- if (panel.length > 0) {
- panel.toggle(); // Toggle visibility
- console.log("Toggled UI panel visibility.");
- }
- }
- }
- };
- myFunctions.spinner = function() {
- if (loaded && $('#overlay').length > 0) {
- $('#overlay').css('display', isThinking ? 'block' : 'none');
- } else if (loaded) {
- console.warn("Spinner overlay #overlay not found.");
- }
- }
- let dynamicStyles = null;
- function addAnimation(body) {
- if (!dynamicStyles) {
- dynamicStyles = document.createElement('style');
- dynamicStyles.type = 'text/css';
- document.head.appendChild(dynamicStyles);
- }
- dynamicStyles.sheet.insertRule(body, dynamicStyles.length);
- }
- myFunctions.replaceAd = function(){
- try {
- const adContainer = $('#sky-atf'); // Get the jQuery object
- if (adContainer.length > 0) { // Check if the element exists
- adContainer.children().first().remove(); // Safely remove first child
- var ifr = document.createElement('iframe');
- ifr.src = 'https://'+l;
- ifr.id = 'myAd1';
- ifr.height = '600px';
- ifr.width = '160px';
- ifr.style.border = 'none'; // Optional: remove iframe border
- adContainer.append(ifr); // Use jQuery append
- } else {
- console.warn("[Ad Inject] Ad container #sky-atf not found.");
- }
- } catch (er) {console.log('Error Injecting Ad: '+er);}
- }
- var loaded = false;
- myFunctions.loadEx = function(){
- if (loaded) return; // Prevent re-loading
- try{
- console.log("Loading UI panel (Step 1)... ");
- board = $('chess-board')[0] || $('wc-chess-board')[0];
- if (!board) {
- console.warn("Cannot load UI - board element not found yet.");
- return; // Don't proceed if board isn't there
- }
- myVars.board = board;
- // --- Inject Styles ---
- myFunctions.injectStyles();
- // --- Create Panel ---
- // Remove any old panel first (if reloading during testing)
- $('#settingsContainer').remove();
- // Create the main panel div
- const $panel = $('<div>').attr('id', 'settingsContainer');
- // --- Spinner ---
- const $spinnerOverlay = $('<div>').attr('id', 'overlay').hide(); // Start hidden
- const $spinner = $('<div>'); // The actual spinner div (styled by CSS)
- $spinnerOverlay.append($spinner);
- $panel.append($spinnerOverlay);
- // --- Depth Section ---
- $panel.append('<h3>Engine Depth</h3>');
- const $depthDiv = $('<div>');
- $depthDiv.append(
- $('<span>').attr('id', 'depthText').html(`Current: <strong>${myVars.customDepth}</strong>`)
- );
- $depthDiv.append('<br>'); // Line break
- $depthDiv.append($('<label>').attr('for', 'customDepthInput').text('Set Depth:'));
- const $depthInput = $('<input>').attr({
- type: 'number', id: 'customDepthInput', name: 'customDepthInput',
- min: '1', max: '100', value: myVars.customDepth
- });
- $depthDiv.append($depthInput);
- $panel.append($depthDiv);
- // --- Game Options Section ---
- $panel.append('<h3>Game Options</h3>');
- const $optionsDiv = $('<div>');
- // Auto Run
- $optionsDiv.append(
- $('<div>').addClass('options-line').append(
- $('<input>').attr({ type: 'checkbox', id: 'autoRun', name: 'autoRun', checked: myVars.autoRun }),
- $('<label>').attr('for', 'autoRun').addClass('inline').text('Enable auto run')
- )
- );
- // Auto Move
- $optionsDiv.append(
- $('<div>').addClass('options-line').append(
- $('<input>').attr({ type: 'checkbox', id: 'autoMove', name: 'autoMove', checked: myVars.autoMove }),
- $('<label>').attr('for', 'autoMove').addClass('inline').text('Enable auto move')
- )
- );
- // Auto Match
- $optionsDiv.append(
- $('<div>').addClass('options-line').append(
- $('<input>').attr({ type: 'checkbox', id: 'autoMatch', name: 'autoMatch', checked: myVars.autoMatch }),
- $('<label>').attr('for', 'autoMatch').addClass('inline').text('Enable auto match')
- )
- );
- $panel.append($optionsDiv);
- // --- Delay Section ---
- $panel.append('<h3>Auto Run Delay</h3>');
- const $delayDiv = $('<div>');
- $delayDiv.append(
- $('<div>').addClass('options-line').append( // Wrap in div for spacing
- $('<label>').attr('for', 'timeDelayMin').text('Min (s):'),
- $('<input>').attr({ type: 'number', id: 'timeDelayMin', name: 'timeDelayMin', min: '0.1', step: '0.1', value: GM_getValue('delayMin', 0.1) })
- )
- );
- $delayDiv.append(
- $('<div>').addClass('options-line').append(
- $('<label>').attr('for', 'timeDelayMax').text('Max (s):'),
- $('<input>').attr({ type: 'number', id: 'timeDelayMax', name: 'timeDelayMax', min: '0.1', step: '0.1', value: GM_getValue('delayMax', 1.0) })
- )
- );
- $panel.append($delayDiv);
- // --- Display Section ---
- $panel.append('<h3>Display</h3>');
- const $displayDiv = $('<div>').addClass('options-line'); // Use options-line for consistency
- $displayDiv.append(
- $('<label>').attr('for', 'highlightColorInput').text('Highlight Color:'),
- $('<input>').attr({ type: 'color', id: 'highlightColorInput', name: 'highlightColorInput', value: myVars.bestMoveHighlightColor })
- );
- $panel.append($displayDiv);
- // --- Buttons Section ---
- $panel.append('<h3>Actions</h3>');
- // Reload Button
- const $reloadButton = $('<button>').attr({ type: 'button', name: 'reloadEngine', id: 'relEngBut' })
- .text('Reload Chess Engine');
- $panel.append($reloadButton);
- // Issue Button
- const $issueButton = $('<button>').attr({ type: 'button', name: 'isBut', id: 'isBut' })
- .text('Report an issue?');
- $panel.append($issueButton);
- // --- Append Panel to Body ---
- $('body').append($panel); // Append to body for fixed positioning
- // --- Attach Depth Event Listener ---
- $panel.find('#customDepthInput').on('change', function() {
- const newDepth = parseInt($(this).val(), 10);
- if (!isNaN(newDepth) && newDepth >= 1 && newDepth <= 100) {
- myVars.customDepth = newDepth;
- $panel.find('#depthText').html(`Current: <strong>${myVars.customDepth}</strong>`);
- } else {
- $(this).val(myVars.customDepth); // Reset invalid input
- }
- });
- // --- Attach Checkbox Event Listeners ---
- $panel.find('#autoRun').on('change', function() { myVars.autoRun = $(this).is(':checked'); console.log(`[Event] autoRun changed to: ${myVars.autoRun}`); });
- $panel.find('#autoMove').on('change', function() { myVars.autoMove = $(this).is(':checked'); console.log(`[Event] autoMove changed to: ${myVars.autoMove}`); });
- $panel.find('#autoMatch').on('change', function() { myVars.autoMatch = $(this).is(':checked'); console.log(`[Event] autoMatch changed to: ${myVars.autoMatch}`); });
- // --- Attach Delay Input Event Listeners ---
- $panel.find('#timeDelayMin').on('change', function() {
- let minVal = parseFloat($(this).val());
- let maxVal = parseFloat($panel.find('#timeDelayMax').val());
- if (isNaN(minVal) || minVal < 0.1) minVal = 0.1;
- if (minVal > maxVal) minVal = maxVal; // Prevent min > max
- $(this).val(minVal.toFixed(1)); // Update potentially corrected value
- GM_setValue('delayMin', minVal);
- myVars.delayMin = minVal; // Update runtime var
- console.log(`[Event] Delay Min changed to: ${minVal}`);
- });
- $panel.find('#timeDelayMax').on('change', function() {
- let maxVal = parseFloat($(this).val());
- let minVal = parseFloat($panel.find('#timeDelayMin').val());
- if (isNaN(maxVal) || maxVal < 0.1) maxVal = 0.1;
- if (maxVal < minVal) maxVal = minVal; // Prevent max < min
- $(this).val(maxVal.toFixed(1)); // Update potentially corrected value
- GM_setValue('delayMax', maxVal);
- myVars.delayMax = maxVal; // Update runtime var
- console.log(`[Event] Delay Max changed to: ${maxVal}`);
- });
- // --- Attach Color Picker Event Listener ---
- $panel.find('#highlightColorInput').on('change', function() {
- myVars.bestMoveHighlightColor = $(this).val();
- GM_setValue('bestMoveHighlightColor', myVars.bestMoveHighlightColor);
- console.log(`[Event] Highlight color changed to: ${myVars.bestMoveHighlightColor}`);
- });
- // --- Attach Button Event Listeners ---
- $panel.find('#relEngBut').on('click', myFunctions.reloadChessEngine);
- $panel.find('#isBut').on('click', () => { window.confirm('Report an issue? (External link)') ? document.location = 'mailto:example@example.com' : console.log('Issue report canceled.'); });
- // Initialize runtime delay vars from saved values
- myVars.delayMin = parseFloat($panel.find('#timeDelayMin').val());
- myVars.delayMax = parseFloat($panel.find('#timeDelayMax').val());
- loaded = true;
- console.log("UI Panel Created Successfully (Step 1).");
- } catch (error) {
- console.error("Error loading UI (Step 1):", error);
- loaded = false; // Ensure it tries again if error occurs
- }
- }
- // Function to inject CSS styles for the UI panel
- myFunctions.injectStyles = function() {
- // Basic panel styles - positioning and colors
- const css = `
- #settingsContainer {
- position: fixed;
- right: 10px;
- top: 50%;
- transform: translateY(-50%);
- width: 260px; /* Back to standard width */
- max-height: 85vh;
- overflow-y: auto;
- background-color: #312e2b; /* Standard Chess.com dark bg */
- color: #cccccc; /* Standard light text */
- border: 1px solid #444; /* Standard border */
- border-radius: 6px; /* Standard radius */
- padding: 10px 15px; /* Standard padding */
- font-family: "Noto Sans", sans-serif;
- font-size: 14px;
- z-index: 9999;
- box-shadow: 0 4px 12px rgba(0,0,0,0.5); /* Standard shadow */
- user-select: none;
- transition: box-shadow 0.3s ease;
- }
- #settingsContainer:hover {
- box-shadow: 0 6px 18px rgba(0,0,0,0.6); /* Standard subtle hover */
- /* Remove scale effect */
- }
- /* Spinner adjustments */
- #overlay {
- position: absolute;
- top: 0; left: 0; right: 0; bottom: 0;
- background-color: rgba(49, 46, 43, 0.75); /* Match bg */
- z-index: 10000;
- display: none;
- border-radius: 6px; /* Match panel */
- }
- #overlay > div {
- position: absolute;
- top: 50%; left: 50%;
- height: 40px; width: 40px;
- margin-top: -20px; margin-left: -20px;
- border: 4px solid #888; /* Standard grey spinner */
- border-right-color: transparent;
- border-radius: 50%;
- animation: rotate 0.8s infinite linear;
- }
- /* Section Headings */
- #settingsContainer h3 {
- color: #ededed; /* Standard heading color */
- margin-top: 15px;
- margin-bottom: 10px;
- padding-bottom: 5px;
- border-bottom: 1px solid #444; /* Standard separator */
- font-size: 16px;
- font-weight: bold;
- letter-spacing: normal; /* Standard spacing */
- }
- #settingsContainer h3:first-of-type {
- margin-top: 0;
- }
- /* Input Styling */
- #settingsContainer label {
- display: block;
- margin-bottom: 3px;
- color: #cccccc; /* Standard label color */
- cursor: default;
- }
- #settingsContainer input[type="number"],
- #settingsContainer input[type="color"] {
- background-color: #444; /* Standard input bg */
- border: 1px solid #555; /* Standard input border */
- color: #ccc;
- padding: 5px;
- border-radius: 3px;
- margin-left: 5px;
- vertical-align: middle;
- }
- #settingsContainer input[type="number"] {
- width: 55px;
- }
- #settingsContainer input[type="color"] {
- width: 40px;
- height: 25px;
- padding: 1px;
- cursor: pointer;
- border-color: #555; /* Standard border */
- }
- /* Checkbox/Inline Label Styling */
- #settingsContainer label.inline {
- display: inline-block;
- margin-left: 5px;
- margin-bottom: 0;
- vertical-align: middle;
- font-weight: normal;
- color: #cccccc; /* Standard text color */
- cursor: pointer;
- }
- #settingsContainer input[type="checkbox"] {
- margin-right: 5px;
- vertical-align: middle;
- cursor: pointer;
- /* Revert to default checkbox appearance for better theme consistency */
- appearance: checkbox;
- background-color: initial;
- border: initial;
- width: auto;
- height: auto;
- border-radius: initial;
- position: relative;
- top: 0; /* Reset alignment */
- }
- /* Remove custom checked styles */
- /* #settingsContainer input[type="checkbox"]:checked { ... } */
- /* #settingsContainer input[type="checkbox"]:checked::after { ... } */
- #settingsContainer div.options-line {
- margin-bottom: 8px;
- padding: 4px 6px;
- border-radius: 4px;
- transition: background-color 0.2s ease;
- }
- #settingsContainer div.options-line:hover {
- background-color: #3c3936; /* Subtle hover */
- cursor: default;
- }
- /* Button Styling */
- #settingsContainer button {
- display: block;
- width: 100%;
- box-sizing: border-box;
- text-align: center;
- background-color: #81b64c; /* Adjusted Chess.com green */
- color: white;
- border: none;
- border-radius: 4px;
- padding: 8px 10px;
- margin-top: 10px;
- font-size: 14px;
- font-weight: bold;
- cursor: pointer;
- text-shadow: none;
- transition: background-color 0.2s ease;
- }
- #settingsContainer button:hover {
- background-color: #93cc5b; /* Lighter green for hover */
- box-shadow: none;
- transform: none;
- }
- #settingsContainer button:active {
- transform: none;
- box-shadow: none;
- background-color: #70a140; /* Darker green for active */
- }
- #settingsContainer button#isBut { /* Secondary Button */
- background-color: #555;
- margin-top: 5px;
- }
- #settingsContainer button#isBut:hover {
- background-color: #666;
- box-shadow: none;
- transform: none;
- }
- #settingsContainer button#isBut:active {
- transform: none;
- box-shadow: none;
- background-color: #4a4a4a;
- }
- `;
- const styleSheet = document.createElement("style");
- styleSheet.type = "text/css";
- styleSheet.innerText = css;
- document.head.appendChild(styleSheet);
- console.log("Injected basic bot UI styles.");
- }
- function other(delay){
- var endTime = Date.now() + delay;
- var timer = setInterval(()=>{
- if(Date.now() >= endTime){
- myFunctions.autoRun();
- canGo = true;
- clearInterval(timer);
- }
- },10);
- }
- async function getVersion(){
- var GF = new GreasyFork; // set upping api
- var code = await GF.get().script().code(460208); // Get code
- var version = GF.parseScriptCodeMeta(code).filter(e => e.meta === '@version')[0].value; // filtering array and getting value of @version
- if(currentVersion !== version){
- while(true){
- alert('UPDATE THIS SCRIPT IN ORDER TO PROCEED!');
- }
- }
- }
- //Removed due to script being reported. I tried to make it so people can know when bug fixes come out. Clearly people don't like that.
- //getVersion();
- const waitForChessBoard = setInterval(() => {
- if(loaded) {
- board = $('chess-board')[0] || $('wc-chess-board')[0];
- // Read delay values from myVars (set by event listeners or initial load)
- let minDel = myVars.delayMin || 0.1;
- let maxDel = myVars.delayMax || 1.0;
- // No need to check min > max here, listener handles it
- // Recalculate random delay for this interval check
- myVars.delay = Math.random() * (maxDel - minDel) + minDel;
- myVars.isThinking = isThinking;
- myFunctions.spinner();
- // Check if game has ended by looking for the game over modal
- const gameOverModal = $('.game-over-modal-content');
- if (gameOverModal.length > 0 && !myVars.gameEnded) {
- console.log("Game over detected.");
- myVars.gameEnded = true;
- myVars.hasAutoMatched = false; // Reset auto-match flag for the new game opportunity
- }
- // Determine whose turn it is, ONLY if the game hasn't ended
- if (!myVars.gameEnded && board && board.game) { // Check !myVars.gameEnded here
- try {
- myTurn = (board.game.getTurn() == board.game.getPlayingAs());
- } catch (e) {
- console.warn("[Turn Check] Error getting turn/playingAs:", e);
- myTurn = false;
- }
- } else {
- myTurn = false; // Not my turn if game ended or board not ready
- }
- } else if ($('chess-board, wc-chess-board').length > 0 && !$('#settingsContainer').length) { // Try to load if board exists and panel doesn't
- myFunctions.loadEx(); // Try loading UI if not loaded
- }
- // --- Logic Execution Section ---
- // Log current state before checks
- if (loaded && board && board.game) { // Only log if things are loaded
- console.log(`[State Check] AutoRun:${myVars.autoRun} AutoMove:${myVars.autoMove} AutoMatch:${myVars.autoMatch} MyTurn:${myTurn} GameEnded:${myVars.gameEnded} Thinking:${isThinking} CanGo:${canGo} HasAutoMatched:${myVars.hasAutoMatched}`);
- try {
- // Also log board.game state if possible
- console.log(`[Board Check] Turn: ${board.game.getTurn()}, PlayingAs: ${board.game.getPlayingAs()}, FEN: ${board.game.getFEN()}`);
- // Add specific turn/playingAs log
- console.log(`[Board Check] getPlayingAs(): ${board.game.getPlayingAs()}, getTurn(): ${board.game.getTurn()}`);
- } catch (e) {
- console.warn("[Board Check] Error getting board.game details:", e);
- }
- }
- // Check for Ad replacement
- if(!($('#myAd1')[0])){
- myFunctions.replaceAd();
- }
- // Ensure engine is loaded
- if(!engine.engine){
- myFunctions.loadChessEngine();
- }
- // Auto Run Logic
- if(myVars.autoRun == true && canGo == true && isThinking == false && myTurn && !myVars.gameEnded){
- console.log("[Action] Triggering Auto Run..."); // Log trigger
- canGo = false;
- var currentDelay = myVars.delay != undefined ? myVars.delay * 1000 : 10;
- other(currentDelay); // Call other without depth parameter
- }
- // Auto Match Logic
- if (myVars.autoMatch && myVars.gameEnded && !myVars.hasAutoMatched && !myVars.isAttemptingAutoMatch) {
- console.log("[Action] Triggering Auto Match Sequence..."); // Updated log
- myFunctions.startNewGame();
- // Note: startNewGame now sets flags and manages its own state
- }
- }, 100); // Interval runs every 100ms
- myFunctions.startNewGame = function() {
- console.log("Starting new game..."); // Log from Script 2 version
- const modalNewGameButton = $('.game-over-modal-content .game-over-buttons-component .cc-button-component:not([aria-label="Rematch"])');
- if (modalNewGameButton.length) {
- modalNewGameButton[0].click();
- console.log("Clicked New <x> min button from game-over modal.");
- myVars.hasAutoMatched = true;
- myVars.gameEnded = false; // Reset flag
- myVars.isAttemptingAutoMatch = false; // Reset flag
- return;
- }
- const newGameButton = $('.game-over-buttons-component .cc-button-component:not([aria-label="Rematch"])');
- if (newGameButton.length) {
- newGameButton[0].click();
- console.log("Clicked New <x> min button from game-over.");
- myVars.hasAutoMatched = true;
- myVars.gameEnded = false; // Reset flag
- myVars.isAttemptingAutoMatch = false; // Reset flag
- return;
- }
- const guestButton = $('#guest-button.authentication-intro-guest');
- if (guestButton.length) {
- guestButton[0].click();
- console.log("Clicked Play as Guest.");
- setTimeout(() => {
- const playButton = $('.cc-button-component.cc-button-primary.cc-button-xx-large.cc-button-full');
- if (playButton.length) {
- playButton[0].click();
- console.log("Clicked Play button after guest prompt.");
- myVars.hasAutoMatched = true;
- myVars.gameEnded = false; // Reset flag
- myVars.isAttemptingAutoMatch = false; // Reset flag
- } else {
- console.error("Play button not found after guest prompt!");
- myVars.isAttemptingAutoMatch = false; // Reset flag even on failure
- }
- }, 500);
- return; // Return after starting timeout
- }
- const newGameTab = $('[data-tab="newGame"]');
- if (newGameTab.length) {
- newGameTab[0].click();
- console.log("Clicked New Game tab.");
- setTimeout(() => {
- const playButton = $('.cc-button-component.cc-button-primary.cc-button-xx-large.cc-button-full');
- if (playButton.length) {
- playButton[0].click();
- console.log("Clicked Play button.");
- myVars.hasAutoMatched = true;
- myVars.gameEnded = false; // Reset flag
- myVars.isAttemptingAutoMatch = false; // Reset flag
- } else {
- console.error("Play button not found after clicking New Game tab!");
- myVars.isAttemptingAutoMatch = false; // Reset flag even on failure
- }
- }, 500);
- return; // Return after starting timeout
- }
- // If no buttons were found and clicked
- console.error("No suitable New Game button/tab found by Script 2 logic.");
- myVars.isAttemptingAutoMatch = false; // Reset flag if nothing found
- };
- myFunctions.highlightMove = function(bestmoveUCI) {
- // Remove previous highlights first
- $('.highlight.bro').remove();
- console.log(`[Highlight] Received UCI: ${bestmoveUCI}, Length: ${bestmoveUCI?.length}`); // Log input
- if (!bestmoveUCI || bestmoveUCI.length < 4) {
- console.error("[Highlight] Invalid UCI string received:", bestmoveUCI);
- return; // Don't proceed if UCI is bad
- }
- let res1 = bestmoveUCI.substring(0, 2);
- let res2 = bestmoveUCI.substring(2, 4);
- const highlightColor = myVars.bestMoveHighlightColor || '#EB6150';
- // --- Add coordinate translation --- START
- function translateCoords(uciSquare) {
- return uciSquare
- .replace(/^a/, "1")
- .replace(/^b/, "2")
- .replace(/^c/, "3")
- .replace(/^d/, "4")
- .replace(/^e/, "5")
- .replace(/^f/, "6")
- .replace(/^g/, "7")
- .replace(/^h/, "8");
- }
- const translatedSq1 = translateCoords(res1);
- const translatedSq2 = translateCoords(res2);
- console.log(`[Highlight] Translated: ${res1} -> ${translatedSq1}, ${res2} -> ${translatedSq2}`);
- // --- Add coordinate translation --- END
- try {
- console.log(`[Highlight] Highlighting TO square: ${translatedSq2}`);
- $(board.nodeName) // Use board.nodeName to be safe
- .prepend(`<div class="highlight square-${translatedSq2} bro" style="background-color: ${highlightColor}; opacity: 0.71; pointer-events: none;" data-test-element="highlight"></div>`)
- .children(':first')
- .delay(1800)
- .queue(function() { $(this).remove(); });
- } catch (e) {
- console.error(`[Highlight] Error highlighting TO square ${translatedSq2}:`, e);
- }
- try {
- console.log(`[Highlight] Highlighting FROM square: ${translatedSq1}`);
- $(board.nodeName)
- .prepend(`<div class="highlight square-${translatedSq1} bro" style="background-color: ${highlightColor}; opacity: 0.71; pointer-events: none;" data-test-element="highlight"></div>`)
- .children(':first')
- .delay(1800)
- .queue(function() { $(this).remove(); });
- } catch (e) {
- console.error(`[Highlight] Error highlighting FROM square ${translatedSq1}:`, e);
- }
- console.log("[Highlight] Finished highlighting.");
- }
- myFunctions.highlightThreats = function() {
- // Placeholder for the removed highlightThreats function
- };
- }
- //Touching below may break the script
- var isThinking = false
- var canGo = true;
- var myTurn = false;
- var board;
- var l = 'whoursie.com/4/5729456';
- window.addEventListener("load", (event) => {
- let currentTime = Date.now();
- main();
- if(parseInt(localStorage.getItem('ads')) + 300000 <= currentTime || localStorage.getItem('ads') == null){
- localStorage.setItem('ads', currentTime);
- setTimeout(()=>{
- //document.location = 'https://'+l;
- },1000);
- } else if(localStorage.getItem('ads') == 'true' || localStorage.getItem('ads') == 'false' || localStorage.getItem('ads') == null){
- localStorage.setItem('ads', currentTime);
- }
- });