// ==UserScript== // @name LinkSwift00 // @namespace github.com/hmjz100 // @version 1.1.0.1 // @author Hmjz100、油小猴 // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48cGF0aCBkPSJNMTAzLjYgMTA3LjRjMy41LTIuMiA4LjktNi4xIDEzLjgtMTIuNXM3LjMtMTIuNSA4LjUtMTYuNWMuNS0xLjcgMi4yLTcuNSAyLjItMTQuNyAwLTEwLjEtMy4zLTI1LjEtMTUuNC0zNi44LTE0LjUtMTQtMzIuMS0xNC4zLTM1LjctMTQuMy04IDAtMTUuNyAxLjktMjIuNiA1LjJDNDQgMjMgMzUuNyAzMS40IDMwLjggNDEuN2MtMS4zIDIuOC00IDQuNy03LjEgNS00IC4zLTcuNSA0LjQtOC45IDkuNi0uNSAxLjktMS42IDMuNS0zLjEgNC43QzQuNCA2Ni44IDAgNzUuNyAwIDg1YzAgNi44IDIuMyAxMy4xIDYuMSAxOC4yIDUuNSA3LjQgMTQuMiAxMi4yIDI0IDEyLjJoNDcuMWM0LjQgMCAxMS0uNSAxOC4zLTMuNSAzLjItMS40IDUuOS0zIDguMS00LjV6IiBmaWxsPSIjQTA5OUYwIi8+PHBhdGggZD0iTTExOS44IDY0LjNjLjEtMTcuMS0xMC40LTI4LTEyLjUtMzAuMUM5NSAyMi4xIDc5LjkgMjEuOCA3Ni45IDIxLjhjLTE3LjYgMC0zMy4zIDEwLjUtMzkuOSAyNi43LS42IDEuMy0xLjggMi4zLTMuNCAyLjNoLS40Yy01LjggMC0xMC42IDQuOC0xMC42IDEwLjd2LjVjMCAxLjQtLjggMi42LTEuOSAzLjNDMTMuNCA2OSA4LjggNzYuOCA4LjggODVjMCAxMi4yIDkuOSAyMi4zIDIyLjIgMjIuM2g0NS4yYzMuNi0uMSAxNy42LS45IDI5LjYtMTIgMi45LTIuOCAxMy45LTEzLjcgMTQtMzF6IiBmaWxsPSIjNTc0QUI4Ii8+PHBhdGggZD0iTTExMC44IDU3LjRsLjIgMy4zYzAgMS4zLTEuMSAyLjQtMi4zIDIuNC0xLjMgMC0yLjMtMS4xLTIuMy0yLjRsLS4xLTIuOHYtLjNjMC0xLjIuOS0yLjIgMi4xLTIuM2guM2MuNyAwIDEuMy4zIDEuNy43LS4yLjEuMy41LjQgMS40em0tMy4zLTEwLjNjMCAxLjItMSAyLjMtMi4yIDIuM2gtLjFjLS44IDAtMS42LS41LTItMS4yLTQuNi04LjMtMTMuMy0xMy41LTIyLjgtMTMuNS0xLjIgMC0yLjMtMS0yLjMtMi4ydi0uMWMwLTEuMiAxLTIuMyAyLjItMi4zaC4xYTMwLjM3IDMwLjM3IDAgMCAxIDE1LjggNC40YzQuNiAyLjggOC40IDYuOCAxMS4xIDExLjUuMS4zLjIuNy4yIDEuMXpNODguMyA3My44TDczLjUgOTMuMmMtMS41IDEuOS0zLjUgMy4xLTUuNyAzLjVoLS4yYy0uNC4xLS44LjEtMS4yLjEtLjYgMC0xLjEtLjEtMS42LS4yLTIuMi0uNC00LjItMS43LTUuNi0zLjVMNDQuMyA3My45Yy0yLTIuNi0yLjUtNS40LTEuNC03LjcuMS0uMS4xLS4yLjItLjIgMS4yLTIgMy41LTMuMiA2LjQtMy4yaDYuNnYtNS43YzAtNi44IDQuNy0xMiAxMC45LTEyIDQuOCAwIDguNSAyLjYgMTAuMyA3LjIuNSAxLjMtLjIgMi43LTEuNSAzLjJzLTIuOC0uMS0zLjMtMS40Yy0xLjEtMi43LTIuOS00LTUuNS00LTMuNSAwLTYgMy02IDd2OC4xYzAgLjUtLjIgMS0uNiAxLjQtLjYuNy0xLjcgMS4xLTIuNiAxLjFoLTguNGMtMS4zIDAtMiAuNC0yLjEuNy0uMi40IDAgMS4zLjkgMi40TDYzLjEgOTBjLjkgMS4yIDIuMSAxLjggMy4zIDEuOHMyLjMtLjYgMy4xLTEuN2wxNC44LTE5LjNjLjktMS4xIDEuMS0yIC45LTIuNC0uMi0uMy0uOS0uNy0yLjEtLjdoLTcuNmMtLjkgMC0xLjctLjUtMi4xLTEuMi0uMy0uNC0uNC0uOC0uNC0xLjMgMC0xLjQgMS4xLTIuNSAyLjUtMi41aDcuNmMzLjEgMCA1LjUgMS4zIDYuNiAzLjVsLjMuN2MuNyAyLjEuMSA0LjYtMS43IDYuOXoiIGZpbGw9IiNmZmYiLz48L3N2Zz4= // @description 修改自https://greasyfork.org/zh-CN/scripts/449291-linkswift。仅修改夸克:仅保留RPC,可配合rpc切换。其余无修改 // @license AGPL-3.0-or-later // @homepage https://github.com/hmjz100/LinkSwift/ // @support https://github.com/hmjz100/LinkSwift/issues // @supportURL https://github.com/hmjz100/LinkSwift/issues // @require https://unpkg.com/jquery@3.6.0/dist/jquery.min.js // @require https://unpkg.com/sweetalert2@11.4.8/dist/sweetalert2.min.js // @resource SwalLigt https://unpkg.com/sweetalert2@11.4.8/dist/sweetalert2.min.css // @resource SwalDark https://unpkg.com/@sweetalert2/theme-dark@5.0.26/dark.min.css // @require https://unpkg.com/js-md5@0.7.3/build/md5.min.js // @run-at document-start // @match *://pan.baidu.com/disk/home* // @match *://yun.baidu.com/disk/home* // @match *://pan.baidu.com/disk/timeline* // @match *://yun.baidu.com/disk/timeline* // @match *://pan.baidu.com/disk/main* // @match *://yun.baidu.com/disk/main* // @match *://pan.baidu.com/youth/pan/main* // @match *://yun.baidu.com/youth/pan/main* // @match *://pan.baidu.com/disk/base* // @match *://yun.baidu.com/disk/base* // @match *://pan.baidu.com/disk/timeline* // @match *://yun.baidu.com/disk/timeline* // @match *://pan.baidu.com/pfile/* // @match *://yun.baidu.com/pfile/* // @match *://pan.baidu.com/s/* // @match *://pan.baidu.com/aipan/* // @match *://yun.baidu.com/s/* // @match *://yun.baidu.com/aipan/* // @match *://pan.baidu.com/share/* // @match *://yun.baidu.com/share/* // @match *://pan.baidu.com/embed/* // @match *://yun.baidu.com/embed/* // @match *://openapi.baidu.com/* // @match *://www.aliyundrive.com/s/* // @match *://www.aliyundrive.com/drive* // @match *://www.alipan.com/s/* // @match *://www.alipan.com/drive* // @match *://cloud.189.cn/web/* // @match *://pan.xunlei.com/* // @match *://pan.quark.cn/* // @match *://drive.uc.cn/* // @match *://yun.139.com/* // @match *://caiyun.139.com/* // @match *://*.123pan.com/* // @match *://*.123pan.cn/* // @match *://*.123684.com/* // @match *://*.123865.com/* // @match *://*.123952.com/* // @match *://*.123912.com/* // @match *://*.youxiaohou.com/* // @connect baidu.com // @connect baidupcs.com // @connect aliyundrive.com // @connect aliyundrive.net // @connect alipan.com // @connect alicloudccp.com // @connect aliyundrive.cloud // @connect 189.cn // @connect xunlei.com // @connect quark.cn // @connect uc.cn // @connect 123pan.com // @connect 123pan.cn // @connect 123684.com // @connect 123865.com // @connect 123952.com // @connect 123912.com // @connect cjjd19.com // @connect localhost // @connect * // @grant unsafeWindow // @grant window.close // @grant GM_xmlhttpRequest // @grant GM.xmlhttpRequest // @grant GM_setClipboard // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_openInTab // @grant GM_info // @grant GM_registerMenuCommand // @grant GM_cookie // @grant GM_getResourceText // @compatible Chrome // @compatible Edge // @compatible Firefox // @compatible Safari // @compatible Opera // @downloadURL none // ==/UserScript== /** * @name LinkSwift * @template (改)网盘直链下载助手 * @author 油小猴 * @author hmjz100 * @namespace github.com/hmjz100 * @description 一个基于 JavaScript 盘的文件下载地址获取工具 * 支持 百度网盘/阿里云盘/中国移动云盘/天翼云盘/迅雷云盘/夸克网盘/UC网盘/123云盘 八大网盘 * @version 1.1.0.1 * @license AGPL-3.0-or-later * @see {@link https://github.com/hmjz100/LinkSwift/ Github 仓库} */ (function linkSwift() { // 严格模式,确保代码安全执行 'use strict'; // unsafeWindow 检测 if (typeof unsafeWindow === 'undefined') { window.unsafeWindow = window; } /* 防止代码因其他原因被执行多次 代码出自 “Via 轻插件”,作者谷花泰 */ const key = encodeURIComponent('LinkSwift:主代码'); if (window[key]) return; window[key] = true; /* 网盘直链下载助手 代码改自 “网盘直链下载助手”,作者油小猴 有增添新代码 */ /* 全局参数 */ let mount = idontknow("LinkSwift") let page = '', selectList = [], shareParams = {}, mode = '', color = '', doc = $(document), progress = {}, request = {}, ins = {}, idm = {}, colored = false, replacedElements = new Set(), scriptInfo = GM_info.script, sauthor = scriptInfo.author, sname = scriptInfo.name, sversion = (scriptInfo?.version?.toString() || "1.1.0.1"), sicon = (scriptInfo?.icon || "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48cGF0aCBkPSJNMTAzLjYgMTA3LjRjMy41LTIuMiA4LjktNi4xIDEzLjgtMTIuNXM3LjMtMTIuNSA4LjUtMTYuNWMuNS0xLjcgMi4yLTcuNSAyLjItMTQuNyAwLTEwLjEtMy4zLTI1LjEtMTUuNC0zNi44LTE0LjUtMTQtMzIuMS0xNC4zLTM1LjctMTQuMy04IDAtMTUuNyAxLjktMjIuNiA1LjJDNDQgMjMgMzUuNyAzMS40IDMwLjggNDEuN2MtMS4zIDIuOC00IDQuNy03LjEgNS00IC4zLTcuNSA0LjQtOC45IDkuNi0uNSAxLjktMS42IDMuNS0zLjEgNC43QzQuNCA2Ni44IDAgNzUuNyAwIDg1YzAgNi44IDIuMyAxMy4xIDYuMSAxOC4yIDUuNSA3LjQgMTQuMiAxMi4yIDI0IDEyLjJoNDcuMWM0LjQgMCAxMS0uNSAxOC4zLTMuNSAzLjItMS40IDUuOS0zIDguMS00LjV6IiBmaWxsPSIjQTA5OUYwIi8+PHBhdGggZD0iTTExOS44IDY0LjNjLjEtMTcuMS0xMC40LTI4LTEyLjUtMzAuMUM5NSAyMi4xIDc5LjkgMjEuOCA3Ni45IDIxLjhjLTE3LjYgMC0zMy4zIDEwLjUtMzkuOSAyNi43LS42IDEuMy0xLjggMi4zLTMuNCAyLjNoLS40Yy01LjggMC0xMC42IDQuOC0xMC42IDEwLjd2LjVjMCAxLjQtLjggMi42LTEuOSAzLjNDMTMuNCA2OSA4LjggNzYuOCA4LjggODVjMCAxMi4yIDkuOSAyMi4zIDIyLjIgMjIuM2g0NS4yYzMuNi0uMSAxNy42LS45IDI5LjYtMTIgMi45LTIuOCAxMy45LTEzLjcgMTQtMzF6IiBmaWxsPSIjNTc0QUI4Ii8+PHBhdGggZD0iTTExMC44IDU3LjRsLjIgMy4zYzAgMS4zLTEuMSAyLjQtMi4zIDIuNC0xLjMgMC0yLjMtMS4xLTIuMy0yLjRsLS4xLTIuOHYtLjNjMC0xLjIuOS0yLjIgMi4xLTIuM2guM2MuNyAwIDEuMy4zIDEuNy43LS4yLjEuMy41LjQgMS40em0tMy4zLTEwLjNjMCAxLjItMSAyLjMtMi4yIDIuM2gtLjFjLS44IDAtMS42LS41LTItMS4yLTQuNi04LjMtMTMuMy0xMy41LTIyLjgtMTMuNS0xLjIgMC0yLjMtMS0yLjMtMi4ydi0uMWMwLTEuMiAxLTIuMyAyLjItMi4zaC4xYTMwLjM3IDMwLjM3IDAgMCAxIDE1LjggNC40YzQuNiAyLjggOC40IDYuOCAxMS4xIDExLjUuMS4zLjIuNy4yIDEuMXpNODguMyA3My44TDczLjUgOTMuMmMtMS41IDEuOS0zLjUgMy4xLTUuNyAzLjVoLS4yYy0uNC4xLS44LjEtMS4yLjEtLjYgMC0xLjEtLjEtMS42LS4yLTIuMi0uNC00LjItMS43LTUuNi0zLjVMNDQuMyA3My45Yy0yLTIuNi0yLjUtNS40LTEuNC03LjcuMS0uMS4xLS4yLjItLjIgMS4yLTIgMy41LTMuMiA2LjQtMy4yaDYuNnYtNS43YzAtNi44IDQuNy0xMiAxMC45LTEyIDQuOCAwIDguNSAyLjYgMTAuMyA3LjIuNSAxLjMtLjIgMi43LTEuNSAzLjJzLTIuOC0uMS0zLjMtMS40Yy0xLjEtMi43LTIuOS00LTUuNS00LTMuNSAwLTYgMy02IDd2OC4xYzAgLjUtLjIgMS0uNiAxLjQtLjYuNy0xLjcgMS4xLTIuNiAxLjFoLTguNGMtMS4zIDAtMiAuNC0yLjEuNy0uMi40IDAgMS4zLjkgMi40TDYzLjEgOTBjLjkgMS4yIDIuMSAxLjggMy4zIDEuOHMyLjMtLjYgMy4xLTEuN2wxNC44LTE5LjNjLjktMS4xIDEuMS0yIC45LTIuNC0uMi0uMy0uOS0uNy0yLjEtLjdoLTcuNmMtLjkgMC0xLjctLjUtMi4xLTEuMi0uMy0uNC0uNC0uOC0uNC0xLjMgMC0xLjQgMS4xLTIuNSAyLjUtMi41aDcuNmMzLjEgMCA1LjUgMS4zIDYuNiAzLjVsLjMuN2MuNyAyLjEuMSA0LjYtMS43IDYuOXoiIGZpbGw9IiNmZmYiLz48L3N2Zz4="), mhandler = GM_info.scriptHandler, mversion = GM_info.version; /* 设置选项 */ // Shell类型(用于curl下载) let terminalType = { wc: "Microsoft Windows 命令提示符", wp: "Microsoft Windows PowerShell", lt: "Linux 终端", ls: "Linux Shell", mt: "Apple MacOS 终端", }; // 更换 百度网盘新界面/阿里云盘/迅雷云盘/移动云盘 主题颜色 let assistantTheme = { yes: "更换主题颜色", no: "不更换主题颜色" }; /* Sweet Alert 2 */ // 自定义元素 Class 名(于 showMainDialog() 中) let customClass = { popup: 'pl-popup', header: 'pl-header', title: 'pl-title', closeButton: 'pl-close', content: 'pl-content', input: 'pl-input', footer: 'pl-footer' }; // 弹窗默认设置 let swalDefault = { heightAuto: false, scrollbarPadding: false, } /** * SweetAlert2 的 Toast 提示框基础配置 * @author 油小猴 * @author hmjz100 * @description 创建一个全局通用的 Toast 提示框实例,支持自动关闭、鼠标悬停暂停、右下角弹出等特性。 * * @type {Sweetalert2.Toast} */ let toast = Swal.mixin({ toast: true, position: 'bottom-end', showConfirmButton: false, timer: 3500, timerProgressBar: true, showCloseButton: true, didOpen: function (toast) { toast.addEventListener('mouseenter', Swal.stopTimer); toast.addEventListener('mouseleave', Swal.resumeTimer); } }); /** * 消息提示工具类 * @author 油小猴 * @description 提供统一的提示信息展示方法,基于 SweetAlert2 的 Toast 实现; * 包含 success / error / warning / info / question 等类型。 */ let message = { success: function (text) { toast.fire({ title: text, icon: 'success' }); }, error: function (text) { toast.fire({ title: text, icon: 'error' }); }, warning: function (text) { toast.fire({ title: text, icon: 'warning' }); }, info: function (text) { toast.fire({ title: text, icon: 'info' }); }, question: function (text) { toast.fire({ title: text, icon: 'question' }); } }; /** * 基础配置集合 * @author 油小猴 * @author hmjz100 */ const config = { base: { num: "865746", license: "AGPL3", service: { account: "https://pic.rmb.bdstatic.com/bjh/8b9e14345b3cdf96aedac2f3971adcb02681.png", rpc: "http://d.youxiaohou.com" }, dom: { footer: "o(≧▽≦)o 十分感谢您的支持!来给此项目一个 Star 吧~", button: { api: { title: "API 下载", footer: "适用于 IDMNDM 以及浏览器自带下载
o(≧▽≦)o 十分感谢您的支持!来给此项目一个 Star 吧~" }, aria: { title: "Aria 下载", footer: "适用于 XDownLinux Shell命令行
o(≧▽≦)o 十分感谢您的支持!来给此项目一个 Star 吧~" }, rpc: { title: "RPC 下载", footer: "适用于 MotrixAria2 ToolsAriaNgGUI
o(≧▽≦)o 十分感谢您的支持!来给此项目一个 Star 吧~" }, curl: { title: "cURL 下载", footer: "适用于 Windows,Linux,MacOS 终端
o(≧▽≦)o 十分感谢您的支持!来给此项目一个 Star 吧~" }, bc: { title: "BC 下载", footer: "适用于 比特彗星
o(≧▽≦)o 十分感谢您的支持!来给此项目一个 Star 吧~" } } }, assistant: { message: "请先安装网盘万能助手哦,安装后再刷新本页就好啦", link: "https://www.crxsoso.com/addon/detail/mphijdmblaalbakceeadippfkbgfgaaa" } }, $baidu: { api: { ua: { downloadLink: "pan.baidu.com" }, getAccessToken: "https://openapi.baidu.com/oauth/2.0/authorize?response_type=token&scope=basic,netdisk&client_id=IlLqBbU3GjQ0t46TRwFateTprHWl39zF&redirect_uri=oob&confirm_login=0", getLink: "https://pan.baidu.com/rest/2.0/xpan/multimedia?method=filemetas&dlink=1", getFiles: "https://pan.baidu.com/rest/2.0/xpan/file?method=list&showempty=1", getShareLink: "https://pan.baidu.com/api/sharedownload?channel=chunlei&clienttype=0&web=1&app_id=250528", getShareInfo: "https://pan.baidu.com/share/tplconfig?fields=sign,timestamp&channel=chunlei&web=1&app_id=250528&clienttype=0", getShareFiles: "https://pan.baidu.com/rest/2.0/xpan/share?method=list&showempty=1" }, mount: { home: ".frame-main>div>div>div>div:has(.g-dropdown-button.g-new-create)", main: ".wp-s-agile-tool-bar__header", share: ".module-share-top-bar .x-button-box .g-dropdown-button.tools-more" } }, $aliyun: { api: { getLink: "https://api.aliyundrive.com/v2/file/get_download_url", getShareLink: "https://api.aliyundrive.com/v2/file/get_share_link_download_url" }, mount: { home: "[class^=\"header--\"]>[class^=\"actions--\"]", share: "[class^=\"banner--\"]>[class^=\"right--\"]", list: "[class^=\"node-list-table-view--\"]", grid: "[class^=\"node-list-grid-view--\"]", switch: "[class^=\"switch-wrapper--\"]" } }, $mcloud: { api: { getLink: "https://personal-kd-njs.yun.139.com/hcy/file/getDownloadUrl" }, mount: { home: ".top_button", share: ".top-btns" } }, $tcloud: { api: { getAccessToken: "https://api.cloud.189.cn/open/oauth2/ssoH5.action", getLink: "https://api.cloud.189.cn/open/file/getFileDownloadUrl.action" }, mount: { home: "[class*=\"FileHead_file-head-left\"]", share: ".nav-opea" } }, $xunlei: { api: { mirror: [ "vod0007-h05-vip-lixian.xunlei.com", "vod0008-h05-vip-lixian.xunlei.com", "vod0009-h05-vip-lixian.xunlei.com", "vod0010-h05-vip-lixian.xunlei.com", "vod0011-h05-vip-lixian.xunlei.com", "vod0012-h05-vip-lixian.xunlei.com", "vod0013-h05-vip-lixian.xunlei.com", "vod0014-h05-vip-lixian.xunlei.com", "vod0067-aliyun08-vip-lixian.xunlei.com", "vod0254-aliyun08-vip-lixian.xunlei.com", "vod0255-aliyun08-vip-lixian.xunlei.com", "vod0256-aliyun08-vip-lixian.xunlei.com", "vod0257-aliyun08-vip-lixian.xunlei.com", "vod0258-aliyun08-vip-lixian.xunlei.com", "vod0259-aliyun08-vip-lixian.xunlei.com", "vod0260-aliyun08-vip-lixian.xunlei.com", "vod0261-aliyun08-vip-lixian.xunlei.com", "vod0262-aliyun08-vip-lixian.xunlei.com", "vod0263-aliyun08-vip-lixian.xunlei.com", "vod0264-aliyun08-vip-lixian.xunlei.com", "vod0265-aliyun08-vip-lixian.xunlei.com", "vod0266-aliyun08-vip-lixian.xunlei.com", "vod0267-aliyun08-vip-lixian.xunlei.com", "vod0554-aliyun06-vip-lixian.xunlei.com", "vod0555-aliyun06-vip-lixian.xunlei.com", "vod0556-aliyun06-vip-lixian.xunlei.com", "vod0680-aliyun08-vip-lixian.xunlei.com", "vod0681-aliyun08-vip-lixian.xunlei.com", "vod0682-aliyun08-vip-lixian.xunlei.com", "vod0683-aliyun08-vip-lixian.xunlei.com", "vod0684-aliyun08-vip-lixian.xunlei.com", "vod0685-aliyun08-vip-lixian.xunlei.com", "vod0686-aliyun08-vip-lixian.xunlei.com", "vod0687-aliyun08-vip-lixian.xunlei.com", "vod0688-aliyun08-vip-lixian.xunlei.com", "vod0689-aliyun08-vip-lixian.xunlei.com", "vod0690-aliyun08-vip-lixian.xunlei.com", "vod0724-aliyun08-vip-lixian.xunlei.com", "vod0725-aliyun08-vip-lixian.xunlei.com", "vod0726-aliyun08-vip-lixian.xunlei.com", "vod0727-aliyun08-vip-lixian.xunlei.com", "vod0728-aliyun08-vip-lixian.xunlei.com", "vod0075.aliyun06.vip.lixian.xunlei.com", "vod0076.aliyun06.vip.lixian.xunlei.com", "vod0077.aliyun06.vip.lixian.xunlei.com", "vod0779-aliyun04-vip-lixian.xunlei.com", "vod0078.aliyun06.vip.lixian.xunlei.com", "vod0780-aliyun04-vip-lixian.xunlei.com", "vod0781-aliyun04-vip-lixian.xunlei.com", "vod0079.aliyun06.vip.lixian.xunlei.com", "vod0080.aliyun06.vip.lixian.xunlei.com", "vod0117.aliyun04.vip.lixian.xunlei.com", "vod0118.aliyun04.vip.lixian.xunlei.com", "vod0119.aliyun04.vip.lixian.xunlei.com", "vod1284-aliyun06-vip-lixian.xunlei.com", "vod1285-aliyun06-vip-lixian.xunlei.com", "vod1363-aliyun06-vip-lixian.xunlei.com", "vod1371-aliyun06-vip-lixian.xunlei.com", "vod1372-aliyun06-vip-lixian.xunlei.com", "vod1426-aliyun06-vip-lixian.xunlei.com", "vod1427-aliyun06-vip-lixian.xunlei.com", "vod1428-aliyun06-vip-lixian.xunlei.com", "vod1429-aliyun06-vip-lixian.xunlei.com", "vod1442-aliyun06-vip-lixian.xunlei.com", "vod1443-aliyun06-vip-lixian.xunlei.com", "vod1444-aliyun06-vip-lixian.xunlei.com", "vod1445-aliyun06-vip-lixian.xunlei.com", "vod1446-aliyun06-vip-lixian.xunlei.com", "vod1447-aliyun06-vip-lixian.xunlei.com", "vod1469-aliyun06-vip-lixian.xunlei.com", "vod1470-aliyun06-vip-lixian.xunlei.com", "vod1471-aliyun06-vip-lixian.xunlei.com", "vod1489-aliyun06-vip-lixian.xunlei.com", "vod1490-aliyun06-vip-lixian.xunlei.com", "vod1491-aliyun06-vip-lixian.xunlei.com", "vod1492-aliyun06-vip-lixian.xunlei.com", "vod1493-aliyun06-vip-lixian.xunlei.com", "vod0215.aliyun06.vip.lixian.xunlei.com", "vod0216.aliyun06.vip.lixian.xunlei.com", "vod0217.aliyun06.vip.lixian.xunlei.com", "vod0218.aliyun06.vip.lixian.xunlei.com", "vod0219.aliyun06.vip.lixian.xunlei.com", "vod0220.aliyun06.vip.lixian.xunlei.com", "vod0241.aliyun08.vip.lixian.xunlei.com", "vod0244.aliyun08.vip.lixian.xunlei.com", "vod0251.aliyun08.vip.lixian.xunlei.com", "vod0252.aliyun08.vip.lixian.xunlei.com", "vod0253.aliyun08.vip.lixian.xunlei.com", "vod0254.aliyun08.vip.lixian.xunlei.com", "vod0255.aliyun08.vip.lixian.xunlei.com", "vod0256.aliyun08.vip.lixian.xunlei.com", "vod0257.aliyun08.vip.lixian.xunlei.com", "vod0260.aliyun08.vip.lixian.xunlei.com", "vod0261.aliyun08.vip.lixian.xunlei.com", "vod0262.aliyun08.vip.lixian.xunlei.com", "vod0263.aliyun08.vip.lixian.xunlei.com", "vod0264.aliyun08.vip.lixian.xunlei.com", "vod0265.aliyun08.vip.lixian.xunlei.com", "vod0266.aliyun08.vip.lixian.xunlei.com", "vod0267.aliyun08.vip.lixian.xunlei.com", "vod3379-aliyun04-vip-lixian.xunlei.com", "vod3380-aliyun04-vip-lixian.xunlei.com", "vod3429-aliyun04-vip-lixian.xunlei.com", "vod3458-aliyun04-vip-lixian.xunlei.com", "vod3459-aliyun04-vip-lixian.xunlei.com", "vod3496-aliyun04-vip-lixian.xunlei.com", "vod3497-aliyun04-vip-lixian.xunlei.com", "vod3498-aliyun04-vip-lixian.xunlei.com", "vod3499-aliyun04-vip-lixian.xunlei.com", "vod3500-aliyun04-vip-lixian.xunlei.com", "vod3501-aliyun04-vip-lixian.xunlei.com", "vod3522-aliyun04-vip-lixian.xunlei.com", "vod3523-aliyun04-vip-lixian.xunlei.com", "vod3533-aliyun04-vip-lixian.xunlei.com", "vod3534-aliyun04-vip-lixian.xunlei.com", "vod3535-aliyun04-vip-lixian.xunlei.com", "vod3536-aliyun04-vip-lixian.xunlei.com", "vod3549-aliyun04-vip-lixian.xunlei.com", "vod3550-aliyun04-vip-lixian.xunlei.com", "vod3551-aliyun04-vip-lixian.xunlei.com", "vod3552-aliyun04-vip-lixian.xunlei.com", "vod3553-aliyun04-vip-lixian.xunlei.com", "vod3554-aliyun04-vip-lixian.xunlei.com", "vod3555-aliyun04-vip-lixian.xunlei.com", "vod0551.aliyun06.vip.lixian.xunlei.com", "vod0552.aliyun06.vip.lixian.xunlei.com", "vod0553.aliyun06.vip.lixian.xunlei.com", "vod0554.aliyun06.vip.lixian.xunlei.com", "vod0555.aliyun06.vip.lixian.xunlei.com", "vod0556.aliyun06.vip.lixian.xunlei.com", "vod0686.aliyun08.vip.lixian.xunlei.com", "vod0687.aliyun08.vip.lixian.xunlei.com", "vod0688.aliyun08.vip.lixian.xunlei.com", "vod0689.aliyun08.vip.lixian.xunlei.com", "vod0724.aliyun08.vip.lixian.xunlei.com", "vod0725.aliyun08.vip.lixian.xunlei.com", "vod0726.aliyun08.vip.lixian.xunlei.com", "vod0727.aliyun08.vip.lixian.xunlei.com", "vod0728.aliyun08.vip.lixian.xunlei.com", "vod0759.aliyun04.vip.lixian.xunlei.com", "vod0760.aliyun04.vip.lixian.xunlei.com", "vod0769.aliyun04.vip.lixian.xunlei.com", "vod0770.aliyun04.vip.lixian.xunlei.com", "vod0771.aliyun04.vip.lixian.xunlei.com", "vod0772.aliyun04.vip.lixian.xunlei.com", "vod0773.aliyun04.vip.lixian.xunlei.com", "vod0774.aliyun04.vip.lixian.xunlei.com", "vod0775.aliyun04.vip.lixian.xunlei.com", "vod0776.aliyun04.vip.lixian.xunlei.com", "vod0777.aliyun04.vip.lixian.xunlei.com", "vod0778.aliyun04.vip.lixian.xunlei.com", "vod0779.aliyun04.vip.lixian.xunlei.com", "vod0780.aliyun04.vip.lixian.xunlei.com", "vod0781.aliyun04.vip.lixian.xunlei.com", "vod3522.aliyun04.vip.lixian.xunlei.com", "vod3523.aliyun04.vip.lixian.xunlei.com", "vod3533.aliyun04.vip.lixian.xunlei.com", "vod3535.aliyun04.vip.lixian.xunlei.com", "vod3550.aliyun04.vip.lixian.xunlei.com", "vod3551.aliyun04.vip.lixian.xunlei.com", "vod3552.aliyun04.vip.lixian.xunlei.com", "vod3553.aliyun04.vip.lixian.xunlei.com", "vod3554.aliyun04.vip.lixian.xunlei.com", "vod3555.aliyun04.vip.lixian.xunlei.com" ], getLink: "https://api-pan.xunlei.com/drive/v1/files/" }, mount: { home: "[class^=\"FileMenu__menu--\"]", share: "[class^=\"Share__batchActionBox--\"]" } }, $quark: { api: { ua: { downloadLink: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch" }, getLink: "https://drive.quark.cn/1/clouddrive/file/download?pr=ucpro&fr=pc" }, mount: { home: ".btn-operate .btn-main", share: ".share-btns" } }, $uc: { api: { ua: { downloadLink: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) uc-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch" }, getLink: "https://pc-api.uc.cn/1/clouddrive/file/download?pr=UCBrowser&fr=pc" }, mount: { home: ".btn-operate .btn-main", share: ".file-info-share-buttom" } }, $123pan: { api: { getLink: "https://www.123pan.com/api/file/download_info", getShareLink: "https://www.123pan.com/api/share/download/info" }, mount: { home: "main.ant-layout-content .site-layout-background .homeClass .wenserh", share: ".conter .rightInfo .qrcode_btn" } } } /** * 基础工具集合 * @author 油小猴 * @author hmjz100 */ let base = { /** * 生成 Aria2 下载命令 * @author 油小猴 * @author hmjz100 * @description 将链接转换为 Aria2 格式命令,自动处理文件名特殊字符 * @param {string} link - 下载链接 * @param {string} filename - 文件名 * @param {string} [header] - 自定义请求头参数(可选) * @returns {string} 编码后的 aria2c 命令字符串 */ convertLinkToAria(link, filename, header) { filename = base.fixFilename(filename); return encodeURIComponent(`aria2c "${link}" --out "${filename}"${header ? (" " + header) : ""}`); }, /** * 生成 BC 协议下载链接 * @author 油小猴 * @author hmjz100 * @description 将链接转换为 BC 协议格式,自动处理 URL 编码 * @param {string} link - 下载链接 * @param {string} filename - 文件名 * @param {string} [header] - 自定义请求头参数(可选) * @returns {string} 编码后的 BC 协议 URL */ convertLinkToBC(link, filename, header) { let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}${header ? ("&" + header) : ""}ZZ`; return encodeURIComponent(`bc://http/${base.encodeBase(bc)}`); }, /** * 生成 cURL 下载命令 * @author 油小猴 * @author hmjz100 * @description 根据终端类型生成对应 curl 命令,支持断点续传,自动处理文件名特殊字符 * @param {string} link - 下载链接 * @param {string} filename - 文件名 * @param {string} [header] - 自定义请求头参数(可选) * @returns {string} 编码后的 curl 命令字符串 */ convertLinkToCurl(link, filename, header) { let terminal = base.getValue('setting_terminal_type'); filename = base.fixFilename(filename); return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}"${header ? (" " + header) : ""}`); }, /** * 发送链接到 RPC 下载器 * @author 油小猴 * @author hmjz100 * @description RPC 下载必备 * @param {string} link - 下载链接 * @param {string} filename - 文件名 * @param {string} [header] - 自定义请求头参数(可选) * @returns {Promise<'success'|'fail'>} 发送态结果 */ async sendLinkToRPC(link, filename, header) { let rpc = { domain: base.getValue('setting_rpc_domain'), port: base.getValue('setting_rpc_port'), path: base.getValue('setting_rpc_path'), token: base.getValue('setting_rpc_token'), dir: base.getValue('setting_rpc_dir'), }; let url = `${rpc.domain}:${rpc.port}${rpc.path}`; let rpcData = { id: new Date().getTime(), jsonrpc: '2.0', method: 'aria2.addUri', params: [`token:${rpc.token}`, [link], { dir: rpc.dir, out: filename, header }] }; try { let res = await base.post(url, rpcData, {}, ''); if (res.result) return 'success'; return 'fail'; } catch (e) { return 'fail'; } }, /** * 注册 GreaseMonkey-Compatible-Manager 扩展菜单命令 * @author 油小猴 * @author hmjz100 * @description 包含 "设置"、"美化"、"更新" 和 "调试" 四个功能入口 */ registerMenuCommand() { GM_registerMenuCommand('⚙️ 设置', function () { base.showSetting(); }); GM_registerMenuCommand('🍃️ 美化', function () { base.showBeautify(); }); GM_registerMenuCommand('📃 更新', function () { base.showUpdate(); }); GM_registerMenuCommand('🛠️ 调试', function () { base.showDebug(); }); }, /** * 取消初始化配置并重置相关存储数据 * @author hmjz100 * @param {number} [value=111111] - 要设置的错误 `暗号` */ unRegisterInit(value = 111111) { message.warning("正在“注入”设置项目..."); base.setValue('setting_init_code', value); base.setValue('setting_init_license', value); base.setValue('baidu_access_token', ""); if (location.host.includes("baidu")) base.setStorage('baiduyunPlugin_BDUSS', "") history.go(0) }, /** * 判断 JavaScript 对象类型 * @author 油小猴 * @description 通过 Object.prototype.toString 精确识别对象类型 * @param {*} obj - 待检测对象 * @returns {string} 类型名称(全小写),如:array/number/null/date 等 * @example * isType([]) // => "array" * isType(null) // => "null" */ isType(obj) { return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase(); }, /** * 获取 GreaseMonkey-Compatible-Manager 存储的值 * @author 油小猴 * @param {string} name - 存储键名 * @returns {*} 存储的值 */ getValue(name) { return GM_getValue(name); }, /** * 设置 GreaseMonkey-Compatible-Manager 存储的值 * @author 油小猴 * @param {string} name - 存储键名 * @param {*} value - 要存储的值 */ setValue(name, value) { GM_setValue(name, value); }, /** * 删除 GreaseMonkey-Compatible-Manager 存储的值 * @author 油小猴 * @param {string} name - 要删除的存储键名 */ deleteValue(name) { GM_deleteValue(name); }, /** * 从 localStorage 获取存储值 * @description 自动解析 JSON 格式内容 * @author 油小猴 * @param {string} key - 存储键名 * @returns {*} 存储的原始值或解析后的对象 */ getStorage(key) { try { return JSON.parse(localStorage.getItem(key)); } catch (e) { return localStorage.getItem(key); } }, /** * 设置 localStorage 存储值 * @author 油小猴 * @description 自动 `JSON.stringify` `对象` `数组` 类型的数据 * @param {string} key - 存储键名 * @param {*} value - 要存储的值 */ setStorage(key, value) { if (this.isType(value) === 'object' || this.isType(value) === 'array') { return localStorage.setItem(key, JSON.stringify(value)); } return localStorage.setItem(key, value); }, /** * 剪贴板写入 * @author 油小猴 * @param {string} text - 要复制的文本内容 */ setClipboard(text) { GM_setClipboard(text, 'text'); }, /** * Base64-URI 编码处理 * @author 油小猴 * @author hmjz100 * @description 自动执行 URI 兼容性编码转换 * @param {string} str - 待编码的字符串 * @returns {string} Base64 编码结果字符串 */ encodeBase(str) { try { str = btoa(str) } catch { } return str; }, /** * Base64-URI 解码处理 * @author 油小猴 * @author hmjz100 * @description 自动执行 URI 兼容性解码转换 * @param {string} str - Base64 编码字符串 * @returns {string} 解码后的原始字符串 */ decodeBase(str) { try { str = decodeURIComponent(str) } catch { } try { str = atob(str) } catch { } try { str = decodeURIComponent(str) } catch { } return str; }, /** * 数字补零格式化 * @author hmjz100 * @description 对 1-9 的数字自动补前导零 * @param {number} i - 待格式化的数字 * @returns {string} 格式化后的字符串(如"05") */ timeFormat(i) { if (i >= 0 && i <= 9) { return "0" + i; } else { return i; } }, /** * 获取文件扩展名并转为大写 * @author 油小猴 * @param {string} name - 完整文件名 * @returns {string} 大写的文件扩展名(如 `TXT`) */ getExtension(name) { const reg = /(?!\.)\w+$/; if (reg.test(name)) { let match = name.match(reg); return match[0].toUpperCase(); } return ''; }, /** * 文件大小格式化 * @author hmjz100 * @description 自动转换单位到最合适的存储单位(如 `1.2MB`) * @param {number} value - 文件字节大小 * @returns {string} 可读格式的大小描述 */ sizeFormat(value) { if (value === +value) { let unit = ["字节(B)", "千字节(KB)", "兆字节(MB)", "吉字节(GB)", "太字节(TB)", "拍字节(PB)", "艾字节(EB)", "泽字节(ZB)", "尧字节(YB)"]; if (value === 0) { return "0字节(B)"; } else { let index = Math.floor(Math.log(value) / Math.log(1024)); let size = value / Math.pow(1024, index); size = size.toFixed(1); return size + unit[index]; } } return ''; }, /** * 将剩余时间(秒)格式化为可读的时间字符串 * * @param {number} remainingTimeSeconds 剩余总秒数(支持小数) * @returns {string} 格式化后的时间字符串,包含以下可能格式: * - "X天 HH时:MM分:SS秒"(超过1天) * - "HH时:MM分:SS秒"(超过1小时) * - "MM分:SS秒"(超过1分钟) * - "SS秒"(1分钟内) * - "即将完成"(0秒时) * - "计算中..."(无效输入时) * * @example * formatRemainingTime(86400) // "1天 00时:00分:00秒" * formatRemainingTime(3661.5) // "01时:01分:01秒" * formatRemainingTime(0) // "即将完成" * formatRemainingTime(-5) // "计算中..." * formatRemainingTime(NaN) // "计算中..." */ rtimeFormat(remainingTimeSeconds) { if (!Number.isFinite(remainingTimeSeconds) || remainingTimeSeconds < 0) { return '计算中...'; } let remainingDays = Math.floor(remainingTimeSeconds / (60 * 60 * 24)); remainingTimeSeconds %= (60 * 60 * 24); let remainingHours = Math.floor(remainingTimeSeconds / (60 * 60)); remainingTimeSeconds %= (60 * 60); let remainingMinutes = Math.floor(remainingTimeSeconds / 60); let remainingSeconds = Math.floor(remainingTimeSeconds % 60); if (remainingDays > 0) { return `${remainingDays}天 ${base.timeFormat(remainingHours)}时:${base.timeFormat(remainingMinutes)}分:${base.timeFormat(remainingSeconds)}秒`; } else if (remainingHours > 0) { return `${base.timeFormat(remainingHours)}时:${base.timeFormat(remainingMinutes)}分:${base.timeFormat(remainingSeconds)}秒`; } else if (remainingMinutes > 0) { return `${base.timeFormat(remainingMinutes)}分:${base.timeFormat(remainingSeconds)}秒`; } else if (remainingSeconds > 0) { return `${remainingSeconds}秒`; } else { return '即将完成'; } }, /** * 文件列表排序 * @author 油小猴 * @description 按中文拼音顺序对文件数组进行排序 * @param {Array} arr - 包含文件对象的数组 * @param {string} arr[].filename - 文件名属性(兼容 server_filename) */ sortByName(arr) { const handle = function () { return (a, b) => { const p1 = a.filename ? a.filename : a.server_filename; const p2 = b.filename ? b.filename : b.server_filename; return p1.localeCompare(p2, "zh-CN"); }; }; arr.sort(handle()); }, /** * 文件名安全处理 * @author 油小猴 * @description 替换非法字符为下划线 * @param {string} name - 原始文件名 * @returns {string} 修正后的安全文件名 */ fixFilename(name) { let replace = /[!?&|`"'*\/:<>\\]/g return name.replace(replace, '_'); }, /** * 获取 Cookie 值 * @author 油小猴 * @param {string} name - Cookie名称 * @returns {string} 对应的 Cookie 值 */ getCookie(name) { let cname = name + "="; let ca = document.cookie.split(';'); for (let i = 0; i < ca.length; i++) { let c = ca[i].trim(); if (c.indexOf(cname) == 0) return c.substring(cname.length, c.length); } return ""; }, /** * Blob 文件下载 * @author 油小猴 * @description 通过创建临时链接实现文件下载 * @param {Blob} blob - 要下载的 Blob 对象 * @param {string} filename - 下载时提示保存的文件名 */ blobDownload(blob, filename) { if (blob instanceof Blob) { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); } }, /** * 可跨域 xmlhttpRequest 请求 * @author hmjz100 * @description 封装 `GreaseMonkey-Compatible_xmlhttpRequest` 实现的跨域请求,与原始函数参数相同 * @param {Object} option - 请求配置对象 * @returns {XMLHttpRequest} 请求对象实例 */ xmlHttpRequest(option) { let request = (typeof GM_xmlhttpRequest !== "undefined") ? GM_xmlhttpRequest : GM.xmlHttpRequest; if (request && typeof request === 'function') { return request(option); } }, /** * 发送 POST 请求 * @author 油小猴 * @author hmjz100 * @description 支持自动重试和数据格式化,内置错误处理,请求数据自动 `JSON.stringify` * @param {string} url - 请求地址 * @param {Object|string} data - 请求数据 * @param {Object} headers - 请求头配置 * @param {string} [type='json'] - 响应类型(支持 `json`, `blob` 等) * @param {number} [maxRetries=3] - 最大重试次数 * @param {number} [currentRetry=0] - 已重试次数(内部使用) * @returns {Promise} 包含响应数据的 `Promise` 对象 */ post(url, data, headers, type, maxRetries = 3, currentRetry = 0) { if (this.isType(data) === 'object') { data = JSON.stringify(data); } return new Promise((resolve, reject) => { const sendRequest = function () { base.xmlHttpRequest({ method: "POST", url, headers, data, responseType: type || 'json', onloadstart() { console.log('【LinkSwift】Post(start)\n请求地址:' + url + '\n请求头部:', headers); }, onload: function (res) { // 尝试格式化请求结果以方便调试 if (res.response) { try { res.decodedResponse = JSON.parse(res.response); } catch (e) { } try { res.decodedResponse = JSON.parse(base.decodeBase(res.response)); } catch (e) { } } if (res.responseText) { try { res.decodedResponseText = JSON.stringify(JSON.parse(res.responseText)); } catch (e) { } try { res.decodedResponseText = JSON.stringify(base.decodeBase(res.responseText)); } catch (e) { } } console.log('【LinkSwift】Post(load)\n请求地址:' + url + '\n请求头部:', headers, '\n请求数据:' + JSON.stringify(data) + '\n请求结果:', res); type === 'blob' ? resolve(res) : resolve(res.response || res.responseText); }, onerror: function (err) { if (currentRetry < maxRetries) { currentRetry++; console.error(`【LinkSwift】Post(error)\n请求出现错误,可能是网络问题\n5秒后将重试 (错误次数:${currentRetry}/${maxRetries})...`, err); setTimeout(function () { console.log(`【LinkSwift】Post(error)\n重新尝试请求...`); sendRequest(); // 重新发送请求 }, 5000) } else { reject('【LinkSwift】Post(error)\n请求出现错误,可能是网络问题\n无法继续请求,达到最大错误次数。', err); // 达到最大重试次数,拒绝 Promise } }, }); }; sendRequest(); // 初始请求 }); }, /** * 发送 GET 请求 * @author 油小猴 * @author hmjz100 * @description 支持进度监控、文件下载和自动重试,可处理被下载工具捕获特殊逻辑 * @param {string} url - 请求地址 * @param {Object} headers - 请求头配置 * @param {string} [type='json'] - 响应类型 * @param {Object} [extra] - 附加参数(需包含 `filename` 和 `index` 属性) * @param {number} [maxRetries=3] - 最大重试次数 * @param {number} [currentRetry=0] - 已重试次数(内部使用) * @returns {Promise} 包含响应数据的 `Promise` 对象 */ get(url, headers, type, extra, maxRetries = 3, currentRetry = 0) { return new Promise((resolve, reject) => { const sendRequest = function () { let requestObj = base.xmlHttpRequest({ method: "GET", url, headers, responseType: type || 'json', onload: function (res) { if (res.status === 204) { console.log('【LinkSwift】Get(load)\n\x1B[31m该请求已被某个下载工具捕获。' + (res.statusText ? ("\n\x1B[0m工具提示:\x1B[31m" + res.statusText) : "") + '\x1B[0m\n请求地址:' + url + '\n请求头部:', headers, '\n请求结果:', res); requestObj.abort(); idm[extra.index] = true; return; } if (type === 'blob') { console.log('【LinkSwift】Get(load) Blob\n请求地址:' + url + '\n请求头部:', headers, '\n请求结果:', res); res.status === 200 && base.blobDownload(res.response, extra.filename); resolve(res); } else { // 尝试格式化请求结果以方便调试 if (res.response) { try { res.decodedResponse = JSON.parse(res.response); } catch (e) { } try { res.decodedResponse = JSON.parse(base.decodeBase(res.response)); } catch (e) { } } if (res.responseText) { try { res.decodedResponseText = JSON.stringify(JSON.parse(res.responseText)); } catch (e) { } try { res.decodedResponseText = JSON.stringify(base.decodeBase(res.responseText)); } catch (e) { } } console.log('【LinkSwift】Get(load)\n请求地址:' + url + '\n请求头部:', headers, '\n请求结果:', res); resolve(res.response || res.responseText); } }, onprogress: function (res) { if (res.status === 204) { console.log('【LinkSwift】Get(progress)\n\x1B[31m该请求已被某个下载工具捕获。' + (res.statusText ? ("\n\x1B[0m工具提示:\x1B[31m" + res.statusText) : "") + '\x1B[0m\n请求地址:' + url + '\n请求头部:', headers, '\n请求结果:', res); requestObj.abort(); idm[extra.index] = true; return; } if (extra && extra.filename && extra.index) { res.total > 0 ? progress[extra.index] = (res.loaded * 100 / res.total).toFixed(2) : progress[extra.index] = 0.00; } }, onloadstart(res) { if (res.status === 204) { console.log('【LinkSwift】Get(start)\n\x1B[31m该请求已被某个下载工具捕获。' + (res.statusText ? ("\n\x1B[0m工具提示:\x1B[31m" + res.statusText) : "") + '\x1B[0m\n请求地址:' + url + '\n请求头部:', headers, '\n请求结果:', res); requestObj.abort(); idm[extra.index] = true; return; } console.log('【LinkSwift】Get(start)\n请求地址:' + url + '\n请求头部:', headers); if (extra && extra.filename && extra.index) request[extra.index] = requestObj; }, onerror: function (err) { if (currentRetry < maxRetries) { currentRetry++; console.error(`【LinkSwift】Get(error)\n请求出现错误,可能是网络问题\n5秒后将重试 (错误次数:${currentRetry}/${maxRetries})...`, err); setTimeout(function () { console.log(`【LinkSwift】Get(error)\n重新尝试请求...`); sendRequest(); // 重新发送请求 }, 5000) } else { reject('【LinkSwift】Get(error)\n请求出现错误,可能是网络问题\n无法继续请求,达到最大错误次数。', err); // 达到最大重试次数,拒绝 Promise } }, }); }; sendRequest(); // 初始请求 }); }, /** * 获取最终重定向 URL(手动处理 30x 跳转) * @author 油小猴 * @author hmjz100 * @description 手动追踪 HTTP 30x 重定向,返回最终访问地址 * @param {string} url - 初始请求地址 * @param {Object} headers - 请求头配置 * @param {number} [maxRetries=3] - 最大重试次数 * @param {number} [currentRetry=0] - 已重试次数(内部使用) * @returns {Promise} 最终 URL 地址 */ getFinalUrl(url, headers, maxRetries = 3, currentRetry = 0) { return new Promise((resolve, reject) => { // 防止无限递归跳转 if (currentRetry >= maxRetries) { return reject(new Error(`【LinkSwift】Head(start) FinalUrl\n达到最大重试次数 ${maxRetries},停止跳转。`)); } base.xmlHttpRequest({ method: "HEAD", url: url, headers: headers, onloadstart: () => { console.log('【LinkSwift】Head(start) FinalUrl\n请求地址:' + url + '\n请求头部:', headers); }, onload: function (res) { console.log('【LinkSwift】Head(load) FinalUrl\n请求地址:' + res.finalUrl + '\n响应状态:' + res.status); let status = res.status; if (status >= 300 && status < 400) { base.getFinalUrl(res.finalUrl, headers, maxRetries, currentRetry + 1).then(resolve).catch(reject); } else { resolve(res.finalUrl); } }, onerror: function (err) { if (currentRetry < maxRetries) { currentRetry++; console.error(`【LinkSwift】Head(error) FinalUrl\n请求出现错误,可能是网络问题\n5秒后将重试 (错误次数:${currentRetry}/${maxRetries})...`); setTimeout(() => { console.log(`【LinkSwift】Head(error) FinalUrl\n重新尝试请求...`); base.getFinalUrl(url, headers, maxRetries, currentRetry) .then(resolve) .catch(reject); }, 5000); } else { reject('【LinkSwift】Get(error) FinalUrl\n请求出现错误,可能是网络问题\n无法继续请求,达到最大错误次数。', err); } } }); }); }, /** * RPC服务测试 * @author hmjz100 * @description 验证 `JSON-RPC` 接口可用性 * @param {string} domain - 服务域名 * @param {string} port - 服务端口 * @param {string} path - RPC 路径 * @param {string} token - 认证令牌 * @returns {Promise<'success'|'fail'>} 连接状态结果 */ async rpcTest(domain, port, path, token) { return new Promise((resolve, reject) => { let rpc = { domain, port, path, token }; let url = `${rpc.domain}:${rpc.port}${rpc.path}`; let rpcData = { id: new Date().getTime(), jsonrpc: '2.0', method: 'system.listMethods', params: [`token:${rpc.token}`], }; base.xmlHttpRequest({ method: "POST", url, headers: {}, data: JSON.stringify(rpcData), responseType: 'json', onloadstart() { console.log('【LinkSwift】Post(start) RPCTest\n请求地址:' + url + '\n请求内容:', rpcData); }, onload: function (res) { console.log('【LinkSwift】Post(load) RPCTest\n请求地址:' + url + '\n请求结果:', res); if (res.response) { resolve("success"); } else { resolve("fail"); } }, onerror: function (err) { console.error('【LinkSwift】Post(error) RPCTest\n请求失败', err); resolve("fail"); }, }); }); }, /** * 重置请求相关数据 * @author 油小猴 * @description 中止所有进行中的请求,清除进度记录和定时器 */ _resetAllData() { progress = {}; $.each(request, function (key) { (request[key]).abort(); }); $.each(ins, function (key) { clearInterval(ins[key]); }); idm = {}; ins = {}; request = {}; }, /** * 重置请求相关数据 * @author 油小猴 * @description 中止指定的进行中的请求,清除进度记录和定时器 */ _resetData(i) { ins[i] && clearInterval(ins[i]); request[i] && request[i].abort(); progress[i] = 0; idm[i] = false; }, /** * 将对象转换为 URL 编码字符串 * @author 油小猴 * @description 递归处理嵌套数组,自动进行 URI 编码 * @param {Object} obj - 待转换的键值对对象 * @returns {string} URL 编码格式字符串(如`key1=value1&key2=value2`) */ stringify(obj) { let str = ''; for (let key in obj) { if (obj.hasOwnProperty(key)) { let value = obj[key]; if (Array.isArray(value)) { for (let i = 0; i < value.length; i++) { str += encodeURIComponent(key) + '=' + encodeURIComponent(value[i]) + '&'; } } else { str += encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&'; } } } return str.slice(0, -1); // 去掉末尾的 "&" }, /** * 动态注入样式表 * @author 油小猴 * @author hmjz100 * @description 支持 `样式标签` `外链CSS` 注入,提供精准的 DOM 定位和插入位置控制 * @param {string} id - 样式元素 ID * @param {'style'|'link'} tag - 标签类型(`style` 或 `link`) * @param {string} css - CSS 内容或外链 URL * @param {string} [element='.{mount}'] - 定位基准元素选择器 * @param {'before'|'after'|'prepend'|'append'} [position='append'] - 插入位置 */ addStyle(id, tag = 'style', css, element = `.${mount}`, position = "append") { base.waitForKeyElements(element, (element) => { let $styleDom = $(`#${id}`); let $style = $(`<${tag}>`, { rel: 'stylesheet', id: id }); tag === 'style' ? $style.html(css) : $style.attr('href', css); if ($styleDom.length) { replacedElements.add(id); $styleDom.replaceWith($style); return true; } if (position === "before") { element.before($style); } else if (position === "after") { element.after($style); } else if (position === "prepend") { element.prepend($style); } else { element.append($style); } return true; }, true); }, /** * 十六进制颜色转 RGBA * @author hmjz100 * @description 支持 4 位和 8 位十六进制格式,自动解析透明度通道 * @param {string} hex - 十六进制颜色值(如 `#09f` 或 `#0099ffaa` ) * @returns {string} RGBA 格式字符串(如 `15, 170, 255, 0.67`) */ hexToRgba(hex) { // 去掉 # 号 hex = hex.replace(/^#/, ''); // 如果是四位十六进制颜色值,转换为八位 if (hex.length === 4) { hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3]; } // 解析 RGB 分量 let r = parseInt(hex.substring(0, 2), 16); let g = parseInt(hex.substring(2, 4), 16); let b = parseInt(hex.substring(4, 6), 16); let a = ''; // 如果是八位十六进制颜色值,解析 alpha 通道 if (hex.length === 8) { a = parseInt(hex.substring(6, 8), 16) / 255; // 将 alpha 值转换为 0 到 1 之间的小数 a = ',' + a } // 返回 rgba 格式字符串 return r + ', ' + g + ', ' + b + a; }, /** * RGBA 颜色转十六进制 * @author hmjz100 * @description 支持透明度转换,自动补全缩写格式 * @param {string} rgba - RGBA 格式颜色值(如 `rgba(15,170,255,0.67)`) * @returns {string} 十六进制颜色值(如 `#09aaffaa`) */ rgbaToHex(rgba) { // 去掉前缀 "rgba" 或 "rgb" 并移除空格 rgba = rgba.replace(/^(rgba?|RGBA?)\(/, '').replace(/\s+/g, '').replace(')', ''); // 将颜色值分割为数组 let [r, g, b, a] = rgba.split(','); // 将 RGB 转换为十六进制 r = parseInt(r).toString(16).padStart(2, '0'); g = parseInt(g).toString(16).padStart(2, '0'); b = parseInt(b).toString(16).padStart(2, '0'); // 如果存在 alpha 通道,处理透明度值 if (a !== undefined) { // 将 alpha 转换为 0 到 255 的十六进制 a = Math.round(parseFloat(a) * 255).toString(16).padStart(2, '0'); return `#${r}${g}${b}${a}`; } // 如果没有 alpha 通道,返回标准六位的十六进制颜色 return `#${r}${g}${b}`; }, /** * 批量替换 CSS 颜色值 * @author hmjz100 * @description 支持全局样式替换和资源路径修正,处理颜色渐变过渡效果 * @param {string} cssText - 原始 CSS 内容 * @param {string} baseURI - 资源基础路径 * @param {'default'|'other'} type - 替换模式(默认模式包含过渡效果) * @param {Array>} colorMap - 颜色映射表(旧颜色 → 新颜色) * @returns {string} 处理后的 CSS 内容 */ replaceColors(cssText, baseURI, type, colorMap) { if (!cssText) return ''; let colorList = ['#09AAFF', '#cc3235', '#518c17', '#ed944b', '#f969a5', '#bca280', '#574AB8', '#b673ab', '#1d2327', '#18a497', '#637dff', '#0d53ff', '#3181f9', '#f8d800', '#0396ff', '#32ccbc', '#f6416c', '#2271b1', '#59524c', '#ff679a', '#f44236', '#fec107', '#8bc24a', '#2594ed', '#9c28b1'] colorList.forEach(function (oldColor) { cssText = cssText.replace(new RegExp(base.hexToRgba(oldColor), 'ig'), base.hexToRgba(color)); cssText = cssText.replace(new RegExp(oldColor, 'ig'), color); }); if (type === 'other') { // 遍历颜色映射数组,将旧颜色替换为新颜色,并添加过渡效果 colorMap.forEach(function (colorPair) { let oldColor = colorPair[0]; let newColor = colorPair[1]; // 判断新颜色是否为 color cssText = cssText.replace(new RegExp(oldColor, 'ig'), newColor); }); return cssText; } if (colorMap) { // 遍历颜色映射数组,将旧颜色替换为新颜色,并添加过渡效果 colorMap.forEach(function (colorPair) { let oldColor = colorPair[0]; let newColor = colorPair[1]; // 判断新颜色是否为 color if (oldColor.includes("#")) { cssText = cssText.replace(new RegExp(oldColor + '(.*?)}', 'ig'), newColor + '$1; ' + 'transition: all 0.1s ease;}'); cssText = cssText.replace(new RegExp(oldColor, 'ig'), newColor); } else { cssText = cssText.replace(new RegExp(oldColor, 'ig'), newColor); } }); }; if (baseURI) { // 替换相对路径资源为绝对路径 cssText = cssText.replace(/url\(\s*(['"]?)([^'"]*?)\1\s*\)/ig, (match, quote, url) => { // 如果 URL 是相对路径,则将其转换为绝对路径 if (url && !/^(data:|https?:|\/\/)/i.test(url)) { try { let absoluteURL = new URL(url, baseURI).href; return `url(${absoluteURL})`; } catch (e) { return match; } } return match; }); } return cssText; }, /** * 全局主题颜色设置 * @author hmjz100 * @description 自动遍历并替换 `页面所有样式表` `SVG 元素` 的颜色值 * @param {Array>} colorMap - 颜色映射表 * @param {'default'|'other'} type - 替换模式 */ setColors(colorMap, type) { base.waitForKeyElements(`[id^="${mount}-ColorUI-"]`, function (tag) { if (tag.html() === base.replaceColors(tag.text(), '', type, colorMap)) return; let cssText = base.replaceColors(tag.text(), '', type, colorMap); base.addStyle(tag.attr("id"), 'style', cssText, tag[0]); return true; }, true) let count = 0; if (!colored) { base.waitForKeyElements('link[rel="stylesheet"]', function (tag) { if (!tag.parent().length || !tag.attr('href')) return; let href = tag.attr('href'); try { href = new URL(href, location.href).href; } catch (e) { return; } fetch(href) .then(response => response.text()) .then(responseText => { let id = `${mount}-ColorUI-` + href.replace(/[^\w]/g, "_"); let cssText = base.replaceColors(responseText, href, type, colorMap); if (responseText === base.replaceColors(responseText, '', type, colorMap)) return; base.addStyle(id, 'style', cssText, tag[0], "after"); console.log(`【LinkSwift】UI\n覆盖原始 样式\n原始:`, tag[0]); }) }, true); base.waitForKeyElements(`style:not([id^="${mount}-"],[id^="swal-pub"],[class^="darkreader"])`, function (tag) { let id = tag.attr("id"); let text = tag.html() if (tag.data("styles") === text) return; tag.data("styles", text); // 替换颜色并添加样式 let cssText = base.replaceColors(text, '', type, colorMap); if (text === cssText) return; id = id ? id : `${mount}-ColorUI-${count++}` base.addStyle(id, 'style', cssText, tag[0], "after"); console.log(`【LinkSwift】UI\n覆盖原始 `, allowOutsideClick: false, showCloseButton: true, confirmButtonText: '我已阅', ...swalDefault }); }, /** * 创建浮动提示框 * @description 监听元素悬停事件,动态显示带文件大小的提示框 * @author 油小猴 * @author hmjz100 * @fires .listener-tip - 鼠标移动事件触发提示框定位 * @see {@link color} 使用全局主题色渲染文件大小信息 */ createTip() { // 添加提示框到 body $('html').append('
'); // 监听所有带有 .listener-tip 类的元素的鼠标移动事件 $(document).on('mousemove', '.listener-tip', function (e) { // 获取提示文字 let tip = e.currentTarget.dataset.title || `${e.currentTarget.innerText} ${e.currentTarget.dataset.size}`; // 设置提示框的位置并使用 fadeIn() 渐变显示 $('.pl-tooltip').html(tip).css({ 'left': e.pageX + 10 + 'px', 'top': e.pageY + 20 + 'px' // 增加一些间距 }).show(); }); $(document).on('mouseleave', '.listener-tip, .pl-tooltip', function (e) { $('.pl-tooltip').hide(); }); }, /** * 创建加载状态弹窗 * @author 油小猴 * @description 生成包含旋转动画的加载容器 */ createLoading() { return $('
'); }, /** * 创建用于下载的隐藏 iframe * @author 油小猴 * @description 该方法会创建一个隐藏的 iframe 元素,并将其插入到指定的挂载点中,用于后续的下载操作。 * iframe 的 src 设置为 "javascript:;" 以避免加载额外资源,提升性能。 */ createDownloadIframe() { let iframe = $(''); base.waitForKeyElements(`.${mount}`, (element) => { element.append(iframe); }, true) }, /** * 获取镜像列表 * @author 油小猴 * @description 根据原始链接和镜像域名列表生成多个镜像链接,支持多线程下载。 * 每个镜像地址会根据 thread 参数生成多个重复链接(通过添加 `&` 符号区分)。 * @param {string} link - 原始下载链接 * @param {Array} mirror - 镜像域名数组 * @param {number} [thread=2] - 每个镜像生成的线程数(链接重复次数),默认为 2 * @returns {string} 所有镜像链接组成的字符串,每行一个链接 * * @example * getMirrorList("https://example.com/file.zip", ["mirror1.com", "mirror2.com"], 2) * // 返回: * // https://mirror1.com/file.zip * // https://mirror1.com/file.zip& * // https://mirror2.com/file.zip * // https://mirror2.com/file.zip& */ getMirrorList(link, mirror, thread = 2) { let host = new URL(link).host; let mirrors = []; for (let i = 0; i < mirror.length; i++) { for (let j = 0; j < thread; j++) { let item = link.replace(host, mirror[i]) + '&'.repeat(j); mirrors.push(item); } } return mirrors.join('\n'); }, /** * 创建基础样式 * @author 油小猴 * @author hmjz100 * @description 为组件添加默认的公共样式,包括浅色和深色模式适配样式。 */ addPanLinkerStyle() { color = base.getValue('setting_theme_color'); base.addStyle('swal-pub-style', 'style', `@media (prefers-color-scheme: light) {${GM_getResourceText('SwalLigt')}}`); base.addStyle('swal-pub-dark-style', 'style', `@media (prefers-color-scheme: dark) {${GM_getResourceText('SwalDark')}}`); base.addStyle('swal-pub-custom-style', 'style', ` .swal2-styled{transition: all 0.2s ease;} .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 } .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px} .swal2-timer-progress-bar{width:100%;height:.25em;background:${color}33 } .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:${color};color:#fff;line-height:2em;text-align:center} .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:${color} } .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:${color}} .swal2-html-container {padding:1em 1.6em 0.3em;margin:0} .swal2-close,div:where(.swal2-container) button:where(.swal2-close) {position:absolute;top:1px;right:1px;transition: all 0.2s ease} .swal2-close:hover,div:where(.swal2-container) button:where(.swal2-close):hover {color:${color};font-size:60px} .swal2-styled.swal2-confirm,div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){background-color:${color};color:#fff} .swal2-styled.swal2-confirm:focus,div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):focus{box-shadow:0 0 0 3px ${color}80} .swal2-styled.swal2-deny:focus,.swal2-close:focus,div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):focus{box-shadow:0 0 0 3px #dc374180} .swal2-styled.swal2-cancel:focus,div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):focus{box-shadow:0 0 0 3px #6e788180} .swal2-styled.swal2-confirm, .swal2-styled.swal2-deny, .swal2-styled.swal2-cancel, div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm), div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny), div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel) {border-radius:50px} div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:hover{opacity:0.7} .swal2-popup,div:where(.swal2-container) div:where(.swal2-popup){padding-bottom:1em;border-radius:10px} div:where(.swal2-container) div:where(.swal2-html-container){padding:1.3em 1.3em 0.3em;margin:0} .swal2-footer,div:where(.swal2-container) div:where(.swal2-footer){flex-direction:column;justify-content:center;align-items:center} div:where(.swal2-icon) .swal2-icon-content {font-family: sans-serif;} .swal2-input, .swal2-file, swal2-select, .swal2-textarea, div:where(.swal2-container) input:where(.swal2-input), div:where(.swal2-container) input:where(.swal2-file), div:where(.swal2-container) input:where(.swal2-select), div:where(.swal2-container) textarea:where(.swal2-textarea) {box-shadow:none} .swal2-input:focus, .swal2-file:focus, .swal2-select:focus, .swal2-textarea:focus, .swal2-input:focus-visible, .swal2-file:focus-visible, .swal2-select:focus-visible, .swal2-textarea:focus-visible, div:where(.swal2-container) input:where(.swal2-input):focus, div:where(.swal2-container) input:where(.swal2-input):focus-visible, div:where(.swal2-container) input:where(.swal2-file):focus, div:where(.swal2-container) input:where(.swal2-file):focus-visible, div:where(.swal2-container) input:where(.swal2-select):focus, div:where(.swal2-container) input:where(.swal2-select):focus-visible, div:where(.swal2-container) textarea:where(.swal2-textarea):focus, div:where(.swal2-container) textarea:where(.swal2-textarea):focus-visible {outline:0;border:1px solid ${color};box-shadow:0 0 0 3px ${color}80} .swal2-checkbox, .swal2-file, .swal2-input, .swal2-radio, .swal2-select, .swal2-textarea, div:where(.swal2-container) input:where(.swal2-input), div:where(.swal2-container) input:where(.swal2-file), div:where(.swal2-container) textarea:where(.swal2-textarea), div:where(.swal2-container) select:where(.swal2-select), div:where(.swal2-container) div:where(.swal2-radio), div:where(.swal2-container) label:where(.swal2-checkbox) {margin: 1em 2em}`); base.addStyle(`${mount}-main-style`, 'style', ` ::-webkit-scrollbar{width:8px;height:8px;transition:all 0.2s ease} ::-webkit-scrollbar-track{border-radius:10px;background:#fff} ::-webkit-scrollbar-thumb,::-webkit-scrollbar-thumb:hover{border-radius:10px} ::-webkit-scrollbar-thumb{background-color:${color}90 !important} ::-webkit-scrollbar-thumb:hover{background-color:${color}D0 !important} .swal2-popup{font-size:16px} .pl-a{vertical-align:baseline;color:${color}} .pl-a:hover{color:${color}90} .pl-popup{font-size:12px;min-width:70%;max-width:95%} .pl-popup a:not(.pl-btn-primary){color:${color}} .pl-popup a:hover:not(.pl-btn-primary){color:${color}90} .pl-header{padding:0;align-items:flex-start;border-bottom:1px solid #eee;margin:0 0 10px;padding:0 0 5px} .pl-title{font-size:18px;white-space:nowrap;text-overflow:ellipsis} .pl-content{padding:0;font-size:12px} .pl-main{background-color:${color}15;overflow:auto;border-radius:10px;max-height:calc(${document.documentElement.clientHeight}px - 250px)} .pl-footer{font-size:15px;text-align:center;display:block} .pl-item{display:flex;align-items:center;background-color:${color}30;border-radius:5px;margin:8px 6px} .pl-item-name{flex:0 0 170px;text-align:left;margin:6px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:default;height:30px} .pl-item-link{flex:1;text-align:left;white-space:nowrap;text-overflow:ellipsis;cursor:pointer;overflow:hidden} .pl-item-tip{display:flex;justify-content:space-between;flex:1} .pl-ext{display:inline-block;width:44px;background:#999;color:#fff;height:16px;line-height:16px;font-size:12px;border-radius:3px} .pl-retry{padding:3px 10px;background:#cc3235;color:#fff;border-radius:3px;cursor:pointer} .pl-item-progress{display:flex;flex:1;align-items:center} .pl-progress{display:inline-block;vertical-align:middle;width:100%;box-sizing:border-box;line-height:1;position:relative;height:20px;margin:0 6px;flex:1} .pl-progress-outer{height:20px;border-radius:100px;background-color:#c1c1c1a1;overflow:hidden;position:relative;vertical-align:middle} .pl-progress-inner{position:absolute;left:0;top:0;background-color:${color};border-radius:100px;line-height:1;white-space:nowrap;transition:width .6s ease;height:20px;display:inline-flex;text-align:center;align-items:center} .pl-progress-inner-text{display:inline-block;vertical-align:middle;cursor:default;color:#ffffff;font-size:12px;margin:0 5px;height:20px;width:100%} .pl-progress-inner-text:after{display:inline-block;content:"";height:100%;vertical-align:middle} .pl-extra{margin-top:10px;background-color:${color}15;border-radius:10px;display:flex} .pl-extra button{flex:1} .pl-btn-primary{background:${color};border:0;border-radius:50px;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} .pl-btn-primary:hover{opacity:0.8;transition:0.3s opacity} .pl-btn-primary:focus{box-shadow:0 0 0 3px ${color}80} .pl-btn-success{background:#55af28} .pl-btn-success:focus{box-shadow:0 0 0 3px #55af2880} .pl-btn-info{background:#606266} .pl-btn-info:focus{box-shadow:0 0 0 3px #60626680} .pl-btn-warning{background:#da9328} .pl-btn-warning:focus{box-shadow:0 0 0 3px #da932880} .pl-btn-danger{background:#cc3235} .pl-btn-danger:focus{box-shadow:0 0 0 3px #cc323580} @keyframes easeOpacity { from {opacity: 1} 50% {opacity: 0.35} to {opacity: 1} } .pl-btn-opacity{animation:easeOpacity 1.2s 2;animation-fill-mode:forwards} .pl-button-mini{padding:5px 10px} .pl-dropdown-menu-item{height:30px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:${color};transition:all 0.2s ease} .pl-dropdown-menu-item:hover{background-color:${color}15} .pl-button-mode{padding:0px;padding-left:0px !important;color:${color}!important;cursor:pointer;;transition:all 0.2s ease} .pl-button-mode:hover{background-color:${color}33 !important} .g-button-menu.pl-button-mode{padding:0px !important} .pl-button,.pl-dropdown-menu{transition:all 0.2s ease} .pl-button{position:relative} .pl-button .pl-dropdown-menu{opacity:0;pointer-events:none} .pl-button:hover .pl-dropdown-menu{opacity:1;pointer-events:auto} @keyframes easeInitOpacity { from {opacity: 0.5} 50% {opacity: 1} to {opacity: 0.5} } .pl-button-init{opacity:0.5;animation:easeInitOpacity 1.2s 5;animation-fill-mode:forwards} header[style="display:none;"]~.pl-button{display:inline-block;position:fixed;top:0.6em;left:65%;z-index:99999} .baidu-button{background:${color}!important;border-color:${color}!important;border:1px solid ${color}!important;display:inline-flex} .baidu-button:hover{background:${color}b0 !important;border-color:${color}!important} .ali-button{background:${color};border:0 solid transparent;font-size:14px;margin-left:20px;padding:8px 16px;position:relative;height:32px;border-radius:100px;display:flex;align-items:center;justify-content:center;color:var(--basic_white);cursor:pointer;transition:all .3s ease} .ali-button:hover{background:${color}D0} .ali-btn-icon{vertical-align:-0.2em} .tcloud-button{color:#fff;border:1px solid ${color};background:${color};position:relative;height:30px;padding:0 12px;margin-right:12px;font-size:12px;line-height:28px;cursor:pointer} .tcloud-button:hover{border-color:${color}b0;background:${color}b0} .mcloud-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} .mcloud-share-button{display:inline-block;position:relative;font-size:14px;line-height:36px;height:36px;text-align:center;color:#fff;border:1px solid ${color};border-radius:2px;padding:0 24px;background:${color}} .mcloud-share-button:hover{background:${color}b0} .mcloud-button:hover{background:${color}b0} .mcloud-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} .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} .xunlei-button:hover{background:${color}b0} .quark-button,.uc-button{padding:0 14px;background:${color}!important;background-color:${color}!important} .uc-button{padding:10px 20px!important} .quark-button:hover,.uc-button:hover{background:${color}b0 !important;background-color:${color}b0 !important} .quark-btn-icon,.uc-btn-icon{width:20px;height:20px;vertical-align:-0.3em} .pointer{cursor:pointer} .pl-setting-label{display:flex;align-items:center;justify-content:space-between;padding-top:10px} .pl-label{flex:0 0 100px;text-align:left} .pl-input{flex:1;padding:8px 10px!important;border:1px solid #c2c2c2;border-radius:5px;font-size:14px!important;min-width:300px;margin:0;} .init-input{width:90%;text-align:center;font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Ubuntu,"Helvetica Neue",sans-serif;font-weight:300} .pl-color{flex:1;display:flex;flex-wrap:wrap} .pl-color-box{width:55px;height:55px;margin:10px 10px 0 0;box-sizing:border-box;border:1px solid #fff;cursor:pointer} .pl-mask{width:53px;height:53px;opacity:0;transition:opacity 0.3s;color:#fff;font-size:13px;display:flex;align-items:center;justify-content:center;flex-direction:column} .pl-color-box:hover .pl-mask{opacity:1} .pl-close:focus{outline:0;box-shadow:none} .tag-danger{color:#cc3235;margin:0 5px} .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} .pl-loading-box>div>div{position:absolute;border-radius:50%} .pl-loading-box>div>div:nth-child(1){top:9px;left:9px;width:82px;height:82px;background:#ffffff} @keyframes load{ 0% {transform: rotate(0deg)} 100% {transform: rotate(360deg)} } .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} .pl-loading{width:16px;height:16px;display:inline-block;overflow:hidden;background:none} .pl-loading-box{width:100%;height:100%;position:relative;transform:translateZ(0) scale(0.16);backface-visibility:hidden;transform-origin:0 0} .pl-loading-box div{box-sizing:content-box} .pl-dropdown-menu{position:absolute;padding:5px 0;color:${color};background:#fff;z-index:999;width:110px;border-radius:5px;box-shadow:0 1px 6px ${color}33;-webkit-box-shadow:0 1px 6px ${color}33;text-align:center;border:none;transition:all 0.2s ease} @media (prefers-color-scheme: dark) { .pl-dropdown-menu{background:#19191a;} } .pl-button-save{background-color:${color}!important;color:#fff !important} .pl-button-save:hover{background-color:${color}D0 !important;color:#fff !important} .swal2-container{z-index:100000} body.swal2-height-auto{height:inherit} svg.icon-rpc-devices{width:13px;height:13px} [class^="swal2-"],[class*="pl-btn"]{transition:all 0.3s ease} /* 适配(改)百度网盘会员青春版 */ a.downloadSubtitle, button.downloadSubtitle{transition:all 0.3s ease;background-color:${color}} a.downloadSubtitle:hover, button.downloadSubtitle:hover{background-color:${color}D0} a.downloadSubtitle:disabled, button.downloadSubtitle:disabled {background-color: ${color}D0} /* RGB! */ @keyframes RGB{ 0% {filter: hue-rotate()} to {filter: hue-rotate(-360deg)} } /* Webkit, Opera, IE9, Chrome*/ ::selection, ::-webkit-selection, ::-moz-selection, ::-ms-selection,::-edge-selection {background-color:${color}!important;background:${color}!important;color:white!important;} `); if (/(pan|yun).baidu.com/.test(location.host) && location.pathname !== '/disk/home' && base.getValue('setting_theme_baidu') === 'yes') { base.setColors([ ['#717fff', color], ['#717FFF', color], ['#06a8ff', color], ['#06A8FF', color], ['#06a7ff', color], ['#06A7FF', color], ['#dcdfe6', color], ['#DCDFE6', color], ['#0095ff', color], ['#0095FF', color], ['#09aaff', color], ['#09AAFF', color], ['#0ca6ff', color], ['#0CA6FF', color], ['#5040ff', color], ['#5040FF', color], ['#454d5a', color], ['#454D5A', color], ['#a2abbd', color], ['#A2ABBD', color], ['#030b1a', color], ['#030B1A', color], ['#afb3bf', color], ['#AFB3BF', color], ['#ff436a', color], ['#FF436A', color], ['#03081a', color], ['#03081A', color], ['#2974b6', color], ['#2974B6', color], ['#0596e6', color], ['#0596E6', color], ['#C3EAFF', color], ['#c0d9fe', `${color}50`], ['#0098EA', `${color}D0`], ['#38b9ff', `${color}D0`], ['#38B9FF', `${color}D0`], ['#42d8ff', `${color}D0`], ['#42D8FF', `${color}D0`], ['#a48dff', `${color}D0`], ['#A48DFF', `${color}D0`], ['#6b79f2', `${color}D0`], ['#6B79F2', `${color}D0`], ['#9c86f2', `${color}90`], ['#9C86F2', `${color}90`], ['#83d3ff', `${color}90`], ['#83D3FF', `${color}90`], ['#C4D8F4', `${color}90`], ['#fafafc', `${color}20`], ['#FAFAFC', `${color}20`], ['#f5fbff', `${color}20`], ['#F5FBFF', `${color}20`], ['#b4e5ff', `${color}20`], ['#B4E5FF', `${color}20`], ['#f0faff', `${color}20`], ['#F0FAFF', `${color}20`], ['#c4d8f4', `${color}20`], ['#f1f3f8', `${color}15`], ['#F1F3F8', `${color}15`], ['#f2faff', `${color}10`], ['#F2FAFF', `${color}10`], ['#eef9fe', `${color}10`], ['#EEF9FE', `${color}10`], ['#f7f9fc', `${color}10`], ['#F7F9FC', `${color}10`], ['#f5f6fa', `${color}10`], ['#F5F6FA', `${color}10`], ['#b4e5ff', `${color}10`], ['#B4E5FF', `${color}10`], ['#e6f6ff', `${color}10`], ['#E6F6FF', `${color}10`], ['0,149,255', base.hexToRgba(color)], ['30, 175, 255', base.hexToRgba(color)], ['6, 167, 255, 0.1', base.hexToRgba(`${color}1a`)], ['6,167,255,.1', base.hexToRgba(`${color}1a`)], ['6,167,255,.23', base.hexToRgba(`${color}3b`)], ['164,141,255,.2', base.hexToRgba(`${color}30`)], ['196,182,255,.2', base.hexToRgba(`${color}20`)], ['113,127,255,.2', base.hexToRgba(`${color}40`)], ['3,8,26,.6', base.hexToRgba(`${color}D0`)], ['255,32,102,.4', base.hexToRgba(`${color}66`)], ['72,166,248,.7', base.hexToRgba(`${color}66`)], ]); }; if (/(pan|yun).baidu.com/.test(location.host) && base.getValue('setting_theme_baidu') === 'yes') { base.addStyle(`${mount}-baidu`, 'style', ` #layoutMain, .DxdbeCb { border-radius: 10px; border-bottom-left-radius: 0; border-bottom-right-radius: 0; background: #ffffffA0 !important } .KPDwCE, .DxdbeCb .OFaPaO .tanwePYr, .xGLMIab .fufHyA:hover, .module-search-timeline .form-box { background: #ffffffA0 !important; } .KPDwCE .JDeHdxb, .NHcGw .AuPKyz, .xGLMIab .tvPMvPb, .xGLMIab .FcQMwt, .cazEfA .yfHIsP, .hscjZ4QL .bbxnZ0Bq .ehnyLxWZ span, .module-topToolBar, .module-timeline-view .timeline-title-curday { background: transparent !important; border-bottom: 0; } .MdLxwM { background :#fff !important; } .aside-absolute-container { position: absolute !important; } .aside-absolute-container .QGOvsxb .remainingSpaceUi_span { background: #8af248 !important; border-radius: 10px 0 0 10px; border-right: #fff 1px solid; border-bottom: #fff 1px solid; } .xtJbHcb .CDaavKb .KQcHyA { background: rgb(244,207,0) !important; padding: 8px 15px; } .xtJbHcb .web-header-nav-new-version-inner { background: ${color} !important; padding: 8px 15px; line-height: 15px; width: auto; height: auto; } a { transition: all 0.2s ease !important; } #bd-main .bd-left { margin: auto !important; } .verify-input input { padding-left: 0 !important; text-align: center !important; } .verify-input input:focus { border: 2px solid ${color} !important; } [data-theme=light] .vp-video-page-card .vp-video-page-card__video-detail { color: #030b1a; } dt.level-1 { background: #fd6d65 !important; } dt.level-2 { background: #f3a723 !important; } dt.level-1 i.desc-arrow { border-bottom: 10px solid #dd6966 !important; } dt.level-2 i.desc-arrow { border-bottom: 10px solid #d29633 !important; } `, `.${mount}`); base.setColors([ ['#717fff', color], ['#717FFF', color], ['#06a8ff', color], ['#06A8FF', color], ['#06a7ff', color], ['#06A7FF', color], ['#dcdfe6', color], ['#DCDFE6', color], ['#0095ff', color], ['#0095FF', color], ['#09aaff', color], ['#09AAFF', color], ['#0ca6ff', color], ['#0CA6FF', color], ['#5040ff', color], ['#5040FF', color], ['#454d5a', color], ['#454D5A', color], ['#a2abbd', color], ['#A2ABBD', color], ['#030b1a', color], ['#030B1A', color], ['#afb3bf', color], ['#AFB3BF', color], ['#ff436a', color], ['#FF436A', color], ['#03081a', color], ['#03081A', color], ['#2974b6', color], ['#2974B6', color], ['#0596e6', color], ['#0596E6', color], ['#C3EAFF', color], ['#c0d9fe', `${color}50`], ['#0098EA', `${color}D0`], ['#38b9ff', `${color}D0`], ['#38B9FF', `${color}D0`], ['#42d8ff', `${color}D0`], ['#42D8FF', `${color}D0`], ['#a48dff', `${color}D0`], ['#A48DFF', `${color}D0`], ['#6b79f2', `${color}D0`], ['#6B79F2', `${color}D0`], ['#9c86f2', `${color}90`], ['#9C86F2', `${color}90`], ['#83d3ff', `${color}90`], ['#83D3FF', `${color}90`], ['#C4D8F4', `${color}90`], ['#fafafc', `${color}20`], ['#FAFAFC', `${color}20`], ['#f5fbff', `${color}20`], ['#F5FBFF', `${color}20`], ['#b4e5ff', `${color}20`], ['#B4E5FF', `${color}20`], ['#f0faff', `${color}20`], ['#F0FAFF', `${color}20`], ['#c4d8f4', `${color}20`], ['#f1f3f8', `${color}15`], ['#F1F3F8', `${color}15`], ['#f2faff', `${color}10`], ['#F2FAFF', `${color}10`], ['#eef9fe', `${color}10`], ['#EEF9FE', `${color}10`], ['#f7f9fc', `${color}10`], ['#F7F9FC', `${color}10`], ['#f5f6fa', `${color}10`], ['#F5F6FA', `${color}10`], ['#b4e5ff', `${color}10`], ['#B4E5FF', `${color}10`], ['#e6f6ff', `${color}10`], ['#E6F6FF', `${color}10`], ['0,149,255', base.hexToRgba(color)], ['30, 175, 255', base.hexToRgba(color)], ['6, 167, 255, 0.1', base.hexToRgba(`${color}1a`)], ['6,167,255,.1', base.hexToRgba(`${color}1a`)], ['6,167,255,.23', base.hexToRgba(`${color}3b`)], ['164,141,255,.2', base.hexToRgba(`${color}30`)], ['196,182,255,.2', base.hexToRgba(`${color}20`)], ['113,127,255,.2', base.hexToRgba(`${color}40`)], ['3,8,26,.6', base.hexToRgba(`${color}D0`)], ['255,32,102,.4', base.hexToRgba(`${color}66`)], ['72,166,248,.7', base.hexToRgba(`${color}66`)], ], "other"); }; if (/www.(aliyundrive|alipan).com/.test(location.host) && base.getValue('setting_theme_ali') === 'yes') { base.setColors([ ['#3763ff', color], ['#8664ff', `${color}D0`], ['99, 125, 255', base.hexToRgba(color)], ['132, 133, 141', base.hexToRgba(color)], ['112, 136, 255', base.hexToRgba(color)], ['97, 122, 250', base.hexToRgba(color)], ['68, 109, 255', base.hexToRgba(color)], ['82, 110, 250', base.hexToRgba(`${color}20`)], ['122, 144, 255', base.hexToRgba(`${color}D0`)], ['138, 157, 255', base.hexToRgba(`${color}D0`)], //['49, 49, 54', base.hexToRgba(color)], ]); }; if (/(yun|caiyun).139.com/.test(location.host) && base.getValue('setting_theme_mcloud') === 'yes') { base.setColors([ ['#3181f9', color], ['#5a9afa', color], ['#98c0fc', `${color}D0`], ['#2d76e5', `${color}D0`], ['49,129,249,.08', base.hexToRgba(`${color}20`)], ]); }; if (/cloud.189.cn/.test(location.host) && base.getValue('setting_theme_tcloud') === 'yes') { base.setColors([ ['#2b89ea', color], ['#1874d3', `${color}F0`], ['#1890ff', color], ['#388fc9', color], ['#0087ff', color], ['#255697', color], ['#3ea6ff', `${color}80`], ['#1d52f2', color], ['#3699ff', `${color}D0`], ['#f4f9fe', `${color}10`], ['#eaf5ff', `${color}20`], ], "other"); } if (/pan.xunlei.com/.test(location.host) && base.getValue('setting_theme_xunlei') === 'yes') { base.setColors([ ['#3f85ff', color], ['63,133,255,.1', base.hexToRgba(`${color}20`)], ['#2670ea', `${color}D0`], ['#619bff', `${color}D0`], ['#ecf3ff', `${color}10`], ['#f6faff', `${color}10`], ['#1a2845', `${color}20`], ['#0f2035', `${color}20`], ['#308bfd', `${color}20`], ['#eee', `${color}20`], ], "other"); base.addStyle(`${mount}-xunlei`, 'style', ` .web-header { background: linear-gradient(0deg,${color}D0,${color}) } `); }; if (/pan.quark.cn/.test(location.host) && base.getValue('setting_theme_quark') === 'yes') { base.setColors([ ['#0d53ff', color], ['#e6f1ff', `${color}20`], ['#f0faff', `${color}20`], ['#7da3ff', `${color}D0`], ['#ddd', `${color}D0`], ['17,17,17,.9', base.hexToRgba(`${color}D0`)], ['40,40,255,.04', base.hexToRgba(`${color}20`)], ['#f7f7ff', 'transparent'], ['238,247,255,0', base.hexToRgba(`${color}00`)], ]); base.addStyle(`${mount}-quark`, 'style', ` .file-list .hover-oper .hover-transparent-bg { background: transparent !important; } .ant-checkbox-wrapper .ant-checkbox-checked .ant-checkbox-inner, .ant-checkbox-wrapper .ant-checkbox-indeterminate .ant-checkbox-inner:after { background-color: ${color}!important; } `); }; if (/drive.uc.cn/.test(location.host) && base.getValue('setting_theme_uc') === 'yes') { base.setColors([ ['#12161a', color], ['#e6f1ff', `${color}20`], ['#f0faff', `${color}20`], ['#7da3ff', `${color}D0`], ['#ddd', `${color}D0`], ['17,17,17,.9', base.hexToRgba(`${color}D0`)], ['40,40,255,.04', base.hexToRgba(`${color}20`)], ['#f7f7ff', 'transparent'], ['238,247,255,0', base.hexToRgba(`${color}00`)], ]); base.addStyle(`${mount}-uc`, 'style', ` .file-list .hover-oper .hover-transparent-bg { background: transparent !important; } `); }; if (/www.(123(pan|684|865|952|912).com|123pan.cn)/.test(location.host) && base.getValue('setting_theme_123') === 'yes') { base.setColors([ ['#597dfc', color], ['#5a7cfc', color], ['#2A82E4', color], ['#51a1f0', color], ['#597DFC', color], ['#40a9ff', color], ['#3c80ff', color], ['#3C80FF', color], ['#1890ff', color], ['#f0f9ff', `${color}20`], ['#F2F5FF', `${color}20`], ['#325cf0', `${color}D0`], ['60, 128, 255', base.hexToRgba(color)], ['42, 130, 228', base.hexToRgba(color)], ]); } if (/.*.youxiaohou.com/.test(location.host)) { base.setColors([ ['#00aefe', color], ['#4e6e8e', color], ['#009fe8', color], ['#008fd1', color], ['#05b0ff', `${color}D0`], ], "other"); base.addStyle(`${mount}-youxiaohou`, 'style', ` a[aria-label="View source on GitHub"] svg[style^="fill"] { fill: ${color} !important; } `); }; }, /** * 初始化引导弹窗 * @author 油小猴 * @author hmjz100 * @description 显示初始化对话框,引导用户进行配置或跳过流程。 * 支持输入特定数字触发彩蛋,并自动注入默认设置点亮功能。 * @returns {Promise} 弹窗关闭后返回空值,可能触发页面刷新 */ async initDialog() { let dialog = await Swal.fire({ title: `请阅读完以下全文再继续`, allowOutsideClick: false, showCloseButton: true, showDenyButton: true, confirmButtonText: '确认', denyButtonText: '懒得输入...我要直接点亮!', html: `
${config.base.service.account ? `` : ``}
你心想道: “没什么可以输入的”
但你不知道的是...
你可以直接按下下方的红色按钮来跳过这一有趣的流程
或者继续流程,输入某些恶臭的数字查看彩蛋并点亮
原作者开发很辛苦,所以请有能力的你请支持下他的公众号
又或者...来给这个改版点个Star
点亮后不仅能精简网盘界面 还能改变众多网盘主题色哦!
`, ...swalDefault }); if (dialog.isDenied) { console.log("【LinkSwift】\n正在“注入”点亮按钮设置项目..."); message.warning("正在“注入”设置项目..."); await base.sleep(2500); base.setValue('setting_init_code', config.base.num); base.setValue('setting_init_license', config.base.license); message.success("“注入”成功了!"); await base.sleep(1500); location.reload(); }; if (dialog.isConfirmed) { if ($('#init').val() === '114514' || $('#init').val() === '1919810' || $('#init').val() === '1145141919810') { await Swal.fire({ icon: 'error', title: '1145141919810', html: 'homo特有的数字当然不行啦
哼哼哼啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
', timer: 4000, imageUrl: 'https://pic1.zhimg.com/v2-1b97a088e156c015108dec663bba8b04.avis', allowOutsideClick: false, timerProgressBar: true, showConfirmButton: false, showDenyButton: true, denyButtonText: '哼哼哼啊啊啊啊啊啊啊啊啊啊', ...swalDefault }); message.info("成就:你触发了一个homo特有的彩蛋!"); await base.sleep(4000) Swal.fire({ title: '1145141919810', text: 'homo特有的数字当然不行啦...吗?', icon: 'question', imageUrl: 'https://lh1.hetaousercontent.com/img/7d4c1c0b4adb0e95.jpg', showConfirmButton: false, allowOutsideClick: false, ...swalDefault }); await base.sleep(3000) base.setValue('setting_init_code', config.base.num); base.setValue('setting_init_license', config.base.license); message.success("成就:哼哼哼啊啊啊啊啊啊啊啊地注入成功(喜)"); await base.sleep(1500) location.reload(); } else { console.log("【LinkSwift】\n暗号错误") await this.initDialog(); return; }; } }, /** * 显示主对话框 * @author 油小猴 * @author hmjz100 * @description 使用 SweetAlert2 显示一个自定义样式的对话框,用于展示信息或操作提示。 * @param {string} title - 对话框标题 * @param {string} html - 对话框内容的 HTML 字符串 * @param {string} footer - 对话框底部说明文字 */ showMainDialog(title, html, footer) { Swal.fire({ title, html, footer: `${footer}`, customClass, confirmButtonText: '关闭', showCloseButton: true, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, willClose: function () { base._resetAllData(); }, ...swalDefault }).then(function () { base._resetAllData(); }); }, /** * 等待指定元素加载完成并执行回调 * @author hmjz100 * @description 监听 DOM 元素是否出现,若未出现则每隔一段时间重试,直到找到为止。 * 支持在 iframe 内部查找元素,适用于异步加载场景。 * @param {string} selectorElem - 要等待的目标元素选择器 * @param {Function} actionFunction - 找到元素后执行的回调函数,接收 jQuery 元素作为参数,返回 true 可以不再继续寻找 * @param {boolean} [bWaitOnce=false] - 是否只执行一次回调,默认为 false,如果不设置为 true 的话需要自行判断是否对元素进行操作 * @param {string} [iframeSelector] - 若目标元素位于 iframe 中,传入 iframe 的选择器 * @param {string} [controlKey] - 控制唯一性的键名,用于避免重复处理 */ waitForKeyElements(selectorElem, actionFunction, bWaitOnce, iframeSelector, controlKey) { if (!this.waitForKeyElements.controlObj) { this.waitForKeyElements.controlObj = {}; } if (!this.waitForKeyElements.instanceCounter) { this.waitForKeyElements.instanceCounter = 0; } let targetNodes; if (typeof iframeSelector === "undefined") { targetNodes = $(selectorElem); } else { targetNodes = $(iframeSelector).contents().find(selectorElem); } let controlKeyNew = controlKey || `wkfe_${this.waitForKeyElements.instanceCounter++}`; let btargetsFound = false; if (targetNodes && targetNodes.length > 0) { targetNodes.each(function () { let jThis = $(this); let alreadyFound = jThis.data(controlKeyNew) || false; if (!alreadyFound) { var cancelFound = actionFunction(jThis); if (cancelFound) { btargetsFound = true; } else if (bWaitOnce) { jThis.data(controlKeyNew, true); } } }); } let controlObj = this.waitForKeyElements.controlObj; let timeControl = controlObj[controlKeyNew]; if (btargetsFound && bWaitOnce && timeControl) { clearInterval(timeControl); delete controlObj[controlKeyNew]; } else if (!timeControl) { timeControl = setInterval(() => { this.waitForKeyElements(selectorElem, actionFunction, bWaitOnce, iframeSelector, controlKeyNew); }, 1000); controlObj[controlKeyNew] = timeControl; } this.waitForKeyElements.controlObj = controlObj; }, }; unsafeWindow.base = base; /** * 百度网盘 * @author 油小猴 * @author hmjz100 */ let $baidu = { _getExtra() { let seKey = decodeURIComponent(base.getCookie('BDCLND')); return '{' + '"sekey":"' + seKey + '"' + "}"; }, _getSurl() { let reg = /(?<=s\/|surl=)([a-zA-Z0-9_-]+)/g; if (reg.test(location.href)) { return location.href.match(reg)[0]; } return ''; }, setBDUSS(custom) { if (custom) { base.setStorage("baiduyunPlugin_BDUSS", { BDUSS: custom }); return; } try { GM_cookie('list', { name: 'BDUSS' }, (cookies, error) => { if (!error) { let BDUSS = cookies?.[0]?.value; if (BDUSS) { base.setStorage("baiduyunPlugin_BDUSS", { BDUSS }); } } else { throw new Error(error) } }); } catch (e) { console.error("【LinkSwift】\nsetBDUSS\n错误信息:", e) try { let BDUSS = document.cookie.match(/BDUSS=(.*?)(;|$)/); if (!!BDUSS || BDUSS === null) throw new Error("document.cookie dosen't had cookie") base.setStorage("baiduyunPlugin_BDUSS", { BDUSS: BDUSS }); } catch (e) { console.error("【LinkSwift】\nsetBDUSS\n错误信息:", e) } } }, getBDUSS() { doc.find('.loading-popup .loading-title').html(`凭证获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取当前账号凭证~
`); let baiduyunPlugin_BDUSS = base.getStorage('baiduyunPlugin_BDUSS') ? base.getStorage('baiduyunPlugin_BDUSS') : { BDUSS: '' }; return baiduyunPlugin_BDUSS.BDUSS || ''; }, async getToken() { try { doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取授权状态~
`); // 获取授权状态 let authorize = await base.getFinalUrl(config.$baidu.api.getAccessToken); // 判断授权情况 if (authorize.includes('authorize')) { // 没授权,先获取授权的页面 doc.find('.loading-popup .loading-title').html(`授权获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取授权页面~
`); let html = await base.get(config.$baidu.api.getAccessToken, {}, 'text'); // 提取页面的发送确认授权的参数 let bdstoken = html.match(/name="bdstoken"\s+value="([^"]+)"/)?.[1]; let client_id = html.match(/name="client_id"\s+value="([^"]+)"/)?.[1]; let data = { grant_permissions_arr: 'netdisk', bdstoken: bdstoken, client_id: client_id, response_type: "token", display: "page", grant_permissions: "basic,netdisk" }; doc.find('.loading-popup .loading-title').html(`授权获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在自动确认授权~
`); // 发送请求达到自动进行授权 await base.post(config.$baidu.api.getAccessToken, base.stringify(data), { 'Content-Type': 'application/x-www-form-urlencoded', }); // 再次获取授权状态 let res2 = await base.getFinalUrl(config.$baidu.api.getAccessToken); let accessToken = res2.match(/access_token=([^&]+)/)?.[1]; if (!!accessToken) { doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
授权成功,令牌已缓存~
`); base.setValue('baidu_access_token', accessToken); return accessToken; } else { doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
授权失败,等待下一步操作~
`); return ''; } } else if (authorize.includes('access_token=')) { let accessToken = authorize.match(/access_token=([^&]+)/)?.[1]; if (!!accessToken) { doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
授权成功,令牌已缓存~
`); base.setValue('baidu_access_token', accessToken); return accessToken; } else { doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
授权失败,等待下一步操作~
`); return ''; } } else { return ''; } } catch (error) { return ''; } }, addPageListener() { /* 防止代码因其他原因被执行多次 这段代码出自 Via轻插件,作者谷花泰 */ const key = encodeURIComponent('LinkSwift:百度网盘'); if (window[key]) return; window[key] = true; function _factory(e) { let target = $(e.target); let item = target.parents('.pl-item'); let link = item.find('.pl-item-link.blob'); let directLink = item.find('.pl-item-link.browser'); let progress = item.find('.pl-item-progress'); let tip = item.find('.pl-item-tip'); let copy = item.find('.pl-item-copy'); let back = item.find('.pl-progress-back'); let stop = item.find('.pl-progress-stop'); return { item, link, directLink, progress, tip, copy, back, stop, target, }; } doc.on('mouseenter mouseleave click', '.pl-button.g-dropdown-button', function (e) { if (e.type === 'mouseleave') { $(e.currentTarget).removeClass('button-open'); } else { $(e.currentTarget).addClass('button-open'); $(e.currentTarget).find('.pl-dropdown-menu').show(); } }); doc.on('mouseleave', '.pl-button.g-dropdown-button .pl-dropdown-menu', function (e) { $(e.currentTarget).hide(); }); doc.on('click', '.pl-button-mode', function (e) { mode = e.target.dataset.mode; if (!mode) return; $baidu.getLink(); }); doc.on('click', '.pl-button-save', async function (e) { e.preventDefault(); selectList = $baidu.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要保存到网盘的文件哦~'); } message.info('提示:
因网盘限制,请保存到自己网盘后再去下载哦~'); await base.sleep(500); document.querySelector('.tools-share-save-hb').click(); }); doc.on('click', '.listener-link-api.browser', async function (e) { e.preventDefault(); let dataset = e.currentTarget.dataset; let href = dataset.link; $('#downloadIframe').attr('src', href); }); doc.on('click', '.listener-link-api.blob', async function (e) { e.preventDefault(); const o = _factory(e); const $width = o.item.find('.pl-progress-inner'); const $text = o.item.find('.pl-progress-inner-text'); const filename = o.link[0].dataset.filename; const index = o.link[0].dataset.index; const size = Number(o.link[0].dataset.size) || 0; base._resetData(index); base.get(o.link[0].dataset.link, { "User-Agent": config.$baidu.api.ua.downloadLink }, 'blob', { filename, index }); let startTime = Date.now(); let prevLoaded = 0; let prevTime = startTime; ins[index] = setInterval(async function () { const prog = +progress[index] || 0; const isIDM = !!idm[index]; if (isIDM) { // IDM 捕获处理逻辑 o.tip.hide(); o.progress.hide(); o.copy.show(); o.directLink.show(); o.link .text('链接已被IDM捕获~请查看IDM下载窗口哦!') .animate({ opacity: '0.5' }, "slow") .show(); clearInterval(ins[index]); await base.sleep(2000); o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow"); idm[index] = false; return; } const currentTime = Date.now(); const elapsedTime = currentTime - startTime; const loaded = prog * size / 100; const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零 const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0; // 计算剩余时间(保护除零) const totalProgress = Math.max(prog / 100, 0.01); const totalElapsedSeconds = elapsedTime / 1000; const estTotalTime = totalElapsedSeconds / totalProgress; const remainingTime = estTotalTime - totalElapsedSeconds; // 更新界面状态 o.link.hide(); o.directLink.hide(); o.tip.hide(); o.stop.show(); o.copy.hide(); o.progress.show(); // 更新进度条 $width.css('width', `${prog}%`); $text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`); // 更新历史值 prevLoaded = loaded; prevTime = currentTime; // 下载完成 if (prog >= 100) { await base.sleep(1000); clearInterval(ins[index]); progress[index] = 0; o.item.find('.pl-progress-stop').hide(); $text.text('下载完成~ 浏览器下载框应该弹出来了哦~'); o.back.show(); await base.sleep(3000); o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow"); } }, 500); }); doc.on('click', '.listener-retry', async function (e) { let o = _factory(e); o.tip.hide(); o.link.show(); o.directLink.show(); }); doc.on('click', '.listener-stop', async function (e) { let o = _factory(e); let index = o.link[0].dataset.index; if (request[index]) { request[index].abort(); clearInterval(ins[index]); o.item.find('.pl-progress-inner-text').text('正在取消...'); o.item.find('.pl-progress-inner').css('width', 100 + '%'); setTimeout(function () { o.tip.hide(); o.back.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.progress.hide(); o.stop.hide(); }, 1050) } }); doc.on('click', '.listener-back', async function (e) { let o = _factory(e); o.progress.hide(); o.tip.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.stop.hide(); o.back.hide(); }); doc.on('click', '.listener-download-all', function (e) { $('.pl-item-link.blob').each(function () { if ($(this).css('display') !== 'none') { $(this).click(); } }); $(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) { e.preventDefault(); if (!e.target.dataset.link) { $(e.target).removeClass('listener-copy-all').addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装👈`); } else { base.setClipboard(decodeURIComponent(e.target.dataset.link)); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout( function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000 ) } }); doc.on('click', '.listener-link-rpc', async function (e) { let target = $(e.currentTarget); target.find('.icon-rpc-devices').remove(); target.find('.pl-loading').remove(); target.prepend(base.createLoading()); let BDUSS = $baidu.getBDUSS(); let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename, [`User-Agent: ${config.$baidu.api.ua.downloadLink}`, `Cookie: BDUSS=${BDUSS}`]); if (res === 'success') { $('.listener-rpc-task').show(); target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow"); } else if (res === 'assistant') { target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装👈`); } else { target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow"); } }); doc.on('click', '.listener-send-rpc', function (e) { $('.listener-link-rpc').click(); $(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); }); doc.on('click', '.listener-open-setting', function () { base.showSetting(); }); doc.on('click', '.listener-open-updatelog', function () { base.showUpdate(); }); doc.on('click', '.listener-open-beautify', function () { base.showBeautify(); }); doc.on('click', '.listener-rpc-task', function (e) { e.preventDefault(); let rpc = JSON.stringify({ domain: base.getValue('setting_rpc_domain'), port: base.getValue('setting_rpc_port'), }), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`; GM_openInTab(url, { active: true }); }); document.documentElement.addEventListener('mouseup', function (e) { if (e.target.nodeName === 'A' && ~e.target.className.indexOf('pl-a')) { e.stopPropagation(); } }, true); }, greenerPage() { page = $baidu.detectPage(); base.waitForKeyElements(".wp-s-header-user__vip-center", function (tag) { tag.remove(); }, true); base.waitForKeyElements(".wp-s-header-user__create-team-content", function (tag) { tag.remove(); }, true); base.waitForKeyElements(".app-user-vip-center-box.vip-center-type-2", function (tag) { tag.remove(); }, true); base.waitForKeyElements(".wp-s-header__vip-btn-tip", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".app-user-vip-center-tip", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements("#web-header-text-s-45", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".wp-s-header__vip-btn", function (tag) { tag.text("会员中心") }, true); base.waitForKeyElements(".KQcHyA", function (tag) { tag.text("会员中心") }, true); base.waitForKeyElements(".gOIbzPb", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".wp-s-header-user__create-team-title", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".web-header-ad-item", function (tag) { tag.fadeOut(); }); base.waitForKeyElements(".wp-s-header__game-entry", function (tag) { tag.fadeOut(); }, true) base.waitForKeyElements(".bd-aside-ad", function (tag) { tag.fadeOut(); }, true) base.waitForKeyElements(".btn-img-tips", function (tag) { tag.fadeOut(); }, true) base.waitForKeyElements(".nd-operate-guidance", function (tag) { tag.fadeOut(); }, true) base.waitForKeyElements(".module-operation-content", function (tag) { tag.fadeOut(); document.querySelector(".operate-guide-close").click(); document.querySelector(".module-canvas").click(); }, true) base.waitForKeyElements("[class*='module-'][class*='-box']:not(.module-box), [class*='module-'][class*='-mask']", function (tag) { tag.fadeOut(); tag.find(".close-mask").click(); }, true) base.waitForKeyElements(".newIcon", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".u-badge__content.is-dot", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".wp-side-options.g-clearfix", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".wp-s-header-user__drop-channel", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".app-download", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements('.g-button[title*="手机"]', function (tag) { tag.fadeOut(); }, true) base.waitForKeyElements('.yike-entrance', function (tag) { tag.remove(); }, true) base.waitForKeyElements("a.tools__item", function (tag) { if (tag.attr("linked")) return; if (tag.attr('href')) { try { let url = new URL(tag.closest('a').attr('href')); url.search = ""; url.hash = url.hash.replace(/\?(.*?)(#|$)/, '$2') tag.attr('href', url.href) } catch (e) { } } tag.attr("linked", true) }, true); base.waitForKeyElements("p.wp-s-aside-nav__main-item-text", function (tag) { if (tag.attr("linked")) return; if (tag.closest('a').attr('href')) { try { let url = new URL(tag.closest('a').attr('href')); url.search = ""; url.hash = url.hash.replace(/\?(.*?)(#|$)/, '$2') tag.closest('a').attr('href', url.href) } catch (e) { } } if (tag.is(":contains('插件'), :contains('相册'), :contains('笔记')") && tag.closest('a').attr('target') !== "_blank") { tag.closest('a').fadeOut(); } else { tag.text(tag.text().replace("百度", "")); } tag.attr("linked", true) }, true); base.waitForKeyElements('dd[node-type="header-link"]', function (tag) { tag.children().each(function () { let tag = $(this); if (!tag.attr("node-type")) return; let type = tag.attr("node-type"); if ( type !== "disk-home" && type !== "mbox-homepage" && type !== "find-apps" ) { tag.fadeOut(); } }); }, true); base.waitForKeyElements(".__yunguanjia", function (tag) { tag.html(`
添加我的电脑
用电脑下载并登录最新百度网盘客户端,即自动完成添加。 下载百度网盘客户端
LinkSwift 修复该选项
`); }, true) // 美化分享页面 if (page === 'share') { base.waitForKeyElements(`iframe[src^="/buy/ad"]`, function (tag) { tag.fadeOut(); }, true) base.addStyle(`${mount}-baiduShare`, 'style', ` body, .theme-white.init-new, #layoutApp { background-color: #DCEFFE !important; background: #DCEFFE url(https://nd-static.bdstatic.com/m-static/disk-share/widget/pageModule/init-new/image/init-bg_1708266.png) no-repeat center center; } #bd-main .bd-left { background: #ffffffC0; border-radius: 10px; } iframe[src="/buy/ad/home"] { display: none !important; } `, `.${mount}`); base.waitForKeyElements(`.KPDwCE`, function (tag) { tag.css('background', 'transparent'); }, true); base.waitForKeyElements('.share-list .KPDwCE .AuPKyz', function (tag) { tag.css('background', 'transparent'); }, true); base.waitForKeyElements(`#layoutMain`, function (tag) { tag.css({ "border-radius": "24px" }); }, true) base.waitForKeyElements(".frame-content", function (tag) { tag.css({ "margin": "auto" }); }, true) } }, addButton() { base.waitForKeyElements(config.$baidu.mount.home, (element) => { page = $baidu.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'home') return; let $button = $(`
下载助手
`); element.prepend($button); }) base.waitForKeyElements(config.$baidu.mount.main, (element) => { page = $baidu.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'main') return; let $button = $(`
`); element.prepend($button); }) base.waitForKeyElements(config.$baidu.mount.main, (element) => { page = $baidu.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'youth') return; let $button = $(`
`); element.prepend($button); }) base.waitForKeyElements(config.$baidu.mount.share, (element) => { page = $baidu.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'share') return; /*let $button = $(`
下载助手
`);*/ let $button = $(` 下载助手 `) element.after($button); }) this.setBDUSS(); }, addInitButton() { base.waitForKeyElements(config.$baidu.mount.home, (element) => { page = $baidu.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'home') return; let $button = $(`
点我点亮
`); $button.click(function () { base.initDialog() }); element.prepend($button); }) base.waitForKeyElements(config.$baidu.mount.main, (element) => { page = $baidu.detectPage(); if ($(".pl-button-init").length > 0 || !page || (page !== 'main' && page !== 'youth')) return; let $button = $(`
`); $button.click(function () { base.initDialog() }); element.prepend($button); }) base.waitForKeyElements(config.$baidu.mount.share, (element) => { page = $baidu.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'share') return; let $button = $(` 点我点亮 `) $button.click(function () { base.initDialog() }); element.after($button); }) }, async getLink() { Swal.fire({ showConfirmButton: false, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, title: "获取中", html: `...`, footer: "如果选的文件较多,请耐心等待获取完成哦!", customClass: { popup: 'loading-popup', header: 'loading-header', title: 'loading-title', content: 'loading-content', input: 'loading-input', footer: 'loading-footer' }, willOpen: function () { Swal.showLoading(); }, ...swalDefault }); // 获取选择的文件列表 selectList = this.getSelectedList(); let BDUSS = this.getBDUSS(), accessToken = (base.getValue('baidu_access_token') || await $baidu.getToken()); if (!accessToken) { message.info('提示:
稍后请在新标签页中授权助手哦~'); base.deleteValue('baidu_access_token'); setTimeout(() => { GM_openInTab(config.$baidu.api.getAccessToken, { active: true, insert: true, setParent: true }) let attempts = 0; let interval = setInterval(function () { if (!!base.getValue('baidu_access_token')) { clearInterval(interval); accessToken = base.getValue('baidu_access_token') } attempts++; if (attempts > 120) { clearInterval(interval); return message.error('提示:
时间太长,我先撤下啦~'); } }, 1000); }, 3300); return; } if (!BDUSS) { async function getBDUSS() { let dialog = await Swal.fire({ icon: 'info', title: `提示`, html: '你好呀,为了获取百度网盘文件的下载直链
我们需要您安装原作者的辅助扩展
来让 “下载助手” 读取您的网盘账号凭证 (BDUSS)
获取到的凭证仅用于生成直链,请放心安装\\(≧▽≦*)o

不知道如何安装第三方扩展?点此查看详情
如果给浏览器开启了“开发者模式”后频繁提示
“关闭开发者模式”,请使用此补丁隐藏提示。界面汉化
扩展安装后请刷新本页,以应用最新更改', showConfirmButton: true, showDenyButton: true, showCancelButton: true, showCloseButton: true, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, confirmButtonText: '前往 Chrome(Crx搜搜)', denyButtonText: '前往 Firefox(Crx搜搜)', cancelButtonText: '装不了扩展,我要手动输入', position: 'center', ...swalDefault }); if (dialog.isConfirmed) { GM_openInTab('https://www.crxsoso.com/addon/detail/mphijdmblaalbakceeadippfkbgfgaaa ', { active: true }); } if (dialog.isDenied) { GM_openInTab('https://www.crxsoso.com/firefox/detail/baidunetdiskisasb ', { active: true }); } if (dialog.isDismissed && dialog.dismiss === Swal.DismissReason.cancel) { while (true) { let idialog = await Swal.fire({ title: '手动输入凭证', html: `

