File size: 13,477 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 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | (function () {
console.log("%c Monkeytype Command Typer (Human-Like) v2 ", "background: #222; color: #00ff00; font-size: 20px");
const CONFIG = {
min_wpm: 300,
max_wpm: 340,
// Key Hold Time (Seconds)
min_key_hold: 0.01,
max_key_hold: 0.04,
// Imperfection Rates (0.0 to 1.0)
wrong_char_rate: 0.005,
adjacent_key_rate: 0.005,
double_letter_rate: 0.001,
skip_letter_rate: 0.001,
hesitation_rate: 0.02,
burst_rate: 0.08,
insane_burst_rate: 0.001,
// Timing Multipliers
hesitation_multiplier: 2.5,
burst_speed_multiplier: 0.6,
post_mistake_pause: 0.4, // Seconds
word_start_slowdown: 1.2,
};
// QWERTY keyboard adjacency map for realistic typos
const ADJACENT_KEYS = {
'a': ['q', 'w', 's', 'z'],
'b': ['v', 'g', 'h', 'n'],
'c': ['x', 'd', 'f', 'v'],
'd': ['s', 'e', 'r', 'f', 'c', 'x'],
'e': ['w', 's', 'd', 'r'],
'f': ['d', 'r', 't', 'g', 'v', 'c'],
'g': ['f', 't', 'y', 'h', 'b', 'v'],
'h': ['g', 'y', 'u', 'j', 'n', 'b'],
'i': ['u', 'j', 'k', 'o'],
'j': ['h', 'u', 'i', 'k', 'm', 'n'],
'k': ['j', 'i', 'o', 'l', 'm'],
'l': ['k', 'o', 'p'],
'm': ['n', 'j', 'k'],
'n': ['b', 'h', 'j', 'm'],
'o': ['i', 'k', 'l', 'p'],
'p': ['o', 'l'],
'q': ['w', 'a'],
'r': ['e', 'd', 'f', 't'],
's': ['a', 'w', 'e', 'd', 'x', 'z'],
't': ['r', 'f', 'g', 'y'],
'u': ['y', 'h', 'j', 'i'],
'v': ['c', 'f', 'g', 'b'],
'w': ['q', 'a', 's', 'e'],
'x': ['z', 's', 'd', 'c'],
'y': ['t', 'g', 'h', 'u'],
'z': ['a', 's', 'x'],
};
let isArmed = true;
let inBurstMode = false;
let inInsaneBurstMode = false;
let burstCharsRemaining = 0;
let totalCharsTyped = 0;
let recentMistake = false;
function randomRange(min, max) {
return Math.random() * (max - min) + min;
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Type a single character with key hold simulation
async 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
};
target.dispatchEvent(new KeyboardEvent('keydown', keyConfig));
target.dispatchEvent(new KeyboardEvent('keypress', keyConfig));
document.execCommand('insertText', false, char);
// Simulate key hold
const holdTime = randomRange(CONFIG.min_key_hold, CONFIG.max_key_hold) * 1000;
await sleep(holdTime);
target.dispatchEvent(new KeyboardEvent('keyup', keyConfig));
totalCharsTyped++;
}
// Single backspace with key hold simulation
async function typeBackspace() {
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);
const holdTime = randomRange(CONFIG.min_key_hold, CONFIG.max_key_hold) * 1000;
await sleep(holdTime);
target.dispatchEvent(new KeyboardEvent('keyup', bsConfig));
}
// Get adjacent key for realistic typo
function getAdjacentKey(char) {
const lowerChar = char.toLowerCase();
const adjacent = ADJACENT_KEYS[lowerChar];
if (adjacent && adjacent.length > 0) {
const randomAdj = adjacent[Math.floor(Math.random() * adjacent.length)];
return char === char.toUpperCase() ? randomAdj.toUpperCase() : randomAdj;
}
return char; // Fallback to same char if no adjacent found
}
// Get random wrong character
function getRandomChar() {
const chars = "abcdefghijklmnopqrstuvwxyz";
return chars.charAt(Math.floor(Math.random() * chars.length));
}
// Calculate keystroke delay
function getKeystrokeDelay() {
const currentWPM = Math.floor(Math.random() * (CONFIG.max_wpm - CONFIG.min_wpm + 1)) + CONFIG.min_wpm;
let baseDelay = 60000 / (currentWPM * 5);
// Apply burst mode (faster typing)
if (inBurstMode && burstCharsRemaining > 0) {
let multiplier = CONFIG.burst_speed_multiplier;
if (inInsaneBurstMode) {
multiplier *= 0.6; // Even faster for insane burst
}
baseDelay *= multiplier;
burstCharsRemaining--;
if (burstCharsRemaining === 0) {
inBurstMode = false;
inInsaneBurstMode = false;
}
}
// Add variance
const variance = baseDelay * 0.25;
const noise = (Math.random() * variance * 2) - variance;
return Math.max(8, baseDelay + noise);
}
// Get current word's remaining untyped text
function getCurrentWordText() {
const activeWord = document.querySelector('#words .word.active');
if (!activeWord) return null;
const letters = activeWord.querySelectorAll('letter');
let text = "";
let foundUntyped = false;
for (const letter of letters) {
if (!letter.classList.contains('correct') && !letter.classList.contains('incorrect')) {
foundUntyped = true;
}
if (foundUntyped) {
text += letter.textContent;
}
}
return text;
}
// Check if we're at the start of a word
function isWordStart() {
const activeWord = document.querySelector('#words .word.active');
if (!activeWord) return false;
const typed = activeWord.querySelectorAll('letter.correct, letter.incorrect');
return typed.length === 0;
}
// === MISTAKE SIMULATION FUNCTIONS ===
// Type wrong character and correct it
async function simulateWrongChar(correctChar) {
const wrongChar = getRandomChar();
await typeChar(wrongChar);
await sleep(getKeystrokeDelay() * 2.5);
await typeBackspace();
await sleep(getKeystrokeDelay() * 1.5);
recentMistake = true;
}
// Type adjacent key typo and correct it
async function simulateAdjacentKeyTypo(correctChar) {
const adjacentChar = getAdjacentKey(correctChar);
if (adjacentChar !== correctChar) {
await typeChar(adjacentChar);
await sleep(getKeystrokeDelay() * 2.2);
await typeBackspace();
await sleep(getKeystrokeDelay() * 1.3);
recentMistake = true;
}
}
// Double letter mistake
async function simulateDoubleLetter(char) {
// Type the correct char first (assumed done by caller loop usually, but here we do it)
// Actually, the main loop calls this INSTEAD of typing normally if it hits.
// But logic in main loop: if we match doubleLetterRate, we want to type char + char.
await typeChar(char);
await sleep(getKeystrokeDelay() * 0.3); // Very fast double tap
await typeChar(char);
// Pause to realize mistake
await sleep(getKeystrokeDelay() * 2.0);
// Delete the extra
await typeBackspace();
await sleep(getKeystrokeDelay() * 1.2);
recentMistake = true;
}
// Main typing loop with human imperfections
async function autoTypeLoop() {
console.log("Starting human-like auto-type loop v2...");
let wordCount = 0;
while (true) {
const currentWordText = getCurrentWordText();
if (currentWordText === null) {
console.log(`Auto-type complete! Typed ${wordCount} words, ${totalCharsTyped} characters.`);
break;
}
if (currentWordText.length === 0) {
const activeWord = document.querySelector('#words .word.active');
const nextWord = activeWord ? activeWord.nextElementSibling : null;
if (!nextWord || !nextWord.classList.contains('word')) {
await sleep(50);
const stillActive = document.querySelector('#words .word.active');
if (!stillActive) {
console.log(`Auto-type complete! Typed ${wordCount} words.`);
break;
}
continue;
}
await typeChar(' ');
wordCount++;
// Longer pause between words
let delay = getKeystrokeDelay() * 1.4;
await sleep(delay);
continue;
}
const char = currentWordText[0];
const nextChar = currentWordText.length > 1 ? currentWordText[1] : null;
let delay = getKeystrokeDelay();
// === APPLY HUMAN IMPERFECTIONS ===
// Slow start to words
if (isWordStart()) {
delay *= CONFIG.word_start_slowdown;
}
// Random hesitation (thinking pause)
if (Math.random() < CONFIG.hesitation_rate) {
delay *= CONFIG.hesitation_multiplier;
}
// Post-mistake recovery pause
if (recentMistake) {
await sleep(CONFIG.post_mistake_pause * 1000); // Fixed pause in seconds
recentMistake = false;
}
// Trigger burst mode
// Insane Burst (Higher priority / check first or separate?)
if (!inBurstMode && Math.random() < CONFIG.insane_burst_rate) {
inBurstMode = true;
inInsaneBurstMode = true;
burstCharsRemaining = 12; // Longer burst
} else if (!inBurstMode && Math.random() < CONFIG.burst_rate) {
inBurstMode = true;
burstCharsRemaining = 5;
}
// Skip letter imperfection
if (/[a-zA-Z]/.test(char) && Math.random() < CONFIG.skip_letter_rate && nextChar) {
// Type next char instead
await typeChar(nextChar);
await sleep(getKeystrokeDelay() * 2.5);
await typeBackspace();
await sleep(getKeystrokeDelay() * 1.3);
recentMistake = true;
// Now type correct char
await typeChar(char);
await sleep(delay);
continue;
}
// Double letter
if (/[a-zA-Z]/.test(char) && Math.random() < CONFIG.double_letter_rate) {
await simulateDoubleLetter(char);
await sleep(delay);
continue;
}
// Adjacent key typo
if (/[a-zA-Z]/.test(char) && Math.random() < CONFIG.adjacent_key_rate) {
await simulateAdjacentKeyTypo(char);
// After fixing, we still need to type the correct char, which is handled at end of loop?
// Wait, simulateAdjacentKeyTypo fixes it but doesn't type the correct one?
// Let's check original logic.
// Original: simulateAdjacentKeyTypo types wrong, deletes. Main loop falls through to type correct char.
}
// Wrong character
if (/[a-zA-Z]/.test(char) && Math.random() < CONFIG.wrong_char_rate) {
await simulateWrongChar(char);
// Same pattern: types wrong, deletes. Main loop falls through.
}
// Type the correct character
await typeChar(char);
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;
window.removeEventListener('keydown', triggerHandler);
console.log("Trigger detected. Starting Human-Like Command Typer v2...");
console.log("Config:", CONFIG);
// Start delay? Original had CONFIG.startDelay. New config doesn't have it.
// We'll default to a small delay or 0.
setTimeout(() => {
autoTypeLoop();
}, 100);
}
}
};
window.addEventListener('keydown', triggerHandler);
console.log("READY! Type the first letter to activate Human-Like Mode v2.");
})();
|