mtgbrr - Monkeytype Speeder 2025

just press slash and start typing.

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

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name mtgbrr - Monkeytype Speeder 2025
// @author natsukitheslashuser 
// @description just press slash and start typing.
// @icon https://i.imgur.com/fUjylt3.png
// @version 42.01
// @match *://monkeytype.com/*
// @run-at document-start
// @grant none
// @license idk
// @namespace natsuki
// ==/UserScript==
/* jshint esversion:6 */

(function() {
    "use strict";

    // Configuration
    const MIN_DELAY = 0;
    const MAX_DELAY = 0;
    const TOGGLE_KEY = "Slash";
    const MISTAKES_PER_MINUTE = 5; // Target mistakes per minute
    const STOP_DELAY = 1; // Ultra-fast 1ms stop delay
    const log = console.log;

    // State variables
    let toggle = false;
    let typingTimeout = null;
    let stopCheckInterval = null;
    let lastKeyPressTime = 0;
    let realKeypressCount = 0;
    let autoKeypressCount = 0;
    let mistakeCount = 0;
    let startTime = 0;
    let isTyping = false;

    function random(min, max) {
        return Math.floor(Math.random() * (max - min + 1) + min);
    }

    function canType() {
        const typingTest = document.getElementById("typingTest");
        if (!typingTest) return false;
        
        const isHidden = typingTest.classList.contains("hidden");
        if (isHidden) toggle = false;
        
        // Only allow typing if toggle is on, test is visible AND we're in active typing state
        return toggle && !isHidden && isTyping;
    }

    function getNextCharacter() {
        const currentWord = document.querySelector(".word.active");
        if (!currentWord) return "";
        
        for (const letter of currentWord.children) {
            if (letter.className === "") return letter.textContent;
        }
        return " ";
    }

    function shouldMakeMistake() {
        // Calculate dynamic mistake chance based on elapsed time to meet target mistakes per minute
        const elapsedSeconds = (Date.now() - startTime) / 1000;
        const elapsedMinutes = elapsedSeconds / 60;
        const targetMistakes = elapsedMinutes * MISTAKES_PER_MINUTE;
        
        // If we've made fewer mistakes than target, increase the chance
        if (mistakeCount < targetMistakes) {
            const remainingTime = 60 - (elapsedSeconds % 60);
            const remainingMistakes = Math.ceil(MISTAKES_PER_MINUTE - mistakeCount % MISTAKES_PER_MINUTE);
            
            // Higher chance as we approach the end of the minute with fewer mistakes
            return Math.random() < (remainingMistakes / (remainingTime * 2));
        }
        
        return false;
    }
    
    function getRandomWrongCharacter(correctChar) {
        const nearbyKeys = {
            'a': ['s', 'q', 'z', 'w'],
            'b': ['v', 'n', 'g', 'h'],
            'c': ['x', 'v', 'd', 'f'],
            'd': ['s', 'f', 'e', 'r'],
            'e': ['w', 'r', 'd', 'f'],
            'f': ['d', 'g', 'r', 't'],
            'g': ['f', 'h', 't', 'y'],
            'h': ['g', 'j', 'y', 'u'],
            'i': ['u', 'o', 'k', 'l'],
            'j': ['h', 'k', 'u', 'i'],
            'k': ['j', 'l', 'i', 'o'],
            'l': ['k', ';', 'o', 'p'],
            'm': ['n', ',', 'j', 'k'],
            'n': ['b', 'm', 'h', 'j'],
            'o': ['i', 'p', 'k', 'l'],
            'p': ['o', '[', 'l', ';'],
            'q': ['w', 'a', '1', '2'],
            'r': ['e', 't', 'd', 'f'],
            's': ['a', 'd', 'w', 'e'],
            't': ['r', 'y', 'f', 'g'],
            'u': ['y', 'i', 'h', 'j'],
            'v': ['c', 'b', 'f', 'g'],
            'w': ['q', 'e', 'a', 's'],
            'x': ['z', 'c', 's', 'd'],
            'y': ['t', 'u', 'g', 'h'],
            'z': ['a', 'x', 's', 'd'],
            ' ': ['n', 'm', 'b', 'v']
        };
        
        if (correctChar in nearbyKeys) {
            const possibleMistakes = nearbyKeys[correctChar];
            return possibleMistakes[Math.floor(Math.random() * possibleMistakes.length)];
        }
        
        // Fallback for characters not in the map
        return String.fromCharCode(correctChar.charCodeAt(0) + (Math.random() > 0.5 ? 1 : -1));
    }

    const InputEvents = {};
    function pressKey(key) {
        const wordsInput = document.getElementById("wordsInput");
        if (!wordsInput) return;
        
        const KeyboardEvent = Object.assign({}, DEFAULT_INPUT_OPTIONS, { target: wordsInput, data: key });
        const InputEvent = Object.assign({}, DEFAULT_KEY_OPTIONS, { target: wordsInput, key: key });

        wordsInput.value += key;
        
        if (InputEvents.beforeinput) InputEvents.beforeinput(InputEvent);
        if (InputEvents.input) InputEvents.input(InputEvent);
        if (InputEvents.keyup) InputEvents.keyup(KeyboardEvent);
        
        autoKeypressCount++;
        
        // Log status occasionally
        if (autoKeypressCount % 10 === 0) {
            log(`Auto: ${autoKeypressCount}, Real: ${realKeypressCount}, Mistakes: ${mistakeCount}`);
        }
    }

    // Ultra-fast continuous stop check
    function setupStopCheck() {
        if (stopCheckInterval) {
            clearInterval(stopCheckInterval);
        }
        
        // Check every 1ms if we should be typing
        stopCheckInterval = setInterval(() => {
            const now = Date.now();
            const idleTime = now - lastKeyPressTime;
            
            // If we haven't had a keypress in STOP_DELAY ms, immediately stop typing
            if (idleTime > STOP_DELAY && isTyping) {
                isTyping = false;
                
                // Clear typing timeout to stop immediately
                if (typingTimeout) {
                    clearTimeout(typingTimeout);
                    typingTimeout = null;
                }
            }
        }, 1); // Check every 1ms for optimal responsiveness
    }

    function typeCharacter() {
        // Clear any existing timeout
        if (typingTimeout) {
            clearTimeout(typingTimeout);
            typingTimeout = null;
        }
        
        // Check if we can type
        if (!canType()) {
            return; // Don't schedule another character if conditions aren't met
        }

        // Get the correct next character
        const nextChar = getNextCharacter();
        
        if (nextChar) {
            // Decide if we should make a mistake
            if (shouldMakeMistake()) {
                const wrongChar = getRandomWrongCharacter(nextChar);
                pressKey(wrongChar);
                mistakeCount++;
                log(`Made mistake: typed '${wrongChar}' instead of '${nextChar}'. Total mistakes: ${mistakeCount}`);
            } else {
                pressKey(nextChar);
            }
            
            // Schedule the next character if still active
            if (canType()) {
                typingTimeout = setTimeout(typeCharacter, random(MIN_DELAY, MAX_DELAY));
            }
        }
    }

    // Handle keydown events
    window.addEventListener("keydown", function(event) {
        if (event.code === TOGGLE_KEY) {
            event.preventDefault();
            if (event.repeat) return;
            
            toggle = !toggle;
            if (toggle) {
                // Reset counters and timers when starting
                realKeypressCount = 0;
                autoKeypressCount = 0;
                mistakeCount = 0;
                startTime = Date.now();
                log("TYPING BOT ENABLED - Press keys to activate typing");
                
                // Set up the ultra-fast stop check interval
                setupStopCheck();
            } else {
                log("TYPING BOT DISABLED");
                
                // Clear all timers
                if (typingTimeout) {
                    clearTimeout(typingTimeout);
                    typingTimeout = null;
                }
                
                if (stopCheckInterval) {
                    clearInterval(stopCheckInterval);
                    stopCheckInterval = null;
                }
                
                isTyping = false;
            }
        } else if (toggle) {
            // Count real keypresses for regular keys
            if (!["Control", "Alt", "Shift", "Meta", "CapsLock", "Tab", "Escape"].includes(event.key)) {
                realKeypressCount++;
                
                // Update the last key press time to keep typing active
                lastKeyPressTime = Date.now();
                
                // Set typing state to active
                isTyping = true;
                
                // Start typing if not already typing
                if (!typingTimeout) {
                    typeCharacter();
                }
                
                // Prevent the keypress from affecting the typing
                event.preventDefault();
            }
        }
    }, true);

    // Clean up when page unloads
    window.addEventListener("beforeunload", function() {
        if (typingTimeout) clearTimeout(typingTimeout);
        if (stopCheckInterval) clearInterval(stopCheckInterval);
    });

    // Intercept event listeners
    function hook(element) {
        element.addEventListener = new Proxy(element.addEventListener, {
            apply(target, _this, args) {
                const [type, listener, ...options] = args;
                if (_this.id === "wordsInput") {
                    InputEvents[type] = listener;
                }
                return target.apply(_this, args);
            }
        });
    }
    hook(HTMLInputElement.prototype);

    const DEFAULT_KEY_OPTIONS = {
        key: "", code: "", keyCode: 0, which: 0, isTrusted: true, altKey: false,
        bubbles: true, cancelBubble: false, cancelable: true, charCode: 0,
        composed: true, ctrlKey: false, currentTarget: null, defaultPrevented: false,
        detail: 0, eventPhase: 0, isComposing: false, location: 0, metaKey: false,
        path: null, repeat: false, returnValue: true, shiftKey: false, srcElement: null,
        target: null, timeStamp: Date.now(), type: "", view: window,
    };

    const DEFAULT_INPUT_OPTIONS = {
        isTrusted: true, bubbles: true, cancelBubble: false, cancelable: false,
        composed: true, data: "", dataTransfer: null, defaultPrevented: false,
        detail: 0, eventPhase: 0, inputType: "insertText", isComposing: false,
        path: null, returnValue: true, sourceCapabilities: null, srcElement: null,
        target: null, currentTarget: null, timeStamp: Date.now(), type: "input",
        view: null, which: 0
    };
    
    log("MonkeyType Script loaded - Press / to toggle, then type to activate");
})();