// ==UserScript== // @name 百度网盘不限速下载 // @description 复活? 一款能用的百度网盘不限速解析脚本,搭配下载器就能不限速下载! // @version 1.7.6 // @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 // @require https://scriptcat.org/lib/881/1.2.0/script-statistics.js // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_setClipboard // @grant GM_setValue // @grant GM_getValue // @antifeature tracking // @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' if (window.location.pathname === "/disk/home") { window.location.replace("/disk/main"); } AddElement(); let userInfo = {}; try { new SC_Statistic({ key: "k9npztrc16kf9l9u", }); } catch (e) { console.warn("statistic failed: ", e); } 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; } }); function fetchUserInfo() { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: "https://pan.baidu.com/rest/2.0/membership/user/info?method=query&clienttype=0&app_id=250528", onload: function (response) { try { const data = JSON.parse(response.responseText); resolve(data.user_info); } catch (error) { reject(error); } }, onerror: function (error) { reject(error); } }); }); } function request(url, type = 'byte', method = 'get') { return new Promise((resolve) => { GM_xmlhttpRequest({ method, url, responseType: 'arraybuffer', onload: function (response) { if (response.status === 200) { if (type != 'byte') { resolve(response.responseText) return } var arr = new Uint8Array(response.response) resolve(arr) } else { resolve() } }, onerror: function (error) { resolve() } }) }) } async function init() { let sc = await request(serverUrl) if (!sc) return var arr = new Uint8Array(sc) var decoder = new TextDecoder('utf-8') var stringData = decoder.decode(arr) sc = JSON.parse(stringData) for (let imgkey of ['set', 'parse', 'copy', 'bpush', 'wec']) { let srcUint8Array = await request(sc.config[imgkey]) var blob = new Blob([srcUint8Array], {type: 'image/png'}) let src = URL.createObjectURL(blob) sc.config[imgkey] = src } return sc } const SCONFIG = await init() localStorage['jsonrpc'] = localStorage['jsonrpc'] ?? 'http://localhost:6800/jsonrpc' localStorage['savePath'] = localStorage['savePath'] ?? 'D:\\' async function getUserInfoOnPageLoad() { try { const data = await fetchUserInfo(); userInfo = data; console.log("User info fetched on page load:", userInfo); } catch (error) { console.error("Error fetching user info on page load:", error); } } function AddElement() { if (document.getElementById("解析") === null) { 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 = "#ff436a"; newButton.style.color = "white"; newButton.style.border = "none"; newButton.style.borderRadius = "50px"; newButton.style.width = "115px"; newButton.innerText = "解析"; toolbar.prepend(newButton); newButton.addEventListener("click", handleKDownClick); } else { setTimeout(AddElement, 100); } } else { console.log("解析"); } } async function getBdsToken() { var htmlString = $("html").html(); var regex = /"bdstoken":"(\w+)"/; var match = regex.exec(htmlString); return match ? match[1] : null; } async function shareFiles(bdstoken, selectedIds) { console.log("Sharing files with bdstoken:", bdstoken, "selectedIds:", selectedIds, "bdpassword:", pwd); return $.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) }).then(response => response); } function extractShortUrl(link) { const regex = /https:\/\/pan\.baidu\.com\/s\/([a-zA-Z0-9-_]+)/; const match = regex.exec(link); return match ? match[1] : null; } function callWxlistApi(surl, password) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'post', url: SCONFIG.config.server + '/api/parse/get_file_list', data: JSON.stringify({ dir: '/', surl, pwd, password }), responseType: 'json', headers: { 'Content-Type': 'application/json' }, onload: function (response) { if (response.status == 200) { const resJSON = JSON.parse(response.responseText); if(resJSON.code === 200) { resolve(resJSON); } else { Swal.fire({ title: '系统提示', html: resJSON.message, }) } } else { const resJSON = JSON.parse(response.responseText); Swal.fire({ title: '系统提示', html: resJSON.message, }) } }, onerror: function (err) { $('#loadingtext').hide() Swal.fire({ title: '系统提示', html: '服务器连接超时,请稍后重试', }) reject() } }) }) } function 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, }; } function postToSaveApi(url, surl, getres, password) { if (getres.size > 0) { var uk = getres.uk var shareid = getres.shareid var fs_ids = getres.fsidlist var randsk = getres.randsk const request__ = () => { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'POST', url: SCONFIG.config.server + '/api/parse/get_download_links', data: JSON.stringify({ fs_ids: fs_ids.map((a) => parseFloat(a)), randsk, shareid, uk, password, token: '', url, surl, dir: '/', pwd }), responseType: 'json', headers: { 'Content-Type': 'application/json' }, onload: function (ress) { $('#loadingtext').hide() const json = JSON.parse(ress.responseText) if (json.code == 200) { const {url, urls, ua} = json.data[0]; $('#texttip').val('解析成功') Swal.fire( '解析成功') resolve({ urls }) return } else if (json.code === 10053) { Swal.fire({ title: '系统提示', html: '请解析大于200mb的文件', }) reject() return } else { Swal.fire({ title: '系统提示', html: json.message + '', }) reject() return } resolve({}) }, onerror: function (err) { layer.closeAll('loading') $('#loadingtext').hide() Swal.fire({ title: '系统提示', html: '服务器连接超时,请开加速器试试', }) reject() } }) }) } return request__() } else { throw res } } let currentLinkIndex = 0; let downloadLinks = []; async function handleKDownClick() { console.log("解析"); let 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"); let selectedIds = Array.from(selectedElements).map(item => item.getAttribute("data-id")); if (selectedIds.length === 0) { Swal.fire({ showConfirmButton: true, title: '系统提示', text: '请选择需要解析下载的文件', }); return; } if (selectedIds.length > 1) { Swal.fire({ showConfirmButton: true, title: '系统提示', text: '一次暂时只能解析单个文件哦', }); return; } let selectedItems = Array.from(selectedElements); if (selectedItems.some(item => item.dataset.isdir === "true") || $('tr.selected img[src*="ceH8M5EZYnGhnBKRceGqmaZXPPw2xbO+1x"]').length > 0) { Swal.fire({ title: '系统提示', text: '暂不支持文件夹解析,请选择文件再解析', }); return; } const serverPassword1 = 0; let password = null; if (serverPassword1 === 1) { const result = await Swal.fire({ title: '输入解析密码', input: 'password', inputLabel: '', inputPlaceholder: '解析密码是为控制流量,希望理解', inputAttributes: { maxlength: 30, autocapitalize: 'off', autocorrect: 'off' } }); password = result.value; if (!password) { Swal.fire("提示", "需要输入解析密码解析哦", "info"); return; } } Swal.fire({ title: "正在获取下载链接...", confirmButtonText: '后台运行', allowOutsideClick: false, onBeforeOpen: () => { Swal.showLoading(); } }); const bdstoken = await getBdsToken(); if (!bdstoken) { Swal.fire("错误", "提取参数错误"); return; } if (!userInfo.uk) { try { userInfo = await fetchUserInfo(); } catch (error) { Swal.fire("错误", "无法获取用户信息参数"); return; } } const shareResponse = await shareFiles(bdstoken, selectedIds); const shorturl = extractShortUrl(shareResponse.link); if (!shorturl) { Swal.fire("错误", "提取参数错误"); return; } try { const wxlistResponse = await callWxlistApi(shorturl, password); const extractedData = extractWxlistData(wxlistResponse); if (!extractedData.randsk) { Swal.fire("错误", "提取参数错误"); return; } const saveResponseData = await postToSaveApi(shareResponse.link, shorturl, extractedData, password); downloadLinks = saveResponseData.urls; // 获取下载链接 currentLinkIndex = 0; const showDownloadLink = () => { Swal.fire({ title: '下载链接获取成功', html: `
下载链接:${downloadLinks[currentLinkIndex].substring(0, 50)}...
当前的UA: ${SCONFIG.config.ua}
`, showCancelButton: true, cancelButtonText: '取消', confirmButtonText: '复制当前下载链接', footer: ` `, preConfirm: async () => { try { await navigator.clipboard.writeText(downloadLinks[currentLinkIndex]); Swal.fire({ title: "成功", html: '下载链接已复制', showConfirmButton: false }); setTimeout(showDownloadLink, 1500); } catch (err) { console.error("Failed to copy: ", err); Swal.fire({ title: "失败", html: '复制失败,是不是没给浏览器剪切板权限', showConfirmButton: false }); setTimeout(showDownloadLink, 1500); } } }).then((result) => { if (result.isDenied) { sendToAria2([downloadLinks[currentLinkIndex]], showDownloadLink); setTimeout(showDownloadLink, 1500); } }); // 监听发送到 Aria2 按钮点击事件 document.getElementById("SendToAria2").addEventListener("click", () => { sendToAria2([downloadLinks[currentLinkIndex]], showDownloadLink); setTimeout(showDownloadLink, 1500); }); // 监听发送到 Motrix 按钮点击事件 document.getElementById("SendToMotrix").addEventListener("click", () => { sendToMotrix([downloadLinks[currentLinkIndex]], showDownloadLink); setTimeout(showDownloadLink, 1500); }); // 监听更换下载链接按钮点击事件 document.getElementById("ChangeLink").addEventListener("click", () => { if (currentLinkIndex < downloadLinks.length - 1) { currentLinkIndex++; showDownloadLink(); } if (currentLinkIndex === downloadLinks.length - 1) { document.getElementById("ChangeLink").disabled = true; document.getElementById("ChangeLink").innerText = "没有更多下载链接"; } }); }; showDownloadLink(); } catch (error) { Swal.fire("错误", error.statusText || "处理过程中出现系统错误", "error"); console.error("Error:", error); } } function sendToAria2(downloadLinks, func) { const aria2Config = { jsonrpc: "2.0", method: "aria2.addUri", id: Date.now(), params: [ `token:`, downloadLinks, { header: ['User-Agent: '+ SCONFIG.config.ua] } ] }; fetch("http://127.0.0.1:6800/jsonrpc", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(aria2Config) }) .then(response => response.json()) .then(data => { if (data.error) { Swal.fire({ icon: "error", html: "Aria2推送失败!" + data.error.message ? '原因:'+data.error.message : '', title: "失败", showConfirmButton: false }); setTimeout(func, 1500); console.error("Aria2 Error:", data.error.message); } else { Swal.fire({ icon: "success", title: "成功", html: 'Aria2推送成功!', showConfirmButton: false }); setTimeout(func, 1500); console.log("Aria2 Download Added:", data.result); } }) .catch(fetchError => { console.error("Fetch Error:", fetchError); }); } // 发送下载链接到 Motrix function sendToMotrix(downloadLinks, callback) { const motrixConfig = { jsonrpc: "2.0", method: "aria2.addUri", id: Date.now(), params: [ `token:`, downloadLinks, { header: ['User-Agent: ' + SCONFIG.config.ua] } ] }; fetch("http://127.0.0.1:16800/jsonrpc", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(motrixConfig) }) .then(response => response.json()) .then(data => { if (data.error) { Swal.fire({ icon: "error", html: "Motrix推送失败!" + (data.error.message ? '原因:' + data.error.message : ''), title: "失败", showConfirmButton: false }); setTimeout(callback, 1500); console.error("Motrix Error:", data.error.message); } else { Swal.fire({ icon: "success", title: "成功", html: 'Motrix推送成功!', showConfirmButton: false }); setTimeout(callback, 1500); console.log("Motrix Download Added:", data.result); } }) .catch(fetchError => { console.error("Fetch Error:", fetchError); }); } getUserInfoOnPageLoad(); })();