インストールの前に、Greasy Forkは、このスクリプトにアンチ機能が含まれることをお知らせします。これはあなたではなく、スクリプトの作者の利益を目的としてます。
このスクリプトは、何かに登録することでのみ完全な機能となります。例、グループへの参加、チャンネル登録、ページへの「いいね」など。
このスクリプトは作者に手数料を獲得させます。例えば、リンクの書き変えたりクーポンコードを提供する際に、紹介・アフィリエイト用のコードを含めます。
Greasy Fork is available in English.
复活版TT快下,加速?
// ==UserScript== // @name 【复活版】百度网盘不限速下载-TT快下 // @namespace https://wiki.tttt.ee // @description 复活版TT快下,加速? // @version 1.2.1 // @license MIT // @author MoTeam-Top、TT-down // @icon https://wiki.tttt.ee/logo.png // @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/* // @match *://yun.baidu.com/* // @match *://pan.baidu.com/disk/home* // @match *://yun.baidu.com/disk/home* // @match *://pan.baidu.com/disk/main* // @match *://yun.baidu.com/disk/main* // @match *://pan.baidu.com/s/* // @match *://yun.baidu.com/s/* // @match *://pan.baidu.com/share/* // @match *://yun.baidu.com/share/* // @connect moiu.cn // @connect jsdelivr.net // @connect baidu.com // @antifeature membership // @antifeature referral-link // ==/UserScript== (async () => { // 在页面加载时立即调用GetNotify函数 GetNotify(); if (window.location.pathname === "/disk/home") { window.location.replace("/disk/main"); } AddElement(); let filelistValue = ''; // 新增变量,用于保存从 save 接口返回的 to 值 // 添加一些自定义 CSS 来调整按钮样式 const style = document.createElement('style'); style.innerHTML = ` .swal2-cancel-button { margin-left: 10px; } `; document.head.appendChild(style); function GetNotify() { GM_xmlhttpRequest({ method: "GET", url: "https://api.moiu.cn/JavaScript/PaiPai/info_v2", onload: function(response) { try { const jsondata = JSON.parse(response.responseText); const { code, message, ua, gg, open, url, url_data } = jsondata; // 确保公告是打开状态 if (open === 1 && code === 200) { const showCancelButton = url_data === 'y'; Swal.fire({ icon: "info", title: gg, // 使用公告标题 text: message, // 使用公告信息 confirmButtonText: "关闭", showCancelButton: showCancelButton, // 根据 url_data 控制取消按钮的显示 cancelButtonText: "我要租号", cancelButtonColor: '#007bff', // 自定义取消按钮颜色 customClass: { cancelButton: 'swal2-cancel-button' // 自定义按钮类名 }, preConfirm: () => { // 这个函数在点击“关闭”时触发 console.log('关闭按钮被点击'); } }).then((result) => { if (result.dismiss === Swal.DismissReason.cancel) { // 点击“我要租号”按钮的行为 window.open(url, "_blank"); } }); } } catch (e) { console.error("Error fetching announcement:", e); } }, }); } // 存储用户信息 let userInfo = {}; // 获取用户信息 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); } }); }); } // 在页面加载完成后请求用户信息 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("TTDown") === null) { const toolbar = document.querySelector("div.wp-s-agile-tool-bar__header"); if (toolbar) { const newButton = document.createElement("button"); newButton.id = "TTDown"; newButton.className = "u-button nd-file-list-toolbar-action-item"; // 去掉原有的颜色类名 newButton.style.marginRight = "8px"; newButton.style.backgroundColor = "red"; // 设置背景颜色为红色 newButton.style.color = "white"; // 设置文字颜色为白色以便更好地显示 newButton.innerText = "TTDown"; toolbar.prepend(newButton); const statusButton = document.createElement("button"); statusButton.id = "TTDownStatus"; statusButton.className = "u-button nd-file-list-toolbar-action-item"; // 去掉原有的颜色类名 statusButton.style.marginRight = "8px"; statusButton.style.backgroundColor = "red"; // 设置背景颜色为红色 statusButton.style.color = "white"; // 设置文字颜色为白色以便更好地显示 statusButton.innerText = "TTDown Status"; toolbar.prepend(statusButton); newButton.addEventListener("click", handleTTDownClick); statusButton.addEventListener("click", handleTTDownStatusClick); } else { setTimeout(AddElement, 100); } } else { console.log("TTDown button already added."); } } async function getBdsToken() { var htmlString = $("html").html(); var regex = /"bdstoken":"(\w+)"/; var match = regex.exec(htmlString); console.log("bdstoken:", match ? match[1] : null); return match ? match[1] : null; } async function shareFiles(bdstoken, selectedIds) { const bdpassword = "7777"; console.log("Sharing files with bdstoken:", bdstoken, "selectedIds:", selectedIds, "bdpassword:", bdpassword); return $.post("https://pan.baidu.com/share/set?channel=chunlei&bdstoken=" + bdstoken, { period: 1, pwd: bdpassword, 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); console.log("Extracted short URL:", match ? match[1] : null); return match ? match[1] : null; } function callWxlistApi(shorturl, password) { console.log("Calling Wxlist API with shorturl:", shorturl, "password:", password); const bdpassword = "7777"; return new Promise((resolve, reject) => { const url = "https://api.moiu.cn/api/List"; const formParams = { "surl": shorturl, "dir": "/", "password": password, "pwd": bdpassword }; $.ajax({ type: "POST", url: url, data: formParams, success: function(response) { console.log("Wxlist API response:", response); resolve(response); }, error: function(xhr, status, error) { console.error("Error calling Wxlist API:", xhr, status, error); reject({ status: xhr.status, statusText: xhr.statusText }); } }); }); } function extractWxlistData(responseBody) { const data = responseBody.data; console.log("Extracted data from Wxlist response:", 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, // 提取第一个列表项的 size 属性 filename: data.list[0]?.server_filename || 0, // 提取第一个列表项的 size 属性 }; } function postToSaveApi(data, password, userid, shorturl) { const requestData = { fsidlist: String(data.list[0].fs_id), sekey: data.randsk, uk: data.uk, surl: shorturl, shareid: data.shareid, password, userid, size: data.size, filename: data.filename // 添加 filename 参数 }; console.log("Prepared request data for Save API:", requestData); return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "POST", url: "https://api.moiu.cn/api/Pai/parse", headers: { "Content-Type": "application/json" }, data: JSON.stringify(requestData), onload: function(response) { const responseData = JSON.parse(response.responseText); console.log("Save API response:", responseData); if (responseData.code !== 200) { Swal.fire("错误", responseData.message, "error"); reject({ status: response.status, statusText: responseData.message }); } else { resolve(responseData.data); // 直接返回data对象 } }, onerror: function(response) { const errorMessage = JSON.parse(response.responseText).message || '网络错误'; Swal.fire("错误", errorMessage, "error"); console.error("Error posting to Save API:", response); reject({ status: response.status, statusText: errorMessage }); } }); }); } let currentLinkIndex = 0; let downloadLinks = []; async function handleTTDownClick() { console.log("TTDown button clicked."); 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")); console.log("Selected elements:", selectedElements); console.log("Selected IDs:", selectedIds); if (selectedIds.length === 0) { Swal.fire({ showConfirmButton: true, title: '系统提示', text: '请选择需要下载的文件', icon: 'error' }); return; } if (selectedIds.length > 1) { Swal.fire({ showConfirmButton: true, title: '系统提示', text: '暂时只能下载一个文件', icon: 'error' }); 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: '请不要选择文件夹解析,因为还没学会.', icon: 'error' }); return; } const { value: requestType } = await Swal.fire({ title: '选择请求类型', html: ` <div> <input type="radio" id="cloud" name="requestType" value="cloud" checked> <label for="cloud">1号接口(全天稳定无法保证,有时可能加速正常)</label> </div> <div> <input type="radio" id="local" name="requestType" value="local"> <label for="local">2号接口(稳定,加速需要自带SVIP账号)</label> </div> `, showCancelButton: true, cancelButtonText: '取消', preConfirm: () => { const requestType = document.querySelector('input[name="requestType"]:checked').value; return requestType; } }); if (!requestType) { Swal.fire("提示", "您需要选择一个请求类型来继续", "info"); return; } const { value: password } = await Swal.fire({ title: '输入密码', input: 'password', inputLabel: '使用前请先关注公众号:冰箱喵 获取验证码吧!', inputPlaceholder: '密码为了控制流量,理解下', inputAttributes: { maxlength: 6, autocapitalize: 'off', autocorrect: 'off' } }); if (!password) { Swal.fire("提示", "需要密码来继续", "info"); return; } Swal.fire({ title: "正在获取下载链接...", onBeforeOpen: () => { Swal.showLoading(); } }); if (requestType === 'local') { try { const rootListResponse = await fetchBaiduRootFileList(); const rootFileList = rootListResponse.list; console.log("Baidu root file list response:", rootFileList); const myResourceFolderExists = rootFileList.some(file => file.path === "/我的资源"); if (!myResourceFolderExists) { Swal.fire({ title: '错误', text: '似乎你解析的文件没有放在 我的资源 文件夹,或者你根本没创建这个文件夹', icon: 'error' }); return; } let pathLocal; let filename; try { const listResponse = await fetchBaiduFileList(); const fileList = listResponse.list; console.log("Baidu file list response:", fileList); fileList.forEach(file => { if (selectedIds.includes(file.fs_id.toString())) { pathLocal = file.path; filename = file.server_filename; } }); if (!pathLocal || !filename) { Swal.fire("错误", "未找到匹配的文件或文件名", "error"); return; } console.log("Matched file path:", pathLocal); console.log("Matched file name:", filename); // 生成下载链接的请求 const bdstoken = await getBdsToken(); if (!bdstoken) { Swal.fire("错误", "无法获取bdstoken", "error"); return; } const queryParams = new URLSearchParams({ "target": JSON.stringify([pathLocal]), "dlink": 1, "channel": "chunlei", "web": 1, "app_id": 250528, "bdstoken": bdstoken, "logid": "QzBQUQORDY1N0E0QzMzNzEyRDDBNjZDZjc1NzJFQUY6Rkc9MQ%3D%3D", "clienttype": 0 }); const requestUrl = `https://pan.baidu.com/api/filemetas?${queryParams.toString()}`; // 发起请求以获取下载链接 const downloadLinkResponse = await fetch(requestUrl); const downloadLinkData = await downloadLinkResponse.json(); if (downloadLinkData.errno === 0) { console.log("Download link data:", downloadLinkData); const downloadLink = downloadLinkData.info[0].dlink; // 发送请求到 parse 接口 const parseResponse = await postToSaveApi({ filename, dlink: downloadLink }, password, userInfo.uk, shorturl); console.log("Parse API Response Data:", parseResponse); Swal.fire({ icon: 'success', title: '下载链接获取成功', html: `<a href="${downloadLink}" target="_blank">${downloadLink}</a>`, showCancelButton: true, cancelButtonText: '关闭', confirmButtonText: '复制链接', preConfirm: async () => { try { await navigator.clipboard.writeText(downloadLink); Swal.fire("已复制", "下载链接已复制到剪贴板", "success"); } catch (err) { console.error("Failed to copy: ", err); Swal.fire("复制失败", "无法将链接复制到剪贴板", "error"); } } }); } else { Swal.fire("错误", "无法获取下载链接", "error"); } } catch (error) { Swal.fire("错误", "无法获取文件列表", "error"); console.error("Error fetching file list:", error); return; } } catch (error) { Swal.fire("错误", "无法获取根目录文件列表", "error"); console.error("Error fetching root directory file list:", error); return; } } else { const bdstoken = await getBdsToken(); if (!bdstoken) { Swal.fire("错误", "无法获取bdstoken", "error"); return; } const shareResponse = await shareFiles(bdstoken, selectedIds); const shorturl = extractShortUrl(shareResponse.link); if (!shorturl) { Swal.fire("错误", "无法提取shorturl", "error"); return; } try { const wxlistResponse = await callWxlistApi(shorturl, password); const extractedData = extractWxlistData(wxlistResponse); console.log("Extracted Wxlist Data:", extractedData); if (!extractedData.randsk) { console.error("randsk is undefined in extracted data"); Swal.fire("错误", "无法提取 randsk", "error"); return; } const saveResponseData = await postToSaveApi(extractedData, password, userInfo.uk, shorturl); console.log("Save API Response Data:", saveResponseData); downloadLinks = [saveResponseData.dlink, ...saveResponseData.urls]; // 获取 dlink 和其他链接 currentLinkIndex = 0; const showDownloadLink = () => { Swal.fire({ icon: 'success', title: '下载链接获取成功', html: ` <div style="border: 1px solid #ddd; padding: 10px; margin-bottom: 10px;"> <a href="${downloadLinks[currentLinkIndex]}" target="_blank">下载链接:${downloadLinks[currentLinkIndex].substring(0, 50)}...</a> </div> <div style="border: 1px solid #ddd; padding: 10px; margin-top: 10px;">当前的UA: netdisk;P2SP;2.2.61.31;netdisk;10.0.183;android-android;ttdown</div> `, showCancelButton: true, cancelButtonText: '取消', confirmButtonText: '复制当前链接', showDenyButton: true, denyButtonText: '发送到 Aria2', footer: '<button id="ChangeLink" class="swal2-deny">换个下载链接</button>', preConfirm: async () => { try { await navigator.clipboard.writeText(downloadLinks[currentLinkIndex]); Swal.fire("已复制", "下载链接已复制到剪贴板", "success"); } catch (err) { console.error("Failed to copy: ", err); Swal.fire("复制失败", "无法将链接复制到剪贴板", "error"); } } }).then((result) => { if (result.isDenied) { sendToAria2([downloadLinks[currentLinkIndex]]); } }); 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) { const aria2Config = { jsonrpc: "2.0", method: "aria2.addUri", id: Date.now(), params: [ `token:`, downloadLinks, { header: ['User-Agent: netdisk;TTdown;svip'] } ] }; fetch("http://127.0.0.1:16800/jsonrpc", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(aria2Config) }) .then(response => response.json()) .then(data => { if (data.error) { console.error("Aria2 Error:", data.error.message); } else { console.log("Aria2 Download Added:", data.result); } }) .catch(fetchError => { console.error("Fetch Error:", fetchError); }); } async function handleTTDownStatusClick() { Swal.fire("检查中...", "正在检查服务器状态,请稍候...", "info"); GM_xmlhttpRequest({ method: "GET", url: "https://api.moiu.cn/JavaScript/users/status", onload: function(response) { try { const data = JSON.parse(response.responseText); const { code, message } = data; console.log("Server status response:", data); if (code === 200) { Swal.fire({ icon: "success", title: "服务器状态", text: message, }); } else if (code === 201) { Swal.fire({ icon: "error", title: "服务器状态", text: message, }); } else { Swal.fire({ icon: "warning", title: "服务器状态", text: "未知状态", }); } } catch (error) { Swal.fire("错误", "处理服务器响应时发生错误", "error"); console.error("Error handling server response:", error); } }, onerror: function(error) { Swal.fire("错误", "无法连接到服务器", "error"); console.error("Error connecting to server:", error); }, }); } // 获取百度网盘根目录文件列表 async function fetchBaiduRootFileList() { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: "https://pan.baidu.com/api/list?clienttype=0&app_id=250528&web=1&order=time&desc=1&dir=%2F&num=100&page=1", onload: function(response) { try { const data = JSON.parse(response.responseText); if (data.errno === 0) { resolve(data); } else { reject(new Error("API 返回错误: " + data.errno)); } } catch (error) { reject(error); } }, onerror: function(error) { reject(error); } }); }); } // 获取百度网盘文件列表 async function fetchBaiduFileList() { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: "https://pan.baidu.com/api/list?clienttype=0&app_id=250528&web=1&order=time&desc=1&dir=%2F%E6%88%91%E7%9A%84%E8%B5%84%E6%BA%90&num=100&page=1", onload: function(response) { try { const data = JSON.parse(response.responseText); if (data.errno === 0) { resolve(data); } else { reject(new Error("API 返回错误: " + data.errno)); } } catch (error) { reject(error); } }, onerror: function(error) { reject(error); } }); }); } // 在页面加载完成后请求用户信息 getUserInfoOnPageLoad(); })();