From 1379341864fe7c983a72370cb60603187b828525 Mon Sep 17 00:00:00 2001 From: bigmoneycheese Date: Fri, 11 Jul 2025 13:11:09 -0500 Subject: [PATCH 01/10] Add files via upload --- BetterMint/html/options.html | 36 +++++- BetterMint/js/Mint.js | 228 +++++++++++++++++++++++++++++++---- BetterMint/js/loader.js | 4 + BetterMint/js/options.js | 12 ++ BetterMint/manifest.json | 4 +- 5 files changed, 255 insertions(+), 29 deletions(-) diff --git a/BetterMint/html/options.html b/BetterMint/html/options.html index fd7a583..3831e5e 100644 --- a/BetterMint/html/options.html +++ b/BetterMint/html/options.html @@ -2,7 +2,7 @@ - Mint V2 Internal + Unofficial Mint V2.1 @@ -224,7 +224,7 @@ +
+ + +
+
+ + +
+ +
+ + +
+
+
Panic Threshold (seconds):
+ +
+
Auto Move Delay:
@@ -554,11 +582,11 @@

Features (not updated)

-
BetterMint v2.0 +
BetterMint v2.1
Public

- by BetterMint, HotaVN, lucaskvasirr, Webcubed, & thedemons + by BetterMint, HotaVN, lucaskvasirr, Webcubed, & thedemons. Updated by .baconater69.
diff --git a/BetterMint/js/Mint.js b/BetterMint/js/Mint.js index b1e4b22..8fef138 100644 --- a/BetterMint/js/Mint.js +++ b/BetterMint/js/Mint.js @@ -126,8 +126,42 @@ var enumOptions = { MoveAnalysis: "option-move-analysis", DepthBar: "option-depth-bar", EvaluationBar: "option-evaluation-bar", + AutoQueue: "option-auto-queue", + PanicMode: "option-panic-mode", + PanicTime: "option-panic-time", + Notifications: "option-notifications", }; +// helper to parse remaining time for current player +function getRemainingPlayerTimeSeconds() { + const selectors = [ + '.clock-component.clock-bottom', + '.clock-button-component.clock-bottom', + '.clock.clock-bottom', + '.clock-bottom', + ]; + for (const sel of selectors) { + const el = document.querySelector(sel); + if (el && el.textContent) { + const text = el.textContent.trim(); + // Extract time like 1:23, 10:15, 0:05, 1:02:15 + const match = text.match(/\d{1,2}(:\d{2}){1,2}/); + if (!match) continue; + const parts = match[0].split(':').map(Number); + let seconds = 0; + if (parts.length === 3) { + seconds = parts[0] * 3600 + parts[1] * 60 + parts[2]; + } else if (parts.length === 2) { + seconds = parts[0] * 60 + parts[1]; + } else if (parts.length === 1) { + seconds = parts[0]; + } + return seconds; + } + } + return null; +} + var BetterMintmaster; var Config = undefined; var context = undefined; @@ -193,6 +227,8 @@ class GameController { BetterMintmaster.engine.moveCounter = 0; BetterMintmaster.engine.hasShownLimitMessage = false; BetterMintmaster.engine.isPreMoveSequence = true; + } else if (event.data === "gameOver") { + this.handleGameOver(); } }); let checkEventOne = false; @@ -221,7 +257,62 @@ class GameController { this.evalBar.classList.add("evaluation-bar-flipped"); else this.evalBar.classList.remove("evaluation-bar-flipped"); } + // handle auto queue toggle dynamically + this.setupAutoQueueObserver(); + }); + + // Setup auto-queue observer initially if enabled + this.setupAutoQueueObserver(); + } + + // Observe DOM for the "New" game button and click it when Auto Queue is enabled + setupAutoQueueObserver() { + if (this.autoQueueObserver) { + // If observer exists but AutoQueue is disabled, disconnect it. + if (!getValueConfig(enumOptions.AutoQueue)) { + this.autoQueueObserver.disconnect(); + this.autoQueueObserver = null; + } + return; + } + + if (!getValueConfig(enumOptions.AutoQueue)) return; + + this.autoQueueObserver = new MutationObserver(() => { + const buttons = document.querySelectorAll('button.game-over-buttons-button'); + for (const btn of buttons) { + const span = btn.querySelector('span'); + if (span && span.textContent.trim().startsWith('New')) { + btn.click(); + break; + } + } }); + + this.autoQueueObserver.observe(document.body, { childList: true, subtree: true }); + } + + handleGameOver() { + if (getValueConfig(enumOptions.AutoQueue)) { + const maxAttempts = 60; // Poll for 30 seconds + let attempts = 0; + const intervalId = setInterval(() => { + attempts++; + if (attempts > maxAttempts) { + clearInterval(intervalId); + return; + } + + const buttons = document.querySelectorAll('.game-over-buttons-button'); + for (const button of buttons) { + if (button.textContent && button.textContent.trim().startsWith('New')) { + button.click(); + clearInterval(intervalId); + return; + } + } + }, 500); + } } UpdateExtensionOptions() { if (getValueConfig(enumOptions.EvaluationBar) && this.evalBar == null) @@ -233,12 +324,8 @@ class GameController { this.evalBar.remove(); this.evalBar = null; } - if (getValueConfig(enumOptions.DepthBar) && this.depthBar == null) - this.CreateAnalysisTools(); - else if (!getValueConfig(enumOptions.DepthBar) && this.depthBar != null) { - this.depthBar.parentElement.remove(); - this.depthBar = null; - } + // Start or stop auto queue observer based on updated option + this.setupAutoQueueObserver(); if (!getValueConfig(enumOptions.ShowHints)) { this.RemoveCurrentMarkings(); } @@ -467,6 +554,75 @@ class GameController { } } +function getPieceFromFen(fen, square) { + const fenBoard = fen.split(' ')[0]; + const ranks = fenBoard.split('/'); + + const file = square.charCodeAt(0) - 'a'.charCodeAt(0); + const rank = 8 - parseInt(square.charAt(1), 10); + + if (rank < 0 || rank > 7 || file < 0 || file > 7) { + return null; // Invalid square + } + + const rankStr = ranks[rank]; + let fileIdx = 0; + for (let i = 0; i < rankStr.length; i++) { + const char = rankStr.charAt(i); + if (/\d/.test(char)) { // it's a number for empty squares + fileIdx += parseInt(char, 10); + } else { + if (fileIdx === file) { + return char; + } + fileIdx++; + } + } + return null; // Should be an empty square +} + +function getVerboseMove(move, fen) { + const piece = getPieceFromFen(fen, move.from); + // if (!piece) return move.move; // fallback - let's be optimistic + + const pieceNames = { + 'p': 'pawn', 'n': 'knight', 'b': 'bishop', 'r': 'rook', 'q': 'queen', 'k': 'king' + }; + + const pieceName = pieceNames[piece.toLowerCase()]; + + let verboseMove = `${pieceName} to ${move.to}`; + + const capturedPiece = getPieceFromFen(fen, move.to); + if (capturedPiece) { + const capturedPieceName = pieceNames[capturedPiece.toLowerCase()]; + verboseMove = `${pieceName} takes ${capturedPieceName} on ${move.to}`; + } + + // basic castling detection + if (piece.toLowerCase() === 'k') { + const fromFile = move.from.charCodeAt(0); + const toFile = move.to.charCodeAt(0); + if (Math.abs(fromFile - toFile) > 1) { + if (toFile > fromFile) return "castles kingside"; + else return "castles queenside"; + } + } + + // en passant detection + if (piece.toLowerCase() === 'p' && !capturedPiece && move.from.charAt(0) !== move.to.charAt(0)) { + verboseMove = `pawn takes on ${move.to}`; + } + + if (move.promotion) { + const promotionPieceName = pieceNames[move.promotion.toLowerCase()]; + verboseMove += ` promoting to a ${promotionPieceName}`; + } + + return verboseMove; +} + + class StockfishEngine { constructor(BetterMintmaster) { let stockfishJsURL; @@ -582,11 +738,22 @@ class StockfishEngine { go() { this.onReady(() => { this.stopEvaluation(() => { - // Prevent overlapping evaluations if (this.isEvaluating) return; - console.assert(!this.isEvaluating, "Duplicated Stockfish go command"); this.isEvaluating = true; - this.send(`go depth ${this.depth}`); + + // Panic mode logic + let cmd = null; + if (getValueConfig(enumOptions.PanicMode) && getValueConfig(enumOptions.LegitAutoMove)) { + const remaining = getRemainingPlayerTimeSeconds(); + const threshold = parseInt(getValueConfig(enumOptions.PanicTime)); + if (remaining !== null && remaining <= threshold) { + cmd = `go depth 1`; + } + } + if (!cmd) { + cmd = `go depth ${this.depth}`; + } + this.send(cmd); }); }); } @@ -972,7 +1139,7 @@ class StockfishEngine { setTimeout(() => { this.BetterMintmaster.game.controller.move(moveData); - if (window.toaster) { + if (getValueConfig(enumOptions.Notifications) && window.toaster) { window.toaster.add({ id: "auto-move-counter", duration: 2000, @@ -989,7 +1156,7 @@ class StockfishEngine { } if (this.moveCounter >= getValueConfig(enumOptions.MaxPreMoves)) { - if (window.toaster) { + if (getValueConfig(enumOptions.Notifications) && window.toaster) { window.toaster.add({ id: "auto-move-limit", duration: 2000, // Reduced from 3000 @@ -1024,7 +1191,7 @@ class StockfishEngine { moveData.promotion = bestMove.promotion; } - if (window.toaster) { + if (getValueConfig(enumOptions.Notifications) && window.toaster) { window.toaster.add({ id: "premove-mate", duration: 2000, @@ -1049,7 +1216,9 @@ class StockfishEngine { if (getValueConfig(enumOptions.TextToSpeech)) { const topMove = this.topMoves[0]; // Select the top move from the PV list - const msg = new SpeechSynthesisUtterance(topMove.move); // Use topMove.move for the spoken text + const currentFEN = this.BetterMintmaster.game.controller.getFEN(); + const verboseMove = getVerboseMove(topMove, currentFEN); + const msg = new SpeechSynthesisUtterance(verboseMove); // Use topMove.move for the spoken text const voices = window.speechSynthesis.getVoices(); const femaleVoices = voices.filter((voice) => voice.voiceURI.includes("Google UK English Female") @@ -1208,13 +1377,25 @@ class StockfishEngine { top_pv_moves = [fastestMateMove]; } } - let auto_move_time = - getValueConfig(enumOptions.AutoMoveTime) + - (Math.floor( - Math.random() * getValueConfig(enumOptions.AutoMoveTimeRandom) - ) % - getValueConfig(enumOptions.AutoMoveTimeRandomDiv)) * - getValueConfig(enumOptions.AutoMoveTimeRandomMulti); + let panicActive = false; + if (getValueConfig(enumOptions.PanicMode) && getValueConfig(enumOptions.LegitAutoMove)) { + const remaining = getRemainingPlayerTimeSeconds(); + const threshold = parseInt(getValueConfig(enumOptions.PanicTime)); + if (remaining !== null && remaining <= threshold) panicActive = true; + } + + let auto_move_time; + if (panicActive) { + auto_move_time = Math.floor(Math.random() * 600); // 0-599 ms + } else { + auto_move_time = + getValueConfig(enumOptions.AutoMoveTime) + + (Math.floor( + Math.random() * getValueConfig(enumOptions.AutoMoveTimeRandom) + ) % + getValueConfig(enumOptions.AutoMoveTimeRandomDiv)) * + getValueConfig(enumOptions.AutoMoveTimeRandomMulti); + } if ( isNaN(auto_move_time) || auto_move_time === null || @@ -1223,7 +1404,7 @@ class StockfishEngine { auto_move_time = 100; } const secondsTillAutoMove = (auto_move_time / 1000).toFixed(1); - if (window.toaster) { + if (getValueConfig(enumOptions.Notifications) && window.toaster) { window.toaster.add({ id: "chess.com", duration: (parseFloat(secondsTillAutoMove) + 1) * 1000, @@ -1293,6 +1474,7 @@ class BetterMint { // show a notification when the settings is updated, but only if the previous // notification has gone if ( + getValueConfig(enumOptions.Notifications) && window.toaster && window.toaster.notifications.findIndex( (noti) => noti.id == "BetterMint-settings-updated" @@ -1310,12 +1492,12 @@ class BetterMint { ); } onEngineLoaded() { - if (window.toaster) { + if (getValueConfig(enumOptions.Notifications) && window.toaster) { window.toaster.add({ id: "chess.com", duration: 3000, icon: "circle-info", - content: `BetterMint V2 is enabled!`, + content: `Unofficial Mint V2.1 is enabled!`, }); } } diff --git a/BetterMint/js/loader.js b/BetterMint/js/loader.js index 43476db..508f2e0 100644 --- a/BetterMint/js/loader.js +++ b/BetterMint/js/loader.js @@ -28,6 +28,10 @@ let inputObjects = { "option-move-analysis": { default_value: true }, "option-depth-bar": { default_value: true }, "option-evaluation-bar": { default_value: true }, + "option-auto-queue": { default_value: false }, + "option-panic-mode": { default_value: false }, + "option-panic-time": { default_value: 10 }, + "option-notifications": { default_value: true }, }; let DefaultExtensionOptions = {}; diff --git a/BetterMint/js/options.js b/BetterMint/js/options.js index 47a577b..2b229e9 100644 --- a/BetterMint/js/options.js +++ b/BetterMint/js/options.js @@ -85,6 +85,18 @@ let inputObjects = { "option-evaluation-bar": { default_value: true, }, + "option-auto-queue": { + default_value: false, + }, + "option-panic-mode": { + default_value: false, + }, + "option-panic-time": { + default_value: 10, + }, + "option-notifications": { + default_value: true, + }, }; let DefaultExtensionOptions = {}; diff --git a/BetterMint/manifest.json b/BetterMint/manifest.json index 4153019..144a640 100644 --- a/BetterMint/manifest.json +++ b/BetterMint/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, - "name": "Mint V2 - Chess", - "short_name": "Mint V2 - Chess", + "name": "Unofficial Mint V2.1 - Chess", + "short_name": "Unofficial Mint V2.1 - Chess", "icons": { "16": "img/logo-16.png", "48": "img/logo-48.png", From 1b0598b6620d3db003e6ecc618837432a981bbb2 Mon Sep 17 00:00:00 2001 From: bigmoneycheese Date: Fri, 11 Jul 2025 13:19:43 -0500 Subject: [PATCH 02/10] Add files via upload Added panic mode, better tts, autoqueue, and notification toggle. --- BetterMint/html/options.html | 6 +++--- BetterMint/js/Mint.js | 2 +- BetterMint/manifest.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/BetterMint/html/options.html b/BetterMint/html/options.html index 3831e5e..75233ea 100644 --- a/BetterMint/html/options.html +++ b/BetterMint/html/options.html @@ -2,7 +2,7 @@ - Unofficial Mint V2.1 + Mint V2.0 @@ -224,7 +224,7 @@
-
BetterMint v2.1 +
BetterMint v2.0
Public

