(改)网盘直链下载助手

可以获取网盘文件真实下载地址。现已支持百度阿里天翼迅雷夸克移动六大网盘,基于【网盘直链下载助手】修改自6.1.1版本,自用,去推广,修原有BUG,修改界面,甚至比原版还好用!

当前为 2023-07-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name (改)网盘直链下载助手
  3. // @namespace https://github.com/syhyz1990/baiduyun
  4. // @version 1.0.7
  5. // @author Hmjz100、油小猴
  6. // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48cGF0aCBkPSJNMTAzLjYgMTA3LjRjMy41LTIuMiA4LjktNi4xIDEzLjgtMTIuNXM3LjMtMTIuNSA4LjUtMTYuNWMuNS0xLjcgMi4yLTcuNSAyLjItMTQuNyAwLTEwLjEtMy4zLTI1LjEtMTUuNC0zNi44LTE0LjUtMTQtMzIuMS0xNC4zLTM1LjctMTQuMy04IDAtMTUuNyAxLjktMjIuNiA1LjJDNDQgMjMgMzUuNyAzMS40IDMwLjggNDEuN2MtMS4zIDIuOC00IDQuNy03LjEgNS00IC4zLTcuNSA0LjQtOC45IDkuNi0uNSAxLjktMS42IDMuNS0zLjEgNC43QzQuNCA2Ni44IDAgNzUuNyAwIDg1YzAgNi44IDIuMyAxMy4xIDYuMSAxOC4yIDUuNSA3LjQgMTQuMiAxMi4yIDI0IDEyLjJoNDcuMWM0LjQgMCAxMS0uNSAxOC4zLTMuNSAzLjItMS40IDUuOS0zIDguMS00LjV6IiBmaWxsPSIjNDQ0Ii8+PHBhdGggZD0iTTExOS44IDY0LjNjLjEtMTcuMS0xMC40LTI4LTEyLjUtMzAuMUM5NSAyMi4xIDc5LjkgMjEuOCA3Ni45IDIxLjhjLTE3LjYgMC0zMy4zIDEwLjUtMzkuOSAyNi43LS42IDEuMy0xLjggMi4zLTMuNCAyLjNoLS40Yy01LjggMC0xMC42IDQuOC0xMC42IDEwLjd2LjVjMCAxLjQtLjggMi42LTEuOSAzLjNDMTMuNCA2OSA4LjggNzYuOCA4LjggODVjMCAxMi4yIDkuOSAyMi4zIDIyLjIgMjIuM2g0NS4yYzMuNi0uMSAxNy42LS45IDI5LjYtMTIgMi45LTIuOCAxMy45LTEzLjcgMTQtMzF6IiBmaWxsPSIjMTM5N2Q4Ii8+PHBhdGggZD0iTTExMC44IDU3LjRsLjIgMy4zYzAgMS4zLTEuMSAyLjQtMi4zIDIuNC0xLjMgMC0yLjMtMS4xLTIuMy0yLjRsLS4xLTIuOHYtLjNjMC0xLjIuOS0yLjIgMi4xLTIuM2guM2MuNyAwIDEuMy4zIDEuNy43LS4yLjEuMy41LjQgMS40em0tMy4zLTEwLjNjMCAxLjItMSAyLjMtMi4yIDIuM2gtLjFjLS44IDAtMS42LS41LTItMS4yLTQuNi04LjMtMTMuMy0xMy41LTIyLjgtMTMuNS0xLjIgMC0yLjMtMS0yLjMtMi4ydi0uMWMwLTEuMiAxLTIuMyAyLjItMi4zaC4xYTMwLjM3IDMwLjM3IDAgMCAxIDE1LjggNC40YzQuNiAyLjggOC40IDYuOCAxMS4xIDExLjUuMS4zLjIuNy4yIDEuMXpNODguMyA3My44TDczLjUgOTMuMmMtMS41IDEuOS0zLjUgMy4xLTUuNyAzLjVoLS4yYy0uNC4xLS44LjEtMS4yLjEtLjYgMC0xLjEtLjEtMS42LS4yLTIuMi0uNC00LjItMS43LTUuNi0zLjVMNDQuMyA3My45Yy0yLTIuNi0yLjUtNS40LTEuNC03LjcuMS0uMS4xLS4yLjItLjIgMS4yLTIgMy41LTMuMiA2LjQtMy4yaDYuNnYtNS43YzAtNi44IDQuNy0xMiAxMC45LTEyIDQuOCAwIDguNSAyLjYgMTAuMyA3LjIuNSAxLjMtLjIgMi43LTEuNSAzLjJzLTIuOC0uMS0zLjMtMS40Yy0xLjEtMi43LTIuOS00LTUuNS00LTMuNSAwLTYgMy02IDd2OC4xYzAgLjUtLjIgMS0uNiAxLjQtLjYuNy0xLjcgMS4xLTIuNiAxLjFoLTguNGMtMS4zIDAtMiAuNC0yLjEuNy0uMi40IDAgMS4zLjkgMi40TDYzLjEgOTBjLjkgMS4yIDIuMSAxLjggMy4zIDEuOHMyLjMtLjYgMy4xLTEuN2wxNC44LTE5LjNjLjktMS4xIDEuMS0yIC45LTIuNC0uMi0uMy0uOS0uNy0yLjEtLjdoLTcuNmMtLjkgMC0xLjctLjUtMi4xLTEuMi0uMy0uNC0uNC0uOC0uNC0xLjMgMC0xLjQgMS4xLTIuNSAyLjUtMi41aDcuNmMzLjEgMCA1LjUgMS4zIDYuNiAzLjVsLjMuN2MuNyAyLjEuMSA0LjYtMS43IDYuOXoiIGZpbGw9IiM0NDQiLz48L3N2Zz4=
  7. // @description 可以获取网盘文件真实下载地址。现已支持百度阿里天翼迅雷夸克移动六大网盘,基于【网盘直链下载助手】修改自6.1.1版本,自用,去推广,修原有BUG,修改界面,甚至比原版还好用!
  8. // @license MIT
  9. // @homepage https://github.com/hmjz100/Online-disk-direct-link-download-assistant/
  10. // @supportURL https://github.com/hmjz100/Online-disk-direct-link-download-assistant/issues
  11. // @match *://pan.baidu.com/disk/home*
  12. // @match *://yun.baidu.com/disk/home*
  13. // @match *://pan.baidu.com/disk/main*
  14. // @match *://yun.baidu.com/disk/main*
  15. // @match *://pan.baidu.com/disk/base*
  16. // @match *://yun.baidu.com/disk/base*
  17. // @match *://pan.baidu.com/wap/home*
  18. // @match *://yun.baidu.com/wap/home*
  19. // @match *://pan.baidu.com/wap/main*
  20. // @match *://yun.baidu.com/wap/main*
  21. // @match *://pan.baidu.com/s/*
  22. // @match *://pan.baidu.com/aipan/*
  23. // @match *://yun.baidu.com/s/*
  24. // @match *://yun.baidu.com/aipan/*
  25. // @match *://pan.baidu.com/share/*
  26. // @match *://yun.baidu.com/share/*
  27. // @match *://www.aliyundrive.com/s/*
  28. // @match *://www.aliyundrive.com/drive*
  29. // @match *://cloud.189.cn/web/*
  30. // @match *://pan.xunlei.com/*
  31. // @match *://pan.quark.cn/*
  32. // @match *://yun.139.com/*
  33. // @match *://caiyun.139.com/*
  34. // @match *://*.youxiaohou.com/*
  35. // @require https://unpkg.com/jquery@3.6.0/dist/jquery.min.js
  36. // @require https://unpkg.com/sweetalert2@11/dist/sweetalert2.js
  37. // @require https://unpkg.com/js-md5@0.7.3/build/md5.min.js
  38. // @connect baidu.com
  39. // @connect baidupcs.com
  40. // @connect aliyundrive.com
  41. // @connect 189.cn
  42. // @connect xunlei.com
  43. // @connect quark.cn
  44. // @connect youxiaohou.com
  45. // @connect localhost
  46. // @connect *
  47. // @run-at document-idle
  48. // @compatible Chrome
  49. // @compatible Edge
  50. // @compatible Firefox
  51. // @compatible Safari
  52. // @compatible Opera
  53. // @grant unsafeWindow
  54. // @grant GM_xmlhttpRequest
  55. // @grant GM_setClipboard
  56. // @grant GM_setValue
  57. // @grant GM_getValue
  58. // @grant GM_openInTab
  59. // @grant GM_info
  60. // @grant GM_registerMenuCommand
  61. // @grant GM_cookie
  62. // @grant GM_addStyle
  63. // @grant GM_getResourceText
  64. // ==/UserScript==
  65.  
  66. (function () {
  67. 'use strict';
  68.  
  69. // 界面参数
  70. let pt = '', selectList = [], params = {}, mode = '', width = 800, pan = {}, color = '',
  71. doc = $(document), progress = {}, request = {}, ins = {}, idm = {};
  72.  
  73.  
  74. // 准备好对应的元素
  75. const customClass = {
  76. popup: 'pl-popup',
  77. header: 'pl-header',
  78. title: 'pl-title',
  79. closeButton: 'pl-close',
  80. content: 'pl-content',
  81. input: 'pl-input',
  82. footer: 'pl-footer'
  83. };
  84.  
  85.  
  86. // 准备好Shell类型(用于curl下载)
  87. const terminalType = {
  88. wc: "Microsoft Windows 命令提示符",
  89. wp: "Microsoft Windows PowerShell",
  90. lt: "Linux 终端",
  91. ls: "Linux Shell",
  92. mt: "Apple MacOS 终端",
  93. };
  94.  
  95. //准备好信息界面的设置选项
  96. const getuserinfo = {
  97. yes: "允许",
  98. };
  99. const hideidm = {
  100. yes: "隐藏",
  101. no: "显示"
  102. };
  103. const baidutheme = {
  104. yes: "修改主题色",
  105. no: "不修改主题色"
  106. };
  107.  
  108. //准备好右上角的Toast提示
  109. let toast = Swal.mixin({
  110. toast: true,
  111. position: 'top-end',
  112. showConfirmButton: false,
  113. timer: 3500,
  114. timerProgressBar: true,
  115. showCloseButton: true,
  116. didOpen: (toast) => {
  117. toast.addEventListener('mouseenter', Swal.stopTimer);
  118. toast.addEventListener('mouseleave', Swal.resumeTimer);
  119. }
  120. });
  121.  
  122. //提示的信息内容
  123. const message = {
  124. success: (text) => {
  125. toast.fire({title: text, icon: 'success'});
  126. },
  127. error: (text) => {
  128. toast.fire({title: text, icon: 'error'});
  129. },
  130. warning: (text) => {
  131. toast.fire({title: text, icon: 'warning'});
  132. },
  133. info: (text) => {
  134. toast.fire({title: text, icon: 'info'});
  135. },
  136. question: (text) => {
  137. toast.fire({title: text, icon: 'question'});
  138. }
  139. };
  140.  
  141. // 封装好要用的函数
  142. let base = {
  143. // 默认菜单
  144. registerMenuCommand() {
  145. GM_registerMenuCommand('⚙️ 设置', () => {
  146. base.showSetting();
  147. });
  148. GM_registerMenuCommand('更新日志', () => {
  149. base.showUpdateLog();
  150. });
  151. GM_registerMenuCommand('分析信息', () => {
  152. base.showInfo();
  153. });
  154. },
  155.  
  156. // 对于非网盘的菜单
  157. registerPanMenuCommand() {
  158. GM_registerMenuCommand('⚙️ 设置', () => {
  159. base.showSetting();
  160. });
  161. GM_registerMenuCommand('更新日志', () => {
  162. base.showUpdateLog();
  163. });
  164. GM_registerMenuCommand('分析信息', () => {
  165. base.showPanInfo();
  166. });
  167. },
  168.  
  169. // 取消点亮按钮按下后运行的
  170. registerInitCode(value) {
  171. console.log("【(改)网盘直链下载助手】\n正在注入取消点亮按钮设置项目...");
  172. message.warning("正在注入取消点亮按钮设置项目...(您可以再次点亮按钮)");
  173. base.setValue('setting_init_code', value);
  174. history.go(0)
  175. },
  176.  
  177. // 获取Cookie
  178. getCookie(name) {
  179. let arr = document.cookie.replace(/\s/g, "").split(';');
  180. for (let i = 0, l = arr.length; i < l; i++) {
  181. let tempArr = arr[i].split('=');
  182. if (tempArr[0] === name) {
  183. return decodeURIComponent(tempArr[1]);
  184. }
  185. }
  186. return '';
  187. },
  188.  
  189. /*-- 对象类型判断
  190. 示例:
  191. isType([]) // 输出"array"
  192. isType(123) // 输出"number"
  193. isType(null) // 输出"null"
  194. isType(new Date()) // 输出"date"
  195. */
  196. isType(obj) {
  197. return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase();
  198. },
  199.  
  200.  
  201. // 获取本地保存的数值(仅用于 Greasemonkey)
  202. getValue(name) {
  203. return GM_getValue(name);
  204. },
  205.  
  206. // 修改本地保存的数值(仅用于 Greasemonkey)
  207. setValue(name, value) {
  208. GM_setValue(name, value);
  209. },
  210.  
  211. // 获取本地保存的数值
  212. getStorage(key) {
  213. try {
  214. return JSON.parse(localStorage.getItem(key));
  215. } catch (e) {
  216. return localStorage.getItem(key);
  217. }
  218. },
  219.  
  220. // 修改本地保存的数值
  221. setStorage(key, value) {
  222. if (this.isType(value) === 'object' || this.isType(value) === 'array') {
  223. return localStorage.setItem(key, JSON.stringify(value));
  224. }
  225. return localStorage.setItem(key, value);
  226. },
  227.  
  228. // 设置剪贴板(仅用于 Greasemonkey)
  229. setClipboard(text) {
  230. GM_setClipboard(text, 'text');
  231. },
  232.  
  233. // 加密成base64(先转换成URL编码)
  234. encode(str) {
  235. return btoa(unescape(encodeURIComponent(str)));
  236. },
  237.  
  238. // 从base64解密
  239. decode(str) {
  240. return decodeURIComponent(escape(atob(str)));
  241. },
  242.  
  243. //数字补零
  244. repairTimer(i){
  245. if (i >= 0 && i <= 9) {
  246. return "0" + i;
  247. } else {
  248. return i;
  249. }
  250. },
  251.  
  252. // 接受文件名并返回大写扩展名
  253. getExtension(name) {
  254. const reg = /(?!\.)\w+$/;
  255. if (reg.test(name)) {
  256. let match = name.match(reg);
  257. return match[0].toUpperCase();
  258. }
  259. return '';
  260. },
  261.  
  262. // 文件大小转换(以字节为单位)
  263. sizeFormat(value) {
  264. if (value === +value) {
  265. let unit = ["字节(B)", "千字节(KB)", "兆字节(MB)", "吉字节(GB)", "太字节(TB)", "拍字节(PB)", "艾字节(EB)", "泽字节(ZB)", "尧字节(YB)"];
  266. let index = Math.floor(Math.log(value) / Math.log(1024));
  267. let size = value / Math.pow(1024, index);
  268. size = size.toFixed(1);
  269. return size + unit[index];
  270. }
  271. return '';
  272. },
  273.  
  274. // 根据数组中的每个文件名进行排序,使用了localeCompare方法来比较中文字符串的顺序。
  275. sortByName(arr) {
  276. const handle = () => {
  277. return (a, b) => {
  278. const p1 = a.filename ? a.filename : a.server_filename;
  279. const p2 = b.filename ? b.filename : b.server_filename;
  280. return p1.localeCompare(p2, "zh-CN");
  281. };
  282. };
  283. arr.sort(handle());
  284. },
  285.  
  286. // 替换特殊字符为下划线
  287. fixFilename(name) {
  288. return name.replace(/[!?&|`"'*\/:<>\\]/g, '_');
  289. },
  290.  
  291. // 接受Blob对象和文件名,然后创建临时链接指向blob对象,之后创建a标签指向临时链接和设置文件名,最后模拟点击a标签实现下载和释放临时链接
  292. blobDownload(blob, filename) {
  293. if (blob instanceof Blob) {
  294. const url = URL.createObjectURL(blob);
  295. const a = document.createElement('a');
  296. a.href = url;
  297. a.download = filename;
  298. a.click();
  299. URL.revokeObjectURL(url);
  300. }
  301. },
  302.  
  303. // 使用Post发送请求
  304. post(url, data, headers, type) {
  305. if (this.isType(data) === 'object') {
  306. data = JSON.stringify(data);
  307. }
  308. return new Promise((resolve, reject) => {
  309. GM_xmlhttpRequest({
  310. method: "POST", url, headers, data,
  311. responseType: type || 'json',
  312. onload: (res) => {
  313. // 判断是否是base64编码的字符串,包含空白字符
  314. if (/^[A-Za-z0-9+/=\\s]+$/.test(res.response) || /^[A-Za-z0-9+/=\\s]+$/.test(res.responseText)) {
  315. // 使用base里封装好的decode函数(decodeURIComponent和escape)解码非ASCII字符
  316. if (res.response) {
  317. res.decodedResponse = JSON.parse(base.decode(res.response));
  318. };
  319. if (res.responseText) {
  320. res.decodedResponseText = base.decode(res.responseText);
  321. };
  322. };
  323. console.log('【(改)网盘直链下载助手】Post\n请求地址:' + url + '\n请求头部:' + JSON.stringify(headers) + '\n请求结果:', res);
  324. type === 'blob' ? resolve(res) : resolve(res.response || res.responseText);
  325. },
  326. onerror: (err) => {
  327. reject(err);
  328. },
  329. });
  330. });
  331. },
  332.  
  333. // 使用Get发送请求
  334. get(url, headers, type, extra) {
  335. return new Promise((resolve, reject) => {
  336. let requestObj = GM_xmlhttpRequest({
  337. method: "GET", url, headers,
  338. responseType: type || 'json',
  339. onload: (res) => {
  340. console.log('【(改)网盘直链下载助手】Get Onload\n请求地址:' + url + '\n请求头部:' + JSON.stringify(headers) + '\n请求结果:', res);
  341. if (res.status === 204) {
  342. requestObj.abort();
  343. idm[extra.index] = true;
  344. }
  345. if (type === 'blob') {
  346. res.status === 200 && base.blobDownload(res.response, extra.filename);
  347. resolve(res);
  348. } else {
  349. resolve(res.response || res.responseText);
  350. }
  351. },
  352. onprogress: (res) => {
  353. console.log('【(改)网盘直链下载助手】Get OnProgress\n请求地址:' + url + '\n请求头部:' + JSON.stringify(headers) + '\n返回结果:', res);
  354. if (extra && extra.filename && extra.index) {
  355. res.total > 0 ? progress[extra.index] = (res.loaded * 100 / res.total).toFixed(2) : progress[extra.index] = 0.00;
  356. }
  357. },
  358. onloadstart() {
  359. extra && extra.filename && extra.index && (request[extra.index] = requestObj);
  360. },
  361. onerror: (err) => {
  362. reject(err);
  363. },
  364. });
  365. });
  366. },
  367.  
  368. // 获取最终链接
  369. getFinalUrl(url, headers) {
  370. return new Promise((resolve, reject) => {
  371. let requestObj = GM_xmlhttpRequest({
  372. method: "GET", url, headers,
  373. onload: (res) => {
  374. console.log('【(改)网盘直链下载助手】GetFinalUrl\n请求地址:' + url + '\n请求头部:' + JSON.stringify(headers) + '\n返回结果:', res);
  375. resolve(res.finalUrl);
  376. },
  377. onerror: (err) => {
  378. reject(err);
  379. },
  380. });
  381. });
  382. },
  383.  
  384. stringify(obj) {
  385. let str = '';
  386. for (var key in obj) {
  387. if (obj.hasOwnProperty(key)) {
  388. var value = obj[key];
  389. if (Array.isArray(value)) {
  390. for (var i = 0; i < value.length; i++) {
  391. str += encodeURIComponent(key) + '=' + encodeURIComponent(value[i]) + '&';
  392. }
  393. } else {
  394. str += encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';
  395. }
  396. }
  397. }
  398. return str.slice(0, -1); // 去掉末尾的 "&"
  399. },
  400.  
  401. addStyle(id, tag, css) {
  402. tag = tag || 'style';
  403. let doc = document, styleDom = doc.getElementById(id);
  404. if (styleDom) return;
  405. let style = doc.createElement(tag);
  406. style.rel = 'stylesheet';
  407. style.id = id;
  408. tag === 'style' ? style.innerHTML = css : style.href = css;
  409. doc.getElementsByTagName('head')[0].appendChild(style);
  410. },
  411.  
  412. sleep(time) {
  413. return new Promise(resolve => setTimeout(resolve, time));
  414. },
  415.  
  416. findReact(dom, traverseUp = 0) {
  417. const key = Object.keys(dom).find(key => {
  418. return key.startsWith("__reactFiber$")
  419. || key.startsWith("__reactInternalInstance$");
  420. });
  421. const domFiber = dom[key];
  422. if (domFiber == null) return null;
  423.  
  424. if (domFiber._currentElement) {
  425. let compFiber = domFiber._currentElement._owner;
  426. for (let i = 0; i < traverseUp; i++) {
  427. compFiber = compFiber._currentElement._owner;
  428. }
  429. return compFiber._instance;
  430. }
  431.  
  432. const GetCompFiber = fiber => {
  433. let parentFiber = fiber.return;
  434. while (typeof parentFiber.type == "string") {
  435. parentFiber = parentFiber.return;
  436. }
  437. return parentFiber;
  438. };
  439. let compFiber = GetCompFiber(domFiber);
  440. for (let i = 0; i < traverseUp; i++) {
  441. compFiber = GetCompFiber(compFiber);
  442. }
  443. return compFiber.stateNode || compFiber;
  444. },
  445.  
  446. //注册默认设置
  447. initDefaultConfig() {
  448. let value = [{
  449. name: 'setting_rpc_domain',
  450. value: 'http://localhost'
  451. }, {
  452. name: 'setting_rpc_port',
  453. value: '16800'
  454. }, {
  455. name: 'setting_rpc_path',
  456. value: '/jsonrpc'
  457. }, {
  458. name: 'setting_rpc_token',
  459. value: ''
  460. }, {
  461. name: 'setting_rpc_dir',
  462. value: 'D:'
  463. }, {
  464. name: 'setting_terminal_type',
  465. value: 'wc'
  466. }, {
  467. name: 'setting_theme_color',
  468. value: '#574ab8'
  469. }, {
  470. name: 'setting_init_code',
  471. value: ''
  472. }, {
  473. name: 'setting_getuser_info',
  474. value: 'yes'
  475. }, {
  476. name: 'setting_hide_idm',
  477. value: 'no'
  478. }, {
  479. name: 'setting_baidu_theme',
  480. value: 'no'
  481. }];
  482.  
  483. value.forEach((v) => {
  484. // 没有对应的项目就添加上项目
  485. base.getValue(v.name) === undefined && base.setValue(v.name, v.value);
  486. });
  487. },
  488.  
  489. // 设置界面
  490. showSetting() {
  491. let dom = '',
  492. btn = '',
  493. colorList = ['#09AAFF','#cc3235','#637df8','#518c17','#ed944b','#f969a5','#bca280','#574AB8','#0d53ff','#637dff','#3181f9','#f8d800','#0396ff','#32ccbc','#f6416c','#2271b1','#59524c','#10171d','#1d2327','#18a497'],
  494. colorNameList = ['度盘<br>经典蓝','度盘<br>平安红','度盘<br>霞光紫','度盘<br>盎然绿','度盘<br>周年橙','度盘<br>幸会粉','度盘<br>午后棕','度盘<br>星空紫','夸克<br>明亮蓝','阿里<br>云盘紫','移动<br>彩云蓝','果核<br>柠檬黄','果核<br>默认蓝','果核<br>碧波绿','果核<br>玫瑰红','文派<br>默认蓝','文派<br>咖啡灰','文派<br>默认黑','OpenAI<br>默认黑','OpenAI<br>默认青'];
  495. 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>`;
  496. 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>`;
  497. 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>`;
  498. 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>`;
  499. 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>`;
  500.  
  501. colorList.forEach((v, i) => {
  502. btn += `<div data-color="${v}" style="background: ${v};border: 1px solid ${v}" class="pl-color-box ${v === base.getValue('setting_theme_color') ? 'checked' : 'listener-color'}">
  503. <div data-color="${v}" class="pl-mask">${colorNameList[i]}${v === base.getValue('setting_theme_color') ? '<br>(当前)' : ''}</div>
  504. </div>`;
  505. });
  506.  
  507.  
  508. dom += `<label class="pl-setting-label"><div class="pl-label">终端类型</div><select class="pl-input listener-terminal">`;
  509. Object.keys(terminalType).forEach(k => {
  510. dom += `<option value="${k}" ${base.getValue('setting_terminal_type') === k ? 'selected' : ''}>${terminalType[k]}</option>`;
  511. });
  512. dom += `</select></label>`;
  513.  
  514. dom +=`<label class="pl-setting-label"><div class="pl-label">未找到IDM提示</div><select class="pl-input hide_idm">`;
  515. Object.keys(hideidm).forEach(value2 => {dom += `<option value="${value2}" ${base.getValue('setting_hide_idm') === value2 ? 'selected' : ''}>${hideidm[value2]}</option>`;});
  516. dom += `</select></label>`;
  517.  
  518. dom +=`<label class="pl-setting-label"><div class="pl-label">修改百度网盘界面为主题色[实验]</div><select class="pl-input baidu_theme">`;
  519. Object.keys(hideidm).forEach(value3 => {dom += `<option value="${value3}" ${base.getValue('setting_baidu_theme') === value3 ? 'selected' : ''}>${baidutheme[value3]}</option>`;});
  520. dom += `</select></label>`;
  521.  
  522. dom += `<label class="pl-setting-label"><div class="pl-label">主题颜色</div> <div class="pl-color">${btn}</div></label>`;
  523.  
  524. dom += `<button type="button" class="swal2-confirm swal2-styled listener-register">熄灭已经点亮的按钮</button>`
  525.  
  526. dom = '<div>' + dom + '</div>';
  527.  
  528. Swal.fire({
  529. title: '助手设置',
  530. html: dom,
  531. icon: 'info',
  532. showCloseButton: true,
  533. showConfirmButton: false,
  534. footer: pan.footer,
  535. }).then(() => {
  536. message.success('设置成功!');
  537. history.go(0);
  538. });
  539.  
  540. doc.on('click', '.listener-register', async (e) => {
  541. base.registerInitCode(111111);
  542. });
  543. doc.on('click', '.listener-color', async (e) => {
  544. base.setValue('setting_theme_color', e.target.dataset.color);
  545. message.success('主题色设置成功!');
  546. setTimeout(function(){
  547. history.go(0);
  548. },1000)
  549. });
  550. doc.on('input', '.listener-domain', async (e) => {
  551. base.setValue('setting_rpc_domain', e.target.value);
  552. });
  553. doc.on('input', '.listener-port', async (e) => {
  554. base.setValue('setting_rpc_port', e.target.value);
  555. });
  556. doc.on('input', '.listener-path', async (e) => {
  557. base.setValue('setting_rpc_path', e.target.value);
  558. });
  559. doc.on('input', '.listener-token', async (e) => {
  560. base.setValue('setting_rpc_token', e.target.value);
  561. });
  562. doc.on('input', '.listener-dir', async (e) => {
  563. base.setValue('setting_rpc_dir', e.target.value);
  564. });
  565. doc.on('change', '.listener-terminal', async (e) => {
  566. base.setValue('setting_terminal_type', e.target.value);
  567. });
  568. doc.on('change', '.hide_idm', async (e) => {
  569. base.setValue('setting_hide_idm', e.target.value);
  570. });
  571. doc.on('change', '.baidu_theme', async (e) => {
  572. base.setValue('setting_baidu_theme', e.target.value);
  573. });
  574. },
  575.  
  576. showInfo() {
  577. let hideinfo='';
  578. hideinfo +=`<span>以下内容都是脚本自己检测到的信息<br>本页面仅作为调试使用<span>`;
  579. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">版本</div>${realversion}</label>`;
  580. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">虚假版本</div>${version}</label>`;
  581. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">脚本作者</div>${realauthor}</label>`;
  582. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">虚假作者</div>${author}</label>`;
  583. hideinfo += `<label class="pl-setting-label"><div class="pl-label">初始化暗号</div>${pan.num}</label>`;
  584. hideinfo += `<label class="pl-setting-label"><div class="pl-label">UA代理</div>${pan.ua}</label>`;
  585. hideinfo += `<label class="pl-setting-label"><div class="pl-label">公众号地址</div>${pan.img}</label>`;
  586. hideinfo += `<label class="pl-setting-label"><div class="pl-label">网盘万能助手</div>${pan.assistant}</label>`;
  587. hideinfo += `<label class="pl-setting-label"><div class="pl-label">网盘镜像</div>${pan.mirror}</label>`;
  588. hideinfo += `<label class="pl-setting-label"><div class="pl-label">RPC管理</div>${pan.d}</label>`;
  589. hideinfo += `<label class="pl-setting-label"><div class="pl-label">IDM介绍</div>${pan.idm}</label>`;
  590. hideinfo += `<label class="pl-setting-label"><div class="pl-label">提示文本</div>0、${pan.init[0]}<br>1、${pan.init[1]}<br>2、${pan.init[2]}<br>3、${pan.init[3]}<br>4、${pan.init[4]}<br>5、${pan.init[5]}</label>`;
  591. hideinfo += `<label class="pl-setting-label"><div class="pl-label">页脚</div>${pan.fotter}</label>`;
  592. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">允许油小猴在线收集作者名称与获取暗号(没有用)</div><select class="pl-input getuser_info">`;
  593. Object.keys(getuserinfo).forEach(value1 => {hideinfo += `<option value="${value1}" ${base.getValue('setting_getuser_info') === value1 ? 'selected' : ''}>${getuserinfo[value1]}</option></select></label>`;});
  594. hideinfo = '<div>' + hideinfo + '</div>';
  595.  
  596. Swal.fire({
  597. icon: 'info',
  598. title: '脚本分析信息',
  599. html: hideinfo,
  600. allowOutsideClick: false,
  601. showCloseButton: true,
  602. confirmButtonText: '保存配置(关闭)'
  603. });
  604.  
  605. doc.on('change', '.getuser_info', async (e) => {
  606. base.setValue('setting_getuser_info', e.target.value);
  607. });
  608. },
  609.  
  610. showPanInfo() {
  611. let hideinfo='';
  612. hideinfo +=`<span>本页面仅作为调试使用<span>`;
  613. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">版本</div>${realversion}</label>`;
  614. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">作者</div>${realauthor}</label>`;
  615. hideinfo += `<label class="pl-setting-label"><div class="pl-label">初始化暗号</div>${pan.num}</label>`;
  616. hideinfo += `<label class="pl-setting-label"><div class="pl-label">公众号地址</div>${pan.img}</label>`;
  617. hideinfo += `<label class="pl-setting-label"><div class="pl-label">网盘万能助手</div>${pan.assistant}</label>`;
  618. hideinfo += `<label class="pl-setting-label"><div class="pl-label">RPC管理</div>${pan.d}</label>`;
  619. hideinfo += `<label class="pl-setting-label"><div class="pl-label">IDM介绍</div>${pan.idm}</label>`;
  620. hideinfo = '<div>' + hideinfo + '</div>';
  621.  
  622. Swal.fire({
  623. icon: 'info',
  624. title: '脚本分析信息',
  625. html: hideinfo,
  626. allowOutsideClick: false,
  627. showCloseButton: true,
  628. confirmButtonText: '关闭'
  629. });
  630. },
  631.  
  632. showUpdateLog() {
  633. Swal.fire({
  634. icon: 'info',
  635. title: '更新日志(关闭按钮在下面哦)',
  636. html: `<span>
  637. V1.0.7<br>1、重构夸克网盘、阿里云盘按钮。<br><br>
  638. V1.0.6.9<br>1、下载窗口加入关闭按钮。<br><br>
  639. V1.0.6.8<br>1、修复夸克网盘按钮错位。<br><br>
  640. V1.0.6.7<br>1、将百度网盘界面修改为主题色,可在设置选择是否修改;<br>2、增加主题色名称,更改部分内容颜色;<br>3、移动云盘API下载支持批量复制;<br>4、优化控制台输出结果;<br>5、百度网盘API下载不使用IDM时可以显示剩余时间;<br>6、“取消点亮按钮”按钮的位置现已移动到设置页面。<br>7homo特有的彩蛋又回来力(喜)。<br><br>
  641. V1.0.6.6<br>1、修复暗号错误。<br><br>
  642. V1.0.6.5<br>1、修复即使输入正确暗号也不能成功点亮按钮的服务器错误。<br><br>
  643. V1.0.6.4<br>1、跟进官方V6.1.1版本,修复阿里云盘获取下载链接时的问题。<br><br>
  644. V1.0.6.3<br>1、照顾小屏幕用户,将始终显示复制全部链接的按钮;<br>2、增加取消下载时的动画。<br><br>
  645. V1.0.6.2<br>1、修复部分界面错位,实现CSS内置;<br>2、百度网盘界面将变得更加简洁。<br><br>
  646. V1.0.6.1<br>1、新增百度云盘API下载支持复制链接;<br>2、为了照顾手机浏览器用户,增大项目之间间隙,新增隐藏IDM提示选项,可在助手设置中启用;<br>3、修改CSS,界面会出现更多的主题色;<br>4、支持在游小猴官网查看暗号;<br>5、修复部分语法错误。<br><br>
  647. V1.0.6<br>1、修复了打开阿里云盘分享连接时因下载移动端广告导致只能点击API下载;<br>2、跟进官方6.0.4版本,修复夸克网盘获取下载链接失效、支持移动云盘。<br><br>
  648. V1.0.5.5<br>1、感谢<a href="https://github.com/Night-stars-1">Night-stars-1</a>的帮助,修复因为原作者服务器导致的初始化暗号识别错误;<br>2、修改一些文本以及提供给服务器的信息。<br><br>
  649. V1.0.5.4<br>1、小修小改css,让主题色出现在更多地方;<br>2、修改下载链接获取失败的提示;<br>3、增加更多的主题色,可在助手设置查看;<br>4homo彩蛋被删去力(悲)。<br><br>
  650. V1.0.5.3<br>1、修啦修啦,阿里云盘可以摸到下载菜单了。<br><br>
  651. V1.0.5.2<br>1、增加脚本信息菜单(没有用);<br>2、优化阿里云盘显示svg图片;<br>3、修改弹窗按钮颜色。<br><br>
  652. V1.0.5.1<br>1、修复在切换按钮主题后夸克网盘不能正常显示按钮。<br><br>
  653. V1.0.5<br>1、跟进官方V5.0.4版本;<br>2、小改动,照着官方版本更正文件名称检测;<br>3、保留彩蛋,但必须舍弃官方暗号。<br><br>
  654. V1.0.4<br>大改!<br>1、修复了原作者留下的夸克网盘切换文件夹就多一个“下载助手”按钮的大BUG;<br>2、终于来了,在下载菜单增加“助手设置”“更新日志”按钮;<br>【再也不用点进油猴管理再进设置了(保留油猴管理内设置)】<br>3、修改阿里云盘和夸克网盘下载助手按钮样式;<br>4、增加“取消点亮按钮”油猴菜单;<br>5、修改部分css,使其与选择的主题更贴切。<br><br>
  655. V1.0.3<br>1、增加一个小彩蛋; 提示:homo(需在未点亮按钮状态触发)<br>【需要重新恢复按钮为未点亮状态请进入 已安装脚本->编辑->开发者->重置到出厂->确定】<br>2、修改/增加默认主题色。<br><br>
  656. V1.0.2<br>1、修改并加宽界面,调整部分css,使Sweetalert2界面更美观,更与原版相近;<br>2、修改部分提示文字,使文字更容易复制。 <br><br>
  657. V1.0.1<br>1、去除更新提示;<br>2、更新Sweetalert211版本;<br>3、部分CDN节点更换为jsdelivr。<br><br>
  658. V1.0.0<br>1、增加“注入”功能(bushi);<br>2、去除广告。
  659. </span>`,
  660. allowOutsideClick: false,
  661. showCloseButton: false,
  662. confirmButtonText: '我已阅',
  663. });
  664. },
  665.  
  666. createTip() {
  667. $('body').append('<div class="pl-tooltip"></div>');
  668.  
  669. doc.on('mouseenter mouseleave', '.listener-tip', (e) => {
  670. if (e.type === 'mouseenter') {
  671. let filename = e.currentTarget.innerText;
  672. let size = e.currentTarget.dataset.size;
  673. let tip = `${filename}<span style="margin-left: 10px;color: ${color}">${size}</span>`;
  674. $(e.currentTarget).css({opacity: '0.5'});
  675. $('.pl-tooltip').html(tip).css({
  676. 'left': e.pageX + 10 + 'px',
  677. 'top': e.pageY - e.currentTarget.offsetTop > 14 ? e.pageY + 'px' : e.pageY + 20 + 'px'
  678. }).show();
  679. } else {
  680. $(e.currentTarget).css({opacity: '1'});
  681. $('.pl-tooltip').hide(0);
  682. }
  683. });
  684. },
  685.  
  686. createLoading() {
  687. return $('<div class="pl-loading"><div class="pl-loading-box"><div><div></div><div></div></div></div></div>');
  688. },
  689.  
  690. createDownloadIframe() {
  691. let $div = $('<div style="padding:0;margin:0;display:block"></div>');
  692. let $iframe = $('<iframe src="javascript:;" id="downloadIframe" style="display:none"></iframe>');
  693. $div.append($iframe);
  694. $('body').append($div);
  695. },
  696.  
  697. getMirrorList(link, mirror, thread = 2) {
  698. let host = new URL(link).host;
  699. let mirrors = [];
  700. for (let i = 0; i < mirror.length; i++) {
  701. for (let j = 0; j < thread; j++) {
  702. let item = link.replace(host, mirror[i]) + '&'.repeat(j);
  703. mirrors.push(item);
  704. }
  705. }
  706. return mirrors.join('\n');
  707. },
  708.  
  709. addPanLinkerStyle() {
  710. color = base.getValue('setting_theme_color');
  711. let css = `
  712. body::-webkit-scrollbar { display: none }
  713. ::-webkit-scrollbar { width: 6px; height: 10px }
  714. ::-webkit-scrollbar-track { border-radius: 0; background: none }
  715. ::-webkit-scrollbar-thumb { background-color: rgba(85,85,85,.4) }
  716. ::-webkit-scrollbar-thumb,::-webkit-scrollbar-thumb:hover { border-radius: 5px; -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.2) }
  717. ::-webkit-scrollbar-thumb:hover { background-color: rgba(85,85,85,.3) }
  718. .swal2-popup { font-size: 16px !important; width: 550px;}
  719. .pl-popup { font-size: 12px !important; width: 90% !important;}
  720. .pl-popup a { color: ${color} !important; }
  721. .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; }
  722. .pl-title { font-size: 16px!important; line-height: 1!important;white-space: nowrap!important; text-overflow: ellipsis!important;}
  723. .pl-content { padding: 0 !important; font-size: 12px!important; }
  724. .pl-main { background-color:${color}15 ;overflow:auto; border-radius: 5px; max-height:calc(${document.documentElement.clientHeight}px - 250px);}
  725. .pl-footer {font-size: 15px!important; margin-top: 10px!important; padding-top: 5px!important; color: #f56c6c!important;}
  726. .pl-item { display: flex; align-items: center; line-height: 22px; height: 50px; background-color: ${color}30; border-radius: 5px; margin: 8px 6px; }
  727. .pl-item-name { flex: 0 0 170px; text-align: left;margin: 6px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; cursor:default; height: 30px;}
  728. .pl-item-link { flex: 1; text-align: left; white-space: nowrap; text-overflow: ellipsis;cursor:pointer; overflow: hidden; }
  729. .pl-item-btn { background: ${color}; border-radius: 3px; color: #ffffff; cursor: pointer; font-size: 12px; outline: none; display: flex; align-items: center; justify-content: center; margin: 6px 6px; padding: 0.625em 1.1em; }
  730. .pl-item-tip { display: flex; justify-content: space-between;flex: 1; }
  731. .pl-back { width: 70px; background: #ddd; border-radius: 3px; cursor:pointer; margin:1px 6px; }
  732. .pl-ext { display: inline-block; width: 44px; background: #999; color: #fff; height: 16px; line-height: 16px; font-size: 12px; border-radius: 3px;}
  733. .pl-retry {padding: 3px 10px; background: #cc3235; color: #fff; border-radius: 3px; cursor: pointer;}
  734. .pl-browserdownload { padding: 3px 10px; background: ${color}; color: #fff; border-radius: 3px; cursor: pointer;}
  735. .pl-item-progress { display:flex;flex: 1;align-items:center}
  736. .pl-progress { display: inline-block;vertical-align: middle;width: 100%; box-sizing: border-box;line-height: 1;position: relative;height:15px; flex: 1}
  737. .pl-progress-outer { height: 15px;border-radius: 100px;background-color: #c1c1c1;overflow: hidden;position: relative;vertical-align: middle;}
  738. .pl-progress-inner{ position: absolute;left: 0;top: 0;background-color: ${color};text-align: center;border-radius: 100px;line-height: 1;white-space: nowrap;transition: width .6s ease;}
  739. .pl-progress-inner-text { display: inline-block;vertical-align: middle;color: #ffffff;font-size: 12px;margin: 0 5px;height: 15px}
  740. .pl-progress-tip{ flex:1; text-align:right}
  741. .pl-progress-how{ flex: 0 0 100px; background: #ddd; border-radius: 3px; margin-left: 10px; cursor: pointer; text-align: center;}
  742. .pl-progress-stop{ flex: 0 0 80px; background: #cc3235; cursor: pointer; margin: 6px 6px 6px 10px; font-size: 12px; border: 0; border-radius: 4px; color: #ffffff; outline: none; display: flex; align-items: center; justify-content: center; padding: 0.625em 1.1em;}
  743. .pl-progress-inner-text:after { display: inline-block;content: "";height: 100%;vertical-align: middle;}
  744. .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: 6px 6px; padding: 0.625em 1.1em;transition: 0.3s opacity; }
  745. .pl-btn-primary:hover { opacity: 0.9;transition: 0.3s opacity; }
  746. .pl-btn-success { background: #55af28; animation: easeOpacity 1.2s 2; animation-fill-mode:forwards }
  747. .pl-btn-info { background: #606266; }
  748. .pl-btn-warning { background: #da9328; }
  749. .pl-btn-warning { background: #da9328; }
  750. .pl-btn-danger { background: #cc3235; }
  751. .baidu-button { background: ${color} !important; border-color: ${color} !important;}
  752. .baidu-button:hover { background: ${color}b0 !important; border-color: ${color} !important;}
  753. .ali-button {border: 0 solid transparent;font-size: 14px;margin-left: 20px;padding: 1px 12px;position: relative;height: 32px;width: 32px;background: linear-gradient(129.12deg, ${color} 0%, rgba(99, 125, 255, 0.75) 100%);border-radius: 100px;display: flex;align-items: center;justify-content: center;color: var(--basic_white);cursor: pointer;transition: all .3s ease;}
  754. .ali-button:hover {background: linear-gradient(129.12deg, #446dff 0%, ${color} 100%);}
  755. .ali-btn-icon {vertical-align: -0.2em;}
  756. .tianyi-button {margin-right: 20px; padding: 4px 12px; border-radius: 4px; color: #fff; font-size: 12px; border: 1px solid ${color}; background: ${color}; cursor: pointer; position: relative;}
  757. .tianyi-button:hover {border-color: ${color}b0; background: ${color}b0;}
  758. .yidong-button {float: left; position: relative; margin: 20px 24px 20px 0; width: 110px; height: 36px; background: ${color}; border-radius: 2px; font-size: 14px; color: #fff; line-height: 39px; text-align: center; cursor: pointer;}
  759. .yidong-share-button {display: inline-block; position: relative; font-size: 14px; line-height: 36px; text-align: center; color: #fff; border: 1px solid ${color}; border-radius: 2px; padding: 0 24px; background: ${color};}
  760. .yidong-share-button:hover {background: ${color}b0;}
  761. .yidong-button:hover {background: ${color}b0;}
  762. .yidong-btn { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAGNQTFRFAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////mkUNoAAAACF0Uk5TAAbHPP9AMRtr9PwrV8zqXfmNgDODHTLD4iJxhGJJ8Z269m0aDgAAAMZJREFUeJzd0ssOgyAQBVDUK74rWq0PFP3/ryxqTMdGqJtuvGHD5CTDTGDs3nFc17kEPcC7BH3At/Tjvk5AYbBU+NcrwghL4uQDk3gtRSF1KWCCQEpghkd+3jp/ICNQoDANU0AQCJQmWAJ3h8+q3mFdvSywQdttsGvRWGAPLReoHXrbG6WWAzBoJ+3DaCnWI39NLbcvszvLeuTB2fYoqbNBNo7sGjzk31BhMsEJitxmiKk8zSQwE8gFjBGcNuCzOmdqPrib5A2JRQ7qK9g+hQAAAABJRU5ErkJggg==); height: 20px; line-height: 20px; display: inline-block; background-repeat: no-repeat; background-size: 20px 20px; text-indent: 25px;}
  763. .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: ${color};margin-left: 12px;padding: 0px 12px;position: relative; cursor:pointer; height: 36px;}
  764. .xunlei-button:hover {background: ${color}b0;}
  765. .quark-button {background: ${color} !important;}
  766. .quark-button:hover { background: ${color}b0 !important;}
  767. .quark-btn-icon {width: 20px !important; height: 20px !important; vertical-align: -0.3em !important;}
  768. .pl-dropdown-menu {position: absolute;padding: 5px 0;color: ${color};background: #fff;z-index: 999;width: 102px;border-radius: 10px;box-shadow: 0 0 1px 1px rgb(28 28 32 / 5%), 0 8px 24px rgb(28 28 32 / 12%); text-align: center;}
  769. .pl-dropdown-menu-old {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%);}
  770. .pl-dropdown-menu-item {height: 30px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: ${color}; transition: all 0.3s ease;}
  771. .pl-dropdown-menu-item:hover { background-color: ${color}15 !important;}
  772. .pl-button-mode {padding: 0px !important; color: ${color} !important;}
  773. .pl-button-mode:hover {background-color: ${color}15 !important;}
  774. .pl-button, .pl-dropdown-menu { transition: all 0.3s ease;}
  775. .pl-button .pl-dropdown-menu { display: none;}
  776. .pl-button:hover .pl-dropdown-menu { display: block!important; }
  777. .pl-button-init { opacity: 0.5; animation: easeInitOpacity 1.2s 3; animation-fill-mode:forwards }
  778. @keyframes easeInitOpacity { from { opacity: 0.5; } 50% { opacity: 1 } to { opacity: 0.5; } }
  779. @keyframes easeOpacity { from { opacity: 1; } 50% { opacity: 0.35 } to { opacity: 1; } }
  780. .element-clicked { opacity: 0.5; }
  781. .pl-extra { margin-top: 10px;display:flex}
  782. .pl-extra button { flex: 1}
  783. .pointer { cursor:pointer }
  784. .pl-setting-label { display: flex;align-items: center;justify-content: space-between;padding-top: 10px; }
  785. .pl-label { flex: 0 0 100px;text-align:left; }
  786. .pl-input { flex: 1; padding: 8px 10px; border: 1px solid #c2c2c2; border-radius: 5px; font-size: 14px }
  787. .init-input {
  788. width: 373px !important;
  789. font-size: 20px !important;
  790. text-align: center !important;
  791. font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif !important;
  792. font-weight: 300 !important;
  793. }
  794. .pl-color { flex: 1;display: flex;flex-wrap: wrap}
  795. .pl-color-box { width: 50px;height: 50px;margin:10px 10px 0 0;; box-sizing: border-box;border:1px solid #fff;cursor:pointer }
  796. .pl-mask {
  797. width: 50px;
  798. height: 50px;
  799. background-color: rgba(0,0,0,0.5);
  800. opacity: 0;
  801. transition: opacity 0.3s;
  802. position: absolute;
  803. color: #fff;
  804. font-size: 13px;
  805. display: flex;
  806. align-items: center;
  807. justify-content: center;
  808. }
  809. .pl-color-box:hover .pl-mask {
  810. opacity: 1;
  811. }
  812. .pl-color-box.checked { border:3px dashed #111!important }
  813. .pl-close:focus { outline: 0; box-shadow: none; }
  814. .tag-danger {color:#cc3235;margin: 0 5px;}
  815. .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;}
  816. @keyframes load { 0% { transform: rotate(0deg) } 100% { transform: rotate(360deg) } }
  817. .pl-loading-box > div > div { position: absolute;border-radius: 50%;}
  818. .pl-loading-box > div > div:nth-child(1) { top: 9px;left: 9px;width: 82px;height: 82px;background: #ffffff;}
  819. .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;}
  820. .pl-loading { width: 16px;height: 16px;display: inline-block;overflow: hidden;background: none;}
  821. .pl-loading-box { width: 100%;height: 100%;position: relative;transform: translateZ(0) scale(0.16);backface-visibility: hidden;transform-origin: 0 0;}
  822. .pl-loading-box div { box-sizing: content-box; }
  823. .swal2-container { z-index:100000!important; }
  824. body.swal2-height-auto { height: inherit!important; }
  825.  
  826.  
  827. .share-detail-content .share-content {
  828. width: auto !important;
  829. }
  830. .DetailLayout--content--14Z28Ay {
  831. width: 950px !important;
  832. }
  833. /* webkit, opera, IE9, Chrome*/
  834. ::selection {
  835. background-color: ${color} !important;
  836. background: ${color} !important;
  837. color: white;
  838. }
  839. /* mozilla firefox */
  840. ::-moz-selection {
  841. background-color: ${color} !important;
  842. background: ${color} !important;
  843. color: white;
  844. }
  845. `;
  846. this.addStyle('panlinker-style', 'style', css);
  847.  
  848.  
  849. let swalcss = `
  850. .swal2-popup.swal2-toast{box-sizing:border-box;grid-column:1/4!important;grid-row:1/4!important;grid-template-columns:1fr 99fr 1fr;padding:1em;overflow-y:hidden;background:#fff;box-shadow:0 0 1px hsla(0deg,0%,0%,.075),0 1px 2px hsla(0deg,0%,0%,.075),1px 2px 4px hsla(0deg,0%,0%,.075),1px 3px 8px hsla(0deg,0%,0%,.075),2px 4px 16px hsla(0deg,0%,0%,.075);pointer-events:all}
  851. .swal2-popup.swal2-toast>*{grid-column:2}
  852. .swal2-popup.swal2-toast .swal2-title{margin:.5em 1em;padding:0;font-size:1em;text-align:initial}
  853. .swal2-popup.swal2-toast .swal2-loading{justify-content:center}
  854. .swal2-popup.swal2-toast .swal2-input{height:2em;margin:.5em;font-size:1em}
  855. .swal2-popup.swal2-toast .swal2-validation-message{font-size:1em}
  856. .swal2-popup.swal2-toast .swal2-footer{margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}
  857. .swal2-popup.swal2-toast .swal2-close{grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}
  858. .swal2-popup.swal2-toast .swal2-html-container{margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}
  859. .swal2-popup.swal2-toast .swal2-html-container:empty{padding:0}
  860. .swal2-popup.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}
  861. .swal2-popup.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}
  862. .swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:700}
  863. .swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}
  864. .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}
  865. .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}
  866. .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}
  867. .swal2-popup.swal2-toast .swal2-actions{justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}
  868. .swal2-popup.swal2-toast .swal2-styled{margin:.25em .5em;padding:.4em .6em;font-size:1em}
  869. .swal2-popup.swal2-toast .swal2-success{border-color:#a5dc86}
  870. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;transform:rotate(45deg);border-radius:50%}
  871. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.8em;left:-.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}
  872. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}
  873. .swal2-popup.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}
  874. .swal2-popup.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}
  875. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}
  876. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}
  877. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}
  878. .swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-toast-animate-success-line-tip .75s;animation:swal2-toast-animate-success-line-tip .75s}
  879. .swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-toast-animate-success-line-long .75s;animation:swal2-toast-animate-success-line-long .75s}
  880. .swal2-popup.swal2-toast.swal2-show{-webkit-animation:swal2-toast-show .5s;animation:swal2-toast-show .5s}
  881. .swal2-popup.swal2-toast.swal2-hide{-webkit-animation:swal2-toast-hide .1s forwards;animation:swal2-toast-hide .1s forwards}
  882. .swal2-container{display:grid;position:fixed;z-index:1060;top:0;right:0;bottom:0;left:0;box-sizing:border-box;grid-template-areas:"top-start top top-end" "center-start center center-end" "bottom-start bottom-center bottom-end";grid-template-rows:minmax(-webkit-min-content,auto) minmax(-webkit-min-content,auto) minmax(-webkit-min-content,auto);grid-template-rows:minmax(min-content,auto) minmax(min-content,auto) minmax(min-content,auto);height:100%;padding:.625em;overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}
  883. .swal2-container.swal2-backdrop-show,.swal2-container.swal2-noanimation{background:#00000066}
  884. .swal2-container.swal2-backdrop-hide{background:0 0!important}
  885. .swal2-container.swal2-bottom-start,.swal2-container.swal2-center-start,.swal2-container.swal2-top-start{grid-template-columns:minmax(0,1fr) auto auto}
  886. .swal2-container.swal2-bottom,.swal2-container.swal2-center,.swal2-container.swal2-top{grid-template-columns:auto minmax(0,1fr) auto}
  887. .swal2-container.swal2-bottom-end,.swal2-container.swal2-center-end,.swal2-container.swal2-top-end{grid-template-columns:auto auto minmax(0,1fr)}
  888. .swal2-container.swal2-top-start>.swal2-popup{align-self:start}
  889. .swal2-container.swal2-top>.swal2-popup{grid-column:2;align-self:start;justify-self:center}
  890. .swal2-container.swal2-top-end>.swal2-popup,.swal2-container.swal2-top-right>.swal2-popup{grid-column:3;align-self:start;justify-self:end}
  891. .swal2-container.swal2-center-left>.swal2-popup,.swal2-container.swal2-center-start>.swal2-popup{grid-row:2;align-self:center}
  892. .swal2-container.swal2-center>.swal2-popup{grid-column:2;grid-row:2;align-self:center;justify-self:center}
  893. .swal2-container.swal2-center-end>.swal2-popup,.swal2-container.swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;align-self:center;justify-self:end}
  894. .swal2-container.swal2-bottom-left>.swal2-popup,.swal2-container.swal2-bottom-start>.swal2-popup{grid-column:1;grid-row:3;align-self:end}
  895. .swal2-container.swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;justify-self:center;align-self:end}
  896. .swal2-container.swal2-bottom-end>.swal2-popup,.swal2-container.swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;align-self:end;justify-self:end}
  897. .swal2-container.swal2-grow-fullscreen>.swal2-popup,.swal2-container.swal2-grow-row>.swal2-popup{grid-column:1/4;width:100%}
  898. .swal2-container.swal2-grow-column>.swal2-popup,.swal2-container.swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}
  899. .swal2-container.swal2-no-transition{transition:none!important}
  900. .swal2-popup{display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0,100%);width:32em;max-width:100%;padding:0 0 1.25em;border:none;border-radius:5px;background:#fff;color:#545454;font-family:inherit;font-size:1rem}
  901. .swal2-popup:focus{outline:0}
  902. .swal2-popup.swal2-loading{overflow-y:hidden}
  903. .swal2-title{position:relative;max-width:100%;margin:0;padding:.8em 1em 0;color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}
  904. .swal2-actions{display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:auto;margin:1.25em auto 0;padding:0}
  905. .swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}
  906. .swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}
  907. .swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}
  908. .swal2-loader{display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:${color} transparent ${color} transparent !important}
  909. .swal2-styled{margin:.3125em;padding:.625em 1.1em;transition:box-shadow .1s;box-shadow:0 0 0 3px transparent;font-weight:500;transition: all 0.3s ease !important;}
  910. .swal2-styled:not([disabled]){cursor:pointer}
  911. .swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:${color} !important;color:#fff;font-size:1em}
  912. .swal2-styled.swal2-confirm:focus{box-shadow:0 0 0 3px ${color}80 !important}
  913. .swal2-styled.swal2-deny{border:0;border-radius:.25em;background:initial;background-color:#dc3741 !important;color:#fff;font-size:1em}
  914. .swal2-styled.swal2-deny:focus{box-shadow:0 0 0 3px rgba(220,55,65,.5)}
  915. .swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#dd3333 !important;color:#fff;font-size:1em}
  916. .swal2-styled.swal2-cancel:focus{box-shadow:0 0 0 3px rgba(110,120,129,.5)}
  917. .swal2-styled.swal2-default-outline:focus{box-shadow:0 0 0 3px rgba(100,150,200,.5)}
  918. .swal2-styled:focus{outline:0}
  919. .swal2-styled::-moz-focus-inner{border:0}
  920. .swal2-footer{justify-content:center;margin:1em 0 0;padding:1em 1em 0;border-top:1px solid #eee;color:inherit;font-size:1em}
  921. .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto!important;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px}
  922. .swal2-timer-progress-bar{width:100%;height:.25em;background:${color}33 !important}
  923. .swal2-image{max-width:100%;margin:2em auto 1em}
  924. .swal2-close{z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:color .1s,box-shadow .1s;border:none;border-radius:5px;background:0 0;color:#ccc;font-family:serif;font-family:monospace;font-size:2.5em;cursor:pointer;justify-self:end}
  925. .swal2-close:hover{transform:none;background:0 0;color:#f27474}
  926. .swal2-close:focus{outline:0;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}
  927. .swal2-close::-moz-focus-inner{border:0}
  928. .swal2-html-container{z-index:1;justify-content:center;margin:1em 1.6em .3em;padding:0;overflow:auto;color:inherit;font-size:1.125em;font-weight:400;line-height:normal;text-align:center;word-wrap:break-word;word-break:break-word}
  929. .swal2-checkbox,.swal2-file,.swal2-input,.swal2-radio,.swal2-select,.swal2-textarea{margin:1em 2em 3px}
  930. .swal2-file,.swal2-input,.swal2-textarea{box-sizing:border-box;width:auto;transition:border-color .1s,box-shadow .1s;border:1px solid #d9d9d9;border-radius:.1875em;background:0 0;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px transparent;color:inherit;font-size:1.125em}
  931. .swal2-file.swal2-inputerror,.swal2-input.swal2-inputerror,.swal2-textarea.swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}
  932. .swal2-file:focus,.swal2-input:focus,.swal2-textarea:focus{border:1px solid #b4dbed;outline:0;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5)}
  933. .swal2-file::-moz-placeholder,.swal2-input::-moz-placeholder,.swal2-textarea::-moz-placeholder{color:#ccc}
  934. .swal2-file::placeholder,.swal2-input::placeholder,.swal2-textarea::placeholder{color:#ccc}
  935. .swal2-range{margin:1em 2em 3px;background:#fff}
  936. .swal2-range input{width:80%}
  937. .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}
  938. .swal2-range input,.swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}
  939. .swal2-input{height:2.625em;padding:0 .75em}
  940. .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:0 0;font-size:1.125em}
  941. .swal2-textarea{height:6.75em;padding:.75em}
  942. .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:0 0;color:inherit;font-size:1.125em}
  943. .swal2-checkbox,.swal2-radio{align-items:center;justify-content:center;background:#fff;color:inherit}
  944. .swal2-checkbox label,.swal2-radio label{margin:0 .6em;font-size:1.125em}
  945. .swal2-checkbox input,.swal2-radio input{flex-shrink:0;margin:0 .4em}
  946. .swal2-input-label{display:flex;justify-content:center;margin:1em auto 0}
  947. .swal2-validation-message{align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:#f0f0f0;color:#666;font-size:1em;font-weight:300}
  948. .swal2-validation-message::before{content:"!";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}
  949. .swal2-icon{position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;border:.25em solid transparent;border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;-webkit-user-select:none;-moz-user-select:none;user-select:none}
  950. .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}
  951. .swal2-icon.swal2-error{border-color:#f27474;color:#f27474}
  952. .swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}
  953. .swal2-icon.swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}
  954. .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}
  955. .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}
  956. .swal2-icon.swal2-error.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}
  957. .swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark{-webkit-animation:swal2-animate-error-x-mark .5s;animation:swal2-animate-error-x-mark .5s}
  958. .swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}
  959. .swal2-icon.swal2-warning.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}
  960. .swal2-icon.swal2-warning.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-i-mark .5s;animation:swal2-animate-i-mark .5s}
  961. .swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}
  962. .swal2-icon.swal2-info.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}
  963. .swal2-icon.swal2-info.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-i-mark .8s;animation:swal2-animate-i-mark .8s}
  964. .swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}
  965. .swal2-icon.swal2-question.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}
  966. .swal2-icon.swal2-question.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-question-mark .8s;animation:swal2-animate-question-mark .8s}
  967. .swal2-icon.swal2-success{border-color:#a5dc86;color:#a5dc86}
  968. .swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;transform:rotate(45deg);border-radius:50%}
  969. .swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}
  970. .swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}
  971. .swal2-icon.swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-.25em;left:-.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}
  972. .swal2-icon.swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}
  973. .swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}
  974. .swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}
  975. .swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}
  976. .swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-animate-success-line-tip .75s;animation:swal2-animate-success-line-tip .75s}
  977. .swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-animate-success-line-long .75s;animation:swal2-animate-success-line-long .75s}
  978. .swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right{-webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;animation:swal2-rotate-success-circular-line 4.25s ease-in}
  979. .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:0 0;font-weight:600}
  980. .swal2-progress-steps li{display:inline-block;position:relative}
  981. .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:${color} !important;color:#fff;line-height:2em;text-align:center}
  982. .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:${color} !important}
  983. .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}
  984. .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}
  985. .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:${color} !important}
  986. [class^=swal2]{-webkit-tap-highlight-color:transparent}
  987. .swal2-show{-webkit-animation:swal2-show .3s;animation:swal2-show .3s}
  988. .swal2-hide{-webkit-animation:swal2-hide .15s forwards;animation:swal2-hide .15s forwards}
  989. .swal2-noanimation{transition:none}
  990. .swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}
  991. .swal2-rtl .swal2-close{margin-right:initial;margin-left:0}
  992. .swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}
  993. .leave-russia-now-and-apply-your-skills-to-the-world{display:flex;position:fixed;z-index:1939;top:0;right:0;bottom:0;left:0;flex-direction:column;align-items:center;justify-content:center;padding:25px 0 20px;background:#20232a;color:#fff;text-align:center}
  994. .leave-russia-now-and-apply-your-skills-to-the-world div{max-width:560px;margin:10px;line-height:146%}
  995. .leave-russia-now-and-apply-your-skills-to-the-world iframe{max-width:100%;max-height:55.5555555556vmin;margin:16px auto}
  996. .leave-russia-now-and-apply-your-skills-to-the-world strong{border-bottom:2px dashed #fff}
  997. .leave-russia-now-and-apply-your-skills-to-the-world button{display:flex;position:fixed;z-index:1940;top:0;right:0;align-items:center;justify-content:center;width:48px;height:48px;margin-right:10px;margin-bottom:-10px;border:none;background:0 0;color:#aaa;font-size:48px;font-weight:700;cursor:pointer}
  998. .leave-russia-now-and-apply-your-skills-to-the-world button:hover{color:#fff}
  999. @-webkit-keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}
  1000. 33%{transform:translateY(0) rotateZ(-2deg)}
  1001. 66%{transform:translateY(.3125em) rotateZ(2deg)}
  1002. 100%{transform:translateY(0) rotateZ(0)}
  1003. }@keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}
  1004. 33%{transform:translateY(0) rotateZ(-2deg)}
  1005. 66%{transform:translateY(.3125em) rotateZ(2deg)}
  1006. 100%{transform:translateY(0) rotateZ(0)}
  1007. }@-webkit-keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}
  1008. }@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}
  1009. }@-webkit-keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}
  1010. 54%{top:.125em;left:.125em;width:0}
  1011. 70%{top:.625em;left:-.25em;width:1.625em}
  1012. 84%{top:1.0625em;left:.75em;width:.5em}
  1013. 100%{top:1.125em;left:.1875em;width:.75em}
  1014. }@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}
  1015. 54%{top:.125em;left:.125em;width:0}
  1016. 70%{top:.625em;left:-.25em;width:1.625em}
  1017. 84%{top:1.0625em;left:.75em;width:.5em}
  1018. 100%{top:1.125em;left:.1875em;width:.75em}
  1019. }@-webkit-keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}
  1020. 65%{top:1.25em;right:.9375em;width:0}
  1021. 84%{top:.9375em;right:0;width:1.125em}
  1022. 100%{top:.9375em;right:.1875em;width:1.375em}
  1023. }@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}
  1024. 65%{top:1.25em;right:.9375em;width:0}
  1025. 84%{top:.9375em;right:0;width:1.125em}
  1026. 100%{top:.9375em;right:.1875em;width:1.375em}
  1027. }@-webkit-keyframes swal2-show{0%{transform:scale(.7)}
  1028. 45%{transform:scale(1.05)}
  1029. 80%{transform:scale(.95)}
  1030. 100%{transform:scale(1)}
  1031. }@keyframes swal2-show{0%{transform:scale(.7)}
  1032. 45%{transform:scale(1.05)}
  1033. 80%{transform:scale(.95)}
  1034. 100%{transform:scale(1)}
  1035. }@-webkit-keyframes swal2-hide{0%{transform:scale(1);opacity:1}
  1036. 100%{transform:scale(.5);opacity:0}
  1037. }@keyframes swal2-hide{0%{transform:scale(1);opacity:1}
  1038. 100%{transform:scale(.5);opacity:0}
  1039. }@-webkit-keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}
  1040. 54%{top:1.0625em;left:.125em;width:0}
  1041. 70%{top:2.1875em;left:-.375em;width:3.125em}
  1042. 84%{top:3em;left:1.3125em;width:1.0625em}
  1043. 100%{top:2.8125em;left:.8125em;width:1.5625em}
  1044. }@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}
  1045. 54%{top:1.0625em;left:.125em;width:0}
  1046. 70%{top:2.1875em;left:-.375em;width:3.125em}
  1047. 84%{top:3em;left:1.3125em;width:1.0625em}
  1048. 100%{top:2.8125em;left:.8125em;width:1.5625em}
  1049. }@-webkit-keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}
  1050. 65%{top:3.375em;right:2.875em;width:0}
  1051. 84%{top:2.1875em;right:0;width:3.4375em}
  1052. 100%{top:2.375em;right:.5em;width:2.9375em}
  1053. }@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}
  1054. 65%{top:3.375em;right:2.875em;width:0}
  1055. 84%{top:2.1875em;right:0;width:3.4375em}
  1056. 100%{top:2.375em;right:.5em;width:2.9375em}
  1057. }@-webkit-keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}
  1058. 5%{transform:rotate(-45deg)}
  1059. 12%{transform:rotate(-405deg)}
  1060. 100%{transform:rotate(-405deg)}
  1061. }@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}
  1062. 5%{transform:rotate(-45deg)}
  1063. 12%{transform:rotate(-405deg)}
  1064. 100%{transform:rotate(-405deg)}
  1065. }@-webkit-keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}
  1066. 50%{margin-top:1.625em;transform:scale(.4);opacity:0}
  1067. 80%{margin-top:-.375em;transform:scale(1.15)}
  1068. 100%{margin-top:0;transform:scale(1);opacity:1}
  1069. }@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}
  1070. 50%{margin-top:1.625em;transform:scale(.4);opacity:0}
  1071. 80%{margin-top:-.375em;transform:scale(1.15)}
  1072. 100%{margin-top:0;transform:scale(1);opacity:1}
  1073. }@-webkit-keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}
  1074. 100%{transform:rotateX(0);opacity:1}
  1075. }@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}
  1076. 100%{transform:rotateX(0);opacity:1}
  1077. }@-webkit-keyframes swal2-rotate-loading{0%{transform:rotate(0)}
  1078. 100%{transform:rotate(360deg)}
  1079. }@keyframes swal2-rotate-loading{0%{transform:rotate(0)}
  1080. 100%{transform:rotate(360deg)}
  1081. }@-webkit-keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}
  1082. 100%{transform:rotateY(0)}
  1083. }@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}
  1084. 100%{transform:rotateY(0)}
  1085. }@-webkit-keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}
  1086. 25%{transform:rotateZ(-25deg);opacity:.4}
  1087. 50%{transform:rotateZ(15deg);opacity:.8}
  1088. 75%{transform:rotateZ(-5deg);opacity:1}
  1089. 100%{transform:rotateX(0);opacity:1}
  1090. }@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}
  1091. 25%{transform:rotateZ(-25deg);opacity:.4}
  1092. 50%{transform:rotateZ(15deg);opacity:.8}
  1093. 75%{transform:rotateZ(-5deg);opacity:1}
  1094. 100%{transform:rotateX(0);opacity:1}
  1095. }body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}
  1096. body.swal2-height-auto{height:auto!important}
  1097. body.swal2-no-backdrop .swal2-container{background-color:transparent!important;pointer-events:none}
  1098. body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}
  1099. body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}
  1100. @media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}
  1101. body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}
  1102. body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static!important}
  1103. }body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:transparent;pointer-events:none}
  1104. body.swal2-toast-shown .swal2-container.swal2-top{top:0;right:auto;bottom:auto;left:50%;transform:translateX(-50%)}
  1105. body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{top:0;right:0;bottom:auto;left:auto}
  1106. body.swal2-toast-shown .swal2-container.swal2-top-left,body.swal2-toast-shown .swal2-container.swal2-top-start{top:0;right:auto;bottom:auto;left:0}
  1107. body.swal2-toast-shown .swal2-container.swal2-center-left,body.swal2-toast-shown .swal2-container.swal2-center-start{top:50%;right:auto;bottom:auto;left:0;transform:translateY(-50%)}
  1108. body.swal2-toast-shown .swal2-container.swal2-center{top:50%;right:auto;bottom:auto;left:50%;transform:translate(-50%,-50%)}
  1109. body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{top:50%;right:0;bottom:auto;left:auto;transform:translateY(-50%)}
  1110. body.swal2-toast-shown .swal2-container.swal2-bottom-left,body.swal2-toast-shown .swal2-container.swal2-bottom-start{top:auto;right:auto;bottom:0;left:0}
  1111. body.swal2-toast-shown .swal2-container.swal2-bottom{top:auto;right:auto;bottom:0;left:50%;transform:translateX(-50%)}
  1112. body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{top:auto;right:0;bottom:0;left:auto}
  1113. `;
  1114. this.addStyle('swal-style', 'style', swalcss);
  1115.  
  1116.  
  1117. let baiducss = `
  1118. .wp-s-aside-nav__file-list-all.is-active.is-exact-active, .wp-s-aside-nav__sub-container.is-active, .wp-s-aside-nav__sub-item.is-active, .wp-s-aside-nav__main-item.is-active, .wp-s-agile-tool-bar__h-action-button:hover, .u-button--text, .wp-s-search .u-input__inner:focus+.u-input__suffix .wp-s-search__search-text, .wp-s-search .u-input__inner:hover+.u-input__suffix .wp-s-search__search-text, .wp-s-pan-list__file-name-title-text:hover, .aiTools-aside__item--active, .wp-s-pan-table__sort .icon.active, .g-button, .u-button--week, .nd-list-name__title-text:hover, .NHcGw .open-enable .file-name a:hover, .NHcGw .open-enable .file-name a:active, .BNfIyPb .cEefyz.open-enable .file-name a:hover, .BNfIyPb .cEefyz.open-enable .file-name a:active, .wp-s-pan-file-main__nav-item-title, .theme-primary-text, .icon.active, .wrapper .blueBtn[data-v-c74cfc74], .module-timeline-ruler .hover-day-desc .day-desc[data-v-08d8abbe], .imc-edit-keyword__breadcrumb-golist, .imc-edit-keyword__bottom-wrapper .u-button--week.is-disabled, .imc-keyword-list__table-list .action-btn {
  1119. color: ${color} !important;
  1120. }
  1121. .wp-s-aside-nav__file-list-all.is-active.is-exact-active, .wp-s-agile-tool-bar__h-more-group, .wp-s-pan-table__body-row:hover, .wp-s-agile-tool-bar__h-action, .aiTools-aside__item--active, .wp-s-agile-tool-bar__h-action.is-need-left-sep+.is-need-left-sep:after, .wp-s-aside-nav__sub-item.is-active, .NHcGw .jlilR9go, .NHcGw .vzxrm4R, .u-button--week, .u-button--week:focus, .u-button--week:hover, .g-dropdown-button .menu .g-button-menu:hover, .xGLMIab .fufHyA:hover, .module-timeline-ruler .hover-day-desc .day-desc[data-v-08d8abbe], .imc-edit-keyword__bottom-wrapper .u-button--week.is-disabled, .wp-s-pan-table__body-row.selected, .nd-table__body-row.selected {
  1122. transition: all 0.3s ease;
  1123. background-color: ${color}10;
  1124. background: ${color}10;
  1125. }
  1126. .mzf_new_btn, .u-button--primary, .wp-s-aside-nav__quota-progress-rate, .u-checkbox__input.is-checked .u-checkbox__inner, .u-checkbox__input.is-indeterminate .u-checkbox__inner, .g-button-blue, .g-button-blue-large, .select, .m-button, .u-tabs__active-bar, .module-timeline-ruler .line-current[data-v-08d8abbe], .module-timeline-ruler .line-hover[data-v-08d8abbe], .module-timeline-ruler .line-current[data-v-08d8abbe]:after, .module-timeline-ruler .line-hover[data-v-08d8abbe]:after, .u-switch.is-checked .u-switch__core {
  1127. transition: all 0.3s ease;
  1128. background-color: ${color} !important;
  1129. }
  1130. .wp-s-pan-table__body-row:hover, .wp-s-search .u-input--small .u-input__inner:hover, .u-checkbox__input.is-checked .u-checkbox__inner, .u-checkbox__inner:hover, .u-checkbox__input.is-indeterminate .u-checkbox__inner, .nd-table__body-row:hover .u-checkbox__inner, .NHcGw .jlilR9go, .NHcGw .vzxrm4R, .u-button--week, .u-button--primary, .g-button, .u-switch.is-checked .u-switch__core {
  1131. transition: all 0.3s ease;
  1132. border-color: ${color} !important;
  1133. }
  1134. .wp-s-aside-nav__file-list-cate.is-active {
  1135. background-color: #fff !important
  1136. }
  1137. .g-button:hover, .wp-s-pan-file-main__nav-item-sep {
  1138. transition: all 0.3s ease;
  1139. color: ${color}d0 !important;
  1140. }
  1141. .g-button-blue:hover, .g-button.g-button-blue-large:hover {
  1142. transition: all 0.3s ease;
  1143. color: ${color}d0 !important;
  1144. background-color: ${color}b0 !important;
  1145. }
  1146. .g-button:hover .icon {
  1147. color: ${color}d0;
  1148. }
  1149. .back-old-version {
  1150. background: #f1f3f8;
  1151. border-radius: 32px;
  1152. width: 30px;
  1153. height: 30px;
  1154. display: flex;
  1155. justify-content: center;
  1156. }
  1157. /* 百度网盘 */
  1158. :not([class*="rwl-exempt"]) ::selection {
  1159. background-color: ${color} !important;
  1160. background: ${color} !important;
  1161. color: white;
  1162. }
  1163. `
  1164. if (base.getValue('setting_baidu_theme') === 'yes') {
  1165. this.addStyle('panlinker-baidu-style', 'style', baiducss);
  1166. };
  1167. },
  1168.  
  1169. async initDialog() {
  1170. let result = await Swal.fire({
  1171. title: pan.init[0],
  1172. allowOutsideClick: false,
  1173. showCloseButton: true,
  1174. showCancelButton: true,
  1175. confirmButtonText: '确定',
  1176. html: `<div><img style="width: 250px;margin-bottom: 10px;" src="${pan.img}" alt="${pan.img}">
  1177. <input class="swal2-input init-input" id="init" type="text" placeholder="${pan.init[1]}"><br>
  1178. <span>你可以选择"注入"立即点亮按钮,或者输入暗号点亮。<br>当前暗号是:“${pan.num}”。<br>
  1179. 还可以扫码支持一下原作者油小猴的公众号<br>或者来给这个改版点个<a href="https://github.com/hmjz100/Online-disk-direct-link-download-assistant/">Star</a>...<br>
  1180. 点亮后可以精简百度网盘界面哦!</span></div>`,
  1181. cancelButtonText: '注入(点亮下载助手按钮)'
  1182. });
  1183. if (result.isDismissed && result.dismiss === 'close') {return};
  1184. if (result.isDismissed && result.dismiss === 'cancel') {
  1185. console.log("【(改)网盘直链下载助手】\n正在注入点亮按钮设置项目...");
  1186. message.warning("正在注入点亮按钮设置项目...");
  1187. setTimeout(() => {
  1188. base.setValue('setting_init_code', pan.num);
  1189. message.success("注入成功!");
  1190. setTimeout(() => {
  1191. message.success(pan.init[2]);
  1192. setTimeout(() => {
  1193. history.go(0);
  1194. }, 3000);
  1195. }, 3000);
  1196. }, 5000);
  1197. return;
  1198. };
  1199. if (pan.num === $('#init').val()) {
  1200. console.log("【(改)网盘直链下载助手】\n暗号正确")
  1201. message.success(pan.init[2]);
  1202. setTimeout(() => {
  1203. base.setValue('setting_init_code', pan.num);
  1204. history.go(0);
  1205. }, 3000)
  1206. return;
  1207. } else if ($('#init').val() === '114514' || $('#init').val() === '1919810' || $('#init').val() === '1145141919810') {
  1208. /*---
  1209. homo彩蛋又回来力(喜)
  1210. imageUrl: 'https://pic4.zhimg.com/80/v2-1b97a088e156c015108dec663bba8b04.jpg',
  1211. imageUrl: 'https://lh1.hetaousercontent.com/img/7d4c1c0b4adb0e95.jpg',
  1212. */
  1213. await Swal.fire({
  1214. icon: 'error',
  1215. title: '1145141919810',
  1216. html: '<span>homo特有的数字当然不行啦<br>哼哼哼啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊</span>',
  1217. timer: 8000,
  1218. imageUrl: 'https://pic4.zhimg.com/80/v2-1b97a088e156c015108dec663bba8b04.jpg',
  1219. allowOutsideClick: false,
  1220. timerProgressBar: true,
  1221. showConfirmButton: false,
  1222. showCancelButton: true,
  1223. cancelButtonText: '哼哼哼啊啊啊啊啊啊啊啊啊啊',
  1224. });
  1225. message.info("成就:你触发了一个homo特有的彩蛋!");
  1226. setTimeout(() => {
  1227. Swal.fire({
  1228. title: '1145141919810',
  1229. text:'homo特有的数字当然不行啦...吗?',
  1230. icon: 'question',
  1231. imageUrl: 'https://lh1.hetaousercontent.com/img/7d4c1c0b4adb0e95.jpg',
  1232. showConfirmButton: false,
  1233. allowOutsideClick: false,
  1234. });
  1235. setTimeout(() => {
  1236. base.setValue('setting_init_code', pan.num);
  1237. message.success("成就:哼哼哼啊啊啊啊啊啊啊啊地注入成功(喜)");
  1238. setTimeout(() => {
  1239. history.go(0);
  1240. }, 3000);
  1241. }, 3000)
  1242. }, 4000)
  1243. } else {
  1244. console.log("【(改)网盘直链下载助手】\n暗号错误")
  1245. await Swal.fire({
  1246. imageUrl: pan.img,
  1247. title: pan.init[3],
  1248. html: `<div><span>${pan.init[4]}<br>你可以在返回后选择“注入”立即点亮按钮,<br>或者在输入框键入以下暗号:“${pan.num}”。</span></div>`,
  1249. confirmButtonText: '重新输入(返回)',
  1250. });
  1251. await this.initDialog();
  1252. return;
  1253. };
  1254. },
  1255. };
  1256.  
  1257. //百度网盘
  1258. let baidu = {
  1259.  
  1260. _getExtra() {
  1261. let seKey = decodeURIComponent(base.getCookie('BDCLND'));
  1262. return '{' + '"sekey":"' + seKey + '"' + "}";
  1263. },
  1264.  
  1265. _getSurl() {
  1266. let reg = /(?<=s\/|surl=)([a-zA-Z0-9_-]+)/g;
  1267. if (reg.test(location.href)) {
  1268. return location.href.match(reg)[0];
  1269. }
  1270. return '';
  1271. },
  1272.  
  1273. _getFidList() {
  1274. let fidlist = [];
  1275. selectList.forEach(v => {
  1276. if (+v.isdir === 1) return;
  1277. fidlist.push(v.fs_id);
  1278. });
  1279. return '[' + fidlist + ']';
  1280. },
  1281.  
  1282. _resetData() {
  1283. progress = {};
  1284. $.each(request, (key) => {
  1285. (request[key]).abort();
  1286. });
  1287. $.each(ins, (key) => {
  1288. clearInterval(ins[key]);
  1289. });
  1290. idm = {};
  1291. ins = {};
  1292. request = {};
  1293. },
  1294.  
  1295. setBDUSS() {
  1296. try {
  1297. GM_cookie && GM_cookie('list', {name: 'BDUSS'}, (cookies, error) => {
  1298. if (!error) {
  1299. base.setStorage("baiduyunPlugin_BDUSS", {BDUSS: cookies[0].value});
  1300. }
  1301. });
  1302. } catch (e) {
  1303. }
  1304. },
  1305.  
  1306. getBDUSS() {
  1307. let baiduyunPlugin_BDUSS = base.getStorage('baiduyunPlugin_BDUSS') ? base.getStorage('baiduyunPlugin_BDUSS') : '{"baiduyunPlugin_BDUSS":""}';
  1308. return baiduyunPlugin_BDUSS.BDUSS || '';
  1309. },
  1310.  
  1311. convertLinkToAria(link, filename, ua) {
  1312. let BDUSS = this.getBDUSS();
  1313. if (!!BDUSS) {
  1314. filename = base.fixFilename(filename);
  1315. return encodeURIComponent(`aria2c "${link}" --out "${filename}" --header "User-Agent: ${ua}" --header "Cookie: BDUSS=${BDUSS}"`);
  1316. }
  1317. return {
  1318. link: pan.assistant,
  1319. text: pan.init[5]
  1320. };
  1321. },
  1322.  
  1323. convertLinkToBC(link, filename, ua) {
  1324. let BDUSS = this.getBDUSS();
  1325. if (!!BDUSS) {
  1326. let cookie = `BDUSS=${BDUSS}`;
  1327. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}&cookie=${encodeURIComponent(cookie)}&user_agent=${encodeURIComponent(ua)}ZZ`;
  1328. return encodeURIComponent(`bc://http/${base.encode(bc)}`);
  1329. }
  1330. return {
  1331. link: pan.assistant,
  1332. text: pan.init[5]
  1333. };
  1334. },
  1335.  
  1336. convertLinkToCurl(link, filename, ua) {
  1337. let BDUSS = this.getBDUSS();
  1338. if (!!BDUSS) {
  1339. let terminal = base.getValue('setting_terminal_type');
  1340. filename = base.fixFilename(filename);
  1341. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}" -A "${ua}" -b "BDUSS=${BDUSS}"`);
  1342. }
  1343. return {
  1344. link: pan.assistant,
  1345. text: pan.init[5]
  1346. };
  1347. },
  1348.  
  1349. addPageListener() {
  1350. function _factory(e) {
  1351. let target = $(e.target);
  1352. let item = target.parents('.pl-item');
  1353. let link = item.find('.pl-item-link');
  1354. let progress = item.find('.pl-item-progress');
  1355. let tip = item.find('.pl-item-tip');
  1356. let copy = item.find('.pl-item-copy');
  1357. let howidm = item.find('.pl-progress-how');
  1358. let back = item.find('.pl-progress-back');
  1359. let stop = item.find('.pl-progress-stop');
  1360. return {
  1361. item, link, progress, tip, copy, howidm, back, stop, target,
  1362. };
  1363. }
  1364.  
  1365. function _reset(i) {
  1366. ins[i] && clearInterval(ins[i]);
  1367. request[i] && request[i].abort();
  1368. progress[i] = 0;
  1369. idm[i] = false;
  1370. }
  1371.  
  1372. doc.on('mouseenter mouseleave click', '.pl-button.g-dropdown-button', (e) => {
  1373. if (e.type === 'mouseleave') {
  1374. $(e.currentTarget).removeClass('button-open');
  1375. } else {
  1376. $(e.currentTarget).addClass('button-open');
  1377. $(e.currentTarget).find('.pl-dropdown-menu').show();
  1378. }
  1379. });
  1380. doc.on('mouseleave', '.pl-button.g-dropdown-button .pl-dropdown-menu', (e) => {
  1381. $(e.currentTarget).hide();
  1382. });
  1383.  
  1384. doc.on('click', '.pl-button-mode', (e) => {
  1385. mode = e.target.dataset.mode;
  1386. Swal.showLoading();
  1387. this.getPCSLink();
  1388. });
  1389. doc.on('click', '.listener-link-api', async (e) => {
  1390. e.preventDefault();
  1391. let o = _factory(e);
  1392. let $width = o.item.find('.pl-progress-inner');
  1393. let $text = o.item.find('.pl-progress-inner-text');
  1394. let filename = o.link[0].dataset.filename;
  1395. let index = o.link[0].dataset.index;
  1396. _reset(index);
  1397. base.get(o.link[0].dataset.link, {"User-Agent": pan.ua}, 'blob', {filename, index});
  1398. let startTime = Date.now(); // 记录下载开始时间
  1399. ins[index] = setInterval(() => {
  1400. let prog = +progress[index] || 0;
  1401. let isIDM = idm[index] || false;
  1402. if (isIDM) {
  1403. // 处理IDM的代码
  1404. o.tip.hide();
  1405. o.progress.hide();
  1406. o.copy.show();
  1407. o.link.text('已成功唤起IDM,请查看IDM下载框!').animate({opacity: '0.5'}, "slow").show();
  1408. clearInterval(ins[index]);
  1409. setTimeout(
  1410. function (){
  1411. o.link.text('重新下载').animate({opacity: '1'}, "slow");
  1412. },2000
  1413. )
  1414. idm[index] = false;
  1415. } else {
  1416. // 处理普通下载的情况...
  1417. let currentTime = Date.now();
  1418. let elapsedTime = currentTime - startTime;
  1419. let totalProgress = prog / 100;
  1420. let totalElapsedSeconds = elapsedTime / 1000;
  1421. let estimatedTotalTimeSeconds = totalElapsedSeconds / totalProgress;
  1422. let remainingTimeSeconds = estimatedTotalTimeSeconds - totalElapsedSeconds;
  1423.  
  1424. // 将剩余时间转换为天、时、分、秒
  1425. let remainingDays = Math.floor(remainingTimeSeconds / (60 * 60 * 24));
  1426. remainingTimeSeconds %= (60 * 60 * 24);
  1427.  
  1428. let remainingHours = Math.floor(remainingTimeSeconds / (60 * 60));
  1429. remainingTimeSeconds %= (60 * 60);
  1430.  
  1431. let remainingMinutes = Math.floor(remainingTimeSeconds / 60);
  1432. let remainingSeconds = Math.floor(remainingTimeSeconds % 60);
  1433.  
  1434. // 更改界面
  1435. o.link.hide();
  1436. o.tip.hide();
  1437. o.stop.show();
  1438. o.copy.hide();
  1439. o.progress.show();
  1440.  
  1441. // 更新进度条
  1442. $width.css('width', prog + '%');
  1443.  
  1444. // 更新进度条文本
  1445. let timeText = '';
  1446. if (Number.isFinite(remainingDays) && remainingDays > 0) {
  1447. timeText = remainingDays + '天 ' + base.repairTimer(remainingHours) + '时:' + base.repairTimer(remainingMinutes) + '分:' + base.repairTimer(remainingSeconds) + '秒';
  1448. } else if (Number.isFinite(remainingHours) && remainingHours > 0) {
  1449. timeText = base.repairTimer(remainingHours) + '时:' + base.repairTimer(remainingMinutes) + '分:' + base.repairTimer(remainingSeconds) + '秒';
  1450. } else if (Number.isFinite(remainingMinutes) && remainingMinutes > 0) {
  1451. timeText = base.repairTimer(remainingMinutes) + '分:' + base.repairTimer(remainingSeconds) + '秒';
  1452. } else if (Number.isFinite(remainingSeconds) && remainingSeconds > 0) {
  1453. timeText = remainingSeconds + '秒';
  1454. } else if (Number.isFinite(remainingSeconds) && remainingSeconds === 0) {
  1455. timeText = '即将完成';
  1456. } else {
  1457. timeText = '计算中...';
  1458. }
  1459. $text.text(prog + '% | 剩余时间:' + timeText);
  1460.  
  1461. if (prog === 100) {
  1462. setTimeout(function (){
  1463. clearInterval(ins[index]);
  1464. progress[index] = 0;
  1465. o.item.find('.pl-progress-stop').hide();
  1466. o.howidm.hide();
  1467. $text.text('下载完成,正在弹出浏览器下载框!');
  1468. o.back.show()
  1469. setTimeout(function (){
  1470. o.link.text('重新下载').animate({opacity: '1'}, "slow");
  1471. },3000)
  1472. },3000)
  1473. }
  1474. }
  1475. }, 500);
  1476. });
  1477. doc.on('click', '.listener-retry', async (e) => {
  1478. let o = _factory(e);
  1479. o.tip.hide();
  1480. o.link.show();
  1481. });
  1482. doc.on('click', '.listener-how', async (e) => {
  1483. let o = _factory(e);
  1484. let index = o.link[0].dataset.index;
  1485. if (request[index]) {
  1486. request[index].abort();
  1487. clearInterval(ins[index]);
  1488. o.progress.hide();
  1489. o.tip.show();
  1490. }
  1491.  
  1492. });
  1493. doc.on('click', '.listener-stop', async (e) => {
  1494. let o = _factory(e);
  1495. let index = o.link[0].dataset.index;
  1496. if (request[index]) {
  1497. request[index].abort();
  1498. clearInterval(ins[index]);
  1499. o.item.find('.pl-progress-inner-text').text('正在取消...');
  1500. o.item.find('.pl-progress-inner').css('width', 100 + '%');
  1501. setTimeout(function(){
  1502. o.tip.hide();
  1503. o.back.hide();
  1504. o.link.show(0);
  1505. o.copy.show();
  1506. o.progress.hide();
  1507. o.stop.hide();
  1508. },1050)
  1509. }
  1510. });
  1511. doc.on('click', '.listener-back', async (e) => {
  1512. let o = _factory(e);
  1513. o.progress.hide();
  1514. o.tip.hide();
  1515. o.link.show();
  1516. o.copy.show();
  1517. o.stop.hide();
  1518. o.back.hide();
  1519. });
  1520. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  1521. e.preventDefault();
  1522. if (!e.target.dataset.link) {
  1523. $(e.target).removeClass('listener-copy-all').addClass('pl-btn-danger').html(`${pan.init[5]}👉<a href="${pan.assistant}" target="_blank" class="pl-a">点击此处安装</a>👈`);
  1524. } else {
  1525. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  1526. $(e.target).text('复制成功!').animate({opacity: '0.5'}, "slow");
  1527. setTimeout(
  1528. function (){
  1529. $(e.target).text('重新复制').animate({opacity: '1'}, "slow");
  1530. },2000
  1531. )
  1532. }
  1533. });
  1534. doc.on('click', '.listener-link-rpc', async (e) => {
  1535. let target = $(e.currentTarget);
  1536. target.find('.icon').remove();
  1537. target.find('.pl-loading').remove();
  1538. target.prepend(base.createLoading());
  1539. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  1540. if (res === 'success') {
  1541. $('.listener-rpc-task').show();
  1542. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  1543. } else if (res === 'assistant') {
  1544. target.addClass('pl-btn-danger').html(`${pan.init[5]}👉<a href="${pan.assistant}" target="_blank" class="pl-a">点击此处安装</a>👈`);
  1545. } else {
  1546. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  1547. }
  1548. });
  1549. doc.on('click', '.listener-send-rpc', (e) => {
  1550. $('.listener-link-rpc').click();
  1551. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  1552. });
  1553. doc.on('click', '.listener-open-setting', () => {
  1554. base.showSetting();
  1555. });
  1556. doc.on('click', '.listener-open-updatelog', () => {
  1557. base.showUpdateLog();
  1558. });
  1559. doc.on('click', '.listener-rpc-task', () => {
  1560. let rpc = JSON.stringify({
  1561. domain: base.getValue('setting_rpc_domain'),
  1562. port: base.getValue('setting_rpc_port'),
  1563. }), url = `${pan.d}/?rpc=${base.encode(rpc)}#${base.getValue('setting_rpc_token')}`;
  1564. GM_openInTab(url, {active: true});
  1565. });
  1566. document.documentElement.addEventListener('mouseup', (e) => {
  1567. if (e.target.nodeName === 'A' && ~e.target.className.indexOf('pl-a')) {
  1568. e.stopPropagation();
  1569. }
  1570. }, true);
  1571. },
  1572.  
  1573. addButton() {
  1574. if(document.getElementById("pl-button-link")){
  1575. document.getElementById("pl-button-link").remove()
  1576. }
  1577. waitForKeyElements(".wp-s-header__vip-btn-tip", function () {
  1578. let vip1 = document.getElementsByClassName("wp-s-header__vip-btn-tip")[0];
  1579. vip1.remove();
  1580. });
  1581. waitForKeyElements(".app-user-vip-center-tip", function () {
  1582. let vip2 = document.getElementsByClassName("app-user-vip-center-tip")[0];
  1583. vip2.remove();
  1584. });
  1585. waitForKeyElements(".web-header-text-s-45", function () {
  1586. let vip3 = document.getElementById("web-header-text-s-45");
  1587. vip3.remove();
  1588. });
  1589. waitForKeyElements(".wp-s-header__vip-btn", function () {
  1590. let vip4 = document.getElementsByClassName("wp-s-header__vip-btn")[0];
  1591. vip4.innerText = "会员中心";
  1592. });
  1593. waitForKeyElements(".KQcHyA", function () {
  1594. let vip5 = document.getElementsByClassName("KQcHyA")[0];
  1595. vip5.innerText = "会员中心";
  1596. });
  1597. waitForKeyElements(".gOIbzPb", function () {
  1598. let vip6 = document.getElementsByClassName("gOIbzPb")[0];
  1599. vip6.remove();
  1600. });
  1601. waitForKeyElements(".app-user-vip-center-box", function () {
  1602. let vip7 = document.getElementsByClassName("app-user-vip-center-box vip-center-type-2")[0];
  1603. vip7.remove();
  1604. });
  1605. waitForKeyElements(".u-popover", function () {
  1606. setInterval(function(){
  1607. let vip8 = document.getElementsByClassName("wp-s-header-user__vip-center")[0];
  1608. let arrow = document.getElementsByClassName("popper__arrow")[0];
  1609. if(vip8){
  1610. vip8.remove();
  1611. }
  1612. if(arrow){
  1613. arrow.remove();
  1614. };
  1615. },10)
  1616. });
  1617. waitForKeyElements(".wp-s-header-user__create-team-title", function () {
  1618. let ad1 = document.getElementsByClassName("wp-s-header-user__create-team-title")[0];
  1619. ad1.remove();
  1620. });
  1621. waitForKeyElements(".wp-side-options g-clearfix", function () {
  1622. let ad2 = document.getElementsByClassName("wp-side-options g-clearfix")[0];
  1623. ad2.remove();
  1624. });
  1625. waitForKeyElements(".web-header-ad-item", function () {
  1626. let ad3 = document.querySelectorAll(".web-header-ad-item")[0];
  1627. ad3.remove();
  1628. });
  1629. waitForKeyElements(".wp-s-header__game-entry", function () {
  1630. let ad4 = document.getElementsByClassName("wp-s-header__game-entry")[0];
  1631. ad4.remove();
  1632. })
  1633. waitForKeyElements(".operate-guide-close", function () {
  1634. let adwindow = document.getElementsByClassName("operate-guide-close")[0];
  1635. adwindow.click();
  1636. })
  1637. waitForKeyElements(".nd-operate-guidance__close", function () {
  1638. let adwindow = document.getElementsByClassName("nd-operate-guidance__close")[0];
  1639. adwindow.click();
  1640. })
  1641. waitForKeyElements("ctx-menu-container", function () {
  1642. let ctxmenus = document.querySelectorAll(".ctx-menu-container");
  1643. ctxmenus.forEach(ctxmenu => ctxmenu.remove());
  1644. })
  1645. waitForKeyElements(".newIcon", function () {
  1646. let newicon1 = document.getElementsByClassName("newIcon")[0];
  1647. newicon1.remove();
  1648. });
  1649. waitForKeyElements(".u-badge__content", function () {
  1650. let newicon2 = document.getElementsByClassName("u-badge__content is-dot")[0];
  1651. if(newicon2) {
  1652. newicon2.remove();
  1653. }
  1654. });
  1655. waitForKeyElements(".wp-side-options-btn", function () {
  1656. let qiye1 = document.getElementsByClassName("wp-side-options g-clearfix")[0];
  1657. qiye1.remove();
  1658. });
  1659. waitForKeyElements(".app-download", function () {
  1660. let app1 = document.getElementsByClassName("app-download")[0];
  1661. app1.remove();
  1662. });
  1663. if (!pt) return;
  1664. let $toolWrap;
  1665. let $button = $(`<div class="g-dropdown-button pointer pl-button" id="pl-button-link"><div class="baidu-button g-button g-button-blue"><span class="g-button-right"><em class="icon icon-download" style="color:#fff;"></em><span class="text" style="width: 60px;">下载助手</span></span></div><div class="menu" style="color: ${color};border-color: ${color};width:auto;z-index:41;"><div class="g-button-menu pl-button-mode" data-mode="api" ">API下载</div><div class="g-button-menu pl-button-mode" data-mode="aria" ">Aria下载</div><div class="g-button-menu pl-button-mode" data-mode="rpc" ">RPC下载</div><div class="g-button-menu pl-button-mode" data-mode="curl" ">cURL下载</div><div class="g-button-menu pl-button-mode" data-mode="bc" ">BC下载</div><div class="g-button-menu pl-button-mode listener-open-setting" ">助手设置</div><div class="g-button-menu pl-button-mode listener-open-updatelog" ">更新日志</div></div></div>`);
  1666. if (pt === 'home') $toolWrap = $(pan.btn.home);
  1667. if (pt === 'main') {
  1668. $toolWrap = $(pan.btn.main);
  1669. $button = $(`</div><div class="pl-button" id="pl-button-link" style="position: relative; display: inline-block; margin-right: 8px;"><button class="baidu-button u-button u-button--primary u-button--small is-round is-has-icon" style="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="pl-button-mode sub cursor-p" data-mode="api">API下载</li><li class="pl-button-mode sub cursor-p" data-mode="aria">Aria下载</li><li class="pl-button-mode sub cursor-p" data-mode="rpc">RPC下载</li><li class="pl-button-mode sub cursor-p" data-mode="curl">cURL下载</li><li class="pl-button-mode sub cursor-p" data-mode="bc">BC下载</li><li class="pl-button-mode sub cursor-p listener-open-setting"">助手设置</li><li class="pl-button-mode sub cursor-p listener-open-updatelog">更新日志</li></ul></div>`);
  1670. }
  1671. if (pt === 'share') $toolWrap = $(pan.btn.share);
  1672. $toolWrap.prepend($button);
  1673. this.setBDUSS();
  1674. this.addPageListener();
  1675. setInterval(function(){
  1676. if(!document.getElementById("pl-button-link")){
  1677. baidu.addButton();
  1678. }
  1679. },5000)
  1680. },
  1681.  
  1682. addInitButton() {
  1683. if(document.getElementById("pl-button-link")){
  1684. document.getElementById("pl-button-link").remove()
  1685. }
  1686. if (!pt) return;
  1687. let $toolWrap;
  1688. let $button = $(`<div class="g-dropdown-button pointer pl-button-init" id="pl-button-link" 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" style="color:#fff;"></em><span class="text" style="width: 60px;">下载助手</span></span></div></div>`);
  1689. if (pt === 'home') $toolWrap = $(pan.btn.home);
  1690. if (pt === 'main') {
  1691. $toolWrap = $(pan.btn.main);
  1692. $button = $(`<div class="pl-button-init" id="pl-button-link" style="opacity:.5; display: inline-block; margin-right: 8px;"><button class="baidu-button 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>`);
  1693. }
  1694. if (pt === 'share') $toolWrap = $(pan.btn.share);
  1695. $toolWrap.prepend($button);
  1696. $button.click(() => base.initDialog());
  1697. setInterval(function(){
  1698. if(!document.getElementById("pl-button-link")){
  1699. baidu.addInitButton()
  1700. }
  1701. },1000)
  1702. },
  1703.  
  1704. async getToken() {
  1705. let res = await base.getFinalUrl(pan.pcs[3]);
  1706. if (res.indexOf('access_token') === -1) {
  1707. let html = await base.get(pan.pcs[3], {}, 'text');
  1708. let bdstoken = html.match(/name="bdstoken"\s+value="([^"]+)"/)?.[1];
  1709. let client_id = html.match(/name="client_id"\s+value="([^"]+)"/)?.[1];
  1710. let data = {
  1711. grant_permissions_arr: 'netdisk',
  1712. bdstoken: bdstoken,
  1713. client_id: client_id,
  1714. response_type: "token",
  1715. display: "page",
  1716. grant_permissions: "basic,netdisk"
  1717. }
  1718. await base.post(pan.pcs[3], base.stringify(data), {
  1719. 'Content-Type': 'application/x-www-form-urlencoded',
  1720. })
  1721. let res2 = await base.getFinalUrl(pan.pcs[3]);
  1722. let accessToken = res2.match(/access_token=([^&]+)/)?.[1];
  1723. accessToken && base.setStorage('accessToken', accessToken);
  1724. return accessToken;
  1725. }
  1726. let accessToken = res.match(/access_token=([^&]+)/)?.[1];
  1727. accessToken && base.setStorage('accessToken', accessToken);
  1728. return accessToken;
  1729. },
  1730.  
  1731. async getPCSLink(maxRequestTime = 2) {
  1732. selectList = this.getSelectedList();
  1733. let fidList = this._getFidList(), url, res;
  1734.  
  1735. if (pt === 'home' || pt === 'main') {
  1736. if (selectList.length === 0) {
  1737. return message.error('提示:请先勾选要下载的文件!');
  1738. }
  1739. if (fidList.length === 2) {
  1740. return message.error('提示:请打开文件夹后勾选文件!');
  1741. }
  1742. fidList = encodeURIComponent(fidList);
  1743. let accessToken = base.getStorage('accessToken') || await this.getToken();
  1744. url = `${pan.pcs[0]}&fsids=${fidList}&access_token=${accessToken}`;
  1745. res = await base.get(url, {"User-Agent": pan.ua});
  1746. }
  1747. if (pt === 'share') {
  1748. this.getShareData();
  1749. if (selectList.length === 0) {
  1750. return message.error('提示:请先勾选要下载的文件!');
  1751. }
  1752. if (fidList.length === 2) {
  1753. return message.error('提示:请打开文件夹后勾选文件!');
  1754. }
  1755. if (!params.sign) {
  1756. let url = `${pan.pcs[2]}&surl=${params.surl}&logid=${params.logid}`;
  1757. let r = await base.get(url);
  1758. if (r.errno === 0) {
  1759. params.sign = r.data.sign;
  1760. params.timestamp = r.data.timestamp;
  1761. } else {
  1762. let dialog = await Swal.fire({
  1763. toast: true,
  1764. icon: 'info',
  1765. title: `提示:请将文件<span class="tag-danger">[保存到网盘]</span>👉前往<span class="tag-danger">[我的网盘]</span>中下载!`,
  1766. showConfirmButton: true,
  1767. confirmButtonText: '点击保存',
  1768. position: 'top',
  1769. });
  1770. if (dialog.isConfirmed) {
  1771. $('.tools-share-save-hb')[0].click();
  1772. }
  1773. return;
  1774. }
  1775. }
  1776. if (!params.bdstoken) {
  1777. return message.error('提示:请先登录网盘!');
  1778. }
  1779. let formData = new FormData();
  1780. formData.append('encrypt', params.encrypt);
  1781. formData.append('product', params.product);
  1782. formData.append('uk', params.uk);
  1783. formData.append('primaryid', params.primaryid);
  1784. formData.append('fid_list', fidList);
  1785. formData.append('logid', params.logid);
  1786. params.shareType === 'secret' ? formData.append('extra', params.extra) : '';
  1787. url = `${pan.pcs[1]}&sign=${params.sign}&timestamp=${params.timestamp}`;
  1788. res = await base.post(url, formData, {"User-Agent": pan.ua});
  1789. }
  1790. if (res.errno === 0) {
  1791. let html = this.generateDom(res.list);
  1792. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  1793. } else if (res.errno === 112) {
  1794. return message.error('提示:页面过期,请刷新重试!');
  1795. } else if (res.errno === 9019) {
  1796. maxRequestTime--;
  1797. await this.getToken();
  1798. if (maxRequestTime > 0) {
  1799. await this.getPCSLink(maxRequestTime);
  1800. } else {
  1801. message.error('提示:获取下载链接失败!请刷新网页后重试!');
  1802. }
  1803. } else {
  1804. message.error('提示:获取下载链接失败!请刷新网页后重试!(或者试试重新登录网盘?)');
  1805. }
  1806. },
  1807.  
  1808. generateDom(list) {
  1809. let content = '<div class="pl-main">';
  1810. let alinkAllText = '';
  1811. base.sortByName(list);
  1812. list.forEach((v, i) => {
  1813. if (v.isdir === 1) return;
  1814. let filename = v.server_filename || v.filename;
  1815. let ext = base.getExtension(filename);
  1816. let size = base.sizeFormat(v.size);
  1817. let dlink = v.dlink;
  1818. if (mode === 'api') {
  1819. alinkAllText += dlink + '\r\n';
  1820. content += `<div class="pl-item">
  1821. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1822. <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>
  1823. <!--<a class="pl-item-copy" target="_blank" href="${dlink}" title="点击使用浏览器下载" data-filename="${filename}" data-link="${dlink}">传统下载</a>-->
  1824. <button class="pl-item-copy pl-btn-primary listener-copy-all" href="${dlink}" title="点击复制链接" data-filename="${filename}" data-link="${dlink}">复制链接</button>
  1825. <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>
  1826. <div class="pl-item-progress" style="display: none">
  1827. <div class="pl-progress">
  1828. <div class="pl-progress-outer"></div>
  1829. <div class="pl-progress-inner" style="width:5%">
  1830. <div class="pl-progress-inner-text">正在加载进度...0%</div>
  1831. </div>
  1832. </div>
  1833. <span class="pl-progress-stop listener-stop">取消下载</span>
  1834. `;
  1835. if (base.getValue('setting_hide_idm') === 'no') {
  1836. content+=`<span class="pl-progress-tip" >未发现IDM,使用自带浏览器下载</span>
  1837. <span class="pl-progress-back pl-back listener-back" style="display: none">返回</span>
  1838. <span class="pl-progress-how listener-how">如何唤起IDM?</span>
  1839. `
  1840. } else {
  1841. content+=`<span class="pl-progress-tip" style="display: none" >未发现IDM,使用自带浏览器下载</span>
  1842. <span class="pl-progress-back pl-back listener-back" style="display: none">返回</span>
  1843. <span class="pl-progress-how listener-how" style="display: none">如何唤起IDM?</span>
  1844. `
  1845. };
  1846. content +=`</div></div>`
  1847. }
  1848. if (mode === 'aria') {
  1849. let alink = this.convertLinkToAria(dlink, filename, pan.ua);
  1850. if (typeof (alink) === 'object') {
  1851. content += `<div class="pl-item">
  1852. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1853. <a class="pl-item-link pl-a" target="_blank" href="${alink.link}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}<br>复制 ${filename} 下载命令行</a> </div>`;
  1854. } else {
  1855. alinkAllText += alink + '\r\n';
  1856. content += `<div class="pl-item">
  1857. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1858. <a class="pl-item-link pl-a listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}<br>复制 ${filename} 下载命令行</a> </div>`;
  1859. }
  1860. }
  1861. if (mode === 'rpc') {
  1862. content += `<div class="pl-item">
  1863. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1864. <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;">将 ${filename} 推送到 RPC 下载器</span></button></div>`;
  1865. }
  1866. if (mode === 'curl') {
  1867. let alink = this.convertLinkToCurl(dlink, filename, pan.ua);
  1868. if (typeof (alink) === 'object') {
  1869. content += `<div class="pl-item">
  1870. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1871. <a class="pl-item-link pl-a" target="_blank" href="${alink.link}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}<br>复制 ${filename} 下载命令行</a> </div>`;
  1872. } else {
  1873. alinkAllText += alink + '\r\n';
  1874. content += `<div class="pl-item">
  1875. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1876. <a class="pl-item-link pl-a listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}<br>复制 ${filename} 下载命令行</a> </div>`;
  1877. }
  1878. }
  1879. if (mode === 'bc') {
  1880. let alink = this.convertLinkToBC(dlink, filename, pan.ua);
  1881. if (typeof (alink) === 'object') {
  1882. content += `<div class="pl-item">
  1883. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1884. <a class="pl-item-link pl-a" href="${decodeURIComponent(alink.link)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink.text)}<br>下载 ${filename}</a> </div>`;
  1885. } else {
  1886. alinkAllText += alink + '\r\n';
  1887. content += `<div class="pl-item">
  1888. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  1889. <a class="pl-item-link pl-a" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}<br>下载 ${filename}</a> </div>`;
  1890. }
  1891. }
  1892. });
  1893.  
  1894. content += '</div>';
  1895.  
  1896. if (mode === 'api'){
  1897. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;}
  1898. if (mode === 'aria'){
  1899. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;}
  1900. if (mode === 'rpc') {
  1901. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  1902. 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>`;
  1903. }
  1904. if (mode === 'curl'){
  1905. 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>`;}
  1906. return content;
  1907. },
  1908.  
  1909. async sendLinkToRPC(filename, link) {
  1910. let rpc = {
  1911. domain: base.getValue('setting_rpc_domain'),
  1912. port: base.getValue('setting_rpc_port'),
  1913. path: base.getValue('setting_rpc_path'),
  1914. token: base.getValue('setting_rpc_token'),
  1915. dir: base.getValue('setting_rpc_dir'),
  1916. };
  1917. let BDUSS = this.getBDUSS();
  1918. if (!BDUSS) return 'assistant';
  1919.  
  1920. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  1921. let rpcData = {
  1922. id: new Date().getTime(),
  1923. jsonrpc: '2.0',
  1924. method: 'aria2.addUri',
  1925. params: [`token:${rpc.token}`, [link], {
  1926. dir: rpc.dir,
  1927. out: filename,
  1928. header: [`User-Agent: ${pan.ua}`, `Cookie: BDUSS=${BDUSS}`]
  1929. }]
  1930. };
  1931. try {
  1932. let res = await base.post(url, rpcData, {"User-Agent": pan.ua}, '');
  1933. if (res.result) return 'success';
  1934. return 'fail';
  1935. } catch (e) {
  1936. return 'fail';
  1937. }
  1938. },
  1939.  
  1940. getSelectedList() {
  1941. try {
  1942. return require('system-core:context/context.js').instanceForSystem.list.getSelected();
  1943. } catch (e) {
  1944. return document.querySelector('.wp-s-core-pan').__vue__.selectedList;
  1945. }
  1946. },
  1947.  
  1948. getLogid() {
  1949. let ut = require("system-core:context/context.js").instanceForSystem.tools.baseService;
  1950. return ut.base64Encode(base.getCookie("BAIDUID"));
  1951. },
  1952.  
  1953. getShareData() {
  1954. let res = locals.dump();
  1955. params.shareType = 'secret';
  1956. params.sign = '';
  1957. params.timestamp = '';
  1958. params.bdstoken = res.bdstoken.value;
  1959. params.channel = 'chunlei';
  1960. params.clienttype = 0;
  1961. params.web = 1;
  1962. params.app_id = 250528;
  1963. params.encrypt = 0;
  1964. params.product = 'share';
  1965. params.logid = this.getLogid();
  1966. params.primaryid = res.shareid.value;
  1967. params.uk = res.share_uk.value;
  1968. params.shareType === 'secret' && (params.extra = this._getExtra());
  1969. params.surl = this._getSurl();
  1970. },
  1971.  
  1972. detectPage() {
  1973. let path = location.pathname;
  1974. if (/^\/disk\/home/.test(path)) return 'home';
  1975. if (/^\/disk\/main/.test(path)) return 'main';
  1976. if (/^\/(s|share)\//.test(path)) return 'share';
  1977. return '';
  1978. return '';
  1979. },
  1980.  
  1981. showMainDialog(title, html, footer) {
  1982. Swal.fire({
  1983. title,
  1984. html,
  1985. footer,
  1986. allowOutsideClick: false,
  1987. showCloseButton: true,
  1988. position: 'top',
  1989. width: '1000px',
  1990. customClass,
  1991. confirmButtonText: '关闭',
  1992. }).then(() => {
  1993. this._resetData();
  1994. });
  1995. },
  1996.  
  1997. async initPanLinker() {
  1998. base.initDefaultConfig();
  1999. pt = this.detectPage();
  2000. if (base.getValue('setting_getuser_info') === 'yes') {
  2001. let res = await base.post
  2002. (`https://api.youxiaohou.com/config?ver=${version}&a=${author}`, {}, {}, 'text');
  2003. pan = JSON.parse(base.decode(res));
  2004. };
  2005. Object.freeze && Object.freeze(pan);
  2006. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  2007. base.createTip();
  2008. base.registerMenuCommand();
  2009. }
  2010. };
  2011.  
  2012. //阿里云盘
  2013. let ali = {
  2014.  
  2015. convertLinkToAria(link, filename, ua) {
  2016. filename = base.fixFilename(filename);
  2017. return encodeURIComponent(`aria2c "${link}" --out "${filename}" --header "Referer: https://www.aliyundrive.com/"`);
  2018. },
  2019.  
  2020. convertLinkToBC(link, filename, ua) {
  2021. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}&refer=${encodeURIComponent('https://www.aliyundrive.com/')}ZZ`;
  2022. return encodeURIComponent(`bc://http/${base.encode(bc)}`);
  2023. },
  2024.  
  2025. convertLinkToCurl(link, filename, ua) {
  2026. let terminal = base.getValue('setting_terminal_type');
  2027. filename = base.fixFilename(filename);
  2028. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}" -e "https://www.aliyundrive.com/"`);
  2029. },
  2030.  
  2031. addPageListener() {
  2032. doc.on('click', '.pl-button-mode', (e) => {
  2033. mode = e.target.dataset.mode;
  2034. Swal.showLoading();
  2035. this.getPCSLink();
  2036. });
  2037. doc.on('click', '.listener-link-api', async (e) => {
  2038. e.preventDefault();
  2039. let dataset = e.currentTarget.dataset;
  2040. let href = dataset.link;
  2041. let url = await this.getRealLink(dataset.did, dataset.fid);
  2042. if (url) href = url;
  2043. let d = document.createElement("a");
  2044. d.download = e.currentTarget.dataset.filename;
  2045. d.rel = "noopener";
  2046. d.href = href;
  2047. d.dispatchEvent(new MouseEvent("click"));
  2048. });
  2049. doc.on('click', '.listener-link-api-btn', async (e) => {
  2050. base.setClipboard(e.target.dataset.filename);
  2051. $(e.target).text('复制成功').animate({opacity: '0.5'}, "slow");
  2052. setTimeout(
  2053. function (){
  2054. $(e.target).text('重新复制').animate({opacity: '1'}, "slow");
  2055. },2000
  2056. )
  2057. });
  2058. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  2059. e.preventDefault();
  2060. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  2061. $(e.target).text('复制成功!').animate({opacity: '0.5'}, "slow");
  2062. setTimeout(
  2063. function (){
  2064. $(e.target).text('重新复制').animate({opacity: '1'}, "slow");
  2065. },2000
  2066. )
  2067. });
  2068. doc.on('click', '.listener-link-rpc', async (e) => {
  2069. let target = $(e.currentTarget);
  2070. target.find('.icon').remove();
  2071. target.find('.pl-loading').remove();
  2072. target.prepend(base.createLoading());
  2073. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  2074. if (res === 'success') {
  2075. $('.listener-rpc-task').show();
  2076. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  2077. } else {
  2078. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  2079. }
  2080. });
  2081. doc.on('click', '.listener-send-rpc', (e) => {
  2082. $('.listener-link-rpc').click();
  2083. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  2084. });
  2085. doc.on('click', '.listener-open-setting', () => {
  2086. base.showSetting();
  2087. });
  2088. doc.on('click', '.listener-open-updatelog', () => {
  2089. base.showUpdateLog();
  2090. });
  2091. doc.on('click', '.listener-rpc-task', () => {
  2092. let rpc = JSON.stringify({
  2093. domain: base.getValue('setting_rpc_domain'),
  2094. port: base.getValue('setting_rpc_port'),
  2095. }), url = `${pan.d}/?rpc=${base.encode(rpc)}#${base.getValue('setting_rpc_token')}`;
  2096. GM_openInTab(url, {active: true});
  2097. });
  2098. },
  2099.  
  2100. async getRealLink(d, f) {
  2101. let authorization = `${base.getStorage('token').token_type} ${base.getStorage('token').access_token}`;
  2102. let res = await base.post(pan.pcs[1], {
  2103. drive_id: d,
  2104. file_id: f
  2105. }, {
  2106. authorization,
  2107. "content-type": "application/json;charset=utf-8",
  2108. });
  2109. if (res.url) {
  2110. return res.url;
  2111. }
  2112. return '';
  2113. },
  2114.  
  2115. addButton() {
  2116. if(document.getElementById("pl-button-link")){
  2117. document.getElementById("pl-button-link").remove()
  2118. }
  2119. waitForKeyElements(".share-list-banner--1E8Jr", function () {
  2120. let tip1 = document.getElementsByClassName("share-list-banner--1E8Jr")[0];
  2121. tip1.style.zIndex = 0;
  2122. });
  2123. waitForKeyElements(".to-app--DrlQQ", function () {
  2124. let tip2 = document.getElementsByClassName("to-app--DrlQQ")[0];
  2125. tip2.remove();
  2126. });
  2127. waitForKeyElements(".btn-mobile-save--2nXdf", function () {
  2128. let tip3 = document.getElementsByClassName("btn-mobile-save--2nXdf")[0];
  2129. tip3.remove();
  2130. });
  2131. if (!pt) return;
  2132. let $toolWrap;
  2133. let $button = $(`<div id="pl-button-link" class="ali-button pl-button"><span data-role="icon" data-render-as="svg" class="icon"><svg class="ali-btn-icon" 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="#FFFFFF"></path><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="#FFFFFF"></path></svg></span><ul class="pl-dropdown-menu" style="top: 30px; right: 0;"><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><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li></ul></div>`);
  2134. if (pt === 'home') {
  2135. //let ins = setInterval(() => {
  2136. $toolWrap = $(pan.btn.home);
  2137. if ($toolWrap.length > 0) {
  2138. $toolWrap.append($button);
  2139. //clearInterval(ins);
  2140. }
  2141. //}, 50);
  2142. }
  2143. if (pt === 'share') {
  2144. let $button = $(`<div id="pl-button-link" class="ali-button pl-button"><span data-role="icon" data-render-as="svg" class="icon"><svg class="ali-btn-icon" style="margin-right: 3px;" 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="#FFFFFF"></path><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="#FFFFFF"></path></svg>下载助手</span><ul class="pl-dropdown-menu" style="top: 30px; right: 16px;"><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><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li></ul></div>`);
  2145. $button.css({'margin-right': '10px',"height":"36px","width":"auto","padding":"1px 30px"});
  2146. //let ins = setInterval(() => {
  2147. $toolWrap = $(pan.btn.share);
  2148. if ($toolWrap.length > 0) {
  2149. $toolWrap.prepend($button);
  2150. //clearInterval(ins);
  2151. }
  2152. //}, 50);
  2153. }
  2154. base.createDownloadIframe();
  2155. this.addPageListener();
  2156. setInterval(function(){
  2157. if(!document.getElementById("pl-button-link")){
  2158. ali.addButton();
  2159. }
  2160. },1000)
  2161. },
  2162.  
  2163. addInitButton() {
  2164. if(document.getElementById("pl-button-link")){
  2165. document.getElementById("pl-button-link").remove()
  2166. }
  2167. if (!pt) return;
  2168. let $toolWrap;
  2169. let $button = $(`<div id="pl-button-link" class="ali-button pl-button-init"><span data-role="icon" data-render-as="svg" class="icon"><svg class="ali-btn-icon" style="margin-right: 3px;" 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="#FFFFFF"></path><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="#FFFFFF"></path></svg>(未点亮)</span></div>`);
  2170. $button.css({"width":"auto"});
  2171. $button.click(() => base.initDialog());
  2172. if (pt === 'home') {
  2173. //let ins = setInterval(() => {
  2174. $toolWrap = $(pan.btn.home);
  2175. if ($toolWrap.length > 0) {
  2176. $toolWrap.append($button);
  2177. //clearInterval(ins);
  2178. }
  2179. //}, 50);
  2180. }
  2181. if (pt === 'share') {
  2182. let $button = $(`<div id="pl-button-link" class="ali-button pl-button-init"><span data-role="icon" data-render-as="svg" class="icon"><svg class="ali-btn-icon" style="margin-right: 3px;" 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="#FFFFFF"></path><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="#FFFFFF"></path></svg>(未点亮)</span></div>`);
  2183. $button.css({'margin-right': '10px',"height":"36px","padding":"1px 30px","width":"auto"});
  2184. $button.click(() => base.initDialog());
  2185. //let ins = setInterval(() => {
  2186. $toolWrap = $(pan.btn.share);
  2187. if ($toolWrap.length > 0) {
  2188. $toolWrap.prepend($button);
  2189. //clearInterval(ins);
  2190. }
  2191. //}, 50);
  2192. }
  2193. setInterval(function(){
  2194. if(!document.getElementById("pl-button-link")){
  2195. ali.addInitButton();
  2196. }
  2197. },1000)
  2198. },
  2199.  
  2200. async getPCSLink() {
  2201. let reactDomGrid = document.querySelector(pan.dom.grid);
  2202. if (reactDomGrid) {
  2203. let res = await Swal.fire({
  2204. title: '提示',
  2205. html: '<div style="display: flex;align-items: center;justify-content: center;">请先切换到&nbsp;&nbsp;<b>列表视图</b>&nbsp;“<svg class="icon" viewBox="0 0 1024 1024" width="20" height="20"><use xlink:href="#PDSDrag"></use></svg>”&nbsp;&nbsp;后获取下载链接</div>',
  2206. icon: 'info',
  2207. confirmButtonText: '点击切换'
  2208. });
  2209. if (res) {
  2210. document.querySelector(pan.dom.switch).click();
  2211. return message.success('切换成功,请重新获取下载链接!');
  2212. }
  2213. return false;
  2214. }
  2215. selectList = this.getSelectedList();
  2216. if (selectList.length === 0) {
  2217. return message.error('提示:请先勾选要下载的文件!');
  2218. }
  2219. if (this.isOnlyFolder()) {
  2220. return message.error('提示:请打开文件夹后勾选文件!');
  2221. }
  2222. if (pt === 'share') {
  2223. if (selectList.length > 20) {
  2224. return message.error('提示:单次最多可勾选 20 个文件!');
  2225. }
  2226. try {
  2227. let authorization = `${base.getStorage('token').token_type} ${base.getStorage('token').access_token}`;
  2228. let xShareToken = base.getStorage('shareToken').share_token;
  2229.  
  2230. for (let i = 0; i < selectList.length; i++) {
  2231. let res = await base.post(pan.pcs[0], {
  2232. expire_sec: 600,
  2233. file_id: selectList[i].fileId,
  2234. share_id: selectList[i].shareId
  2235. }, {
  2236. authorization,
  2237. "content-type": "application/json;charset=utf-8",
  2238. "x-share-token": xShareToken
  2239. });
  2240. if (res.download_url) {
  2241. selectList[i].downloadUrl = res.download_url;
  2242. }
  2243. }
  2244. } catch (e) {
  2245. return message.error('提示:请先登录网盘!');
  2246. }
  2247. }
  2248. let html = this.generateDom(selectList);
  2249. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  2250. },
  2251.  
  2252. generateDom(list) {
  2253. let content = '<div class="pl-main">';
  2254. let alinkAllText = '';
  2255. list.forEach((v, i) => {
  2256. if (v.type === 'folder') return;
  2257. let filename = v.name;
  2258. let fid = v.fileId;
  2259. let did = v.driveId;
  2260. let size = base.sizeFormat(v.size);
  2261. let dlink = v.downloadUrl || v.url;
  2262. if (mode === 'api') {
  2263. content += `<div class="pl-item">
  2264. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2265. <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>
  2266. <div class="pl-item-btn listener-link-api-btn" data-filename="${filename}">复制文件名</div>
  2267. </div>`;
  2268. }
  2269. if (mode === 'aria') {
  2270. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  2271. alinkAllText += alink + '\r\n';
  2272. content += `<div class="pl-item">
  2273. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2274. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2275. }
  2276. if (mode === 'rpc') {
  2277. content += `<div class="pl-item">
  2278. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2279. <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>`;
  2280. }
  2281. if (mode === 'curl') {
  2282. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  2283. alinkAllText += alink + '\r\n';
  2284. content += `<div class="pl-item">
  2285. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2286. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2287. }
  2288. if (mode === 'bc') {
  2289. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  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" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2293. }
  2294. });
  2295. content += '</div>';
  2296. if (mode === 'aria')
  2297. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  2298. if (mode === 'rpc') {
  2299. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  2300. 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>`;
  2301. }
  2302. if (mode === 'curl')
  2303. 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>`;
  2304. return content;
  2305. },
  2306.  
  2307. async sendLinkToRPC(filename, link) {
  2308. let rpc = {
  2309. domain: base.getValue('setting_rpc_domain'),
  2310. port: base.getValue('setting_rpc_port'),
  2311. path: base.getValue('setting_rpc_path'),
  2312. token: base.getValue('setting_rpc_token'),
  2313. dir: base.getValue('setting_rpc_dir'),
  2314. };
  2315.  
  2316. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  2317. let rpcData = {
  2318. id: new Date().getTime(),
  2319. jsonrpc: '2.0',
  2320. method: 'aria2.addUri',
  2321. params: [`token:${rpc.token}`, [link], {
  2322. dir: rpc.dir,
  2323. out: filename,
  2324. header: [`Referer: https://www.aliyundrive.com/`]
  2325. }]
  2326. };
  2327. try {
  2328. let res = await base.post(url, rpcData, {"Referer": "https://www.aliyundrive.com/"}, '');
  2329. if (res.result) return 'success';
  2330. return 'fail';
  2331. } catch (e) {
  2332. return 'fail';
  2333. }
  2334. },
  2335.  
  2336. getSelectedList() {
  2337. try {
  2338. let selectedList = [];
  2339. let reactDom = document.querySelector(pan.dom.list);
  2340. let reactObj = base.findReact(reactDom, 1);
  2341. let props = reactObj.pendingProps;
  2342. if (props) {
  2343. let fileList = props.dataSource || [];
  2344. let selectedKeys = props.selectedKeys.split(',');
  2345. fileList.forEach((val) => {
  2346. if (selectedKeys.includes(val.fileId)) {
  2347. selectedList.push(val);
  2348. }
  2349. });
  2350. }
  2351. return selectedList;
  2352. } catch (e) {
  2353. return [];
  2354. }
  2355. },
  2356.  
  2357. detectPage() {
  2358. let path = location.pathname;
  2359. if (/^\/(drive)/.test(path)) return 'home';
  2360. if (/^\/(s|share)\//.test(path)) return 'share';
  2361. return '';
  2362. },
  2363.  
  2364. isOnlyFolder() {
  2365. for (let i = 0; i < selectList.length; i++) {
  2366. if (selectList[i].type === 'file') return false;
  2367. }
  2368. return true;
  2369. },
  2370.  
  2371. showMainDialog(title, html, footer) {
  2372. Swal.fire({
  2373. title,
  2374. html,
  2375. footer,
  2376. allowOutsideClick: false,
  2377. showCloseButton: true,
  2378. position: 'top',
  2379. width,
  2380. padding: '15px 20px 5px',
  2381. customClass,
  2382. confirmButtonText: '关闭',
  2383. });
  2384. },
  2385.  
  2386. async initPanLinker() {
  2387. base.initDefaultConfig();
  2388. pt = this.detectPage();
  2389. if (base.getValue('setting_getuser_info') === 'yes') {
  2390. let res = await base.post
  2391. (`https://api.youxiaohou.com/config/ali?ver=${version}&a=${author}`, {}, {}, 'text');
  2392. pan = JSON.parse(base.decode(res));
  2393. };
  2394. Object.freeze && Object.freeze(pan);
  2395. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  2396. base.createTip();
  2397. base.registerMenuCommand();
  2398. }
  2399. };
  2400.  
  2401. //天翼云
  2402. let tianyi = {
  2403.  
  2404. convertLinkToAria(link, filename, ua) {
  2405. filename = base.fixFilename(filename);
  2406. return encodeURIComponent(`aria2c "${link}" --out "${filename}"`);
  2407. },
  2408.  
  2409. convertLinkToBC(link, filename, ua) {
  2410. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}ZZ`;
  2411. return encodeURIComponent(`bc://http/${base.encode(bc)}`);
  2412. },
  2413.  
  2414. convertLinkToCurl(link, filename, ua) {
  2415. let terminal = base.getValue('setting_terminal_type');
  2416. filename = base.fixFilename(filename);
  2417. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}"`);
  2418. },
  2419.  
  2420. addPageListener() {
  2421. doc.on('click', '.pl-button-mode', (e) => {
  2422. mode = e.target.dataset.mode;
  2423. Swal.showLoading();
  2424. this.getPCSLink();
  2425. });
  2426. doc.on('click', '.listener-link-api', async (e) => {
  2427. e.preventDefault();
  2428. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  2429. });
  2430. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  2431. e.preventDefault();
  2432. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  2433. $(e.target).text('复制成功!').animate({opacity: '0.5'}, "slow");
  2434. setTimeout(
  2435. function (){
  2436. $(e.target).text('重新复制').animate({opacity: '1'}, "slow");
  2437. },2000
  2438. )
  2439. });
  2440. doc.on('click', '.listener-link-rpc', async (e) => {
  2441. let target = $(e.currentTarget);
  2442. target.find('.icon').remove();
  2443. target.find('.pl-loading').remove();
  2444. target.prepend(base.createLoading());
  2445. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  2446. if (res === 'success') {
  2447. $('.listener-rpc-task').show();
  2448. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  2449. } else {
  2450. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  2451. }
  2452. });
  2453. doc.on('click', '.listener-send-rpc', (e) => {
  2454. $('.listener-link-rpc').click();
  2455. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  2456. });
  2457. doc.on('click', '.listener-open-setting', () => {
  2458. base.showSetting();
  2459. });
  2460. doc.on('click', '.listener-open-updatelog', () => {
  2461. base.showUpdateLog();
  2462. });
  2463. doc.on('click', '.listener-rpc-task', () => {
  2464. let rpc = JSON.stringify({
  2465. domain: base.getValue('setting_rpc_domain'),
  2466. port: base.getValue('setting_rpc_port'),
  2467. }), url = `${pan.d}/?rpc=${base.encode(rpc)}#${base.getValue('setting_rpc_token')}`;
  2468. GM_openInTab(url, {active: true});
  2469. });
  2470. },
  2471.  
  2472. addButton() {
  2473. if(document.getElementById("pl-button-link")){
  2474. document.getElementById("pl-button-link").remove()
  2475. }
  2476. if (!pt) return;
  2477. let $toolWrap;
  2478. let $button = $(`<div class="tianyi-button pl-button" id="pl-button-link">下载助手<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><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li></ul></div>`);
  2479. if (pt === 'home') {
  2480. //let ins = setInterval(() => {
  2481. $toolWrap = $(pan.btn.home);
  2482. if ($toolWrap.length > 0) {
  2483. $toolWrap.prepend($button);
  2484. //clearInterval(ins);
  2485. }
  2486. //}, 50);
  2487. }
  2488. if (pt === 'share') {
  2489. //let ins = setInterval(() => {
  2490. $toolWrap = $(pan.btn.share);
  2491. if ($toolWrap.length > 0) {
  2492. $toolWrap.prepend($button);
  2493. //clearInterval(ins);
  2494. }
  2495. //}, 50);
  2496. }
  2497. base.createDownloadIframe();
  2498. this.addPageListener();
  2499. setInterval(function(){
  2500. if(!document.getElementById("pl-button-link")){
  2501. tianyi.addButton();
  2502. }
  2503. },1000)
  2504. },
  2505.  
  2506. addInitButton() {
  2507. if(document.getElementById("pl-button-link")){
  2508. document.getElementById("pl-button-link").remove()
  2509. }
  2510. if (!pt) return;
  2511. let $toolWrap;
  2512. let $button = $(`<div class="tianyi-button pl-button-init" id="pl-button-link">下载助手(未点亮)</div>`);
  2513. if (pt === 'home') {
  2514. //let ins = setInterval(() => {
  2515. $toolWrap = $(pan.btn.home);
  2516. if ($toolWrap.length > 0) {
  2517. $toolWrap.append($button);
  2518. //clearInterval(ins);
  2519. }
  2520. //}, 50);
  2521. }
  2522. if (pt === 'share') {
  2523. $button.css({'margin-right': '10px'});
  2524. //let ins = setInterval(() => {
  2525. $toolWrap = $(pan.btn.share);
  2526. if ($toolWrap.length > 0) {
  2527. $toolWrap.prepend($button);
  2528. //clearInterval(ins);
  2529. }
  2530. //}, 50);
  2531. }
  2532. $button.click(() => base.initDialog());
  2533. setInterval(function(){
  2534. if(!document.getElementById("pl-button-link")){
  2535. tianyi.addInitButton();
  2536. }
  2537. },1000)
  2538. },
  2539.  
  2540. async getToken() {
  2541. let res = await base.getFinalUrl(pan.pcs[1], {});
  2542. let accessToken = res.match(/accessToken=(\w+)/)?.[1];
  2543. accessToken && base.setStorage('accessToken', accessToken);
  2544. return accessToken;
  2545. },
  2546.  
  2547. async getFileUrlByOnce(item, index, token) {
  2548. try {
  2549. if (item.downloadUrl) return {
  2550. index,
  2551. downloadUrl: item.downloadUrl
  2552. };
  2553. let time = Date.now(),
  2554. fileId = item.fileId,
  2555. o = "AccessToken=" + token + "&Timestamp=" + time + "&fileId=" + fileId,
  2556. url = pan.pcs[2] + '?fileId=' + fileId;
  2557. if (item.shareId) {
  2558. o = "AccessToken=" + token + "&Timestamp=" + time + "&dt=1&fileId=" + fileId + "&shareId=" + item.shareId;
  2559. url += '&dt=1&shareId=' + item.shareId;
  2560. }
  2561. let sign = md5(o).toString();
  2562. let res = await base.get(url, {
  2563. "accept": "application/json;charset=UTF-8",
  2564. "sign-type": 1,
  2565. "accesstoken": token,
  2566. "timestamp": time,
  2567. "signature": sign
  2568. });
  2569. if (res.res_code === 0) {
  2570. return {
  2571. index,
  2572. downloadUrl: res.fileDownloadUrl
  2573. };
  2574. } else if (res.errorCode === 'InvalidSessionKey') {
  2575. return {
  2576. index,
  2577. downloadUrl: '提示:请先登录网盘!'
  2578. };
  2579. } else if (res.res_code === 'ShareNotFoundFlatDir') {
  2580. return {
  2581. index,
  2582. downloadUrl: '提示:请先[转存]文件,👉前往[我的网盘]中下载!'
  2583. };
  2584. } else {
  2585. return {
  2586. index,
  2587. downloadUrl: '获取下载地址失败,请刷新重试!'
  2588. };
  2589. }
  2590. } catch (e) {
  2591. return {
  2592. index,
  2593. downloadUrl: '获取下载地址失败,请刷新重试!'
  2594. };
  2595. }
  2596. },
  2597.  
  2598. async getPCSLink() {
  2599. selectList = this.getSelectedList();
  2600. if (selectList.length === 0) {
  2601. return message.error('提示:请先勾选要下载的文件!');
  2602. }
  2603. if (this.isOnlyFolder()) {
  2604. return message.error('提示:请打开文件夹后勾选文件!');
  2605. }
  2606. let token = base.getStorage('accessToken') || await this.getToken();
  2607. if (!token) {
  2608. return message.error('提示:请先登录网盘!');
  2609. }
  2610. let queue = [];
  2611. selectList.forEach((item, index) => {
  2612. queue.push(this.getFileUrlByOnce(item, index, token));
  2613. });
  2614.  
  2615. const res = await Promise.all(queue);
  2616. res.forEach(val => {
  2617. selectList[val.index].downloadUrl = val.downloadUrl;
  2618. });
  2619.  
  2620. let html = this.generateDom(selectList);
  2621. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  2622. },
  2623.  
  2624. generateDom(list) {
  2625. let content = '<div class="pl-main">';
  2626. let alinkAllText = '';
  2627. list.forEach((v, i) => {
  2628. if (v.isFolder) return;
  2629. let filename = v.fileName;
  2630. let size = base.sizeFormat(v.size);
  2631. let dlink = v.downloadUrl;
  2632. if (mode === 'api') {
  2633. content += `<div class="pl-item">
  2634. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2635. <a class="pl-item-link listener-link-api" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  2636. </div>`;
  2637. }
  2638. if (mode === 'aria') {
  2639. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  2640. alinkAllText += alink + '\r\n';
  2641. content += `<div class="pl-item">
  2642. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2643. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2644. }
  2645. if (mode === 'rpc') {
  2646. content += `<div class="pl-item">
  2647. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2648. <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>`;
  2649. }
  2650. if (mode === 'curl') {
  2651. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  2652. alinkAllText += alink + '\r\n';
  2653. content += `<div class="pl-item">
  2654. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2655. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2656. }
  2657. if (mode === 'bc') {
  2658. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  2659. content += `<div class="pl-item">
  2660. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2661. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  2662. }
  2663. });
  2664. content += '</div>';
  2665. if (mode === 'aria')
  2666. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  2667. if (mode === 'rpc') {
  2668. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  2669. 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>`;
  2670. }
  2671. if (mode === 'curl')
  2672. 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>`;
  2673. return content;
  2674. },
  2675.  
  2676. async sendLinkToRPC(filename, link) {
  2677. let rpc = {
  2678. domain: base.getValue('setting_rpc_domain'),
  2679. port: base.getValue('setting_rpc_port'),
  2680. path: base.getValue('setting_rpc_path'),
  2681. token: base.getValue('setting_rpc_token'),
  2682. dir: base.getValue('setting_rpc_dir'),
  2683. };
  2684.  
  2685. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  2686. let rpcData = {
  2687. id: new Date().getTime(),
  2688. jsonrpc: '2.0',
  2689. method: 'aria2.addUri',
  2690. params: [`token:${rpc.token}`, [link], {
  2691. dir: rpc.dir,
  2692. out: filename,
  2693. header: []
  2694. }]
  2695. };
  2696. try {
  2697. let res = await base.post(url, rpcData, {}, '');
  2698. if (res.result) return 'success';
  2699. return 'fail';
  2700. } catch (e) {
  2701. return 'fail';
  2702. }
  2703. },
  2704.  
  2705. getSelectedList() {
  2706. try {
  2707. return document.querySelector(".c-file-list").__vue__.selectedList;
  2708. } catch (e) {
  2709. return [document.querySelector(".info-detail").__vue__.fileDetail];
  2710. }
  2711. },
  2712.  
  2713. detectPage() {
  2714. let path = location.pathname;
  2715. if (/^\/web\/main/.test(path)) return 'home';
  2716. if (/^\/web\/share/.test(path)) return 'share';
  2717. return '';
  2718. },
  2719.  
  2720. isOnlyFolder() {
  2721. for (let i = 0; i < selectList.length; i++) {
  2722. if (!selectList[i].isFolder) return false;
  2723. }
  2724. return true;
  2725. },
  2726.  
  2727. showMainDialog(title, html, footer) {
  2728. Swal.fire({
  2729. title,
  2730. html,
  2731. footer,
  2732. allowOutsideClick: false,
  2733. showCloseButton: true,
  2734. position: 'top',
  2735. width,
  2736. padding: '15px 20px 5px',
  2737. customClass,
  2738. confirmButtonText: '关闭',
  2739. });
  2740. },
  2741.  
  2742. async initPanLinker() {
  2743. base.initDefaultConfig();
  2744. pt = this.detectPage();
  2745. if (base.getValue('setting_getuser_info') === 'yes') {
  2746. let res = await base.post
  2747. (`https://api.youxiaohou.com/config/tianyi?ver=${version}&a=${author}`, {}, {}, 'text');
  2748. pan = JSON.parse(base.decode(res));
  2749. };
  2750. Object.freeze && Object.freeze(pan);
  2751. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  2752. this.getToken();
  2753. base.createTip();
  2754. base.registerMenuCommand();
  2755. }
  2756. };
  2757.  
  2758. //迅雷云盘
  2759. let xunlei = {
  2760.  
  2761. convertLinkToAria(link, filename, ua) {
  2762. filename = base.fixFilename(filename);
  2763. return encodeURIComponent(`aria2c "${link}" --out "${filename}"`);
  2764. },
  2765.  
  2766. convertLinkToBC(link, filename, ua) {
  2767. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}ZZ`;
  2768. return encodeURIComponent(`bc://http/${base.encode(bc)}`);
  2769. },
  2770.  
  2771. convertLinkToCurl(link, filename, ua) {
  2772. let terminal = base.getValue('setting_terminal_type');
  2773. filename = base.fixFilename(filename);
  2774. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}"`);
  2775. },
  2776.  
  2777. addPageListener() {
  2778. doc.on('click', '.pl-button-mode', (e) => {
  2779. mode = e.target.dataset.mode;
  2780. Swal.showLoading();
  2781. this.getPCSLink();
  2782. });
  2783. doc.on('click', '.listener-link-api', async (e) => {
  2784. e.preventDefault();
  2785. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  2786. });
  2787. doc.on('click', '.listener-link-api-btn', async (e) => {
  2788. base.setClipboard(e.target.dataset.filename);
  2789. $(e.target).text('复制成功').animate({opacity: '0.5'}, "slow");
  2790. setTimeout(
  2791. function (){
  2792. $(e.target).text('重新复制').animate({opacity: '1'}, "slow");
  2793. },2000
  2794. )
  2795. });
  2796. doc.on('click', '.listener-link-bc-btn', async (e) => {
  2797. let mirror = base.getMirrorList(e.target.dataset.dlink, pan.mirror);
  2798. base.setClipboard(mirror);
  2799. $(e.target).text('复制成功').animate({opacity: '0.5'}, "slow");
  2800. setTimeout(
  2801. function (){
  2802. $(e.target).text('重新复制').animate({opacity: '1'}, "slow");
  2803. },2000
  2804. )
  2805. });
  2806. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  2807. e.preventDefault();
  2808. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  2809. $(e.target).text('复制成功!').animate({opacity: '0.5'}, "slow");
  2810. setTimeout(
  2811. function (){
  2812. $(e.target).text('重新复制').animate({opacity: '1'}, "slow");
  2813. },2000
  2814. )
  2815. });
  2816. doc.on('click', '.listener-link-rpc', async (e) => {
  2817. let target = $(e.currentTarget);
  2818. target.find('.icon').remove();
  2819. target.find('.pl-loading').remove();
  2820. target.prepend(base.createLoading());
  2821. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  2822. if (res === 'success') {
  2823. $('.listener-rpc-task').show();
  2824. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  2825. } else {
  2826. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  2827. }
  2828. });
  2829. doc.on('click', '.listener-send-rpc', (e) => {
  2830. $('.listener-link-rpc').click();
  2831. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  2832. });
  2833. doc.on('click', '.listener-open-setting', () => {
  2834. base.showSetting();
  2835. });
  2836. doc.on('click', '.listener-open-updatelog', () => {
  2837. base.showUpdateLog();
  2838. });
  2839. doc.on('click', '.listener-rpc-task', () => {
  2840. let rpc = JSON.stringify({
  2841. domain: base.getValue('setting_rpc_domain'),
  2842. port: base.getValue('setting_rpc_port'),
  2843. }), url = `${pan.d}/?rpc=${base.encode(rpc)}#${base.getValue('setting_rpc_token')}`;
  2844. GM_openInTab(url, {active: true});
  2845. });
  2846. },
  2847.  
  2848. addButton() {
  2849. if(document.getElementById("pl-button-link")){
  2850. document.getElementById("pl-button-link").remove()
  2851. }
  2852. if (!pt) return;
  2853. let $toolWrap;
  2854. let $button = $(`<div class="xunlei-button pl-button" id="pl-button-link"><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><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li></ul></div>`);
  2855. if (pt === 'home') {
  2856. //let ins = setInterval(() => {
  2857. $toolWrap = $(pan.btn.home);
  2858. if ($toolWrap.length > 0) {
  2859. $toolWrap.prepend($button);
  2860. //clearInterval(ins);
  2861. }
  2862. //}, 50);
  2863. }
  2864. if (pt === 'share') {
  2865. $button.css({'margin-right': '10px'});
  2866. //let ins = setInterval(() => {
  2867. $toolWrap = $(pan.btn.share);
  2868. if ($toolWrap.length > 0) {
  2869. $toolWrap.prepend($button);
  2870. //clearInterval(ins);
  2871. }
  2872. //}, 50);
  2873. }
  2874. base.createDownloadIframe();
  2875. this.addPageListener();
  2876. setInterval(function(){
  2877. if(!document.getElementById("pl-button-link")){
  2878. xunlei.addButton();
  2879. }
  2880. },1000)
  2881. },
  2882.  
  2883. addInitButton() {
  2884. if(document.getElementById("pl-button-link")){
  2885. document.getElementById("pl-button-link").remove()
  2886. }
  2887. if (!pt) return;
  2888. let $toolWrap;
  2889. let $button = $(`<div class="xunlei-button pl-button-init" id="pl-button-link"><i class="xlpfont xlp-download"></i><span style="font-size: 13px;margin-left: 6px;">下载助手(未点亮)</span></div>`);
  2890. if (pt === 'home') {
  2891. //let ins = setInterval(() => {
  2892. $toolWrap = $(pan.btn.home);
  2893. if ($toolWrap.length > 0) {
  2894. $toolWrap.append($button);
  2895. //clearInterval(ins);
  2896. }
  2897. //}, 50);
  2898. }
  2899. if (pt === 'share') {
  2900. $button.css({'margin-right': '10px'});
  2901. //let ins = setInterval(() => {
  2902. $toolWrap = $(pan.btn.share);
  2903. if ($toolWrap.length > 0) {
  2904. $toolWrap.prepend($button);
  2905. //clearInterval(ins);
  2906. }
  2907. //}, 50);
  2908. }
  2909. $button.click(() => base.initDialog());
  2910. setInterval(function(){
  2911. if(!document.getElementById("pl-button-link")){
  2912. xunlei.addInitButton();
  2913. }
  2914. },1000)
  2915. },
  2916.  
  2917. getToken() {
  2918. let credentials = {}, captcha = {};
  2919. for (let i = 0; i < localStorage.length; i++) {
  2920. if (/^credentials_/.test(localStorage.key(i))) {
  2921. credentials = base.getStorage(localStorage.key(i));
  2922. base.setStorage('');
  2923. }
  2924. if (/^captcha_[\w]{16}/.test(localStorage.key(i))) {
  2925. captcha = base.getStorage(localStorage.key(i));
  2926. }
  2927. }
  2928. let deviceid = /(\w{32})/.exec(base.getStorage('deviceid').split(','))[0];
  2929. let token = {
  2930. credentials,
  2931. captcha,
  2932. deviceid
  2933. };
  2934. return token;
  2935. },
  2936.  
  2937. async getFileUrlByOnce(item, index, token) {
  2938. try {
  2939. if (item.downloadUrl) return {
  2940. index,
  2941. downloadUrl: item.downloadUrl
  2942. };
  2943. let res = await base.get(pan.pcs[0] + item.id, {
  2944. 'Authorization': `${token.credentials.token_type} ${token.credentials.access_token}`,
  2945. 'content-type': "application/json",
  2946. 'x-captcha-token': token.captcha.token,
  2947. 'x-device-id': token.deviceid,
  2948. });
  2949. if (res.web_content_link) {
  2950. return {
  2951. index,
  2952. downloadUrl: res.web_content_link
  2953. };
  2954. } else {
  2955. return {
  2956. index,
  2957. downloadUrl: '获取下载地址失败,请刷新重试!'
  2958. };
  2959. }
  2960. } catch (e) {
  2961. return message.error('提示:请先登录网盘后刷新页面!');
  2962. }
  2963. },
  2964.  
  2965. async getPCSLink() {
  2966. selectList = this.getSelectedList();
  2967. if (selectList.length === 0) {
  2968. return message.error('提示:请先勾选要下载的文件!');
  2969. }
  2970. if (this.isOnlyFolder()) {
  2971. return message.error('提示:请打开文件夹后勾选文件!');
  2972. }
  2973. if (pt === 'home') {
  2974. let queue = [];
  2975. let token = this.getToken();
  2976. selectList.forEach((item, index) => {
  2977. queue.push(this.getFileUrlByOnce(item, index, token));
  2978. });
  2979. const res = await Promise.all(queue);
  2980. res.forEach(val => {
  2981. selectList[val.index].downloadUrl = val.downloadUrl;
  2982. });
  2983. } else {
  2984. return message.error('提示:请保存到自己网盘后去网盘主页下载!');
  2985. }
  2986. let html = this.generateDom(selectList);
  2987. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  2988.  
  2989. },
  2990.  
  2991. generateDom(list) {
  2992. let content = '<div class="pl-main">';
  2993. let alinkAllText = '';
  2994. list.forEach((v, i) => {
  2995. if (v.kind === 'drive#folder') return;
  2996. let filename = v.name;
  2997. let size = base.sizeFormat(+v.size);
  2998. let dlink = v.downloadUrl;
  2999. if (mode === 'api') {
  3000. content += `<div class="pl-item">
  3001. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3002. <a class="pl-item-link listener-link-api" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  3003. <div class="pl-item-btn listener-link-api-btn" data-filename="${filename}">复制文件名</div>
  3004. </div>`;
  3005. }
  3006. if (mode === 'aria') {
  3007. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  3008. alinkAllText += alink + '\r\n';
  3009. content += `<div class="pl-item">
  3010. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3011. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3012. }
  3013. if (mode === 'rpc') {
  3014. content += `<div class="pl-item">
  3015. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3016. <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>`;
  3017. }
  3018. if (mode === 'curl') {
  3019. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  3020. alinkAllText += alink + '\r\n';
  3021. content += `<div class="pl-item">
  3022. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3023. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3024. }
  3025. if (mode === 'bc') {
  3026. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  3027. content += `<div class="pl-item">
  3028. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3029. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a>
  3030. <div class="pl-item-btn listener-link-bc-btn" data-dlink="${dlink}">复制镜像地址</div>
  3031. </div>`;
  3032. }
  3033. });
  3034. content += '</div>';
  3035. if (mode === 'aria')
  3036. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  3037. if (mode === 'rpc') {
  3038. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  3039. 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>`;
  3040. }
  3041. if (mode === 'curl')
  3042. 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>`;
  3043. return content;
  3044. },
  3045.  
  3046. async sendLinkToRPC(filename, link) {
  3047. let rpc = {
  3048. domain: base.getValue('setting_rpc_domain'),
  3049. port: base.getValue('setting_rpc_port'),
  3050. path: base.getValue('setting_rpc_path'),
  3051. token: base.getValue('setting_rpc_token'),
  3052. dir: base.getValue('setting_rpc_dir'),
  3053. };
  3054.  
  3055. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  3056. let rpcData = {
  3057. id: new Date().getTime(),
  3058. jsonrpc: '2.0',
  3059. method: 'aria2.addUri',
  3060. params: [`token:${rpc.token}`, [link], {
  3061. dir: rpc.dir,
  3062. out: filename,
  3063. header: []
  3064. }]
  3065. };
  3066. try {
  3067. let res = await base.post(url, rpcData, {}, '');
  3068. if (res.result) return 'success';
  3069. return 'fail';
  3070. } catch (e) {
  3071. return 'fail';
  3072. }
  3073. },
  3074.  
  3075. getSelectedList() {
  3076. try {
  3077. let doms = document.querySelectorAll('.pan-list-item');
  3078. let selectedList = [];
  3079. for (let dom of doms) {
  3080. let domVue = dom.__vue__;
  3081. if (domVue.selected.includes(domVue.info.id)) {
  3082. selectedList.push(domVue.info);
  3083. }
  3084. }
  3085. return selectedList;
  3086. } catch (e) {
  3087. return [];
  3088. }
  3089. },
  3090.  
  3091. detectPage() {
  3092. let path = location.pathname;
  3093. if (/^\/$/.test(path)) return 'home';
  3094. if (/^\/(s|share)\//.test(path)) return 'share';
  3095. return '';
  3096. },
  3097.  
  3098. isOnlyFolder() {
  3099. for (let i = 0; i < selectList.length; i++) {
  3100. if (selectList[i].kind === 'drive#file') return false;
  3101. }
  3102. return true;
  3103. },
  3104.  
  3105. showMainDialog(title, html, footer) {
  3106. Swal.fire({
  3107. title,
  3108. html,
  3109. footer,
  3110. allowOutsideClick: false,
  3111. showCloseButton: true,
  3112. position: 'top',
  3113. width,
  3114. padding: '15px 20px 5px',
  3115. customClass,
  3116. confirmButtonText: '关闭',
  3117. });
  3118. },
  3119.  
  3120. async initPanLinker() {
  3121. base.initDefaultConfig();
  3122. pt = this.detectPage();
  3123. if (base.getValue('setting_getuser_info') === 'yes') {
  3124. let res = await base.post
  3125. (`https://api.youxiaohou.com/config/xunlei?ver=${version}&a=${author}`, {}, {}, 'text');
  3126. pan = JSON.parse(base.decode(res));
  3127. };
  3128. Object.freeze && Object.freeze(pan);
  3129. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  3130. base.createTip();
  3131. base.registerMenuCommand();
  3132. }
  3133. };
  3134.  
  3135. //夸克网盘
  3136. let quark = {
  3137.  
  3138. convertLinkToAria(link, filename, ua) {
  3139. filename = base.fixFilename(filename);
  3140. return encodeURIComponent(`aria2c "${link}" --out "${filename}" --header "Cookie: ${document.cookie}"`);
  3141. },
  3142.  
  3143. convertLinkToBC(link, filename, ua) {
  3144. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}&cookie=${encodeURIComponent(document.cookie)}ZZ`;
  3145. return encodeURIComponent(`bc://http/${base.encode(bc)}`);
  3146. },
  3147.  
  3148. convertLinkToCurl(link, filename, ua) {
  3149. let terminal = base.getValue('setting_terminal_type');
  3150. filename = base.fixFilename(filename);
  3151. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}" -b "${document.cookie}"`);
  3152. },
  3153.  
  3154. addPageListener() {
  3155. window.addEventListener('hashchange', async (e) => {
  3156. let home = 'https://pan.quark.cn/list#/', all = 'https://pan.quark.cn/list#/list/all';
  3157. if (e.oldURL === home && e.newURL === all) return;
  3158. await base.sleep(150);
  3159. if ($('.quark-button').length > 0) return;
  3160. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  3161. });
  3162. doc.on('click', '.pl-button-mode', (e) => {
  3163. mode = e.target.dataset.mode;
  3164. Swal.showLoading();
  3165. this.getPCSLink();
  3166. });
  3167. doc.on('click', '.listener-link-save', async (e) => {
  3168. e.preventDefault();
  3169. selectList = this.getSelectedList();
  3170. if (selectList.length === 0) {
  3171. return message.error('提示:请先勾选要保存到网盘的内容!');
  3172. }
  3173. message.info('提示:因夸克限制,请先保存到自己网盘后再下载哦');
  3174. await base.sleep(500);
  3175. document.querySelector('.file-info_r').click();
  3176. });
  3177. doc.on('click', '.listener-link-api', async (e) => {
  3178. e.preventDefault();
  3179. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  3180. });
  3181. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  3182. e.preventDefault();
  3183. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  3184. $(e.target).text('复制成功!').animate({opacity: '0.5'}, "slow");
  3185. setTimeout(
  3186. function (){
  3187. $(e.target).text('重新复制').animate({opacity: '1'}, "slow");
  3188. },2000
  3189. )
  3190. });
  3191. doc.on('click', '.listener-link-rpc', async (e) => {
  3192. let target = $(e.currentTarget);
  3193. target.find('.icon').remove();
  3194. target.find('.pl-loading').remove();
  3195. target.prepend(base.createLoading());
  3196. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  3197. if (res === 'success') {
  3198. $('.listener-rpc-task').show();
  3199. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  3200. } else {
  3201. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  3202. }
  3203. });
  3204. doc.on('click', '.listener-send-rpc', (e) => {
  3205. $('.listener-link-rpc').click();
  3206. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  3207. });
  3208. doc.on('click', '.listener-open-setting', () => {
  3209. base.showSetting();
  3210. });
  3211. doc.on('click', '.listener-open-updatelog', () => {
  3212. base.showUpdateLog();
  3213. });
  3214. doc.on('click', '.listener-rpc-task', () => {
  3215. let rpc = JSON.stringify({
  3216. domain: base.getValue('setting_rpc_domain'),
  3217. port: base.getValue('setting_rpc_port'),
  3218. }), url = `${pan.d}/?rpc=${base.encode(rpc)}#${base.getValue('setting_rpc_token')}`;
  3219. GM_openInTab(url, {active: true});
  3220. });
  3221. },
  3222.  
  3223. addButton() {
  3224. let svg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiI+PHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNOSAxMmwyIDIgMi0yeiIvPjxwYXRoIGQ9Ik0xNCA4aDEuNTUzYy44NSAwIDEuMTYuMDkzIDEuNDcuMjY3LjMxMS4xNzQuNTU2LjQzLjcyMi43NTYuMTY2LjMyNi4yNTUuNjUuMjU1IDEuNTR2NC44NzNjMCAuODkyLS4wODkgMS4yMTUtLjI1NSAxLjU0LS4xNjYuMzI3LS40MS41ODMtLjcyMi43NTctLjMxLjE3NC0uNjIuMjY3LTEuNDcuMjY3SDYuNDQ3Yy0uODUgMC0xLjE2LS4wOTMtMS40Ny0uMjY3YTEuNzc4IDEuNzc4IDAgMDEtLjcyMi0uNzU2Yy0uMTY2LS4zMjYtLjI1NS0uNjUtLjI1NS0xLjU0di00Ljg3M2MwLS44OTIuMDg5LTEuMjE1LjI1NS0xLjU0LjE2Ni0uMzI3LjQxLS41ODMuNzIyLS43NTcuMzEtLjE3NC42Mi0uMjY3IDEuNDctLjI2N0gxMSIvPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTExIDN2MTAiLz48L2c+PC9zdmc+';
  3225. if(document.getElementById("pl-button-link")){
  3226. document.getElementById("pl-button-link").remove()
  3227. }
  3228. if (!pt) return;
  3229.  
  3230. waitForKeyElements(".share-content-right", function () {
  3231. let ad1 = document.getElementsByClassName("share-content-right")[0];
  3232. ad1.remove();
  3233. });
  3234.  
  3235. let $toolWrap;
  3236. if (pt === 'home') {
  3237. let $button = $(`<div id="pl-button-link" class="ant-dropdown-trigger pl-button"><button type="button" class="quark-button ant-btn btn-file ant-btn-primary"><img class="quark-btn-icon btn-icon" src="`+ svg +`"><span>下载助手</span></button><ul class="pl-dropdown-menu" style="top: 55px;"><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><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li></ul></div>`);
  3238. $button.css({"margin-right":"10px","display":"inline-block"});
  3239. $toolWrap = $(pan.btn.home);
  3240. if ($toolWrap.length > 0) {
  3241. $toolWrap.prepend($button);
  3242. }
  3243. }
  3244. if (pt === 'share') {
  3245. let $button = $(`<div id="pl-button-link" class="ant-dropdown-trigger pl-button"><button type="button" class="quark-button ant-btn btn-file ant-btn-primary" style="height: 40px;"><img class="quark-btn-icon btn-icon" src="`+ svg +`"><span>下载助手</span></button><ul class="pl-dropdown-menu" style="top: 100px;"><li class="pl-dropdown-menu-item pl-button-mode listener-link-save" style="background-color: ${color}b0 !important;color:#fff !important;" data-mode="save"><span class="save-btn-icon"></span>保存后下载</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li></ul></div>`);
  3246. $button.css({"margin-right":"10px","display":"inline-block"});
  3247. $toolWrap = $(pan.btn.share);
  3248. if ($toolWrap.length > 0) {
  3249. $toolWrap.prepend($button);
  3250. }
  3251. }
  3252. setInterval(function(){
  3253. if(!document.getElementById("pl-button-link")){
  3254. quark.addButton();
  3255. }
  3256. },1000)
  3257. },
  3258.  
  3259. addInitButton() {
  3260. let svg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiI+PHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNOSAxMmwyIDIgMi0yeiIvPjxwYXRoIGQ9Ik0xNCA4aDEuNTUzYy44NSAwIDEuMTYuMDkzIDEuNDcuMjY3LjMxMS4xNzQuNTU2LjQzLjcyMi43NTYuMTY2LjMyNi4yNTUuNjUuMjU1IDEuNTR2NC44NzNjMCAuODkyLS4wODkgMS4yMTUtLjI1NSAxLjU0LS4xNjYuMzI3LS40MS41ODMtLjcyMi43NTctLjMxLjE3NC0uNjIuMjY3LTEuNDcuMjY3SDYuNDQ3Yy0uODUgMC0xLjE2LS4wOTMtMS40Ny0uMjY3YTEuNzc4IDEuNzc4IDAgMDEtLjcyMi0uNzU2Yy0uMTY2LS4zMjYtLjI1NS0uNjUtLjI1NS0xLjU0di00Ljg3M2MwLS44OTIuMDg5LTEuMjE1LjI1NS0xLjU0LjE2Ni0uMzI3LjQxLS41ODMuNzIyLS43NTcuMzEtLjE3NC42Mi0uMjY3IDEuNDctLjI2N0gxMSIvPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTExIDN2MTAiLz48L2c+PC9zdmc+';
  3261. if(document.getElementById("pl-button-link")){
  3262. document.getElementById("pl-button-link").remove()
  3263. }
  3264. if (!pt) return;
  3265. let $toolWrap;
  3266. let $button = $(`<div id="pl-button-link" class="ant-dropdown-trigger pl-button-init"><button type="button" class="quark-button ant-btn btn-file ant-btn-primary" style="height: 40px;"><img class="quark-btn-icon btn-icon" src="`+ svg +`"><span>下载助手(未点亮)</span></button></div>`);
  3267. $button.css({"margin-right":"10px","display":"inline-block"});
  3268. if (pt === 'home') {
  3269. //let ins = setInterval(() => {
  3270. $toolWrap = $(pan.btn.home);
  3271. if ($toolWrap.length > 0) {
  3272. $toolWrap.prepend($button);
  3273. //clearInterval(ins);
  3274. }
  3275. //}, 50);
  3276. }
  3277. if (pt === 'share') {
  3278. //let ins = setInterval(() => {
  3279. $toolWrap = $(pan.btn.share);
  3280. if ($toolWrap.length > 0) {
  3281. $toolWrap.prepend($button);
  3282. //clearInterval(ins);
  3283. }
  3284. //}, 50);
  3285. }
  3286. $button.click(() => base.initDialog());
  3287. setInterval(function(){
  3288. if(!document.getElementById("pl-button-link")){
  3289. quark.addInitButton();
  3290. }
  3291. },1000)
  3292. },
  3293.  
  3294. async getPCSLink() {
  3295. selectList = this.getSelectedList();
  3296. if (selectList.length === 0) {
  3297. return message.error('提示:请先勾选要下载的文件!');
  3298. }
  3299. if (this.isOnlyFolder()) {
  3300. return message.error('提示:请打开文件夹后勾选文件!');
  3301. }
  3302. let fids = [];
  3303. selectList.forEach(val => {
  3304. fids.push(val.fid);
  3305. });
  3306. if (pt === 'home') {
  3307. let res = await base.post(pan.pcs[0], {
  3308. "fids": fids
  3309. }, {"content-type": "application/json;charset=utf-8", "user-agent": pan.ua});
  3310. if (res.code === 31001) {
  3311. return message.error('提示:请先登录网盘!');
  3312. }
  3313. if (res.code !== 0) {
  3314. return message.error('提示:获取链接失败!');
  3315. }
  3316. let html = this.generateDom(res.data);
  3317. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  3318. } else {
  3319. message.error('提示:请保存到自己网盘后去网盘主页下载!');
  3320. await base.sleep(1000);
  3321. document.querySelector('.file-info_r').click();
  3322. return;
  3323. }
  3324. },
  3325.  
  3326. generateDom(list) {
  3327. let content = '<div class="pl-main">';
  3328. let alinkAllText = '';
  3329. list.forEach((v, i) => {
  3330. if (v.file === false) return;
  3331. let filename = v.file_name;
  3332. let fid = v.fid;
  3333. let size = base.sizeFormat(v.size);
  3334. let dlink = v.download_url;
  3335. if (mode === 'api') {
  3336. content += `<div class="pl-item">
  3337. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3338. <a class="pl-item-link listener-link-api" data-fid="${fid}" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  3339. </div>`;
  3340. }
  3341. if (mode === 'aria') {
  3342. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  3343. alinkAllText += alink + '\r\n';
  3344. content += `<div class="pl-item">
  3345. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3346. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3347. }
  3348. if (mode === 'rpc') {
  3349. content += `<div class="pl-item">
  3350. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3351. <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>`;
  3352. }
  3353. if (mode === 'curl') {
  3354. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  3355. alinkAllText += alink + '\r\n';
  3356. content += `<div class="pl-item">
  3357. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3358. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3359. }
  3360. if (mode === 'bc') {
  3361. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  3362. content += `<div class="pl-item">
  3363. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3364. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3365. }
  3366. });
  3367. content += '</div>';
  3368. if (mode === 'aria')
  3369. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  3370. if (mode === 'rpc') {
  3371. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  3372. 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>`;
  3373. }
  3374. if (mode === 'curl')
  3375. 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>`;
  3376. return content;
  3377. },
  3378.  
  3379. async sendLinkToRPC(filename, link) {
  3380. let rpc = {
  3381. domain: base.getValue('setting_rpc_domain'),
  3382. port: base.getValue('setting_rpc_port'),
  3383. path: base.getValue('setting_rpc_path'),
  3384. token: base.getValue('setting_rpc_token'),
  3385. dir: base.getValue('setting_rpc_dir'),
  3386. };
  3387.  
  3388. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  3389. let rpcData = {
  3390. id: new Date().getTime(),
  3391. jsonrpc: '2.0',
  3392. method: 'aria2.addUri',
  3393. params: [`token:${rpc.token}`, [link], {
  3394. dir: rpc.dir,
  3395. out: filename,
  3396. header: [`Cookie: ${document.cookie}`]
  3397. }]
  3398. };
  3399. try {
  3400. let res = await base.post(url, rpcData, {"Cookie": document.cookie}, '');
  3401. if (res.result) return 'success';
  3402. return 'fail';
  3403. } catch (e) {
  3404. return 'fail';
  3405. }
  3406. },
  3407.  
  3408. getSelectedList() {
  3409. try {
  3410. let selectedList = [];
  3411. let reactDom = document.getElementsByClassName('file-list')[0];
  3412. let reactObj = base.findReact(reactDom);
  3413. let props = reactObj.props;
  3414. if (props) {
  3415. let fileList = props.list || [];
  3416. let selectedKeys = props.selectedRowKeys || [];
  3417. fileList.forEach((val) => {
  3418. if (selectedKeys.includes(val.fid)) {
  3419. selectedList.push(val);
  3420. }
  3421. });
  3422. }
  3423. return selectedList;
  3424. } catch (e) {
  3425. return [];
  3426. }
  3427. },
  3428.  
  3429. detectPage() {
  3430. let path = location.pathname;
  3431. if (/^\/(list)/.test(path)) return 'home';
  3432. if (/^\/(s|share)\//.test(path)) return 'share';
  3433. return '';
  3434. },
  3435.  
  3436. isOnlyFolder() {
  3437. for (let i = 0; i < selectList.length; i++) {
  3438. if (selectList[i].file) return false;
  3439. }
  3440. return true;
  3441. },
  3442.  
  3443. showMainDialog(title, html, footer) {
  3444. Swal.fire({
  3445. title,
  3446. html,
  3447. footer,
  3448. allowOutsideClick: false,
  3449. showCloseButton: true,
  3450. position: 'top',
  3451. width,
  3452. padding: '15px 20px 5px',
  3453. customClass,
  3454. confirmButtonText: '关闭',
  3455. });
  3456. },
  3457.  
  3458. async initPanLinker() {
  3459. base.initDefaultConfig();
  3460. pt = this.detectPage();
  3461. if (base.getValue('setting_getuser_info') === 'yes') {
  3462. let res = await base.post
  3463. (`https://api.youxiaohou.com/config/quark?ver=${version}&a=${author}`, {}, {}, 'text');
  3464. pan = JSON.parse(base.decode(res));
  3465. };
  3466. Object.freeze && Object.freeze(pan);
  3467. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  3468. this.addPageListener();
  3469. base.createTip();
  3470. base.createDownloadIframe();
  3471. base.registerMenuCommand();
  3472. }
  3473. };
  3474.  
  3475. //中国移动云盘/和彩云
  3476. let yidong = {
  3477.  
  3478. convertLinkToAria(link, filename, ua) {
  3479. filename = base.fixFilename(filename);
  3480. return encodeURIComponent(`aria2c "${link}" --out "${filename}"`);
  3481. },
  3482.  
  3483. convertLinkToBC(link, filename, ua) {
  3484. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}ZZ`;
  3485. return encodeURIComponent(`bc://http/${base.encode(bc)}`);
  3486. },
  3487.  
  3488. convertLinkToCurl(link, filename, ua) {
  3489. let terminal = base.getValue('setting_terminal_type');
  3490. filename = base.fixFilename(filename);
  3491. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}"`);
  3492. },
  3493.  
  3494. addPageListener() {
  3495. doc.on('click', '.pl-button-mode', (e) => {
  3496. mode = e.target.dataset.mode;
  3497. Swal.showLoading();
  3498. this.getPCSLink();
  3499. });
  3500. doc.on('click', '.listener-link-api', async (e) => {
  3501. e.preventDefault();
  3502. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  3503. });
  3504. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  3505. e.preventDefault();
  3506. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  3507. $(e.target).text('复制成功!').animate({opacity: '0.5'}, "slow");
  3508. setTimeout(
  3509. function (){
  3510. $(e.target).text('重新复制').animate({opacity: '1'}, "slow");
  3511. },2000
  3512. )
  3513. });
  3514. doc.on('click', '.listener-link-rpc', async (e) => {
  3515. let target = $(e.currentTarget);
  3516. target.find('.icon').remove();
  3517. target.find('.pl-loading').remove();
  3518. target.prepend(base.createLoading());
  3519. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  3520. if (res === 'success') {
  3521. $('.listener-rpc-task').show();
  3522. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  3523. } else {
  3524. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  3525. }
  3526. });
  3527. doc.on('click', '.listener-send-rpc', (e) => {
  3528. $('.listener-link-rpc').click();
  3529. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  3530. });
  3531. doc.on('click', '.listener-open-setting', () => {
  3532. base.showSetting();
  3533. });
  3534. doc.on('click', '.listener-open-updatelog', () => {
  3535. base.showUpdateLog();
  3536. });
  3537. doc.on('click', '.listener-rpc-task', () => {
  3538. let rpc = JSON.stringify({
  3539. domain: base.getValue('setting_rpc_domain'),
  3540. port: base.getValue('setting_rpc_port'),
  3541. }), url = `${pan.d}/?rpc=${base.encode(rpc)}#${base.getValue('setting_rpc_token')}`;
  3542. GM_openInTab(url, {active: true});
  3543. });
  3544. },
  3545.  
  3546. addButton() {
  3547. if(document.getElementById("pl-button-link")){
  3548. document.getElementById("pl-button-link").remove()
  3549. }
  3550. if (!pt) return;
  3551. let $toolWrap;
  3552. let $button = $(`<div class="yidong-button pl-button btn-top" id="pl-button-link"><span class="yidong-btn">下载助手</span><ul class="pl-dropdown-menu" style="top: 36px;"><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><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li>${pan.code == 200 && version < pan.version ? pan.new : ''}</ul></div>`);
  3553. if (pt === 'home') {
  3554. //let ins = setInterval(() => {
  3555. $toolWrap = $(pan.btn.home);
  3556. if ($toolWrap.length > 0) {
  3557. $toolWrap.prepend($button);
  3558. //clearInterval(ins);
  3559. }
  3560. //}, 50);
  3561. }
  3562. if (pt === 'share') {
  3563. $button.removeClass('yidong-button').addClass('yidong-share-button');
  3564. //let ins = setInterval(() => {
  3565. $toolWrap = $(pan.btn.share);
  3566. if ($toolWrap.length > 0) {
  3567. $toolWrap.prepend($button);
  3568. //clearInterval(ins);
  3569. }
  3570. //}, 50);
  3571. }
  3572. base.createDownloadIframe();
  3573. this.addPageListener();
  3574. setInterval(function(){
  3575. if(!document.getElementById("pl-button-link")){
  3576. yidong.addButton();
  3577. }
  3578. },1000)
  3579. },
  3580.  
  3581. addInitButton() {
  3582. if(document.getElementById("pl-button-link")){
  3583. document.getElementById("pl-button-link").remove()
  3584. }
  3585. if (!pt) return;
  3586. let $toolWrap;
  3587. let $button = $(`<div class="yidong-button pl-button-init btn-top" id="pl-button-link"><span class="yidong-btn">下载助手(未点亮)</span></div>`);
  3588. if (pt === 'home') {
  3589. //let ins = setInterval(() => {
  3590. $toolWrap = $(pan.btn.home);
  3591. if ($toolWrap.length > 0) {
  3592. $toolWrap.prepend($button);
  3593. //clearInterval(ins);
  3594. }
  3595. //}, 50);
  3596. }
  3597. if (pt === 'share') {
  3598. $button.removeClass('yidong-button').addClass('yidong-share-button');
  3599. //let ins = setInterval(() => {
  3600. $toolWrap = $(pan.btn.share);
  3601. if ($toolWrap.length > 0) {
  3602. $toolWrap.prepend($button);
  3603. //clearInterval(ins);
  3604. }
  3605. //}, 50);
  3606. }
  3607. $button.click(() => base.initDialog());
  3608. setInterval(function(){
  3609. if(!document.getElementById("pl-button-link")){
  3610. yidong.addInitButton();
  3611. }
  3612. },1000)
  3613. },
  3614.  
  3615. getRandomString(len) {
  3616. len = len || 16;
  3617. let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
  3618. let maxPos = $chars.length;
  3619. let pwd = '';
  3620. for (let i = 0; i < len; i++) {
  3621. pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
  3622. }
  3623. return pwd;
  3624. },
  3625.  
  3626. utob(str) {
  3627. const u = String.fromCharCode;
  3628. return str.replace(/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g, (t) => {
  3629. if (t.length < 2) {
  3630. let e = t.charCodeAt(0);
  3631. return e < 128 ? t : e < 2048 ? u(192 | e >>> 6) + u(128 | 63 & e) : u(224 | e >>> 12 & 15) + u(128 | e >>> 6 & 63) + u(128 | 63 & e);
  3632. }
  3633. e = 65536 + 1024 * (t.charCodeAt(0) - 55296) + (t.charCodeAt(1) - 56320);
  3634. return u(240 | e >>> 18 & 7) + u(128 | e >>> 12 & 63) + u(128 | e >>> 6 & 63) + u(128 | 63 & e);
  3635. });
  3636. },
  3637.  
  3638. getSign(e, t, a, n) {
  3639. let r = "",
  3640. i = "";
  3641. if (t) {
  3642. let s = Object.assign({}, t);
  3643. i = JSON.stringify(s),
  3644. i = i.replace(/\s*/g, ""),
  3645. i = encodeURIComponent(i);
  3646. let c = i.split(""),
  3647. u = c.sort();
  3648. i = u.join("");
  3649. }
  3650. let A = md5(base.encode(this.utob(i)));
  3651. let l = md5(a + ":" + n);
  3652. return md5(A + l).toUpperCase();
  3653. },
  3654.  
  3655. async getFileUrlByOnce(item, index) {
  3656. try {
  3657. if (item.downloadUrl) return {
  3658. index,
  3659. downloadUrl: item.downloadUrl
  3660. };
  3661.  
  3662. if (this.detectPage() === 'home') {
  3663. let body = {
  3664. "appName": "",
  3665. "contentID": item.contentID,
  3666. "commonAccountInfo": {"account": item.owner, "accountType": 1}
  3667. };
  3668. let time = new Date(+new Date() + 8 * 3600 * 1000).toJSON().substr(0, 19).replace('T', ' ');
  3669. let key = this.getRandomString(16);
  3670. let sign = this.getSign(undefined, body, time, key);
  3671.  
  3672. let res = await base.post(pan.pcs[0], body, {
  3673. 'x-huawei-channelSrc': '10000034',
  3674. 'x-inner-ntwk': '2',
  3675. 'mcloud-channel': '1000101',
  3676. 'mcloud-client': '10701',
  3677. 'mcloud-sign': time + "," + key + "," + sign,
  3678. 'content-type': "application/json;charset=UTF-8",
  3679. 'caller': 'web',
  3680. 'CMS-DEVICE': 'default',
  3681. 'x-DeviceInfo': '||9|7.11.0|chrome|102.0.0.0|||windows 10||zh-CN|||',
  3682. 'x-SvcType': '1',
  3683. });
  3684. if (res.success) {
  3685. return {
  3686. index,
  3687. downloadUrl: res.data.downloadURL
  3688. };
  3689. } else {
  3690. return {
  3691. index,
  3692. downloadUrl: '获取下载地址失败,请刷新重试!'
  3693. };
  3694. }
  3695. }
  3696. if (this.detectPage() === 'share') {
  3697. let vueDom = document.querySelector(".home-page").__vue__;
  3698.  
  3699. let res = await base.post(pan.pcs[1], `linkId=${vueDom.linkID}&contentIds=${encodeURIComponent(vueDom.currentPath.id + '/' + item.coID)}&catalogIds=`, {
  3700. 'Content-Type': 'application/x-www-form-urlencoded',
  3701. });
  3702. if (res.code === 0) {
  3703. return {
  3704. index,
  3705. downloadUrl: res.data.redrUrl
  3706. };
  3707. } else {
  3708. return {
  3709. index,
  3710. downloadUrl: '获取下载地址失败,请刷新重试!'
  3711. };
  3712. }
  3713. }
  3714. } catch (e) {
  3715. return {
  3716. index,
  3717. downloadUrl: '获取下载地址失败,请刷新重试!'
  3718. };
  3719. }
  3720. },
  3721.  
  3722. async getPCSLink() {
  3723. selectList = this.getSelectedList();
  3724. if (selectList.length === 0) {
  3725. return message.error('提示:请先勾选要下载的文件!');
  3726. }
  3727. if (this.isOnlyFolder()) {
  3728. return message.error('提示:请打开文件夹后勾选文件!');
  3729. }
  3730.  
  3731. let queue = [];
  3732. selectList.forEach((item, index) => {
  3733. queue.push(this.getFileUrlByOnce(item, index));
  3734. });
  3735.  
  3736. const res = await Promise.all(queue);
  3737. res.forEach(val => {
  3738. selectList[val.index].downloadUrl = val.downloadUrl;
  3739. });
  3740.  
  3741. let html = this.generateDom(selectList);
  3742. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  3743. },
  3744.  
  3745. generateDom(list) {
  3746. let content = '<div class="pl-main">';
  3747. let alinkAllText = '';
  3748. list.forEach((v, i) => {
  3749. if (v.dirEtag || v.caName) return;
  3750. let filename = v.contentName || v.coName;
  3751. let size = base.sizeFormat(v.contentSize || v.coSize);
  3752. let dlink = v.downloadUrl;
  3753. if (mode === 'api') {
  3754. alinkAllText += dlink + '\r\n';
  3755. content += `<div class="pl-item">
  3756. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3757. <a class="pl-item-link listener-link-api" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  3758. <button class="pl-item-copy pl-btn-primary listener-copy-all" href="${dlink}" title="点击复制链接" data-filename="${filename}" data-link="${dlink}">复制链接</button>
  3759. </div>`;
  3760. }
  3761. if (mode === 'aria') {
  3762. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  3763. alinkAllText += alink + '\r\n';
  3764. content += `<div class="pl-item">
  3765. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3766. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3767. }
  3768. if (mode === 'rpc') {
  3769. content += `<div class="pl-item">
  3770. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3771. <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>`;
  3772. }
  3773. if (mode === 'curl') {
  3774. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  3775. alinkAllText += alink + '\r\n';
  3776. content += `<div class="pl-item">
  3777. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3778. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3779. }
  3780. if (mode === 'bc') {
  3781. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  3782. content += `<div class="pl-item">
  3783. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3784. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3785. }
  3786. });
  3787. content += '</div>';
  3788. if (mode === 'api'){
  3789. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;}
  3790. if (mode === 'aria')
  3791. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  3792. if (mode === 'rpc') {
  3793. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  3794. 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>`;
  3795. }
  3796. if (mode === 'curl')
  3797. 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>`;
  3798. return content;
  3799. },
  3800.  
  3801. async sendLinkToRPC(filename, link) {
  3802. let rpc = {
  3803. domain: base.getValue('setting_rpc_domain'),
  3804. port: base.getValue('setting_rpc_port'),
  3805. path: base.getValue('setting_rpc_path'),
  3806. token: base.getValue('setting_rpc_token'),
  3807. dir: base.getValue('setting_rpc_dir'),
  3808. };
  3809.  
  3810. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  3811. let rpcData = {
  3812. id: new Date().getTime(),
  3813. jsonrpc: '2.0',
  3814. method: 'aria2.addUri',
  3815. params: [`token:${rpc.token}`, [link], {
  3816. dir: rpc.dir,
  3817. out: filename,
  3818. header: []
  3819. }]
  3820. };
  3821. try {
  3822. let res = await base.post(url, rpcData, {}, '');
  3823. if (res.result) return 'success';
  3824. return 'fail';
  3825. } catch (e) {
  3826. return 'fail';
  3827. }
  3828. },
  3829.  
  3830. getSelectedList() {
  3831. try {
  3832. return document.querySelector(".main_file_list").__vue__.selectList.map(val => val.item);
  3833. } catch (e) {
  3834. let vueDom = document.querySelector(".home-page").__vue__;
  3835. let fileList = vueDom._computedWatchers.fileList.value;
  3836. let dirList = vueDom._computedWatchers.dirList.value;
  3837. let selectedFileIndex = vueDom.selectedFile;
  3838. let selectedDirIndex = vueDom.selectedDir;
  3839. let selectFileList = fileList.filter((v, i) => {
  3840. return selectedFileIndex.includes(i);
  3841. });
  3842. let selectDirList = dirList.filter((v, i) => {
  3843. return selectedDirIndex.includes(i);
  3844. });
  3845. return [...selectFileList, ...selectDirList];
  3846. }
  3847. },
  3848.  
  3849. detectPage() {
  3850. let hostname = location.hostname;
  3851. if (/^yun/.test(hostname)) return 'home';
  3852. if (/^caiyun/.test(hostname)) return 'share';
  3853. return '';
  3854. },
  3855.  
  3856. isOnlyFolder() {
  3857. for (let i = 0; i < selectList.length; i++) {
  3858. if (selectList[i].fileEtag || selectList[i].coName) return false;
  3859. }
  3860. return true;
  3861. },
  3862.  
  3863. showMainDialog(title, html, footer) {
  3864. Swal.fire({
  3865. title,
  3866. html,
  3867. footer,
  3868. allowOutsideClick: false,
  3869. showCloseButton: true,
  3870. position: 'top',
  3871. width,
  3872. padding: '15px 20px 5px',
  3873. customClass,
  3874. confirmButtonText: '关闭',
  3875. });
  3876. },
  3877.  
  3878. async initPanLinker() {
  3879. base.initDefaultConfig();
  3880. pt = this.detectPage();
  3881. let res = await base.post
  3882. (`https://api.youxiaohou.com/config/yidong?ver=${version}&a=${author}`, {}, {}, 'text');
  3883. pan = JSON.parse(base.decode(res));
  3884. Object.freeze && Object.freeze(pan);
  3885. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  3886. base.createTip();
  3887. base.registerMenuCommand();
  3888. }
  3889. };
  3890.  
  3891. // 油小猴
  3892. let youxiaohou ={
  3893. async initPanLinker() {
  3894. base.initDefaultConfig();
  3895. let res = await base.post(`https://api.youxiaohou.com/config/?ver=${version}&a=${author}`, {}, {}, 'text');
  3896. pan = JSON.parse(base.decode(res));
  3897. base.createTip();
  3898. base.registerPanMenuCommand();
  3899.  
  3900. let $button1 = `<div class="nav-item" style="text-align: center;"><a class="listener-open-updatelog">(改)下载助手<br>更新日志</a></div>`
  3901. let $button2 = `<div class="nav-item" style="text-align: center;"><a class="listener-open-info">(改)下载助手<br>暗号查看</a></div>`
  3902. doc.on('click', '.listener-open-updatelog', () => {
  3903. base.showUpdateLog();
  3904. });
  3905. doc.on('click', '.listener-open-info', () => {
  3906. base.showPanInfo();
  3907. });
  3908. document.getElementsByClassName("nav-links can-hide")[0].innerHTML += $button1 + $button2
  3909. }
  3910. }
  3911.  
  3912. //获取实时脚本信息
  3913. function fetchScriptInfo(url, retryCount) {
  3914. fetch(url)
  3915. .then(response => response.json())
  3916. .then(data => {
  3917. console.log('【(改)网盘直链下载助手】Fetch\n请求地址:' + url + ' (GreasyFork)\n返回结果:', data);
  3918. var scriptVersion = data.version;
  3919. var scriptAuthor = data.users[0].name;
  3920. var scriptName = data.name;
  3921. var scriptDescription = data.description;
  3922. /*---
  3923. console/log('原脚本名称:', scriptName);
  3924. console/log('原脚本版本:', scriptVersion);
  3925. console/log('原脚本作者:', scriptAuthor);
  3926. console/log('原脚本介绍:', scriptDescription);
  3927. console/log('真实名称:', scriptInfo.name);
  3928. console/log('真实版本:', scriptInfo.version);
  3929. console/log('真实作者:', scriptInfo.author);
  3930. console/log('真实介绍:', scriptInfo.description);
  3931. */
  3932. base.setValue('setting_script_version', scriptVersion);
  3933. base.setValue('setting_script_author', 'YouXiaoHou');
  3934. base.setValue('setting_script_name', scriptName);
  3935. base.setValue('setting_script_description', scriptDescription);
  3936. })
  3937. .catch(error => {
  3938. console.error('【(改)网盘直链下载助手】\n获取脚本版本时发生错误', error);
  3939. if (retryCount > 0) {
  3940. console.log("【(改)网盘直链下载助手】\n5秒后将重试获取版本")
  3941. setTimeout(function(){
  3942. console.log('【(改)网盘直链下载助手】\n重新尝试获取脚本信息...');
  3943. fetchScriptInfo(url, retryCount - 1); // 重新尝试获取脚本版本
  3944. },5000)
  3945. } else {
  3946. console.error('【(改)网盘直链下载助手】\n无法获取脚本信息,达到最大尝试次数。');
  3947. }
  3948. });
  3949. }
  3950.  
  3951. //获取原脚本的GreasyFork信息,确保油小猴服务器信任
  3952. var retryCount = 5; // 重新尝试次数
  3953. fetchScriptInfo('https://greasyfork.org/zh-CN/scripts/436446.json', retryCount);
  3954.  
  3955. //用于油小猴服务器检测的脚本信息
  3956. const scriptInfo = GM_info.script;
  3957.  
  3958. //用于油小猴服务器检测的脚本作者
  3959. const realauthor = scriptInfo.author;
  3960. const author = base.getValue('setting_script_author');
  3961.  
  3962. //用于油小猴服务器检测的脚本名称
  3963. const realname = scriptInfo.name;
  3964. const name = base.getValue('setting_script_name');
  3965.  
  3966. //用于油小猴服务器检测的脚本版本,防止服务器返回更新信息
  3967. const realversion = scriptInfo.version;
  3968. const version = base.getValue('setting_script_version');
  3969.  
  3970. /*--- waitForKeyElements(): 一个实用函数,用于Greasemonkey脚本,
  3971. 它可以检测和处理AJAX加载的内容。
  3972. 使用示例:
  3973. waitForKeyElements (
  3974. "div.comments"
  3975. , commentCallbackFunction
  3976. );
  3977. // 页面特定的函数,用于在找到节点时执行我们想要的操作。
  3978. function commentCallbackFunction (jNode) {
  3979. jNode.text ("waitForKeyElements() 更改了这段注释。");
  3980. }
  3981. 重要提示:这个函数需要你的脚本加载了jQuery。
  3982. */
  3983. function waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector) {
  3984. var targetNodes, btargetsFound;
  3985.  
  3986. if (typeof iframeSelector == "undefined")
  3987. targetNodes = $(selectorTxt);
  3988. else
  3989. targetNodes = $(iframeSelector).contents()
  3990. .find(selectorTxt);
  3991.  
  3992. if (targetNodes && targetNodes.length > 0) {
  3993. btargetsFound = true;
  3994. targetNodes.each(function () {
  3995. var jThis = $(this);
  3996. var alreadyFound = jThis.data('alreadyFound') || false;
  3997.  
  3998. if (!alreadyFound) {
  3999. //--- 调用载荷函数。
  4000. var cancelFound = actionFunction(jThis);
  4001. if (cancelFound) btargetsFound = false;
  4002. else jThis.data('alreadyFound', true);
  4003. }
  4004. });
  4005. } else {
  4006. btargetsFound = false;
  4007. }
  4008.  
  4009. //--- 获取这个选择器的定时器控制变量。
  4010. var controlObj = waitForKeyElements.controlObj || {};
  4011. var controlKey = selectorTxt.replace(/[^\w]/g, "_");
  4012. var timeControl = controlObj[controlKey];
  4013.  
  4014. //--- 现在根据情况设置或清除定时器。
  4015. if (btargetsFound && bWaitOnce && timeControl) {
  4016. //--- 唯一需要清除定时器的情况。
  4017. clearInterval(timeControl);
  4018. delete controlObj[controlKey]
  4019. } else {
  4020. //--- 如果需要的话,设置一个定时器。
  4021. if (!timeControl) {
  4022. timeControl = setInterval(function () {
  4023. waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector);
  4024. }, 300);
  4025. controlObj[controlKey] = timeControl;
  4026. }
  4027. }
  4028. waitForKeyElements.controlObj = controlObj;
  4029. }
  4030.  
  4031. // 主代码
  4032. let main = {
  4033. init() {
  4034. // 加载网页样式
  4035. base.addPanLinkerStyle();
  4036.  
  4037. // 判断网盘地址并加载对应的initPanLinker
  4038. if (/(pan|yun).baidu.com/.test(location.host)) {
  4039. baidu.initPanLinker();
  4040. }
  4041. if (/www.aliyundrive.com/.test(location.host)) {
  4042. ali.initPanLinker();
  4043. }
  4044. if (/cloud.189.cn/.test(location.host)) {
  4045. tianyi.initPanLinker();
  4046. }
  4047. if (/pan.xunlei.com/.test(location.host)) {
  4048. xunlei.initPanLinker();
  4049. }
  4050. if (/pan.quark.cn/.test(location.host)) {
  4051. quark.initPanLinker();
  4052. }
  4053. if (/(yun|caiyun).139.com/.test(location.host)) {
  4054. yidong.initPanLinker();
  4055. }
  4056. if (/www.youxiaohou.com/.test(location.host)) {
  4057. youxiaohou.initPanLinker();
  4058. }
  4059. }
  4060. };
  4061. main.init();
  4062. })();