NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name 移花宫(磁力搜索器)添加磁力链接按钮和复制按钮
// @namespace http://tampermonkey.net/
// @version 1.0.1
// @description "恢复"旧版网站的"[磁力链接]"按钮。从搜索结果提取 Hash、资源名称和资源大小,自动生成标准磁力链接按钮和复制按钮
// @author wujinjun
// @license MIT
// @match *://yhg007.com/search-*.html
// @match *://yhg007.com/search-*.html?*
// @icon https://www.google.com/s2/favicons?sz=64&domain=yhg007.com
// @grant GM_setClipboard
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// ==/UserScript==
(function () {
'use strict';
// 默认使用的 Tracker 列表(包含 opentracker 等)
const DEFAULT_TRACKERS = [
"https://opentracker.i2p.rocks/announce",
"udp://tracker.opentrackr.org:1337/announce",
"udp://open.demonii.com:1337/announce",
"udp://tracker.openbittorrent.com:80/announce",
"udp://exodus.desync.com:6969/announce"
];
/**
* 获取用户设置的 Tracker 列表
*/
function getTrackers() {
const saved = GM_getValue('custom_trackers', null);
if (saved) {
return saved.split('\n').map(t => t.trim()).filter(t => t.length > 0);
}
return DEFAULT_TRACKERS;
}
/**
* 注册油猴菜单,方便随时修改 Tracker 列表
*/
GM_registerMenuCommand("⚙️ 配置 Tracker 列表", () => {
const currentTrackers = getTrackers().join('\n');
const input = prompt("请输入 Tracker 列表 (每行一个 tracker 地址):", currentTrackers);
if (input !== null) {
GM_setValue('custom_trackers', input.trim());
alert("Tracker 配置已更新!页面刷新后或加载新内容时生效。");
// 清除已添加标记,重新刷新当前页面的链接
document.querySelectorAll('[data-magnet-added]').forEach(el => {
delete el.dataset.magnetAdded;
const oldBtn = el.querySelector('.magnet-btn-container');
if (oldBtn) oldBtn.remove();
});
processArticles();
}
});
/**
* 将带有单位的大小字符串转换为字节数 (Byte)
* 支持 B, KB, MB, GB, TB
*/
function parseSizeToBytes(sizeStr) {
if (!sizeStr) return 0;
// 匹配数字与单位(忽略大小写)
const match = sizeStr.match(/([\d.]+)\s*([a-zA-Z]+)/);
if (!match) return 0;
const val = parseFloat(match[1]);
const unit = match[2].toUpperCase();
const units = {
'B': 1,
'KB': 1024,
'MB': 1024 * 1024,
'GB': 1024 * 1024 * 1024,
'TB': 1024 * 1024 * 1024 * 1024
};
return Math.round(val * (units[unit] || 1));
}
/**
* 解析每一个 article 节点并添加磁力链接
*/
function processArticles() {
const articles = document.querySelectorAll('#main-content > div > article');
const trackers = getTrackers();
articles.forEach(article => {
// 防止重复处理
if (article.dataset.magnetAdded) return;
// 1. 提取 Hash 与 资源名称
const nameEl = article.querySelector('.zsky-result-body > a');
if (!nameEl) return;
const href = nameEl.getAttribute('href') || '';
const hashMatch = href.match(/([a-fA-F0-9]{40})/); // 匹配 40 位 hex hash
if (!hashMatch) return;
const hash = hashMatch[1];
const rawName = nameEl.textContent.trim();
const encodedName = encodeURIComponent(rawName);
// 2. 提取并转换资源大小
let bytes = 0;
const metaSpans = article.querySelectorAll('.zsky-result-meta > span');
metaSpans.forEach(span => {
const text = span.textContent.trim();
if (text.includes('大小:') || text.includes('大小:')) {
const sizeStr = text.replace(/大小[::]\s*/, '');
bytes = parseSizeToBytes(sizeStr);
}
});
// 3. 构造完整磁力链接
let magnetUrl = `magnet:?xt=urn:btih:${hash}&dn=${encodedName}`;
if (bytes > 0) {
magnetUrl += `&xl=${bytes}`;
}
// 拼接 Tracker 节点
trackers.forEach(tr => {
magnetUrl += `&tr=${encodeURIComponent(tr)}`;
});
// 4. 在元素末尾追加 UI 按钮与链接
const btnContainer = document.createElement('div');
btnContainer.className = 'magnet-btn-container';
btnContainer.style.cssText = 'margin-top: 6px; display: flex; gap: 10px; align-items: center;';
// 磁力超链接
const magnetLink = document.createElement('a');
magnetLink.href = magnetUrl;
// magnetLink.textContent = '🧲 磁力下载';
magnetLink.textContent = '[磁力链接]';
magnetLink.style.cssText = 'color: #1e88e5; text-decoration: none; font-weight: bold; font-size: 13px;';
// 一键复制按钮
const copyBtn = document.createElement('button');
copyBtn.textContent = '复制磁力链接';
copyBtn.style.cssText = 'padding: 2px 8px; font-size: 12px; border: 1px solid #ccc; background: #f5f5f5; border-radius: 4px; cursor: pointer;';
copyBtn.addEventListener('click', (e) => {
e.preventDefault();
GM_setClipboard(magnetUrl);
copyBtn.textContent = '已复制!';
copyBtn.style.background = '#e8f5e9';
setTimeout(() => {
copyBtn.textContent = '复制磁力链接';
copyBtn.style.background = '#f5f5f5';
}, 1500);
});
btnContainer.appendChild(magnetLink);
btnContainer.appendChild(copyBtn);
const bodyDiv = article.querySelector('.zsky-result-body') || article;
bodyDiv.appendChild(btnContainer);
// 标记已处理
article.dataset.magnetAdded = 'true';
});
}
// 初始化执行
processArticles();
// 使用 MutationObserver 监听动态加载或翻页加载的内容
const observer = new MutationObserver(() => {
processArticles();
});
observer.observe(document.body, { childList: true, subtree: true });
})();