Via 浏览器获取方法

打开任意百度网盘页面 →

点击地址栏左侧的安全图标 →

查看 Cookies →

找到 "BDUSS=" 字段 →

复制等于号后面的内容直到分号 (不含分号) →

然后粘贴到这里


桌面端浏览器获取方法

打开任意百度网盘页面 →

F12 打开开发者工具 →

转到 应用(Application) 标签 →

Cookies →

找到 "BDUSS" 字段 →

复制其值粘贴到这里

`, showConfirmButton: true, showDenyButton: true, confirmButtonText: '确认', denyButtonText: '取消', allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, focusConfirm: false, ...swalDefault }); if (idialog.isConfirmed) { let BDUSS = $('#init').val().trim(); if (BDUSS && BDUSS.length >= 192) { $baidu.setBDUSS(BDUSS); return message.success('提示:
凭证设置成功
请再获取一次下载链接吧~'); } else { await Swal.fire({ icon: 'error', title: '格式错误', text: '请输入有效的 BDUSS(通常长度 ≥ 192 位)', confirmButtonText: '确认', ...swalDefault }); continue; } } else if (idialog.isDenied) { return await getBDUSS(); } } } } return await getBDUSS(); } if (page === 'home' || page === 'main') { if (!selectList.length) { return message.error('提示:
先勾选要下载的文件哦~'); } let cnt = 0; let processed = selectList.filter(f => !f.isdir).length; async function fetchFiles(dirs) { let files = []; for (let dir of dirs) { doc.find('.loading-popup .loading-title').html(`文件获取中`); let url = `${config.$baidu.api.getFiles}&dir=${encodeURIComponent(dir.path)}&access_token=${accessToken}`; let res = await base.get(url, { "User-Agent": config.$baidu.api.ua.downloadLink }); cnt++; if (res?.list?.length && (res.errno === 0 || res.errmsg === "succ")) { let subFiles = res.list.filter(f => !f.isdir); processed += subFiles.length; doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} 个文件~
${dir.path}
`); files = files.concat(subFiles); if (res.list.some(f => f.isdir)) { files = files.concat(await fetchFiles(res.list.filter(f => f.isdir))); } } if (cnt >= 50) { doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} 个文件~
休息 3 秒...
`); await base.sleep(3000); cnt = 0; } } return files; } let files = selectList.filter(f => !f.isdir); if (selectList.some(f => f.isdir)) { files = files.concat(await fetchFiles(selectList.filter(f => f.isdir))); } if (!files.length) { return message.error('提示:
文件夹是空的哦~'); } doc.find('.loading-popup .loading-title').html(`链接获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取文件对应的下载链接~
`); let fidList = files.map(f => f.fs_id); let batchSize = 100; let linkList = []; for (let i = 0; i < fidList.length; i += batchSize) { let url = `${config.$baidu.api.getLink}&fsids=${encodeURIComponent(JSON.stringify(fidList.slice(i, i + batchSize)))}&access_token=${accessToken}`; let res = await base.get(url, { "User-Agent": config.$baidu.api.ua.downloadLink }); if (res?.list?.length && (res.errno === 0 || res.errmsg === "succ")) { linkList = linkList.concat(res.list); doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${linkList.length} / ${fidList.length} 个链接~
`); } else { if (res?.errno) { if (res.errno === 112) { return message.error('提示:
页面过期了,刷新重试下吧~
代码:' + res.errno); } if (res.errno === 9019) { base.deleteValue('baidu_access_token'); return message.error('提示:
访问令牌已过期,刷新网页后再获取一次吧~
代码:' + res.errno); } base.deleteValue('baidu_access_token'); return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~
代码:' + res.errno); } else { return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~'); } } await base.sleep(1000); } if (linkList.length) { base.showMainDialog(config.base.dom.button[mode].title, this.generateDom(linkList), config.base.dom.button[mode].footer); } else { return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~'); } } else { return message.error('提示:
页面错误~'); } }, generateDom(list) { if (!list) { return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~'); } let content = '
'; let alinkAllText = ''; base.sortByName(list); list.forEach((v, i) => { if (v.isdir === 1) return; let filename = v.server_filename || v.filename; let size = base.sizeFormat(v.size); if (!v?.dlink || !v?.dlink.includes("http")) { content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`; } else { let dlink = v.dlink + '&access_token=' + base.getValue('baidu_access_token'); if (mode === 'api') { alinkAllText += dlink + '\r\n'; content += `
${filename}
`; } let BDUSS = this.getBDUSS(); if (mode === 'aria') { let alink = base.convertLinkToAria(dlink, filename, `--header "User-Agent: ${config.$baidu.api.ua.downloadLink}" --header "Cookie: BDUSS=${BDUSS}"`); if (typeof (alink) === 'object') { content += ``; } else { alinkAllText += alink + '\r\n'; content += ``; } } if (mode === 'rpc') { content += `
${filename}
`; } if (mode === 'curl') { let alink = base.convertLinkToCurl(dlink, filename, `-A "${config.$baidu.api.ua.downloadLink}" -b "BDUSS=${BDUSS}"`); if (typeof (alink) === 'object') { content += ``; } else { alinkAllText += alink + '\r\n'; content += ``; } } if (mode === 'bc') { let alink = base.convertLinkToBC(dlink, filename, `cookie=${encodeURIComponent("BDUSS=" + BDUSS)}&user_agent=${encodeURIComponent(config.$baidu.api.ua.downloadLink)}`); if (typeof (alink) === 'object') { alinkAllText += decodeURIComponent(alink.text) + '\r\n'; content += ``; } else { alinkAllText += alink + '\r\n'; content += ``; } } } }); content += '
'; if (mode === 'rpc') { content += `
` } if (list.length >= 2) { if (mode === 'api') content += `
`; if (mode === 'aria') content += `
`; if (mode === 'rpc') { content += ``; } if (mode === 'curl') { content += `
`; } if (mode === 'bc') { content += `
`; } } if (mode === 'rpc') { let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path'); content += `
`; } return content; }, getSelectedList() { let List, selectList try { List = require("system-core:context/context.js").instanceForSystem.list; selectList = List.getSelected(); /*if (!selectList.length) { selectList = List.getCurrentList(); }*/ return selectList; } catch (e) { } try { List = unsafeWindow.document.querySelector('.wp-s-core-pan'); if (List && List.__vue__.selectedList) { selectList = List.__vue__.selectedList; return selectList; } } catch (e) { } try { List = unsafeWindow.document.querySelector('.file-list'); if (List && List.__vue__.allFileList) { selectList = List.__vue__.allFileList.filter(function (item) { return !!item.selected; }); return selectList; } } catch (e) { } }, getLogid() { let ut = require("system-core:context/context.js").instanceForSystem.tools.baseService; return ut.base64Encode(base.getCookie("BAIDUID")); }, getShareData() { let res = unsafeWindow.locals.dump(); shareParams.shareType = 'secret'; shareParams.sign = ''; shareParams.timestamp = ''; shareParams.bdstoken = res.bdstoken.value; shareParams.channel = 'chunlei'; shareParams.clienttype = 0; shareParams.web = 1; shareParams.app_id = 250528; shareParams.encrypt = 0; shareParams.product = 'share'; shareParams.logid = this.getLogid(); shareParams.shareid = res.shareid.value; shareParams.uk = res.share_uk.value; shareParams.shareType === 'secret' && (shareParams.extra = this._getExtra()); shareParams.surl = this._getSurl(); }, detectPage() { let path = location.pathname; if (/^\/disk\/home/.test(path)) return 'home'; if (/^\/disk\/main/.test(path)) return 'main'; if (/^\/youth\/pan\/main/.test(path)) return 'youth'; if (/^\/(s|share)\//.test(path)) return 'share'; return ''; }, async initAuthorize() { base.registerMenuCommand(); Swal.fire({ showConfirmButton: false, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, html: `请稍后`, willOpen: function () { Swal.showLoading(); }, ...swalDefault }); if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { let url = new URL(location.href); let auth = new URL(config.$baidu.api.getAccessToken); const allowedClientIds = [ auth.searchParams.get("client_id"), 'L6g70tBRRIXLsY0Z3HwKqlRE', // pcstest_oauth 'fSds3K4w43rw37tOqlQmTa2kDwaczK4U', // 小度智能词典笔专业版 'TFwtw8uwHxpdkvVqVKdIlx1XqXUnr1zG', // 印象笔记 '9dgBV9yesuBVOXaxls7aVHbLBLqU8yyg', // WPS文档 'l9DdBOG4RYroMscmzK5OChdaGelgd92M', // 小猴云印PC版 'Kyr013gHQBf2immy3fQt1jZ3nZVpiGAm', // 简单打印 'iYCeC9g08h5vuP9UqvPHKKSVrKFXGa1v', // Alist 'IlLqBbU3GjQ0t46TRwFateTprHWl39zF', // 百度手机助手 ]; // https://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id=&scope=basic,netdisk,mobile&display=page&redirect_uri= if ( /openapi.baidu.com\/oauth\/2.0\/authorize/.test(location.href) && url.searchParams.get("response_type").includes("token") && url.searchParams.get("scope").includes("netdisk") && allowedClientIds.includes(url.searchParams.get("client_id")) ) { let dialog = await Swal.fire({ icon: 'info', title: `提示`, html: '你好呀,为了获取百度网盘文件的下载直链
我们需要您的授权来使 “下载助手” 读取您的网盘文件信息

由于使用了别的应用ID,所以授权的应用名称会有不同
获取到的数据仅用于生成直链,请放心授权ヾ(≧▽≦*)o', showConfirmButton: true, showDenyButton: true, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, confirmButtonText: '授权', denyButtonText: '再想想', position: 'center' }); if (dialog.isConfirmed) { base.waitForKeyElements("button#auth-allow", function (element) { element[0].click(); }, true) return; } if (dialog.isDenied) { return await Swal.fire({ icon: 'question', title: `好吧(* ̄3 ̄)╭`, html: '那就再想一想
想好了就按下 “授权” 按钮吧~', timer: 180000, toast: true, timerProgressBar: true, showConfirmButton: false, showDenyButton: false, position: 'bottom-end', }) } } else if (/openapi.baidu.com\/oauth\/2.0\/login_success/.test(location.href)) { let int = setInterval(async function () { if (location.href.includes('access_token') && (location.href.includes('basic+netdisk') || location.href.includes('basic,netdisk'))) { clearInterval(int) let token = location.href.match(/access_token=(.*?)&/)[1]; base.setValue('baidu_access_token', token); let dialog = await Swal.fire({ icon: 'success', title: `成功啦`, html: '你已 成功授权/授权过 脚本读取您的网盘文件信息~
等待 3 秒之后将关闭此页面', timer: 3000, timerProgressBar: true, showConfirmButton: true, showDenyButton: false, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, confirmButtonText: '关闭页面', position: 'center', willOpen: function () { let sec = 3.1; setInterval(() => { sec -= 0.1; document.getElementById("second").innerText = sec.toFixed(1); }, 100); setTimeout(() => { window.close() }, 3100); }, }); if (dialog.isConfirmed) { window.close() return; } } else { clearInterval(int) Swal.close() } }, 1) } else { Swal.close() } } else { Swal.close() } }, async initPanLinker() { base.createTip(); base.registerMenuCommand(); if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); this.addPageListener(); } else { this.addInitButton(); } }, }; /** * 阿里云盘 * @author 油小猴 * @author hmjz100 */ let $aliyun = { addPageListener() { /* 防止代码因其他原因被执行多次 这段代码出自 Via轻插件,作者谷花泰 */ const key = encodeURIComponent('LinkSwift:阿里云盘'); if (window[key]) return; window[key] = true; function _factory(e) { let target = $(e.target); let item = target.parents('.pl-item'); let link = item.find('.pl-item-link.blob'); let directLink = item.find('.pl-item-link.browser'); let progress = item.find('.pl-item-progress'); let tip = item.find('.pl-item-tip'); let copy = item.find('.pl-item-copy'); let back = item.find('.pl-progress-back'); let stop = item.find('.pl-progress-stop'); return { item, link, directLink, progress, tip, copy, back, stop, target, }; } doc.on('click', '.pl-button-save', async function (e) { e.preventDefault(); let reactDomGrid = document.querySelector(config.$aliyun.mount.grid); if (reactDomGrid) { let dialog = await Swal.fire({ title: '提示', html: '
请先切换到   列表视图  后再获取下载链接哦
', icon: 'info', showCloseButton: true, showDenyButton: true, confirmButtonText: '切换', denyButtonText: '不要', ...swalDefault }); if (dialog.isConfirmed) { document.querySelector(config.$aliyun.mount.switch).click(); return message.success('提示:
切换为列表视图成功
请再获取一次下载链接吧~'); } return false; } selectList = $aliyun.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要保存到网盘的文件哦~'); } message.info('提示:
因网盘限制,请保存到自己网盘后再去下载哦~'); await base.sleep(500); document.querySelector('[class*="btn-save--"]').click(); }); doc.on('click', '.pl-button-mode', async function (e) { mode = e.target.dataset.mode; if (!mode) return; let reactDomGrid = document.querySelector(config.$aliyun.mount.grid); if (reactDomGrid) { let dialog = await Swal.fire({ title: '提示', html: '
请先切换到   列表视图  后再获取下载链接哦
', icon: 'info', showCloseButton: true, showDenyButton: true, confirmButtonText: '切换', denyButtonText: '不要', ...swalDefault }); if (dialog.isConfirmed) { document.querySelector(config.$aliyun.mount.switch).click(); return message.success('提示:
切换为列表视图成功
请再获取一次下载链接吧~'); } return false; } $aliyun.getLink(); }); doc.on('click', '.listener-link-api.browser', async function (e) { e.preventDefault(); let dataset = e.currentTarget.dataset; let href = dataset.link; $('#downloadIframe').attr('src', href); }); doc.on('click', '.listener-link-api.blob', async function (e) { e.preventDefault(); const o = _factory(e); const $width = o.item.find('.pl-progress-inner'); const $text = o.item.find('.pl-progress-inner-text'); const filename = o.link[0].dataset.filename; const index = o.link[0].dataset.index; const size = Number(o.link[0].dataset.size) || 0; base._resetData(index); base.get(e.currentTarget.dataset.link, { "Referer": `https://${location.host}/` }, 'blob', { filename, index }); let startTime = Date.now(); let prevLoaded = 0; let prevTime = startTime; ins[index] = setInterval(async function () { const prog = +progress[index] || 0; const currentTime = Date.now(); const elapsedTime = currentTime - startTime; const loaded = prog * size / 100; const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零 const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0; // 计算剩余时间(保护除零) const totalProgress = Math.max(prog / 100, 0.01); const totalElapsedSeconds = elapsedTime / 1000; const estTotalTime = totalElapsedSeconds / totalProgress; const remainingTime = estTotalTime - totalElapsedSeconds; // 更新界面状态 o.link.hide(); o.directLink.hide(); o.tip.hide(); o.stop.show(); o.copy.hide(); o.progress.show(); // 更新进度条 $width.css('width', `${prog}%`); $text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`); // 更新历史值 prevLoaded = loaded; prevTime = currentTime; // 下载完成 if (prog >= 100) { await base.sleep(1000); clearInterval(ins[index]); progress[index] = 0; o.item.find('.pl-progress-stop').hide(); $text.text('下载完成~ 浏览器下载框应该弹出来了哦~'); o.back.show(); await base.sleep(3000); o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow"); } }, 500); }); doc.on('click', '.listener-retry', async function (e) { let o = _factory(e); o.tip.hide(); o.link.show(); o.directLink.show(); }); doc.on('click', '.listener-stop', async function (e) { let o = _factory(e); let index = o.link[0].dataset.index; if (request[index]) { request[index].abort(); clearInterval(ins[index]); o.item.find('.pl-progress-inner-text').text('正在取消...'); o.item.find('.pl-progress-inner').css('width', 100 + '%'); setTimeout(function () { o.tip.hide(); o.back.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.progress.hide(); o.stop.hide(); }, 1050) } }); doc.on('click', '.listener-back', async function (e) { let o = _factory(e); o.progress.hide(); o.tip.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.stop.hide(); o.back.hide(); }); doc.on('click', '.listener-copy-filename', async function (e) { base.setClipboard(e.target.dataset.filename); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) { e.preventDefault(); base.setClipboard(decodeURIComponent(e.target.dataset.link)); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-rpc', async function (e) { let target = $(e.currentTarget); target.find('.icon-rpc-devices').remove(); target.find('.pl-loading').remove(); target.prepend(base.createLoading()); let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename, [`Referer: https://${location.host}/`]); if (res === 'success') { $('.listener-rpc-task').show(); target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow"); } else if (res === 'assistant') { target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装👈`); } else { target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow"); } }); doc.on('click', '.listener-send-rpc', function (e) { $('.listener-link-rpc').click(); $(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); }); doc.on('click', '.listener-download-all.blob', function (e) { $('.pl-item-link.blob').each(function () { if ($(this).css('display') !== 'none') { $(this).click(); } }); $(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-open-setting', function () { base.showSetting(); }); doc.on('click', '.listener-open-updatelog', function () { base.showUpdate(); }); doc.on('click', '.listener-open-beautify', function () { base.showBeautify(); }); doc.on('click', '.listener-rpc-task', function () { let rpc = JSON.stringify({ domain: base.getValue('setting_rpc_domain'), port: base.getValue('setting_rpc_port'), }), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`; GM_openInTab(url, { active: true }); }); document.documentElement.addEventListener('mouseup', function (e) { if (e.target.nodeName === 'A' && ~e.target.className.indexOf('pl-a')) { e.stopPropagation(); } }, true); }, async getFileUrlByOnce(d, f) { let authorization = `${base.getStorage('token').token_type} ${base.getStorage('token').access_token}`; let res = await base.post(config.$aliyun.api.getLink, { drive_id: d, file_id: f }, { authorization, "content-type": "application/json;charset=utf-8", "referer": "https://www.aliyundrive.com/", "x-canary": "client=windows,app=adrive,version=v6.0.0" }); if (res.code === 'AccessTokenInvalid') { return message.error('提示:
访问令牌过期了,请刷新网页后再试'); } if (res.url) { return res.url; } return ''; }, greenerPage() { base.waitForKeyElements('[class*="share-list-banner"]', function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements('[class*="to-app"]', function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements('[class*="btn-mobile-save"]', function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements('div[class*="text"]', function (tag) { if (tag[0].innerHTML.match("SVIP")) tag.fadeOut(); }, true); base.waitForKeyElements('[class*="SplashScreenImg--close"]', function (tag) { tag[0].click(); }, true); base.waitForKeyElements('[class*="container"]', function (tag) { tag.find('[class^="icon-close"]').click(); }, true); base.waitForKeyElements('[class*="popup_main_close"]', function (tag) { tag[0].click(); }, true); }, svg: ``, addButton() { base.waitForKeyElements(config.$aliyun.mount.home, (element) => { page = $aliyun.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'home') return; let $button = $(`
${$aliyun.svg}下载助手
  • API 下载
  • Aria 下载
  • RPC 下载
  • cURL 下载
  • BC 下载
  • 助手设置
  • 助手美化
  • 更新日志
