您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
自动识别页面中的福利吧百家姓暗号并转换为磁力链接
// ==UserScript== // @name 福利吧百家姓暗号转换器 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 自动识别页面中的福利吧百家姓暗号并转换为磁力链接 // @author MR.Z // @match https://fuliba2023.net/* // @grant GM_setClipboard // ==/UserScript== // ==UserScript== // @name 百家姓暗号 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 识别和转换网页中的"百家姓暗号" // @license MIT // ==/UserScript== (function() { 'use strict'; // 百家姓映射表 const surnameMap = { "赵":"0", "钱":"1", "孙":"2", "李":"3", "周":"4", "吴":"5", "郑":"6", "王":"7", "冯":"8", "陈":"9", "褚":"a", "卫":"b", "蒋":"c", "沈":"d", "韩":"e", "杨":"f", "朱":"g", "秦":"h", "尤":"i", "许":"j", "何":"k", "吕":"l", "施":"m", "张":"n", "孔":"o", "曹":"p", "严":"q", "华":"r", "金":"s", "魏":"t", "陶":"u", "姜":"v", "戚":"w", "谢":"x", "邹":"y", "喻":"z", "福":"A", "水":"B", "窦":"C", "章":"D", "云":"E", "苏":"F", "潘":"G", "葛":"H", "奚":"I", "范":"J", "彭":"K", "郎":"L", "鲁":"M", "韦":"N", "昌":"O", "马":"P", "苗":"Q", "凤":"R", "花":"S", "方":"T", "俞":"U", "任":"V", "袁":"W", "柳":"X", "唐":"Y", "罗":"Z", "薛":".", "伍":"-", "余":"_", "米":"+", "贝":"=", "姚":"/", "孟":"?", "顾":"#", "尹":"%", "江":"&", "钟":"*" }; // 获取评论区元素 function findCommentContainer() { // 常见评论区选择器 const commentSelectors = [ '#comments', '#comment', '.comments', '.comment', '.comment-list', '.comment-section', '.comment-container', '.comment-area', '.article-comments', '.post-comments' ]; for (const selector of commentSelectors) { const element = document.querySelector(selector); if (element) { return element; } } return document.body; // 如果找不到则返回整个body } // 自动扫描页面文本节点 function scanTextNodes() { console.log('开始扫描页面文本节点...'); const commentContainer = findCommentContainer(); const walker = document.createTreeWalker( commentContainer, NodeFilter.SHOW_TEXT, { acceptNode: function(node) { // 跳过script、style、textarea等元素 if (node.parentNode.nodeName === 'SCRIPT' || node.parentNode.nodeName === 'STYLE' || node.parentNode.nodeName === 'TEXTAREA' || node.parentNode.nodeName === 'INPUT' || node.parentNode.hasAttribute('data-surname-ignore')) { return NodeFilter.FILTER_REJECT; } // 检查是否已处理过 if (node.parentNode.hasAttribute('data-surname-processed')) { return NodeFilter.FILTER_REJECT; } return NodeFilter.FILTER_ACCEPT; } }, false ); let node; let foundCount = 0; while (node = walker.nextNode()) { const text = node.nodeValue.trim(); if (text.length === 0) continue; console.log('扫描到文本:', text.substring(0, 50) + (text.length > 50 ? '...' : '')); if (isSurnameCode(text)) { console.log('发现百家姓暗号:', text); foundCount++; processSurnameCode(node, text); } } console.log(`扫描完成,共发现${foundCount}处百家姓暗号`); } // 检查是否是百家姓暗号 function isSurnameCode(text) { // 检查是否包含至少3个百家姓字符,提高准确性 let surnameCount = 0; const surnames = Object.keys(surnameMap); for (const surname of surnames) { if (text.includes(surname)) { surnameCount++; if (surnameCount >= 3) { return true; } } } return false; } // 处理找到的百家姓暗号 function processSurnameCode(textNode, text) { // 双重检查是否已经处理过 if (textNode.parentNode.hasAttribute('data-surname-processed') || textNode.parentNode.querySelector('button[data-surname-button]')) { return; } const span = document.createElement('span'); span.textContent = text; const button = document.createElement('button'); button.textContent = '识别暗号'; button.setAttribute('data-surname-button', 'true'); button.style.cssText = ` margin-left: 8px; padding: 4px 12px; font-size: 13px; font-weight: 500; color: #fff; background-color: #4a6cf7; border: none; border-radius: 4px; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 1px 2px rgba(0,0,0,0.1); min-width: 80px; min-height: 32px; `; // 移动端样式调整 const mobileStyle = document.createElement('style'); mobileStyle.textContent = ` @media (max-width: 768px) { button[data-surname-button] { padding: 8px 16px; font-size: 15px; min-width: 90px; min-height: 36px; } div[data-surname-toast] { font-size: 16px; padding: 16px 28px; bottom: 30px; max-width: 80%; } } `; document.head.appendChild(mobileStyle); button.addEventListener('mouseenter', () => { button.style.backgroundColor = '#3a5ce9'; button.style.transform = 'translateY(-1px)'; }); button.addEventListener('mouseleave', () => { button.style.backgroundColor = '#4a6cf7'; button.style.transform = 'none'; }); // 创建美观的提示函数 function showToast(message) { const toast = document.createElement('div'); toast.textContent = message; toast.setAttribute('data-surname-toast', 'true'); toast.style.cssText = ` position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background-color: #4a6cf7; color: white; padding: 12px 24px; border-radius: 4px; font-size: 14px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 9999; opacity: 0; transition: opacity 0.3s ease; white-space: nowrap; `; document.body.appendChild(toast); // 显示动画 setTimeout(() => { toast.style.opacity = '1'; }, 10); // 3秒后自动消失 setTimeout(() => { toast.style.opacity = '0'; setTimeout(() => { document.body.removeChild(toast); }, 300); }, 3000); } button.addEventListener('click', function() { const magnetLink = 'magnet:?xt=urn:btih:' + encodeToCipher(text); GM_setClipboard(magnetLink); showToast('磁力链接已复制'); }); const wrapper = document.createElement('span'); wrapper.setAttribute('data-surname-processed', 'true'); wrapper.appendChild(span); wrapper.appendChild(button); textNode.parentNode.replaceChild(wrapper, textNode); } // 转换函数 function encodeToCipher(text) { const chars = text.split(''); let result = ''; for(let i = 0; i < chars.length; i++) { const cipher = getValueByKey(surnameMap, chars[i]); result += cipher || ''; } return result; } function getValueByKey(obj, key) { for(let k in obj) { if(k === key) { return obj[k]; } } return ''; } // 初始化扫描 - 优化性能版本 let isScanning = false; let scanQueue = []; let debounceTimer; function throttledScan() { if (isScanning) { return; } isScanning = true; const startTime = performance.now(); // 每次最多处理50个节点 const nodesToProcess = scanQueue.splice(0, 50); for (const node of nodesToProcess) { // 跳过已处理的节点 if (node.parentNode && node.parentNode.hasAttribute('data-surname-processed')) { continue; } const text = node.nodeValue.trim(); if (text.length > 0 && isSurnameCode(text)) { processSurnameCode(node, text); } } isScanning = false; console.log(`扫描完成,耗时${(performance.now() - startTime).toFixed(2)}ms`); if (scanQueue.length > 0) { setTimeout(throttledScan, 100); } } function handleMutations(mutations) { // 暂停期间不处理 if (!observer) return; mutations.forEach(mutation => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { const walker = document.createTreeWalker( node, NodeFilter.SHOW_TEXT, { acceptNode: function(n) { // 跳过已处理节点 if (processedNodes.has(n)) { return NodeFilter.FILTER_REJECT; } if (n.parentNode.nodeName === 'SCRIPT' || n.parentNode.nodeName === 'STYLE' || n.parentNode.nodeName === 'TEXTAREA' || n.parentNode.nodeName === 'INPUT') { return NodeFilter.FILTER_REJECT; } return NodeFilter.FILTER_ACCEPT; } }, false ); let textNode; while (textNode = walker.nextNode()) { // 检查是否已存在相同内容的按钮 if (!textNode.parentNode.querySelector('button[data-surname-button]')) { scanQueue.push(textNode); } } } }); } }); // 防抖处理 clearTimeout(debounceTimer); debounceTimer = setTimeout(throttledScan, 300); // 缩短防抖时间 } // 延迟初始化扫描 setTimeout(() => { try { console.log('开始初始扫描...'); const initialWalker = document.createTreeWalker( document.body, NodeFilter.SHOW_TEXT, { acceptNode: function(node) { if (node.parentNode.nodeName === 'SCRIPT' || node.parentNode.nodeName === 'STYLE' || node.parentNode.nodeName === 'TEXTAREA' || node.parentNode.nodeName === 'INPUT') { return NodeFilter.FILTER_REJECT; } return NodeFilter.FILTER_ACCEPT; } }, false ); let initialNode; while (initialNode = initialWalker.nextNode()) { scanQueue.push(initialNode); } throttledScan(); // 监听DOM变化,使用防抖 const observer = new MutationObserver(handleMutations); observer.observe(document.body, { childList: true, subtree: true, attributes: false, characterData: false }); } catch (e) { console.error('初始化扫描出错:', e); } }, 2000); // 延长初始延迟 })();