インストールの前に、Greasy Forkは、このスクリプトにアンチ機能が含まれることをお知らせします。これはあなたではなく、スクリプトの作者の利益を目的としてます。
このスクリプトは、何かに登録することでのみ完全な機能となります。例、グループへの参加、チャンネル登録、ページへの「いいね」など。
Greasy Fork is available in English.
一个纯净好用的百度网盘下载助手,绝无多余附加功能。免SVIP会员,免安装浏览器扩展,无视黑号,只要你有个IDM或Aria2,就能享受极速下载的快感!
// ==UserScript== // @name 神速Down // @namespace http://sswpdd.xyz/ // @version 3.2.1 // @antifeature membership // @description 一个纯净好用的百度网盘下载助手,绝无多余附加功能。免SVIP会员,免安装浏览器扩展,无视黑号,只要你有个IDM或Aria2,就能享受极速下载的快感! // @author SSDown // @icon http://sswpdd.xyz/ewm.jpg // @match *://pan.baidu.com/* // @match *://yun.baidu.com/* // @require https://lib.baomitu.com/jquery/3.6.0/jquery.js // @require https://lib.baomitu.com/sweetalert/2.1.2/sweetalert.min.js // @require https://lib.baomitu.com/clipboard.js/2.0.6/clipboard.min.js // @run-at document-idle // @grant unsafeWindow // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_openInTab // @grant GM_notification // @grant GM_xmlhttpRequest // @connect localhost // @connect 127.0.0.1 // @connect baidu.com // @connect sswpdd.xyz // ==/UserScript== (function () { 'use strict'; let globalData = { scriptVersion: '2.1.0', domain: '', domainB: '', param: '', downloading: 0, sending: 0, storageNamePrefix: 'SSD_storageName', // 本地储存名称前缀 } let getAppSettingData = function () { return { scriptVersion: globalData.scriptVersion, param: globalData.param, storageNamePrefix: globalData.storageNamePrefix, getDownloadUrl: `/bd/api.php`, } } let tmpData = { response: '', pwd: '', fs_id: '', token: '', } let configDefault = { savePath: 'D:\\SSDown', jsonRpc: 'http://localhost:6800/jsonrpc', token: '', mine: '', code: '', }; let getConfig = function () { // 上次使用 > 应用配置 > 代码默认 return { savePath: getStorage.getLastUse('savePath') || getStorage.getAppConfig('savePath') || configDefault.savePath, jsonRpc: getStorage.getLastUse('jsonRpc') || getStorage.getAppConfig('jsonRpc') || configDefault.jsonRpc, token: getStorage.getLastUse('token') || getStorage.getAppConfig('token') || configDefault.token, mine: getStorage.getLastUse('mine') || getStorage.getAppConfig('mine') || configDefault.mine, code: getStorage.getLastUse('code') || configDefault.code, } } let getStorage = { getAppConfig: (key) => { return GM_getValue(getAppSettingData().storageNamePrefix + '_app_' + key) || ''; }, setAppConfig: (key, value) => { GM_setValue(getAppSettingData().storageNamePrefix + '_app_' + key, value || ''); }, getLastUse: (key) => { return GM_getValue(getAppSettingData().storageNamePrefix + '_last_' + key) || ''; }, setLastUse: (key, value) => { GM_setValue(getAppSettingData().storageNamePrefix + '_last_' + key, value || ''); }, getCommonValue: (key) => { return GM_getValue(getAppSettingData().storageNamePrefix + '_common_' + key) || ''; }, setCommonValue: (key, value) => { GM_setValue(getAppSettingData().storageNamePrefix + '_common_' + key, value || ''); } } let uInfo = {}; let isOldHomePage = function () { let url = location.href; if (url.indexOf(".baidu.com/disk/home") > 0) { return true; } else { return false; } }; let isNewHomePage = function () { let url = location.href; if (url.indexOf(".baidu.com/disk/main") > 0) { return true; } else { return false; } }; let isSharePage = function () { let path = location.pathname.replace('/disk/', ''); if (/^\/(s|share)\//.test(path)) { return true; } else { return false; } } let getSelectedFileList = function () { let pageType = getPageType(); if (pageType === 'old') { return require('system-core:context/context.js').instanceForSystem.list.getSelected(); } if (pageType === 'new') { let mainList = document.querySelector('.nd-main-list'); if (!mainList) mainList = document.querySelector('.nd-new-main-list');//20220524 新版 return mainList.__vue__.selectedList; } }; let getFileListStat = function (fileList) { let fileStat = { file_num: 0, dir_num: 0 }; fileList.forEach(function (item) { if (item.isdir == 0) { fileStat.file_num++; } else { fileStat.dir_num++; } }); return fileStat; }; let initButtonEvent = function () { console.log('initButtonEvent初始化按钮事件'); let pageType = getPageType(); let yunData = getYunData(); if (!yunData && pageType != 'new') { showLogin(); return; } //暂时限制只能在管理页面中使用 if (pageType === 'share') { showTipErrorSwal('必须先转存到自己网盘中,然后进入网盘进行下载!'); console.log('必须先转存到自己网盘中'); showShareSave(); } else { let fileList = getSelectedFileList(); let fileStat = getFileListStat(fileList); if (fileList.length) { if (fileStat.file_num > 1 || fileStat.dir_num > 0) { showTipError('请选择一个文件进行下载(暂时不支持文件夹和多文件批量下载)') } if (fileStat.dir_num == 0 && fileStat.file_num == 1) { showDownloadDialog(fileList, fileStat); setShareCompleteState(); //自动下载 // getJquery()("#dialogBtnGetUrl").click(); } } else { showTipErrorSwal('请选择一个文件进行下载'); } } }; let getYunData = function () { return unsafeWindow.yunData; }; let showTipErrorSwal = function (err) { showSwal(err, {icon: 'error'}); } let showTipError = function (err) { // showSwal(err,{icon: 'error'}); alert(err); } let showTipInfo = function (info) { //getJquery()("#dialogOpTips").show().html(info); getJquery()("#dialogRemark").html(info); } let showTipInfoAria = function (info) { //getJquery()("#dialogOpTipsAria").show().html(info); getJquery()("#dialogBtnAria").contents().last()[0].textContent = info; } let showTipInfoIdm = function (info) { // getJquery()("#dialogOpTipsIdm").show().html(info); getJquery()("#dialogBtnIdm").contents().last()[0].textContent = info; } let showSwal = function (content, option) { divTips.innerHTML = content; option.content = divTips; if (!option.hasOwnProperty('button')) { option.button = '好! 我 知 道 了' } swal(option); } let getJquery = function () { // return require("base:widget/libs/jquerypacket.js"); return $; }; let showLogin = function () { require("base:widget/libs/jquerypacket.js")("[node-type='header-login-btn']").click(); }; let showShareSave = function () { require("base:widget/libs/jquerypacket.js")("[node-type='shareSave']").click(); }; let popup = function() { let t = getJquery()("#popup"); if (t.css("display") == "none") { t.show(); } else { t.hide(); } } //下载面板 let showDownloadDialog = function (fileList, fileStat) { let theFile = fileList[0]; console.log(theFile); let content = ` <div id="downloadDialog"> <div id="dialogTop"> 已选中的文件 ${CutString(theFile.server_filename, 35)} </div> <div id="dialogMiddle"> <div id="dialogLeft"> <div id="dialogQr"> <img id="dialogQrImg" src="http://sswpdd.xyz/ewm.jpg"> </div> <p class="title">扫一扫不失联</p> <div class="sub_title">发送</div><div><em class="emwz">免费白嫖</em></div><br<div class="emwtl" style=" color: initial; font-size: 20px; caret-color:transparent; ">四个字获取暗号/无套路</br<div> <div id="gearIcon"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAh9JREFUWEfFl9FRxDAMRHWdQCVAJUAlQCUclUAn0AnMy3gzwmfJTpyZy89dEltaSauVc7IrX6cr+7ctAJ7M7NHM3szsKwB+b2YvZvZR1vz0AhwBgON3M8MYjrk/FyBycFPAvZZ3AOHZc7kPcfQAfJoZxjBM5FzcAwgH/gIMDpUd1rBWz5vZyACQSqJ9KEZaUchBlGqBVcYubGQAFCUAZq5vV7JNAIieLNzOeDez34wLIyWYBbA7AyD35NubCHGpGUiUATbhnE0tgqntPAnp/dbalIgtAHIO+VqCo/dkBIdqR/5HbNeeC13wAHx/RwIiQwDz3eGFKCqbSgFQsgXYVYoxAFkwjPOor+FF7dxzA+HCVqQdBImc02FLeZUBXrA56wpJcsQLgCiQngQTyFJiORzpeYSJdT35TtuupIs1SPvZA8DBEbrgSxm17ipOdQmy9KpMUXeMlkBl+lcCGc9I6IkazQdNzygQnRf4XYL3KVeb4ChqJRERoP5gwh6N32ivOITflaSZEGX9zLtaiLjv7aH3cb5eM1JMGu9K65GRSIpVugvndQlqxo6008iA2jWMMHzUgQRiijObDiQp8pHQa9Fp7TlCeHpYdh9I1FbRYIFc/jwQnQUoQXiwyTKAA003/x0weiyXKGXTsztYREZ9aGCM/2q7ZaaXZ3CGdzxDsDJd6OpAXVfNcX79x0e9TsQV6w/5NOuRbOp9b7ZPGR/Z/AfzOqohK4HohwAAAABJRU5ErkJggg==" alt="Settings"> </div> <div id="popup" class="hidden"> <div id="closeButton">X</div> <div class="content"> <div id="dialogDivSavePath"> <span> 保存路径:</span><input type="text" id="dialogTxtSavePath" value="D:\SSDown" style="width: 170px;"><br> <span id="dialogAriaConfigClick">配置Aria2/Motrix>></span> <div id="dialogAriaConfig"> <input type="text" id="dialogAriaRPC" value="http://localhost:6800/jsonrpc" title="RPC地址" placeholder="RPC地址" style="width: 100%;"> <input type="text" id="dialogAriaToken" value="" title="token" placeholder="token" style="width: 77px;"> <br> <input type="checkbox" id="dialogAriaMine" value="checked"> <span>使用自己的Aria2/Motrix(如不懂,勿勾选)</span> <span class="bcsp">Motrix默认地址:</span><span>http://localhost:16800/jsonrpc </span> <br> <span class="bcsp">Aria2默认地址:</span><span> http://localhost:6800/jsonrpc </span> </div> </div> </div> </div> </div> <div id="dialogRight"> <div id="dialogContent"> <div id="tipp"> <div class="block1"> <p class="titleidmair">IDM</p> <p class="sub_titledown">选项 -> 下载 -> 手动添加任务时使用的用户代理(UA)-> 填入 LogStatistic。在 IDM 新建任务,粘贴链接即可下载。</p> <a id="" class="btnInterfaceidmyc" style="display: inline;"></a> <a id="dialogBtnIdm" data-clipboard-text="" class="btnInterface">复制链接</a> </div> <hr class="hrfg"> <div class="block2"><p class="titleidmair">Air2/Motrix</p> <p class="sub_titledown2">点击 推送到 Aria2将自动下载,使用Motrix要在设置里修改配置,支持Windows/Android。</p> <a id="" class="btnInterfaceairyc"></a> <a id="dialogBtnAria" class="btnInterface">推送Air2</a> </div> </div> <div id="dialogOpButtons"> <div id="dialogOpTipsAria"></div> </div> </div> <div id="dialogBottomss"> <div style="background: #FFF; padding: 6px 14px; border-radius: 8px;flex: 7;"> <div id="dialogRemark"> 下载速度因人而异,特别是共享网络(例如 校园网) </div> <div id="dialogVaptchaCode"> <div id="dialogVaptchaCodeInput"> <span id="dialogVaptchaCodeTips"></span> <input id="dialogCode" placeholder="请输入暗号..." type="text" value="${getConfig().code}" /> </div> </div> </div> <button id="dialogBtnGetUrl" class="btnInterfacess"> <svg class="css-i6dzq1" stroke-linejoin="round" stroke-linecap="round" fill="none" stroke-width="2" stroke="currentColor" height="64" width="24" viewBox="2 0 19 24"> <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon> </svg> 解析</button> </div> </div> </div> <div id="dialogClear"></div> </div> `; showSwal(content, { button: 'X', closeOnClickOutside: false }); //分享(入口 ) let dialogBtnClick = function () { if (globalData.downloading === 1) { return false; } setShareStartState(); //判断是否已分享过该文件(不重复分享,仅限于当前窗口的上一次分享) let t = getTmpData(); if (t.response && t.fs_id == theFile.fs_id) { console.warn('已分享过此文件,不再重复分享'); getDownloadUrl(t.response, t.pwd, t.fs_id, ''); return; } else { console.info('未分享过此文件,开始分享'); } //获取数据 let bdstoken = '';//unsafeWindow.locals.get('bdstoken'); let pwd = getRndPwd(4); //+=================================== //分享 let details = { method: 'POST', responseType: 'json', timeout: 10000, // 10秒超时 url: `/share/set?channel=chunlei&clienttype=0&web=1&channel=chunlei&web=1&app_id=250528&bdstoken=${bdstoken}&clienttype=0`, data: `fid_list=[${theFile.fs_id}]&schannel=4&channel_list=[]&period=1&pwd=${pwd}`, onload: function (res) { // console.log('分享文件时,百度返回:', res); if (res.status === 200) { switch (res.response.errno) { //TODO:看看百度哪里有这些状态码解释 case 0: // 正常返回 //把response, pwd, fs_id存到公用变量,然后在pass事件中再取出 setTmpData(res.response, pwd, theFile.fs_id, ''); getDownloadUrl(res.response, pwd, theFile.fs_id, ''); break; case 110: showTipInfo('发生错误!') showTipError('百度说:您今天分享太多了,24小时后再试吧!\n百度返回状态码:' + res.response.errno); setShareCompleteState(); console.error(res); break; case 115: showTipInfo('发生错误!') showTipError('百度说:该文件禁止分享!\n百度返回状态码:' + res.response.errno); setShareCompleteState(); console.error(res); break; case -6: showTipInfo('发生错误!') showTipError('百度说:请重新登录!\n百度返回状态码:' + res.response.errno); setShareCompleteState(); console.error(res); break; default: // 其它错误 showTipInfo('发生错误!') showTipError('分享文件失败,请重试!\n百度返回状态码:' + res.response.errno + '\n使用百度分享按钮试试,就知道具体原因了。'); setShareCompleteState(); console.error(res); break; } } else { showTipInfo('发生错误') showTipError('分享文件失败,导致无法获取直链下载地址!\n百度返回:' + res.responseText); setShareCompleteState(); console.error(res); } }, ontimeout: (res) => { showTipInfo('发生错误') showTipError('分享文件时连接百度接口超时,请重试!'); setShareCompleteState(); console.error(res); }, onerror: (res) => { showTipInfo('发生错误') showTipError('分享文件时发生错误,请重试!'); setShareCompleteState(); console.error(res); } }; try { GM_xmlhttpRequest(details); } catch (error) { showTipInfo('发生错误') showTipError('未知错误,请重试!'); setShareCompleteState(); console.error(error); } }; //绑定按钮点击(点击获取直链地址) getJquery()("#dialogBtnGetUrl").click(function () { dialogBtnClick() }); //点击配置Aria2 getJquery()("#gearIcon").click(function () { popup() }); getJquery()("#closeButton").click(function () { popup() }); //点击配置Aria2 getJquery()("#dialogAriaConfigClick").click(function () { showAriaConfig() }); // 绑定点击复制事件 copyUrl2Clipboard(); }; //请求备用参数 let getParams = function () { let hkUrl = "https://pan.baidu.com/pcloud/user/getinfo?query_uk="; // let hkUrl = "http://localhost:48818/bd/getinfo.php?query_uk=1573827667"; let details = { method: 'GET', timeout: 10000, // 10秒超时 url: hkUrl + '&' + new Date().getTime(), responseType: 'json', onload: function (res) { if (res.status === 200) { globalData.domainB = res.response.user_info.intro; // console.info("domainB:" + globalData.domainB); } else { console.error(res); } } }; try { GM_xmlhttpRequest(details); } catch (error) { console.error(error); } } let getUInfo = function () { let url = "https://pan.baidu.com/rest/2.0/xpan/nas?method=uinfo"; let details = { method: 'GET', timeout: 10000, // 10秒超时 url: url + '&' + new Date().getTime(), responseType: 'json', onload: function (res) { if (res.status === 200) { uInfo = res.response; } else { console.error(res); } } }; try { GM_xmlhttpRequest(details); } catch (error) { console.error(error); } } let setShareStartState = function () { globalData.downloading = 1; showTipInfo('正在分享文件...') //保存用户输入的数据 saveLastUseData(); getJquery()('#dialogVaptchaCode').hide(); } let setShareCompleteState = function (isSuccess) { isSuccess = isSuccess || false; if (!isSuccess) { //失败之后,允许重复点击按钮 globalData.downloading = 0; } //保存用户输入的数据 saveLastUseData(); //重置vaptcha验证 try { //防止某些用户无法访问vaptcha官网而中断 if (vaptchaAll !== null && vaptchaAll.hasOwnProperty("reset")) { vaptchaAll.reset(); } else { console.warn("vaptchaAll is undefined"); } } catch (error) { console.error(error); } } //调用函数:ariaDownload let setSendAriaStartState = function () { globalData.sending = 1; showTipInfoAria('正在推送'); // getJquery()("#dialogBtnAria").val('正在推送'); //保存用户输入的数据 saveLastUseData(); } let setSendAriaCompleteState = function (isSuccess) { globalData.sending = 0; if (isSuccess) { getJquery()("#dialogBtnAria").val('Aria2已经开始下载了'); // showTipInfoAria('Aria2已经开始下载了'); } else { getJquery()("#dialogBtnAria").val('发送至Aria2'); // showTipInfoAria('推送成功'); } //保存用户输入的数据 saveLastUseData(); } let showAriaConfig = function () { let t = getJquery()("#dialogAriaConfig"); if (t.css("display") == "none") { t.show(); } else { t.hide(); } } //分享成功后,开始手势验证 let vaptchaValidate = function () { loadVaptchaSdk(function () { vaptcha({ vid: "5fc5252656181ea89f9ead2e", // 验证单元id type: "invisible", // 显示类型 隐藏式 scene: 1, // 场景值 默认0 offline_server: "", //离线模式服务端地址,若尚未配置离线模式,请填写任意地址即可。 }).then(function (vaptchaObj) { vaptchaAll = vaptchaObj; //将VAPTCHA验证实例保存到全局变量中 console.log(vaptchaAll); //验证通过时触发 vaptchaAll.listen("pass", function () { // 验证成功进行后续操作 let token = vaptchaAll.getToken(); console.log(token); let t = getTmpData(); getDownloadUrl(t.response, t.pwd, t.fs_id, token); }); //关闭验证弹窗时触发 vaptchaAll.listen("close", function () { showTipInfo('通过验证才可以取直链!点击上面按钮重新开始。'); setShareCompleteState() }); //开始手势验证 vaptchaAll.validate(); }); }); } let setTmpData = function (response, pwd, fs_id, token) { tmpData.response = response; tmpData.pwd = pwd; tmpData.fs_id = fs_id; tmpData.token = token; } let getTmpData = function () { return tmpData; } //查询接口地址-->发起服务器请求 let getDownloadUrl = function (response, pwd, fsid, token) { let code=getJquery()('#dialogCode').val().trim(); let bdUrl = "http://sswpdd.xyz/parse/list"; console.log("response",response) let shareid = response.link.split('/').slice(-1)[0]; let details = { method: 'POST', timeout: 10000, // 10秒超时 url: bdUrl, data:"surl="+ shareid+"&pwd="+pwd+"&password="+code, responseType: 'json', headers: { "Content-Type": "application/x-www-form-urlencoded" }, onload: function (res) { try { showTipInfo('正在查询服务器接口地址...'); // console.log(res); if (res.status === 200) { if(res.response.error == 101){ setShareCompleteState(); showTipInfo(res.response.err); getJquery()('#dialogVaptchaCode').show(); showQrTips(res.response); }else if (res.response.error == 0) { var data_ = res.response.dirdata var data__ = res.response.filedata[0] GM_xmlhttpRequest({ method: "POST", url: "http://sswpdd.xyz/parse/link", data:"fs_id="+data__.fs_id+"×tamp="+data_.timestamp+"&sign="+data_.sign+"&randsk="+data_.randsk+"&shareid="+data_.shareid+"&surl="+data_.surl+"&pwd="+data_.pwd+"&uk="+data_.uk, responseType: 'json', headers: { "Content-Type": "application/x-www-form-urlencoded" }, onload: function (ress) { if(ress.response.error == 0){ let downlink = ress.response; setShareCompleteState(true); changeClickEvent(downlink); saveStartState(); showQrTips(downlink); } else { showTipInfo('发生错误') showTipError('请求直链下载地址失败!服务器返回:' + res.response.status); } } }); } else { throw res; } } else { throw res; } } catch (error) { console.error(error); showTipInfo('发生错误') showTipError('请求直链下载地址失败!服务器返回:' + res.response.status); } } }; try { GM_xmlhttpRequest(details); } catch (error) { console.error(error); showTipInfo('发生错误') showTipError('请求直链下载地址失败!服务器返回:' + res.response.status); } } //请求直链成功后,改变按钮点击事件 let changeClickEvent = function (res) { //显示操作按钮 getJquery()("#dialogOpButtons").show(); getJquery()("#dialogDivSavePath").show(); getJquery()("#dialogBtnIdm").show(); getJquery()("#dialogBtnAria").show(); //if (res.error == 0) { //正常返回:复制直链下载地址 showTipInfo('获取地址成功,请选择下载方式。'); let url = res.directlink; getJquery()("#dialogBtnIdm").attr("data-clipboard-text", url); // } else { //Aria2 下载提示(隐藏idm下载按钮) // showTipInfo(res.err); // getJquery()("#dialogBtnIdm").hide(); getJquery()("#dialogOpTipsIdm").hide(); // } //发送至Aria2 let btnAria2 = getJquery()("#dialogBtnAria"); btnAria2.unbind(); btnAria2.click(function () { ariaDownload(res); }); } //请求直链成功后,tips let showQrTips = function (res) { let qrImg = getJquery().trim(res.qrImg); let qrTips = getJquery().trim(res.qrTips); let codeTips = getJquery().trim(res.codeTips); let codeRemark = getJquery().trim(res.codeRemark); //console.log(qrImg, qrTips); if (qrImg.length > 0) { getJquery()("#dialogQrImg").attr('src', qrImg); } if (qrTips.length > 0) { getJquery()("#dialogBottom").html(qrTips); } if (codeTips.length > 0) { getJquery()("#dialogVaptchaCodeTips").html(codeTips).show(); } if (codeRemark.length > 0) { getJquery()("#dialogCodeRemark").html(codeRemark).show(); } } //请求直链成功后,xxxx let saveStartState = function (res) { let start = getStorage.getCommonValue('start'); if (start) return; start = new Date().getTime(); getStorage.setCommonValue('start', start); } //发送至aria2 let ariaDownload = function (response) { let rpcDir = (getJquery()("#dialogTxtSavePath").val()).replace(/\\/g, '/'); let rpcUrl = getJquery()("#dialogAriaRPC").val(); let rpcToken = getJquery()("#dialogAriaToken").val(); //使用自己的Aria2 if (getConfig().mine == "checked") { delete response.aria2info.params[2].dir; // delete response.aria2info.params[2]['max-connection-per-server']; // delete response.aria2info.params[2].split; // delete response.aria2info.params[2]['piece-length']; } var dd = { "id":"shensuDown", "jsonrpc": "2.0", "method": "aria2.addUri", "params":[ [ response.directlink ], { "max-connection-per-server":16, "dir":rpcDir, "out":response.filedata.filename, "user-agent": "LogStatistic" } ] } let data = JSON.stringify(dd); // let data = {directlink:response}; // data = data.replace('{{{rpcDir}}}', rpcDir).replace('{{{rpcToken}}}', rpcToken); //发送至aria2 let details = { method: 'POST', responseType: 'json', timeout: 3000, // 3秒超时 url: rpcUrl, data: data, onloadstart: function () { setSendAriaStartState(); }, onload: function (res) { console.log('发送至Aria2,返回:', res); if (res.status === 200) { if (res.response.result) { // 正常返回 setSendAriaCompleteState(true); showTipInfoAria('推送成功'); } else { // 其它错误 showTipInfoAria('发生错误') showTipError(res.response.message); setSendAriaCompleteState(false); } } else { showTipInfoAria('发生错误') showTipError('发送至Aria2失败!<br />服务器返回:' + res.responseText); setSendAriaCompleteState(false); console.error(res); } }, ontimeout: (res) => { showTipInfoAria('发生错误') showTipError('连接到RPC服务器超时:请检查Aria2是否已连接,RPC配置是否正确!'); setSendAriaCompleteState(false); console.error(res); }, onerror: (res) => { showTipInfoAria('发生错误') showTipError('发送至Aria2时发生错误,请重试!'); setSendAriaCompleteState(false); console.error(res); } }; try { GM_xmlhttpRequest(details); } catch (error) { showTipInfoAria('发生错误') showTipError('发送至Aria2时发生未知错误,请重试!'); setSendAriaCompleteState(false); console.error(error); } } //保存用户输入的数据(下次当默认值使用) let saveLastUseData = function () { getStorage.setLastUse('savePath', getJquery()("#dialogTxtSavePath").val()); getStorage.setLastUse('jsonRpc', getJquery()("#dialogAriaRPC").val()); getStorage.setLastUse('token', getJquery()("#dialogAriaToken").val()); let mine = ""; if (getJquery()("#dialogAriaMine").prop("checked") == true) { mine = "checked"; } getStorage.setLastUse('mine', mine); getStorage.setLastUse('code', getJquery()("#dialogCode").val()); } //复制直链下载地址 let copyUrl2Clipboard = function () { let copyBtn = new ClipboardJS('#dialogBtnIdm') copyBtn.on("success", function (e) { // 复制成功(右键下载不好使,别再尝试了) showTipInfoIdm(`复制成功`) }); } //========================================= 公共函数 function CutString(str, len, suffix) { if (!str) return ""; if (len <= 0) return ""; if (!suffix) suffix = "..."; let templen = 0; for (let i = 0; i < str.length; i++) { if (str.charCodeAt(i) > 255) { templen += 2; } else { templen++ } if (templen == len) { return str.substring(0, i + 1) + suffix; } else if (templen > len) { return str.substring(0, i) + suffix; } } return str; } function getRndPwd(len) { len = len || 4; let $chars = 'AEJPTZaejptz258'; let maxPos = $chars.length; let pwd = ''; for (let i = 0; i < len; i++) { pwd += $chars.charAt(Math.floor(Math.random() * maxPos)); } return pwd; } function checkVsite() { let vDomain = document.domain.split('.').slice(-2).join('.'); if (vDomain == 'vaptcha.com') return true; return false; } // 延迟执行,否则找不到对应的按钮 let sleep = function (time) { return new Promise((resolve) => setTimeout(resolve, time)); }; /** * 已知前后文 取中间文本 * @param str 全文 * @param start 前文 * @param end 后文 * @returns 中间文本 || null */ let getMidStr = function (str, start, end) { let res = str.match(new RegExp(`${start}(.*?)${end}`)) return res ? res[1] : null } let getPageType = function () { if (isOldHomePage()) return 'old'; if (isNewHomePage()) return 'new'; if (isSharePage()) return 'share'; return ''; } //========================================= css GM_addStyle(` .swal-modal { min-width: 834px; background: #0162b0; } .swal-modal input { border: 1px grey solid; } #downloadDialog{ width: 800px; margin-left: 29px; font-size:14px; } #dialogTop{ margin: 21px 0; color: #fff; font-size: 25px; margin-left: -41px; caret-color: transparent; } #dialogFileName{ color: blue; text-decoration:underline; } #dialogMiddle{ height: 490px; display: flex; } #dialogLeftTips{ text-align: left; margin: 0 0 10px 0px; color: #4c4433; font-size: 13px; } #dialogRight{ width: 384px; margin-left: 22px; display: flex; flex-direction: column; justify-content: space-between; } #dialogContent{ background: #ffffff; padding: 10px; border-radius: 10px; height: 83%; border: rgba(0,0,0,.3) 0.5px solid; box-shadow: 0 12px 25px rgb(114 150 192 / 40%); } #dialogContent input{ vertical-align: middle; } #dialogRemark{ text-align: left; font-size: 16px; color: rgba(0,0,0,.6); caret-color: transparent; } #dialogVaptchaCode{ display: none; text-align: left; margin-top: 5px; font-size: 12px; } #dialogVaptchaCodeInput{ font-size: 14px; } .sub_titledown2 { width: 308px; font-size: 15px; line-height: 25px; font-weight: 400; color: rgba(0,0,0,.6); margin-top: 5px; margin-left: 22px; text-align: left; margin-bottom: 3px; caret-color: transparent; } #dialogCodeRemark{} #dialogQr{ display: flex; align-items: center; justify-content: center; height: 280px; margin-top: 29px; margin-bottom: 20px; caret-color: transparent; } #dialogQr img{ max-width: 100%; max-height: 100%; } #dialogClear{ clear: both; } #dialogBottomss{ display: flex; margin-top: 11px; height: 23%; } #dialogBtnIdm,#dialogBtnAria{ display: none; } .btnInterface { display: flex; justify-content: center; align-items: center; width: 90%; height: 40px; margin-top: 12px; background-color: #fff; border: #205aef 2px solid; border-radius: 8px; color: #205aef; font-size: 22px; line-height: 30px; font-weight: 400; cursor: pointer; line-height: 1; text-decoration: none; display: inline-flex; align-items: center; padding: .35rem 1.5rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: background-color } .btnInterfaceidmyc { height: 40px; margin-top: 12px; border-radius: 8px; color: #205aef; font-size: 22px; line-height: 30px; font-weight: 400; cursor: pointer; line-height: 1; text-decoration: none; display: inline-flex; align-items: center; padding: .35rem 1.5rem; white-space: nowrap; overflow: hidden; margin-left:-226px; text-overflow: ellipsis; transition: background-color caret-color: transparent; } .btnInterfaceairyc { height: 40px; margin-top: 12px; border-radius: 8px; color: #205aef; font-size: 22px; line-height: 30px; font-weight: 400; cursor: pointer; line-height: 1; text-decoration: none; display: inline-flex; align-items: center; padding: .35rem 1.5rem; white-space: nowrap; overflow: hidden; margin-left: -235px; text-overflow: ellipsis; transition: background-color; caret-color: transparent; } .button__icon-wrapper { flex-shrink: 0; width: 25px; height: 25px; position: relative; color: var(--clr); background-color: #fff; border-radius: 50%; display: grid; place-items: center; overflow: hidden; } .btnInterfacess { width: 100%; align-items: center; justify-content: center; gap: 2px; font-family: inherit; font-size: 26px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.8px; color: #ffffff; background-color: #ff5f5f; border-style: none; border-radius: 8px; transition: 0.2s; box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); cursor: pointer; margin-left: 10px; flex: 3; } #dialogDivSavePath{ text-align: left; line-height: 21px; position: absolute; padding: 15px; color:rgba(0,0,0,.86); } #dialogOpButtons{ display: none; } #dialogBtnIdm, #dialogBtnAria{ margin-top: 15px; } #dialogAriaConfig{ display: none; margin-top: 2px; } #dialogAriaConfigClick{ color: #0098EA; text-decoration: underline; cursor:pointer; font-size: 13px; caret-color: transparent; } #dialogAriaConfig{ font-size: 12px; } #dialogLeft{ background: #fff; border-radius: 10px; width: 338px; box-shadow: 0 12px 25px rgb(114 150 192 / 40%); border: rgba(0,0,0,.3) 0.5px solid; position: relative; } .swal-footer{ margin-top: 3px; } .jiaochengbtn{ background-color: #fff; padding: 10px 24px; margin: 0; cursor: pointer; border-radius: 4px; transition: .3s; border: 1px solid #666;; color: #666; font-weight: 100; margin-right: 10px; } .jiaochengbtn:last-child { margin-right: 0; } #todayText { position: absolute; bottom: 0; left: 0; padding: 8px; } #dateSpan { position: absolute; bottom: 0; right: 0; padding: 8px; } .tooltip:hover .tooltiptext, .tooltip .tooltiptext:hover { visibility: visible; opacity: 1; } .tooltip { position: relative; display: inline-block; } .tooltip .tooltiptext { visibility: hidden; width: 120px; background-color: black; color: #fff; text-align: center; border-radius: 5px; padding: 5px 0; position: absolute; z-index: 1; bottom: 125%; left: 50%; margin-left: -60px; opacity: 0; transition: opacity 0.3s; } .tooltip .tooltiptext a { color: #fff; text-decoration: none; } .tooltip .tooltiptext::after { content: " "; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: black transparent transparent transparent; } .tooltip:hover .tooltiptext, .tooltip .tooltiptext:hover { visibility: visible; opacity: 1; } .swal-button { background-color: #ff436a; color: #fff; border: none; box-shadow: none; border-radius: 5px; font-weight: 600; font-size: 13px; padding: 8px 11px; margin: 0; cursor: pointer; border: #fff 0.5px solid; margin-top:-1090px; } #englishText { position: absolute; top: 0; left: 0; padding: 10px; font-size: 10px; color: #fff; border-bottom-right-radius: 8px; } #cornerMark { position: absolute; top: 8px; right: 10px; width: 15px; height: 15px; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAVVJREFUWEftlWsSATEQhHtu4iicBCfBSayT4CTcZFSTqCSbl1TWVin5S6a/7p2ZCGY+MrM+/gC/k4CqLgHcReT+SV91S0BVNwCOALYiMtRCTAFA7YsBKaYxFQAhKH4opdEFwMS/BsA+CA8/B0GiaTQDmKazoovCN6c4e4OfxjsfAxjhXcJtqff2AE5uGtUAqkqX7PJYzCVh93evQasAVJWOSd/zvNLIVezoOiUzJAGM+K2n5aDWICLbKMAXxFd2IkYAE4uPNqQHMLH4XkQO2T2gqueGMXOXS2xEk0uIMO8EzIIhQO5wrV752ISr1XkN3fvPRssVfAJkoqe7U0wwLBoAZF27dy1AuGjolCtztLtTbhwAprOqHV8LwHnnqqUgX65qYStkAFB6fkdN6MQf7dJaJ63/E7Pnry2uW0W9HmD3zyXujWEPNy01qp7jlsK1d/4AsyfwAITij9pLkORkAAAAAElFTkSuQmCC'); background-size: cover; border-bottom-left-radius: 8px; } .btnInterfacess:hover { background-color: #ff3b3b; box-shadow: 0px 6px 8px rgba(0, 0, 0, 0.2); } .btnInterfacess:active { transform: scale(0.95); box-shadow: none; } #dialogCode{ --input-focus: #2d8cf0; --font-color: #323232; --font-color-sub: #666; --bg-color: #fff; --main-color: #323232; width: 200px; height: 34px; border-radius: 5px; border: 2px solid var(--main-color); background-color: var(--bg-color); box-shadow: 4px 4px var(--main-color); font-size: 15px; font-weight: 600; color: var(--font-color); padding: 5px 10px; outline: none; } #dialogCode::placeholder { color: var(--font-color-sub); opacity: 0.8; } #dialogCode:focus { border: 2px solid var(--input-focus); } .title { font-size: 31px; line-height: 66px; font-weight: 600; color: #242424; margin-top: -19px; margin-bottom: 0; caret-color: transparent; } .sub_title { margin-left:-89px; font-family:segoe-vf, sans-serif; line-height:46px; font-size:20px; box-sizing:border-box; color: initial; caret-color: transparent; } .block1 { position: relative; margin-bottom: 25px; margin-top: 0px; caret-color: transparent; } .block2 { position: relative; margin-bottom: 25px; margin-top: 26px; caret-color: transparent; } .titleidmair { font-size: 38px; line-height: 36px; font-weight: 600; color: rgba(0,0,0,.86); margin-top: 20px; margin-left: 21px; text-align: left; caret-color: transparent; } .sub_titledown { width: 308px; font-size: 15px; line-height: 25px; font-weight: 400; color: rgba(0,0,0,.6); margin-top: 5px; margin-left: 22px; text-align: left; margin-bottom: 18px; caret-color: transparent; } .tipp{ margin-top: -11px; } hr.hrfg { width: 320px; height: 1.8px; background-color: rgba(0,0,0,.3); margin: 20px; caret-color: transparent; } #gearIcon { position: absolute; right: 0; bottom: 0; cursor: pointer; padding: 14px; caret-color: transparent; } #popup { width: 300px; height: 180px; position: absolute; right: 17px; bottom: 58px; border: 1px solid #000; background-color: #fff; display: none; } #closeButton { cursor: pointer; position: absolute; right: 0; top: 0; padding: 5px; } .hidden { display: none; } div#divTips{ font-size: 25px; color:#fff; margin-top:25px; } .bcsp{ color: rgba(0,0,0,.86); font-size: 13px; font-weight: 800; } .emwz { float: inline-end; font-family: segoe-vf, sans-serif; -webkit-background-clip: text; background-image: linear-gradient(90deg, rgb(114, 9, 212), rgb(40, 50, 212) 33%, rgb(0, 165, 178)); color: rgba(0, 0, 0, 0); display: inline; margin-top: -36px; margin-right: 108px; font-size: 20px; font-style: normal; font-weight: 400; } `); // ==================================== 逻辑代码开始 console.log('脚本开始'); getParams(); getUInfo(); const divTips = document.createElement('div'); divTips.id = "divTips"; let isLogin = document.querySelector('.login-main'); // 登录页面 let isVsite = checkVsite(); //载入vaptcha let vaptchaAll = null; let btnDownload = { id: 'btnEasyHelper', text: '神速Down', title: '使用神速Down进行下载', html: function (pageType) { if (pageType === 'old' || pageType == 'share') { return ` <span class="g-button-right"> <em class="icon icon-download" style="color:#ffffff" title="${this.text}"></em> <span class="text" style="width: auto;">${this.text}</span> </span> ` } if (pageType === 'new') { return ` <button class="u-button nd-file-list-toolbar-action-item is-need-left-sep u-button--primary u-button--default u-button--small is-has-icon u-button--danger"> <i class="iconfont icon-download"></i> <span>${this.text}</span> </button> `; } }, style: function (pageType) { if (pageType === 'old' || pageType == 'share') { return 'margin: 0px;'; } if (pageType === 'new') { return ''; } }, class: function (pageType) { if (pageType === 'old' || pageType == 'share') { return 'g-button g-button-red-large'; } if (pageType === 'new') { return ''; } } } let start = function () {//迭代调用 if (isVsite) return; let pageType = getPageType(); if (pageType === '') { // console.log('非正常页面,1秒后将重新查找!'); sleep(500).then(() => { start(); }) return; } // 创建按钮 START let btn = document.createElement('a'); btn.id = btnDownload.id; btn.title = btnDownload.title; btn.innerHTML = btnDownload.html(pageType); btn.style.cssText = btnDownload.style(pageType); btn.className = btnDownload.class(pageType); btn.addEventListener('click', function (e) { initButtonEvent(); e.preventDefault(); }); // 创建按钮 END // 添加按钮 START let parent = null; if (pageType === 'old') { let btnUpload = document.querySelector('[node-type=upload]'); // 管理页面:【上传】 parent = btnUpload.parentNode; parent.insertBefore(btn, parent.childNodes[0]); } else if (pageType === 'new') { let btnUpload; btnUpload = document.querySelector("[class='nd-file-list-toolbar nd-file-list-toolbar__actions inline-block-v-middle']"); // 管理页面:【新建文件夹】 if (btnUpload) { btn.style.cssText = 'margin-right: 5px;'; // alert('inline-block-v-middle'); btnUpload.insertBefore(btn, btnUpload.childNodes[0]); } else { btnUpload = document.querySelector("[class='wp-s-agile-tool-bar__header is-default-skin is-header-tool']"); // 20220612管理页面:整个工具条 // console.log(btnUpload); if (!btnUpload) { btnUpload = document.querySelector("[class='wp-s-agile-tool-bar__header is-header-tool']"); // 20220629管理页面:整个工具条 } let parentDiv = document.createElement('div'); parentDiv.className = 'wp-s-agile-tool-bar__h-action is-need-left-sep is-list'; parentDiv.style.cssText = 'margin-right: 10px;'; parentDiv.insertBefore(btn, parentDiv.childNodes[0]); btnUpload.insertBefore(parentDiv, btnUpload.childNodes[0]); } } else if (pageType === 'share') { let btnQrCode = document.querySelector('[node-type=qrCode]'); // 分享页面:【保存到手机】 parent = btnQrCode.parentNode; parent.insertBefore(btn, btnQrCode); } // 添加按钮 END // 修改搜索框宽度,否则在小显示器上,元素会重叠 document.querySelectorAll('span').forEach((e) => { if (e.textContent.includes('搜索您的文件')) { let divP = e.parentNode.parentNode.parentNode divP.style.maxWidth = '200px'; } }); } sleep(500).then(() => { start(); }) })(); //###########################################END##################################################