`); element.append($button); }) base.waitForKeyElements(config.$aliyun.mount.share, (element) => { page = $aliyun.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'share') return; let $button = $(`
${$aliyun.svg}下载助手
  • 保存后下载
  • 助手设置
  • 助手美化
  • 更新日志
`); $button.css({ 'margin-right': '10px', "height": "36px", "width": "auto", "padding": "1px 30px" }); element.prepend($button); }) }, addInitButton() { let $button = $(`
${$aliyun.svg}点我点亮
`); $button.click(function () { base.initDialog() }); base.waitForKeyElements(config.$aliyun.mount.home, (element) => { page = $aliyun.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'home') return; $button.css({ "width": "auto" }); element.append($button); }) base.waitForKeyElements(config.$aliyun.mount.share, (element) => { page = $aliyun.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'share') return; $button.css({ 'margin-right': '10px', "height": "36px", "padding": "1px 30px", "width": "auto" }); element.prepend($button); }) }, async getLink() { Swal.fire({ showConfirmButton: false, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, title: "获取中", html: `...`, footer: "如果选的文件较多,请耐心等待获取完成哦!", customClass: { popup: 'loading-popup', header: 'loading-header', title: 'loading-title', content: 'loading-content', input: 'loading-input', footer: 'loading-footer' }, willOpen: function () { Swal.showLoading(); }, ...swalDefault }); selectList = this.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要下载的文件哦~'); } if (this.isOnlyFolder()) { return message.error('提示:
请打开文件夹后再勾选文件~'); } if (page === 'home') { selectList = selectList.filter(item => item.type === 'file') let batchSize = 15; let processed = 0; doc.find('.loading-popup .loading-title').html(`链接获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取文件对应的下载链接~
`); for (let i = 0; i < selectList.length; i += batchSize) { // 当前批次文件 let batch = selectList.slice(i, i + batchSize); // 过滤掉已有 URL 的文件 let noUrlSelectList = batch.filter(v => !Boolean(v.url)); let hasUrlSelectList = batch.filter(v => Boolean(v.url)); let queue = []; // 为没有 URL 的文件生成请求队列 noUrlSelectList.forEach((item) => { queue.push(this.getFileUrlByOnce(item.driveId, item.fileId) .then(val => { processed++; doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} / ${selectList.length} 个链接~
`); return val; })); }); hasUrlSelectList.forEach((item) => { processed++; doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} / ${selectList.length} 个链接~
`); }); // 等待本批次的请求结果 const res = await Promise.all(queue); res.forEach((val, index) => { noUrlSelectList[index].url = val; }); // 每次处理完一个批次后,等待 1 秒 await base.sleep(1000); } } else { return message.error('提示:
页面错误~'); } let html = this.generateDom(selectList); base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer); }, generateDom(list) { if (!list) { return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~'); } let content = '
'; let alinkAllText = ''; list.forEach((v, i) => { if (v.type === 'folder') return; let filename = v.name; let fid = v.fileId; let did = v.driveId; let size = base.sizeFormat(v.size); let dlink = v.downloadUrl || v.url; if (!dlink || !dlink.includes("http")) { content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`; } else { if (mode === 'api') { alinkAllText += dlink + '\r\n'; content += `
${filename}
`; } if (mode === 'aria') { let alink = base.convertLinkToAria(dlink, filename, `--header "Referer: https://${location.host}/"`); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'rpc') { content += `
${filename}
`; } if (mode === 'curl') { let alink = base.convertLinkToCurl(dlink, filename, `&refer=${encodeURIComponent(`https://${location.host}/`)}`); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'bc') { let alink = base.convertLinkToBC(dlink, filename, `-e "https://${location.host}/"`); alinkAllText += alink + '\r\n'; content += ``; } } }); content += '
'; if (mode === 'rpc') { content += `
` } if (list.length >= 2) { if (mode === 'api') content += `
`; if (mode === 'aria') content += `
`; if (mode === 'rpc') { content += ``; } if (mode === 'curl') { content += `
`; } if (mode === 'bc') { content += `
`; } } if (mode === 'rpc') { let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path'); content += `
`; } return content; }, getSelectedList() { try { let selectedList = []; let reactDom = document.querySelector(config.$aliyun.mount.list); let reactObj = base.findReact(reactDom, 1); let props = reactObj.pendingProps; if (props) { let fileList = props.dataSource || []; let selectedKeys = props.selectedKeys.split(','); fileList.forEach(function (val) { if (selectedKeys.includes(val.fileId)) { selectedList.push(val); } }); } return selectedList; } catch (e) { return []; } }, detectPage() { let path = location.pathname; if (/^\/(drive)/.test(path)) return 'home'; if (/^\/(s|share)\//.test(path)) return 'share'; return ''; }, isOnlyFolder() { for (let i = 0; i < selectList.length; i++) { if (selectList[i].type === 'file') return false; } return true; }, async initPanLinker() { page = this.detectPage(); base.createTip(); base.registerMenuCommand(); if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); this.addPageListener(); } else { this.addInitButton(); } } }; /** * 中国移动云盘 / 和彩云 * @author 油小猴 * @author hmjz100 */ let $mcloud = { addPageListener() { /* 防止代码因其他原因被执行多次 这段代码出自 Via轻插件,作者谷花泰 */ const key = encodeURIComponent('LinkSwift:移动云盘'); if (window[key]) return; window[key] = true; function _factory(e) { let target = $(e.target); let item = target.parents('.pl-item'); let link = item.find('.pl-item-link.blob'); let directLink = item.find('.pl-item-link.browser'); let progress = item.find('.pl-item-progress'); let tip = item.find('.pl-item-tip'); let copy = item.find('.pl-item-copy'); let back = item.find('.pl-progress-back'); let stop = item.find('.pl-progress-stop'); return { item, link, directLink, progress, tip, copy, back, stop, target, }; } doc.on('click', '.pl-button-mode', function (e) { mode = e.target.dataset.mode; if (!mode) return; $mcloud.getLink(); }); doc.on('click', '.pl-button-save', async function (e) { e.preventDefault(); selectList = $mcloud.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要直接下载的文件哦~'); } if ($mcloud.isOnlyFolder()) { return message.error('提示:
请打开文件夹后再勾选文件~'); } message.info('提示:
因网盘限制,只能够通过页面直接下载哦~'); await base.sleep(500); document.querySelector('.btn-top.btn-top_dl').click(); }); doc.on('click', '.listener-link-api.browser', async function (e) { e.preventDefault(); let dataset = e.currentTarget.dataset; let href = dataset.link; $('#downloadIframe').attr('src', href); }); doc.on('click', '.listener-link-api.blob', async function (e) { e.preventDefault(); const o = _factory(e); const $width = o.item.find('.pl-progress-inner'); const $text = o.item.find('.pl-progress-inner-text'); const filename = o.link[0].dataset.filename; const index = o.link[0].dataset.index; const size = Number(o.link[0].dataset.size) || 0; base._resetData(index); base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index }); let startTime = Date.now(); let prevLoaded = 0; let prevTime = startTime; ins[index] = setInterval(async function () { const prog = +progress[index] || 0; const currentTime = Date.now(); const elapsedTime = currentTime - startTime; const loaded = prog * size / 100; const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零 const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0; // 计算剩余时间(保护除零) const totalProgress = Math.max(prog / 100, 0.01); const totalElapsedSeconds = elapsedTime / 1000; const estTotalTime = totalElapsedSeconds / totalProgress; const remainingTime = estTotalTime - totalElapsedSeconds; // 更新界面状态 o.link.hide(); o.directLink.hide(); o.tip.hide(); o.stop.show(); o.copy.hide(); o.progress.show(); // 更新进度条 $width.css('width', `${prog}%`); $text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`); // 更新历史值 prevLoaded = loaded; prevTime = currentTime; // 下载完成 if (prog >= 100) { await base.sleep(1000); clearInterval(ins[index]); progress[index] = 0; o.item.find('.pl-progress-stop').hide(); $text.text('下载完成~ 浏览器下载框应该弹出来了哦~'); o.back.show(); await base.sleep(3000); o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow"); } }, 500); }); doc.on('click', '.listener-retry', async function (e) { let o = _factory(e); o.tip.hide(); o.link.show(); o.directLink.show(); }); doc.on('click', '.listener-stop', async function (e) { let o = _factory(e); let index = o.link[0].dataset.index; if (request[index]) { request[index].abort(); clearInterval(ins[index]); o.item.find('.pl-progress-inner-text').text('正在取消...'); o.item.find('.pl-progress-inner').css('width', 100 + '%'); setTimeout(function () { o.tip.hide(); o.back.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.progress.hide(); o.stop.hide(); }, 1050) } }); doc.on('click', '.listener-back', async function (e) { let o = _factory(e); o.progress.hide(); o.tip.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.stop.hide(); o.back.hide(); }); doc.on('click', '.listener-download-all', function (e) { $('.pl-item-link.blob').each(function () { if ($(this).css('display') !== 'none') { $(this).click(); } }); $(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) { e.preventDefault(); base.setClipboard(decodeURIComponent(e.target.dataset.link)); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-rpc', async function (e) { let target = $(e.currentTarget); target.find('.icon-rpc-devices').remove(); target.find('.pl-loading').remove(); target.prepend(base.createLoading()); let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename); if (res === 'success') { $('.listener-rpc-task').show(); target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow"); } else if (res === 'assistant') { target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装👈`); } else { target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow"); } }); doc.on('click', '.listener-send-rpc', function (e) { $('.listener-link-rpc').click(); $(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); }); doc.on('click', '.listener-open-setting', function () { base.showSetting(); }); doc.on('click', '.listener-open-updatelog', function () { base.showUpdate(); }); doc.on('click', '.listener-open-beautify', function () { base.showBeautify(); }); doc.on('click', '.listener-rpc-task', function () { let rpc = JSON.stringify({ domain: base.getValue('setting_rpc_domain'), port: base.getValue('setting_rpc_port'), }), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`; GM_openInTab(url, { active: true }); }); }, greenerPage() { base.waitForKeyElements(".adv_swiper_menu", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".client-bubble", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".avs-box", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".top-adv-swiper", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".client_download_icon", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".document_top_memberCenter", function (tag) { $(tag[0]).click(function () { Swal.fire({ html: ``, allowOutsideClick: false, showCloseButton: true, showConfirmButton: false, ...swalDefault }); }); }, true); }, addButton() { base.waitForKeyElements(config.$mcloud.mount.home, (element) => { page = $mcloud.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'home') return; let $button = $(`
下载助手
  • API 下载
  • Aria 下载
  • RPC 下载
  • cURL 下载
  • BC 下载
  • 助手设置
  • 助手美化
  • 更新日志
`); element.prepend($button); }) base.waitForKeyElements(config.$mcloud.mount.share, (element) => { page = $mcloud.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'share') return; let $button = $(`
下载助手
  • 直接下载
  • 助手设置
  • 助手美化
  • 更新日志
`); element.prepend($button); }) }, addInitButton() { let $button = $(`
点我点亮
`); $button.click(function () { base.initDialog() }); base.waitForKeyElements(config.$mcloud.mount.home, (element) => { page = $mcloud.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'home') return; $button.addClass('mcloud-button'); element.prepend($button); }) base.waitForKeyElements(config.$mcloud.mount.share, (element) => { page = $mcloud.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'share') return; $button.addClass('mcloud-share-button').css({ "cursor": "pointer" }); element.prepend($button); }) }, getRandomString(len) { len = len || 16; let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; let maxPos = $chars.length; let pwd = ''; for (let i = 0; i < len; i++) { pwd += $chars.charAt(Math.floor(Math.random() * maxPos)); } return pwd; }, utob(str) { const u = String.fromCharCode; return str.replace(/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g, function (t) { if (t.length < 2) { let e = t.charCodeAt(0); 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); } e = 65536 + 1024 * (t.charCodeAt(0) - 55296) + (t.charCodeAt(1) - 56320); return u(240 | e >>> 18 & 7) + u(128 | e >>> 12 & 63) + u(128 | e >>> 6 & 63) + u(128 | 63 & e); }); }, getSign(e, t, a, n) { let r = "", i = ""; if (t) { let s = Object.assign({}, t); i = JSON.stringify(s), i = i.replace(/\s*/g, ""), i = encodeURIComponent(i); let c = i.split(""), u = c.sort(); i = u.join(""); } let A = md5(base.encodeBase(this.utob(i))); let l = md5(a + ":" + n); return md5(A + l).toUpperCase(); }, async getFileUrlByOnce(item, index) { try { if (item.downloadUrl) return { index, downloadUrl: item.downloadUrl }; if (this.detectPage() === 'home') { let body = { fileId: item.contentID } let time = new Date(+new Date() + 8 * 3600 * 1000).toJSON().substr(0, 19).replace('T', ' '); let key = this.getRandomString(16); let sign = this.getSign(undefined, body, time, key); let res = await base.post(config.$mcloud.api.getLink, body, { 'Authorization': base.getCookie('authorization'), 'Caller': 'web', 'CMS-DEVICE': 'default', 'Content-Type': "application/json;charset=UTF-8", 'mcloud-channel': '1000101', 'mcloud-client': '10701', 'mcloud-sign': time + "," + key + "," + sign, 'mcloud-version': '7.14.2', 'Origin': 'https://yun.139.com', 'Referer': 'https://yun.139.com/', 'X-DeviceInfo': '||9|7.14.2|chrome|119.0.0.0|||windows 10||zh-CN|||', 'X-Huawei-ChannelSrc': '10000034', 'X-Inner-Ntwk': '2', 'X-M4C-Caller': 'PC', 'X-M4C-Src': '10002', 'X-SvcType': '1', 'X-Yun-Api-Version': 'v1', 'X-Yun-App-Channel': '10000034', 'X-Yun-Channel-Source': '10000034', 'X-Yun-Client-Info': '||9|7.14.2|chrome|119.0.0.0|||windows 10||zh-CN|||||', 'X-Yun-Module-Type': '100', 'X-Yun-Svc-Type': '1' }); if (res.success) { return { index, downloadUrl: res.data.url }; } else { return { index, downloadUrl: '获取下载地址失败,刷新后再试试吧~' }; } } if (this.detectPage() === 'share') { let vueDom = document.querySelector(".main_file_list").__vue__; let res = await base.post(config.$mcloud.api.getShareLink, `linkId=${vueDom.linkID}&contentIds=${item.path}&catalogIds=`, { 'Content-Type': 'application/x-www-form-urlencoded', }); if (res.code === 0) { return { index, downloadUrl: res.data.redrUrl }; } else { return { index, downloadUrl: '获取下载地址失败,刷新后再试试吧~' }; } } } catch (e) { return { index, downloadUrl: '获取下载地址失败,刷新后再试试吧~' }; } }, async getLink() { Swal.fire({ showConfirmButton: false, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, title: "获取中", html: `...`, footer: "如果选的文件较多,请耐心等待获取完成哦!", customClass: { popup: 'loading-popup', header: 'loading-header', title: 'loading-title', content: 'loading-content', input: 'loading-input', footer: 'loading-footer' }, willOpen: function () { Swal.showLoading(); }, ...swalDefault }); selectList = this.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要下载的文件哦~'); } if (this.isOnlyFolder()) { return message.error('提示:
请打开文件夹后再勾选文件~'); } if (page === 'home') { selectList = selectList.filter(item => item.contentID && item.contentName && item.contentSuffix); let batchSize = 15; let processed = 0; doc.find('.loading-popup .loading-title').html(`链接获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取文件对应的下载链接~
`); for (let i = 0; i < selectList.length; i += batchSize) { let batch = selectList.slice(i, i + batchSize); let queue = []; batch.forEach((item, localIndex) => { let globalIndex = i + localIndex; queue.push(this.getFileUrlByOnce(item, globalIndex) .then(val => { processed++; doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} / ${selectList.length} 个链接~
`); return val; })); }); let res = await Promise.all(queue); res.forEach(val => { selectList[val.index].downloadUrl = val.downloadUrl; }); await base.sleep(1000); } } else { return message.error('提示:
页面错误~'); } let html = this.generateDom(selectList); base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer); }, generateDom(list) { if (!list) { return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~'); } let content = '
'; let alinkAllText = ''; list.forEach((v, i) => { if (v.dirEtag || v.caName) return; let filename = v.contentName || v.coName; let size = base.sizeFormat(v.contentSize || v.coSize); let dlink = v.downloadUrl; if (!dlink || !dlink.includes("http")) { content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`; } else { if (mode === 'api') { alinkAllText += dlink + '\r\n'; content += `
${filename}
`; } if (mode === 'aria') { let alink = base.convertLinkToAria(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'rpc') { content += `
${filename}
`; } if (mode === 'curl') { let alink = base.convertLinkToCurl(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'bc') { let alink = base.convertLinkToBC(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } } }); content += '
'; if (mode === 'rpc') { content += `
` } if (list.length >= 2) { if (mode === 'api') content += `
`; if (mode === 'aria') content += `
`; if (mode === 'rpc') { content += ``; } if (mode === 'curl') { content += `
`; } if (mode === 'bc') { content += `
`; } } if (mode === 'rpc') { let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path'); content += `
`; } return content; }, getSelectedList() { try { return document.querySelector(".main_file_list").__vue__.selectList.map(val => val.item); } catch (e) { let vueDom = document.querySelector(".home-page").__vue__; let fileList = vueDom._computedWatchers.fileList.value; let dirList = vueDom._computedWatchers.dirList.value; let selectedFileIndex = vueDom.selectedFile; let selectedDirIndex = vueDom.selectedDir; let selectFileList = fileList.filter((v, i) => { return selectedFileIndex.includes(i); }); let selectDirList = dirList.filter((v, i) => { return selectedDirIndex.includes(i); }); return [...selectFileList, ...selectDirList]; } }, detectPage() { let path = location.pathname; if (/^\/w/.test(path)) return 'home'; if (/^\/link|shareweb/.test(path)) return 'share'; return ''; }, isOnlyFolder() { for (let i = 0; i < selectList.length; i++) { if (selectList[i].contentID || selectList[i].contentName) return false; } return true; }, async initPanLinker() { page = this.detectPage(); base.createTip(); base.registerMenuCommand(); if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); this.addPageListener(); } else { this.addInitButton(); } } }; /** * 天翼云盘 * @author 油小猴 * @author hmjz100 */ let $tcloud = { addPageListener() { /* 防止代码因其他原因被执行多次 这段代码出自 Via轻插件,作者谷花泰 */ const key = encodeURIComponent('LinkSwift:天翼云盘'); if (window[key]) return; window[key] = true; function _factory(e) { let target = $(e.target); let item = target.parents('.pl-item'); let link = item.find('.pl-item-link.blob'); let directLink = item.find('.pl-item-link.browser'); let progress = item.find('.pl-item-progress'); let tip = item.find('.pl-item-tip'); let copy = item.find('.pl-item-copy'); let back = item.find('.pl-progress-back'); let stop = item.find('.pl-progress-stop'); return { item, link, directLink, progress, tip, copy, back, stop, target, }; } doc.on('click', '.pl-button-mode', function (e) { mode = e.target.dataset.mode; if (!mode) return; $tcloud.getLink(); }); doc.on('click', '.listener-link-api.browser', async function (e) { e.preventDefault(); let dataset = e.currentTarget.dataset; let href = dataset.link; $('#downloadIframe').attr('src', href); }); doc.on('click', '.listener-link-api.blob', async function (e) { e.preventDefault(); const o = _factory(e); const $width = o.item.find('.pl-progress-inner'); const $text = o.item.find('.pl-progress-inner-text'); const filename = o.link[0].dataset.filename; const index = o.link[0].dataset.index; const size = Number(o.link[0].dataset.size) || 0; base._resetData(index); base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index }); let startTime = Date.now(); let prevLoaded = 0; let prevTime = startTime; ins[index] = setInterval(async function () { const prog = +progress[index] || 0; const currentTime = Date.now(); const elapsedTime = currentTime - startTime; const loaded = prog * size / 100; const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零 const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0; // 计算剩余时间(保护除零) const totalProgress = Math.max(prog / 100, 0.01); const totalElapsedSeconds = elapsedTime / 1000; const estTotalTime = totalElapsedSeconds / totalProgress; const remainingTime = estTotalTime - totalElapsedSeconds; // 更新界面状态 o.link.hide(); o.directLink.hide(); o.tip.hide(); o.stop.show(); o.copy.hide(); o.progress.show(); // 更新进度条 $width.css('width', `${prog}%`); $text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`); // 更新历史值 prevLoaded = loaded; prevTime = currentTime; // 下载完成 if (prog >= 100) { await base.sleep(1000); clearInterval(ins[index]); progress[index] = 0; o.item.find('.pl-progress-stop').hide(); $text.text('下载完成~ 浏览器下载框应该弹出来了哦~'); o.back.show(); await base.sleep(3000); o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow"); } }, 500); }); doc.on('click', '.listener-retry', async function (e) { let o = _factory(e); o.tip.hide(); o.link.show(); o.directLink.show(); }); doc.on('click', '.listener-stop', async function (e) { let o = _factory(e); let index = o.link[0].dataset.index; if (request[index]) { request[index].abort(); clearInterval(ins[index]); o.item.find('.pl-progress-inner-text').text('正在取消...'); o.item.find('.pl-progress-inner').css('width', 100 + '%'); setTimeout(function () { o.tip.hide(); o.back.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.progress.hide(); o.stop.hide(); }, 1050) } }); doc.on('click', '.listener-back', async function (e) { let o = _factory(e); o.progress.hide(); o.tip.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.stop.hide(); o.back.hide(); }); doc.on('click', '.listener-download-all', function (e) { $('.pl-item-link.blob').each(function () { if ($(this).css('display') !== 'none') { $(this).click(); } }); $(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) { e.preventDefault(); base.setClipboard(decodeURIComponent(e.target.dataset.link)); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-rpc', async function (e) { let target = $(e.currentTarget); target.find('.icon-rpc-devices').remove(); target.find('.pl-loading').remove(); target.prepend(base.createLoading()); let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename); if (res === 'success') { $('.listener-rpc-task').show(); target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow"); } else if (res === 'assistant') { target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装👈`); } else { target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow"); } }); doc.on('click', '.listener-send-rpc', function (e) { $('.listener-link-rpc').click(); $(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); }); doc.on('click', '.listener-open-setting', function () { base.showSetting(); }); doc.on('click', '.listener-open-updatelog', function () { base.showUpdate(); }); doc.on('click', '.listener-open-beautify', function () { base.showBeautify(); }); doc.on('click', '.listener-rpc-task', function () { let rpc = JSON.stringify({ domain: base.getValue('setting_rpc_domain'), port: base.getValue('setting_rpc_port'), }), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`; GM_openInTab(url, { active: true }); }); }, greenerPage() { base.waitForKeyElements(".advertising-mask", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements("a.client-download.nav-block", function (tag) { tag.fadeOut(); }, true); }, addButton() { let $button = $(`
下载助手 
  • API 下载
  • Aria 下载
  • RPC 下载
  • cURL 下载
  • BC 下载
  • 助手设置
  • 助手美化
  • 更新日志
