File size: 6,389 Bytes
364eb96 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | (function () {
console.log("%c Monkeytype Command Typer (execCommand) ", "background: #222; color: #ff0000; font-size: 20px");
const CONFIG = {
minWPM: 250, // Minimum expected WPM
maxWPM: 350, // Maximum expected WPM
errorRate: 0.15, // 15% chance to make a mistake
accuracy: 90, // Target accuracy (affects error correction)
startDelay: 50, // Delay before starting to type
};
let isArmed = true;
// EXECCOMMAND METHOD
// This often bypasses "isTrusted" checks because it simulates a browser action (paste/insert)
// rather than a raw key event.
function typeChar(char) {
const target = document.activeElement || document.body;
const keyConfig = {
key: char,
code: char === ' ' ? 'Space' : `Key${char.toUpperCase()}`,
bubbles: true,
cancelable: true,
view: window
};
// Dispatch keydown
target.dispatchEvent(new KeyboardEvent('keydown', keyConfig));
// Dispatch keypress (typical for character input)
target.dispatchEvent(new KeyboardEvent('keypress', keyConfig));
// We use insertText which is a powerful way to simulate user input
document.execCommand('insertText', false, char);
// Dispatch input event (execCommand usually triggers this, but to be safe)
// target.dispatchEvent(new InputEvent('input', { data: char, inputType: 'insertText', bubbles: true }));
// Dispatch keyup
target.dispatchEvent(new KeyboardEvent('keyup', keyConfig));
}
// Helper to sleep for a random duration
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Calculate dynamic delay based on WPM
// Standard word length is 5 chars. WPM = (Chars / 5) / (Time_min)
// Time_char_ms = (60000 / (WPM * 5))
function getKeystrokeDelay() {
// Pick a random WPM between min and max
const currentWPM = Math.floor(Math.random() * (CONFIG.maxWPM - CONFIG.minWPM + 1)) + CONFIG.minWPM;
const baseDelay = 60000 / (currentWPM * 5);
// Add some noise: +/- 20% variance per keystroke
const variance = baseDelay * 0.2;
const noise = (Math.random() * variance * 2) - variance;
return Math.max(10, baseDelay + noise); // Ensure delay is at least 10ms
}
async function simulateMistake(correctChar) {
const possibleMistakes = "abcdefghijklmnopqrstuvwxyz";
const distinctMistake = possibleMistakes.charAt(Math.floor(Math.random() * possibleMistakes.length));
// Type wrong char
typeChar(distinctMistake);
// Realization reaction time (slower than typing)
await sleep(getKeystrokeDelay() * 2.5);
// Backspace - simulate by selecting and deleting or execCommand delete?
// execCommand 'delete' works well for single char deletion
// Dispatch Backspace events
const target = document.activeElement || document.body;
const bsConfig = { key: 'Backspace', code: 'Backspace', bubbles: true, cancelable: true, view: window };
target.dispatchEvent(new KeyboardEvent('keydown', bsConfig));
document.execCommand('delete', false, null);
target.dispatchEvent(new KeyboardEvent('keyup', bsConfig));
// Correction pause
await sleep(getKeystrokeDelay() * 1.5);
}
async function autoType(text) {
console.log(`Typing ${text.length} chars (Human-Like Method)...`);
for (let i = 0; i < text.length; i++) {
const char = text[i];
// Check for mistake opportunity (only on alpha characters, not spaces)
if (/[a-zA-Z]/.test(char) && Math.random() < CONFIG.errorRate) {
// Determine if we should correct it immediately (high accuracy simulation)
// For now, always correct immediately
await simulateMistake(char);
}
typeChar(char);
let delay = getKeystrokeDelay();
// Pause longer on word boundaries (spaces)
if (char === ' ') {
delay *= 1.3;
}
await sleep(delay);
}
}
const triggerHandler = (e) => {
if (!isArmed) return;
if (e.key.length === 1 && !e.ctrlKey && !e.altKey && !e.metaKey) {
const activeWord = document.querySelector('#words .word.active');
if (!activeWord) return;
const firstLetterElement = activeWord.querySelector('letter');
const firstLetter = firstLetterElement ? firstLetterElement.textContent : null;
if (firstLetter && e.key === firstLetter) {
isArmed = false;
// Fetch text similar to before
const allWords = document.querySelectorAll('#words .word');
let fullBuffer = "";
let foundActive = false;
allWords.forEach(word => {
if (word === activeWord) {
foundActive = true;
const letters = word.querySelectorAll('letter');
for (let i = 1; i < letters.length; i++) {
fullBuffer += letters[i].textContent;
}
fullBuffer += " ";
} else if (foundActive) {
const letters = word.querySelectorAll('letter');
letters.forEach(l => fullBuffer += l.textContent);
fullBuffer += " ";
}
});
if (fullBuffer.endsWith(" ")) {
fullBuffer = fullBuffer.slice(0, -1);
}
window.removeEventListener('keydown', triggerHandler);
console.log("Trigger detected. Starting Command Typer...");
setTimeout(() => {
autoType(fullBuffer);
}, CONFIG.startDelay);
}
}
};
window.addEventListener('keydown', triggerHandler);
console.log("READY! Type the first letter to test Command Mode.");
})();
|