// ==UserScript== // @name monkeytype // @version 1.0 // @description Auto typing bot // @author elias // @match https://monkeytype.com/* // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; const CONFIG = { wpmTarget: 200, accuracy: 1, toggleKey: 'Slash', // "-" on german keyboard autoStart: false, pauseBetweenWords: 50 }; let isActive = CONFIG.autoStart; const InputEvents = {}; // believable misstype const adjacent = { 'a': 'sqw', 'b': 'vghn', 'c': 'xdfv', 'd': 'erfcxs', 'e': 'wsdr', 'f': 'rtgvcd', 'g': 'tyhbvf', 'h': 'yubjng', 'i': 'uojk', 'j': 'ikmnuh', 'k': 'olmji', 'l': 'pk', 'm': 'njk', 'n': 'bhjm', 'o': 'iplk', 'p': 'ol', 'q': 'wa', 'r': 'etdf', 's': 'awedxz', 't': 'ryfg', 'u': 'yihj', 'v': 'cfgb', 'w': 'qase', 'x': 'zsdc', 'z': 'tugh', 'y': 'asx' }; function getDelay() { const charsPerSecond = (CONFIG.wpmTarget * 5) / 60; const baseDelay = 1000 / charsPerSecond; const variance = baseDelay * 0.3; return baseDelay + (Math.random() * variance * 2 - variance); } function getNextCharacter() { const currentWord = document.querySelector(".word.active"); for (const letter of currentWord.children) { if (letter.className === "") return letter.textContent; } return " "; } function pressKey(key) { const wordsInput = document.getElementById("wordsInput"); 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; InputEvents.beforeinput(InputEvent); InputEvents.input(InputEvent); InputEvents.keyup(KeyboardEvent); } function typeCharacter() { const typingTest = document.getElementById("typingTest"); if (!isActive || (typingTest && typingTest.classList.contains("hidden"))) return; const nextChar = getNextCharacter(); if (Math.random() > CONFIG.accuracy && nextChar !== " ") { const wrongChar = adjacent[nextChar.toLowerCase()]?.[0] || 'x'; pressKey(wrongChar); setTimeout(() => { pressKey('\b'); setTimeout(() => { pressKey(nextChar); setTimeout(typeCharacter, getDelay()); }, 50); }, 100); } else { pressKey(nextChar); const delay = nextChar === " " ? CONFIG.pauseBetweenWords : getDelay(); setTimeout(typeCharacter, delay); } } window.addEventListener("keydown", function(event) { if (event.code === CONFIG.toggleKey) { event.preventDefault(); if (event.repeat) return; isActive = !isActive; if (isActive) typeCharacter(); } }); 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); // no idea what all this is 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: 6338.5, 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: 11543, type: "input", view: null, which: 0 }; setTimeout(() => { typeCharacter(); }, 1000); })();