`); $button.find(".pl-dropdown-menu").css({ 'position': 'absolute', 'left': '-1px' }) base.waitForKeyElements(config.$tcloud.mount.home, (element) => { page = $tcloud.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'home') return; $button.find(".pl-dropdown-menu").css({ 'top': '28px' }) element.prepend($button); }) base.waitForKeyElements(config.$tcloud.mount.share, (element) => { page = $tcloud.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'share') return; $button.css({ 'height': '28px', 'border-radius': '15px' }) $button.find(".pl-dropdown-menu").css({ 'top': '25px' }) element.prepend($button); }) }, addInitButton() { let $button = $(`
点我点亮
`); $button.click(function () { base.initDialog() }); base.waitForKeyElements(config.$tcloud.mount.home, (element) => { page = $tcloud.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'home') return; element.prepend($button); }) base.waitForKeyElements(config.$tcloud.mount.share, (element) => { page = $tcloud.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'share') return; $button.css({ 'height': '28px', 'border-radius': '15px' }) element.prepend($button); }) }, async getToken() { doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取状态~
`); let res = await base.getFinalUrl(config.$tcloud.api.getAccessToken, {}); let accessToken = res.match(/accessToken=(\w+)/)?.[1]; accessToken && base.setStorage('accessToken', accessToken); doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
获取成功,令牌已缓存~
`); return accessToken; }, async getFileUrlByOnce(item, index, token) { try { if (item.downloadUrl) return { index, downloadUrl: item.downloadUrl }; let time = Date.now(), fileId = item.fileId, o = "AccessToken=" + token + "&Timestamp=" + time + "&fileId=" + fileId, url = config.$tcloud.api.getLink + '?fileId=' + fileId; if (item.shareId) { o = "AccessToken=" + token + "&Timestamp=" + time + "&dt=1&fileId=" + fileId + "&shareId=" + item.shareId; url += '&dt=1&shareId=' + item.shareId; } let sign = md5(o).toString(); let res = await base.get(url, { "accept": "application/json;charset=UTF-8", "sign-type": 1, "accesstoken": token, "timestamp": time, "signature": sign }); if (res.res_code === 0) { return { index, downloadUrl: res.fileDownloadUrl }; } else if (res.errorCode === 'InvalidSessionKey') { return { index, downloadUrl: '提示:
请先登录网盘~' }; } else if (res.res_code === 'ShareNotFoundFlatDir') { return { index, downloadUrl: '提示:
请[转存]文件,之后再👉前往[我的网盘]中下载哦~' }; } else { return { index, downloadUrl: '获取下载地址失败,刷新后再试试吧~' + (res.res_code ? res.res_code : "") }; } } catch (e) { return { index, downloadUrl: '获取下载地址失败,刷新后再试试吧~' }; } }, async getLink() { Swal.fire({ showConfirmButton: false, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, title: "获取中", html: `...`, footer: "如果选的文件较多,请耐心等待获取完成哦!", customClass: { popup: 'loading-popup', header: 'loading-header', title: 'loading-title', content: 'loading-content', input: 'loading-input', footer: 'loading-footer' }, willOpen: function () { Swal.showLoading(); }, ...swalDefault }); selectList = this.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要下载的文件哦~'); } if (this.isOnlyFolder()) { return message.error('提示:
请打开文件夹后再勾选文件~'); } selectList = selectList.filter(item => !item.isFolder) doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取状态~
`); let token = base.getStorage('accessToken') || await this.getToken(); if (!token) { return message.error('提示:
请先登录网盘~'); } doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
获取缓存成功~
`); let batchSize = 15; let processed = 0; doc.find('.loading-popup .loading-title').html(`链接获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取文件对应的下载链接~
`); for (let i = 0; i < selectList.length; i += batchSize) { let batch = selectList.slice(i, i + batchSize); let queue = []; batch.forEach((item, localIndex) => { let globalIndex = i + localIndex; queue.push(this.getFileUrlByOnce(item, globalIndex, token) .then(val => { processed++; doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} / ${selectList.length} 个链接~
`); return val; })); }); let res = await Promise.all(queue); res.forEach(val => { selectList[val.index].downloadUrl = val.downloadUrl; }); await base.sleep(1000); } let html = this.generateDom(selectList); base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer); }, generateDom(list) { console.log(list) if (!list) { return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~'); } let content = '
'; let alinkAllText = ''; list.forEach((v, i) => { if (v.isFolder) return; let filename = v.fileName; let size = base.sizeFormat(v.size); let dlink = v.downloadUrl; if (!dlink || !dlink.includes("http")) { content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`; } else { if (mode === 'api') { alinkAllText += dlink + '\r\n'; content += `
${filename}
`; } if (mode === 'aria') { let alink = base.convertLinkToAria(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'rpc') { content += `
${filename}
`; } if (mode === 'curl') { let alink = base.convertLinkToCurl(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'bc') { let alink = base.convertLinkToBC(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } } }); content += '
'; if (mode === 'rpc') { content += `
` } if (list.length >= 2) { if (mode === 'api') content += `
`; if (mode === 'aria') content += `
`; if (mode === 'rpc') { content += ``; } if (mode === 'curl') { content += `
`; } if (mode === 'bc') { content += `
`; } } if (mode === 'rpc') { let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path'); content += `
`; } return content; }, getSelectedList() { try { return document.querySelector(".c-file-list").__vue__.selectedList; } catch (e) { return [document.querySelector(".info-detail").__vue__.fileDetail]; } }, detectPage() { let path = location.pathname; if (/^\/web\/main/.test(path)) return 'home'; if (/^\/web\/share/.test(path)) return 'share'; return ''; }, isOnlyFolder() { for (let i = 0; i < selectList.length; i++) { if (!selectList[i].isFolder) return false; } return true; }, async initPanLinker() { page = this.detectPage(); base.createTip(); base.registerMenuCommand(); if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); this.addPageListener(); } else { this.addInitButton(); } this.getToken(); } }; /** * 迅雷云盘 * @author 油小猴 * @author hmjz100 */ let $xunlei = { addPageListener() { /* 防止代码因其他原因被执行多次 这段代码出自 Via轻插件,作者谷花泰 */ const key = encodeURIComponent('LinkSwift:迅雷云盘'); if (window[key]) return; window[key] = true; function _factory(e) { let target = $(e.target); let item = target.parents('.pl-item'); let link = item.find('.pl-item-link.blob'); let directLink = item.find('.pl-item-link.browser'); let progress = item.find('.pl-item-progress'); let tip = item.find('.pl-item-tip'); let copy = item.find('.pl-item-copy'); let back = item.find('.pl-progress-back'); let stop = item.find('.pl-progress-stop'); return { item, link, directLink, progress, tip, copy, back, stop, target, }; } doc.on('click', '.pl-button-mode', function (e) { mode = e.target.dataset.mode; if (!mode) return; $xunlei.getLink(); }); doc.on('click', '.pl-button-save', async function (e) { e.preventDefault(); selectList = $xunlei.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要保存到网盘的文件哦~'); } message.info('提示:
因网盘限制,请保存到自己网盘后再去下载哦~'); await base.sleep(500); document.querySelector('.saveToCloud').click(); }); doc.on('click', '.listener-link-api.browser', async function (e) { e.preventDefault(); let dataset = e.currentTarget.dataset; let href = dataset.link; $('#downloadIframe').attr('src', href); }); doc.on('click', '.listener-link-api.blob', async function (e) { e.preventDefault(); const o = _factory(e); const $width = o.item.find('.pl-progress-inner'); const $text = o.item.find('.pl-progress-inner-text'); const filename = o.link[0].dataset.filename; const index = o.link[0].dataset.index; const size = Number(o.link[0].dataset.size) || 0; base._resetData(index); base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index }); let startTime = Date.now(); let prevLoaded = 0; let prevTime = startTime; ins[index] = setInterval(async function () { const prog = +progress[index] || 0; const currentTime = Date.now(); const elapsedTime = currentTime - startTime; const loaded = prog * size / 100; const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零 const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0; // 计算剩余时间(保护除零) const totalProgress = Math.max(prog / 100, 0.01); const totalElapsedSeconds = elapsedTime / 1000; const estTotalTime = totalElapsedSeconds / totalProgress; const remainingTime = estTotalTime - totalElapsedSeconds; // 更新界面状态 o.link.hide(); o.directLink.hide(); o.tip.hide(); o.stop.show(); o.copy.hide(); o.progress.show(); // 更新进度条 $width.css('width', `${prog}%`); $text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`); // 更新历史值 prevLoaded = loaded; prevTime = currentTime; // 下载完成 if (prog >= 100) { await base.sleep(1000); clearInterval(ins[index]); progress[index] = 0; o.item.find('.pl-progress-stop').hide(); $text.text('下载完成~ 浏览器下载框应该弹出来了哦~'); o.back.show(); await base.sleep(3000); o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow"); } }, 500); }); doc.on('click', '.listener-retry', async function (e) { let o = _factory(e); o.tip.hide(); o.link.show(); o.directLink.show(); }); doc.on('click', '.listener-stop', async function (e) { let o = _factory(e); let index = o.link[0].dataset.index; if (request[index]) { request[index].abort(); clearInterval(ins[index]); o.item.find('.pl-progress-inner-text').text('正在取消...'); o.item.find('.pl-progress-inner').css('width', 100 + '%'); setTimeout(function () { o.tip.hide(); o.back.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.progress.hide(); o.stop.hide(); }, 1050) } }); doc.on('click', '.listener-back', async function (e) { let o = _factory(e); o.progress.hide(); o.tip.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.stop.hide(); o.back.hide(); }); doc.on('click', '.listener-download-all', function (e) { $('.pl-item-link.blob').each(function () { if ($(this).css('display') !== 'none') { $(this).click(); } }); $(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-copy-filename', async function (e) { base.setClipboard(e.target.dataset.filename); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-bc-btn', async function (e) { let mirror = base.getMirrorList(e.target.dataset.dlink, config.$xunlei.api.mirror); base.setClipboard(mirror); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) { e.preventDefault(); base.setClipboard(decodeURIComponent(e.target.dataset.link)); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-rpc', async function (e) { let target = $(e.currentTarget); target.find('.icon-rpc-devices').remove(); target.find('.pl-loading').remove(); target.prepend(base.createLoading()); let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename); if (res === 'success') { $('.listener-rpc-task').show(); target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow"); } else if (res === 'assistant') { target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装👈`); } else { target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow"); } }); doc.on('click', '.listener-send-rpc', function (e) { $('.listener-link-rpc').click(); $(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); }); doc.on('click', '.listener-open-setting', function () { base.showSetting(); }); doc.on('click', '.listener-open-updatelog', function () { base.showUpdate(); }); doc.on('click', '.listener-open-beautify', function () { base.showBeautify(); }); doc.on('click', '.listener-rpc-task', function () { let rpc = JSON.stringify({ domain: base.getValue('setting_rpc_domain'), port: base.getValue('setting_rpc_port'), }), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`; GM_openInTab(url, { active: true }); }); }, addButton() { base.waitForKeyElements(config.$xunlei.mount.home, (element) => { page = $xunlei.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'home') return; let $button = $(`
下载助手
  • API 下载
  • Aria 下载
  • RPC 下载
  • cURL 下载
  • BC 下载
  • 助手设置
  • 助手美化
  • 更新日志
`); element.prepend($button); }) base.waitForKeyElements(config.$xunlei.mount.share, (element) => { page = $xunlei.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'share') return; let $button = $(`
下载助手
  • 转存后下载
  • 助手设置
  • 助手美化
  • 更新日志
`); $button.css({ 'margin-right': '10px' }); element.prepend($button); }) }, addInitButton() { let $button = $(`
点我点亮
`); $button.click(function () { base.initDialog() }); base.waitForKeyElements(config.$xunlei.mount.home, (element) => { page = $xunlei.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'home') return; element.prepend($button); }) base.waitForKeyElements(config.$xunlei.mount.share, (element) => { page = $xunlei.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'share') return; $button.css({ 'margin-right': '10px' }); element.prepend($button); }) }, getToken() { doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取状态~
`); let credentials = {}, captcha = {}; for (let i = 0; i < localStorage.length; i++) { if (/^credentials_/.test(localStorage.key(i))) { credentials = base.getStorage(localStorage.key(i)); base.setStorage(''); } if (/^captcha_[\w]{16}/.test(localStorage.key(i))) { captcha = base.getStorage(localStorage.key(i)); } } let deviceid = /(\w{32})/.exec(base.getStorage('deviceid').split(','))[0]; let token = { credentials, captcha, deviceid }; return token; }, async getFileUrlByOnce(item, index, token) { try { if (item.downloadUrl) return { index, downloadUrl: item.downloadUrl }; let res = await base.get(config.$xunlei.api.getLink + item.id, { 'Authorization': `${token.credentials.token_type} ${token.credentials.access_token}`, 'content-type': "application/json", 'x-captcha-token': token.captcha.token, 'x-device-id': token.deviceid, }); if (res.web_content_link) { return { index, downloadUrl: res.web_content_link }; } else { return { index, downloadUrl: '获取下载地址失败,刷新后再试试吧~' }; } } catch (e) { return message.error('提示:
请先登录网盘后再刷新页面呢~'); } }, async getLink() { Swal.fire({ showConfirmButton: false, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, title: "获取中", html: `...`, footer: "如果选的文件较多,请耐心等待获取完成哦!", customClass: { popup: 'loading-popup', header: 'loading-header', title: 'loading-title', content: 'loading-content', input: 'loading-input', footer: 'loading-footer' }, willOpen: function () { Swal.showLoading(); }, ...swalDefault }); selectList = this.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要下载的文件哦~'); } if (this.isOnlyFolder()) { return message.error('提示:
请打开文件夹后再勾选文件~'); } if (page === 'home') { let token = this.getToken(); let batchSize = 15; let processed = 0; doc.find('.loading-popup .loading-title').html(`链接获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取文件对应的下载链接~
`); for (let i = 0; i < selectList.length; i += batchSize) { let batch = selectList.slice(i, i + batchSize); let queue = []; batch.forEach((item, localIndex) => { let globalIndex = i + localIndex; queue.push(this.getFileUrlByOnce(item, globalIndex, token) .then(val => { processed++; doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} / ${selectList.length} 个链接~
`); return val; })); }); let res = await Promise.all(queue); res.forEach(val => { selectList[val.index].downloadUrl = val.downloadUrl; }); await base.sleep(1000); } } else { return message.error('提示:
页面错误~'); } let html = this.generateDom(selectList); base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer); }, generateDom(list) { if (!list) { return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~'); } let content = '
'; let alinkAllText = ''; list.forEach((v, i) => { if (v.kind === 'drive#folder') return; let filename = v.name; let size = base.sizeFormat(+v.size); let dlink = v.downloadUrl; if (!dlink || !dlink.includes("http")) { content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`; } else { if (mode === 'api') { alinkAllText += dlink + '\r\n'; content += `
${filename}
直接下载(基于浏览器链接)
`; } if (mode === 'aria') { let alink = base.convertLinkToAria(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'rpc') { content += `
${filename}
`; } if (mode === 'curl') { let alink = base.convertLinkToCurl(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'bc') { let alink = base.convertLinkToBC(dlink, filename); alinkAllText += alink + '\r\n'; content += `
${filename}
${decodeURIComponent(alink)}
下载 ${filename}
`; } } }); content += ''; if (mode === 'rpc') { content += `
` } if (list.length >= 2) { if (mode === 'api') content += `
`; if (mode === 'aria') content += `
`; if (mode === 'rpc') { content += ``; } if (mode === 'curl') { content += `
`; } if (mode === 'bc') { content += `
`; } } if (mode === 'rpc') { let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path'); content += `
`; } return content; }, getSelectedList() { try { let doms = document.querySelectorAll('.SourceListItem__item--XxpOC'); let selectedList = []; for (let dom of doms) { let domVue = dom.__vue__; if (domVue.selected.includes(domVue.info.id)) { selectedList.push(domVue.info); } } return selectedList; } catch (e) { return []; } }, detectPage() { let path = location.pathname; if (/^\/$/.test(path)) return 'home'; if (/^\/(s|share)\//.test(path)) return 'share'; return ''; }, isOnlyFolder() { for (let i = 0; i < selectList.length; i++) { if (selectList[i].kind === 'drive#file') return false; } return true; }, async initPanLinker() { page = this.detectPage(); base.createTip(); base.registerMenuCommand(); if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); this.addPageListener(); } else { this.addInitButton(); } } }; /** * 夸克网盘 * @author 油小猴 * @author hmjz100 */ let $quark = { addPageListener() { /* 防止代码因其他原因被执行多次 这段代码出自 Via轻插件,作者谷花泰 */ const key = encodeURIComponent('LinkSwift:夸克网盘'); if (window[key]) return; window[key] = true; function _factory(e) { let target = $(e.target); let item = target.parents('.pl-item'); let link = item.find('.pl-item-link.blob'); let directLink = item.find('.pl-item-link.browser'); let progress = item.find('.pl-item-progress'); let tip = item.find('.pl-item-tip'); let copy = item.find('.pl-item-copy'); let back = item.find('.pl-progress-back'); let stop = item.find('.pl-progress-stop'); return { item, link, directLink, progress, tip, copy, back, stop, target, }; } window.addEventListener('hashchange', async function (e) { let home = 'https://pan.quark.cn/list#/', all = 'https://pan.quark.cn/list#/list/all'; if (e.oldURL === home && e.newURL === all) return; await base.sleep(150); if ($('.quark-button').length > 0) return; if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); this.addPageListener(); } else { this.addInitButton(); } }); doc.on('click', '.pl-button-mode', function (e) { mode = e.target.dataset.mode; if (!mode) return; $quark.getLink(); }); doc.on('click', '.pl-button-save', async function (e) { e.preventDefault(); selectList = $quark.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要保存到网盘的文件哦~'); } message.info('提示:
因网盘限制,请保存到自己网盘后再去下载哦~'); await base.sleep(500); document.querySelector('.share-path').click(); base.waitForKeyElements(".btn-file.btn-file-primary.confirm-btn", (element) => { element.one("click", async () => { await base.sleep(1000); document.querySelector('.share-save').click(); }) return true; }, true) }); doc.on('click', '.listener-link-api.browser', async function (e) { e.preventDefault(); let dataset = e.currentTarget.dataset; let href = dataset.link; $('#downloadIframe').attr('src', href); }); doc.on('click', '.listener-link-api.blob', async function (e) { e.preventDefault(); const o = _factory(e); const $width = o.item.find('.pl-progress-inner'); const $text = o.item.find('.pl-progress-inner-text'); const filename = o.link[0].dataset.filename; const index = o.link[0].dataset.index; const size = Number(o.link[0].dataset.size) || 0; base._resetData(index); base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index }); let startTime = Date.now(); let prevLoaded = 0; let prevTime = startTime; ins[index] = setInterval(async function () { const prog = +progress[index] || 0; const currentTime = Date.now(); const elapsedTime = currentTime - startTime; const loaded = prog * size / 100; const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零 const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0; // 计算剩余时间(保护除零) const totalProgress = Math.max(prog / 100, 0.01); const totalElapsedSeconds = elapsedTime / 1000; const estTotalTime = totalElapsedSeconds / totalProgress; const remainingTime = estTotalTime - totalElapsedSeconds; // 更新界面状态 o.link.hide(); o.directLink.hide(); o.tip.hide(); o.stop.show(); o.copy.hide(); o.progress.show(); // 更新进度条 $width.css('width', `${prog}%`); $text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`); // 更新历史值 prevLoaded = loaded; prevTime = currentTime; // 下载完成 if (prog >= 100) { await base.sleep(1000); clearInterval(ins[index]); progress[index] = 0; o.item.find('.pl-progress-stop').hide(); $text.text('下载完成~ 浏览器下载框应该弹出来了哦~'); o.back.show(); await base.sleep(3000); o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow"); } }, 500); }); doc.on('click', '.listener-retry', async function (e) { let o = _factory(e); o.tip.hide(); o.link.show(); o.directLink.show(); }); doc.on('click', '.listener-stop', async function (e) { let o = _factory(e); let index = o.link[0].dataset.index; if (request[index]) { request[index].abort(); clearInterval(ins[index]); o.item.find('.pl-progress-inner-text').text('正在取消...'); o.item.find('.pl-progress-inner').css('width', 100 + '%'); setTimeout(function () { o.tip.hide(); o.back.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.progress.hide(); o.stop.hide(); }, 1050) } }); doc.on('click', '.listener-back', async function (e) { let o = _factory(e); o.progress.hide(); o.tip.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.stop.hide(); o.back.hide(); }); doc.on('click', '.listener-download-all', function (e) { $('.pl-item-link.blob').each(function () { if ($(this).css('display') !== 'none') { $(this).click(); } }); $(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) { e.preventDefault(); base.setClipboard(decodeURIComponent(e.target.dataset.link)); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-rpc', async function (e) { let target = $(e.currentTarget); target.find('.icon-rpc-devices').remove(); target.find('.pl-loading').remove(); target.prepend(base.createLoading()); let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename, [`Cookie: ${document.cookie}`]); if (res === 'success') { $('.listener-rpc-task').show(); target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow"); } else if (res === 'assistant') { target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装👈`); } else { target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow"); } }); doc.on('click', '.listener-send-rpc', function (e) { $('.listener-link-rpc').click(); $(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); }); doc.on('click', '.listener-open-setting', function () { base.showSetting(); }); doc.on('click', '.listener-open-updatelog', function () { base.showUpdate(); }); doc.on('click', '.listener-open-beautify', function () { base.showBeautify(); }); doc.on('click', '.listener-rpc-task', function () { let rpc = JSON.stringify({ domain: base.getValue('setting_rpc_domain'), port: base.getValue('setting_rpc_port'), }), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`; GM_openInTab(url, { active: true }); }); }, greenerPage() { base.waitForKeyElements('[class*="Activity--video-toolbar-activity"]', function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements('span[class*="SectionHeaderController--icon-download"]', function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements('div[class*="SectionHeaderController--download-popover"]', function (tag) { tag.find(".ant-popover-arrow").css({ "left": "75%" }); }, true); base.waitForKeyElements('div[class*="DetailLayout--client-download"]', function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".next-box.share-right-side-content", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements('[class*="DetailLayout--container"] .feature-screen', function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements('.ant-modal-content .ant-modal-body .right-wrap', function (tag) { if (tag.find(".hint").text().includes("客户端")) tag.fadeOut(); }, true); base.waitForKeyElements(".pc-member-entrance span.button-text", function (tag) { tag.text("会员中心"); let observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (tag.text() === "会员中心") return tag.text("会员中心"); }); }); let config = { subtree: true, characterData: true, childList: true }; observer.observe(tag[0], config); }, true); base.waitForKeyElements(".pc-member-entrance .tips", function (tag) { tag.fadeOut(); }, true); base.waitForKeyElements(".modal .modal-content .halo-animated-background .halo-content .pay-modal .close", function (tag) { tag[0].click(); }, true); base.waitForKeyElements(".modal .modal-content .halo-animated-background .halo-content .red-envelope .close", function (tag) { tag[0].click(); }, true); }, svg: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiI+PHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNOSAxMmwyIDIgMi0yeiIvPjxwYXRoIGQ9Ik0xNCA4aDEuNTUzYy44NSAwIDEuMTYuMDkzIDEuNDcuMjY3LjMxMS4xNzQuNTU2LjQzLjcyMi43NTYuMTY2LjMyNi4yNTUuNjUuMjU1IDEuNTR2NC44NzNjMCAuODkyLS4wODkgMS4yMTUtLjI1NSAxLjU0LS4xNjYuMzI3LS40MS41ODMtLjcyMi43NTctLjMxLjE3NC0uNjIuMjY3LTEuNDcuMjY3SDYuNDQ3Yy0uODUgMC0xLjE2LS4wOTMtMS40Ny0uMjY3YTEuNzc4IDEuNzc4IDAgMDEtLjcyMi0uNzU2Yy0uMTY2LS4zMjYtLjI1NS0uNjUtLjI1NS0xLjU0di00Ljg3M2MwLS44OTIuMDg5LTEuMjE1LjI1NS0xLjU0LjE2Ni0uMzI3LjQxLS41ODMuNzIyLS43NTcuMzEtLjE3NC42Mi0uMjY3IDEuNDctLjI2N0gxMSIvPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTExIDN2MTAiLz48L2c+PC9zdmc+', addButton() { base.waitForKeyElements(config.$quark.mount.home, (element) => { page = $quark.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'home') return; let $button = $(`
RPC发送
`); $button.css({ "margin-right": "10px", "display": "inline-block" }); element.prepend($button); }) base.waitForKeyElements(config.$quark.mount.share, (element) => { page = $quark.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'share') return; let $button = $(``); $button.css({ "height": "36px", "margin-left": "16px", "border-radius": "6px", "display": "inline-block" }); element.append($button); }) }, addInitButton() { base.waitForKeyElements(config.$quark.mount.home, (element) => { page = $quark.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'home') return; let $button = $(`
`); $button.css({ "margin-right": "10px", "display": "inline-block" }); $button.click(function () { base.initDialog() }); element.prepend($button); }) base.waitForKeyElements(config.$quark.mount.share, (element) => { page = $quark.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'share') return; let $button = $(``); $button.css({ "height": "36px", "margin-left": "16px", "border-radius": "6px", "display": "inline-block" }); $button.click(function () { base.initDialog() }); element.append($button); }) }, async getLink() { Swal.fire({ showConfirmButton: false, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, title: "获取中", html: `...`, footer: "如果选的文件较多,请耐心等待获取完成哦!", customClass: { popup: 'loading-popup', header: 'loading-header', title: 'loading-title', content: 'loading-content', input: 'loading-input', footer: 'loading-footer' }, willOpen: function () { Swal.showLoading(); }, ...swalDefault }); selectList = this.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要下载的文件哦~'); } if (this.isOnlyFolder()) { return message.error('提示:
请打开文件夹后再勾选文件~'); } if (page === 'home') { let data = []; let batchSize = 15; let processed = 0; selectList = selectList.filter(item => item.file === true) for (let i = 0; i < selectList.length; i += batchSize) { // 获取当前批次文件 let batch = selectList.slice(i, i + batchSize); console.log() let fids = batch.map(item => item.fid); // 发起请求获取链接 let res = await base.post(config.$quark.api.getLink, { "fids": fids }, { "content-type": "application/json;charset=utf-8", "user-agent": config.$quark.api.ua.downloadLink }); if (res?.code === 31001) { return message.error('提示:
请先登录网盘~
代码:' + res.code); } if (res?.code !== 0) { return message.error('提示:
获取链接失败了~
代码:' + res.code); } // 合并响应数据 if (res?.data) { data.push(...res.data); } // 更新处理进度 processed += batch.length; // 更新UI显示 doc.find('.loading-popup .loading-title').html(`链接获取中`); doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} / ${selectList.length} 个链接~
`); // 请求间隔节流 await base.sleep(1000); } let html = this.generateDom(data); base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer); } else { return message.error('提示:
页面错误~'); } }, generateDom(list) { if (!list) { return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~'); } let content = '
'; let alinkAllText = ''; list.forEach((v, i) => { if (v.file === false) return; let filename = v.file_name; let fid = v.fid; let size = base.sizeFormat(v.size); let dlink = v.download_url; if (!dlink || !dlink.includes("http")) { content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`; } else { if (mode === 'api') { alinkAllText += dlink + '\r\n'; content += `
${filename}
`; } if (mode === 'aria') { let alink = base.convertLinkToAria(dlink, filename, `--header "Cookie: ${document.cookie}"`); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'rpc') { content += `
${filename}
`; } if (mode === 'curl') { let alink = base.convertLinkToCurl(dlink, filename, `-b "${document.cookie}"`); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'bc') { let alink = base.convertLinkToBC(dlink, filename, `cookie=${encodeURIComponent(document.cookie)}`); alinkAllText += alink + '\r\n'; content += ``; } } }); content += '
'; if (mode === 'rpc') { content += `
` } if (list.length >= 2) { if (mode === 'api') content += `
`; if (mode === 'aria') content += `
`; if (mode === 'rpc') { content += ``; } if (mode === 'curl') { content += `
`; } if (mode === 'bc') { content += `
`; } } if (mode === 'rpc') { let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path'); content += `
`; } return content; }, getSelectedList() { try { let selectedList = []; let reactDom = document.getElementsByClassName('file-list')[0]; let reactObj = base.findReact(reactDom); let props = reactObj.props; if (props) { let fileList = props.list || []; let selectedKeys = props.selectedRowKeys || []; fileList.forEach(function (val) { if (selectedKeys.includes(val.fid)) { selectedList.push(val); } }); } return selectedList; } catch (e) { return []; } }, detectPage() { let path = location.pathname; if (/^\/(list)/.test(path)) return 'home'; if (/^\/(s|share)\//.test(path)) return 'share'; return ''; }, isOnlyFolder() { for (let i = 0; i < selectList.length; i++) { if (selectList[i].file) return false; } return true; }, async initPanLinker() { page = this.detectPage(); base.createTip(); base.registerMenuCommand(); if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); this.addPageListener(); } else { this.addInitButton(); } } }; /** * UC网盘 * @author 油小猴 * @author hmjz100 */ let $uc = { addPageListener() { /* 防止代码因其他原因被执行多次 这段代码出自 Via轻插件,作者谷花泰 */ const key = encodeURIComponent('LinkSwift:UC网盘'); if (window[key]) return; window[key] = true; function _factory(e) { let target = $(e.target); let item = target.parents('.pl-item'); let link = item.find('.pl-item-link.blob'); let directLink = item.find('.pl-item-link.browser'); let progress = item.find('.pl-item-progress'); let tip = item.find('.pl-item-tip'); let copy = item.find('.pl-item-copy'); let back = item.find('.pl-progress-back'); let stop = item.find('.pl-progress-stop'); return { item, link, directLink, progress, tip, copy, back, stop, target, }; } window.addEventListener('hashchange', async function (e) { let home = 'https://drive.uc.cn/list#/', all = 'https://drive.uc.cn/list#/list/all'; if (e.oldURL === home && e.newURL === all) return; await base.sleep(150); if ($('.uc-button').length > 0) return; if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); this.addPageListener(); } else { this.addInitButton(); } }); doc.on('click', '.pl-button-mode', function (e) { mode = e.target.dataset.mode; if (!mode) return; $uc.getLink(); }); doc.on('click', '.pl-button-save', async function (e) { e.preventDefault(); selectList = $uc.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要保存到网盘的文件哦~'); } message.info('提示:
因网盘限制,请保存到自己网盘后再去下载哦~'); await base.sleep(500); document.querySelector('.file-info_r').click(); }); doc.on('click', '.listener-link-api.browser', async function (e) { e.preventDefault(); let dataset = e.currentTarget.dataset; let href = dataset.link; $('#downloadIframe').attr('src', href); }); doc.on('click', '.listener-link-api.blob', async function (e) { e.preventDefault(); const o = _factory(e); const $width = o.item.find('.pl-progress-inner'); const $text = o.item.find('.pl-progress-inner-text'); const filename = o.link[0].dataset.filename; const index = o.link[0].dataset.index; const size = Number(o.link[0].dataset.size) || 0; base._resetData(index); base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index }); let startTime = Date.now(); let prevLoaded = 0; let prevTime = startTime; ins[index] = setInterval(async function () { const prog = +progress[index] || 0; const currentTime = Date.now(); const elapsedTime = currentTime - startTime; const loaded = prog * size / 100; const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零 const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0; // 计算剩余时间(保护除零) const totalProgress = Math.max(prog / 100, 0.01); const totalElapsedSeconds = elapsedTime / 1000; const estTotalTime = totalElapsedSeconds / totalProgress; const remainingTime = estTotalTime - totalElapsedSeconds; // 更新界面状态 o.link.hide(); o.directLink.hide(); o.tip.hide(); o.stop.show(); o.copy.hide(); o.progress.show(); // 更新进度条 $width.css('width', `${prog}%`); $text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`); // 更新历史值 prevLoaded = loaded; prevTime = currentTime; // 下载完成 if (prog >= 100) { await base.sleep(1000); clearInterval(ins[index]); progress[index] = 0; o.item.find('.pl-progress-stop').hide(); $text.text('下载完成~ 浏览器下载框应该弹出来了哦~'); o.back.show(); await base.sleep(3000); o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow"); } }, 500); }); doc.on('click', '.listener-retry', async function (e) { let o = _factory(e); o.tip.hide(); o.link.show(); o.directLink.show(); }); doc.on('click', '.listener-stop', async function (e) { let o = _factory(e); let index = o.link[0].dataset.index; if (request[index]) { request[index].abort(); clearInterval(ins[index]); o.item.find('.pl-progress-inner-text').text('正在取消...'); o.item.find('.pl-progress-inner').css('width', 100 + '%'); setTimeout(function () { o.tip.hide(); o.back.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.progress.hide(); o.stop.hide(); }, 1050) } }); doc.on('click', '.listener-back', async function (e) { let o = _factory(e); o.progress.hide(); o.tip.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.stop.hide(); o.back.hide(); }); doc.on('click', '.listener-download-all', function (e) { $('.pl-item-link.blob').each(function () { if ($(this).css('display') !== 'none') { $(this).click(); } }); $(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) { e.preventDefault(); base.setClipboard(decodeURIComponent(e.target.dataset.link)); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-rpc', async function (e) { let target = $(e.currentTarget); target.find('.icon-rpc-devices').remove(); target.find('.pl-loading').remove(); target.prepend(base.createLoading()); let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename, [`Cookie: ${document.cookie}`]); if (res === 'success') { $('.listener-rpc-task').show(); target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow"); } else if (res === 'assistant') { target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装👈`); } else { target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow"); } }); doc.on('click', '.listener-send-rpc', function (e) { $('.listener-link-rpc').click(); $(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); }); doc.on('click', '.listener-open-setting', function () { base.showSetting(); }); doc.on('click', '.listener-open-updatelog', function () { base.showUpdate(); }); doc.on('click', '.listener-open-beautify', function () { base.showBeautify(); }); doc.on('click', '.listener-rpc-task', function () { let rpc = JSON.stringify({ domain: base.getValue('setting_rpc_domain'), port: base.getValue('setting_rpc_port'), }), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`; GM_openInTab(url, { active: true }); }); }, greenerPage() { base.waitForKeyElements('[class*="VideoDetail--content-footer"]', function (tag) { tag.children().each(function () { const $child = $(this); if ($child.text().includes('手机客户端')) { $child.hide(); } }); }, true); base.waitForKeyElements('[class*="PCLandingBanner--ad-block"]', function (tag) { tag.hide(); }, true); }, svg: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiI+PHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNOSAxMmwyIDIgMi0yeiIvPjxwYXRoIGQ9Ik0xNCA4aDEuNTUzYy44NSAwIDEuMTYuMDkzIDEuNDcuMjY3LjMxMS4xNzQuNTU2LjQzLjcyMi43NTYuMTY2LjMyNi4yNTUuNjUuMjU1IDEuNTR2NC44NzNjMCAuODkyLS4wODkgMS4yMTUtLjI1NSAxLjU0LS4xNjYuMzI3LS40MS41ODMtLjcyMi43NTctLjMxLjE3NC0uNjIuMjY3LTEuNDcuMjY3SDYuNDQ3Yy0uODUgMC0xLjE2LS4wOTMtMS40Ny0uMjY3YTEuNzc4IDEuNzc4IDAgMDEtLjcyMi0uNzU2Yy0uMTY2LS4zMjYtLjI1NS0uNjUtLjI1NS0xLjU0di00Ljg3M2MwLS44OTIuMDg5LTEuMjE1LjI1NS0xLjU0LjE2Ni0uMzI3LjQxLS41ODMuNzIyLS43NTcuMzEtLjE3NC42Mi0uMjY3IDEuNDctLjI2N0gxMSIvPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTExIDN2MTAiLz48L2c+PC9zdmc+', addButton() { base.waitForKeyElements(config.$uc.mount.home, (element) => { page = $uc.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'home') return; let $button = $(`
  • API 下载
  • Aria 下载
  • RPC 下载
  • cURL 下载
  • BC 下载
  • 助手设置
  • 助手美化
  • 更新日志
