您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Detects and translates obfuscation code in Reddit comments + Text selection popup for Google search
当前为
// ==UserScript== // @name Reddit Multi Code Decoder for obfuscated content // @namespace [email protected] // @version 0.2.0 // @description Detects and translates obfuscation code in Reddit comments + Text selection popup for Google search // @author [email protected] // @license MIT // @match https://www.reddit.com/* // @match https://old.reddit.com/* // @grant none // ==/UserScript== (function() { 'use strict'; // Centralized comment selectors for both selection popup and binary decoder const COMMENT_SELECTORS = [ // New Reddit '[data-testid="comment"]', 'shreddit-comment', '.Comment', '[data-click-id="text"]', // Old Reddit '.usertext-body', '.md', // Generic fallbacks '.comment', '[class*="comment"]' ]; // ===== TEXT SELECTION POPUP FEATURE ===== let selectionPopup = null; function createSelectionPopup() { const popup = document.createElement('div'); popup.id = 'text-selection-popup'; popup.style.cssText = ` position: fixed; background: #ffffff; border: 1px solid #e0e0e0; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); padding: 8px; z-index: 10000; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 14px; display: none; max-width: 200px; `; const searchButton = document.createElement('button'); searchButton.textContent = '🔍 Search on Google'; searchButton.style.cssText = ` background: #4285f4; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 13px; width: 100%; transition: background-color 0.2s; display: flex; align-items: center; justify-content: center; line-height: 1; `; searchButton.onmouseover = () => searchButton.style.backgroundColor = '#3367d6'; searchButton.onmouseout = () => searchButton.style.backgroundColor = '#4285f4'; popup.appendChild(searchButton); document.body.appendChild(popup); return { popup, searchButton }; } function hideSelectionPopup() { if (selectionPopup && selectionPopup.popup) { selectionPopup.popup.style.display = 'none'; } } function showSelectionPopup(x, y, selectedText) { if (!selectionPopup) { selectionPopup = createSelectionPopup(); } const { popup, searchButton } = selectionPopup; // Update button click handler with current selected text searchButton.onclick = () => { const encodedText = encodeURIComponent(selectedText.trim()); window.open(`https://www.google.com/search?q=${encodedText}`, '_blank'); hideSelectionPopup(); }; // Position popup near mouse cursor (using clientX/clientY with fixed positioning) popup.style.left = `${x + 10}px`; popup.style.top = `${y + 10}px`; popup.style.display = 'block'; // Adjust position if popup goes off screen const rect = popup.getBoundingClientRect(); const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; if (rect.right > viewportWidth) { popup.style.left = `${x - rect.width - 10}px`; } if (rect.bottom > viewportHeight) { popup.style.top = `${y - rect.height - 10}px`; } } // Check if the target element is within a comment function isWithinComment(element) { return COMMENT_SELECTORS.some(selector => element.closest(selector)); } // Handle text selection events document.addEventListener('mouseup', (e) => { setTimeout(() => { const selection = window.getSelection(); const selectedText = selection.toString().trim(); if (selectedText.length > 0 && isWithinComment(e.target)) { // Use clientX/clientY with fixed positioning for proper viewport positioning showSelectionPopup(e.clientX, e.clientY, selectedText); } else { hideSelectionPopup(); } }, 10); }); // Hide popup when clicking elsewhere or on escape document.addEventListener('mousedown', (e) => { if (selectionPopup && selectionPopup.popup && !selectionPopup.popup.contains(e.target)) { hideSelectionPopup(); } }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { hideSelectionPopup(); } }); // ===== BINARY DECODER FUNCTIONALITY ===== // Binary pattern: sequences of 0s and 1s, typically in groups of 8 (bytes) // Matches patterns like: 01001000 01100101 01101100 01101100 01101111 const binaryPattern = /(?:\b[01]{8}\b[\s]*){2,}/g; // Function to convert binary string to text function binaryToText(binaryString) { try { // Remove all whitespace and split into 8-bit chunks const cleanBinary = binaryString.replace(/\s/g, ''); if (cleanBinary.length % 8 !== 0) { return null; // Invalid binary string } let result = ''; for (let i = 0; i < cleanBinary.length; i += 8) { const byte = cleanBinary.substr(i, 8); const charCode = parseInt(byte, 2); // Only convert printable ASCII characters (32-126) and common whitespace if ((charCode >= 32 && charCode <= 126) || charCode === 9 || charCode === 10 || charCode === 13) { result += String.fromCharCode(charCode); } else { return null; // Contains non-printable characters, probably not text } } return result; } catch (e) { return null; } } // Function to create translation component function createTranslationComponent(binaryText, translatedText) { const container = document.createElement('div'); container.style.cssText = ` margin: 8px 0; padding: 12px; background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; font-family: monospace; font-size: 14px; position: relative; display: flex; align-items: center; gap: 12px; `; const header = document.createElement('div'); header.style.cssText = ` font-weight: bold; color: #1a73e8; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; flex-shrink: 0; `; header.textContent = '🔢 Binary:'; const translationDiv = document.createElement('div'); translationDiv.style.cssText = ` background: #e8f5e8; padding: 8px; border-radius: 4px; font-weight: bold; color: #2d5a2d; flex-grow: 1; `; translationDiv.textContent = `${translatedText}`; const googleLink = document.createElement('a'); googleLink.href = `https://www.google.com/search?q=${encodeURIComponent(translatedText)}&tbm=isch`; googleLink.target = '_blank'; googleLink.rel = 'noopener noreferrer'; googleLink.style.cssText = ` background: #4285f4; color: white; padding: 6px 8px; border-radius: 4px; text-decoration: none; display: flex; align-items: center; gap: 4px; font-size: 12px; flex-shrink: 0; transition: background-color 0.2s; `; googleLink.onmouseover = () => googleLink.style.backgroundColor = '#3367d6'; googleLink.onmouseout = () => googleLink.style.backgroundColor = '#4285f4'; // Google search icon (SVG) const googleIcon = document.createElement('span'); googleIcon.innerHTML = ` <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"> <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/> </svg> `; googleLink.appendChild(googleIcon); googleLink.appendChild(document.createTextNode('Search')); container.appendChild(header); container.appendChild(translationDiv); container.appendChild(googleLink); return container; } // Function to process text nodes and detect binary function processTextNode(textNode) { const text = textNode.textContent; const matches = text.match(binaryPattern); if (matches) { matches.forEach(match => { const translated = binaryToText(match); if (translated && translated.trim().length > 0) { // Create a wrapper for the original text node const wrapper = document.createElement('span'); textNode.parentNode.insertBefore(wrapper, textNode); wrapper.appendChild(textNode); // Add translation component after the text const translationComponent = createTranslationComponent(match, translated); wrapper.parentNode.insertBefore(translationComponent, wrapper.nextSibling); } }); } } // Function to scan for binary in comments function scanForBinary() { // Create selectors for paragraph elements within comments const commentParagraphSelectors = COMMENT_SELECTORS.map(selector => `${selector} p`); commentParagraphSelectors.forEach(selector => { const elements = document.querySelectorAll(selector); elements.forEach(element => { // Skip if already processed if (element.hasAttribute('data-binary-processed')) return; element.setAttribute('data-binary-processed', 'true'); // Process all text nodes in the element const walker = document.createTreeWalker( element, NodeFilter.SHOW_TEXT, null, false ); const textNodes = []; let node; while (node = walker.nextNode()) { textNodes.push(node); } textNodes.forEach(processTextNode); }); }); } // Initial scan setTimeout(scanForBinary, 1000); // Watch for dynamically loaded content const observer = new MutationObserver((mutations) => { let shouldScan = false; mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.nodeType === Node.ELEMENT_NODE) { // Check if the added node contains comments using centralized selectors if (node.querySelector && COMMENT_SELECTORS.some(selector => node.querySelector(selector) || node.matches(selector) )) { shouldScan = true; } } }); }); if (shouldScan) { setTimeout(scanForBinary, 500); } }); observer.observe(document.body, { childList: true, subtree: true }); // Scan when comments are expanded or loaded document.addEventListener('click', (e) => { // Check for comment expansion buttons if (e.target.matches('[aria-expanded]') || e.target.closest('[aria-expanded]') || e.target.textContent.includes('more replies') || e.target.textContent.includes('comments')) { setTimeout(scanForBinary, 1000); } }); console.log('Reddit Binary Decoder v0.2.0 loaded - Binary translation + Text selection Google search'); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址