您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Detect curses on MZ forum posts. Works with Spanish words only.
// ==UserScript== // @name Curse detector // @namespace mz-curse-detector // @description Detect curses on MZ forum posts. Works with Spanish words only. // @description:es Detectar groserías en los mensajes de los foros de MZ. Solamente detecta palabras en español. // @homepage https://github.com/rhonaldomaster/mz-curse-detector // @icon https://www.managerzone.com/favicon.ico?v2 // @include https://*managerzone.*p=forum&sub=topic* // @grant GM_getValue // @grant GM_setValue // @grant GM_xmlhttpRequest // @version 0.4 // @copyright GNU/GPL v3 // @author rhonaldomaster // @license GPL-3.0-or-later // @compatible chrome // @compatible firefox // @compatible opera // @compatible safari // @compatible edge // ==/UserScript== // Default words in case the fetch fails const DEFAULT_CURSE_WORDS = [ 'boba', 'bobo', 'boluda', 'bolu.da', 'boludo', 'bolu.do', 'bosta', 'bostera', 'bostero', 'burrazo', 'burro', 'cometrava', 'cometraba', 'concha', ' culo', 'estupida', 'estúpida', 'estupido', 'estúpido', 'forra', 'forro', 'gil', 'gilipolla', 'gonorrea', 'hdp', 'hipocrita', 'hipócrita', 'hijo de puta', 'hitler', 'idiota', 'imbecil', 'imbécil', 'kkk', 'kuka', 'lacra', 'la tenés adentro', 'la tenes adentro', 'la tenes bien adentro', 'la tenés bien adentro', 'la tenéis bien adentro', ' lta', 'malcogida', 'malcogido', 'mal cogida', 'mal cogido', 'malparida', 'malparido', 'mal parida', 'mal parido', 'marica', 'marmota', 'mediocre', 'mierda', 'miserable', 'mogolico', 'mogólico', 'montonero', 'mu ', 'muerde almohada', 'muerdealmohada', 'negro cabeza', 'patetico', 'patético', 'payasa', 'payaso', 'pelotuda', 'pelotudo', 'pene', 'perra', 'puta', 'putear', 'puto', 'retrasada', 'retrasado', 'ridicula', 'ridícula', 'ridiculo', 'ridículo', 'salame', 'sorete', 'sucio', 'subnormal', 'tarada', 'tarado', 'tonta', 'tontaza', 'tontazo', 'tonto', 'trampa', 'tramposa', 'tramposo', 'vende ajo', 'vendo ajo', 'verduler' ]; // Cache configuration const CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 hours const CACHE_KEY = 'curseWordsCache'; const CACHE_TIMESTAMP = 'curseWordsTimestamp'; const CACHE_VERSION = '1.0.0'; // GitHub Pages URL where the JSON is hosted const WORDS_JSON_URL = 'https://rhonaldomaster.github.io/mz-curse-detector/curse-words.json'; // Store the current list of curse words let curseWords = [...DEFAULT_CURSE_WORDS]; function searchAndHighlightWord(word, textContainer) { const warningColor = 'var(--curseColor)'; const originalText = textContainer.innerHTML; if (originalText.indexOf(`<span style="color:${warningColor};font-weight:bold;text-decoration:underline;">`) > -1) { return; } const regex = new RegExp(`\\b${word}\\b`, 'gi'); const highlightedText = originalText.replace( regex, `<span style="color:${warningColor};font-weight:bold;text-decoration:underline;">$&</span>` ); if (highlightedText !== originalText) { textContainer.innerHTML = highlightedText; const editPostButton = textContainer.parentNode.querySelector('.fa-edit'); if (editPostButton) { editPostButton.style.color = warningColor; } } } async function loadCurseWords() { // Try to get cached data first try { const cachedData = GM_getValue(CACHE_KEY); const cachedTime = GM_getValue(CACHE_TIMESTAMP); const cachedVersion = GM_getValue('curseWordsVersion'); // If we have valid cached data and it's not expired if (cachedData && cachedTime && cachedVersion === CACHE_VERSION) { const age = Date.now() - parseInt(cachedTime, 10); if (age < CACHE_DURATION) { return JSON.parse(cachedData).words; } } // Fetch fresh data const response = await new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url: WORDS_JSON_URL, onload: resolve, onerror: reject, timeout: 5000 // 5 second timeout }); }); if (response.status >= 200 && response.status < 300) { const data = JSON.parse(response.responseText); // Cache the result GM_setValue(CACHE_KEY, JSON.stringify(data)); GM_setValue(CACHE_TIMESTAMP, Date.now().toString()); GM_setValue('curseWordsVersion', CACHE_VERSION); return data.words || DEFAULT_CURSE_WORDS; } } catch (error) { console.error('Failed to load curse words:', error); } // Fallback to default words return DEFAULT_CURSE_WORDS; } function detectCurses() { const messages = document.querySelectorAll('.forum-post-content'); messages.forEach(message => { for (let i = 0; i < curseWords.length; i++) { searchAndHighlightWord(curseWords[i], message); } }); } function addCSSVariables() { const root = document.querySelector(':root'); root.style.setProperty('--curseColor', '#ff4800'); } // Initialize the script async function init() { try { // Load curse words curseWords = await loadCurseWords(); // Set up mutation observer const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { if (mutation.type === 'childList') { mutation.addedNodes.forEach(node => { if (node.nodeType === 1 && node.classList.contains('forum-post-content')) { detectCurses(); } }); } }); }); // Find posts container and start observing const postsContainer = document.querySelector('.forum_content'); if (postsContainer) { addCSSVariables(); observer.observe(postsContainer, { childList: true, subtree: true }); // Initial check detectCurses(); // Add a small indicator addStatusIndicator(); } else { console.error('Posts container not found.'); } } catch (error) { console.error('Error initializing script:', error); } } // Add a small status indicator function addStatusIndicator() { const indicator = document.createElement('div'); indicator.style.position = 'fixed'; indicator.style.bottom = '10px'; indicator.style.right = '10px'; indicator.style.padding = '5px 10px'; indicator.style.background = '#333'; indicator.style.color = '#fff'; indicator.style.borderRadius = '4px'; indicator.style.fontSize = '12px'; indicator.style.zIndex = '9999'; indicator.textContent = `MZ Curse Detector v${GM_info.script.version} (${curseWords.length} palabras)`; document.body.appendChild(indicator); } // Start the script init();