// ==UserScript== // @name WordSleuth // @namespace https://greasyfork.org/en/users/1084087-kueldev // @version 0.2.1 // @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 none // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; let wordSet = new Set(); const guessElem = createGuessElement(); let possibleWords = []; fetchWords().then(words => { words.forEach(word => wordSet.add(word)); observeHints(); observeInput(); }); function fetchWords() { const url = 'https://raw.githubusercontent.com/arstgit/high-frequency-vocabulary/master/30k.txt'; return fetch(url).then(response => response.text()).then(data => data.split('\n').map(word => word.trim())); } function observeHints() { const targetNode = document.querySelector('.hints .container'); 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') { generateGuesses(); } } }; const observer = new MutationObserver(callback); observer.observe(targetNode, config); } function observeInput() { const inputElem = document.querySelector('#game-chat input[data-translate="placeholder"]'); inputElem.addEventListener('input', generateGuesses); inputElem.addEventListener('keydown', handleKeyDown); // Trigger generateGuesses when the user sends a message 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 wordLengthElem = document.querySelector('.hints .word-length'); const wordLength = wordLengthElem ? parseInt(wordLengthElem.textContent) : 0; const hintElems = Array.from(document.querySelectorAll('.hints .hint')); let hints = hintElems.map(elem => elem.textContent === '_' ? '.' : elem.textContent).join(''); const inputElem = document.querySelector('#game-chat input[data-translate="placeholder"]'); const inputText = inputElem.value; if (inputText) { // Replace the part of the hints with the input text, then fill the remainder with '.'. let hintArray = hints.split(''); hintArray.splice(0, inputText.length, ...inputText.split('')); hints = hintArray.join(''); } const regex = new RegExp('^' + hints + '$'); possibleWords = Array.from(wordSet.values()).filter(word => word.length === wordLength && regex.test(word)); 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;'; let colorValue = possibleWords.length > 1 ? Math.floor(255 * index / (possibleWords.length - 1)) : 0; wordElem.style.backgroundColor = `rgb(${colorValue}, ${255 - colorValue}, 0)`; addHoverEffect(wordElem, colorValue); addClickFunctionality(wordElem, word, inputElem); 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) { 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 })); }); } 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;'; document.body.appendChild(guessElem); return guessElem; } })(); // ==UserScript== // @name WordSleuth // @namespace https://greasyfork.org/en/users/1084087-kueldev // @version 0.1 // @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 none // @license MIT // ==/UserScript== (function() { 'use strict'; let wordSet = new Set(); const guessElem = createGuessElement(); let possibleWords = []; fetchWords().then(words => { words.forEach(word => wordSet.add(word)); observeHints(); observeInput(); }); function fetchWords() { const url = 'https://raw.githubusercontent.com/arstgit/high-frequency-vocabulary/master/30k.txt'; return fetch(url).then(response => response.text()).then(data => data.split('\n').map(word => word.trim())); } function observeHints() { const targetNode = document.querySelector('.hints .container'); 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') { generateGuesses(); } } }; const observer = new MutationObserver(callback); observer.observe(targetNode, config); } function observeInput() { const inputElem = document.querySelector('#game-chat input[data-translate="placeholder"]'); inputElem.addEventListener('input', generateGuesses); inputElem.addEventListener('keydown', handleKeyDown); // Trigger generateGuesses when the user sends a message 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 wordLengthElem = document.querySelector('.hints .word-length'); const wordLength = wordLengthElem ? parseInt(wordLengthElem.textContent) : 0; const hintElems = Array.from(document.querySelectorAll('.hints .hint')); let hints = hintElems.map(elem => elem.textContent === '_' ? '.' : elem.textContent).join(''); const inputElem = document.querySelector('#game-chat input[data-translate="placeholder"]'); const inputText = inputElem.value; if (inputText) { // Replace the part of the hints with the input text, then fill the remainder with '.'. let hintArray = hints.split(''); hintArray.splice(0, inputText.length, ...inputText.split('')); hints = hintArray.join(''); } const regex = new RegExp('^' + hints + '$'); possibleWords = Array.from(wordSet.values()).filter(word => word.length === wordLength && regex.test(word)); 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); 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) { 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 })); }); } 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;'; document.body.appendChild(guessElem); return guessElem; } })();