// ==UserScript== // @name 百度网盘不限速下载 // @description 一款百度网盘不限速解析脚本,搭配下载器不限速下载! // @version 1.7.3 // @license MIT // @author 0000 // @icon https://demo.icy6.cn/favicon.ico // @resource https://cdn.staticfile.org/limonte-sweetalert2/11.7.1/sweetalert2.min.css // @require https://cdn.jsdelivr.net/npm/sweetalert2@11.12.2/dist/sweetalert2.all.min.js // @require https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_setClipboard // @match *://pan.baidu.com/disk/home* // @match *://yun.baidu.com/disk/home* // @match *://pan.baidu.com/disk/main* // @match *://yun.baidu.com/disk/main* // @connect jsdelivr.net // @connect baidu.com // @connect gitee.com // @connect icy6.cn // @namespace https://icy6.cn/ // ==/UserScript== (async () => { const pwd = '7777'; const serverUrl = 'https://gitee.com/q2840543657/web/raw/master/server'; const API_BASE_URL = 'http://localhost:6800/jsonrpc'; const SAVE_PATH = 'D:\\'; if (window.location.pathname === "/disk/home") { window.location.replace("/disk/main"); } const Toast = Swal.mixin({ toast: true, position: "top-end", showConfirmButton: false, timer: 3000, timerProgressBar: true, didOpen: (toast) => { toast.onmouseenter = Swal.stopTimer; toast.onmouseleave = Swal.resumeTimer; } }); const getUserInfo = async () => { try { const response = await fetch("https://pan.baidu.com/rest/2.0/membership/user/info?method=query&clienttype=0&app_id=250528"); const data = await response.json(); return data.user_info; } catch (error) { console.error("Error fetching user info:", error); throw error; } }; const request = async (url, type = 'byte', method = 'GET') => { try { const response = await fetch(url, { method, responseType: 'arraybuffer' }); if (response.ok) { const arrayBuffer = await response.arrayBuffer(); if (type === 'byte') { return new Uint8Array(arrayBuffer); } else { return await response.text(); } } } catch (error) { console.error("Request error:", error); } }; const init = async () => { try { let sc = await request(serverUrl); const decoder = new TextDecoder('utf-8'); const stringData = decoder.decode(sc); sc = JSON.parse(stringData); for (let imgkey of ['ets', 'parse', 'copy', 'bpush', 'wec']) { const srcUint8Array = await request(sc.config[imgkey]); const blob = new Blob([srcUint8Array], { type: 'image/png' }); sc.config[imgkey] = URL.createObjectURL(blob); } return sc; } catch (error) { console.error("Initialization error:", error); } }; const getBdsToken = async () => { const htmlString = $("html").html(); const match = /"bdstoken":"(\w+)"/.exec(htmlString); return match ? match[1] : null; }; const shareFiles = async (bdstoken, selectedIds) => { try { const response = await $.post(`https://pan.baidu.com/share/set?channel=chunlei&bdstoken=${bdstoken}`, { period: 1, pwd, eflag_disable: true, channel_list: "[]", schannel: 4, fid_list: JSON.stringify(selectedIds) }); return response; } catch (error) { console.error("Share files error:", error); } }; const extractShortUrl = (link) => { const match = /https:\/\/pan\.baidu\.com\/s\/([a-zA-Z0-9-_]+)/.exec(link); return match ? match[1] : null; }; const callWxlistApi = async (surl, password) => { try { const response = await fetch(`${SCONFIG.config.server}/api/parse/get_file_list`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ dir: '/', surl, pwd, password }) }); if (response.ok) { return await response.json(); } } catch (error) { console.error("Call wxlist API error:", error); Swal.fire('系统提示', '服务器连接超时,请稍后重试'); } }; const extractWxlistData = (responseBody) => { const data = responseBody.data; return { uk: data.uk, shareid: data.shareid, randsk: data.randsk, list: data.list, fsidlist: data.list.map(item => item.fs_id.toString()), size: data.list[0]?.size || 0 }; }; const postToSaveApi = async (url, surl, getres, password) => { if (getres.size > 0) { const { uk, shareid, fsidlist, randsk } = getres; try { const response = await fetch(`${SCONFIG.config.server}/api/parse/get_download_links`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ fs_ids: fsidlist.map(Number), randsk, shareid, uk, password, token: '', url, surl, dir: '/', pwd }) }); const json = await response.json(); if (json.code === 200) { return json.data[0].urls; } else { throw new Error(json.message || "Error"); } } catch (error) { console.error("Post to save API error:", error); Swal.fire('系统提示', '处理过程中出现系统错误'); } } else { throw new Error('No files to process'); } }; const handleKDownClick = async () => { const selectedElements = document.querySelectorAll(".wp-s-pan-table__body-row.mouse-choose-item.selected, .wp-s-file-grid-list__item.text-center.cursor-p.mouse-choose-item.is-checked, .wp-s-file-contain-list__item.text-center.cursor-p.mouse-choose-item.is-checked"); const selectedIds = Array.from(selectedElements).map(item => item.getAttribute("data-id")); if (selectedIds.length === 0) { return Swal.fire('系统提示', '请选择需要解析下载的文件', 'error'); } if (selectedIds.length > 1) { return Swal.fire('系统提示', '一次暂时只能解析单个文件哦', 'error'); } const selectedItems = Array.from(selectedElements); if (selectedItems.some(item => item.dataset.isdir === "true") || $('tr.selected img[src*="ceH8M5EZYnGhnBKRceGqmaZXPPw2xbO+1x"]').length > 0) { return Swal.fire('系统提示', '暂不支持文件夹解析,请选择文件再解析', 'error'); } let serverPassword1 = 0; if (serverPassword1 === 1) { const result = await Swal.fire({ title: '输入解析密码', input: 'password', inputPlaceholder: '解析密码是为控制流量,希望理解', inputAttributes: { maxlength: 30, autocapitalize: 'off', autocorrect: 'off' } }); serverPassword1 = result.value; if (!password) { return Swal.fire('提示', '需要输入解析密码解析哦', 'info'); } } Swal.fire({ title: "正在获取下载链接...", confirmButtonText: '后台运行', allowOutsideClick: false, onBeforeOpen: Swal.showLoading }); try { const bdstoken = await getBdsToken(); if (!bdstoken) throw new Error("无法获取bdstoken参数"); const userInfo = await getUserInfo(); const shareResponse = await shareFiles(bdstoken, selectedIds); const shorturl = extractShortUrl(shareResponse.link); if (!shorturl) throw new Error("无法提取shorturl参数"); const wxlistResponse = await callWxlistApi(shorturl, password); const extractedData = extractWxlistData(wxlistResponse); if (!extractedData.randsk) throw new Error("无法提取 randsk参数"); const downloadLinks = await postToSaveApi(shareResponse.link, shorturl, extractedData, password); currentLinkIndex = 0; const showDownloadLink = () => { Swal.fire({ icon: 'success', title: '下载链接获取成功', html: `
下载链接:${downloadLinks[currentLinkIndex].substring(0, 50)}...
当前的UA: ${SCONFIG.config.ua}
`, showCancelButton: true, cancelButtonText: '取消', confirmButtonText: '复制当前下载链接', footer: ` ` }); document.getElementById("SendToAria2").addEventListener("click", () => { sendToAria2([downloadLinks[currentLinkIndex]], showDownloadLink); }); document.getElementById("SendToMotrix").addEventListener("click", () => { sendToMotrix([downloadLinks[currentLinkIndex]], showDownloadLink); }); document.getElementById("ChangeLink").addEventListener("click", () => { if (currentLinkIndex < downloadLinks.length - 1) { currentLinkIndex++; showDownloadLink(); } else { document.getElementById("ChangeLink").disabled = true; document.getElementById("ChangeLink").innerText = "没有更多下载链接"; } }); }; showDownloadLink(); } catch (error) { Swal.fire('错误', error.message || '处理过程中出现系统错误', 'error'); } }; function sendToAria2(downloadLinks, callback) { fetch("http://127.0.0.1:6800/jsonrpc", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", method: "aria2.addUri", id: Date.now(), params: [ `token:`, downloadLinks, { header: [`User-Agent: ${SCONFIG.config.ua}`] } ] }) }) .then(response => response.json()) .then(data => { if (data.error) { Swal.fire('失败', `Aria2推送失败!原因:${data.error.message || ''}`, 'error'); } else { Swal.fire('成功', 'Aria2推送成功!', 'success'); } callback(); }) .catch(error => console.error("Aria2 Error:", error)); } function sendToMotrix(downloadLinks, callback) { fetch("http://127.0.0.1:16800/jsonrpc", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", method: "aria2.addUri", id: Date.now(), params: [ `token:`, downloadLinks, { header: [`User-Agent: ${SCONFIG.config.ua}`] } ] }) }) .then(response => response.json()) .then(data => { if (data.error) { Swal.fire('失败', `Motrix推送失败!原因:${data.error.message || ''}`, 'error'); } else { Swal.fire('成功', 'Motrix推送成功!', 'success'); } callback(); }) .catch(error => console.error("Motrix Error:", error)); } async function initApp() { try { window.localStorage['jsonrpc'] = window.localStorage['jsonrpc'] || API_BASE_URL; window.localStorage['savePath'] = window.localStorage['savePath'] || SAVE_PATH; const SCONFIG = await init(); const userInfo = await getUserInfo(); window.userInfo = userInfo; window.SCONFIG = SCONFIG; AddElement(); } catch (error) { console.error("Initialization error:", error); } } function AddElement() { if (!document.getElementById("解析")) { const toolbar = document.querySelector("div.wp-s-agile-tool-bar__header"); if (toolbar) { const newButton = document.createElement("button"); newButton.id = "解析"; newButton.className = "u-button nd-file-list-toolbar-action-item u-button--primary"; newButton.style.marginRight = "8px"; newButton.style.backgroundColor = "red"; newButton.style.color = "white"; newButton.innerText = "解析"; toolbar.prepend(newButton); newButton.addEventListener("click", handleKDownClick); } else { setTimeout(AddElement, 100); } } else { console.log("解析 button already added."); } } initApp(); })();