// ==UserScript== // @name Lichess Bot (stockfish8.27) // @description Fully automated lichess bot // @author Nuro // @match *://lichess.org/* // @run-at document-start // @grant none // @require https://raw.githubusercontent.com/workinworld/stkfish/refs/heads/main/stockfish8.js // ==/UserScript== let chessEngine; let currentFen = ""; let bestMove; let webSocketWrapper = null; let gameId = null; let isWhite = true; // Flag to determine if the bot is playing white let isBotTurn = false; // Flag to track if it's the bot's turn function initializeChessEngine() { chessEngine = window.STOCKFISH(); } function interceptWebSocket() { let webSocket = window.WebSocket; const webSocketProxy = new Proxy(webSocket, { construct: function (target, args) { let wrappedWebSocket = new target(...args); webSocketWrapper = wrappedWebSocket; wrappedWebSocket.addEventListener("message", function (event) { let message = JSON.parse(event.data); console.log(message); // Extract game ID and player color if (message.type === "gameFull" && message.id) { gameId = message.id; isWhite = message.white.id === lichess.socket.settings.userId; console.log("Game ID:", gameId); console.log("Playing as white:", isWhite); isBotTurn = isWhite; console.log("isBotTurn", isBotTurn); } // Handle game state updates if (message.d && typeof message.d.fen === "string") { currentFen = message.d.fen; isBotTurn = isWhite ? currentFen.split(' ')[1] === 'w' : currentFen.split(' ')[1] === 'b'; console.log("isBotTurn", isBotTurn); if(isBotTurn){ calculateMove(); } } //Handle game changes if(message.type === "gameState" && message.status ==="started"){ isBotTurn = isWhite ? currentFen.split(' ')[1] === 'w' : currentFen.split(' ')[1] === 'b'; console.log("isBotTurn", isBotTurn); if(isBotTurn){ calculateMove(); } } if(message.type === "clock"){ isBotTurn = isWhite ? currentFen.split(' ')[1] === 'w' : currentFen.split(' ')[1] === 'b'; console.log("isBotTurn", isBotTurn); if(isBotTurn){ calculateMove(); } } }); return wrappedWebSocket; } }); window.WebSocket = webSocketProxy; } function calculateMove() { if(isBotTurn){ chessEngine.postMessage("position fen " + currentFen); chessEngine.postMessage("setoption name Skill Level " + 20); // chessEngine.postMessage("go depth 3"); chessEngine.postMessage("go wtime 0"); } } function setupChessEngineOnMessage() { chessEngine.onmessage = function (event) { if (event && event.includes("bestmove") && isBotTurn) { bestMove = event.split(" ")[1]; webSocketWrapper.send(JSON.stringify({ t: "move", d: { u: bestMove, b: 0, l: 10000, a: 0 } })); isBotTurn = false; } }; } initializeChessEngine(); interceptWebSocket(); setupChessEngineOnMessage();