WordSleuth

A script that helps you guess words in skribblio

目前为 2023-05-29 提交的版本。查看 最新版本

// ==UserScript==
// @name         WordSleuth
// @namespace    https://gf.qytechs.cn/en/users/1084087-kueldev
// @version      0.3.7
// @description  A script that helps you guess words in skribblio
// @author       kueldev
// @match        http*://www.skribbl.io/*
// @match        http*://skribbl.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=skribbl.io
// @grant        GM_setValue
// @grant        GM_getValue
// @license MIT
// ==/UserScript==
(function() {
    'use strict';

    let correctAnswers = GM_getValue('correctAnswers', []);
    const guessElem = createGuessElement();
    let possibleWords = [];

    let exportButton = document.createElement('button');
    exportButton.innerHTML = 'Export Answers';
    exportButton.style = 'position: fixed; bottom: 65px; right: 10px; z-index: 9999; padding: 5px 10px; font-size: 12px; background-color: #333; color: #fff; border: none; border-radius: 5px;';
    document.body.appendChild(exportButton);

    exportButton.addEventListener('click', function() {
        let blob = new Blob([correctAnswers.join('\n')], {
            type: 'text/plain;charset=utf-8'
        });
        let a = document.createElement('a');
        a.href = URL.createObjectURL(blob);
        a.download = 'correctAnswers.txt';
        a.style.display = 'none';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
    });

    // Fetch the latest wordlist
    fetchWords('https://raw.githubusercontent.com/kuel27/wordlist/main/wordlist.txt').then(words => {
        words.forEach(word => {
            if (!correctAnswers.includes(word)) {
                correctAnswers.push(word);
            }
        });

        observeHints();
        observeInput();
    });

    function fetchWords(url) {
        return fetch(url)
            .then(response => response.text())
            .then(data => data.split('\n').map(word => word.trim()));
    }

    function observeHints() {
        const targetNodes = [
            document.querySelector('.hints .container'),
            document.querySelector('.words'),
            document.querySelector('#game-word'),
        ];
        const config = {
            childList: true,
            subtree: true
        };

        const callback = function(mutationsList, observer) {
            const inputElem = document.querySelector('#game-chat input[data-translate="placeholder"]');
            if (inputElem.value) return;

            for (let mutation of mutationsList) {
                if (mutation.type === 'childList') {
                    checkIfAllHintsRevealed();
                    checkWordsElement();
                    generateGuesses();
                }
            }
        };

        const observer = new MutationObserver(callback);
        targetNodes.forEach(targetNode => {
            if (targetNode) {
                observer.observe(targetNode, config);
            }
        });
    }

    function checkIfAllHintsRevealed() {
        const hintElems = Array.from(document.querySelectorAll('.hints .hint'));

        if (hintElems.every(elem => elem.classList.contains('uncover'))) {
            const correctAnswer = hintElems.map(elem => elem.textContent).join('').trim().toLowerCase();

            if (!correctAnswer) {
                return;
            }

            if (!correctAnswers.includes(correctAnswer)) {
                correctAnswers.push(correctAnswer);
                GM_setValue('correctAnswers', correctAnswers);
                console.log("added ${correctAnswer} to the wordlist");
            }
        }
    }

    function checkWordsElement() {
        const wordElems = Array.from(document.querySelectorAll('.words.show .word'));

        wordElems.forEach(elem => {
            const word = elem.textContent.trim().toLowerCase();

            if (!word) {
                return;
            }

            if (word.trim() !== "" && !correctAnswers.includes(word)) {
                correctAnswers.push(word);
                GM_setValue('correctAnswers', correctAnswers);
                console.log("added ${word} to the wordlist");
            }
        });
    }

    function observeInput() {
        const inputElem = document.querySelector('#game-chat input[data-translate="placeholder"]');
        inputElem.addEventListener('input', generateGuesses);
        inputElem.addEventListener('keydown', handleKeyDown);

        const formElem = document.querySelector('#game-chat form');
        formElem.addEventListener('submit', generateGuesses);
    }

    function handleKeyDown(event) {
        if (event.key === 'Tab' && possibleWords.length > 0) {
            event.preventDefault();
            const inputElem = document.querySelector('#game-chat input[data-translate="placeholder"]');
            inputElem.value = possibleWords[0];
            inputElem.focus();
            generateGuesses();
        }
    }

    function generateGuesses() {
        const hintElems = Array.from(document.querySelectorAll('.hints .hint'));
        const inputElem = document.querySelector('#game-chat input[data-translate="placeholder"]');
        const hintParts = hintElems.map(elem => elem.textContent === '_' ? '.' : elem.textContent).join('').split(' ');
        const inputText = inputElem.value ? String(inputElem.value) : '';

        possibleWords = correctAnswers.filter(word => {
            let wordParts = word.split(' ');

            if (wordParts.length !== hintParts.length) {
                return false;
            }

            for (let i = 0, len = wordParts.length; i < len; i++) {
                if (wordParts[i].length !== hintParts[i].length) {
                    return false;
                }
            }

            if (hintParts.join(' ').trim().length <= 0 && inputText.trim().length <= 0) {
                return true;
            }

            let hintRegex = new RegExp(`^${hintParts.join(' ')}$`, 'i');
            if (!hintRegex.test(word)) {
                return false;
            }

            let inputTextRegex = new RegExp(`^${inputText}`, 'i');
            if (!inputTextRegex.test(word)) {
                return false;
            }

            return true;
        });

        guessElem.innerHTML = '';
        renderGuesses(possibleWords, inputElem);
    }

    function renderGuesses(possibleWords, inputElem) {
        possibleWords.slice(0, 100).forEach((word, index) => {
            const wordElem = document.createElement('div');
            wordElem.textContent = word;
            wordElem.style = 'font-weight: bold; display: inline-block; padding: 5px; margin-right: 2px; color: white;';
            const maxValue = possibleWords.length > 100 ? 100 : possibleWords.length;
            let colorValue = possibleWords.length > 1 ? Math.floor(255 * index / (maxValue - 1)) : 0;
            wordElem.style.backgroundColor = `rgb(${colorValue}, ${255 - colorValue}, 0)`;

            addHoverEffect(wordElem, colorValue);
            addClickFunctionality(wordElem, word, inputElem, colorValue);

            guessElem.appendChild(wordElem);
        });
    }

    function addHoverEffect(wordElem, colorValue) {
        wordElem.addEventListener('mouseenter', function() {
            if (!wordElem.classList.contains('pressed')) {
                wordElem.style.backgroundColor = 'lightgray';
            }
            wordElem.classList.add('hovered');
        });

        wordElem.addEventListener('mouseleave', function() {
            if (!wordElem.classList.contains('pressed')) {
                wordElem.style.backgroundColor = `rgb(${colorValue}, ${255 - colorValue}, 0)`;
            }
            wordElem.classList.remove('hovered');
        });
    }

    function addClickFunctionality(wordElem, word, inputElem, colorValue) {
        wordElem.addEventListener('mousedown', function() {
            wordElem.classList.add('pressed');
            wordElem.style.backgroundColor = 'gray';
        });

        wordElem.addEventListener('mouseup', function() {
            wordElem.classList.remove('pressed');
            if (!wordElem.classList.contains('hovered')) {
                wordElem.style.backgroundColor = `rgb(${colorValue}, ${255 - colorValue}, 0)`;
            } else {
                wordElem.style.backgroundColor = 'lightgray';
            }
        });

        wordElem.addEventListener('click', function() {
            const formElem = document.querySelector('#game-chat form');
            inputElem.value = word;
            formElem.dispatchEvent(new Event('submit', {
                bubbles: true,
                cancelable: true
            }));
        });
    }

    function createGuessElement() {
        let guessElem = document.createElement('div');
        guessElem.style = 'position: fixed; bottom: 0; left: 0; right: 0; padding: 10px; background-color: white; max-height: 200px; overflow-x: auto; white-space: nowrap; max-width: 100vw; height: 55px';
        document.body.appendChild(guessElem);
        return guessElem;
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址