Сыравіна Крыніца
max / 威软全能网盘增强助手 (Open API 终极直连版)

// ==UserScript==
// @name         威软全能网盘增强助手 (Open API 终极直连版)
// @namespace    Weiruan-Pan-Helper
// @version      7.2.0
// @description  支持夸克、百度、阿里云盘。修正 AList 最新 API 网关,完美适配 JWT 超长 Token,满速提取直链。
// @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-end
// @connect      drive.quark.cn
// @connect      pan.baidu.com
// @connect      openapi.alipan.com
// @connect      api.alistgo.com
// @connect      api.nn.ci
// @homepage     https://github.com/weiruankeji2025/weiruan-quark
// ==/UserScript==

(function() {
    'use strict';

    const CONFIG = {
        VERSION: "7.2.0",
        DEBUG: true, 
        UA_ALIYUN: "AliApp(Yundrive/4.0.0)",
        UA_QUARK: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160",
        UA_BAIDU: "netdisk;7.0.3.2;PC;PC-Windows;10.0.19045",
    };

    const State = {
        fileMemoryMap: new Map(),
        aliToken: GM_getValue('weiruan_ali_token', ''),
    };

    const Utils = {
        log: (...args) => { if (CONFIG.DEBUG) console.log('[威软全能助手]', ...args); },
        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]; },
        getFileIcon: (fn) => {
            const ext = (fn || '').split('.').pop().toLowerCase();
            if (['mp4', 'mkv', 'avi', 'mov'].includes(ext)) return '🎬';
            if (['mp3', 'wav', 'flac'].includes(ext)) return '🎵';
            if (['zip', 'rar', '7z'].includes(ext)) return '📦';
            return '📄';
        },
        post: (url, data, customHeaders = {}) => new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "POST", url: url,
                headers: Object.assign({"Content-Type": "application/json"}, customHeaders),
                data: typeof data === 'string' ? data : JSON.stringify(data), responseType: 'json',
                onload: res => res.status >= 200 && res.status < 300 ? resolve(res.response) : reject(res),
                onerror: reject
            });
        }),
        toast: (msg, type = 'success', duration = 4000) => {
            if (!document.body) return;
            document.querySelector('.weiruan-toast')?.remove();
            const div = document.createElement('div'); div.className = 'weiruan-toast'; div.innerText = msg;
            const colors = { success: '#764ba2', error: '#ff4444', info: '#00bbff', warning: '#ffbb00' };
            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, sans-serif; white-space: pre-line; text-align: center;`;
            document.body.appendChild(div);
            setTimeout(() => { div.style.animation = 'weiruan-toast-out 0.3s ease-out forwards'; setTimeout(() => div.remove(), 300); }, duration);
        }
    };

    // ==================== 🔑 Open API 核心授权引擎 ====================
    const AliOpenAPI = {
        async getAccessToken() {
            if (!State.aliToken) return null;
            Utils.toast('正在通过 AList 开放网关验证身份...', 'info', 2000);
            try {
                // 【核心修复】:使用最新可用的 alistgo 网关
                const res = await Utils.post('https://api.alistgo.com/alist/ali_open/token', {
                    grant_type: "refresh_token",
                    refresh_token: State.aliToken
                });
                if (res && res.access_token) {
                    if (res.refresh_token) {
                        State.aliToken = res.refresh_token;
                        GM_setValue('weiruan_ali_token', res.refresh_token);
                    }
                    return res.access_token;
                }
            } catch (e) {
                Utils.log("Token 刷新失败,请检查是否过期或复制错误", e);
            }
            return null;
        },

        async getDownloadUrl(driveId, fileId, accessToken) {
            try {
                const res = await Utils.post('https://openapi.alipan.com/adrive/v1.0/openFile/getDownloadUrl', {
                    drive_id: driveId,
                    file_id: fileId,
                    expire_sec: 14400 // 4小时有效
                }, { "Authorization": "Bearer " + accessToken });
                if (res && res.url) return res.url;
            } catch (e) {
                Utils.log(`获取文件 ${fileId} 直链失败`, e);
            }
            return null;
        }
    };

    // ==================== 适配器 ====================
    const Adapters = {
        quark: {
            name: "夸克网盘", matches: ['pan.quark.cn'], ua: CONFIG.UA_QUARK,
            getSelectedFiles: function() {
                const files = new Map();
                document.querySelectorAll('.ant-checkbox-wrapper-checked, .ant-checkbox-checked, input[type="checkbox"]:checked').forEach(el => {
                    if (el.closest('.ant-table-thead')) return;
                    const row = el.closest('.ant-table-row, .file-list-item, [data-fid]');
                    const fid = row?.getAttribute('data-fid') || row?.getAttribute('data-file-id');
                    if (fid) files.set(fid, { fid, name: row.querySelector('.file-name')?.innerText.trim() || '未命名', isDir: false, size: 0, download_url: '' });
                });
                return Array.from(files.values());
            },
            processFiles: async f => f
        },
        baidu: {
            name: "百度网盘", matches: ['pan.baidu.com', 'yun.baidu.com'], ua: CONFIG.UA_BAIDU,
            getSelectedFiles: function() {
                try {
                    return unsafeWindow.require('system-core:context/context.js').instanceForSystem.list.getSelected().map(item => ({
                        fid: item.fs_id, name: item.server_filename, isDir: item.isdir === 1, size: item.size, download_url: ''
                    }));
                } catch (e) { return []; }
            },
            processFiles: async f => f
        },
        aliyun: {
            name: "阿里云盘 (OpenAPI版)", matches: ['aliyundrive.com', 'alipan.com'], ua: CONFIG.UA_ALIYUN,
            getSelectedFiles: function() {
                const files = new Map();
                const findFilesInFiber = (obj, visited = new Set(), depth = 0) => {
                    if (!obj || typeof obj !== 'object' || depth > 15) return;
                    if (visited.has(obj)) return; visited.add(obj);
                    if (obj.file_id && obj.name && typeof obj.file_id === 'string' && obj.file_id.length > 5) State.fileMemoryMap.set(obj.name.trim(), obj);
                    for (let key in obj) {
                        if (key === 'return' || key === 'child' || key === 'sibling' || key.startsWith('__')) continue;
                        try { findFilesInFiber(obj[key], visited, depth + 1); } catch(e) {}
                    }
                };

                document.querySelectorAll('#root, #app, [class*="layout"], [class*="container"]').forEach(el => {
                    const key = Object.keys(el).find(k => k.startsWith('__reactFiber$'));
                    if (key) findFilesInFiber(el[key]);
                });

                document.querySelectorAll('input[type="checkbox"]:checked, [aria-checked="true"], [class*="checked"], .icon-checked').forEach(el => {
                    if (el.closest('thead') || el.closest('[class*="header"]')) return;
                    let matched = false, currentEl = el;

                    for (let i = 0; i < 5 && currentEl; i++) {
                        const titleVal = currentEl.getAttribute('title') || currentEl.getAttribute('data-title');
                        if (titleVal && State.fileMemoryMap.has(titleVal.trim())) {
                            const memObj = State.fileMemoryMap.get(titleVal.trim());
                            files.set(memObj.file_id, { fid: memObj.file_id, drive_id: memObj.drive_id, name: memObj.name, isDir: memObj.type === 'folder', size: memObj.size || 0 });
                            matched = true; break;
                        }
                        currentEl = currentEl.parentElement;
                    }

                    if (!matched) {
                        currentEl = el;
                        const cleanStr = str => (str || '').replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, '');
                        for (let i = 0; i < 10 && currentEl; i++) {
                            const cleanRowText = cleanStr(currentEl.textContent);
                            if (cleanRowText.length > 1) {
                                for (let [memName, memObj] of Array.from(State.fileMemoryMap.entries()).sort((a,b) => b[0].length - a[0].length)) {
                                    const cName = cleanStr(memName);
                                    if (cName.length > 0 && cleanRowText.includes(cName.substring(0, 5))) {
                                        files.set(memObj.file_id, { fid: memObj.file_id, drive_id: memObj.drive_id, name: memObj.name, isDir: memObj.type === 'folder', size: memObj.size || 0 });
                                        matched = true; break;
                                    }
                                }
                            }
                            if (matched) break; currentEl = currentEl.parentElement;
                        }
                    }
                });
                return Array.from(files.values());
            },
            processFiles: async function(files) {
                const validFiles = files.filter(f => !f.isDir);
                if (validFiles.length < files.length) Utils.toast('已过滤文件夹,OpenAPI 仅支持提取文件直链。', 'warning');
                if (validFiles.length === 0) return null;

                const accessToken = await AliOpenAPI.getAccessToken();
                if (!accessToken) {
                    Utils.toast('⚠️ Token 无效或已过期,请重新配置!', 'error');
                    UI.showAuthWindow();
                    return null;
                }

                Utils.toast(`正在向阿里云盘服务器申请 ${validFiles.length} 个满速直链...`, 'info');
                let readyFiles = [];
                for (let f of validFiles) {
                    const url = await AliOpenAPI.getDownloadUrl(f.drive_id, f.fid, accessToken);
                    if (url) readyFiles.push({ ...f, file_name: f.name, download_url: url });
                }
                if (readyFiles.length === 0) { Utils.toast('提取失败,Token可能过期,请重新配置。', 'error'); return null; }
                return readyFiles;
            }
        }
    };

    const DriveManager = {
        currentAdapter: null,
        init() {
            const host = location.host;
            for (const key in Adapters) {
                if (Adapters[key].matches.some(m => host.includes(m))) {
                    this.currentAdapter = Adapters[key]; break;
                }
            }
        },
        async runExtraction() {
            if (!this.currentAdapter) return;
            
            if (this.currentAdapter.name.includes("阿里云盘") && !State.aliToken) {
                UI.showAuthWindow();
                return;
            }

            const btn = document.getElementById('weiruan-btn');
            try {
                if (btn) { btn.innerHTML = `<span class="weiruan-spinner"></span> 处理中`; btn.disabled = true; }
                const initialFiles = this.currentAdapter.getSelectedFiles();
                
                if (initialFiles.length === 0) {
                    Utils.toast('⚠️ 请先在页面上勾选需要下载的文件!', 'error');
                    return;
                }

                const resultData = await this.currentAdapter.processFiles(initialFiles);
                if (resultData && resultData.length > 0) {
                    UI.showResultWindow(resultData);
                }
            } catch (e) {
                Utils.log("提取过程出错", e);
            } finally {
                if (btn) { btn.innerHTML = `<span class="weiruan-icon">⚡</span> 威软提取`; btn.disabled = false; }
            }
        }
    };

    // ==================== 界面 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); } }
                @keyframes weiruan-spin { to { transform: rotate(360deg); } }
                .weiruan-spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-top-color: white; border-radius: 50%; animation: weiruan-spin 0.8s linear infinite; margin-right: 6px; vertical-align: middle; }
                .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 20px; border: none; border-radius: 0 25px 25px 0; cursor: pointer; box-shadow: 0 4px 15px rgba(102, 126, 234, 0.5); transition: all 0.3s ease; }
                .weiruan-btn:hover { padding-left: 26px; box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6); }
                .weiruan-menu { position: fixed; top: calc(50% + 50px); left: 0; transform: translateY(-50%); z-index: 2147483646; display: flex; flex-direction: column; gap: 5px; opacity: 0; pointer-events: none; transition: all 0.3s ease; }
                .weiruan-btn:hover + .weiruan-menu, .weiruan-menu:hover { opacity: 1; pointer-events: auto; left: 5px; }
                .weiruan-menu-item { background: rgba(255,255,255,0.95); color: #333; padding: 10px 16px; border-radius: 20px; font-size: 13px; font-weight: bold; cursor: pointer; box-shadow: 0 2px 10px rgba(0,0,0,0.1); transition: all 0.2s; white-space: nowrap; border: 1px solid #eee; }
                .weiruan-menu-item:hover { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; transform: translateX(5px); }
                .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%; 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: 8px; }
                .weiruan-action-btn { padding: 8px 16px; border: none; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 500; color: white; transition: transform 0.2s;}
                .weiruan-action-btn:hover { transform: translateY(-1px); }
                .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; max-height: 450px; }
                .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; display: inline-block;}
                .weiruan-file-btn.idm { background: linear-gradient(135deg, #56ab2f 0%, #a8e063 100%); }
                .weiruan-file-btn.aria2 { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
                .weiruan-input { width: 100%; padding: 12px; border: 2px solid #ddd; border-radius: 8px; font-size: 14px; margin: 15px 0; outline: none; transition: border-color 0.2s; box-sizing: border-box; }
                .weiruan-input:focus { border-color: #667eea; }
                .weiruan-footer { padding: 12px 24px; border-top: 1px solid #eee; text-align: center; font-size: 12px; color: #999; }
            `);
        },
        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);

            const menu = document.createElement('div');
            menu.className = 'weiruan-menu';
            menu.innerHTML = `<div class="weiruan-menu-item" id="wr-menu-auth">🔑 阿里云盘 OpenAPI 授权</div>`;
            document.body.appendChild(menu);

            document.getElementById('wr-menu-auth').onclick = () => UI.showAuthWindow();
        },

        showAuthWindow: () => {
            document.getElementById('weiruan-modal')?.remove();
            const modal = document.createElement('div');
            modal.id = 'weiruan-modal';
            modal.className = `weiruan-modal-overlay`;

            modal.innerHTML = `
            <div class="weiruan-modal" style="width: 500px;">
                <div class="weiruan-modal-header">
                    <h3 class="weiruan-modal-title">🔐 配置阿里云盘 OpenAPI 授权</h3>
                    <span class="weiruan-modal-close" id="weiruan-modal-close">&times;</span>
                </div>
                <div class="weiruan-modal-body">
                    <div style="background:#fff3cd; color:#856404; padding:12px; border-radius:8px; font-size:13px; margin-bottom:15px; line-height:1.5;">
                        <b>请按以下步骤完成授权(仅需一次,告别限速):</b><br><br>
                        1. 点击下方按钮,前往 AList 官方开放平台。<br>
                        2. 在新页面中使用阿里云盘 APP 扫码。<br>
                        3. 扫码成功后,复制生成的 <b>Refresh Token(长代码)</b>。<br>
                        4. 将其完整粘贴到下方输入框,并点击保存。
                    </div>
                    
                    <button class="weiruan-action-btn primary" id="wr-goto-auth" style="width: 100%; padding: 12px; font-size: 15px; margin-bottom: 10px;">
                        👉 1. 点击前往获取 Refresh Token
                    </button>

                    <input type="text" class="weiruan-input" id="wr-token-input" placeholder="👉 2. 请将获取到的 Token 粘贴在此处..." value="${State.aliToken}">
                    
                    <button class="weiruan-action-btn success" id="wr-save-token" style="width: 100%; padding: 12px; font-size: 15px;">
                        💾 保存 Token 并立即提取
                    </button>
                </div>
            </div>`;
            document.body.appendChild(modal);

            document.getElementById('weiruan-modal-close').addEventListener('click', () => modal.remove());
            
            document.getElementById('wr-goto-auth').addEventListener('click', () => {
                window.open('https://alist.nn.ci/tool/aliyundrive/request', '_blank');
            });

            document.getElementById('wr-save-token').addEventListener('click', () => {
                const tokenVal = document.getElementById('wr-token-input').value.trim();
                // 放宽验证,只要是长字符串就行
                if (tokenVal.length < 50 || !tokenVal.startsWith('ey')) {
                    Utils.toast('Token 格式不正确!请确保复制了完整的以 ey 开头的超长代码。', 'error');
                    return;
                }
                State.aliToken = tokenVal;
                GM_setValue('weiruan_ali_token', tokenVal);
                Utils.toast('✅ 授权保存成功!正在为您提取直链...', 'success');
                modal.remove();
                DriveManager.runExtraction(); 
            });
        },

        showResultWindow: (data) => {
            document.getElementById('weiruan-modal')?.remove();
            const modal = document.createElement('div');
            modal.id = 'weiruan-modal';
            modal.className = `weiruan-modal-overlay`;
            
            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> ${f.file_name}</div>
                        <div class="weiruan-file-meta">${Utils.formatSize(f.size)} | 官方 OpenAPI 满速通道</div>
                    </div>
                    <div style="display:flex; gap:6px;">
                        <a href="${f.download_url.replace(/"/g, '&quot;')}" target="_blank" class="weiruan-file-btn idm">⬇️ 浏览器 / IDM 下载</a>
                        <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>
                    <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">📦 复制全部直链 URL</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());
            
            const activeUA = CONFIG.UA_ALIYUN;
            const getLinks = () => data.map(f => f.download_url).join('\n');
            const getAria2 = () => data.map(f => `aria2c -c -x 16 -s 16 "${f.download_url}" -o "${f.file_name}" -U "${activeUA}" --header="Cookie: ${document.cookie}"`).join('\n\n');

            document.getElementById('weiruan-copy-all-btn').addEventListener('click', () => { GM_setClipboard(getLinks()); Utils.toast('✅ 全部链接已复制'); });
            document.getElementById('weiruan-copy-aria2-btn').addEventListener('click', () => { GM_setClipboard(getAria2()); Utils.toast('✅ aria2 命令已复制'); });

            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(() => {
        // 阻止官方下载按钮事件绑定
        document.body.addEventListener('click', (e) => {
            const t = e.target;
            if ((t.innerText || t.textContent || '').includes('下载') && !t.closest('#weiruan-btn') && !t.closest('#weiruan-modal')) {
                if (location.host.includes('aliyundrive.com') || location.host.includes('alipan.com')) {
                    Utils.toast('🛑 要使用满速提取,请点击左侧紫色的\n【⚡ 威软提取】悬浮按钮!', 'warning', 4000);
                }
            }
        }, true);
        
        UI.injectStyles();
        UI.createFloatButton();
        DriveManager.init();
        console.log(`[威软全能助手] v${CONFIG.VERSION} 网关修正版已启动`);
    });
})();