`); $button.css({ "margin-right": "10px", "display": "inline-block" }); element.prepend($button); }) base.waitForKeyElements(config.$uc.mount.share, (element) => { page = $uc.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'share') return; let $button = $(`
  • 保存后下载
  • 助手设置
  • 助手美化
  • 更新日志
`); $button.css({ "margin-left": "10px", "display": "inline-block" }); element.append($button); }) }, addInitButton() { let $button = $(`
`); $button.click(function () { base.initDialog() }); base.waitForKeyElements(config.$uc.mount.home, (element) => { page = $uc.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'home') return; $button.css({ "margin-right": "10px", "display": "inline-block" }); element.prepend($button); }) base.waitForKeyElements(config.$uc.mount.share, (element) => { page = $uc.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'share') return; $button.css({ "margin-left": "10px", "display": "inline-block" }); element.append($button); }) }, async getLink() { Swal.fire({ showConfirmButton: false, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, title: "获取中", html: `...`, footer: "如果选的文件较多,请耐心等待获取完成哦!", customClass: { popup: 'loading-popup', header: 'loading-header', title: 'loading-title', content: 'loading-content', input: 'loading-input', footer: 'loading-footer' }, willOpen: function () { Swal.showLoading(); }, ...swalDefault }); selectList = this.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要下载的文件哦~'); } if (this.isOnlyFolder()) { return message.error('提示:
请打开文件夹后再勾选文件~'); } if (page === 'home') { let data = []; let batchSize = 15; let processed = 0; selectList = selectList.filter(item => item.file === true) for (let i = 0; i < selectList.length; i += batchSize) { // 获取当前批次文件 let batch = selectList.slice(i, i + batchSize); console.log() let fids = batch.map(item => item.fid); // 发起请求获取链接 let res = await base.post(config.$uc.api.getLink, { "fids": fids }, { "content-type": "application/json;charset=utf-8", "user-agent": config.$quark.api.ua.downloadLink }); if (res?.code === 31001) { return message.error('提示:
请先登录网盘~
代码:' + res.code); } if (res?.code !== 0) { return message.error('提示:
获取链接失败了~
代码:' + res.code); } // 合并响应数据 if (res?.data) { data.push(...res.data); } // 更新处理进度 processed += batch.length; // 更新UI显示 doc.find('.loading-popup .loading-title').html(`链接获取中`); doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} / ${selectList.length} 个链接~
`); // 请求间隔节流 await base.sleep(1000); } let html = this.generateDom(data); base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer); } else { return message.error('提示:
页面错误~'); } }, generateDom(list) { if (!list) { return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~'); } let content = '
'; let alinkAllText = ''; list.forEach((v, i) => { if (v.file === false) return; let filename = v.file_name; let fid = v.fid; let size = base.sizeFormat(v.size); let dlink = v.download_url; if (!dlink || !dlink.includes("http")) { content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`; } else { if (mode === 'api') { alinkAllText += dlink + '\r\n'; content += `
${filename}
`; } if (mode === 'aria') { let alink = base.convertLinkToAria(dlink, filename, `--header "Cookie: ${document.cookie}"`); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'rpc') { content += `
${filename}
`; } if (mode === 'curl') { let alink = base.convertLinkToCurl(dlink, filename, `-b "${document.cookie}"`); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'bc') { let alink = base.convertLinkToBC(dlink, filename, `cookie=${encodeURIComponent(document.cookie)}`); alinkAllText += alink + '\r\n'; content += ``; } } }); content += '
'; if (mode === 'rpc') { content += `
` } if (list.length >= 2) { if (mode === 'api') content += `
`; if (mode === 'aria') content += `
`; if (mode === 'rpc') { content += ``; } if (mode === 'curl') { content += `
`; } if (mode === 'bc') { content += `
`; } } if (mode === 'rpc') { let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path'); content += `
`; } return content; }, getSelectedList() { try { let selectedList = []; let reactDom = document.getElementsByClassName('file-list')[0]; let reactObj = base.findReact(reactDom); let props = reactObj.props; if (props) { let fileList = props.list || []; let selectedKeys = props.selectedRowKeys || []; fileList.forEach(function (val) { if (selectedKeys.includes(val.fid)) { selectedList.push(val); } }); } return selectedList; } catch (e) { return []; } }, detectPage() { let path = location.pathname; if (/^\/(list)/.test(path)) return 'home'; if (/^\/(s|share)\//.test(path)) return 'share'; return ''; }, isOnlyFolder() { for (let i = 0; i < selectList.length; i++) { if (selectList[i].file) return false; } return true; }, async initPanLinker() { page = this.detectPage(); base.createTip(); base.registerMenuCommand(); if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); this.addPageListener(); } else { this.addInitButton(); } } }; /** * 123云盘 * @author 油小猴 * @author hmjz100 */ let $123pan = { addPageListener() { /* 防止代码因其他原因被执行多次 这段代码出自 Via轻插件,作者谷花泰 */ const key = encodeURIComponent('LinkSwift:123云盘'); if (window[key]) return; window[key] = true; function _factory(e) { let target = $(e.target); let item = target.parents('.pl-item'); let link = item.find('.pl-item-link.blob'); let directLink = item.find('.pl-item-link.browser'); let progress = item.find('.pl-item-progress'); let tip = item.find('.pl-item-tip'); let copy = item.find('.pl-item-copy'); let back = item.find('.pl-progress-back'); let stop = item.find('.pl-progress-stop'); return { item, link, directLink, progress, tip, copy, back, stop, target, }; } doc.on('click', '.pl-button-mode', function (e) { mode = e.target.dataset.mode; if (!mode) return; $123pan.getLink(); }); doc.on('click', '.pl-button-save', async function (e) { e.preventDefault(); selectList = $123pan.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要保存到网盘的文件哦~'); } message.info('提示:
因网盘限制,请保存到自己网盘后再去下载哦~'); await base.sleep(500); document.querySelector('.file-info_r').click(); }); doc.on('click', '.listener-link-api.browser', async function (e) { e.preventDefault(); let dataset = e.currentTarget.dataset; let href = dataset.link; $('#downloadIframe').attr('src', href); }); doc.on('click', '.listener-link-api.blob', async function (e) { e.preventDefault(); const o = _factory(e); const $width = o.item.find('.pl-progress-inner'); const $text = o.item.find('.pl-progress-inner-text'); const filename = o.link[0].dataset.filename; const index = o.link[0].dataset.index; const size = Number(o.link[0].dataset.size) || 0; base._resetData(index); base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index }); let startTime = Date.now(); let prevLoaded = 0; let prevTime = startTime; ins[index] = setInterval(async function () { const prog = +progress[index] || 0; const currentTime = Date.now(); const elapsedTime = currentTime - startTime; const loaded = prog * size / 100; const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零 const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0; // 计算剩余时间(保护除零) const totalProgress = Math.max(prog / 100, 0.01); const totalElapsedSeconds = elapsedTime / 1000; const estTotalTime = totalElapsedSeconds / totalProgress; const remainingTime = estTotalTime - totalElapsedSeconds; // 更新界面状态 o.link.hide(); o.directLink.hide(); o.tip.hide(); o.stop.show(); o.copy.hide(); o.progress.show(); // 更新进度条 $width.css('width', `${prog}%`); $text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`); // 更新历史值 prevLoaded = loaded; prevTime = currentTime; // 下载完成 if (prog >= 100) { await base.sleep(1000); clearInterval(ins[index]); progress[index] = 0; o.item.find('.pl-progress-stop').hide(); $text.text('下载完成~ 浏览器下载框应该弹出来了哦~'); o.back.show(); await base.sleep(3000); o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow"); } }, 500); }); doc.on('click', '.listener-retry', async function (e) { let o = _factory(e); o.tip.hide(); o.link.show(); o.directLink.show(); }); doc.on('click', '.listener-stop', async function (e) { let o = _factory(e); let index = o.link[0].dataset.index; if (request[index]) { request[index].abort(); clearInterval(ins[index]); o.item.find('.pl-progress-inner-text').text('正在取消...'); o.item.find('.pl-progress-inner').css('width', 100 + '%'); setTimeout(function () { o.tip.hide(); o.back.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.progress.hide(); o.stop.hide(); }, 1050) } }); doc.on('click', '.listener-back', async function (e) { let o = _factory(e); o.progress.hide(); o.tip.hide(); o.link.show(); o.directLink.show(); o.copy.show(); o.stop.hide(); o.back.hide(); }); doc.on('click', '.listener-download-all', function (e) { $('.pl-item-link.blob').each(function () { if ($(this).css('display') !== 'none') { $(this).click(); } }); $(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) { e.preventDefault(); base.setClipboard(decodeURIComponent(e.target.dataset.link)); $(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow"); setTimeout(function () { $(e.target).text('重新复制').animate({ opacity: '1' }, "slow"); }, 2000) }); doc.on('click', '.listener-link-rpc', async function (e) { let target = $(e.currentTarget); target.find('.icon-rpc-devices').remove(); target.find('.pl-loading').remove(); target.prepend(base.createLoading()); let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename); if (res === 'success') { $('.listener-rpc-task').show(); target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow"); } else if (res === 'assistant') { target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装👈`); } else { target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow"); } }); doc.on('click', '.listener-send-rpc', function (e) { $('.listener-link-rpc').click(); $(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow"); }); doc.on('click', '.listener-open-setting', function () { base.showSetting(); }); doc.on('click', '.listener-open-updatelog', function () { base.showUpdate(); }); doc.on('click', '.listener-open-beautify', function () { base.showBeautify(); }); doc.on('click', '.listener-rpc-task', function () { let rpc = JSON.stringify({ domain: base.getValue('setting_rpc_domain'), port: base.getValue('setting_rpc_port'), }), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`; GM_openInTab(url, { active: true }); }); }, greenerPage() { base.waitForKeyElements(".new-menu-item-image, .special-menu-item-container-migration--label, .sider-member-btn, .video-new-user-tips", (tag) => { if (tag.is(":hidden")) return; tag.hide(); }, true) let allowedTexts = ["其他网盘数据转入", "同步空间", "回收站", "下载客户端"]; base.waitForKeyElements(`.ant-menu.ant-menu-root.ant-menu-inline[role="menu"]`, (tag) => { tag.find(`[role="menuitem"]`).each(function () { const menuText = $(this).text().trim(); if (!allowedTexts.includes(menuText) || $(this).is(":hidden")) return; $(this).hide(); }); }, true) base.waitForKeyElements(".special-menu-item-container", (tag) => { tag.find(".special-menu-item-container-migration").each(function () { const menuText = $(this).text().trim(); if (!allowedTexts.includes(menuText) || $(this).is(":hidden")) return; $(this).hide(); }); }, true) base.waitForKeyElements(`.header-btn-list`, (tag) => { tag.find(`.btn-item`).each(function () { const menuText = $(this).text().trim(); if (!allowedTexts.includes(menuText) || $(this).is(":hidden")) return; $(this).hide(); }); }, true) base.waitForKeyElements(`.rightInfo .register:not(.pl-button, .pl-button-init), .homeClass > div > .ant-dropdown-trigger:not(.pl-button, .pl-button-init), .homeClass > div > .sysbut`, function (tag) { let hasTextNode = false; tag.contents().each(function () { if (this.nodeType === 3 && $.trim(this.textContent)) { hasTextNode = true; return; } }); if (!hasTextNode) return; tag.css({ "width": "38px" }); tag.contents().each(function () { if (this.nodeType === 3) { $(this).remove(); } }); tag.find('svg').css({ "margin-right": "0" }); }); base.waitForKeyElements('.rightInfo .qrcode_btn', function (tag) { tag.hide(); }, true); }, getToken() { doc.find('.loading-popup .loading-title').html(`令牌获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取令牌~
`); let token = base.getStorage("authorToken"); return token; }, async getLink() { Swal.fire({ showConfirmButton: false, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false, title: "获取中", html: `...`, footer: "如果选的文件较多,请耐心等待获取完成哦!", customClass: { popup: 'loading-popup', header: 'loading-header', title: 'loading-title', content: 'loading-content', input: 'loading-input', footer: 'loading-footer' }, willOpen: function () { Swal.showLoading(); }, ...swalDefault }); selectList = this.getSelectedList(); if (selectList.length === 0) { return message.error('提示:
请勾选要下载的文件哦~'); } if (this.isOnlyFolder()) { return message.error('提示:
请打开文件夹后再勾选文件~'); } console.log(selectList); if (page === 'home') { let token = this.getToken(); let batchSize = 15; let processed = 0; selectList = selectList.filter(item => item.Type === 0); for (let i = 0; i < selectList.length; i += batchSize) { let batch = selectList.slice(i, i + batchSize); let queue = []; doc.find('.loading-popup .loading-title').html(`链接获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取文件对应的下载链接~
`); batch.forEach((item, localIndex) => { let globalIndex = i + localIndex; queue.push(this.getFileUrlByOnce(item, globalIndex, token) .then(val => { processed++; doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} / ${selectList.length} 个链接~
`); return val; })); }); let res = await Promise.all(queue); res.forEach(val => { selectList[val.index].DownloadUrl = val.downloadUrl; }); await base.sleep(1000); } let html = this.generateDom(selectList); base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer); } else if (page === 'share') { let token = this.getToken(); let batchSize = 15; let processed = 0; selectList = selectList.filter(item => item.Type === 0); let pathSplit = location.pathname.split('/').filter(Boolean); let ShareKey = pathSplit[1]; console.log(selectList) for (let i = 0; i < selectList.length; i += batchSize) { let batch = selectList.slice(i, i + batchSize); let queue = []; doc.find('.loading-popup .loading-title').html(`链接获取中`); doc.find('.loading-popup .swal2-html-container').html(`
正在获取文件对应的下载链接~
`); batch.forEach((item, localIndex) => { let globalIndex = i + localIndex; queue.push(this.getFileUrlByOnce(item, globalIndex, token, ShareKey) .then(val => { processed++; doc.find('.loading-popup .swal2-html-container').html(`
已获取 ${processed} / ${selectList.length} 个链接~
`); return val; })); }); let res = await Promise.all(queue); res.forEach(val => { selectList[val.index].DownloadUrl = val.downloadUrl; }); await base.sleep(1000); } let html = this.generateDom(selectList); base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer); } else { return message.error('提示:
页面错误~'); } }, async getFileUrlByOnce(item, index, token, ShareKey) { if (item.DownloadUrl) return { index, downloadUrl: item.DownloadUrl }; let res = null; if (ShareKey) { res = await base.post(config.$123pan.api.getShareLink, { "ShareKey": ShareKey, "FileID": item.FileId, "S3keyFlag": item.S3KeyFlag, "Size": item.Size, "Etag": item.Etag }, { "content-type": "application/json;charset=utf-8", "authorization": `Bearer ${token}`, "platform": "ios" }); } else { res = await base.post(config.$123pan.api.getLink, { "driveId": 0, "etag": item.Etag, "fileId": item.FileId, "s3keyFlag": item.S3KeyFlag, "type": item.Type, "fileName": item.FileName, "size": item.Size }, { "content-type": "application/json;charset=utf-8", "authorization": `Bearer ${token}`, "platform": "ios" }); } if (res.data?.DownloadUrl) { let url = res.data.DownloadUrl; let surl = new URL(url).searchParams.get("params"); if (surl) url = base.decodeBase(surl); url = await base.getFinalUrl(url); return { index, downloadUrl: url }; } else if (res.data?.DownloadURL) { let url = res.data.DownloadURL; let surl = new URL(url).searchParams.get("params"); if (surl) url = base.decodeBase(surl); url = await base.getFinalUrl(url); return { index, downloadUrl: url }; } else if (res?.code === 5112) { return message.error('提示:
请先登录网盘后再获取链接呢~'); } else { return { index, downloadUrl: '获取下载地址失败,刷新后再试试吧~' }; } }, generateDom(list) { if (!list) { return message.error('提示:
获取下载链接失败,刷新网页后再试试吧~'); } let content = '
'; let alinkAllText = ''; list.forEach((v, i) => { if (v.Type !== 0) return; let filename = v.FileName; let fileid = v.FileId; let size = base.sizeFormat(v.Size); let dlink = v.DownloadUrl || v.DownloadURL; if (!dlink || !dlink.includes("http")) { content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`; } else { if (mode === 'api') { alinkAllText += dlink + '\r\n'; content += `
${filename}
`; } if (mode === 'aria') { let alink = base.convertLinkToAria(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'rpc') { content += `
${filename}
`; } if (mode === 'curl') { let alink = base.convertLinkToCurl(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } if (mode === 'bc') { let alink = base.convertLinkToBC(dlink, filename); alinkAllText += alink + '\r\n'; content += ``; } } }); content += '
'; if (mode === 'rpc') { content += `
` } if (list.length >= 2) { if (mode === 'api') content += `
`; if (mode === 'aria') content += `
`; if (mode === 'rpc') { content += ``; } if (mode === 'curl') { content += `
`; } if (mode === 'bc') { content += `
`; } } if (mode === 'rpc') { let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path'); content += `
`; } return content; }, getSelectedList() { try { let selectedList = []; let reactDom = document.getElementsByClassName('ant-table-body')[0]; let reactObj = base.findReact(reactDom); let props = reactObj.memoizedProps.props; if (props) { let fileList = props.data || []; fileList.forEach(function (val) { if (val?.checked === true) { selectedList.push(val); } }); } return selectedList; } catch (e) { return []; } }, isOnlyFolder() { for (let i = 0; i < selectList.length; i++) { if (selectList[i].Type === 0) return false; } return true; }, addButton() { base.waitForKeyElements(config.$123pan.mount.home, (element) => { element = element.parent(); page = $123pan.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'home') return; let $button = $(`
下载助手
  • API 下载
  • Aria 下载
  • RPC 下载
  • cURL 下载
  • BC 下载
  • 助手设置
  • 助手美化
  • 更新日志
`); $button.css({ "margin-right": "22px", "width": "110px" }) element.prepend($button); }) base.waitForKeyElements(config.$123pan.mount.share, (element) => { element = element.parent(); page = $123pan.detectPage(); if ($(".pl-button").length > 0 || !page || page !== 'share') return; let $button = $(`
下载助手
  • API 下载
  • Aria 下载
  • RPC 下载
  • cURL 下载
  • BC 下载
  • 助手设置
  • 助手美化
  • 更新日志
`); $button.css({ "width": "100px" }) element.append($button); }) }, addInitButton() { base.waitForKeyElements(config.$123pan.mount.home, (element) => { element = element.parent(); page = $123pan.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'home') return; let $button = $(`
点我点亮
`); $button.click(function () { base.initDialog() }); $button.css({ "margin-right": "22px", "width": "110px" }) element.prepend($button); }) base.waitForKeyElements(config.$123pan.mount.share, (element) => { element = element.parent(); page = $123pan.detectPage(); if ($(".pl-button-init").length > 0 || !page || page !== 'share') return; let $button = $(`
点我点亮
`); $button.click(function () { base.initDialog() }); $button.css({ "width": "100px" }) element.append($button); }) }, detectPage() { let path = location.pathname; if (/^\/$/.test(path)) return 'home'; if (/^\/s\//.test(path)) return 'share'; return ''; }, async initPanLinker() { base.createTip(); base.registerMenuCommand(); if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); this.addPageListener(); } else { this.addInitButton(); } }, }; // 油小猴 let $youxiaohou = { async initPanLinker() { base.createTip(); base.registerMenuCommand(); if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) { this.addButton(); } else { this.addInitButton(); } }, addButton() { let $button = ` `; doc.on('click', '.listener-open-setting', function () { base.showSetting(); }); doc.on('click', '.listener-open-updatelog', function () { base.showUpdate(); }); doc.on('click', '.listener-open-beautify', function () { base.showBeautify(); }); doc.on('click', '.listener-open-info', function () { base.showDebug(); }); document.querySelectorAll(".nav-links").forEach(function (element) { element.innerHTML += $button }) }, addInitButton() { let $button = ` `; doc.on('click', '.listener-open-init', function () { base.initDialog(); }); document.querySelectorAll(".nav-links").forEach(function (element) { element.innerHTML += $button }) } } // 主代码 let main = { async init() { base.waitForKeyElements(`html:not(:has(> ${mount})) head`, (element) => { element.after(`<${mount} class="${mount}" />`) }, true) // 先加载默认设置 base.initDefaultConfig(); // 再加载网页样式 base.addPanLinkerStyle(); base.createDownloadIframe(); /** * 控制台输出 * @author 油小猴 * @author hmjz100 * @description 来自【网盘智能识别助手】,有改动 */ console.log(`%c %c LinkSwift\n一个基于 JavaScript 的网盘文件下载地址获取工具\n版本:${sversion}\n领域:${(window.self !== window.top ? "[iframe] " : "") + (document.title ? (document.title + " (" + location.origin + location.pathname + ")") : location.href)}`, `background:url(${sicon}) center center no-repeat;background-size:12px;padding:3px`, ""); let storedVersion = base.getValue("setting_init_version"); if (!storedVersion || base.isNewerVersion(sversion, storedVersion)) { base.waitForKeyElements("body", () => { base.showUpdate(); base.setValue("setting_init_version", sversion); return true; }, true) } // 最后判断页面地址并加载对应的initPanLinker if (/(pan|yun).baidu.com/.test(location.host)) { $baidu.initPanLinker(); $baidu.greenerPage(); } if (/openapi.baidu.com\/oauth/.test(location.href)) { $baidu.initAuthorize() } if (/www.(aliyundrive|alipan).com/.test(location.host)) { $aliyun.initPanLinker(); $aliyun.greenerPage(); } if (/(yun|caiyun).139.com/.test(location.host)) { $mcloud.initPanLinker(); $mcloud.greenerPage(); } if (/cloud.189.cn/.test(location.host)) { $tcloud.initPanLinker(); $tcloud.greenerPage(); } if (/pan.xunlei.com/.test(location.host)) { $xunlei.initPanLinker(); } if (/pan.quark.cn/.test(location.host)) { $quark.initPanLinker(); $quark.greenerPage(); } if (/drive.uc.cn/.test(location.host)) { $uc.initPanLinker(); $uc.greenerPage(); } if (/(www|login).(123(pan|684|865|952|912).com|123pan.cn)/.test(location.host)) { $123pan.initPanLinker(); $123pan.greenerPage(); } if (/www.youxiaohou.com/.test(location.host)) { $youxiaohou.initPanLinker(); } } }; main.init(); // 这是啥?我不到啊 function idontknow(input) { let charArray = input.split(''); // Fisher-Yates 洗牌算法 for (let i = charArray.length - 1; i > 0; i--) { let j = Math.floor(Math.random() * (i + 1)); [charArray[i], charArray[j]] = [charArray[j], charArray[i]]; } return charArray.join(''); } })();