(改)网盘直链下载助手

可以获取网盘文件真实下载地址。基于【网盘直链下载助手】修改自5.9.0版本,原作者:https://www.baiduyun.wiki/,自用,去推广,加宽界面。

当前为 2022-08-10 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name (改)网盘直链下载助手
  3. // @namespace https://github.com/syhyz1990/baiduyun
  4. // @version 1.0.2
  5. // @author Hmjz100、油小猴
  6. // @icon https://www.youxiaohou.com/48x48.png
  7. // @icon64 https://www.youxiaohou.com/64x64.png
  8. // @description 可以获取网盘文件真实下载地址。基于【网盘直链下载助手】修改自5.9.0版本,原作者:https://www.baiduyun.wiki/,自用,去推广,加宽界面。
  9. // @license AGPL-3.0-or-later
  10. // @homepage https://www.youxiaohou.com/install.html
  11. // @supportURL https://github.com/syhyz1990/baiduyun
  12. // @match *://pan.baidu.com/disk/home*
  13. // @match *://yun.baidu.com/disk/home*
  14. // @match *://pan.baidu.com/disk/main*
  15. // @match *://yun.baidu.com/disk/main*
  16. // @match *://pan.baidu.com/s/*
  17. // @match *://yun.baidu.com/s/*
  18. // @match *://pan.baidu.com/share/*
  19. // @match *://yun.baidu.com/share/*
  20. // @match *://www.aliyundrive.com/s/*
  21. // @match *://www.aliyundrive.com/drive*
  22. // @match *://cloud.189.cn/web/*
  23. // @match *://pan.xunlei.com/*
  24. // @match *://pan.quark.cn/*
  25. // @require https://unpkg.com/jquery@3.6.0/dist/jquery.min.js
  26. // @require https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.all.min.js
  27. // @require https://unpkg.com/js-md5@0.7.3/build/md5.min.js
  28. // @connect baidu.com
  29. // @connect baidupcs.com
  30. // @connect aliyundrive.com
  31. // @connect 189.cn
  32. // @connect xunlei.com
  33. // @connect quark.cn
  34. // @connect youxiaohou.com
  35. // @connect localhost
  36. // @connect *
  37. // @run-at document-idle
  38. // @grant unsafeWindow
  39. // @grant GM_xmlhttpRequest
  40. // @grant GM_setClipboard
  41. // @grant GM_setValue
  42. // @grant GM_getValue
  43. // @grant GM_openInTab
  44. // @grant GM_info
  45. // @grant GM_registerMenuCommand
  46. // @grant GM_cookie
  47. // ==/UserScript==
  48.  
  49. (function () {
  50. 'use strict';
  51. let pt = '', selectList = [], params = {}, mode = '', width = 800, pan = {}, color = '',
  52. doc = $(document), progress = {}, request = {}, ins = {}, idm = {};
  53. const scriptInfo = GM_info.script;
  54. const version = scriptInfo.version;
  55. const author = scriptInfo.author;
  56. const name = scriptInfo.name;
  57. const customClass = {
  58. popup: 'pl-popup',
  59. header: 'pl-header',
  60. title: 'pl-title',
  61. closeButton: 'pl-close',
  62. content: 'pl-content',
  63. input: 'pl-input',
  64. footer: 'pl-footer'
  65. };
  66.  
  67. const terminalType = {
  68. wc: "Windows CMD",
  69. wp: "Windows PowerShell",
  70. lt: "Linux 终端",
  71. ls: "Linux Shell",
  72. mt: "MacOS 终端",
  73. };
  74.  
  75. let toast = Swal.mixin({
  76. toast: true,
  77. position: 'top',
  78. showConfirmButton: false,
  79. timer: 3500,
  80. timerProgressBar: false,
  81. didOpen: (toast) => {
  82. toast.addEventListener('mouseenter', Swal.stopTimer);
  83. toast.addEventListener('mouseleave', Swal.resumeTimer);
  84. }
  85. });
  86.  
  87. const message = {
  88. success: (text) => {
  89. toast.fire({title: text, icon: 'success'});
  90. },
  91. error: (text) => {
  92. toast.fire({title: text, icon: 'error'});
  93. },
  94. warning: (text) => {
  95. toast.fire({title: text, icon: 'warning'});
  96. },
  97. info: (text) => {
  98. toast.fire({title: text, icon: 'info'});
  99. },
  100. question: (text) => {
  101. toast.fire({title: text, icon: 'question'});
  102. }
  103. };
  104.  
  105. let base = {
  106.  
  107. getCookie(name) {
  108. let arr = document.cookie.replace(/\s/g, "").split(';');
  109. for (let i = 0, l = arr.length; i < l; i++) {
  110. let tempArr = arr[i].split('=');
  111. if (tempArr[0] === name) {
  112. return decodeURIComponent(tempArr[1]);
  113. }
  114. }
  115. return '';
  116. },
  117.  
  118. isType(obj) {
  119. return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase();
  120. },
  121.  
  122. getValue(name) {
  123. return GM_getValue(name);
  124. },
  125.  
  126. setValue(name, value) {
  127. GM_setValue(name, value);
  128. },
  129.  
  130. getStorage(key) {
  131. try {
  132. return JSON.parse(localStorage.getItem(key));
  133. } catch (e) {
  134. return localStorage.getItem(key);
  135. }
  136. },
  137.  
  138. setStorage(key, value) {
  139. if (this.isType(value) === 'object' || this.isType(value) === 'array') {
  140. return localStorage.setItem(key, JSON.stringify(value));
  141. }
  142. return localStorage.setItem(key, value);
  143. },
  144.  
  145. setClipboard(text) {
  146. GM_setClipboard(text, 'text');
  147. },
  148.  
  149. e(str) {
  150. return btoa(unescape(encodeURIComponent(str)));
  151. },
  152.  
  153. d(str) {
  154. return decodeURIComponent(escape(atob(str)));
  155. },
  156.  
  157. getExtension(name) {
  158. const reg = /(?!\.)\w+$/;
  159. if (reg.test(name)) {
  160. let match = name.match(reg);
  161. return match[0].toUpperCase();
  162. }
  163. return '';
  164. },
  165.  
  166. sizeFormat(value) {
  167. if (value === +value) {
  168. let unit = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
  169. let index = Math.floor(Math.log(value) / Math.log(1024));
  170. let size = value / Math.pow(1024, index);
  171. size = size.toFixed(1);
  172. return size + unit[index];
  173. }
  174. return '';
  175. },
  176.  
  177. sortByName(arr) {
  178. const handle = () => {
  179. return (a, b) => {
  180. const p1 = a.filename ? a.filename : a.server_filename;
  181. const p2 = b.filename ? b.filename : b.server_filename;
  182. return p1.localeCompare(p2, "zh-CN");
  183. };
  184. };
  185. arr.sort(handle());
  186. },
  187.  
  188. blobDownload(blob, filename) {
  189. if (blob instanceof Blob) {
  190. const url = URL.createObjectURL(blob);
  191. const a = document.createElement('a');
  192. a.href = url;
  193. a.download = filename;
  194. a.click();
  195. URL.revokeObjectURL(url);
  196. }
  197. },
  198.  
  199. post(url, data, headers, type) {
  200. if (this.isType(data) === 'object') {
  201. data = JSON.stringify(data);
  202. }
  203. return new Promise((resolve, reject) => {
  204. GM_xmlhttpRequest({
  205. method: "POST", url, headers, data,
  206. responseType: type || 'json',
  207. onload: (res) => {
  208. type === 'blob' ? resolve(res) : resolve(res.response || res.responseText);
  209. },
  210. onerror: (err) => {
  211. reject(err);
  212. },
  213. });
  214. });
  215. },
  216.  
  217. get(url, headers, type, extra) {
  218. return new Promise((resolve, reject) => {
  219. let requestObj = GM_xmlhttpRequest({
  220. method: "GET", url, headers,
  221. responseType: type || 'json',
  222. onload: (res) => {
  223. if (res.status === 204) {
  224. requestObj.abort();
  225. idm[extra.index] = true;
  226. }
  227. if (type === 'blob') {
  228. res.status === 200 && base.blobDownload(res.response, extra.filename);
  229. resolve(res);
  230. } else {
  231. resolve(res.response || res.responseText);
  232. }
  233. },
  234. onprogress: (res) => {
  235. if (extra && extra.filename && extra.index) {
  236. res.total > 0 ? progress[extra.index] = (res.loaded * 100 / res.total).toFixed(2) : progress[extra.index] = 0.00;
  237. }
  238. },
  239. onloadstart() {
  240. extra && extra.filename && extra.index && (request[extra.index] = requestObj);
  241. },
  242. onerror: (err) => {
  243. reject(err);
  244. },
  245. });
  246. });
  247. },
  248.  
  249. getFinalUrl(url, headers) {
  250. return new Promise((resolve, reject) => {
  251. let requestObj = GM_xmlhttpRequest({
  252. method: "GET", url, headers,
  253. onload: (res) => {
  254. resolve(res.finalUrl);
  255. },
  256. onerror: (err) => {
  257. reject(err);
  258. },
  259. });
  260. });
  261. },
  262.  
  263. addStyle(id, tag, css) {
  264. tag = tag || 'style';
  265. let doc = document, styleDom = doc.getElementById(id);
  266. if (styleDom) return;
  267. let style = doc.createElement(tag);
  268. style.rel = 'stylesheet';
  269. style.id = id;
  270. tag === 'style' ? style.innerHTML = css : style.href = css;
  271. doc.getElementsByTagName('head')[0].appendChild(style);
  272. },
  273.  
  274. findReact(dom, traverseUp = 0) {
  275. const key = Object.keys(dom).find(key => {
  276. return key.startsWith("__reactFiber$")
  277. || key.startsWith("__reactInternalInstance$");
  278. });
  279. const domFiber = dom[key];
  280. if (domFiber == null) return null;
  281.  
  282. if (domFiber._currentElement) {
  283. let compFiber = domFiber._currentElement._owner;
  284. for (let i = 0; i < traverseUp; i++) {
  285. compFiber = compFiber._currentElement._owner;
  286. }
  287. return compFiber._instance;
  288. }
  289.  
  290. const GetCompFiber = fiber => {
  291. let parentFiber = fiber.return;
  292. while (typeof parentFiber.type == "string") {
  293. parentFiber = parentFiber.return;
  294. }
  295. return parentFiber;
  296. };
  297. let compFiber = GetCompFiber(domFiber);
  298. for (let i = 0; i < traverseUp; i++) {
  299. compFiber = GetCompFiber(compFiber);
  300. }
  301. return compFiber.stateNode || compFiber;
  302. },
  303.  
  304. initDefaultConfig() {
  305. let value = [{
  306. name: 'setting_rpc_domain',
  307. value: 'http://localhost'
  308. }, {
  309. name: 'setting_rpc_port',
  310. value: '16800'
  311. }, {
  312. name: 'setting_rpc_path',
  313. value: '/jsonrpc'
  314. }, {
  315. name: 'setting_rpc_token',
  316. value: ''
  317. }, {
  318. name: 'setting_rpc_dir',
  319. value: 'D:'
  320. }, {
  321. name: 'setting_terminal_type',
  322. value: 'wc'
  323. }, {
  324. name: 'setting_theme_color',
  325. value: '#09AAFF'
  326. }, {
  327. name: 'setting_init_code',
  328. value: ''
  329. }];
  330.  
  331. value.forEach((v) => {
  332. base.getValue(v.name) === undefined && base.setValue(v.name, v.value);
  333. });
  334. },
  335.  
  336. showSetting() {
  337. let dom = '', btn = '',
  338. colorList = ['#09AAFF', '#cc3235', '#526efa', '#518c17', '#ed944b', '#f969a5', '#bca280'];
  339. dom += `<label class="pl-setting-label"><div class="pl-label">RPC主机</div><input type="text" placeholder="主机地址,需带上http(s)://" class="pl-input listener-domain" value="${base.getValue('setting_rpc_domain')}"></label>`;
  340. dom += `<label class="pl-setting-label"><div class="pl-label">RPC端口</div><input type="text" placeholder="端口号,例如:Motrix为16800" class="pl-input listener-port" value="${base.getValue('setting_rpc_port')}"></label>`;
  341. dom += `<label class="pl-setting-label"><div class="pl-label">RPC路径</div><input type="text" placeholder="路径,默认为/jsonrpc" class="pl-input listener-path" value="${base.getValue('setting_rpc_path')}"></label>`;
  342. dom += `<label class="pl-setting-label"><div class="pl-label">RPC密钥</div><input type="text" placeholder="无密钥无需填写" class="pl-input listener-token" value="${base.getValue('setting_rpc_token')}"></label>`;
  343. dom += `<label class="pl-setting-label"><div class="pl-label">保存路径</div><input type="text" placeholder="文件下载后保存路径,例如:D:" class="pl-input listener-dir" value="${base.getValue('setting_rpc_dir')}"></label>`;
  344.  
  345. colorList.forEach((v) => {
  346. btn += `<div data-color="${v}" style="background: ${v};border: 1px solid ${v}" class="pl-color-box listener-color ${v === base.getValue('setting_theme_color') ? 'checked' : ''}"></div>`;
  347. });
  348. dom += `<label class="pl-setting-label"><div class="pl-label">终端类型</div><select class="pl-input listener-terminal">`;
  349. Object.keys(terminalType).forEach(k => {
  350. dom += `<option value="${k}" ${base.getValue('setting_terminal_type') === k ? 'selected' : ''}>${terminalType[k]}</option>`;
  351. });
  352. dom += `</select></label>`;
  353. dom += `<label class="pl-setting-label"><div class="pl-label">主题颜色</div> <div class="pl-color">${btn}<div></label>`;
  354. dom = '<div>' + dom + '</div>';
  355.  
  356. Swal.fire({
  357. title: '助手配置',
  358. html: dom,
  359. icon: 'info',
  360. showCloseButton: true,
  361. showConfirmButton: false,
  362. footer: pan.footer,
  363. }).then(() => {
  364. message.success('设置成功!');
  365. history.go(0);
  366. });
  367.  
  368. doc.on('click', '.listener-color', async (e) => {
  369. base.setValue('setting_theme_color', e.target.dataset.color);
  370. message.success('设置成功!');
  371. history.go(0);
  372. });
  373. doc.on('input', '.listener-domain', async (e) => {
  374. base.setValue('setting_rpc_domain', e.target.value);
  375. });
  376. doc.on('input', '.listener-port', async (e) => {
  377. base.setValue('setting_rpc_port', e.target.value);
  378. });
  379. doc.on('input', '.listener-path', async (e) => {
  380. base.setValue('setting_rpc_path', e.target.value);
  381. });
  382. doc.on('input', '.listener-token', async (e) => {
  383. base.setValue('setting_rpc_token', e.target.value);
  384. });
  385. doc.on('input', '.listener-dir', async (e) => {
  386. base.setValue('setting_rpc_dir', e.target.value);
  387. });
  388. doc.on('change', '.listener-terminal', async (e) => {
  389. base.setValue('setting_terminal_type', e.target.value);
  390. });
  391. },
  392.  
  393. registerMenuCommand() {
  394. GM_registerMenuCommand('⚙️ 设置', () => {
  395. this.showSetting();
  396. });
  397. },
  398.  
  399. createTip() {
  400. $('body').append('<div class="pl-tooltip"></div>');
  401.  
  402. doc.on('mouseenter mouseleave', '.listener-tip', (e) => {
  403. if (e.type === 'mouseenter') {
  404. let filename = e.currentTarget.innerText;
  405. let size = e.currentTarget.dataset.size;
  406. let tip = `${filename}<span style="margin-left: 10px;color: #f56c6c;">${size}</span>`;
  407. $(e.currentTarget).css({opacity: '0.5'});
  408. $('.pl-tooltip').html(tip).css({
  409. 'left': e.pageX + 10 + 'px',
  410. 'top': e.pageY - e.currentTarget.offsetTop > 14 ? e.pageY + 'px' : e.pageY + 20 + 'px'
  411. }).show();
  412. } else {
  413. $(e.currentTarget).css({opacity: '1'});
  414. $('.pl-tooltip').hide(0);
  415. }
  416. });
  417. },
  418.  
  419. createLoading() {
  420. return $('<div class="pl-loading"><div class="pl-loading-box"><div><div></div><div></div></div></div></div>');
  421. },
  422.  
  423. createDownloadIframe() {
  424. let $div = $('<div style="padding:0;margin:0;display:block"></div>');
  425. let $iframe = $('<iframe src="javascript:;" id="downloadIframe" style="display:none"></iframe>');
  426. $div.append($iframe);
  427. $('body').append($div);
  428. },
  429.  
  430. getMirrorList(link, mirror, thread = 2) {
  431. let host = new URL(link).host;
  432. let mirrors = [];
  433. for (let i = 0; i < mirror.length; i++) {
  434. for (let j = 0; j < thread; j++) {
  435. let item = link.replace(host, mirror[i]) + '&'.repeat(j);
  436. mirrors.push(item);
  437. }
  438. }
  439. return mirrors.join('\n');
  440. },
  441.  
  442. addPanLinkerStyle() {
  443. color = base.getValue('setting_theme_color');
  444. let css = `
  445. body::-webkit-scrollbar { display: none }
  446. ::-webkit-scrollbar { width: 6px; height: 10px }
  447. ::-webkit-scrollbar-track { border-radius: 0; background: none }
  448. ::-webkit-scrollbar-thumb { background-color: rgba(85,85,85,.4) }
  449. ::-webkit-scrollbar-thumb,::-webkit-scrollbar-thumb:hover { border-radius: 5px; -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.2) }
  450. ::-webkit-scrollbar-thumb:hover { background-color: rgba(85,85,85,.3) }
  451. .swal2-popup { font-size: 16px !important; }
  452. .pl-popup { font-size: 12px !important; }
  453. .pl-popup a { color: ${color} !important; }
  454. .pl-header { padding: 0!important;align-items: flex-start!important; border-bottom: 1px solid #eee!important; margin: 0 0 10px!important; padding: 0 0 5px!important; }
  455. .pl-title { font-size: 16px!important; line-height: 1!important;white-space: nowrap!important; text-overflow: ellipsis!important;}
  456. .pl-content { padding: 0 !important; font-size: 12px!important; }
  457. .pl-main { max-height: 400px;overflow-y:scroll; }
  458. .pl-footer {font-size: 15px!important;justify-content: flex-start!important; margin: 10px 0 0!important; padding: 5px 0 0!important; color: #f56c6c!important; height:25px;}
  459. .pl-item { display: flex; align-items: center; line-height: 22px; }
  460. .pl-item-name { flex: 0 0 200px; text-align: left;margin-right: 10px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; cursor:default; height: 30px;}
  461. .pl-item-link { flex: 1; text-align: left; white-space: nowrap; text-overflow: ellipsis;cursor:pointer }
  462. .pl-item-btn { background: ${color}; padding: 4px 5px; border-radius: 3px; line-height: 1; cursor: pointer; color: #fff; }
  463. .pl-item-tip { display: flex; justify-content: space-between;flex: 1; }
  464. .pl-back { width: 70px; background: #ddd; border-radius: 3px; cursor:pointer; margin:1px 0; }
  465. .pl-ext { display: inline-block; width: 44px; background: #999; color: #fff; height: 16px; line-height: 16px; font-size: 12px; border-radius: 3px;}
  466. .pl-retry {padding: 3px 10px; background: #cc3235; color: #fff; border-radius: 3px; cursor: pointer;}
  467. .pl-browserdownload { padding: 3px 10px; background: ${color}; color: #fff; border-radius: 3px; cursor: pointer;}
  468. .pl-item-progress { display:flex;flex: 1;align-items:center}
  469. .pl-progress { display: inline-block;vertical-align: middle;width: 100%; box-sizing: border-box;line-height: 1;position: relative;height:15px; flex: 1}
  470. .pl-progress-outer { height: 15px;border-radius: 100px;background-color: #ebeef5;overflow: hidden;position: relative;vertical-align: middle;}
  471. .pl-progress-inner{ position: absolute;left: 0;top: 0;background-color: #409eff;text-align: right;border-radius: 100px;line-height: 1;white-space: nowrap;transition: width .6s ease;}
  472. .pl-progress-inner-text { display: inline-block;vertical-align: middle;color: #d1d1d1;font-size: 12px;margin: 0 5px;height: 15px}
  473. .pl-progress-tip{ flex:1;text-align:right}
  474. .pl-progress-how{ flex: 0 0 100px; background: #ddd; border-radius: 3px; margin-left: 10px; cursor: pointer; text-align: center;}
  475. .pl-progress-stop{ flex: 0 0 75px; padding: 0 10px; background: #cc3235; color: #fff; border-radius: 3px; cursor: pointer;margin-left:10px;height:20px}
  476. .pl-progress-inner-text:after { display: inline-block;content: "";height: 100%;vertical-align: middle;}
  477. .pl-btn-primary { background: ${color}; border: 0; border-radius: 4px; color: #ffffff; cursor: pointer; font-size: 12px; outline: none; display:flex; align-items: center; justify-content: center; margin: 2px 0; padding: 6px 0;transition: 0.3s opacity; }
  478. .pl-btn-primary:hover { opacity: 0.9;transition: 0.3s opacity; }
  479. .pl-btn-success { background: #55af28; animation: easeOpacity 1.2s 2; animation-fill-mode:forwards }
  480. .pl-btn-info { background: #606266; }
  481. .pl-btn-warning { background: #da9328; }
  482. .pl-btn-warning { background: #da9328; }
  483. .pl-btn-danger { background: #cc3235; }
  484. .ali-button {display: inline-flex;align-items: center;justify-content: center;border: 0 solid transparent;border-radius: 5px;box-shadow: 0 0 0 0 transparent;width: fit-content;white-space: nowrap;flex-shrink: 0;font-size: 14px;line-height: 1.5;outline: 0;touch-action: manipulation;transition: background .3s ease,color .3s ease,border .3s ease,box-shadow .3s ease;color: #fff;background: rgb(99 125 255);margin-left: 20px;padding: 1px 12px;position: relative; cursor:pointer; height: 32px;}
  485. .ali-button:hover {background: rgb(122, 144, 255)}
  486. .tianyi-button {margin-right: 20px; padding: 4px 12px; border-radius: 4px; color: #fff; font-size: 12px; border: 1px solid #0073e3; background: #2b89ea; cursor: pointer; position: relative;}
  487. .tianyi-button:hover {border-color: #1874d3; background: #3699ff;}
  488. .xunlei-button {display: inline-flex;align-items: center;justify-content: center;border: 0 solid transparent;border-radius: 5px;box-shadow: 0 0 0 0 transparent;width: fit-content;white-space: nowrap;flex-shrink: 0;font-size: 14px;line-height: 1.5;outline: 0;touch-action: manipulation;transition: background .3s ease,color .3s ease,border .3s ease,box-shadow .3s ease;color: #fff;background: #3f85ff;margin-left: 12px;padding: 0px 12px;position: relative; cursor:pointer; height: 36px;}
  489. .xunlei-button:hover {background: #619bff}
  490. .quark-button {display: inline-flex; align-items: center; justify-content: center; border: 1px solid #ddd; border-radius: 8px; white-space: nowrap; flex-shrink: 0; font-size: 14px; line-height: 1.5; outline: 0; color: #333; background: #fff; margin-right: 10px; padding: 0px 14px; position: relative; cursor: pointer; height: 36px;}
  491. .quark-button:hover { background:#f6f6f6 }
  492. .pl-dropdown-menu {position: absolute;right: 0;top: 30px;padding: 5px 0;color: rgb(37, 38, 43);background: #fff;z-index: 999;width: 102px;border: 1px solid #ddd;border-radius: 10px; box-shadow: 0 0 1px 1px rgb(28 28 32 / 5%), 0 8px 24px rgb(28 28 32 / 12%);}
  493. .pl-dropdown-menu-item { height: 30px;display: flex;align-items: center;justify-content: center; }
  494. .pl-dropdown-menu-item:hover { background-color: rgba(132,133,141,0.08);}
  495. .pl-button .pl-dropdown-menu { display: none; }
  496. .pl-button:hover .pl-dropdown-menu { display: block!important; }
  497. .pl-button-init { opacity: 0.5; animation: easeInitOpacity 1.2s 3; animation-fill-mode:forwards }
  498. @keyframes easeInitOpacity { from { opacity: 0.5; } 50% { opacity: 1 } to { opacity: 0.5; } }
  499. @keyframes easeOpacity { from { opacity: 1; } 50% { opacity: 0.35 } to { opacity: 1; } }
  500. .element-clicked { opacity: 0.5; }
  501. .pl-extra { margin-top: 10px;display:flex}
  502. .pl-extra button { flex: 1}
  503. .pointer { cursor:pointer }
  504. .pl-setting-label { display: flex;align-items: center;justify-content: space-between;padding-top: 10px; }
  505. .pl-label { flex: 0 0 100px;text-align:left; }
  506. .pl-input { flex: 1; padding: 8px 10px; border: 1px solid #c2c2c2; border-radius: 5px; font-size: 14px }
  507. .pl-color { flex: 1;display: flex;flex-wrap: wrap; margin-right: -10px;}
  508. .pl-color-box { width: 35px;height: 35px;margin:10px 10px 0 0;; box-sizing: border-box;border:1px solid #fff;cursor:pointer }
  509. .pl-color-box.checked { border:3px dashed #111!important }
  510. .pl-close:focus { outline: 0; box-shadow: none; }
  511. .tag-danger {color:#cc3235;margin: 0 5px;}
  512. .pl-tooltip { position: absolute; color: #ffffff; max-width: 600px; font-size: 12px; padding: 5px 10px; background: #333; border-radius: 5px; z-index: 110000; line-height: 1.3; display:none; word-break: break-all;}
  513. @keyframes load { 0% { transform: rotate(0deg) } 100% { transform: rotate(360deg) } }
  514. .pl-loading-box > div > div { position: absolute;border-radius: 50%;}
  515. .pl-loading-box > div > div:nth-child(1) { top: 9px;left: 9px;width: 82px;height: 82px;background: #ffffff;}
  516. .pl-loading-box > div > div:nth-child(2) { top: 14px;left: 38px;width: 25px;height: 25px;background: #666666;animation: load 1s linear infinite;transform-origin: 12px 36px;}
  517. .pl-loading { width: 16px;height: 16px;display: inline-block;overflow: hidden;background: none;}
  518. .pl-loading-box { width: 100%;height: 100%;position: relative;transform: translateZ(0) scale(0.16);backface-visibility: hidden;transform-origin: 0 0;}
  519. .pl-loading-box div { box-sizing: content-box; }
  520. .swal2-container { z-index:100000!important; }
  521. body.swal2-height-auto { height: inherit!important; }
  522. `;
  523. this.addStyle('panlinker-style', 'style', css);
  524. },
  525.  
  526. async initDialog() {
  527. let result = await Swal.fire({
  528. title: pan.init[0],
  529. allowOutsideClick: false,
  530. showCloseButton: true,
  531. showCancelButton: true,
  532. cancelButtonColor: '#d33',
  533. confirmButtonText: '确定',
  534. html: `<div><img style="width: 250px;margin-bottom: 10px;" src="${pan.img}" alt="${pan.img}"><input class="swal2-input" id="init" style="width:373;font-size:19px;" type="text" placeholder="${pan.init[1]}"><span>你可以选择“注入”立即点亮按钮,<br>或者在输入框键入以下暗号:“${pan.num}”。</span></div>`,
  535. cancelButtonText: '注入(点亮下载助手按钮)'
  536. });
  537. if (result.isDismissed && result.dismiss === 'close') return;
  538. if (result.isDismissed && result.dismiss === 'cancel') {
  539. console.log("正在注入点亮按钮设置项目...");
  540. message.warning("正在注入点亮按钮设置项目...");
  541. setTimeout(() => {
  542. base.setValue('setting_init_code', pan.num);
  543. message.success("注入成功!");
  544. setTimeout(() => {
  545. message.success(pan.init[2]);
  546. setTimeout(() => {
  547. history.go(0);
  548. }, 3000);
  549. }, 3000);
  550. }, 5000);
  551. return;
  552. };
  553. if (pan.num === $('#init').val()) {
  554. base.setValue('setting_init_code', pan.num);
  555. message.success(pan.init[2]);
  556. setTimeout(() => {
  557. history.go(0);
  558. }, 3000);
  559. } else {
  560. await Swal.fire({
  561. imageUrl: pan.img,
  562. title: pan.init[3],
  563. html: `<div><span>${pan.init[4]}<br>你可以在返回后选择“注入”立即点亮按钮,<br>或者在输入框键入以下暗号:“${pan.num}”。</span></div>`,
  564. confirmButtonText: '重新输入(返回)',
  565. });
  566. await this.initDialog();
  567. }
  568. },
  569. };
  570.  
  571. let baidu = {
  572.  
  573. _getExtra() {
  574. let seKey = decodeURIComponent(base.getCookie('BDCLND'));
  575. return '{' + '"sekey":"' + seKey + '"' + "}";
  576. },
  577.  
  578. _getSurl() {
  579. let reg = /(?<=s\/|surl=)([a-zA-Z0-9_-]+)/g;
  580. if (reg.test(location.href)) {
  581. return location.href.match(reg)[0];
  582. }
  583. return '';
  584. },
  585.  
  586. _getFidList() {
  587. let fidlist = [];
  588. selectList.forEach(v => {
  589. if (+v.isdir === 1) return;
  590. fidlist.push(v.fs_id);
  591. });
  592. return '[' + fidlist + ']';
  593. },
  594.  
  595. _resetData() {
  596. progress = {};
  597. $.each(request, (key) => {
  598. (request[key]).abort();
  599. });
  600. $.each(ins, (key) => {
  601. clearInterval(ins[key]);
  602. });
  603. idm = {};
  604. ins = {};
  605. request = {};
  606. },
  607.  
  608. setBDUSS() {
  609. try {
  610. GM_cookie && GM_cookie('list', {name: 'BDUSS'}, (cookies, error) => {
  611. if (!error) {
  612. base.setStorage("baiduyunPlugin_BDUSS", {BDUSS: cookies[0].value});
  613. }
  614. });
  615. } catch (e) {
  616. }
  617. },
  618.  
  619. getBDUSS() {
  620. let baiduyunPlugin_BDUSS = base.getStorage('baiduyunPlugin_BDUSS') ? base.getStorage('baiduyunPlugin_BDUSS') : '{"baiduyunPlugin_BDUSS":""}';
  621. return baiduyunPlugin_BDUSS.BDUSS || '';
  622. },
  623.  
  624. convertLinkToAria(link, filename, ua) {
  625. let BDUSS = this.getBDUSS();
  626. if (!!BDUSS) {
  627. filename = filename.replace(' ', '_');
  628. return encodeURIComponent(`aria2c "${link}" --out "${filename}" --header "User-Agent: ${ua}" --header "Cookie: BDUSS=${BDUSS}"`);
  629. }
  630. return {
  631. link: pan.assistant,
  632. text: pan.init[5]
  633. };
  634. },
  635.  
  636. convertLinkToBC(link, filename, ua) {
  637. let BDUSS = this.getBDUSS();
  638. if (!!BDUSS) {
  639. let cookie = `BDUSS=${BDUSS}`;
  640. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}&cookie=${encodeURIComponent(cookie)}&user_agent=${encodeURIComponent(ua)}ZZ`;
  641. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  642. }
  643. return {
  644. link: pan.assistant,
  645. text: pan.init[5]
  646. };
  647. },
  648.  
  649. convertLinkToCurl(link, filename, ua) {
  650. let BDUSS = this.getBDUSS();
  651. if (!!BDUSS) {
  652. let terminal = base.getValue('setting_terminal_type');
  653. filename = filename.replace(' ', '_');
  654. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L "${link}" --output "${filename}" -A "${ua}" -b "BDUSS=${BDUSS}"`);
  655. }
  656. return {
  657. link: pan.assistant,
  658. text: pan.init[5]
  659. };
  660. },
  661.  
  662. addPageListener() {
  663. function _factory(e) {
  664. let target = $(e.target);
  665. let item = target.parents('.pl-item');
  666. let link = item.find('.pl-item-link');
  667. let progress = item.find('.pl-item-progress');
  668. let tip = item.find('.pl-item-tip');
  669. return {
  670. item, link, progress, tip, target,
  671. };
  672. }
  673.  
  674. function _reset(i) {
  675. ins[i] && clearInterval(ins[i]);
  676. request[i] && request[i].abort();
  677. progress[i] = 0;
  678. idm[i] = false;
  679. }
  680.  
  681. doc.on('mouseenter mouseleave click', '.pl-button.g-dropdown-button', (e) => {
  682. if (e.type === 'mouseleave') {
  683. $(e.currentTarget).removeClass('button-open');
  684. } else {
  685. $(e.currentTarget).addClass('button-open');
  686. $(e.currentTarget).find('.pl-dropdown-menu').show();
  687. }
  688. });
  689. doc.on('mouseleave', '.pl-button.g-dropdown-button .pl-dropdown-menu', (e) => {
  690. $(e.currentTarget).hide();
  691. });
  692.  
  693. doc.on('click', '.pl-button-mode', (e) => {
  694. mode = e.target.dataset.mode;
  695. Swal.showLoading();
  696. this.getPCSLink();
  697. });
  698. doc.on('click', '.listener-link-api', async (e) => {
  699. e.preventDefault();
  700. let o = _factory(e);
  701. let $width = o.item.find('.pl-progress-inner');
  702. let $text = o.item.find('.pl-progress-inner-text');
  703. let filename = o.link[0].dataset.filename;
  704. let index = o.link[0].dataset.index;
  705. _reset(index);
  706. base.get(o.link[0].dataset.link, {"User-Agent": pan.ua}, 'blob', {filename, index});
  707. ins[index] = setInterval(() => {
  708. let prog = +progress[index] || 0;
  709. let isIDM = idm[index] || false;
  710. if (isIDM) {
  711. o.tip.hide();
  712. o.progress.hide();
  713. o.link.text('已成功唤起IDM,请查看IDM下载框!').animate({opacity: '0.5'}, "slow").show();
  714. clearInterval(ins[index]);
  715. idm[index] = false;
  716. } else {
  717. o.link.hide();
  718. o.tip.hide();
  719. o.progress.show();
  720. $width.css('width', prog + '%');
  721. $text.text(prog + '%');
  722. if (prog === 100) {
  723. clearInterval(ins[index]);
  724. progress[index] = 0;
  725. o.item.find('.pl-progress-stop').hide();
  726. o.item.find('.pl-progress-tip').html('下载完成,正在弹出浏览器下载框!');
  727. }
  728. }
  729. }, 500);
  730. });
  731. doc.on('click', '.listener-retry', async (e) => {
  732. let o = _factory(e);
  733. o.tip.hide();
  734. o.link.show();
  735. });
  736. doc.on('click', '.listener-how', async (e) => {
  737. let o = _factory(e);
  738. let index = o.link[0].dataset.index;
  739. if (request[index]) {
  740. request[index].abort();
  741. clearInterval(ins[index]);
  742. o.progress.hide();
  743. o.tip.show();
  744. }
  745.  
  746. });
  747. doc.on('click', '.listener-stop', async (e) => {
  748. let o = _factory(e);
  749. let index = o.link[0].dataset.index;
  750. if (request[index]) {
  751. request[index].abort();
  752. clearInterval(ins[index]);
  753. o.tip.hide();
  754. o.progress.hide();
  755. o.link.show(0);
  756. }
  757. });
  758. doc.on('click', '.listener-back', async (e) => {
  759. let o = _factory(e);
  760. o.tip.hide();
  761. o.link.show();
  762. });
  763. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  764. e.preventDefault();
  765. if (!e.target.dataset.link) {
  766. $(e.target).removeClass('listener-copy-all').addClass('pl-btn-danger').html(`${pan.init[5]}👉<a href="${pan.assistant}" target="_blank" class="pl-a">点击此处安装</a>👈`);
  767. } else {
  768. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  769. $(e.target).text('复制成功,快去粘贴吧!').animate({opacity: '0.5'}, "slow");
  770. }
  771. });
  772. doc.on('click', '.listener-link-rpc', async (e) => {
  773. let target = $(e.currentTarget);
  774. target.find('.icon').remove();
  775. target.find('.pl-loading').remove();
  776. target.prepend(base.createLoading());
  777. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  778. if (res === 'success') {
  779. $('.listener-rpc-task').show();
  780. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  781. } else if (res === 'assistant') {
  782. target.addClass('pl-btn-danger').html(`${pan.init[5]}👉<a href="${pan.assistant}" target="_blank" class="pl-a">点击此处安装</a>👈`);
  783. } else {
  784. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  785. }
  786. });
  787. doc.on('click', '.listener-send-rpc', (e) => {
  788. $('.listener-link-rpc').click();
  789. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  790. });
  791. doc.on('click', '.listener-open-setting', () => {
  792. base.showSetting();
  793. });
  794. doc.on('click', '.listener-rpc-task', () => {
  795. let rpc = JSON.stringify({
  796. domain: base.getValue('setting_rpc_domain'),
  797. port: base.getValue('setting_rpc_port'),
  798. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  799. GM_openInTab(url, {active: true});
  800. });
  801. document.documentElement.addEventListener('mouseup', (e) => {
  802. if (e.target.nodeName === 'A' && ~e.target.className.indexOf('pl-a')) {
  803. e.stopPropagation();
  804. }
  805. }, true);
  806. },
  807.  
  808. addButton() {
  809. if (!pt) return;
  810. let $toolWrap;
  811. let $button = $(`<div class="g-dropdown-button pointer pl-button"><div style="color:#fff;background: ${color};border-color:${color}" class="g-button g-button-blue"><span class="g-button-right"><em class="icon icon-download"></em><span class="text" style="width: 60px;">下载助手</span></span></div><div class="menu" style="width:auto;z-index:41;border-color:${color}"><div style="color:${color}" class="g-button-menu pl-button-mode" data-mode="api">API下载</div><div style="color:${color}" class="g-button-menu pl-button-mode" data-mode="aria">Aria下载</div><div style="color:${color}" class="g-button-menu pl-button-mode" data-mode="rpc">RPC下载</div><div style="color:${color}" class="g-button-menu pl-button-mode" data-mode="curl">cURL下载</div><div style="color:${color}" class="g-button-menu pl-button-mode" data-mode="bc">BC下载</div></div></div>`);
  812. if (pt === 'home') $toolWrap = $(pan.btn.home);
  813. if (pt === 'main') {
  814. $toolWrap = $(pan.btn.main);
  815. $button = $(`<div class="pl-button" style="position: relative; display: inline-block; margin-right: 8px;"><button class="u-button u-button--primary u-button--small is-round is-has-icon" style="background: ${color};border-color: ${color};font-size: 14px; padding: 8px 16px; border: none;"><i class="u-icon u-icon-download"></i><span>下载助手</span></button><ul class="dropdown-list nd-common-float-menu pl-dropdown-menu"><li class="sub cursor-p pl-button-mode" data-mode="api">API下载</li><li class="sub cursor-p pl-button-mode" data-mode="aria">Aria下载</li><li class="sub cursor-p pl-button-mode" data-mode="rpc">RPC下载</li><li class="sub cursor-p pl-button-mode" data-mode="curl">cURL下载</li><li class="sub cursor-p pl-button-mode" data-mode="bc" >BC下载</li></ul></div>`);
  816. }
  817. if (pt === 'share') $toolWrap = $(pan.btn.share);
  818. $toolWrap.prepend($button);
  819. this.setBDUSS();
  820. this.addPageListener();
  821. },
  822.  
  823. addInitButton() {
  824. if (!pt) return;
  825. let $toolWrap;
  826. let $button = $(`<div class="g-dropdown-button pointer pl-button-init" style="opacity:.5"><div style="color:#fff;background: ${color};border-color:${color}" class="g-button g-button-blue"><span class="g-button-right"><em class="icon icon-download"></em><span class="text" style="width: 60px;">下载助手</span></span></div></div>`);
  827. if (pt === 'home') $toolWrap = $(pan.btn.home);
  828. if (pt === 'main') {
  829. $toolWrap = $(pan.btn.main);
  830. $button = $(`<div class="pl-button-init" style="opacity:.5; display: inline-block; margin-right: 8px;"><button class="u-button u-button--primary u-button--small is-round is-has-icon" style="background: ${color};border-color: ${color};font-size: 14px; padding: 8px 16px; border: none;"><i class="u-icon u-icon-download"></i><span>下载助手</span></button></div>`);
  831. }
  832. if (pt === 'share') $toolWrap = $(pan.btn.share);
  833. $toolWrap.prepend($button);
  834. $button.click(() => base.initDialog());
  835. },
  836.  
  837. async getPCSLink() {
  838. selectList = this.getSelectedList();
  839. let fidList = this._getFidList(), url, res;
  840.  
  841. if (pt === 'home' || pt === 'main') {
  842. if (selectList.length === 0) {
  843. return message.error('提示:请先勾选要下载的文件!');
  844. }
  845. if (fidList.length === 2) {
  846. return message.error('提示:请打开文件夹后勾选文件!');
  847. }
  848. fidList = encodeURIComponent(fidList);
  849. url = `${pan.pcs[0]}&fsids=${fidList}`;
  850. res = await base.get(url, {"User-Agent": pan.ua});
  851. }
  852. if (pt === 'share') {
  853. this.getShareData();
  854. if (selectList.length === 0) {
  855. return message.error('提示:请先勾选要下载的文件!');
  856. }
  857. if (fidList.length === 2) {
  858. return message.error('提示:请打开文件夹后勾选文件!');
  859. }
  860. if (!params.sign) {
  861. let url = `${pan.pcs[2]}&surl=${params.surl}&logid=${params.logid}`;
  862. let r = await base.get(url);
  863. if (r.errno === 0) {
  864. params.sign = r.data.sign;
  865. params.timestamp = r.data.timestamp;
  866. } else {
  867. let dialog = await Swal.fire({
  868. toast: true,
  869. icon: 'info',
  870. title: `提示:请将文件<span class="tag-danger">[保存到网盘]</span>👉前往<span class="tag-danger">[我的网盘]</span>中下载!`,
  871. showConfirmButton: true,
  872. confirmButtonText: '点击保存',
  873. position: 'top',
  874. });
  875. if (dialog.isConfirmed) {
  876. $('.tools-share-save-hb')[0].click();
  877. }
  878. return;
  879. }
  880. }
  881. if (!params.bdstoken) {
  882. return message.error('提示:请先登录网盘!');
  883. }
  884. let formData = new FormData();
  885. formData.append('encrypt', params.encrypt);
  886. formData.append('product', params.product);
  887. formData.append('uk', params.uk);
  888. formData.append('primaryid', params.primaryid);
  889. formData.append('fid_list', fidList);
  890. formData.append('logid', params.logid);
  891. params.shareType === 'secret' ? formData.append('extra', params.extra) : '';
  892. url = `${pan.pcs[1]}&sign=${params.sign}&timestamp=${params.timestamp}`;
  893. res = await base.post(url, formData, {"User-Agent": pan.ua});
  894. }
  895. if (res.errno === 0) {
  896. let html = this.generateDom(res.list);
  897. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  898. } else if (res.errno === 112) {
  899. return message.error('提示:页面过期,请刷新重试!');
  900. } else {
  901. message.error('提示:获取下载链接失败!请刷新网页后重试!');
  902. }
  903. },
  904.  
  905. generateDom(list) {
  906. let content = '<div class="pl-main">';
  907. let alinkAllText = '';
  908. base.sortByName(list);
  909. list.forEach((v, i) => {
  910. if (v.isdir === 1) return;
  911. let filename = v.server_filename || v.filename;
  912. let ext = base.getExtension(filename);
  913. let size = base.sizeFormat(v.size);
  914. let dlink = v.dlink;
  915. if (mode === 'api') {
  916. content += `<div class="pl-item">
  917. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  918. <a class="pl-item-link pl-a listener-link-api" href="${dlink}" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}<br>下载 ${filename}</a>
  919. <div class="pl-item-tip" style="display: none"><span>若没有弹出IDM下载框,找到IDM <b>选项</b> -> <b>文件类型</b> -> <b>第一个框</b> 中添加后缀 <span class="pl-ext">${ext}</span>,<a href="${pan.idm}" target="_blank" class="pl-a">详见此处</a></span> <span class="pl-back listener-back">返回</span></div>
  920. <div class="pl-item-progress" style="display: none">
  921. <div class="pl-progress">
  922. <div class="pl-progress-outer"></div>
  923. <div class="pl-progress-inner" style="width:5%">
  924. <div class="pl-progress-inner-text">0%</div>
  925. </div>
  926. </div>
  927. <span class="pl-progress-stop listener-stop">取消下载</span>
  928. <span class="pl-progress-tip">未发现IDM,使用自带浏览器下载</span>
  929. <span class="pl-progress-how listener-how">如何唤起IDM?</span>
  930. </div></div>`;
  931. }
  932. if (mode === 'aria') {
  933. let alink = this.convertLinkToAria(dlink, filename, pan.ua);
  934. if (typeof (alink) === 'object') {
  935. content += `<div class="pl-item">
  936. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  937. <a class="pl-item-link pl-a" target="_blank" href="${alink.link}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}</a> </div>`;
  938. } else {
  939. alinkAllText += alink + '\r\n';
  940. content += `<div class="pl-item">
  941. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  942. <a class="pl-item-link pl-a listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  943. }
  944. }
  945. if (mode === 'rpc') {
  946. content += `<div class="pl-item">
  947. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  948. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">推送到 RPC 下载器</span></button></div>`;
  949. }
  950. if (mode === 'curl') {
  951. let alink = this.convertLinkToCurl(dlink, filename, pan.ua);
  952. if (typeof (alink) === 'object') {
  953. content += `<div class="pl-item">
  954. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  955. <a class="pl-item-link pl-a" target="_blank" href="${alink.link}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}</a> </div>`;
  956. } else {
  957. alinkAllText += alink + '\r\n';
  958. content += `<div class="pl-item">
  959. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  960. <a class="pl-item-link pl-a listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  961. }
  962. }
  963. if (mode === 'bc') {
  964. let alink = this.convertLinkToBC(dlink, filename, pan.ua);
  965. if (typeof (alink) === 'object') {
  966. content += `<div class="pl-item">
  967. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  968. <a class="pl-item-link pl-a" href="${decodeURIComponent(alink.link)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink.text)}</a> </div>`;
  969. } else {
  970. alinkAllText += alink + '\r\n';
  971. content += `<div class="pl-item">
  972. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  973. <a class="pl-item-link pl-a" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  974. }
  975. }
  976. });
  977. content += '</div>';
  978. if (mode === 'aria')
  979. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  980. if (mode === 'rpc') {
  981. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  982. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  983. }
  984. if (mode === 'curl')
  985. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">设置终端类型(当前为:${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;
  986. return content;
  987. },
  988.  
  989. async sendLinkToRPC(filename, link) {
  990. let rpc = {
  991. domain: base.getValue('setting_rpc_domain'),
  992. port: base.getValue('setting_rpc_port'),
  993. path: base.getValue('setting_rpc_path'),
  994. token: base.getValue('setting_rpc_token'),
  995. dir: base.getValue('setting_rpc_dir'),
  996. };
  997. let BDUSS = this.getBDUSS();
  998. if (!BDUSS) return 'assistant';
  999.  
  1000. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  1001. let rpcData = {
  1002. id: new Date().getTime(),
  1003. jsonrpc: '2.0',
  1004. method: 'aria2.addUri',
  1005. params: [`token:${rpc.token}`, [link], {
  1006. dir: rpc.dir,
  1007. out: filename,
  1008. header: [`User-Agent: ${pan.ua}`, `Cookie: BDUSS=${BDUSS}`]
  1009. }]
  1010. };
  1011. try {
  1012. let res = await base.post(url, rpcData, {"User-Agent": pan.ua}, '');
  1013. if (res.result) return 'success';
  1014. return 'fail';
  1015. } catch (e) {
  1016. return 'fail';
  1017. }
  1018. },
  1019.  
  1020. getSelectedList() {
  1021. try {
  1022. return require('system-core:context/context.js').instanceForSystem.list.getSelected();
  1023. } catch (e) {
  1024. return document.querySelector('.wp-s-core-pan').__vue__.selectedList;
  1025. }
  1026. },
  1027.  
  1028. getLogid() {
  1029. let ut = require("system-core:context/context.js").instanceForSystem.tools.baseService;
  1030. return ut.base64Encode(base.getCookie("BAIDUID"));
  1031. },
  1032.  
  1033. getShareData() {
  1034. let res = locals.dump();
  1035. params.shareType = 'secret';
  1036. params.sign = '';
  1037. params.timestamp = '';
  1038. params.bdstoken = res.bdstoken.value;
  1039. params.channel = 'chunlei';
  1040. params.clienttype = 0;
  1041. params.web = 1;
  1042. params.app_id = 250528;
  1043. params.encrypt = 0;
  1044. params.product = 'share';
  1045. params.logid = this.getLogid();
  1046. params.primaryid = res.shareid.value;
  1047. params.uk = res.share_uk.value;
  1048. params.shareType === 'secret' && (params.extra = this._getExtra());
  1049. params.surl = this._getSurl();
  1050. },
  1051.  
  1052. detectPage() {
  1053. let path = location.pathname;
  1054. if (/^\/disk\/home/.test(path)) return 'home';
  1055. if (/^\/disk\/main/.test(path)) return 'main';
  1056. if (/^\/(s|share)\//.test(path)) return 'share';
  1057. return '';
  1058. return '';
  1059. },
  1060.  
  1061. showMainDialog(title, html, footer) { //下载窗口
  1062. Swal.fire({
  1063. title,
  1064. html,
  1065. footer,
  1066. allowOutsideClick: false,
  1067. showCloseButton: true,
  1068. showConfirmButton: false,
  1069. position: 'top',
  1070. width: '1000px',
  1071. padding: '15px 20px 5px',
  1072. customClass,
  1073. }).then(() => {
  1074. this._resetData();
  1075. });
  1076. },
  1077.  
  1078. async initPanLinker() {
  1079. base.initDefaultConfig();
  1080. base.addPanLinkerStyle();
  1081. pt = this.detectPage();
  1082. let res = await base.post
  1083. (`https://api.youxiaohou.com/config?ver=${version}&a=${author}`, {}, {}, 'text');
  1084. pan = JSON.parse(base.d(res));
  1085. Object.freeze && Object.freeze(pan);
  1086. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  1087. base.createTip();
  1088. base.registerMenuCommand();
  1089. }
  1090. };
  1091.  
  1092. let ali = {
  1093.  
  1094. convertLinkToAria(link, filename, ua) {
  1095. filename = filename.replace(' ', '_');
  1096. return encodeURIComponent(`aria2c "${link}" --out "${filename}" --header "Referer: https://www.aliyundrive.com/"`);
  1097. },
  1098.  
  1099. convertLinkToBC(link, filename, ua) {
  1100. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}&refer=${encodeURIComponent('https://www.aliyundrive.com/')}ZZ`;
  1101. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  1102. },
  1103.  
  1104. convertLinkToCurl(link, filename, ua) {
  1105. let terminal = base.getValue('setting_terminal_type');
  1106. filename = filename.replace(' ', '_');
  1107. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L "${link}" --output "${filename}" -e "https://www.aliyundrive.com/"`);
  1108. },
  1109.  
  1110. addPageListener() {
  1111. doc.on('click', '.pl-button-mode', (e) => {
  1112. mode = e.target.dataset.mode;
  1113. Swal.showLoading();
  1114. this.getPCSLink();
  1115. });
  1116. doc.on('click', '.listener-link-api', async (e) => {
  1117. e.preventDefault();
  1118. let dataset = e.currentTarget.dataset;
  1119. let href = dataset.link;
  1120. let url = await this.getRealLink(dataset.did, dataset.fid);
  1121. if (url) href = url;
  1122. let d = document.createElement("a");
  1123. d.download = e.currentTarget.dataset.filename;
  1124. d.rel = "noopener";
  1125. d.href = href;
  1126. d.dispatchEvent(new MouseEvent("click"));
  1127. });
  1128. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  1129. e.preventDefault();
  1130. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  1131. $(e.target).text('复制成功,快去粘贴吧!').animate({opacity: '0.5'}, "slow");
  1132. });
  1133. doc.on('click', '.listener-link-rpc', async (e) => {
  1134. let target = $(e.currentTarget);
  1135. target.find('.icon').remove();
  1136. target.find('.pl-loading').remove();
  1137. target.prepend(base.createLoading());
  1138. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  1139. if (res === 'success') {
  1140. $('.listener-rpc-task').show();
  1141. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  1142. } else {
  1143. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  1144. }
  1145. });
  1146. doc.on('click', '.listener-send-rpc', (e) => {
  1147. $('.listener-link-rpc').click();
  1148. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  1149. });
  1150. doc.on('click', '.listener-open-setting', () => {
  1151. base.showSetting();
  1152. });
  1153. doc.on('click', '.listener-rpc-task', () => {
  1154. let rpc = JSON.stringify({
  1155. domain: base.getValue('setting_rpc_domain'),
  1156. port: base.getValue('setting_rpc_port'),
  1157. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  1158. GM_openInTab(url, {active: true});
  1159. });
  1160. },
  1161.  
  1162. async getRealLink(d, f) {
  1163. let authorization = `${base.getStorage('token').token_type} ${base.getStorage('token').access_token}`;
  1164. let res = await base.post(pan.pcs[1], {
  1165. drive_id: d,
  1166. file_id: f
  1167. }, {
  1168. authorization,
  1169. "content-type": "application/json;charset=utf-8",
  1170. });
  1171. if (res.url) {
  1172. return res.url;
  1173. }
  1174. return '';
  1175. },
  1176.  
  1177. addButton() {
  1178. if (!pt) return;
  1179. let $toolWrap;
  1180. let $button = $(`<div class="ali-button pl-button"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M853.333 938.667H170.667a85.333 85.333 0 0 1-85.334-85.334v-384A85.333 85.333 0 0 1 170.667 384H288a32 32 0 0 1 0 64H170.667a21.333 21.333 0 0 0-21.334 21.333v384a21.333 21.333 0 0 0 21.334 21.334h682.666a21.333 21.333 0 0 0 21.334-21.334v-384A21.333 21.333 0 0 0 853.333 448H736a32 32 0 0 1 0-64h117.333a85.333 85.333 0 0 1 85.334 85.333v384a85.333 85.333 0 0 1-85.334 85.334z" fill="#fff"/><path d="M715.03 543.552a32.81 32.81 0 0 0-46.251 0L554.005 657.813v-540.48a32 32 0 0 0-64 0v539.734L375.893 543.488a32.79 32.79 0 0 0-46.229 0 32.427 32.427 0 0 0 0 46.037l169.557 168.811a32.81 32.81 0 0 0 46.251 0l169.557-168.81a32.47 32.47 0 0 0 0-45.974z" fill="#FF9C00"/></svg><ul class="pl-dropdown-menu"><li class="pl-dropdown-menu-item pl-button-mode" data-mode="api">API下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="aria" >Aria下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="rpc">RPC下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="curl">cURL下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="bc" >BC下载</li></ul></div>`);
  1181. if (pt === 'home') {
  1182. let ins = setInterval(() => {
  1183. $toolWrap = $(pan.btn.home);
  1184. if ($toolWrap.length > 0) {
  1185. $toolWrap.append($button);
  1186. clearInterval(ins);
  1187. }
  1188. }, 50);
  1189. }
  1190. if (pt === 'share') {
  1191. $button.css({'margin-right': '10px'});
  1192. let ins = setInterval(() => {
  1193. $toolWrap = $(pan.btn.share);
  1194. if ($toolWrap.length > 0) {
  1195. $toolWrap.prepend($button);
  1196. clearInterval(ins);
  1197. }
  1198. }, 50);
  1199. }
  1200. base.createDownloadIframe();
  1201. this.addPageListener();
  1202. },
  1203.  
  1204. addInitButton() {
  1205. if (!pt) return;
  1206. let $toolWrap;
  1207. let $button = $(`<div class="ali-button pl-button-init"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M853.333 938.667H170.667a85.333 85.333 0 0 1-85.334-85.334v-384A85.333 85.333 0 0 1 170.667 384H288a32 32 0 0 1 0 64H170.667a21.333 21.333 0 0 0-21.334 21.333v384a21.333 21.333 0 0 0 21.334 21.334h682.666a21.333 21.333 0 0 0 21.334-21.334v-384A21.333 21.333 0 0 0 853.333 448H736a32 32 0 0 1 0-64h117.333a85.333 85.333 0 0 1 85.334 85.333v384a85.333 85.333 0 0 1-85.334 85.334z" fill="#fff"/><path d="M715.03 543.552a32.81 32.81 0 0 0-46.251 0L554.005 657.813v-540.48a32 32 0 0 0-64 0v539.734L375.893 543.488a32.79 32.79 0 0 0-46.229 0 32.427 32.427 0 0 0 0 46.037l169.557 168.811a32.81 32.81 0 0 0 46.251 0l169.557-168.81a32.47 32.47 0 0 0 0-45.974z" fill="#FF9C00"/></svg></div>`);
  1208. if (pt === 'home') {
  1209. let ins = setInterval(() => {
  1210. $toolWrap = $(pan.btn.home);
  1211. if ($toolWrap.length > 0) {
  1212. $toolWrap.append($button);
  1213. clearInterval(ins);
  1214. }
  1215. }, 50);
  1216. }
  1217. if (pt === 'share') {
  1218. $button.css({'margin-right': '10px'});
  1219. let ins = setInterval(() => {
  1220. $toolWrap = $(pan.btn.share);
  1221. if ($toolWrap.length > 0) {
  1222. $toolWrap.prepend($button);
  1223. clearInterval(ins);
  1224. }
  1225. }, 50);
  1226. }
  1227. $button.click(() => base.initDialog());
  1228. },
  1229.  
  1230. async getPCSLink() {
  1231. let reactDomGrid = document.getElementsByClassName(pan.dom.grid)[0];
  1232. if (reactDomGrid) {
  1233. let res = await Swal.fire({
  1234. title: '提示',
  1235. html: '<div style="display: flex;align-items: center;justify-content: center;">请先切换到 <b>列表视图</b>(<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M132 928c-32.8 0-59.2-26.4-59.2-59.2s26.4-59.2 59.2-59.2h760c32.8 0 59.2 26.4 59.2 59.2S924.8 928 892 928H132zm0-356.8c-32.8 0-59.2-26.4-59.2-59.2s26.4-59.2 59.2-59.2h760c32.8 0 59.2 26.4 59.2 59.2s-26.4 59.2-59.2 59.2H132zm0-356c-32.8 0-59.2-26.4-59.2-59.2S99.2 96.8 132 96.8h760c32.8 0 59.2 26.4 59.2 59.2s-26.4 59.2-59.2 59.2H132z"/></svg>)后获取!</div>',
  1236. confirmButtonText: '点击切换'
  1237. });
  1238. if (res) {
  1239. $('.switch-wrapper--1yEfx').trigger('click');
  1240. return message.success('切换成功,请重新获取下载链接!');
  1241. }
  1242. return false;
  1243. }
  1244. selectList = this.getSelectedList();
  1245. if (selectList.length === 0) {
  1246. return message.error('提示:请先勾选要下载的文件!');
  1247. }
  1248. if (this.isOnlyFolder()) {
  1249. return message.error('提示:请打开文件夹后勾选文件!');
  1250. }
  1251. if (pt === 'share') {
  1252. if (selectList.length > 20) {
  1253. return message.error('提示:单次最多可勾选 20 个文件!');
  1254. }
  1255. try {
  1256. let authorization = `${base.getStorage('token').token_type} ${base.getStorage('token').access_token}`;
  1257. let xShareToken = base.getStorage('shareToken').share_token;
  1258.  
  1259. for (let i = 0; i < selectList.length; i++) {
  1260. let res = await base.post(pan.pcs[0], {
  1261. expire_sec: 600,
  1262. file_id: selectList[i].fileId,
  1263. share_id: selectList[i].shareId
  1264. }, {
  1265. authorization,
  1266. "content-type": "application/json;charset=utf-8",
  1267. "x-share-token": xShareToken
  1268. });
  1269. if (res.download_url) {
  1270. selectList[i].downloadUrl = res.download_url;
  1271. }
  1272. }
  1273. } catch (e) {
  1274. return message.error('提示:请先登录网盘!');
  1275. }
  1276. }
  1277. let html = this.generateDom(selectList);
  1278. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  1279. },
  1280.  
  1281. generateDom(list) {
  1282. let content = '<div class="pl-main">';
  1283. let alinkAllText = '';
  1284. list.forEach((v, i) => {
  1285. if (v.type === 'folder') return;
  1286. let filename = v.name;
  1287. let fid = v.fileId;
  1288. let did = v.driveId;
  1289. let size = base.sizeFormat(v.size);
  1290. let dlink = v.downloadUrl || v.url;
  1291. if (mode === 'api') {
  1292. content += `<div class="pl-item">
  1293. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1294. <a class="pl-item-link listener-link-api" data-did="${did}" data-fid="${fid}" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  1295. </div>`;
  1296. }
  1297. if (mode === 'aria') {
  1298. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  1299. if (typeof (alink) === 'object') {
  1300. content += `<div class="pl-item">
  1301. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1302. <a class="pl-item-link" target="_blank" href="${alink.link}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}</a> </div>`;
  1303. } else {
  1304. alinkAllText += alink + '\r\n';
  1305. content += `<div class="pl-item">
  1306. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1307. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  1308. }
  1309. }
  1310. if (mode === 'rpc') {
  1311. content += `<div class="pl-item">
  1312. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1313. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">推送到 RPC 下载器</span></button></div>`;
  1314. }
  1315. if (mode === 'curl') {
  1316. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  1317. if (typeof (alink) === 'object') {
  1318. content += `<div class="pl-item">
  1319. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1320. <a class="pl-item-link" target="_blank" href="${alink.link}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}</a> </div>`;
  1321. } else {
  1322. alinkAllText += alink + '\r\n';
  1323. content += `<div class="pl-item">
  1324. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1325. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  1326. }
  1327. }
  1328. if (mode === 'bc') {
  1329. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  1330. content += `<div class="pl-item">
  1331. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1332. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  1333. }
  1334. });
  1335. content += '</div>';
  1336. if (mode === 'aria')
  1337. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  1338. if (mode === 'rpc') {
  1339. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  1340. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  1341. }
  1342. if (mode === 'curl')
  1343. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">设置终端类型(当前为:${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;
  1344. return content;
  1345. },
  1346.  
  1347. async sendLinkToRPC(filename, link) {
  1348. let rpc = {
  1349. domain: base.getValue('setting_rpc_domain'),
  1350. port: base.getValue('setting_rpc_port'),
  1351. path: base.getValue('setting_rpc_path'),
  1352. token: base.getValue('setting_rpc_token'),
  1353. dir: base.getValue('setting_rpc_dir'),
  1354. };
  1355.  
  1356. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  1357. let rpcData = {
  1358. id: new Date().getTime(),
  1359. jsonrpc: '2.0',
  1360. method: 'aria2.addUri',
  1361. params: [`token:${rpc.token}`, [link], {
  1362. dir: rpc.dir,
  1363. out: filename,
  1364. header: [`Referer: https://www.aliyundrive.com/`]
  1365. }]
  1366. };
  1367. try {
  1368. let res = await base.post(url, rpcData, {"Referer": "https://www.aliyundrive.com/"}, '');
  1369. if (res.result) return 'success';
  1370. return 'fail';
  1371. } catch (e) {
  1372. return 'fail';
  1373. }
  1374. },
  1375.  
  1376. getSelectedList() {
  1377. try {
  1378. let selectedList = [];
  1379. let reactDom = document.getElementsByClassName(pan.dom.list)[0];
  1380. let reactObj = base.findReact(reactDom,1);
  1381. let props = reactObj.pendingProps
  1382. if (props) {
  1383. let fileList = props.dataSource || [];
  1384. let selectedKeys = props.selectedKeys.split(',');
  1385. fileList.forEach((val) => {
  1386. if (selectedKeys.includes(val.fileId)) {
  1387. selectedList.push(val);
  1388. }
  1389. });
  1390. }
  1391. return selectedList;
  1392. } catch (e) {
  1393. return [];
  1394. }
  1395. },
  1396.  
  1397. detectPage() {
  1398. let path = location.pathname;
  1399. if (/^\/(drive)/.test(path)) return 'home';
  1400. if (/^\/(s|share)\//.test(path)) return 'share';
  1401. return '';
  1402. },
  1403.  
  1404. isOnlyFolder() {
  1405. for (let i = 0; i < selectList.length; i++) {
  1406. if (selectList[i].type === 'file') return false;
  1407. }
  1408. return true;
  1409. },
  1410.  
  1411. showMainDialog(title, html, footer) {
  1412. Swal.fire({
  1413. title,
  1414. html,
  1415. footer,
  1416. allowOutsideClick: false,
  1417. showCloseButton: true,
  1418. showConfirmButton: false,
  1419. position: 'top',
  1420. width,
  1421. padding: '15px 20px 5px',
  1422. customClass,
  1423. });
  1424. },
  1425.  
  1426. async initPanLinker() {
  1427. base.initDefaultConfig();
  1428. base.addPanLinkerStyle();
  1429. pt = this.detectPage();
  1430. let res = await base.post
  1431. (`https://api.youxiaohou.com/config/ali?ver=${version}&a=${author}`, {}, {}, 'text');
  1432. pan = JSON.parse(base.d(res));
  1433. Object.freeze && Object.freeze(pan);
  1434. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  1435. base.createTip();
  1436. base.registerMenuCommand();
  1437. }
  1438. };
  1439.  
  1440. let tianyi = {
  1441.  
  1442. convertLinkToAria(link, filename, ua) {
  1443. filename = filename.replace(' ', '_');
  1444. return encodeURIComponent(`aria2c "${link}" --out "${filename}"`);
  1445. },
  1446.  
  1447. convertLinkToBC(link, filename, ua) {
  1448. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}ZZ`;
  1449. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  1450. },
  1451.  
  1452. convertLinkToCurl(link, filename, ua) {
  1453. let terminal = base.getValue('setting_terminal_type');
  1454. filename = filename.replace(' ', '_');
  1455. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L "${link}" --output "${filename}"`);
  1456. },
  1457.  
  1458. addPageListener() {
  1459. doc.on('click', '.pl-button-mode', (e) => {
  1460. mode = e.target.dataset.mode;
  1461. Swal.showLoading();
  1462. this.getPCSLink();
  1463. });
  1464. doc.on('click', '.listener-link-api', async (e) => {
  1465. e.preventDefault();
  1466. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  1467. });
  1468. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  1469. e.preventDefault();
  1470. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  1471. $(e.target).text('复制成功,快去粘贴吧!').animate({opacity: '0.5'}, "slow");
  1472. });
  1473. doc.on('click', '.listener-link-rpc', async (e) => {
  1474. let target = $(e.currentTarget);
  1475. target.find('.icon').remove();
  1476. target.find('.pl-loading').remove();
  1477. target.prepend(base.createLoading());
  1478. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  1479. if (res === 'success') {
  1480. $('.listener-rpc-task').show();
  1481. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  1482. } else {
  1483. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  1484. }
  1485. });
  1486. doc.on('click', '.listener-send-rpc', (e) => {
  1487. $('.listener-link-rpc').click();
  1488. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  1489. });
  1490. doc.on('click', '.listener-open-setting', () => {
  1491. base.showSetting();
  1492. });
  1493. doc.on('click', '.listener-rpc-task', () => {
  1494. let rpc = JSON.stringify({
  1495. domain: base.getValue('setting_rpc_domain'),
  1496. port: base.getValue('setting_rpc_port'),
  1497. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  1498. GM_openInTab(url, {active: true});
  1499. });
  1500. },
  1501.  
  1502. addButton() {
  1503. if (!pt) return;
  1504. let $toolWrap;
  1505. let $button = $(`<div class="tianyi-button pl-button">下载助手<ul class="pl-dropdown-menu" style="top: 26px;"><li class="pl-dropdown-menu-item pl-button-mode" data-mode="api">API下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="aria" >Aria下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="rpc">RPC下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="curl">cURL下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="bc" >BC下载</li></ul></div>`);
  1506. if (pt === 'home') {
  1507. let ins = setInterval(() => {
  1508. $toolWrap = $(pan.btn.home);
  1509. if ($toolWrap.length > 0) {
  1510. $toolWrap.prepend($button);
  1511. clearInterval(ins);
  1512. }
  1513. }, 50);
  1514. }
  1515. if (pt === 'share') {
  1516. let ins = setInterval(() => {
  1517. $toolWrap = $(pan.btn.share);
  1518. if ($toolWrap.length > 0) {
  1519. $toolWrap.prepend($button);
  1520. clearInterval(ins);
  1521. }
  1522. }, 50);
  1523. }
  1524. base.createDownloadIframe();
  1525. this.addPageListener();
  1526. },
  1527.  
  1528. addInitButton() {
  1529. if (!pt) return;
  1530. let $toolWrap;
  1531. let $button = $(`<div class="tianyi-button pl-button-init">下载助手</div>`);
  1532. if (pt === 'home') {
  1533. let ins = setInterval(() => {
  1534. $toolWrap = $(pan.btn.home);
  1535. if ($toolWrap.length > 0) {
  1536. $toolWrap.append($button);
  1537. clearInterval(ins);
  1538. }
  1539. }, 50);
  1540. }
  1541. if (pt === 'share') {
  1542. $button.css({'margin-right': '10px'});
  1543. let ins = setInterval(() => {
  1544. $toolWrap = $(pan.btn.share);
  1545. if ($toolWrap.length > 0) {
  1546. $toolWrap.prepend($button);
  1547. clearInterval(ins);
  1548. }
  1549. }, 50);
  1550. }
  1551. $button.click(() => base.initDialog());
  1552. },
  1553.  
  1554. async getToken() {
  1555. let res = await base.getFinalUrl(pan.pcs[1], {});
  1556. let accessToken = res.match(/accessToken=(\w+)/)?.[1];
  1557. accessToken && base.setStorage('accessToken', accessToken);
  1558. return accessToken;
  1559. },
  1560.  
  1561. async getFileUrlByOnce(item, index, token) {
  1562. try {
  1563. if (item.downloadUrl) return {
  1564. index,
  1565. downloadUrl: item.downloadUrl
  1566. };
  1567. let time = Date.now(),
  1568. fileId = item.fileId,
  1569. o = "AccessToken=" + token + "&Timestamp=" + time + "&fileId=" + fileId,
  1570. url = pan.pcs[2] + '?fileId=' + fileId;
  1571. if (item.shareId) {
  1572. o = "AccessToken=" + token + "&Timestamp=" + time + "&dt=1&fileId=" + fileId + "&shareId=" + item.shareId;
  1573. url += '&dt=1&shareId=' + item.shareId;
  1574. }
  1575. let sign = md5(o).toString();
  1576. let res = await base.get(url, {
  1577. "accept": "application/json;charset=UTF-8",
  1578. "sign-type": 1,
  1579. "accesstoken": token,
  1580. "timestamp": time,
  1581. "signature": sign
  1582. });
  1583. if (res.res_code === 0) {
  1584. return {
  1585. index,
  1586. downloadUrl: res.fileDownloadUrl
  1587. };
  1588. } else if (res.errorCode === 'InvalidSessionKey') {
  1589. return {
  1590. index,
  1591. downloadUrl: '提示:请先登录网盘!'
  1592. };
  1593. } else if (res.res_code === 'ShareNotFoundFlatDir') {
  1594. return {
  1595. index,
  1596. downloadUrl: '提示:请先[转存]文件,👉前往[我的网盘]中下载!'
  1597. };
  1598. } else {
  1599. return {
  1600. index,
  1601. downloadUrl: '获取下载地址失败,请刷新重试!'
  1602. };
  1603. }
  1604. } catch (e) {
  1605. return {
  1606. index,
  1607. downloadUrl: '获取下载地址失败,请刷新重试!'
  1608. };
  1609. }
  1610. },
  1611.  
  1612. async getPCSLink() {
  1613. selectList = this.getSelectedList();
  1614. if (selectList.length === 0) {
  1615. return message.error('提示:请先勾选要下载的文件!');
  1616. }
  1617. if (this.isOnlyFolder()) {
  1618. return message.error('提示:请打开文件夹后勾选文件!');
  1619. }
  1620. let token = base.getStorage('accessToken') || await this.getToken();
  1621. if (!token) {
  1622. return message.error('提示:请先登录网盘!');
  1623. }
  1624. let queue = [];
  1625. selectList.forEach((item, index) => {
  1626. queue.push(this.getFileUrlByOnce(item, index, token));
  1627. });
  1628.  
  1629. const res = await Promise.all(queue);
  1630. res.forEach(val => {
  1631. selectList[val.index].downloadUrl = val.downloadUrl;
  1632. });
  1633.  
  1634. let html = this.generateDom(selectList);
  1635. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  1636. },
  1637.  
  1638. generateDom(list) {
  1639. let content = '<div class="pl-main">';
  1640. let alinkAllText = '';
  1641. list.forEach((v, i) => {
  1642. if (v.isFolder) return;
  1643. let filename = v.fileName;
  1644. let size = base.sizeFormat(v.size);
  1645. let dlink = v.downloadUrl;
  1646. if (mode === 'api') {
  1647. content += `<div class="pl-item">
  1648. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1649. <a class="pl-item-link listener-link-api" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  1650. </div>`;
  1651. }
  1652. if (mode === 'aria') {
  1653. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  1654. if (typeof (alink) === 'object') {
  1655. content += `<div class="pl-item">
  1656. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1657. <a class="pl-item-link" target="_blank" href="${alink.link}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}</a> </div>`;
  1658. } else {
  1659. content += `<div class="pl-item">
  1660. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1661. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  1662. }
  1663. }
  1664. if (mode === 'rpc') {
  1665. content += `<div class="pl-item">
  1666. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1667. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">推送到 RPC 下载器</span></button></div>`;
  1668. }
  1669. if (mode === 'curl') {
  1670. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  1671. if (typeof (alink) === 'object') {
  1672. content += `<div class="pl-item">
  1673. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1674. <a class="pl-item-link" target="_blank" href="${alink.link}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}</a> </div>`;
  1675. } else {
  1676. content += `<div class="pl-item">
  1677. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1678. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  1679. }
  1680. }
  1681. if (mode === 'bc') {
  1682. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  1683. content += `<div class="pl-item">
  1684. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1685. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  1686. }
  1687. });
  1688. content += '</div>';
  1689. if (mode === 'aria')
  1690. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  1691. if (mode === 'rpc') {
  1692. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  1693. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  1694. }
  1695. if (mode === 'curl')
  1696. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">设置终端类型(当前为:${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;
  1697. return content;
  1698. },
  1699.  
  1700. async sendLinkToRPC(filename, link) {
  1701. let rpc = {
  1702. domain: base.getValue('setting_rpc_domain'),
  1703. port: base.getValue('setting_rpc_port'),
  1704. path: base.getValue('setting_rpc_path'),
  1705. token: base.getValue('setting_rpc_token'),
  1706. dir: base.getValue('setting_rpc_dir'),
  1707. };
  1708.  
  1709. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  1710. let rpcData = {
  1711. id: new Date().getTime(),
  1712. jsonrpc: '2.0',
  1713. method: 'aria2.addUri',
  1714. params: [`token:${rpc.token}`, [link], {
  1715. dir: rpc.dir,
  1716. out: filename,
  1717. header: []
  1718. }]
  1719. };
  1720. try {
  1721. let res = await base.post(url, rpcData, {}, '');
  1722. if (res.result) return 'success';
  1723. return 'fail';
  1724. } catch (e) {
  1725. return 'fail';
  1726. }
  1727. },
  1728.  
  1729. getSelectedList() {
  1730. try {
  1731. return document.querySelector(".c-file-list").__vue__.selectedList;
  1732. } catch (e) {
  1733. return [document.querySelector(".info-detail").__vue__.fileDetail];
  1734. }
  1735. },
  1736.  
  1737. detectPage() {
  1738. let path = location.pathname;
  1739. if (/^\/web\/main/.test(path)) return 'home';
  1740. if (/^\/web\/share/.test(path)) return 'share';
  1741. return '';
  1742. },
  1743.  
  1744. isOnlyFolder() {
  1745. for (let i = 0; i < selectList.length; i++) {
  1746. if (!selectList[i].isFolder) return false;
  1747. }
  1748. return true;
  1749. },
  1750.  
  1751. showMainDialog(title, html, footer) {
  1752. Swal.fire({
  1753. title,
  1754. html,
  1755. footer,
  1756. allowOutsideClick: false,
  1757. showCloseButton: true,
  1758. showConfirmButton: false,
  1759. position: 'top',
  1760. width,
  1761. padding: '15px 20px 5px',
  1762. customClass,
  1763. });
  1764. },
  1765.  
  1766. async initPanLinker() {
  1767. base.initDefaultConfig();
  1768. base.addPanLinkerStyle();
  1769. pt = this.detectPage();
  1770. let res = await base.post
  1771. (`https://api.youxiaohou.com/config/tianyi?ver=${version}&a=${author}`, {}, {}, 'text');
  1772. pan = JSON.parse(base.d(res));
  1773. Object.freeze && Object.freeze(pan);
  1774. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  1775. this.getToken();
  1776. base.createTip();
  1777. base.registerMenuCommand();
  1778. }
  1779. };
  1780.  
  1781. let xunlei = {
  1782.  
  1783. convertLinkToAria(link, filename, ua) {
  1784. filename = filename.replace(' ', '_');
  1785. return encodeURIComponent(`aria2c "${link}" --out "${filename}"`);
  1786. },
  1787.  
  1788. convertLinkToBC(link, filename, ua) {
  1789. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}ZZ`;
  1790. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  1791. },
  1792.  
  1793. convertLinkToCurl(link, filename, ua) {
  1794. let terminal = base.getValue('setting_terminal_type');
  1795. filename = filename.replace(' ', '_');
  1796. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L "${link}" --output "${filename}"`);
  1797. },
  1798.  
  1799. addPageListener() {
  1800. doc.on('click', '.pl-button-mode', (e) => {
  1801. mode = e.target.dataset.mode;
  1802. Swal.showLoading();
  1803. this.getPCSLink();
  1804. });
  1805. doc.on('click', '.listener-link-api', async (e) => {
  1806. e.preventDefault();
  1807. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  1808. });
  1809. doc.on('click', '.listener-link-api-btn', async (e) => {
  1810. base.setClipboard(e.target.dataset.filename);
  1811. $(e.target).text('复制成功').animate({opacity: '0.5'}, "slow");
  1812. });
  1813. doc.on('click', '.listener-link-bc-btn', async (e) => {
  1814. let mirror = base.getMirrorList(e.target.dataset.dlink, pan.mirror);
  1815. base.setClipboard(mirror);
  1816. $(e.target).text('复制成功').animate({opacity: '0.5'}, "slow");
  1817. });
  1818. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  1819. e.preventDefault();
  1820. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  1821. $(e.target).text('复制成功,快去粘贴吧!').animate({opacity: '0.5'}, "slow");
  1822. });
  1823. doc.on('click', '.listener-link-rpc', async (e) => {
  1824. let target = $(e.currentTarget);
  1825. target.find('.icon').remove();
  1826. target.find('.pl-loading').remove();
  1827. target.prepend(base.createLoading());
  1828. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  1829. if (res === 'success') {
  1830. $('.listener-rpc-task').show();
  1831. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  1832. } else {
  1833. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  1834. }
  1835. });
  1836. doc.on('click', '.listener-send-rpc', (e) => {
  1837. $('.listener-link-rpc').click();
  1838. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  1839. });
  1840. doc.on('click', '.listener-open-setting', () => {
  1841. base.showSetting();
  1842. });
  1843. doc.on('click', '.listener-rpc-task', () => {
  1844. let rpc = JSON.stringify({
  1845. domain: base.getValue('setting_rpc_domain'),
  1846. port: base.getValue('setting_rpc_port'),
  1847. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  1848. GM_openInTab(url, {active: true});
  1849. });
  1850. },
  1851.  
  1852. addButton() {
  1853. if (!pt) return;
  1854. let $toolWrap;
  1855. let $button = $(`<div class="xunlei-button pl-button"><i class="xlpfont xlp-download"></i><span style="font-size: 13px;margin-left: 6px;">下载助手</span><ul class="pl-dropdown-menu" style="top: 34px;"><li class="pl-dropdown-menu-item pl-button-mode" data-mode="api">API下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="aria" >Aria下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="rpc">RPC下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="curl">cURL下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="bc" >BC下载</li></ul></div>`);
  1856. if (pt === 'home') {
  1857. let ins = setInterval(() => {
  1858. $toolWrap = $(pan.btn.home);
  1859. if ($toolWrap.length > 0) {
  1860. $toolWrap.prepend($button);
  1861. clearInterval(ins);
  1862. }
  1863. }, 50);
  1864. }
  1865. if (pt === 'share') {
  1866. $button.css({'margin-right': '10px'});
  1867. let ins = setInterval(() => {
  1868. $toolWrap = $(pan.btn.share);
  1869. if ($toolWrap.length > 0) {
  1870. $toolWrap.prepend($button);
  1871. clearInterval(ins);
  1872. }
  1873. }, 50);
  1874. }
  1875. base.createDownloadIframe();
  1876. this.addPageListener();
  1877. },
  1878.  
  1879. addInitButton() {
  1880. if (!pt) return;
  1881. let $toolWrap;
  1882. let $button = $(`<div class="xunlei-button pl-button-init"><i class="xlpfont xlp-download"></i><span style="font-size: 13px;margin-left: 6px;">下载助手</span></div>`);
  1883. if (pt === 'home') {
  1884. let ins = setInterval(() => {
  1885. $toolWrap = $(pan.btn.home);
  1886. if ($toolWrap.length > 0) {
  1887. $toolWrap.append($button);
  1888. clearInterval(ins);
  1889. }
  1890. }, 50);
  1891. }
  1892. if (pt === 'share') {
  1893. $button.css({'margin-right': '10px'});
  1894. let ins = setInterval(() => {
  1895. $toolWrap = $(pan.btn.share);
  1896. if ($toolWrap.length > 0) {
  1897. $toolWrap.prepend($button);
  1898. clearInterval(ins);
  1899. }
  1900. }, 50);
  1901. }
  1902. $button.click(() => base.initDialog());
  1903. },
  1904.  
  1905. getToken() {
  1906. let credentials = {}, captcha = {};
  1907. for (let i = 0; i < localStorage.length; i++) {
  1908. if (/^credentials_/.test(localStorage.key(i))) {
  1909. credentials = base.getStorage(localStorage.key(i));
  1910. base.setStorage('');
  1911. }
  1912. if (/^captcha_[\w]{16}/.test(localStorage.key(i))) {
  1913. captcha = base.getStorage(localStorage.key(i));
  1914. }
  1915. }
  1916. let deviceid = /(\w{32})/.exec(base.getStorage('deviceid').split(','))[0];
  1917. let token = {
  1918. credentials,
  1919. captcha,
  1920. deviceid
  1921. };
  1922. return token;
  1923. },
  1924.  
  1925. async getFileUrlByOnce(item, index, token) {
  1926. try {
  1927. if (item.downloadUrl) return {
  1928. index,
  1929. downloadUrl: item.downloadUrl
  1930. };
  1931. let res = await base.get(pan.pcs[0] + item.id, {
  1932. 'Authorization': `${token.credentials.token_type} ${token.credentials.access_token}`,
  1933. 'content-type': "application/json",
  1934. 'x-captcha-token': token.captcha.token,
  1935. 'x-device-id': token.deviceid,
  1936. });
  1937. if (res.web_content_link) {
  1938. return {
  1939. index,
  1940. downloadUrl: res.web_content_link
  1941. };
  1942. } else {
  1943. return {
  1944. index,
  1945. downloadUrl: '获取下载地址失败,请刷新重试!'
  1946. };
  1947. }
  1948. } catch (e) {
  1949. return message.error('提示:请先登录网盘后刷新页面!');
  1950. }
  1951. },
  1952.  
  1953. async getPCSLink() {
  1954. selectList = this.getSelectedList();
  1955. if (selectList.length === 0) {
  1956. return message.error('提示:请先勾选要下载的文件!');
  1957. }
  1958. if (this.isOnlyFolder()) {
  1959. return message.error('提示:请打开文件夹后勾选文件!');
  1960. }
  1961. if (pt === 'home') {
  1962. let queue = [];
  1963. let token = this.getToken();
  1964. selectList.forEach((item, index) => {
  1965. queue.push(this.getFileUrlByOnce(item, index, token));
  1966. });
  1967. const res = await Promise.all(queue);
  1968. res.forEach(val => {
  1969. selectList[val.index].downloadUrl = val.downloadUrl;
  1970. });
  1971. } else {
  1972. return message.error('提示:请转存到自己网盘后去网盘主页下载!');
  1973. }
  1974. let html = this.generateDom(selectList);
  1975. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  1976.  
  1977. },
  1978.  
  1979. generateDom(list) {
  1980. let content = '<div class="pl-main">';
  1981. let alinkAllText = '';
  1982. list.forEach((v, i) => {
  1983. if (v.kind === 'drive#folder') return;
  1984. let filename = v.name;
  1985. let size = base.sizeFormat(+v.size);
  1986. let dlink = v.downloadUrl;
  1987. if (mode === 'api') {
  1988. content += `<div class="pl-item">
  1989. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1990. <a class="pl-item-link listener-link-api" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  1991. <div class="pl-item-btn listener-link-api-btn" data-filename="${filename}">复制文件名</div>
  1992. </div>`;
  1993. }
  1994. if (mode === 'aria') {
  1995. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  1996. if (typeof (alink) === 'object') {
  1997. content += `<div class="pl-item">
  1998. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1999. <a class="pl-item-link" target="_blank" href="${alink.link}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}</a> </div>`;
  2000. } else {
  2001. alinkAllText += alink + '\r\n';
  2002. content += `<div class="pl-item">
  2003. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2004. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2005. }
  2006. }
  2007. if (mode === 'rpc') {
  2008. content += `<div class="pl-item">
  2009. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2010. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">推送到 RPC 下载器</span></button></div>`;
  2011. }
  2012. if (mode === 'curl') {
  2013. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  2014. if (typeof (alink) === 'object') {
  2015. content += `<div class="pl-item">
  2016. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2017. <a class="pl-item-link" target="_blank" href="${alink.link}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}</a> </div>`;
  2018. } else {
  2019. alinkAllText += alink + '\r\n';
  2020. content += `<div class="pl-item">
  2021. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2022. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2023. }
  2024. }
  2025. if (mode === 'bc') {
  2026. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  2027. content += `<div class="pl-item">
  2028. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2029. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a>
  2030. <div class="pl-item-btn listener-link-bc-btn" data-dlink="${dlink}">复制镜像地址</div>
  2031. </div>`;
  2032. }
  2033. });
  2034. content += '</div>';
  2035. if (mode === 'aria')
  2036. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  2037. if (mode === 'rpc') {
  2038. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  2039. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  2040. }
  2041. if (mode === 'curl')
  2042. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">设置终端类型(当前为:${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;
  2043. return content;
  2044. },
  2045.  
  2046. async sendLinkToRPC(filename, link) {
  2047. let rpc = {
  2048. domain: base.getValue('setting_rpc_domain'),
  2049. port: base.getValue('setting_rpc_port'),
  2050. path: base.getValue('setting_rpc_path'),
  2051. token: base.getValue('setting_rpc_token'),
  2052. dir: base.getValue('setting_rpc_dir'),
  2053. };
  2054.  
  2055. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  2056. let rpcData = {
  2057. id: new Date().getTime(),
  2058. jsonrpc: '2.0',
  2059. method: 'aria2.addUri',
  2060. params: [`token:${rpc.token}`, [link], {
  2061. dir: rpc.dir,
  2062. out: filename,
  2063. header: []
  2064. }]
  2065. };
  2066. try {
  2067. let res = await base.post(url, rpcData, {}, '');
  2068. if (res.result) return 'success';
  2069. return 'fail';
  2070. } catch (e) {
  2071. return 'fail';
  2072. }
  2073. },
  2074.  
  2075. getSelectedList() {
  2076. try {
  2077. let doms = document.querySelectorAll('.pan-list-item');
  2078. let selectedList = [];
  2079. for (let dom of doms) {
  2080. let domVue = dom.__vue__;
  2081. if (domVue.selected.includes(domVue.info.id)) {
  2082. selectedList.push(domVue.info);
  2083. }
  2084. }
  2085. return selectedList;
  2086. } catch (e) {
  2087. return [];
  2088. }
  2089. },
  2090.  
  2091. detectPage() {
  2092. let path = location.pathname;
  2093. if (/^\/$/.test(path)) return 'home';
  2094. if (/^\/(s|share)\//.test(path)) return 'share';
  2095. return '';
  2096. },
  2097.  
  2098. isOnlyFolder() {
  2099. for (let i = 0; i < selectList.length; i++) {
  2100. if (selectList[i].kind === 'drive#file') return false;
  2101. }
  2102. return true;
  2103. },
  2104.  
  2105. showMainDialog(title, html, footer) {
  2106. Swal.fire({
  2107. title,
  2108. html,
  2109. footer,
  2110. allowOutsideClick: false,
  2111. showCloseButton: true,
  2112. showConfirmButton: false,
  2113. position: 'top',
  2114. width,
  2115. padding: '15px 20px 5px',
  2116. customClass,
  2117. });
  2118. },
  2119.  
  2120. async initPanLinker() {
  2121. base.initDefaultConfig();
  2122. base.addPanLinkerStyle();
  2123. pt = this.detectPage();
  2124. let res = await base.post
  2125. (`https://api.youxiaohou.com/config/xunlei?ver=${version}&a=${author}`, {}, {}, 'text');
  2126. pan = JSON.parse(base.d(res));
  2127. Object.freeze && Object.freeze(pan);
  2128. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  2129. base.createTip();
  2130. base.registerMenuCommand();
  2131. }
  2132. };
  2133.  
  2134. let quark = {
  2135.  
  2136. convertLinkToAria(link, filename, ua) {
  2137. filename = filename.replace(' ', '_');
  2138. return encodeURIComponent(`aria2c "${link}" --out "${filename}" --header "Cookie: ${document.cookie}"`);
  2139. },
  2140.  
  2141. convertLinkToBC(link, filename, ua) {
  2142. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}&cookie=${encodeURIComponent(document.cookie)}ZZ`;
  2143. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  2144. },
  2145.  
  2146. convertLinkToCurl(link, filename, ua) {
  2147. let terminal = base.getValue('setting_terminal_type');
  2148. filename = filename.replace(' ', '_');
  2149. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L "${link}" --output "${filename}" -b "${document.cookie}"`);
  2150. },
  2151.  
  2152. addPageListener() {
  2153. window.addEventListener('hashchange', (event)=>{
  2154. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  2155.  
  2156. })
  2157. doc.on('click', '.pl-button-mode', (e) => {
  2158. mode = e.target.dataset.mode;
  2159. Swal.showLoading();
  2160. this.getPCSLink();
  2161. });
  2162. doc.on('click', '.listener-link-api', async (e) => {
  2163. e.preventDefault();
  2164. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  2165. });
  2166. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  2167. e.preventDefault();
  2168. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  2169. $(e.target).text('复制成功,快去粘贴吧!').animate({opacity: '0.5'}, "slow");
  2170. });
  2171. doc.on('click', '.listener-link-rpc', async (e) => {
  2172. let target = $(e.currentTarget);
  2173. target.find('.icon').remove();
  2174. target.find('.pl-loading').remove();
  2175. target.prepend(base.createLoading());
  2176. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  2177. if (res === 'success') {
  2178. $('.listener-rpc-task').show();
  2179. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  2180. } else {
  2181. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  2182. }
  2183. });
  2184. doc.on('click', '.listener-send-rpc', (e) => {
  2185. $('.listener-link-rpc').click();
  2186. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  2187. });
  2188. doc.on('click', '.listener-open-setting', () => {
  2189. base.showSetting();
  2190. });
  2191. doc.on('click', '.listener-rpc-task', () => {
  2192. let rpc = JSON.stringify({
  2193. domain: base.getValue('setting_rpc_domain'),
  2194. port: base.getValue('setting_rpc_port'),
  2195. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  2196. GM_openInTab(url, {active: true});
  2197. });
  2198. },
  2199.  
  2200. addButton() {
  2201. if (!pt) return;
  2202. let $toolWrap;
  2203. let $button = $(`<div class="quark-button pl-button"><svg width="22" height="22" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke="#555" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 2-2z"/><path d="M14 8h1.553c.85 0 1.16.093 1.47.267.311.174.556.43.722.756.166.326.255.65.255 1.54v4.873c0 .892-.089 1.215-.255 1.54-.166.327-.41.583-.722.757-.31.174-.62.267-1.47.267H6.447c-.85 0-1.16-.093-1.47-.267a1.778 1.778 0 01-.722-.756c-.166-.326-.255-.65-.255-1.54v-4.873c0-.892.089-1.215.255-1.54.166-.327.41-.583.722-.757.31-.174.62-.267 1.47-.267H11"/><path stroke-linecap="round" stroke-linejoin="round" d="M11 3v10"/></g></svg> 下载助手<ul class="pl-dropdown-menu"><li class="pl-dropdown-menu-item pl-button-mode" data-mode="api">API下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="aria" >Aria下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="rpc">RPC下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="curl">cURL下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="bc" >BC下载</li></ul></div>`);
  2204. if (pt === 'home') {
  2205. let ins = setInterval(() => {
  2206. $toolWrap = $(pan.btn.home);
  2207. if ($toolWrap.length > 0) {
  2208. $toolWrap.prepend($button);
  2209. clearInterval(ins);
  2210. }
  2211. }, 50);
  2212. }
  2213. if (pt === 'share') {
  2214. $button.css({'margin-right': '10px'});
  2215. let ins = setInterval(() => {
  2216. $toolWrap = $(pan.btn.share);
  2217. if ($toolWrap.length > 0) {
  2218. $toolWrap.prepend($button);
  2219. clearInterval(ins);
  2220. }
  2221. }, 50);
  2222. }
  2223. },
  2224.  
  2225. addInitButton() {
  2226. if (!pt) return;
  2227. let $toolWrap;
  2228. let $button = $(`<div class="quark-button pl-button-init"><svg width="22" height="22" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke="#555" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 2-2z"/><path d="M14 8h1.553c.85 0 1.16.093 1.47.267.311.174.556.43.722.756.166.326.255.65.255 1.54v4.873c0 .892-.089 1.215-.255 1.54-.166.327-.41.583-.722.757-.31.174-.62.267-1.47.267H6.447c-.85 0-1.16-.093-1.47-.267a1.778 1.778 0 01-.722-.756c-.166-.326-.255-.65-.255-1.54v-4.873c0-.892.089-1.215.255-1.54.166-.327.41-.583.722-.757.31-.174.62-.267 1.47-.267H11"/><path stroke-linecap="round" stroke-linejoin="round" d="M11 3v10"/></g></svg> 下载助手</div>`);
  2229. if (pt === 'home') {
  2230. let ins = setInterval(() => {
  2231. $toolWrap = $(pan.btn.home);
  2232. if ($toolWrap.length > 0) {
  2233. $toolWrap.prepend($button);
  2234. clearInterval(ins);
  2235. }
  2236. }, 50);
  2237. }
  2238. if (pt === 'share') {
  2239. $button.css({'margin-right': '10px'});
  2240. let ins = setInterval(() => {
  2241. $toolWrap = $(pan.btn.share);
  2242. if ($toolWrap.length > 0) {
  2243. $toolWrap.prepend($button);
  2244. clearInterval(ins);
  2245. }
  2246. }, 50);
  2247. }
  2248. $button.click(() => base.initDialog());
  2249. },
  2250.  
  2251. async getPCSLink() {
  2252. selectList = this.getSelectedList();
  2253. if (selectList.length === 0) {
  2254. return message.error('提示:请先勾选要下载的文件!');
  2255. }
  2256. if (this.isOnlyFolder()) {
  2257. return message.error('提示:请打开文件夹后勾选文件!');
  2258. }
  2259. let fids = [];
  2260. selectList.forEach(val => {
  2261. fids.push(val.fid);
  2262. });
  2263. if (pt === 'home') {
  2264. let res = await base.post(pan.pcs[0], {
  2265. "fids": fids
  2266. }, {"content-type": "application/json;charset=utf-8"});
  2267. if (res.code === 31001) {
  2268. return message.error('提示:请先登录网盘!');
  2269. }
  2270. if (res.code !== 0) {
  2271. return message.error('提示:获取链接失败!');
  2272. }
  2273. let html = this.generateDom(res.data);
  2274. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  2275. } else {
  2276. return message.error('提示:请转存到自己网盘后去网盘主页下载!');
  2277. }
  2278. },
  2279.  
  2280. generateDom(list) {
  2281. let content = '<div class="pl-main">';
  2282. let alinkAllText = '';
  2283. list.forEach((v, i) => {
  2284. if (v.file === false) return;
  2285. let filename = v.file_name;
  2286. let fid = v.fid;
  2287. let size = base.sizeFormat(v.size);
  2288. let dlink = v.download_url;
  2289. if (mode === 'api') {
  2290. content += `<div class="pl-item">
  2291. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2292. <a class="pl-item-link listener-link-api" data-fid="${fid}" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  2293. </div>`;
  2294. }
  2295. if (mode === 'aria') {
  2296. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  2297. if (typeof (alink) === 'object') {
  2298. content += `<div class="pl-item">
  2299. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2300. <a class="pl-item-link" target="_blank" href="${alink.link}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}</a> </div>`;
  2301. } else {
  2302. alinkAllText += alink + '\r\n';
  2303. content += `<div class="pl-item">
  2304. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2305. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2306. }
  2307. }
  2308. if (mode === 'rpc') {
  2309. content += `<div class="pl-item">
  2310. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2311. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">推送到 RPC 下载器</span></button></div>`;
  2312. }
  2313. if (mode === 'curl') {
  2314. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  2315. if (typeof (alink) === 'object') {
  2316. content += `<div class="pl-item">
  2317. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2318. <a class="pl-item-link" target="_blank" href="${alink.link}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}</a> </div>`;
  2319. } else {
  2320. alinkAllText += alink + '\r\n';
  2321. content += `<div class="pl-item">
  2322. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2323. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2324. }
  2325. }
  2326. if (mode === 'bc') {
  2327. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  2328. content += `<div class="pl-item">
  2329. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2330. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2331. }
  2332. });
  2333. content += '</div>';
  2334. if (mode === 'aria')
  2335. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  2336. if (mode === 'rpc') {
  2337. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  2338. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  2339. }
  2340. if (mode === 'curl')
  2341. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">设置终端类型(当前为:${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;
  2342. return content;
  2343. },
  2344.  
  2345. async sendLinkToRPC(filename, link) {
  2346. let rpc = {
  2347. domain: base.getValue('setting_rpc_domain'),
  2348. port: base.getValue('setting_rpc_port'),
  2349. path: base.getValue('setting_rpc_path'),
  2350. token: base.getValue('setting_rpc_token'),
  2351. dir: base.getValue('setting_rpc_dir'),
  2352. };
  2353.  
  2354. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  2355. let rpcData = {
  2356. id: new Date().getTime(),
  2357. jsonrpc: '2.0',
  2358. method: 'aria2.addUri',
  2359. params: [`token:${rpc.token}`, [link], {
  2360. dir: rpc.dir,
  2361. out: filename,
  2362. header: [`Cookie: ${document.cookie}`]
  2363. }]
  2364. };
  2365. try {
  2366. let res = await base.post(url, rpcData, {"Cookie": document.cookie}, '');
  2367. if (res.result) return 'success';
  2368. return 'fail';
  2369. } catch (e) {
  2370. return 'fail';
  2371. }
  2372. },
  2373.  
  2374. getSelectedList() {
  2375. try {
  2376. let selectedList = [];
  2377. let reactDom = document.getElementsByClassName('file-list')[0];
  2378. let reactObj = base.findReact(reactDom);
  2379. let props = reactObj.props
  2380. if (props) {
  2381. let fileList = props.list || [];
  2382. let selectedKeys = props.selectedRowKeys || [];
  2383. fileList.forEach((val) => {
  2384. if (selectedKeys.includes(val.fid)) {
  2385. selectedList.push(val);
  2386. }
  2387. });
  2388. }
  2389. return selectedList;
  2390. } catch (e) {
  2391. return [];
  2392. }
  2393. },
  2394.  
  2395. detectPage() {
  2396. let path = location.pathname;
  2397. if (/^\/(list)/.test(path)) return 'home';
  2398. if (/^\/(s|share)\//.test(path)) return 'share';
  2399. return '';
  2400. },
  2401.  
  2402. isOnlyFolder() {
  2403. for (let i = 0; i < selectList.length; i++) {
  2404. if (selectList[i].file) return false;
  2405. }
  2406. return true;
  2407. },
  2408.  
  2409. showMainDialog(title, html, footer) {
  2410. Swal.fire({
  2411. title,
  2412. html,
  2413. footer,
  2414. allowOutsideClick: false,
  2415. showCloseButton: true,
  2416. showConfirmButton: false,
  2417. position: 'top',
  2418. width,
  2419. padding: '15px 20px 5px',
  2420. customClass,
  2421. });
  2422. },
  2423.  
  2424. async initPanLinker() {
  2425. base.initDefaultConfig();
  2426. base.addPanLinkerStyle();
  2427. pt = this.detectPage();
  2428. let res = await base.post
  2429. (`https://api.youxiaohou.com/config/quark?ver=${version}&a=${author}`, {}, {}, 'text');
  2430. pan = JSON.parse(base.d(res));
  2431. Object.freeze && Object.freeze(pan);
  2432. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  2433. this.addPageListener();
  2434. base.createTip();
  2435. base.createDownloadIframe();
  2436. base.registerMenuCommand();
  2437. }
  2438. };
  2439.  
  2440. let main = {
  2441. init() {
  2442. if (/(pan|yun).baidu.com/.test(location.host)) {
  2443. baidu.initPanLinker();
  2444. }
  2445. if (/www.aliyundrive.com/.test(location.host)) {
  2446. ali.initPanLinker();
  2447. }
  2448. if (/cloud.189.cn/.test(location.host)) {
  2449. tianyi.initPanLinker();
  2450. }
  2451. if (/pan.xunlei.com/.test(location.host)) {
  2452. xunlei.initPanLinker();
  2453. }
  2454. if (/pan.quark.cn/.test(location.host)) {
  2455. quark.initPanLinker();
  2456. }
  2457. }
  2458. };
  2459.  
  2460. main.init();
  2461. })();