Greasy Fork is available in English.
支持夸克、百度、阿里云盘。底部分离解耦架构,只要嗅探到直链无条件强制弹窗,彻底粉碎阿里防盗链。
当前为
// ==UserScript==
// @name 威软全能网盘增强助手 (涅槃重生版)
// @namespace Weiruan-Pan-Helper
// @version 5.0.0
// @description 支持夸克、百度、阿里云盘。底部分离解耦架构,只要嗅探到直链无条件强制弹窗,彻底粉碎阿里防盗链。
// @author 威软科技
// @license MIT
// @icon https://pan.quark.cn/favicon.ico
// @match *://pan.quark.cn/*
// @match *://pan.baidu.com/*
// @match *://yun.baidu.com/*
// @match *://*.aliyundrive.com/*
// @match *://*.alipan.com/*
// @grant GM_xmlhttpRequest
// @grant GM_setClipboard
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @grant unsafeWindow
// @run-at document-start
// @connect drive.quark.cn
// @connect pan.baidu.com
// @connect api.aliyundrive.com
// @homepage https://github.com/weiruankeji2025/weiruan-quark
// ==/UserScript==
(function() {
'use strict';
const CONFIG = { VERSION: "5.0.0", UA_ALIYUN: "AliApp(Yundrive/4.0.0)" };
// ==================== 📡 屏幕雷达 (可视化调试) ====================
const Radar = {
init() {
if (document.getElementById('weiruan-radar')) return;
const div = document.createElement('div');
div.id = 'weiruan-radar';
div.style.cssText = `
position: fixed; bottom: 20px; left: 20px; width: 350px; height: 200px;
background: rgba(0, 0, 0, 0.85); color: #00ff00; font-family: monospace;
font-size: 12px; padding: 10px; border-radius: 8px; z-index: 2147483647;
overflow-y: auto; pointer-events: none; border: 1px solid #333; box-shadow: 0 4px 15px rgba(0,0,0,0.5);
`;
div.innerHTML = `<div style="color:#fff; border-bottom:1px solid #333; padding-bottom:5px; margin-bottom:5px; font-weight:bold;">📡 威软战况雷达 v5.0.0</div>`;
const checkBody = setInterval(() => {
if (document.body) { document.body.appendChild(div); clearInterval(checkBody); }
}, 50);
},
log(msg, type = 'info') {
console.log('[威软雷达]', msg);
const radar = document.getElementById('weiruan-radar');
if (!radar) return;
const p = document.createElement('div');
p.style.margin = '2px 0'; p.style.wordBreak = 'break-all';
if (type === 'error') p.style.color = '#ff4444';
if (type === 'success') p.style.color = '#00bbff';
if (type === 'warn') p.style.color = '#ffbb00';
const time = new Date().toTimeString().split(' ')[0];
p.innerText = `[${time}] ${msg}`;
radar.appendChild(p);
radar.scrollTop = radar.scrollHeight;
}
};
const State = { capturedLinks: new Set() }; // 改为 Set 防止重复添加完全相同的 URL
const Utils = {
formatSize: (bytes) => { if (!bytes) return '0 B'; const k = 1024, i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i]; },
getFileType: (fn) => { if(!fn) return 'other'; const ext = fn.split('.').pop().toLowerCase(); const t = { video: ['mp4', 'mkv', 'avi', 'mov', 'wmv', 'flv', 'rmvb', 'm4v'], audio: ['mp3', 'wav', 'flac', 'aac', 'ogg', 'wma', 'm4a'], image: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'ico'], document: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'md'], archive: ['zip', 'rar', '7z', 'tar', 'gz', 'bz2'] }; for (const [type, exts] of Object.entries(t)) if (exts.includes(ext)) return type; return 'other'; },
getFileIcon: (fn) => ({ video: '🎬', audio: '🎵', image: '🖼️', document: '📄', archive: '📦', other: '📁' }[Utils.getFileType(fn)] || '📁'),
generateBatchLinks: (files) => files.map(f => f.download_url).join('\n'),
generateAria2Commands: (files, ua) => files.map(f => `${f.folderPath ? `mkdir -p "${f.folderPath}" && ` : ''}aria2c -c -x 16 -s 16 "${f.download_url}" -o "${f.fullPath || f.file_name}" -U "${ua}" --header="Cookie: ${document.cookie}"`).join('\n\n'),
generateCurlCommands: (files, ua) => files.map(f => `${f.folderPath ? `mkdir -p "${f.folderPath}" && ` : ''}curl -L -C - "${f.download_url}" -o "${f.fullPath || f.file_name}" -A "${ua}" -b "${document.cookie}"`).join('\n\n'),
toast: (msg, type = 'success', duration = 4500) => {
if (!document.body) return;
document.querySelector('.weiruan-toast')?.remove();
const div = document.createElement('div'); div.className = 'weiruan-toast'; div.innerText = msg;
const colors = { success: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', error: 'linear-gradient(135deg, #ff6b6b 0%, #ee5a5a 100%)', info: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)', warning: 'linear-gradient(135deg, #f6d365 0%, #fda085 100%)' };
div.style.cssText = `position: fixed; top: 80px; left: 50%; transform: translateX(-50%); background: ${colors[type] || colors.success}; color: ${type==='warning'?'#333':'white'}; padding: 16px 28px; border-radius: 12px; z-index: 2147483649; font-size: 15px; font-weight: bold; box-shadow: 0 10px 30px rgba(0,0,0,0.3); animation: weiruan-toast-in 0.3s ease-out; font-family: -apple-system, BlinkMacSystemFont, sans-serif; white-space: pre-line; line-height: 1.6; text-align: center;`;
document.body.appendChild(div);
setTimeout(() => { div.style.animation = 'weiruan-toast-out 0.3s ease-out forwards'; setTimeout(() => div.remove(), 300); }, duration);
}
};
// ==================== 🕸️ 无差别全量嗅探引擎 ====================
const NetworkHook = {
init() {
const win = unsafeWindow || window;
if (win._weiruan_hooked) return;
win._weiruan_hooked = true;
const extractUrlsFromResponse = (text) => {
if (!text || !text.includes('http')) return;
try {
const data = JSON.parse(text);
let foundUrls = [];
const searchUrl = (obj) => {
if (!obj || typeof obj !== 'object') return;
if (obj.url && typeof obj.url === 'string' && (obj.url.includes('aliyundrive.net') || obj.url.includes('alicloudccp.com') || obj.url.includes('x-oss-signature'))) {
foundUrls.push(obj.url);
}
Object.values(obj).forEach(val => searchUrl(val));
};
searchUrl(data);
if (foundUrls.length > 0) {
Radar.log(`🎯 [全量嗅探] 成功斩获真实 CDN 直链! 数量: ${foundUrls.length}`, 'success');
let newlyAdded = false;
foundUrls.forEach(url => {
if (!State.capturedLinks.has(url)) {
State.capturedLinks.add(url);
newlyAdded = true;
}
});
// 【核心改动】:一旦有新的直链入库,不管三七二十一,直接强制唤起面板!无视勾选状态!
if (newlyAdded && document.body) {
setTimeout(() => {
Radar.log(`🚀 准备强行突破渲染面板...`, 'info');
DriveManager.forceRenderCapturedLinks();
}, 300);
}
}
} catch(e) {}
};
const origFetch = win.fetch;
win.fetch = async function(...args) {
const response = await origFetch.apply(this, args);
try {
const clone = response.clone();
clone.text().then(text => extractUrlsFromResponse(text)).catch(()=>{});
} catch(e) {}
return response;
};
const origXhrSend = win.XMLHttpRequest.prototype.send;
win.XMLHttpRequest.prototype.send = function(body) {
this.addEventListener('load', function() {
extractUrlsFromResponse(this.responseText);
});
return origXhrSend.call(this, body);
};
// 拦截 iframe / a 标签原生下载
const interceptDomDownload = (url) => {
if (url && (url.includes('aliyundrive.net') || url.includes('alicloudccp.com') || url.includes('x-oss-signature'))) {
Radar.log(`🚨 [DOM黑洞] 拦截到原生下载: ${url.substring(0,30)}...`, 'warn');
if (!State.capturedLinks.has(url)) {
State.capturedLinks.add(url);
setTimeout(() => DriveManager.forceRenderCapturedLinks(), 300);
}
return true;
}
return false;
};
const origAnchorClick = HTMLAnchorElement.prototype.click;
HTMLAnchorElement.prototype.click = function() {
if (interceptDomDownload(this.href)) return;
return origAnchorClick.apply(this, arguments);
};
}
};
NetworkHook.init();
// ==================== 管理器 ====================
const DriveManager = {
// 这是普通的提取逻辑(点我们的闪电按钮触发)
runExtraction() {
Utils.toast(`⚠️ 阿里云盘提取说明 ⚠️\n\n1. 请勾选你想下载的文件 (别选文件夹)\n2. 去点页面原生的【官方下载按钮】\n3. 助手将在底层自动拦截直链并弹窗!`, 'warning', 6000);
State.capturedLinks.clear(); // 清空旧的拦截池
},
// 【新增】:这是强行弹窗逻辑(被底层网络嗅探触发)
forceRenderCapturedLinks() {
if (State.capturedLinks.size === 0) return;
// 把 Set 里存的链接组装成面板需要的数据结构
const urls = Array.from(State.capturedLinks);
const displayData = urls.map((url, index) => {
// 尝试从 URL 里正则猜一个文件名,猜不到就给个默认名
let inferredName = `已劫持文件_${index + 1}.mp4`;
try {
const match = url.match(/filename%2A%3DUTF-8%27%27([^&]+)/);
if (match && match[1]) inferredName = decodeURIComponent(match[1]);
} catch(e) {}
return {
fid: `hijack_${index}`,
name: inferredName,
file_name: inferredName,
isDir: false,
size: 0,
download_url: url,
folderPath: '',
fullPath: inferredName
};
});
Radar.log(`🎆 强制弹窗执行成功,共展示 ${displayData.length} 个文件!`, 'success');
UI.showResultWindow(displayData);
}
};
// ==================== 界面 UI ====================
const UI = {
injectStyles: () => {
GM_addStyle(`
@keyframes weiruan-toast-in { from { opacity: 0; transform: translate(-50%, -20px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes weiruan-toast-out { from { opacity: 1; transform: translate(-50%, 0); } to { opacity: 0; transform: translate(-50%, -20px); } }
@keyframes weiruan-slide-in { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } }
.weiruan-btn { position: fixed; top: 50%; left: 0; transform: translateY(-50%); z-index: 2147483647; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; font-size: 14px; font-weight: 600; padding: 14px 18px; border: none; border-radius: 0 25px 25px 0; cursor: pointer; box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4); transition: all 0.3s ease; display: flex; align-items: center; gap: 6px; }
.weiruan-btn:hover { padding-left: 22px; box-shadow: 0 6px 25px rgba(102, 126, 234, 0.5); }
.weiruan-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.6); z-index: 2147483648; display: flex; align-items: center; justify-content: center; backdrop-filter: blur(5px); }
.weiruan-modal { background: #fff; width: 720px; max-width: 92%; max-height: 85vh; border-radius: 16px; box-shadow: 0 25px 50px rgba(0,0,0,0.3); display: flex; flex-direction: column; overflow: hidden; font-family: sans-serif; animation: weiruan-slide-in 0.3s ease-out; }
.weiruan-modal-header { padding: 18px 24px; display: flex; justify-content: space-between; align-items: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; }
.weiruan-modal-title { margin: 0; font-size: 18px; font-weight: 600; }
.weiruan-modal-close { cursor: pointer; font-size: 28px; line-height: 1; }
.weiruan-toolbar { padding: 12px 24px; background: #f8f9ff; border-bottom: 1px solid #eee; display: flex; justify-content: space-between; align-items: center;}
.weiruan-btn-group { display: flex; gap: 6px; }
.weiruan-action-btn { padding: 8px 16px; border: none; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 500; color: white; }
.weiruan-action-btn.primary { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
.weiruan-action-btn.success { background: linear-gradient(135deg, #56ab2f 0%, #a8e063 100%); }
.weiruan-modal-body { padding: 16px 24px; overflow-y: auto; flex: 1; max-height: 400px; }
.weiruan-file-item { background: #f9f9f9; padding: 14px 16px; margin-bottom: 10px; border-radius: 10px; border-left: 4px solid #667eea; display: flex; justify-content: space-between; align-items: center; }
.weiruan-file-info { overflow: hidden; flex: 1; margin-right: 12px; }
.weiruan-file-name { font-weight: 600; color: #333; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 14px; }
.weiruan-file-meta { font-size: 12px; color: #888; margin-top: 4px; }
.weiruan-file-btn { padding: 6px 12px; border: none; border-radius: 5px; cursor: pointer; font-size: 12px; color: white; text-decoration: none; }
.weiruan-file-btn.idm { background: linear-gradient(135deg, #56ab2f 0%, #a8e063 100%); }
.weiruan-file-btn.curl { background: #333; }
.weiruan-file-btn.aria2 { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
.weiruan-footer { padding: 12px 24px; border-top: 1px solid #eee; text-align: center; font-size: 12px; color: #999; }
.weiruan-tabs { display: flex; border-bottom: 1px solid #eee; padding: 0 24px; background: #ffffff; }
.weiruan-tab { padding: 12px 20px; cursor: pointer; border: none; background: none; font-size: 14px; font-weight: 500; color: #666; position: relative; }
.weiruan-tab.active { color: #667eea; }
.weiruan-tab.active::after { content: ''; position: absolute; bottom: -1px; left: 0; right: 0; height: 2px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
`);
},
createFloatButton: () => {
if (document.getElementById('weiruan-btn')) return;
const btn = document.createElement('button');
btn.id = 'weiruan-btn'; btn.className = 'weiruan-btn';
btn.innerHTML = `<span class="weiruan-icon">⚡</span> 下载助手`;
btn.onclick = () => DriveManager.runExtraction();
document.body.appendChild(btn);
},
showResultWindow: (data) => {
document.getElementById('weiruan-modal')?.remove();
const modal = document.createElement('div');
modal.id = 'weiruan-modal';
modal.className = `weiruan-modal-overlay`;
const activeUA = CONFIG.UA_ALIYUN;
const batchLinks = Utils.generateBatchLinks(data);
const aria2Commands = Utils.generateAria2Commands(data, activeUA);
const fileListHTML = data.map((f, index) => `
<div class="weiruan-file-item">
<div class="weiruan-file-info">
<div class="weiruan-file-name" title="${f.name}"><span>${Utils.getFileIcon(f.file_name)}</span><span>${f.file_name}</span></div>
</div>
<div style="display:flex; gap:6px;">
<a href="${f.download_url.replace(/"/g, '"')}" target="_blank" class="weiruan-file-btn idm">⬇️ 浏览器下载</a>
<button class="weiruan-file-btn curl weiruan-copy-curl" data-index="${index}">📋 cURL</button>
<button class="weiruan-file-btn aria2 weiruan-copy-aria2" data-index="${index}">🚀 aria2</button>
</div>
</div>`).join('');
modal.innerHTML = `
<div class="weiruan-modal">
<div class="weiruan-modal-header">
<h3 class="weiruan-modal-title">🎉 底层截获成功!(共 ${data.length} 条直链)</h3>
<span class="weiruan-modal-close" id="weiruan-modal-close">×</span>
</div>
<div class="weiruan-tabs"><button class="weiruan-tab active">📁 满速直链</button></div>
<div>
<div class="weiruan-toolbar">
<div class="weiruan-toolbar-info">💡 提示:如果文件名没猜对,使用 IDM 下载时重命名一下即可。</div>
<div class="weiruan-btn-group">
<button class="weiruan-action-btn primary" id="weiruan-copy-all-btn">📦 复制全部直链</button>
<button class="weiruan-action-btn success" id="weiruan-copy-aria2-btn">🚀 批量 aria2</button>
</div>
</div>
<div class="weiruan-modal-body">${fileListHTML}</div>
</div>
<div class="weiruan-footer">威软科技 出品</div>
</div>`;
document.body.appendChild(modal);
document.getElementById('weiruan-modal-close').addEventListener('click', () => {
modal.remove();
State.capturedLinks.clear(); // 关掉面板顺便清空一下池子,防止下次重叠
});
document.getElementById('weiruan-copy-all-btn').addEventListener('click', () => { GM_setClipboard(batchLinks); Utils.toast('✅ 全部链接已复制'); });
document.getElementById('weiruan-copy-aria2-btn').addEventListener('click', () => { GM_setClipboard(aria2Commands); Utils.toast('✅ aria2 已复制'); });
modal.querySelectorAll('.weiruan-copy-curl').forEach(btn => {
btn.addEventListener('click', (e) => {
const f = data[parseInt(e.target.getAttribute('data-index'))];
GM_setClipboard(`curl -L -C - "${f.download_url}" -o "${f.file_name}" -A "${activeUA}" -b "${document.cookie}"`);
Utils.toast('✅ cURL 已复制');
});
});
modal.querySelectorAll('.weiruan-copy-aria2').forEach(btn => {
btn.addEventListener('click', (e) => {
const f = data[parseInt(e.target.getAttribute('data-index'))];
GM_setClipboard(`aria2c -c -x 16 -s 16 "${f.download_url}" -o "${f.file_name}" -U "${activeUA}" --header="Cookie: ${document.cookie}"`);
Utils.toast('✅ aria2 已复制');
});
});
}
};
function domReady(fn) {
if (document.readyState === 'complete' || document.readyState === 'interactive') { setTimeout(fn, 1); }
else { document.addEventListener('DOMContentLoaded', fn); }
}
domReady(() => {
Radar.init();
Radar.log('🚀 涅槃重生版本已注入!彻底抛弃选中判断,见链即抽!');
UI.injectStyles();
UI.createFloatButton();
});
})();