diff --git a/BetterMint/js/Mint.js b/BetterMint/js/Mint.js index 8fef138..001d43a 100644 --- a/BetterMint/js/Mint.js +++ b/BetterMint/js/Mint.js @@ -1497,7 +1497,7 @@ class BetterMint { id: "chess.com", duration: 3000, icon: "circle-info", - content: `Unofficial Mint V2.1 is enabled!`, + content: `Mint V2.0 is enabled!`, }); } } diff --git a/BetterMint/manifest.json b/BetterMint/manifest.json index 144a640..7210a09 100644 --- a/BetterMint/manifest.json +++ b/BetterMint/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, - "name": "Unofficial Mint V2.1 - Chess", - "short_name": "Unofficial Mint V2.1 - Chess", + "name": "Mint V2.0 - Chess", + "short_name": "Mint V2.0 - Chess", "icons": { "16": "img/logo-16.png", "48": "img/logo-48.png", From f4263a70fa25342ef633ef9c3ca079cbeb455122 Mon Sep 17 00:00:00 2001 From: bigmoneycheese Date: Fri, 11 Jul 2025 13:41:04 -0500 Subject: [PATCH 03/10] Add files via upload quick bugfix with engine selection --- run.bat | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 run.bat diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..a17aff5 --- /dev/null +++ b/run.bat @@ -0,0 +1,25 @@ +@echo off +cd /d "%~dp0" + +echo Uninstalling existing version of my_main_manager... +python -m pip uninstall -y my_main_manager + +:: Install dependencies from requirements.txt +echo Installing dependencies from requirements.txt... +python -m pip install -r requirements.txt +if %ERRORLEVEL% neq 0 ( + echo Failed to install dependencies. Exiting. + pause + exit /b +) + +:: Run the application +echo Starting application... +python -m uvicorn main:app --reload +if %ERRORLEVEL% neq 0 ( + echo Failed to start the application. Exiting. + pause + exit /b +) + +pause From 551a368bc1e7d93eae2940888c68f920b18acd97 Mon Sep 17 00:00:00 2001 From: bigmoneycheese Date: Fri, 11 Jul 2025 13:43:05 -0500 Subject: [PATCH 04/10] Delete run.bat --- run.bat | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 run.bat diff --git a/run.bat b/run.bat deleted file mode 100644 index a17aff5..0000000 --- a/run.bat +++ /dev/null @@ -1,25 +0,0 @@ -@echo off -cd /d "%~dp0" - -echo Uninstalling existing version of my_main_manager... -python -m pip uninstall -y my_main_manager - -:: Install dependencies from requirements.txt -echo Installing dependencies from requirements.txt... -python -m pip install -r requirements.txt -if %ERRORLEVEL% neq 0 ( - echo Failed to install dependencies. Exiting. - pause - exit /b -) - -:: Run the application -echo Starting application... -python -m uvicorn main:app --reload -if %ERRORLEVEL% neq 0 ( - echo Failed to start the application. Exiting. - pause - exit /b -) - -pause From c2ae06a3bf816ec1b0a2908d0f6d9c0d47221ff6 Mon Sep 17 00:00:00 2001 From: bigmoneycheese Date: Fri, 11 Jul 2025 13:43:36 -0500 Subject: [PATCH 05/10] Add files via upload From 6814ddc3d0b3b15963ccf436837a23f77a5fddd0 Mon Sep 17 00:00:00 2001 From: bigmoneycheese Date: Fri, 11 Jul 2025 13:45:38 -0500 Subject: [PATCH 06/10] Add files via upload From 9a249761b9efe93bd48ee5a65bfb0a5251359730 Mon Sep 17 00:00:00 2001 From: bigmoneycheese Date: Fri, 11 Jul 2025 13:51:02 -0500 Subject: [PATCH 07/10] Add files via upload From edea3436e4ce66ebee7538fc3108cf445e9e12a2 Mon Sep 17 00:00:00 2001 From: bigmoneycheese Date: Fri, 11 Jul 2025 13:57:23 -0500 Subject: [PATCH 08/10] Add files via upload --- EngineWS/__pycache__/main.cpython-313.pyc | Bin 0 -> 10884 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 EngineWS/__pycache__/main.cpython-313.pyc diff --git a/EngineWS/__pycache__/main.cpython-313.pyc b/EngineWS/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82622596ab45f82b4a101cb4d4f2d0476c659b48 GIT binary patch literal 10884 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 b;5T8rX2SVCy}!&7$0^l|zwxAd_!RfQwvOqU literal 0 HcmV?d00001 From 705b908e73927f12fc18409c4acf402a46a1bdf8 Mon Sep 17 00:00:00 2001 From: bigmoneycheese Date: Fri, 11 Jul 2025 14:13:57 -0500 Subject: [PATCH 09/10] Add files via upload --- EngineWS/main.py | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/EngineWS/main.py b/EngineWS/main.py index 788645a..4054960 100644 --- a/EngineWS/main.py +++ b/EngineWS/main.py @@ -24,13 +24,33 @@ def enqueue_output(out, queue): class EngineChess: def __init__(self, path_engine): - self._engine = subprocess.Popen( - path_engine, - universal_newlines=True, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - ) + print(f"Attempting to start engine: {path_engine}") + if not os.path.exists(path_engine): + show_message(f"ERROR: Engine path does not exist:\n{path_engine}") + raise FileNotFoundError(f"Engine not found at {path_engine}") + + try: + self._engine = subprocess.Popen( + [path_engine], + universal_newlines=True, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) + except OSError as e: + print(f"FATAL ERROR starting engine: {path_engine}") + print(f"DETAILS: {e}") + if hasattr(e, 'winerror') and e.winerror == 193: + show_message( + "The selected file is not a valid Windows application.\\n" + "This can happen if:\\n" + " - The file is for a different OS (e.g., Linux).\\n" + " - The file requires a CPU feature you don't have (like AVX2).\\n" + " - The file is corrupt or not a real engine.\\n\\n" + "Please restart and try selecting a different engine, like 'opental_x64plain.exe'." + ) + raise e + self.queueOutput = Queue() self.thread = Thread(target=enqueue_output, args=(self._engine.stdout, self.queueOutput)) self.thread.daemon = True @@ -78,7 +98,11 @@ def read_line(self) -> str: root.withdraw() show_message("Please select engine executable files.") -engine_exe_paths = filedialog.askopenfilenames(title="Select engine executable files") +initial_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'engines & books') +engine_exe_paths = filedialog.askopenfilenames( + title="Select engine executable files", + initialdir=initial_dir +) if not engine_exe_paths: print("No engine selected. Exiting.") From 48e59e71716c3b3f94f1704c0c2b0c6b84c0ffa4 Mon Sep 17 00:00:00 2001 From: bigmoneycheese Date: Fri, 11 Jul 2025 20:46:42 -0500 Subject: [PATCH 10/10] Add files via upload added instant premove and fast opening moves --- BetterMint/html/options.html | 33 ++++++++++- BetterMint/js/Mint.js | 104 ++++++++++++++++++++++++++--------- BetterMint/js/loader.js | 4 ++ BetterMint/js/options.js | 12 ++++ 4 files changed, 125 insertions(+), 28 deletions(-) diff --git a/BetterMint/html/options.html b/BetterMint/html/options.html index 75233ea..08118e4 100644 --- a/BetterMint/html/options.html +++ b/BetterMint/html/options.html @@ -353,10 +353,25 @@

Misc

+
- - + +
+
+
Activation Key:
+ +
+ +
+ + +
+
+ + +
+
+
Opening Move Speed (% Faster):
+ +
+