您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Instantly replace Discord messages on refresh without flicker, plus Roblox embed & reset menu
// ==UserScript== // @name Discord Message Text Replacer + Reset + Roblox Embed Tool (No Flicker) // @namespace http://tampermonkey.net/ // @version 1.8 // @description Instantly replace Discord messages on refresh without flicker, plus Roblox embed & reset menu // @author ChatGPT // @match *://*.discord.com/* // @grant GM_registerMenuCommand // @grant GM_getValue // @grant GM_setValue // @run-at document-start // ==/UserScript== (function () { 'use strict'; const STORAGE_KEY = 'discordTextReplacements'; function getReplacements() { return GM_getValue(STORAGE_KEY, {}) || {}; } function saveReplacements(replacements) { GM_setValue(STORAGE_KEY, replacements); } function getMessageKey(elem) { const content = (elem.textContent || '').trim().slice(0, 100); const authorElem = elem.closest('[class*="message-"]')?.querySelector('h3'); const author = authorElem ? authorElem.textContent.trim() : 'unknown'; return `${author}::${content}`; } function clearAllOutlines() { document.querySelectorAll('[style*="outline"]').forEach(el => { try { el.style.outline = ''; } catch (e) {} }); } // Replace as soon as element is inserted const observer = new MutationObserver(mutations => { const replacements = getReplacements(); for (const m of mutations) { if (!m.addedNodes) continue; m.addedNodes.forEach(node => { if (!(node instanceof Element)) return; const targets = node.matches('[class*="messageContent"]') ? [node] : Array.from(node.querySelectorAll('[class*="messageContent"]')); targets.forEach(elem => { if (elem.dataset.replaced === '1') return; const key = getMessageKey(elem); if (replacements[key]) { elem.innerHTML = replacements[key]; elem.dataset.replaced = '1'; } }); }); } }); // Start observing immediately, even before load const startObserver = () => { try { observer.observe(document.documentElement || document.body, { childList: true, subtree: true }); } catch { setTimeout(startObserver, 10); } }; startObserver(); function applySingleReplacement(elem, html) { if (!(elem instanceof Element)) return; elem.innerHTML = html; elem.dataset.replaced = '1'; } function pickAndReplaceText() { alert('Click on the message TEXT to replace it.'); function onMouseOver(e) { try { e.target.style.outline = '2px solid red'; } catch {} } function onMouseOut(e) { try { e.target.style.outline = ''; } catch {} } function onClick(e) { e.preventDefault(); e.stopPropagation(); cleanup(); const contentElem = e.target.closest('[class*="messageContent"]'); if (!contentElem) return alert('❌ Could not find message content.'); const key = getMessageKey(contentElem); const newHTML = prompt("Enter new message content (HTML allowed):"); if (newHTML === null) return; const replacements = getReplacements(); replacements[key] = newHTML; saveReplacements(replacements); applySingleReplacement(contentElem, newHTML); clearAllOutlines(); alert('✅ Message replaced and saved.'); } function cleanup() { document.removeEventListener('mouseover', onMouseOver, true); document.removeEventListener('mouseout', onMouseOut, true); document.removeEventListener('click', onClick, true); clearAllOutlines(); } document.addEventListener('mouseover', onMouseOver, true); document.addEventListener('mouseout', onMouseOut, true); document.addEventListener('click', onClick, true); } function addRobloxEmbedBelow() { alert('Click on the message TEXT you want to add the Roblox embed below.'); function onMouseOver(e) { try { e.target.style.outline = '2px solid blue'; } catch {} } function onMouseOut(e) { try { e.target.style.outline = ''; } catch {} } function onClick(e) { e.preventDefault(); e.stopPropagation(); cleanup(); const contentElem = e.target.closest('[class*="messageContent"]'); if (!contentElem) return alert('❌ Could not find message content.'); const key = getMessageKey(contentElem); const robloxEmbed = `<div id="message-accessories-1403787320477487104" class="container_b7e1cb" bis_skin_checked="1"><article class="embedFull__623de embed__623de markup__75297" aria-hidden="false"><div class="gridContainer__623de" bis_skin_checked="1"><div class="grid__623de hasThumbnail__623de" bis_skin_checked="1"><div class="embedSuppressButton__623de" aria-label="Remove all embeds" role="button" tabindex="0" bis_skin_checked="1"><svg aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M17.3 18.7a1 1 0 0 0 1.4-1.4L13.42 12l5.3-5.3a1 1 0 0 0-1.42-1.4L12 10.58l-5.3-5.3a1 1 0 0 0-1.4 1.42L10.58 12l-5.3 5.3a1 1 0 1 0 1.42 1.4L12 13.42l5.3 5.3Z" class=""></path></svg></div><div class="embedProvider__623de embedMargin__623de" bis_skin_checked="1"><span>Roblox</span></div><div class="embedTitle__623de embedMargin__623de" bis_skin_checked="1"><a class="anchor_edefb8 anchorUnderlineOnHover_edefb8 embedTitleLink__623de embedLink__623de embedTitle__623de" tabindex="0" href="https://www.roblox.com/users/1770677206/profile" rel="noreferrer noopener" target="_blank" role="button">aFz_iReyxiee's Profile</a></div><div class="embedDescription__623de embedMargin__623de" bis_skin_checked="1">aFz_iReyxiee is one of the millions creating and exploring the endless possibilities of Roblox. Join aFz_iReyxiee on Roblox and explore together!prof</div><div class="imageContent__0f481 embedThumbnail__623de" bis_skin_checked="1"><div class="imageContainer__0f481" bis_skin_checked="1"><div class="imageWrapper imageWrapper_af017a imageZoom_af017a clickable_af017a" style="width: 80px; height: 80px;" bis_skin_checked="1"><a tabindex="-1" aria-hidden="true" class="originalLink_af017a" href="https://tr.rbxcdn.com/30DAY-Avatar-6FB199DDEBB0D4A13318D53177663D44-Png/352/352/Avatar/Png/noFilter" data-role="img" data-safe-src="https://images-ext-1.discordapp.net/external/-h7OOazWS7vinJ_WzOGAa1BRqwuy3vNmPP_RdlErfiU/https/tr.rbxcdn.com/30DAY-Avatar-6FB199DDEBB0D4A13318D53177663D44-Png/352/352/Avatar/Png/noFilter?format=webp&width=88&height=88"></a><div class="clickableWrapper_af017a" tabindex="0" aria-label="Image" aria-describedby="uid_4" role="button" bis_skin_checked="1"><div class="loadingOverlay_af017a" style="aspect-ratio: 1 / 1;" bis_skin_checked="1"><img alt="Image" src="https://images-ext-1.discordapp.net/external/-h7OOazWS7vinJ_WzOGAa1BRqwuy3vNmPP_RdlErfiU/https/tr.rbxcdn.com/30DAY-Avatar-6FB199DDEBB0D4A13318D53177663D44-Png/352/352/Avatar/Png/noFilter?format=webp&width=88&height=88" style="width: 80px; height: 80px;"></div></div></div></div></div></div></div></article></div>`; const currentHTML = contentElem.innerHTML || ''; const finalHTML = currentHTML + robloxEmbed; const replacements = getReplacements(); replacements[key] = finalHTML; saveReplacements(replacements); applySingleReplacement(contentElem, finalHTML); if (window.getSelection) { const sel = window.getSelection(); if (sel && sel.removeAllRanges) sel.removeAllRanges(); } clearAllOutlines(); alert('✅ Roblox embed added below message and saved.'); } function cleanup() { document.removeEventListener('mouseover', onMouseOver, true); document.removeEventListener('mouseout', onMouseOut, true); document.removeEventListener('click', onClick, true); clearAllOutlines(); } document.addEventListener('mouseover', onMouseOver, true); document.addEventListener('mouseout', onMouseOut, true); document.addEventListener('click', onClick, true); } function resetAllReplacements() { if (confirm("⚠️ This will remove ALL replaced/edited messages. Are you sure?")) { saveReplacements({}); alert('♻️ All replaced messages have been reset.'); location.reload(); } } try { GM_registerMenuCommand("✏️ Replace a message", pickAndReplaceText); GM_registerMenuCommand("➕ Add Roblox embed below a message", addRobloxEmbedBelow); GM_registerMenuCommand("♻️ Reset all replaced messages", resetAllReplacements); } catch {} })();