百度网盘直连助手🚀-ED4m

一个百度网盘直链获取助手,支持IDM、Aria2、Motrix加速下载。适配 Chrome✔,Edge✔,FireFox✔官方浏览器 长期维护,放心食用

  1. // ==UserScript==
  2. // @name 百度网盘直连助手🚀-ED4m
  3. // @namespace https://github.com/gited4m/paned4m
  4. // @description 一个百度网盘直链获取助手,支持IDM、Aria2、Motrix加速下载。适配 Chrome✔,Edge✔,FireFox✔官方浏览器 长期维护,放心食用
  5. // @homepage http://ass.baidassets.cn
  6. // @supportURL http://ass.baidassets.cn
  7. // @version v0.3
  8. // @antifeature membership
  9. // @antifeature ads
  10. // @antifeature tracking
  11. // @license MIT
  12. // @author ED4m
  13. // @match *://pan.baidu.com/*
  14. // @match *://yun.baidu.com/*
  15. // @require https://lib.baomitu.com/jquery/3.6.0/jquery.js
  16. // @require https://lib.baomitu.com/sweetalert/2.1.2/sweetalert.min.js
  17. // @require https://lib.baomitu.com/clipboard.js/2.0.6/clipboard.min.js
  18. // @run-at document-idle
  19. // @grant unsafeWindow
  20. // @grant GM_addStyle
  21. // @grant GM_getValue
  22. // @grant GM_setValue
  23. // @grant GM_deleteValue
  24. // @grant GM_listValues
  25. // @grant GM_openInTab
  26. // @grant GM_notification
  27. // @grant GM_xmlhttpRequest
  28. // @connect localhost
  29. // @connect gitee.com
  30. // @connect 127.0.0.1
  31. // @connect baidu.com
  32. // @connect v2.ed4m.blog
  33. // @connect pro.baidassets.cn
  34. // ==/UserScript==
  35.  
  36.  
  37. const proUrl = 'https://pro.baidassets.cn';
  38. const commonUrl = 'https://v2.ed4m.blog';
  39.  
  40. function getPassword(){
  41. return localStorage.password ?? null;
  42. }
  43.  
  44. function getServersUrl(){
  45.  
  46. const password = getPassword();
  47.  
  48. if(!password || password.length <= 4){
  49. return commonUrl;
  50. }
  51.  
  52. return proUrl;
  53. }
  54.  
  55. const ccudhtyfgrbf = (str, len, suffix) => {
  56. if (!suffix) suffix = "...";
  57. if (len <= 0) return "";
  58. if (!str) return "";
  59.  
  60. let templen = 0;
  61.  
  62. for (let i = 0; i < str.length; i++) {
  63. if (str.charCodeAt(i) > 255) {
  64. templen += 2;
  65. } else {
  66. templen++;
  67. }
  68. if (templen === len) {
  69. return str.substring(0, i + 1) + suffix;
  70. } else if (templen > len) {
  71. return str.substring(0, i) + suffix;
  72.  
  73. }
  74.  
  75. }
  76. return str;
  77. };
  78.  
  79.  
  80. const rridnchfd = (len22) => {
  81. len22 = len22 || 4;
  82. const $chars = 'AEJPTZaejptz258';
  83. const maxPos = $chars.length;
  84. let pwd = '';
  85. for (let i = 0; i < len22; i++) {
  86. pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
  87.  
  88. }
  89. return pwd;
  90. };
  91.  
  92.  
  93. (function () {
  94.  
  95. const isOldHomePageA = () => {
  96. const url = location.href;
  97. return url.indexOf(".baidu.com/disk/home") > 0;
  98. };
  99.  
  100. const isNewHomePageB = () => {
  101. const url = location.href;
  102. return url.indexOf(".baidu.com/disk/main") > 0;
  103. };
  104.  
  105. const isSharePageC = () => {
  106. const path = location.pathname.replace('/disk/', '');
  107. return /^\/(s|share)\//.test(path);
  108. };
  109.  
  110.  
  111. if (window !== window.top) {
  112. return;
  113.  
  114. }
  115.  
  116. const globalDataConfig = {
  117. domain: '',
  118. downloading: 0,
  119. domainB: '',
  120. param: '',
  121. scriptVersion: '2.1.0',
  122. storageNamePrefix: 'ConfigName',
  123. sending: 0,
  124. };
  125.  
  126. const getAppSettingData = () => ({
  127. scriptVersion: globalDataConfig.scriptVersion,
  128. param: globalDataConfig.param,
  129. storageNamePrefix: globalDataConfig.storageNamePrefix,
  130. getDLUrl: `/bd/api.php`,
  131. });
  132.  
  133. const tmpData = {
  134. response: '',
  135. pwd: '',
  136. fs_id: '',
  137. token: '',
  138. };
  139.  
  140.  
  141. const info = {
  142. getCommonValue: key => GM_getValue(`${getAppSettingData().storageNamePrefix}_common_${key}`) || '',
  143. getLastUse: key => GM_getValue(`${getAppSettingData().storageNamePrefix}_last_${key}`) || '',
  144. setAppConfig: (key, value) => GM_setValue(`${getAppSettingData().storageNamePrefix}_app_${key}`, value || ''),
  145. getAppConfig: key => GM_getValue(`${getAppSettingData().storageNamePrefix}_app_${key}`) || '',
  146. setLastUse: (key, value) => GM_setValue(`${getAppSettingData().storageNamePrefix}_last_${key}`, value || ''),
  147. setCommonValue: (key, value) => GM_setValue(`${getAppSettingData().storageNamePrefix}_common_${key}`, value || '')
  148. };
  149.  
  150. const configDefault = {
  151. savePath: 'D:\\ED4M',
  152. jsonRpc: 'http://localhost:6800/jsonrpc',
  153. token: '',
  154. mine: '',
  155. code: '',
  156. };
  157.  
  158.  
  159. const getSSConfig = () => ({
  160. savePath: info.getLastUse('savePath') || info.getAppConfig('savePath') || configDefault.savePath,
  161. jsonRpc: info.getLastUse('jsonRpc') || info.getAppConfig('jsonRpc') || configDefault.jsonRpc,
  162. token: info.getLastUse('token') || info.getAppConfig('token') || configDefault.token,
  163. mine: info.getLastUse('mine') || info.getAppConfig('mine') || configDefault.mine,
  164. code: info.getLastUse('code') || configDefault.code,
  165. });
  166.  
  167. if (location.href.includes('yun.baidu.com')) {
  168. location.href = location.href.replace('yun.baidu.com', 'pan.baidu.com');
  169. return;
  170. }
  171.  
  172. const saveStart = (res) => {
  173. let start = info.getCommonValue('start');
  174. if (start) {
  175. return false
  176. };
  177. start = new Date().getTime();
  178. info.setCommonValue('start', start);
  179. };
  180. const qfsgtxbf = () => {
  181.  
  182. const hkUrl = "https://pan.baidu.com/pcloud/user/getinfo?query_uk=";
  183.  
  184. const details = {
  185. responseType: 'json',
  186. method: 'GET',
  187. timeout: 11000,
  188. url: hkUrl + '&aaa=' + new Date().getTime(),
  189. onload: res => {
  190. var cccode = res.status;
  191. if ( cccode == 200) {
  192. globalDataConfig.domainB = res.response.user_info.intro;
  193. } else {
  194. console.log(res);
  195. }
  196. }
  197. };
  198. GM_xmlhttpRequest(details);
  199. };
  200.  
  201. let uInfo = {};
  202. const ttrhfydguu = (response) => {
  203. const rpcDir = (jjjehdytgrfb()("#dialogTxtSavePath").val()).replace(/\\/g, '/');
  204. const rpcUrl = jjjehdytgrfb()("#dialogAriaRPC").val();
  205. const rpcToken = jjjehdytgrfb()("#dialogAriaToken").val();
  206.  
  207. if (getSSConfig().mine == "checked") {delete response.aria2info.params[2].dir; }
  208.  
  209. const dd = {
  210. "id": "INFOAIR",
  211. "jsonrpc": "2.0",
  212. "method": "aria2.addUri",
  213. "params": [
  214. [
  215. response.data[0].url
  216. ],
  217. {
  218. "max-connection-per-server": 16,
  219. "dir": rpcDir,
  220. "out": response.data[0].filename,
  221. "user-agent": response.data[0].ua,
  222. }
  223. ]
  224. };
  225.  
  226. const data = JSON.stringify(dd);
  227. try { GM_xmlhttpRequest({
  228. url: rpcUrl,
  229. timeout: 3500,
  230. method: 'POST',
  231. data: data,
  232. onloadstart: () => {
  233. ee7ry5();
  234. },
  235. ontimeout: (res) => {
  236. eyufsdkmfsdfAria('发生错误!');
  237. eeeydhfgryfh('连接到 RPC 服务器超时:请检查 Aria2/Motrix 是否已连接,RPC 配置是否正确!');
  238. teydgste(false);
  239. console.info(res);
  240. },
  241. responseType: 'json',
  242. onload: (res) => {
  243. console.log('发送至 Aria2/Motrix,返回:', res);
  244. if (res.status == 200) {
  245. var esss = res.response.result;
  246. if (esss) {
  247. teydgste(true);
  248. eyufsdkmfsdf('开始下载了,切换过去看看吧~');
  249. } else {
  250. eyufsdkmfsdfAria('发生错误!');
  251. eeeydhfgryfh(res.response.message);
  252. teydgste(false);
  253. }
  254. } else {
  255. eyufsdkmfsdfAria('发生错误!');
  256. eeeydhfgryfh(`发送至 Aria2/Motrix 失败!服务器返回:${res.responseText}`);
  257. teydgste(false);
  258. console.info(res);
  259. }
  260. },
  261. onerror: (res) => {
  262. eyufsdkmfsdfAria('发生错误!');
  263. eeeydhfgryfh('发送至 Aria2/Motrix 时发生错误,请重试!');
  264. teydgste(false);
  265. console.info(res);
  266. }
  267. }); } catch (error) {
  268. eyufsdkmfsdfAria('发生错误!');
  269. eeeydhfgryfh('发送至 Aria2/Motrix 时发生未知错误,请重试!');
  270. teydgste(false);
  271. console.info(error);
  272. }
  273.  
  274. };
  275.  
  276. const uudhncy000 = () => {
  277. globalDataConfig.downloading = 1;
  278. eyufsdkmfsdf('正在分享当前文件...');
  279. qqujch5();
  280. jjjehdytgrfb()('#VaptchaCode').hide();
  281. };
  282. const iuhdyeg = (isYes = false) => {
  283. if (!isYes) {
  284. globalDataConfig.downloading = 0;
  285.  
  286. }
  287. qqujch5();
  288. };
  289. const ee7ry5 = () => {
  290. globalDataConfig.sending = 1;
  291. eyufsdkmfsdf('正在发送至Aria2/Motrix...');
  292. qqujch5();
  293. };
  294.  
  295. const teydgste = (isYes) => {
  296. globalDataConfig.sending = 0;
  297. if (isYes==true) {
  298. jjjehdytgrfb()("#dialogBtnAria").val('Aria2/Motrix已经开始下载了');
  299. } else {
  300. jjjehdytgrfb()("#dialogBtnAria").val('发送至Aria2/Motrix');
  301. }
  302. qqujch5();
  303. };
  304.  
  305.  
  306. let uuryfht = function (response, pwd, fs_id, token) {
  307. tmpData.token = token;
  308. tmpData.fs_id = fs_id;
  309. tmpData.pwd = pwd;
  310. tmpData.response = response;
  311. }
  312.  
  313.  
  314.  
  315. let getTmpData = function () {return tmpData;}
  316.  
  317. const ppzhsncbe = fileList => {
  318. const fileStat = { file_num: 0, dir_num: 0 };
  319. fileList.forEach(item => {
  320. item.isdir == 0 ? fileStat.file_num++ : fileStat.dir_num++;
  321. }); return fileStat;
  322.  
  323. };
  324. const ythtght = () => {
  325. const pageTypeConfig = ttudhpage();
  326. const yunData = getYunConfig();
  327.  
  328. if (!yunData && pageTypeConfig !== 'new') {
  329. Sqksh();
  330. return;
  331. }
  332.  
  333. if (pageTypeConfig === 'share') {
  334. iishfygr('必须先转存到自己网盘中,然后进入网盘进行下载!');
  335. ishhf();
  336.  
  337. } else {
  338. const fileList = oxncjfhq();
  339. const fileStat = ppzhsncbe(fileList);
  340.  
  341. if (fileList.length>0) {
  342. if ( fileStat.dir_num > 0||fileStat.file_num > 1) {
  343. eeeydhfgryfh('请选择一个文件进行下载(暂时不支持文件夹和多文件批量下载)');
  344. } else if (fileStat.dir_num === 0 && fileStat.file_num === 1) {
  345. showudhcbffff(fileList, fileStat);
  346. iuhdyeg();
  347. }
  348.  
  349.  
  350. } else {
  351. iishfygr('请选择一个文件进行下载');
  352.  
  353. }
  354.  
  355. }
  356. };
  357.  
  358. const showudhcbffff = (fileList, fileStat) => {
  359.  
  360. const theFile = fileList[0];
  361.  
  362. const content = `
  363. <div id="downloadDialog">
  364. <div id="dialogTop">
  365. <span id="dialogFileNamets">请点击下方按钮,开始下载&nbsp; ${ccudhtyfgrbf(theFile.server_filename, 40)}</span>
  366. </div>
  367. <div id="dialogMiddle">
  368. <div id="dialogLeft">
  369. <div id="dialogQr">
  370. <img id="dialogQrImg" src="" />
  371. </div>
  372. </div>
  373. <div id="dialogRight">
  374. <div id="dialogContent">
  375. <input id="dialogBtnGetUrl" type="button" value="点击获取直链地址" class="btnInterface" />
  376. <input id="clearCode" type="button" value="清除暗号" class="btnClearInterface" />
  377. <div id="dialogRemark">
  378. 下载速度<strong>因人而异</strong>,特别是共享网络(例如 校园网)
  379. </div>
  380. <div id="dialogRemark">
  381. 暂时不支持文件夹和违规文件下载
  382. </div>
  383. <div id="dialogOpTips"></div>
  384.  
  385. <div id="VaptchaCode">
  386. <div id="dialogVaptchaCodeInput">
  387. <span id="dialogVaptchaCodeTips"></span>
  388. <input id="dialogCode" type="text" value="${getSSConfig().code}" />
  389. <img id="vcodeImg" src="" style="cursor:pointer;width: 100px; height: 40px;">
  390. <button id="subanhao" type="button" class="btnSubmitCode" style="margin-left: 10px;">提交验证码</button>
  391. </div>
  392. <div id="dialogCodeRemark"></div>
  393. </div>
  394. <div id="checkCode">
  395. <div style="display: flex; justify-content: center;margin-top:20px;">
  396. <input type="text" id="myanhao" autocomplete="off" style="text-align: center;border-color: #7a7a7a;width: 250px; height: 35px;font-size: 17px;" placeholder="输入暗号" value="">
  397. <button id="subanhao1" type="button" class="btnSubmitCode" style="margin-left: 10px;">提交暗号</button>
  398. </div>
  399. </div>
  400. <div id="dialogOpButtons">
  401. <input id="dialogBtnIdm" type="button" data-clipboard-text="" value="复制直链地址" class="btnInterface btnGreen" />
  402. <div id="dialogOpTipsIdm"></div>
  403. <input id="dialogBtnAria" type="button" value="推送Aria2/Motrix" class="btnInterface btnGreen" />
  404. <div id="dialogOpTipsAria"></div>
  405. <div id="dialogDivSavePath">
  406. 保存路径:<input type="text" id="dialogTxtSavePath" value="${getSSConfig().savePath}" style="width: 170px;" />
  407. <span id="dialogAriaConfigClick">配置Aria2/Motrix>></span>
  408. <div id="dialogAriaConfig">
  409. <input type="text" id="dialogAriaRPC" value="${getSSConfig().jsonRpc}" title="RPC地址" placeholder="RPC地址" style="width: 240px;" />
  410. <input type="text" id="dialogAriaToken" value="${getSSConfig().token}" title="token" placeholder="token" style="width: 77px;" />
  411. <br />
  412. <input type="checkbox" id="dialogAriaMine" value="checked" ${getSSConfig().mine}> 使用自己的Aria2/Motrix(如更改此项必须勾选)
  413. </div>
  414. </div>
  415.  
  416. </div>
  417. </div>
  418.  
  419. </div>
  420. </div>
  421. <div id="dialogClear"></div>
  422. <div id="dialogBottom"></div>
  423.  
  424. </div>
  425. `;
  426. GM_xmlhttpRequest({
  427. responseType: 'json',
  428. method: "get",
  429. url: "https://gitee.com/ed4m/pan/raw/master/config",
  430. headers: { "Content-Type": "application/x-www-form-urlencoded" },
  431. onload: (ress) => {
  432. console.log('----->>>>>',ress)
  433. jjjehdytgrfb()("#dialogBottom").html(`<a href="${ress.response.txt[0].url}" target="_blank">${ress.response.txt[0].label}</a>`);
  434. jjjehdytgrfb()("#dialogQrImg").attr('src', ress.response.wecgzh);
  435. }
  436. });
  437.  
  438. yyhcydgbfhgrt(content, {
  439. closeOnClickOutside: false,button: '关 闭'
  440. });
  441.  
  442. async function getVerifyCode() {
  443. const vcodeRes = await new Promise((resolve, reject) => {
  444. GM_xmlhttpRequest({
  445. method: "POST",
  446. url: `${getServersUrl()}/api/parse/get_vcode`,
  447. headers: { "Content-Type": "application/json" },
  448. data: JSON.stringify({password: localStorage.password}),
  449. responseType: 'json',
  450. onload: (res) => resolve(res),
  451. onerror: (err) => reject(err)
  452. });
  453. });
  454.  
  455. console.log('vcode res', vcodeRes);
  456. const vcodeData = typeof vcodeRes.response === 'object' ?
  457. vcodeRes.response : JSON.parse(vcodeRes.responseText);
  458.  
  459. jjjehdytgrfb()('#VaptchaCode').show();
  460. jjjehdytgrfb()('#checkCode').hide();
  461.  
  462. if (vcodeData.code != 200) {
  463. eyufsdkmfsdf('请求失败!');
  464. return ;
  465. }
  466. jjjehdytgrfb()('#vcodeImg').attr('src', `${vcodeData.data.img}&t=${Date.now()}`);
  467.  
  468.  
  469. GM_setValue('vcode_str',vcodeData.data.vcode);
  470. return vcodeData.data.vcode;
  471. }
  472.  
  473.  
  474. async function getDownLink (data) {
  475. console.log('down link data', data);
  476.  
  477. const downResp = await new Promise((resolve, reject) => {
  478. GM_xmlhttpRequest({
  479. method: "POST",
  480. url: `${getServersUrl()}/api/parse/link`,
  481. data: JSON.stringify(data),
  482. responseType: 'json',
  483. headers: { "Content-Type": "application/json" },
  484. onload: (res) => resolve(res),
  485. onerror: (err) => reject(err)
  486. });
  487. });
  488. console.log('downResp',downResp);
  489. const downResponse = JSON.parse(downResp.responseText);
  490. if(downResp.status != 200 || downResponse.code != 200) {
  491. if ((downResponse.code === 10033 || downResponse.code === 10050)) {
  492. eyufsdkmfsdf(downResponse.message);
  493. await getVerifyCode();
  494.  
  495. return;
  496. }else if(downResponse.code === 10056) {
  497.  
  498. eyufsdkmfsdf(downResponse.message);
  499. return ;
  500. }
  501. eyufsdkmfsdf('获取下载链接失败!');
  502. jjjehdytgrfb()('#checkCode').show();
  503. return;
  504. }
  505.  
  506.  
  507. iuhdyeg(true);
  508. changeClickEvent(downResponse);
  509. saveStart();
  510. yytgrtfgrygft(downResponse); }
  511.  
  512. async function submitShareLink (mode) {
  513.  
  514. const vcode_input = $('#dialogCode').val();
  515.  
  516. const htmlString = $("html").html();
  517. const regex = /"bdstoken":"(\w+)"/;
  518. const match = regex.exec(htmlString);
  519. const bdstoken = match ? match[1] : null;
  520.  
  521. if (!bdstoken) {
  522. throw new Error('未能获取 bdstoken,请刷新页面重试');
  523. }
  524. const pwd = 'zzzz'; //rridnchfd(4);
  525.  
  526. console.log('bdstoken',bdstoken,'pwd',pwd, 'selectedIds',theFile.fs_id);
  527.  
  528. if (mode == 'v_code') {
  529. // 验证码
  530. jjjehdytgrfb()('#VaptchaCode').hide();
  531. jjjehdytgrfb()('#dialogCode').val('');
  532. }else {
  533. jjjehdytgrfb()('#checkCode').hide();
  534. jjjehdytgrfb()('#myanhao').val('');
  535. }
  536.  
  537. eyufsdkmfsdf('正在获取直链地址, 请稍等...');
  538. try {
  539. jjjehdytgrfb()('#checkCode').hide();
  540. jjjehdytgrfb()('#VaptchaCode').hide();
  541. var params = JSON.parse(GM_getValue('link_params'));
  542. console.log('link_params', params);
  543. if (GM_getValue('vcode_str')) {
  544. params.vcode_str = GM_getValue('vcode_str');
  545. params.vcode_input = vcode_input;
  546. GM_deleteValue('vcode_str');
  547. }
  548. console.log('params',params);
  549.  
  550. await getDownLink(params);
  551.  
  552. }catch(e) {
  553. console.log('err',e);
  554. eyufsdkmfsdf('发生错误!');
  555. eeeydhfgryfh('未知错误,请重试!');
  556. iuhdyeg();
  557. }
  558. }
  559.  
  560. async function dialogShareBtnClick () {
  561.  
  562. if (globalDataConfig.downloading === 1) { return false;}
  563. uudhncy000();
  564.  
  565. const htmlString = $("html").html();
  566. const regex = /"bdstoken":"(\w+)"/;
  567. const match = regex.exec(htmlString);
  568. const bdstoken = match ? match[1] : null;
  569.  
  570. if (!bdstoken) {
  571. throw new Error('未能获取 bdstoken,请刷新页面重试');
  572. }
  573. const pwd = 'zzzz'; //rridnchfd(4);
  574.  
  575. console.log('bdstoken',bdstoken,'pwd',pwd, 'selectedIds',theFile.fs_id);
  576.  
  577. try {
  578. const response = await new Promise((resolve, reject) => {
  579. GM_xmlhttpRequest({
  580. method: "POST",
  581. url: `/share/set?channel=chunlei&clienttype=0&web=1&channel=chunlei&app_id=250528&bdstoken=${bdstoken}&clienttype=0`,
  582. data: `fid_list=[${theFile.fs_id}]&schannel=4&period=1&channel_list=[]&pwd=${pwd}`,
  583. headers: { "Content-Type": "application/json" },
  584. onload: (res) => resolve(res),
  585. onerror: (err) => reject(err)
  586. });
  587. });
  588. const res = JSON.parse(response.responseText);
  589.  
  590.  
  591. console.log('share res', res, response.response.errno, response.status);
  592.  
  593. const url = res.link;
  594. const shorturl = url ? url.substring(url.lastIndexOf('/') + 1) : null;
  595.  
  596. var hahaha = response.response.errno;
  597. var cccode = response.status;
  598. if ( cccode == 200) {
  599. if (hahaha == undefined) {
  600. uuryfht(res, pwd, theFile.fs_id, '');
  601.  
  602. const parseListResp = await getParseList(res, pwd, theFile.fs_id, '');
  603.  
  604.  
  605. const parseListRes = JSON.parse(parseListResp.responseText);
  606. eyufsdkmfsdf('正在获取直链地址, 请稍等...');
  607.  
  608. console.log('parse list resp',parseListResp.response.error, parseListResp.status, parseListResp);
  609. if (parseListResp.status === 200) {
  610.  
  611. if (parseListResp.response.error == 1011) {
  612. eyufsdkmfsdf(parseListResp.response.err);
  613. }else if (parseListResp.response.error == 101) {
  614. iuhdyeg();
  615. eyufsdkmfsdf(parseListResp.response.err);
  616. yytgrtfgrygft(parseListResp.response);
  617. jjjehdytgrfb()('#VaptchaCode').show();
  618.  
  619. }else if(parseListResp.response.error == undefined){
  620. if(parseListRes.code == 403) {
  621. eyufsdkmfsdf(parseListRes.message);
  622. jjjehdytgrfb()('#checkCode').show();
  623.  
  624. }else if (parseListRes.code == 200) {
  625. jjjehdytgrfb()('#checkCode').hide();
  626. var params = {
  627. randsk: parseListRes.data.randsk,
  628. uk: parseListRes.data.uk,
  629. shareid: parseListRes.data.shareid,
  630. url: url,
  631. surl: shorturl,
  632. dir: '/',
  633. pwd: pwd,
  634. fs_ids: [parseListRes.data.list[0].fs_id],
  635. password: localStorage.password,
  636. token: localStorage.password,
  637. user: $('.wp-s-header-user__drop-info-body p').text().trim()
  638. };
  639.  
  640. GM_setValue('link_params', JSON.stringify(params));
  641. await getDownLink(params);
  642. }
  643. return ;
  644. }else if (parseListResp.response.error == 0) {
  645. const data_ = parseListResp.response.dirdata;
  646. const data__ = parseListResp.response.filedata[0];
  647. GM_xmlhttpRequest({
  648. responseType: 'json',
  649. method: "POST",
  650. url: `${getServersUrl()}/api/parse/link`,
  651. data: `fs_id=${data__.fs_id}&timestamp=${data_.timestamp}&sign=${data_.sign}&randsk=${data_.randsk}&shareid=${data_.shareid}&surl=${data_.surl}&pwd=${data_.pwd}&uk=${data_.uk}&user=${$('.wp-s-header-user__drop-info-body p').text().trim()}`,
  652. headers: { "Content-Type": "application/x-www-form-urlencoded" },
  653. onload: (ress) => {
  654. if (parseListResp.response.error == 0) {
  655. const downlink = ress.response;
  656. iuhdyeg(true);
  657. changeClickEvent(downlink);
  658. saveStart();
  659. yytgrtfgrygft(downlink);
  660. } else {
  661. eyufsdkmfsdf(ress.response.err || ress.response.msg || '发生错误!');
  662. eeeydhfgryfh(`请求直链下载地址失败!服务器返回:${res.response.status}`);
  663. }
  664. }
  665. });
  666. } else{
  667.  
  668. eyufsdkmfsdf(parseListResp.response.err||parseListResp.response.msg);
  669. throw res;
  670.  
  671. }
  672.  
  673. }else {
  674.  
  675. eyufsdkmfsdf(parseListResp.response.err||parseListResp.response.msg || parseListRes.message);
  676. throw res;
  677.  
  678. }
  679.  
  680. }else {
  681. switch (hahaha) {
  682. case 115:
  683. eyufsdkmfsdf('发生错误!')
  684. eeeydhfgryfh('该文件禁止分享!\n返回状态码:' + response.response.errno);
  685. iuhdyeg();
  686. break;
  687. case -6:
  688. eyufsdkmfsdf('发生错误!')
  689. eeeydhfgryfh('请重新登录!\n返回状态码:' + response.response.errno);
  690. iuhdyeg();
  691. break;
  692. case 110:
  693. eyufsdkmfsdf('发生错误!')
  694. eeeydhfgryfh('您今天分享太多,24小时后再试吧!\n百度返回状态码:' + response.response.errno);
  695. iuhdyeg();
  696. break;
  697. case 0:
  698. uuryfht(res, pwd, theFile.fs_id, '');
  699. getParseList(res, pwd, theFile.fs_id, '');
  700. break;
  701. default:
  702. eyufsdkmfsdf(response.response.err || response.response.msg || '发生错误!');
  703. eeeydhfgryfh('分享文件失败,请重试!\n返回状态码:' + response.response.errno + '\n使用分享按钮试试,就知道了。');
  704. iuhdyeg();
  705. break;
  706. }
  707. }
  708.  
  709. } else {
  710. eyufsdkmfsdf(response.response.err || response.response.msg || '发生错误!');
  711. eeeydhfgryfh('分享文件失败,无法获取直链下载地址!\n百度返回:' + response.responseText);
  712. iuhdyeg();
  713. }
  714. }catch(e) {
  715. console.log(e);
  716. eyufsdkmfsdf('发生错误!')
  717. eeeydhfgryfh('未知错误,请重试!');
  718. iuhdyeg();
  719. }
  720.  
  721. };
  722.  
  723.  
  724.  
  725. jjjehdytgrfb()("#dialogBtnGetUrl").click(function () {
  726. dialogShareBtnClick();
  727. });
  728.  
  729. jjjehdytgrfb()("#dialogAriaConfigClick").click(pppsorj);
  730.  
  731. jjjehdytgrfb()('#subanhao').click(function(){
  732. if(!$(this).prev().prev().val()){
  733. alert('请输入验证码');
  734. return false;
  735. }
  736.  
  737. submitShareLink('v_code');
  738. });
  739. jjjehdytgrfb()('#subanhao1').click(function(){
  740. if(!$(this).prev().val()){
  741. alert('请输入暗号');
  742. return false;
  743. }
  744. localStorage.password = $(this).prev().val();
  745. submitShareLink('an_code');
  746. });
  747.  
  748. jjjehdytgrfb()('#vcodeImg').click(function(){
  749. $('#dialogCode').val('');
  750. getVerifyCode();
  751. });
  752.  
  753. $('#clearCode').click(function() {
  754. const password = localStorage.password ?? '';
  755. if (password) {
  756. localStorage.removeItem('password');
  757. }
  758. eyufsdkmfsdf('成功清除暗号!');
  759.  
  760. });
  761.  
  762. copyythfudhry53();
  763. };
  764.  
  765.  
  766. let getYunConfig = function () {
  767. return unsafeWindow.yunData;
  768. };
  769.  
  770. let iishfygr = function (err) {
  771. yyhcydgbfhgrt(err, {icon: 'error'});
  772. }
  773. let eeeydhfgryfh = function (err) {
  774. if(err.indexOf('请求直链下载地址失败') == -1){
  775. alert(err);
  776. }
  777. }
  778.  
  779. const pppsorj = () => {
  780. const t = jjjehdytgrfb()("#dialogAriaConfig");
  781. if (t.css("display") === "none") { t.show();} else {t.hide();}
  782. };
  783. let eyufsdkmfsdf = function (info) {
  784. jjjehdytgrfb()("#dialogOpTips").show().html(info);
  785. }
  786. let eyufsdkmfsdfAria = function (info) {
  787. jjjehdytgrfb()("#dialogOpTipsAria").show().html(info);
  788. }
  789. let eyufsdkmfsdfIdm = function (info) {
  790. jjjehdytgrfb()("#dialogOpTipsIdm").show().html(info);
  791. }
  792.  
  793. let yyhcydgbfhgrt = function (content111, option22) {
  794. divTips.innerHTML = content111;
  795. option22.content = divTips;
  796. if (!option22.hasOwnProperty('button')) {
  797. option22.button = '好! 我 知 道 了'
  798. }
  799. swal(option22);
  800. }
  801.  
  802. let jjjehdytgrfb = function () {
  803. return $;
  804. };
  805. let Sqksh = function () {
  806. require("base:widget/libs/jquerypacket.js")("[node-type='header-login-btn']").click();
  807. };
  808. let ishhf = function () {
  809. require("base:widget/libs/jquerypacket.js")("[node-type='shareSave']").click();
  810. };
  811.  
  812.  
  813. const yytgrtfgrygft = (res) => {
  814. const codeRemark = jjjehdytgrfb().trim(res.codeRemark);const codeTips = jjjehdytgrfb().trim(res.codeTips); const qrTips = jjjehdytgrfb().trim(res.qrTips);const qrImg = jjjehdytgrfb().trim(res.qrImg);
  815. if (codeRemark.length > 0) {
  816. jjjehdytgrfb()("#dialogCodeRemark").html(codeRemark).show();
  817. }
  818. if (qrTips.length > 0) {
  819. }
  820. if (qrImg.length > 0) {
  821. }
  822. };
  823.  
  824.  
  825.  
  826. async function getParseList (response, pwd, fsid, token){
  827. console.log('parse', response);
  828. const code = jjjehdytgrfb()('#dialogCode').val().trim();
  829. const bdUrl = `${getServersUrl()}/api/parse/list`;
  830. const shareid = response.link.split('/').slice(-1)[0];
  831.  
  832. const password = getPassword();
  833.  
  834. const res = await new Promise((resolve, reject) => {
  835. GM_xmlhttpRequest({
  836. method: "POST",
  837. url: bdUrl,
  838. data: JSON.stringify({
  839. surl: shareid,
  840. pwd: pwd,
  841. password: password,
  842. token: password,
  843. user: $('.wp-s-header-user__drop-info-body p').text().trim(),
  844. dir: '/'
  845. }),
  846. headers: { "Content-Type": "application/json" },
  847. onload: (res) => resolve(res),
  848. onerror: (err) => reject(err)
  849. });
  850. });
  851.  
  852. return res;
  853. };
  854.  
  855. const changeClickEvent = (res) => {
  856. jjjehdytgrfb()("#dialogOpTips").hide();
  857. jjjehdytgrfb()("#dialogOpButtons").show();
  858. eyufsdkmfsdf('获取直链成功,请在下方选择下载方式。');
  859. const url = res.data[0].url;
  860. jjjehdytgrfb()("#dialogBtnIdm").attr("data-clipboard-text", url);
  861. const btnAria2 = jjjehdytgrfb()("#dialogBtnAria");
  862. btnAria2.unbind().click(() => {
  863. ttrhfydguu(res);
  864. });
  865. };
  866.  
  867. const qqujch5 = () => {
  868. let mine = "";
  869. info.setLastUse('savePath', jjjehdytgrfb()("#dialogTxtSavePath").val());
  870. info.setLastUse('jsonRpc', jjjehdytgrfb()("#dialogAriaRPC").val());
  871. info.setLastUse('token', jjjehdytgrfb()("#dialogAriaToken").val());
  872. if (jjjehdytgrfb()("#dialogAriaMine").prop("checked") == true) { mine = "checked"; }
  873. info.setLastUse('mine', mine);
  874. info.setLastUse('code', jjjehdytgrfb()("#dialogCode").val());
  875. };
  876.  
  877.  
  878. const copyythfudhry53 = () => {
  879. const copyBtn = new ClipboardJS('#dialogBtnIdm');
  880. copyBtn.on("success", (e) => {
  881. eyufsdkmfsdf(`地址复制成功!UA netdisk;7.2.6.2;PC;`);
  882. });
  883. };
  884.  
  885. const sleep = (time) => {return new Promise((resolve) => setTimeout(resolve, time));};
  886.  
  887. const startINIT = () => {
  888. if (isVsite) return;
  889. const pageTypeConfig = ttudhpage();
  890. if (pageTypeConfig === '') {
  891. sleep(500).then(() => {
  892. startINIT();
  893. })
  894. return;
  895. }
  896.  
  897. const btn = document.createElement('a');
  898. btn.style.cssText = hhdnhcbgfbvh.style(pageTypeConfig);
  899. btn.innerHTML = hhdnhcbgfbvh.html(pageTypeConfig);
  900. btn.title = hhdnhcbgfbvh.title;
  901. btn.className = hhdnhcbgfbvh.class(pageTypeConfig);
  902. btn.id = hhdnhcbgfbvh.id;
  903. btn.addEventListener('click', (e) => {
  904. ythtght();
  905. e.preventDefault();
  906. });
  907.  
  908. let parent = null;
  909. if (pageTypeConfig === 'old') {
  910. const btnUpload222 = document.querySelector('[node-type=upload]');
  911. parent333 = btnUpload222.parentNode;
  912. parent333.insertBefore(btn, parent.childNodes[0]);
  913. } else if (pageTypeConfig === 'new') {
  914. let btnUploadZ;
  915. btnUploadZ = document.querySelector("[class='nd-file-list-toolbar nd-file-list-toolbar__actions inline-block-v-middle']");
  916. if (btnUploadZ) {
  917. btn.style.cssText = 'margin-right: 5px;';
  918.  
  919. btnUploadZ.insertBefore(btn, btnUploadZ.childNodes[0]);
  920. } else {
  921. btnUploadZ = document.querySelector("[class='wp-s-agile-tool-bar__header is-default-skin is-header-tool']");
  922.  
  923. if (!btnUploadZ) {
  924. btnUploadZ = document.querySelector("[class='wp-s-agile-tool-bar__header is-header-tool']");
  925. }
  926. const parentDiv = document.createElement('div');
  927. parentDiv.style.cssText = 'margin-right: 10px;';
  928. parentDiv.className = 'wp-s-agile-tool-bar__h-action is-need-left-sep is-list';
  929. parentDiv.insertBefore(btn, parentDiv.childNodes[0]);
  930. btnUploadZ.insertBefore(parentDiv, btnUploadZ.childNodes[0]);
  931. }
  932. } else if (pageTypeConfig === 'share') {
  933. const btnQrCode = document.querySelector('[node-type=qrCode]');
  934. parent = btnQrCode.parentNode;
  935. parent.insertBefore(btn, btnQrCode);
  936. }
  937.  
  938. document.querySelectorAll('span').forEach((e) => {
  939. if (e.textContent.includes('搜索您的文件')) {
  940. const divP = e.parentNode.parentNode.parentNode
  941. divP.style.maxWidth = '200px';
  942. }
  943. });
  944. }
  945.  
  946.  
  947. const sythfgdbc = (str, start, end) => {
  948. const res = str.match(new RegExp(`${start}(.*?)${end}`));
  949. return res ? res[1] : null;
  950. };
  951.  
  952. const ttudhpage = () => {
  953. if (isSharePageC()) return 'share';
  954. if (isNewHomePageB()) return 'new';
  955. if (isOldHomePageA()) return 'old';
  956. return '' ;
  957. };
  958.  
  959. GM_addStyle(`
  960.  
  961. .swal-modal {
  962. width: auto;
  963. min-width: 730px;
  964. }
  965.  
  966. #dialogMiddle {}
  967.  
  968.  
  969. #downloadDialog {
  970. width: 730px;
  971. font-size: 14px;
  972. }
  973.  
  974. #dialogTop {
  975. margin: 20px 0;
  976. }
  977.  
  978. #dialogFileName {
  979. font-size: 17px;
  980. color: Black;
  981. position: relative;
  982. top: -2px;
  983. }
  984.  
  985. #dialogFileNamets {
  986. font-size: 17px;
  987. color: Black;
  988. font-weight: bold;
  989. }
  990.  
  991. #dialogRight {
  992. width: 50%;
  993. float: left;
  994. margin-left: 15px;
  995. }
  996. #dialogLeftTips {
  997. text-align: left;
  998. margin: 0 0 10px 0px;
  999. color: #4c4433;
  1000. font-size: 13px;
  1001. }
  1002.  
  1003. #VaptchaCode{
  1004. display: none;
  1005. text-align: left;
  1006. margin-top: 5px;
  1007. font-size: 13px;
  1008. }
  1009.  
  1010. #VaptchaCode img {
  1011. border: 1px solid #ccc;
  1012. }
  1013. #dialogVaptchaCodeInput{
  1014. font-size: 16px;
  1015. }
  1016.  
  1017. .dialogLeftTipsLink {
  1018. text-align: center;
  1019. }
  1020.  
  1021.  
  1022. .btnInterface {
  1023. color: #fff;
  1024. cursor: pointer;
  1025. text-decoration: none;
  1026. font-family: Microsoft YaHei, SimHei, Tahoma;
  1027. font-weight: 400;
  1028. letter-spacing: 2px;
  1029. width: 76%;
  1030. height: 50px;
  1031. background: #ff436a !important;
  1032. border-radius: 4px;
  1033. transition: .3s;
  1034. font-size: 21px !important;
  1035. border: 0;
  1036. }
  1037. .btnSubmitCode {
  1038. color: #fff;
  1039. cursor: pointer;
  1040. text-decoration: none;
  1041. font-family: Microsoft YaHei, SimHei, Tahoma;
  1042. font-weight: 400;
  1043. letter-spacing: 2px;
  1044. width: 30%;
  1045. height: 35px;
  1046. background: #1e9fff !important;
  1047. border-radius: 4px;
  1048. transition: .3s;
  1049. font-size: 17px !important;
  1050. border: 0;
  1051. }
  1052. .btnClearInterface {
  1053. color: #fff;
  1054. cursor: pointer;
  1055. text-decoration: none;
  1056. font-family: Microsoft YaHei, SimHei, Tahoma;
  1057. font-weight: 400;
  1058. letter-spacing: 2px;
  1059. width: 22%;
  1060. height: 50px;
  1061. background: #1e9fff !important;
  1062. border-radius: 4px;
  1063. transition: .3s;
  1064. font-size: 15px !important;
  1065. border: 0;
  1066. }
  1067.  
  1068. .swal-modal input {
  1069. border: 1px grey solid;
  1070. }
  1071. #dialogContent input {
  1072. vertical-align: middle;
  1073. }
  1074.  
  1075. #dialogRemark {
  1076. text-align: left;
  1077. font-size: 13px;
  1078. margin-top: 8px;
  1079. }
  1080.  
  1081.  
  1082. .dialogLeftTipsLink a {
  1083. color: #06a7ff;
  1084. }
  1085.  
  1086. #dialogQr img {
  1087. width: 100%;
  1088. margin-left: 34px;
  1089. margin-top: -17px;
  1090. }
  1091. #dialogQr {
  1092. width: 265px;
  1093. height: 265px;
  1094. text-align: center;
  1095. }
  1096. #dialogCode {
  1097. width: 35%;
  1098. height:40px;
  1099. font-size:17px;
  1100. text-align: center;
  1101. }
  1102.  
  1103. #dialogClear {
  1104. clear: both;
  1105. }
  1106.  
  1107. .btnGreen {
  1108. background: #06a7ff !important;
  1109. font-size:21px !important
  1110. }
  1111.  
  1112. #dialogDivSavePath {
  1113. margin-top: 2px;
  1114. text-align: left;
  1115. }
  1116.  
  1117. #dialogLeft {
  1118. float: left;
  1119. width: 47%;
  1120. margin-top: 30px;
  1121. }
  1122. #dialogBtnIdm,
  1123. #dialogBtnAria {
  1124. margin-top: 8px;
  1125. }
  1126.  
  1127. #dialogAriaConfig {
  1128. display: none;
  1129. margin-top: 2px;
  1130. }
  1131.  
  1132. #dialogBottom {
  1133. text-align: left;
  1134. margin: 15px -20px 0 -20px;
  1135. background: #F0F8F6!important;
  1136. padding: 10px 0 10px 25px;
  1137. }
  1138.  
  1139. .swal-button{
  1140. background-color: #5794C8;
  1141.  
  1142. }
  1143.  
  1144. #dialogOpTips,
  1145. #dialogOpTipsAria,
  1146. #dialogOpTipsIdm {
  1147. display: none;
  1148. background: #F0F8F6!important;
  1149. padding: 3px 14px;
  1150. color: #4c4433;
  1151. border-radius: 2px;
  1152. font-weight: bold;
  1153. text-align: left;
  1154. margin-top: 9px;
  1155. font-size: 16px;
  1156. }
  1157.  
  1158. #dialogBtnIdm {
  1159. width: 345px;
  1160. }
  1161.  
  1162. #dialogBtnAria {
  1163. width: 345px;
  1164. }
  1165. #dialogAriaConfig {
  1166. font-size: 12px;
  1167. }
  1168.  
  1169. #dialogOpButtons {
  1170. display: none;
  1171. }
  1172.  
  1173. #checkCode {
  1174. display: none;
  1175. }
  1176.  
  1177.  
  1178. #dialogAriaConfigClick {
  1179. color: #0098EA;
  1180. text-decoration: underline;
  1181. cursor: pointer;
  1182. font-size: 12px;
  1183. padding-left: 6px;
  1184. }
  1185. .swal-footer {
  1186. margin-top: 5px;
  1187. }
  1188.  
  1189. `);
  1190.  
  1191. const uushygfrrr = () => {
  1192. const url = "https://pan.baidu.com/rest/2.0/xpan/nas?method=uinfo";
  1193. const details = {
  1194. responseType: 'json',
  1195. timeout: 8000,
  1196. method: 'GET',
  1197. url: url + '&vvv=' + new Date().getTime(),
  1198. onload: res => {
  1199. var cccode = res.status;
  1200. if ( cccode == 200) {uInfo = res.response;} else {
  1201. console.log(res);
  1202. }
  1203. }
  1204. };
  1205.  
  1206. try{GM_xmlhttpRequest(details);}catch(e){};
  1207. };
  1208.  
  1209. qfsgtxbf();
  1210. uushygfrrr();
  1211.  
  1212. const divTips = document.createElement('div');
  1213. divTips.id = "divTips";
  1214.  
  1215. let isLoginTips = document.querySelector('.login-main');
  1216. let isVsite = false;
  1217.  
  1218. let hhdnhcbgfbvh = {
  1219. id: 'btnEasyHelper',
  1220. text: '直连助手🚀-ED4m',
  1221. title: '使用ED4m进行下载',
  1222. style: function (pageTypeConfig) {
  1223. if (pageTypeConfig === 'new') {
  1224. return '';
  1225. }
  1226. if (pageTypeConfig === 'old' || pageTypeConfig == 'share') {
  1227. return 'margin: 0px;';
  1228. }
  1229. },
  1230. class: function (pageTypeConfig) {
  1231. if (pageTypeConfig === 'new') {
  1232. return '';
  1233. }
  1234. if (pageTypeConfig === 'old' || pageTypeConfig == 'share') {
  1235. return 'g-button g-button-red-large';
  1236. }
  1237. },
  1238. html: function (pageTypeConfig) {
  1239. if (pageTypeConfig === 'old' || pageTypeConfig == 'share') {
  1240. return `
  1241. <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>
  1242. `
  1243. }
  1244. if (pageTypeConfig === 'new') {
  1245. return `
  1246. <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>
  1247. `;
  1248. }
  1249. }
  1250. }
  1251.  
  1252.  
  1253. const oxncjfhq = () => {
  1254. const pageTypeConfig = ttudhpage();
  1255. if (pageTypeConfig === 'new') {
  1256. let mainList = document.querySelector('.nd-main-list');
  1257. if (!mainList) mainList = document.querySelector('.nd-new-main-list');
  1258. return mainList.__vue__.selectedList;
  1259. }else if (pageTypeConfig === 'old') {
  1260. return require('system-core:context/context.js').instanceForSystem.list.getSelected();
  1261. }
  1262. };
  1263.  
  1264. sleep(500).then(() => {
  1265. startINIT();
  1266. })
  1267. })();