MonkeyType AutoTyper Bot

A Bot that automatically types for you in MokeyType.

安裝腳本?
作者推薦腳本

您可能也會喜歡 Vocabulary.com Answer Bot

安裝腳本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name MonkeyType AutoTyper Bot
// @author longkidkoolstar
// @description A Bot that automatically types for you in MokeyType.
// @icon https://th.bing.com/th/id/R.c8397fb766c4397fea8a8b499c15a453?rik=aROX42RoH7HhXw&pid=ImgRaw&r=0
// @version 2.1
// @match *://monkeytype.com/*
// @run-at document-start
// @grant none
// @license MIT
// @namespace https://greasyfork.org/users/1000020
// ==/UserScript==
/* jshint esversion:6 */

(function () {
    "use strict";
  
    // Minimum and maximum delay (ms)
    let MIN_DELAY = 100;
    let MAX_DELAY = 333;
    const TOGGLE_KEY = "ArrowRight";
    const log = console.log;
  
    function random(min, max) {
      return Math.floor(Math.random() * (max - min + 1) + min);
    }
  
    let toggle = false;
    function canType() {
      const typingTest = document.getElementById("typingTest");
      const isHidden = typingTest.classList.contains("hidden");
      if (isHidden) toggle = false;
      return toggle && !isHidden;
    }
  
    function getNextCharacter() {
      const currentWord = document.querySelector(".word.active");
      for (const letter of currentWord.children) {
        if (letter.className === "") return letter.textContent;
      }
      return " ";
    }
  
    const InputEvents = {};
    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() {
        if (!canType()) {
          log("STOPPED TYPING TEST");
          return;
        }
      
        const nextChar = getNextCharacter();
        let delay;
      
        // Check which section is currently displayed
        const basicSection = document.getElementById("basicSection");
        if (basicSection.style.display === "") { // Basic section is displayed
          delay = 60000 / (document.getElementById("wpmSlider").value * 5);
        } else { // Advanced section is displayed
          delay = random(MIN_DELAY, MAX_DELAY);
        }
      
        const accuracy = document.getElementById("accuracySlider").value;
      
        // introduce some random errors
        if (Math.random() > accuracy) {
          // skip this character
          setTimeout(typeCharacter, delay);
          return;
        } else if (Math.random() > accuracy) {
          // repeat this character
          pressKey(nextChar);
        } else if (Math.random() > accuracy) {
          // insert a random incorrect character
          const adjacentKey = getAdjacentKey(nextChar);
          pressKey(adjacentKey);
        }
      
        // press the next character
        pressKey(nextChar);
      
        // introduce a pause between words
        if (nextChar === " ") {
          const pauseDelay = document.getElementById("pauseDelaySlider").value;
          setTimeout(typeCharacter, pauseDelay);
        } else {
          setTimeout(typeCharacter, delay);
        }
      }
      
      function getAdjacentKey(key) {
        // Define the adjacent keys for each key
        const adjacentKeys = {
          "q": ["w", "a"],
          "w": ["q", "e", "a", "s"],
          "e": ["w", "r", "s", "d"],
          "r": ["e", "t", "d", "f"],
          "t": ["r", "y", "f", "g"],
          "y": ["t", "u", "g", "h"],
          "u": ["y", "i", "h", "j"],
          "i": ["u", "o", "j", "k"],
          "o": ["i", "p", "k", "l"],
          "p": ["o", "l"],
          "a": ["q", "w", "s", "z"],
          "s": ["w", "e", "a", "d", "z", "x"],
          "d": ["e", "r", "s", "f", "x", "c"],
          "f": ["r", "t", "d", "g", "c", "v"],
          "g": ["t", "y", "f", "h", "v", "b"],
          "h": ["y", "u", "g", "j", "b", "n"],
          "j": ["u", "i", "h", "k", "n", "m"],
          "k": ["i", "o", "j", "l", "m"],
          "l": ["o", "p", "k"],
          "z": ["a", "s", "x"],
          "x": ["s", "d", "z", "c"],
          "c": ["d", "f", "x", "v"],
          "v": ["f", "g", "c", "b"],
          "b": ["g", "h", "v", "n"],
          "n": ["h", "j", "b", "m"],
          "m": ["j", "k", "n"]
        };
      
        // Handle space character separately
        if (key === " ") {
          return " ";
        }
      
        // Get the adjacent keys for the given key
        const keys = adjacentKeys[key.toLowerCase()];
      
        // Randomly select an adjacent key
        const randomIndex = Math.floor(Math.random() * keys.length);
        return keys[randomIndex];
      }
      
    window.addEventListener("keydown", function (event) {
      if (event.code === TOGGLE_KEY) {
        event.preventDefault();
  
        if (event.repeat) return;
        toggle = !toggle;
        if (toggle) {
          log("STARTED TYPING TEST");
          typeCharacter();
        }
      }
    });
  
    // Intercept when JQuery attached an addEventListener to the Input element
    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: 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,
    };
  
   // Add GUI to change min and max delay
  const gui = document.createElement("div");
  gui.style.position = "fixed";
  gui.style.bottom = "30%";
  gui.style.right = "0";
  gui.style.transform = "translateY(50%)";
  gui.style.padding = "5px";
  gui.style.background = "rgba(0, 0, 0, 0.6)";
  gui.style.color = "white";
  gui.style.fontFamily = "sans-serif";
  gui.style.fontSize = "12px";
  gui.style.zIndex = "9999"; // set z-index to a high value
  gui.innerHTML = `
    <div style="display: flex; flex-direction: column;">
      <div style="margin-bottom: 10px;">
        <button id="resetButton">Reset to Default</button>
      </div>
    <div style="display: flex; flex-direction: column;">
      <div style="margin-bottom: 10px;">
        <button id="basicButton">Basic</button>
        <button id="advancedButton">Advanced</button>
      </div>
      <div id="basicSection">
        <div style="margin-bottom: 5px;">
          WPM: <input type="range" id="wpmSlider" value="50" min="10" max="100" step="5" style="width: 100px;">
          <span id="wpmValue">50</span>
        </div>
      </div>
      <div id="advancedSection" style="display: none;">
        <div style="margin-bottom: 5px;">
          Min Delay: <input type="range" id="minDelaySlider" value="${MIN_DELAY}" min="0" max="1000" step="10" style="width: 100px;">
          <span id="minDelayValue">${MIN_DELAY}ms</span>
        </div>
        <div style="margin-bottom: 5px;">
          Max Delay: <input type="range" id="maxDelaySlider" value="${MAX_DELAY}" min="0" max="1000" step="10" style="width: 100px;">
          <span id="maxDelayValue">${MAX_DELAY}ms</span>
        </div>
        <div>
          Pause Delay: <input type="range" id="pauseDelaySlider" value="${MAX_DELAY}" min="0" max="1000" step="10" style="width: 100px;">
          <span id="pauseDelayValue">${MAX_DELAY}ms</span>
        </div>
      </div>
    </div>
    <div style="margin-bottom: 5px;">
    Accuracy: <input type="range" id="accuracySlider" value="0.1" min="0" max="1" step="0.01" style="width: 100px;">
    <span id="accuracyValue">0.1</span>
  </div>
  `;
  document.body.appendChild(gui);
  
  // Add event listeners to toggle the visibility of each section
  const basicButton = document.getElementById("basicButton");
  const basicSection = document.getElementById("basicSection");
  basicButton.addEventListener("click", function() {
    basicSection.style.display = "";
    advancedSection.style.display = "none";
  });
  
  const advancedButton = document.getElementById("advancedButton");
  const advancedSection = document.getElementById("advancedSection");
  advancedButton.addEventListener("click", function() {
    basicSection.style.display = "none";
    advancedSection.style.display = "";
  });
  
  // Add event listeners to the sliders
  const wpmSlider = document.getElementById("wpmSlider");
  const wpmValue = document.getElementById("wpmValue");
  wpmSlider.addEventListener("input", function() {
    wpmValue.textContent = wpmSlider.value;
  });
  
  const minDelaySlider = document.getElementById("minDelaySlider");
  const minDelayValue = document.getElementById("minDelayValue");
  minDelaySlider.addEventListener("input", function() {
    MIN_DELAY = parseInt(minDelaySlider.value);
    minDelayValue.textContent = `${MIN_DELAY}ms`;
  });
  
  const maxDelaySlider = document.getElementById("maxDelaySlider");
  const maxDelayValue = document.getElementById("maxDelayValue");
  maxDelaySlider.addEventListener("input", function() {
    MAX_DELAY = parseInt(maxDelaySlider.value);
    maxDelayValue.textContent = `${MAX_DELAY}ms`;
  });
  
  const pauseDelaySlider = document.getElementById("pauseDelaySlider");
  const pauseDelayValue = document.getElementById("pauseDelayValue");
  pauseDelaySlider.addEventListener("input", function() {
    pauseDelayValue.textContent = `${pauseDelaySlider.value}ms`;
  });
  
      const accuracySlider = document.getElementById("accuracySlider");
  const accuracyValue = document.getElementById("accuracyValue");
  accuracySlider.addEventListener("input", function() {
    accuracyValue.textContent = accuracySlider.value;
  });
      const resetButton = document.getElementById("resetButton");
  
  resetButton.addEventListener("click", function() {
    wpmSlider.value = 40;
    minDelaySlider.value = 100;
    maxDelaySlider.value = 333;
    pauseDelaySlider.value = 100;
    accuracySlider.value = 95;
  
    wpmValue.textContent = wpmSlider.value;
    minDelayValue.textContent = `${minDelaySlider.value}ms`;
    maxDelayValue.textContent = `${maxDelaySlider.value}ms`;
    pauseDelayValue.textContent = `${pauseDelaySlider.value}ms`;
    accuracyValue.textContent = accuracySlider.value;
  
    // Save default values to localStorage
    localStorage.setItem('wpmSliderValue', wpmSlider.value);
    localStorage.setItem('minDelaySliderValue', minDelaySlider.value);
    localStorage.setItem('maxDelaySliderValue', maxDelaySlider.value);
    localStorage.setItem('pauseDelaySliderValue', pauseDelaySlider.value);
    localStorage.setItem('accuracySliderValue', accuracySlider.value);
  });
  
      function saveSliderValues() {
    localStorage.setItem('wpmSliderValue', wpmSlider.value);
    localStorage.setItem('minDelaySliderValue', minDelaySlider.value);
    localStorage.setItem('maxDelaySliderValue', maxDelaySlider.value);
    localStorage.setItem('pauseDelaySliderValue', pauseDelaySlider.value);
    localStorage.setItem('accuracySliderValue', accuracySlider.value);
  }
      wpmSlider.addEventListener('input', function() {
    wpmValue.textContent = wpmSlider.value;
    saveSliderValues();
  });
  
  minDelaySlider.addEventListener('input', function() {
    MIN_DELAY = parseInt(minDelaySlider.value);
    minDelayValue.textContent = `${MIN_DELAY}ms`;
    saveSliderValues();
  });
  
  maxDelaySlider.addEventListener('input', function() {
    MAX_DELAY = parseInt(maxDelaySlider.value);
    maxDelayValue.textContent = `${MAX_DELAY}ms`;
    saveSliderValues();
  });
  
  pauseDelaySlider.addEventListener('input', function() {
    pauseDelayValue.textContent = `${pauseDelaySlider.value}ms`;
    saveSliderValues();
  });
  
  accuracySlider.addEventListener('input', function() {
    accuracyValue.textContent = accuracySlider.value;
    saveSliderValues();
  });
      // Retrieve slider values from localStorage
  if (localStorage.getItem('wpmSliderValue')) {
    wpmSlider.value = localStorage.getItem('wpmSliderValue');
    wpmValue.textContent = wpmSlider.value;
  }
  
  if (localStorage.getItem('minDelaySliderValue')) {
    minDelaySlider.value = localStorage.getItem('minDelaySliderValue');
    MIN_DELAY = parseInt(minDelaySlider.value);
    minDelayValue.textContent = `${MIN_DELAY}ms`;
  }
  
  if (localStorage.getItem('maxDelaySliderValue')) {
    maxDelaySlider.value = localStorage.getItem('maxDelaySliderValue');
    MAX_DELAY = parseInt(maxDelaySlider.value);
    maxDelayValue.textContent = `${MAX_DELAY}ms`;
  }
  
  if (localStorage.getItem('pauseDelaySliderValue')) {
    pauseDelaySlider.value = localStorage.getItem('pauseDelaySliderValue');
    pauseDelayValue.textContent = `${pauseDelaySlider.value}ms`;
  }
  
  if (localStorage.getItem('accuracySliderValue')) {
    accuracySlider.value = localStorage.getItem('accuracySliderValue');
    accuracyValue.textContent = accuracySlider.value;
  }
  
  })();