Greasy Fork

Greasy Fork is available in English.

威软全能网盘增强助手 (涅槃重生版)

支持夸克、百度、阿里云盘。底部分离解耦架构,只要嗅探到直链无条件强制弹窗,彻底粉碎阿里防盗链。

当前为 2026-04-24 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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, '&quot;')}" 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">&times;</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();
    });
})();