Typhacker with Auto Typing and Toggle (Fixed UI)

Automates typing on Typewriter with working UI controls

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Typhacker with Auto Typing and Toggle (Fixed UI)
// @namespace    http://tampermonkey.net/
// @version      2.4
// @license      MIT
// @description  Automates typing on Typewriter with working UI controls
// @author       random russian guy
// @match        https://sg.typewriter.ch/index.php?r=typewriter/runLevel
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    let typingEnabled = false;
    let typingTimer = null;
    let controlPanelVisible = true;
    let speed = 100;
    let elementsHidden = false;

    // Elements to hide
    const elementsToToggle = [
        "#hud_info",
        "#hud_top1",
        "#hud_top2",
        ".keyboard",
        'img[height="325"][width="980"][src="/assets/65968696/images/tastatur_background.svg"]'
    ];

    // Function to hide elements
    function hideElements() {
        elementsToToggle.forEach((selector) => {
            const element = document.querySelector(selector);
            if (element) element.style.display = "none";
        });
    }

    // Function to show elements
    function showElements() {
        elementsToToggle.forEach((selector) => {
            const element = document.querySelector(selector);
            if (element) element.style.display = "";
        });
    }

    // Function to toggle element visibility
    function toggleElementsVisibility() {
        elementsHidden = !elementsHidden;
        if (elementsHidden) {
            hideElements();
        } else {
            showElements();
        }
    }

    // Function to simulate typing
    function detectAndType() {
        const spans = document.querySelectorAll('span');

        spans.forEach((span) => {
            const text = span.textContent.trim();
            if (text.length === 1 && isElementInMiddle(span)) {
                typeCharacter(text);
            }
        });
    }

    function isElementInMiddle(element) {
        const rect = element.getBoundingClientRect();
        const middleX = window.innerWidth / 2;
        const middleY = window.innerHeight / 2;

        const middleRegion = {
            left: middleX - window.innerWidth / 4,
            top: middleY - window.innerHeight / 4,
            right: middleX + window.innerWidth / 4,
            bottom: middleY + window.innerHeight / 4
        };

        return (
            rect.left >= middleRegion.left &&
            rect.right <= middleRegion.right &&
            rect.top >= middleRegion.top &&
            rect.bottom <= middleRegion.bottom
        );
    }

    function typeCharacter(char) {
        const typingArea = document.activeElement;
        if (typingArea && (typingArea.tagName === "INPUT" || typingArea.tagName === "TEXTAREA")) {
            const eventOptions = {
                key: char,
                code: `Key${char.toUpperCase()}`,
                char: char,
                keyCode: char.charCodeAt(0),
                which: char.charCodeAt(0),
                bubbles: true,
                cancelable: true
            };

            typingArea.dispatchEvent(new KeyboardEvent("keydown", eventOptions));
            typingArea.dispatchEvent(new KeyboardEvent("keypress", eventOptions));
            typingArea.dispatchEvent(new KeyboardEvent("keyup", eventOptions));
        }
    }

    function startTypingAutomation() {
        if (!typingEnabled) {
            typingEnabled = true;
            typingTimer = setInterval(detectAndType, speed);
        }
    }

    function stopTypingAutomation() {
        typingEnabled = false;
        if (typingTimer) {
            clearInterval(typingTimer);
            typingTimer = null;
        }
    }

    // Function to update typing speed
    function updateTypingSpeed() {
        if (typingEnabled) {
            stopTypingAutomation();
            startTypingAutomation();
        }
    }

    // Create UI
    const controlPanel = document.createElement("div");
    controlPanel.style.position = "fixed";
    controlPanel.style.bottom = "0px";
    controlPanel.style.left = "20px";
    controlPanel.style.padding = "10px";
    controlPanel.style.backgroundColor = "#fff";
    controlPanel.style.border = "2px solid #000";
    controlPanel.style.borderRadius = "8px";
    controlPanel.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.2)";
    controlPanel.style.zIndex = "10000";
    controlPanel.style.transition = "transform 0.5s ease-in-out";
    controlPanel.style.transform = "translateY(0)";

    // Speed slider with input
    const speedLabel = document.createElement("label");
    speedLabel.textContent = "Speed (ms): ";

    const speedSlider = document.createElement("input");
    speedSlider.type = "range";
    speedSlider.min = "50";
    speedSlider.max = "1000";
    speedSlider.value = speed;
    speedSlider.style.width = "100px";
    speedSlider.addEventListener("input", (e) => {
        speed = parseInt(e.target.value);
        speedInput.value = speed;
        updateTypingSpeed();
    });

    const speedInput = document.createElement("input");
    speedInput.type = "number";
    speedInput.value = speed;
    speedInput.style.width = "50px";
    speedInput.addEventListener("change", (e) => {
        speed = parseInt(e.target.value);
        speedSlider.value = speed;
        updateTypingSpeed();
    });

    speedLabel.appendChild(speedSlider);
    speedLabel.appendChild(speedInput);
    controlPanel.appendChild(speedLabel);
    controlPanel.appendChild(document.createElement("br"));

    // Start and stop buttons
    const startButton = document.createElement("button");
    startButton.textContent = "Start Typing";
    startButton.addEventListener("click", startTypingAutomation);
    controlPanel.appendChild(startButton);

    const stopButton = document.createElement("button");
    stopButton.textContent = "Stop Typing";
    stopButton.addEventListener("click", stopTypingAutomation);
    controlPanel.appendChild(stopButton);

    const toggleButton = document.createElement("button");
    toggleButton.textContent = "Toggle Elements";
    toggleButton.addEventListener("click", toggleElementsVisibility);
    controlPanel.appendChild(toggleButton);

    const hideButton = document.createElement("button");
    hideButton.textContent = "Hide Controls";
    hideButton.addEventListener("click", () => {
        controlPanel.style.transform = "translateY(100%)";
        showButton.style.display = "block";
    });
    controlPanel.appendChild(document.createElement("br"));
    controlPanel.appendChild(hideButton);

    // Show controls button
    const showButton = document.createElement("button");
    showButton.textContent = "Show Controls";
    showButton.style.position = "fixed";
    showButton.style.bottom = "20px";
    showButton.style.left = "20px";
    showButton.style.display = "none";
    showButton.addEventListener("click", () => {
        controlPanel.style.transform = "translateY(0)";
        showButton.style.display = "none";
    });

    document.body.appendChild(controlPanel);
    document.body.appendChild(showButton);
})();