// ==UserScript==
// @name LinkSwift
// @namespace github.com/hmjz100
// @version 1.1.2.1
// @author Hmjz100、油小猴
// @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48cGF0aCBkPSJNMTAzLjYgMTA3LjRjMy41LTIuMiA4LjktNi4xIDEzLjgtMTIuNXM3LjMtMTIuNSA4LjUtMTYuNWMuNS0xLjcgMi4yLTcuNSAyLjItMTQuNyAwLTEwLjEtMy4zLTI1LjEtMTUuNC0zNi44LTE0LjUtMTQtMzIuMS0xNC4zLTM1LjctMTQuMy04IDAtMTUuNyAxLjktMjIuNiA1LjJDNDQgMjMgMzUuNyAzMS40IDMwLjggNDEuN2MtMS4zIDIuOC00IDQuNy03LjEgNS00IC4zLTcuNSA0LjQtOC45IDkuNi0uNSAxLjktMS42IDMuNS0zLjEgNC43QzQuNCA2Ni44IDAgNzUuNyAwIDg1YzAgNi44IDIuMyAxMy4xIDYuMSAxOC4yIDUuNSA3LjQgMTQuMiAxMi4yIDI0IDEyLjJoNDcuMWM0LjQgMCAxMS0uNSAxOC4zLTMuNSAzLjItMS40IDUuOS0zIDguMS00LjV6IiBmaWxsPSIjQTA5OUYwIi8+PHBhdGggZD0iTTExOS44IDY0LjNjLjEtMTcuMS0xMC40LTI4LTEyLjUtMzAuMUM5NSAyMi4xIDc5LjkgMjEuOCA3Ni45IDIxLjhjLTE3LjYgMC0zMy4zIDEwLjUtMzkuOSAyNi43LS42IDEuMy0xLjggMi4zLTMuNCAyLjNoLS40Yy01LjggMC0xMC42IDQuOC0xMC42IDEwLjd2LjVjMCAxLjQtLjggMi42LTEuOSAzLjNDMTMuNCA2OSA4LjggNzYuOCA4LjggODVjMCAxMi4yIDkuOSAyMi4zIDIyLjIgMjIuM2g0NS4yYzMuNi0uMSAxNy42LS45IDI5LjYtMTIgMi45LTIuOCAxMy45LTEzLjcgMTQtMzF6IiBmaWxsPSIjNTc0QUI4Ii8+PHBhdGggZD0iTTExMC44IDU3LjRsLjIgMy4zYzAgMS4zLTEuMSAyLjQtMi4zIDIuNC0xLjMgMC0yLjMtMS4xLTIuMy0yLjRsLS4xLTIuOHYtLjNjMC0xLjIuOS0yLjIgMi4xLTIuM2guM2MuNyAwIDEuMy4zIDEuNy43LS4yLjEuMy41LjQgMS40em0tMy4zLTEwLjNjMCAxLjItMSAyLjMtMi4yIDIuM2gtLjFjLS44IDAtMS42LS41LTItMS4yLTQuNi04LjMtMTMuMy0xMy41LTIyLjgtMTMuNS0xLjIgMC0yLjMtMS0yLjMtMi4ydi0uMWMwLTEuMiAxLTIuMyAyLjItMi4zaC4xYTMwLjM3IDMwLjM3IDAgMCAxIDE1LjggNC40YzQuNiAyLjggOC40IDYuOCAxMS4xIDExLjUuMS4zLjIuNy4yIDEuMXpNODguMyA3My44TDczLjUgOTMuMmMtMS41IDEuOS0zLjUgMy4xLTUuNyAzLjVoLS4yYy0uNC4xLS44LjEtMS4yLjEtLjYgMC0xLjEtLjEtMS42LS4yLTIuMi0uNC00LjItMS43LTUuNi0zLjVMNDQuMyA3My45Yy0yLTIuNi0yLjUtNS40LTEuNC03LjcuMS0uMS4xLS4yLjItLjIgMS4yLTIgMy41LTMuMiA2LjQtMy4yaDYuNnYtNS43YzAtNi44IDQuNy0xMiAxMC45LTEyIDQuOCAwIDguNSAyLjYgMTAuMyA3LjIuNSAxLjMtLjIgMi43LTEuNSAzLjJzLTIuOC0uMS0zLjMtMS40Yy0xLjEtMi43LTIuOS00LTUuNS00LTMuNSAwLTYgMy02IDd2OC4xYzAgLjUtLjIgMS0uNiAxLjQtLjYuNy0xLjcgMS4xLTIuNiAxLjFoLTguNGMtMS4zIDAtMiAuNC0yLjEuNy0uMi40IDAgMS4zLjkgMi40TDYzLjEgOTBjLjkgMS4yIDIuMSAxLjggMy4zIDEuOHMyLjMtLjYgMy4xLTEuN2wxNC44LTE5LjNjLjktMS4xIDEuMS0yIC45LTIuNC0uMi0uMy0uOS0uNy0yLjEtLjdoLTcuNmMtLjkgMC0xLjctLjUtMi4xLTEuMi0uMy0uNC0uNC0uOC0uNC0xLjMgMC0xLjQgMS4xLTIuNSAyLjUtMi41aDcuNmMzLjEgMCA1LjUgMS4zIDYuNiAzLjVsLjMuN2MuNyAyLjEuMSA0LjYtMS43IDYuOXoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=
// @description (。>ᴗ•)✧《也许同类型中最好用?》系列 - 一个基于 JavaScript 的网盘文件下载地址获取工具✨,基于【网盘直链下载助手】修改 | 支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅雷云盘 / 夸克网盘 / UC网盘 / 123云盘 八大网盘 | 开源・自用・去广 | 改界面・添功能・修Bug | 既超越原版,亦是同类中最好用版本!👋
// @description:zh-CN (。>ᴗ•)✧《也许同类型中最好用?》系列 - 一个基于 JavaScript 的网盘文件下载地址获取工具✨,基于【网盘直链下载助手】修改 | 支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅雷云盘 / 夸克网盘 / UC网盘 / 123云盘 八大网盘 | 开源・自用・去广 | 改界面・添功能・修Bug | 既超越原版,亦是同类中最好用版本!👋
// @description:zh-TW (。>ᴗ•)✧《也許同類型中最好用?》系列 - 一個基於 JavaScript 的網盤檔案下載地址獲取工具✨,基於【網盤直鏈下載助手】改編 | 支援 百度網盤 / 阿里雲盤 / 中國移動雲盤 / 天翼雲盤 / 迅雷雲盤 / 夸克網盤 / UC網盤 / 123雲盤 八大平台 | 開源・自用・除廣 | 改介面・擴功能・修Bug | 既超越原版,亦是同類中最好用版本!👋
// @description:zh-HK (。>ᴗ•)✧《也許同類型中最好用?》系列 - 一個基於 JavaScript 的網盤檔案下載地址獲取工具✨,基於【網盤直鏈下載助手】改編 | 支援 百度網盤 / 阿里雲盤 / 中國移動雲盤 / 天翼雲盤 / 迅雷雲盤 / 夸克網盤 / UC網盤 / 123雲盤 八大平台 | 開源・自用・除廣 | 改介面・擴功能・修Bug | 既超越原版,亦是同類中最好用版本!👋
// @copyright © 2022 hmjz100
// @license AGPL-3.0-or-later
// @source https://github.com/hmjz100/LinkSwift/
// @website https://github.com/hmjz100/LinkSwift/
// @homepageURL https://github.com/hmjz100/LinkSwift/
// @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
// @early-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 *://yun.139.com/*
// @match *://caiyun.139.com/*
// @match *://cloud.189.cn/web/*
// @match *://pan.xunlei.com/*
// @match *://pan.quark.cn/*
// @match *://drive.uc.cn/*
// @match *://*.123pan.com/*
// @match *://*.123pan.cn/*
// @match *://*.123684.com/*
// @match *://*.123865.com/*
// @match *://*.123952.com/*
// @match *://*.123912.com/*
// @connect *
// @connect localhost
// @connect baidu.com
// @connect baidupcs.com
// @connect aliyundrive.com
// @connect aliyundrive.net
// @connect alipan.com
// @connect alicloudccp.com
// @connect aliyundrive.cloud
// @connect 139.com
// @connect cmecloud.cn
// @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
// @grant unsafeWindow
// @grant window.close
// @grant GM_xmlhttpRequest
// @grant GM_setClipboard
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_openInTab
// @grant GM_registerMenuCommand
// @grant GM_getResourceText
// @compatible Chrome
// @compatible Edge
// @compatible Firefox
// @compatible Safari
// @compatible Opera
// ==/UserScript==
/**
* @name LinkSwift
* @template (改)网盘直链下载助手
* @author 油小猴
* @author hmjz100
* @namespace github.com/hmjz100
* @description 一个基于 JavaScript 盘的文件下载地址获取工具 支持 百度网盘/阿里云盘/中国移动云盘/天翼云盘/迅雷云盘/夸克网盘/UC网盘/123云盘 八大网盘 代码改自 “网盘直链下载助手”,作者油小猴
* @version 1.1.2.1
* @license AGPL-3.0-or-later
* @see {@link https://github.com/hmjz100/LinkSwift/ Github 仓库}
*/
(function linkSwift($) {
// 严格模式,确保代码安全执行,不越界
"use strict";
// unsafeWindow 检测,适用于 Via 这类无 unsafeWindow 的浏览器
if (typeof (unsafeWindow) === "undefined") window.unsafeWindow = window;
// 重复执行检测,适用于部分浏览器;出自 “Via 轻插件”,作者谷花泰
let key = encodeURIComponent("LinkSwift:主代码"); if (window[key]) return; window[key] = true;
// 全局参数
let mount = idontknow("LinkSwift");
let info = {
author: GM_info.script?.author,
name: GM_info.script?.name,
version: (GM_info.script?.version || "1.1.2.1"),
icon: (GM_info.script?.icon || "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48cGF0aCBkPSJNMTAzLjYgMTA3LjRjMy41LTIuMiA4LjktNi4xIDEzLjgtMTIuNXM3LjMtMTIuNSA4LjUtMTYuNWMuNS0xLjcgMi4yLTcuNSAyLjItMTQuNyAwLTEwLjEtMy4zLTI1LjEtMTUuNC0zNi44LTE0LjUtMTQtMzIuMS0xNC4zLTM1LjctMTQuMy04IDAtMTUuNyAxLjktMjIuNiA1LjJDNDQgMjMgMzUuNyAzMS40IDMwLjggNDEuN2MtMS4zIDIuOC00IDQuNy03LjEgNS00IC4zLTcuNSA0LjQtOC45IDkuNi0uNSAxLjktMS42IDMuNS0zLjEgNC43QzQuNCA2Ni44IDAgNzUuNyAwIDg1YzAgNi44IDIuMyAxMy4xIDYuMSAxOC4yIDUuNSA3LjQgMTQuMiAxMi4yIDI0IDEyLjJoNDcuMWM0LjQgMCAxMS0uNSAxOC4zLTMuNSAzLjItMS40IDUuOS0zIDguMS00LjV6IiBmaWxsPSIjQTA5OUYwIi8+PHBhdGggZD0iTTExOS44IDY0LjNjLjEtMTcuMS0xMC40LTI4LTEyLjUtMzAuMUM5NSAyMi4xIDc5LjkgMjEuOCA3Ni45IDIxLjhjLTE3LjYgMC0zMy4zIDEwLjUtMzkuOSAyNi43LS42IDEuMy0xLjggMi4zLTMuNCAyLjNoLS40Yy01LjggMC0xMC42IDQuOC0xMC42IDEwLjd2LjVjMCAxLjQtLjggMi42LTEuOSAzLjNDMTMuNCA2OSA4LjggNzYuOCA4LjggODVjMCAxMi4yIDkuOSAyMi4zIDIyLjIgMjIuM2g0NS4yYzMuNi0uMSAxNy42LS45IDI5LjYtMTIgMi45LTIuOCAxMy45LTEzLjcgMTQtMzF6IiBmaWxsPSIjNTc0QUI4Ii8+PHBhdGggZD0iTTExMC44IDU3LjRsLjIgMy4zYzAgMS4zLTEuMSAyLjQtMi4zIDIuNC0xLjMgMC0yLjMtMS4xLTIuMy0yLjRsLS4xLTIuOHYtLjNjMC0xLjIuOS0yLjIgMi4xLTIuM2guM2MuNyAwIDEuMy4zIDEuNy43LS4yLjEuMy41LjQgMS40em0tMy4zLTEwLjNjMCAxLjItMSAyLjMtMi4yIDIuM2gtLjFjLS44IDAtMS42LS41LTItMS4yLTQuNi04LjMtMTMuMy0xMy41LTIyLjgtMTMuNS0xLjIgMC0yLjMtMS0yLjMtMi4ydi0uMWMwLTEuMiAxLTIuMyAyLjItMi4zaC4xYTMwLjM3IDMwLjM3IDAgMCAxIDE1LjggNC40YzQuNiAyLjggOC40IDYuOCAxMS4xIDExLjUuMS4zLjIuNy4yIDEuMXpNODguMyA3My44TDczLjUgOTMuMmMtMS41IDEuOS0zLjUgMy4xLTUuNyAzLjVoLS4yYy0uNC4xLS44LjEtMS4yLjEtLjYgMC0xLjEtLjEtMS42LS4yLTIuMi0uNC00LjItMS43LTUuNi0zLjVMNDQuMyA3My45Yy0yLTIuNi0yLjUtNS40LTEuNC03LjcuMS0uMS4xLS4yLjItLjIgMS4yLTIgMy41LTMuMiA2LjQtMy4yaDYuNnYtNS43YzAtNi44IDQuNy0xMiAxMC45LTEyIDQuOCAwIDguNSAyLjYgMTAuMyA3LjIuNSAxLjMtLjIgMi43LTEuNSAzLjJzLTIuOC0uMS0zLjMtMS40Yy0xLjEtMi43LTIuOS00LTUuNS00LTMuNSAwLTYgMy02IDd2OC4xYzAgLjUtLjIgMS0uNiAxLjQtLjYuNy0xLjcgMS4xLTIuNiAxLjFoLTguNGMtMS4zIDAtMiAuNC0yLjEuNy0uMi40IDAgMS4zLjkgMi40TDYzLjEgOTBjLjkgMS4yIDIuMSAxLjggMy4zIDEuOHMyLjMtLjYgMy4xLTEuN2wxNC44LTE5LjNjLjktMS4xIDEuMS0yIC45LTIuNC0uMi0uMy0uOS0uNy0yLjEtLjdoLTcuNmMtLjkgMC0xLjctLjUtMi4xLTEuMi0uMy0uNC0uNC0uOC0uNC0xLjMgMC0xLjQgMS4xLTIuNSAyLjUtMi41aDcuNmMzLjEgMCA1LjUgMS4zIDYuNiAzLjVsLjMuN2MuNyAyLjEuMSA0LjYtMS43IDYuOXoiIGZpbGw9IiNmZmYiLz48L3N2Zz4="),
mhandler: GM_info.scriptHandler,
mversion: GM_info.version,
};
let $doc = $(document);
let temp = {
mount: $(`.${mount}`),
main: {},
page: "",
mode: [],
links: [],
color: "",
request: {},
selectList: [],
colored: false,
swalDefault: {
position: "center",
heightAuto: false,
scrollbarPadding: false,
confirmButtonText: ` 确认`,
denyButtonText: ` 拒绝`,
cancelButtonText: ` 取消`
},
terminalType: {
wc: "Microsoft Windows 命令提示符",
wp: "Microsoft Windows PowerShell",
lt: "Linux 终端",
ls: "Linux Shell",
mt: "Apple MacOS 终端"
}
};
/**
* SweetAlert2 的 Toast 提示框基础配置
* @author 油小猴
* @author hmjz100
* @description 创建一个全局通用的 Toast 提示框实例,支持自动关闭、鼠标悬停暂停、右上角弹出等特性。
*
* @type{Sweetalert2.Toast}
*/
let toast = Swal.mixin({
toast: true,
position: "top-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
*/
let config = {
base: {
num: "865746",
license: "AGPL3",
service: {
account: "https://pic.rmb.bdstatic.com/bjh/8b9e14345b3cdf96aedac2f3971adcb02681.png"
},
dom: {
footer: `o(≧▽≦)o 十分感谢您的支持!来给此项目一个 Star 吧~`,
button: {
api: {
title: "API 下载",
footer: `
适用于 IDM , NDM 以及浏览器自带下载
`
},
aria2: {
title: "Aria2 下载",
footer: `RPC 适用于 Motrix , Aria2 Tools , AriaNgGUI
命令行适用于 XDown 及 Linux Shell 命令行
`
},
curl: {
title: "cURL 下载",
footer: `适用于 Windows,Linux,MacOS 终端
`
},
bitcomet: {
title: "比特彗星下载",
footer: `适用于 比特彗星
`
},
abdm: {
title: "ABDM 下载",
footer: `适用于 AB Download Manager
`
}
},
themes: [
{ color: "#09AAFF", name: "度盘|经典蓝" },
{ color: "#cc3235", name: "度盘|平安红" },
{ color: "#518c17", name: "度盘|盎然绿" },
{ color: "#ed944b", name: "度盘|周年橙" },
{ color: "#f969a5", name: "度盘|幸会粉" },
{ color: "#bca280", name: "度盘|午后棕" },
{ color: "#b673ab", name: "度盘|物语紫" },
{ color: "#574AB8", name: "度盘|星空紫" },
{ color: "#1d2327", name: "OpenAI|默认黑" },
{ color: "#18a497", name: "OpenAI|默认青" },
{ color: "#637dff", name: "度里叁|霞光紫" },
{ color: "#0d53ff", name: "夸克|极简蓝" },
{ color: "#3181f9", name: "移动|彩云蓝" },
{ color: "#f8d800", name: "果核|柠檬黄" },
{ color: "#0396ff", name: "果核|默认蓝" },
{ color: "#32ccbc", name: "果核|碧波绿" },
{ color: "#f6416c", name: "果核|玫瑰红" },
{ color: "#2271b1", name: "文派|默认蓝" },
{ color: "#59524c", name: "文派|咖啡灰" },
{ color: "#ff679a", name: "哔哩|少女粉" },
{ color: "#f44236", name: "哔哩|高能红" },
{ color: "#fec107", name: "哔哩|咸蛋黄" },
{ color: "#8bc24a", name: "哔哩|早苗绿" },
{ color: "#2594ed", name: "哔哩|宝石蓝" },
{ color: "#9c28b1", name: "哔哩|罗兰紫" }
]
}
},
$baidu: {
api: {
ua: {
downloadLink: "pan.baidu.com"
},
getAccessToken: "https://openapi.baidu.com/oauth/2.0/authorize?response_type=token&scope=basic,netdisk&client_id=omiOnr2tYnN9vSyDErcVFWpPU2mZA7YO&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"
},
dom: {
enhance: `+ 此方式可以自动设置用户代理(UA),然后下载。 此方式的下载请求可能会 被旧版 IDM 捕获。`,
normal: `+ 此方式无法下载超过 50MB 的文件 ,若超过点击会无反应(服务器 403)。 此方式的下载请求可能会 被 IDM 捕获。`,
copy: `注:此服务直接访问超过 50MB 文件的直链会导致服务器回报 403 错误 如需访问,请修改用户代理(UA)为 "pan.baidu.com" `
}
},
$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--"]`
},
dom: {
enhance: `+ 此方式可以自动设置 Referer,然后下载。 此方式的下载请求不会 被 IDM 捕获。`,
normal: `+ 此方式的下载请求可能会 被 IDM 捕获。`,
copy: `注:此服务直接访问直链会导致服务器回报 403 错误 如需访问,请修改 Referer 为 "https://${location.host}/" `,
filename: `注:此服务在下载高峰期时可能不会 向客户端回报文件名,下载时需要复制文件名。`
}
},
$mcloud: {
api: {
getLink: "https://personal-kd-njs.yun.139.com/hcy/file/getDownloadUrl"
},
mount: {
home: ".top_button",
share: ".top-btns"
},
dom: {
enhance: `+ 此方式的下载请求不会 被 IDM 捕获。`,
normal: `+ 此方式的下载请求可能会 被 IDM 捕获。`
}
},
$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"
},
dom: {
enhance: `+ 此方式的下载请求不会 被 IDM 捕获。`,
normal: `+ 此方式的下载请求可能会 被 IDM 捕获。`
}
},
$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--"]`
},
dom: {
enhance: `+ 此方式可以自动设置文件名,然后下载。 此方式的下载请求不会 被 IDM 捕获。`,
normal: `+ 此服务不会向客户端回报文件名,选用此方式下载需手动重命名文件。 此方式的下载请求不会 被 IDM 捕获。`,
filename: `注:此服务不会向客户端回报文件名,下载时需要复制文件名。`
}
},
$quark: {
api: {
ua: {
downloadLink: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/3.20.0 Chrome/112.0.5615.165 Electron/24.1.3.8 Safari/537.36 Channel/pckk_other_ch"
},
getLink: "https://drive-pc.quark.cn/1/clouddrive/file/download?entry=ft&fr=pc&pr=ucpro"
},
mount: {
home: ".btn-operate .btn-main",
share: ".share-btns"
},
dom: {
enhance: `+ 此方式可以自动设置用户代理(UA),然后下载。 此方式的下载请求不会 被 IDM 捕获。`,
normal: `+ 此方式的下载请求可能会 被 IDM 捕获。`
}
},
$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?entry=ft&fr=pc&pr=UCBrowser"
},
mount: {
home: ".btn-operate .btn-main",
share: ".file-info-share-buttom"
},
dom: {
enhance: `+ 此方式可以自动设置用户代理(UA),然后下载。 此方式的下载请求不会 被 IDM 捕获。`,
normal: `+ 此方式的下载请求可能会 被 IDM 捕获。`
}
},
$123pan: {
api: {
getLink: "https://www.123pan.com/api/file/download_info",
getShareLink: "https://www.123pan.com/api/share/download/info"
},
mount: {
home: ".home-operator .home-operator-button-group",
share: ".conter .rightInfo",
shareNew: ".content .content-header-container-wrap .rightInfo, .single-file-sharing-container-content-file-operate"
},
dom: {
enhance: `+ 此方式的下载请求不会 被 IDM 捕获。`,
normal: `+ 此方式的下载请求可能会 被 IDM 捕获。`
}
}
}
/**
* 基础工具集合
* @author 油小猴
* @author hmjz100
*/
let base = {
/**
* 注册 GreaseMonkey-Compatible-Manager 扩展菜单命令
* @author 油小猴
* @author hmjz100
* @description 包含 "设置"、"美化"、"更新" 和 "调试" 四个功能入口
*/
registerMenuCommand() {
GM_registerMenuCommand("⚙️ 设置", () => {
base.showSetting();
});
GM_registerMenuCommand("🍃️ 美化", () => {
base.showBeautify();
});
GM_registerMenuCommand("📃 更新", () => {
base.showUpdate();
});
GM_registerMenuCommand("🛠️ 调试", () => {
base.showDebug();
});
},
/**
* 判断 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|array} path - 存储键名或路径数组
* @param {*} value - 要存储的值
*/
setValue(path, value) {
if (base.isType(path) === "string") {
GM_setValue(path, value);
return;
}
let key = path[0];
let obj = this.getValue(key) || {};
let current = obj;
for (let i = 1; i < path.length - 1; i++) {
let keyPart = path[i];
if (!current[keyPart]) current[keyPart] = "";
current = current[keyPart];
}
current[path[path.length - 1]] = value;
GM_setValue(key, obj);
},
/**
* 删除 GreaseMonkey-Compatible-Manager 存储的值
* @author 油小猴
* @param {string|array} key - 单个键名
*/
delValue(key) {
return GM_deleteValue(key);
},
/**
* 从 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);
},
/**
* 删除 localStorage 存储值
* @author 油小猴
* @description 没什么特别的
* @param {string} key - 存储键名
*/
delStorage(key) {
return localStorage.removeItem(key);
},
/**
* 剪贴板写入
* @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) {
let reg = /(?!\.)\w+$/;
if (reg.test(name)) {
let match = name.match(reg);
return match[0].toUpperCase();
}
return "";
},
/**
* 文件大小格式化
* @author hmjz100
* @description 自动转换单位到最合适的存储单位(如 `1.2MB`),支持 1000/1024 进制切换
* @param {number} value - 文件字节大小
* @returns {string} 可读格式的大小描述
*/
sizeFormat(value = 0) {
var sizeUnitBase = 1024
try { value = Number(value) } catch { }
if (typeof value === "number" && !isNaN(value) && value >= 0) {
var units = sizeUnitBase === 1024
? ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
: ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
var unitNames = ["字节", "千字节", "兆字节", "吉字节", "太字节", "拍字节", "艾字节", "泽字节", "尧字节"];
if (value === 0) return "0B(字节)";
// 计算单位层级(取整数部分)
var index = Math.min(
Math.floor(Math.log(value) / Math.log(sizeUnitBase)),
units.length - 1
);
var size = value / Math.pow(sizeUnitBase, index);
var formattedSize = size % 1 === 0 ? size.toFixed(0) : size.toFixed(2);
return `${formattedSize}${unitNames[index]}(${units[index]})`;
}
return "";
},
/**
* 将剩余时间(秒)格式化为可读的时间字符串
*
* @param {number} remainingTimeSeconds 剩余总秒数(支持小数)
* @returns {string} 格式化后的时间字符串,包含以下可能格式:
* - "X天 HH时:MM分:SS秒"(超过1天)
* - "HH时:MM分:SS秒"(超过1小时)
* - "MM分:SS秒"(超过1分钟)
* - "SS秒"(1分钟内)
* - "计算中..."(无效输入时)
*
* @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 "0秒";
}
},
/**
* 文件列表排序
* @author 油小猴
* @description 按中文拼音顺序对文件数组进行排序
* @param {Array} arr - 包含文件对象的数组
* @param {string} arr[].filename - 文件名属性(兼容 server_filename)
*/
sortByName(arr) {
let handle = () => {
return (a, b) => {
let p1 = a.filename ? a.filename : a.server_filename;
let 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, "_");
},
/**
* Headers 标准化
* @author hmjz100
* @description 标准化 Headers 的键,使用驼峰命名
* @param {object} headers - 原始文件名
* @param {Boolean} notDeafult - 原始文件名
* @returns {object} 标准化后的 Headers
*/
standHeaders(headers = {}, notDeafult = false) {
let newHeaders = {};
for (let key in headers) {
let value
if (this.isType(headers[key]) === "object") value = JSON.stringify(headers[key]);
else value = String(headers[key]);
newHeaders[key.toLowerCase().split("-").map(word => word.charAt(0).toUpperCase() + word.slice(1)).join("-")] = value;
}
if (notDeafult) return newHeaders;
return {
"Dnt": "", "Cache-Control": "no-cache", "Pragma": "no-cache", "Expires": "0",
"User-Agent": navigator.userAgent,
"Origin": location.origin,
"Referer": `${location.origin}/`,
...newHeaders
};
},
/**
* 生成 cURL 下载命令
* @author 油小猴
* @author hmjz100
* @description 根据终端类型生成对应 curl 命令,支持断点续传,自动处理文件名特殊字符
* @param {string} link - 下载链接
* @param {string} filename - 文件名
* @param {string} [headers] - 自定义请求头参数(可选)
* @returns {string} 编码后的 curl 命令字符串
*/
convertLinkToCurl(link, filename, headers) {
let terminal = base.getValue("setting_curl_terminal");
filename = base.fixFilename(filename);
return `${terminal !== "wp" ? "curl" : "curl.exe"} -L -C - "${link}" -o "${filename}"${headers ? (" " + headers) : ""}`;
},
/**
* 生成 Aria2 下载命令
* @author 油小猴
* @author hmjz100
* @description 将链接转换为 Aria2 格式命令,自动处理文件名特殊字符
* @param {string} link - 下载链接
* @param {string} filename - 文件名
* @param {string} [headers] - 自定义请求头参数(可选)
* @returns {string} 编码后的 aria2c 命令字符串
*/
convertLinkToAria2(link, filename, headers) {
filename = base.fixFilename(filename);
return `aria2c "${link}" --out "${filename}"${headers ? (" " + headers) : ""}`;
},
/**
* 生成 BC 协议下载链接
* @author 油小猴
* @author hmjz100
* @description 将链接转换为 BC 协议格式,自动处理 URL 编码
* @param {string} link - 下载链接
* @param {string} filename - 文件名
* @param {string} [headers] - 自定义请求头参数(可选)
* @returns {string} 编码后的 BC 协议 URL
*/
convertLinkToBitComet(link, filename, headers) {
filename = base.fixFilename(filename);
let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}${headers ? ("&" + headers) : ""}ZZ`;
return `bc://http/${base.encodeBase(bc)}`;
},
/**
* 发送链接到 IDM 下载器
* @author hmjz100
* @author Night-stars-1
* @description IDM 下载必备
* @param {string} link - 下载链接
* @param {string} filename - 文件名
* @param {Array} [headers] - 自定义请求头参数(可选)
* @returns {Promise<"success"|"fail">} 发送态结果
*/
async sendLinkToIDM(link, filename, filesize, headers = {}) {
if (!this.sendLinkToIDM.lock) this.sendLinkToIDM.lock = Promise.resolve();
return this.sendLinkToIDM.lock = this.sendLinkToIDM.lock.then(async () => {
headers = this.standHeaders(headers);
if (!this.sendLinkToIDM.seq) this.sendLinkToIDM.seq = 1;
let seq = this.sendLinkToIDM.seq;
let time = Date.now();
let url = `http://127.0.0.1:1001/client/1?seq=${seq}`;
let ext = base.getExtension(filename);
let headersText = Object.entries(headers).map(([key, value]) => `${key}: ${value}`).join("\n") + "\n"; // 坑1:IDM 对 Header 的解码比较死板,最后不加换行不肯解析
function format(key, val) {
if (val === undefined || val === null) return "";
var strVal = String(val);
var len = new Blob([strVal]).size; // 坑2:使用 blob.size,而不是 length
return `${key}=${len}:${strVal}`;
};
let fields = [
format(4, ext), // 4: 文件类型
format(6, link), // 6: 链接
format(7, location.origin), // 7: 来源页面
format(11, headersText), // 11: 请求头
format(100, filename), // 100: 文件名
format(122, 4), // 122: 代理
];
// 坑3:神秘的请求格式
// MSG # {请求指示} #13#1# {10241/20xx}(是否使用扩展提供的文件信息) : {?}(可能是距离扩展启动的时间?) :0: {当前时间戳} :1: {1/2}(是否优先弹窗,再获取文件信息) : {文件大小} :0,{表单}(格式如上);
let data = `MSG#${seq}#13#1#10241:${seq + 1000}:0:${time}:0:1:2:${filesize}:0,${fields.join(",")};`;
let request = base.post(url, data, {}, "text").catch(() => false);
let timeout = new Promise((_, reject) => {
setTimeout(() => {
if (request.abort) request.abort();
reject(new Error("timeout"));
}, 15 * 1000);
})
let res = await Promise.race([request, timeout]).catch(() => false);
if (res && res.endsWith(`${seq}:3;`)) {
this.sendLinkToIDM.seq++;
return "success";
};
return "fail";
});
},
/**
* 发送链接到 Aria2 下载器
* @author 油小猴
* @author hmjz100
* @description Aria2 下载必备
* @param {string} link - 下载链接
* @param {string} filename - 文件名
* @param {Array} [headers] - 自定义请求头参数(可选)
* @returns {Promise<"success"|"fail">} 发送态结果
*/
async sendLinkToAria2(link, filename, headers) {
let list = base.getValue("setting_aria2_rpc");
let selected = list.find(i => i.default);
let rpc = {
domain: selected.domain,
port: selected.port,
path: selected.path,
dir: selected.dir,
token: selected.token
};
let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
let dir = (rpc.dir !== null && rpc.dir !== "") ? rpc.dir : undefined;
let data = {
id: new Date().getTime(),
jsonrpc: "2.0",
method: "aria2.addUri",
params: [`token:${rpc.token}`, [link], {
dir,
out: filename,
header: headers
}]
};
try {
let res = await base.post(url, data, {}, "");
if (res.result) return "success";
return "fail";
} catch (e) {
return "fail";
}
},
/**
* 发送链接到比特彗星下载器
* @author hmjz100
* @description 比特彗星下载必备
* @param {string} link - 下载链接
* @param {string} filename - 文件名
* @param {Array} [headers] - 自定义请求头参数(可选)
* @returns {Promise<"success"|"fail">} 发送态结果
*/
async sendLinkToBitcomet(link, filename, headers) {
let list = base.getValue("setting_bitcomet_rpc");
let selected = list.find(i => i.default);
let rpc = {
domain: selected.domain,
port: selected.port,
path: selected.path,
dir: selected.dir,
authName: selected.authName,
authPass: selected.authPass,
};
let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
let data = new URLSearchParams();
data.append("url", link);
if (rpc.dir !== null && rpc.dir !== "") data.append("save_path", rpc.dir);
data.append("file_name", filename);
data.append("connection", 200);
if (headers && base.isType(headers) === "object") {
for (var [key, value] of Object.entries(headers)) {
data.append(key, value);
}
}
try {
let res = await base.post(url, data, {
"Authorization": `Basic ${base.encodeBase(rpc.authName + ":" + rpc.authPass)}`,
"Content-Type": "application/x-www-form-urlencoded"
}, "blob");
if (res.response && res?.responseText?.includes("Add task failed!")) {
return "fail";
} else {
return "success";
}
} catch (e) {
return "success";
}
},
/**
* 发送链接到 AB Download Manager 下载器
* @author hmjz100
* @description AB Download Manager 下载必备
* @param {string} link - 下载链接
* @param {string} filename - 文件名
* @param {Array} [headers] - 自定义请求头参数(可选)
* @returns {Promise<"success"|"fail">} 发送态结果
*/
async sendLinkToABDM(link, filename, headers) {
let newHeaders = {};
for (let key in headers) {
newHeaders[key.toLowerCase().split("-").map(word => word.charAt(0).toUpperCase() + word.slice(1)).join("-")] = headers[key];
}
headers = { "User-Agent": navigator.userAgent, "Origin": location.origin, "Referer": `${location.origin}/`, "DNT": "1", ...newHeaders };
let list = base.getValue("setting_abdm_rpc");
let selected = list.find(i => i.default);
let rpc = {
domain: selected.domain,
port: selected.port,
dir: selected.dir
};
let url = `${rpc.domain}:${rpc.port}/start-headless-download`;
let data = {
"downloadSource": {
"name": filename,
"description": "LinkSwift",
"link": link,
"headers": headers,
"downloadPage": headers["Referer"]
},
"name": filename
}
if (rpc.dir) data.folder = rpc.dir;
try {
let res = await base.post(url, data, { "Content-Type": "text/plain;charset=UTF-8" }, "text");
if (res === "OK") return "success";
return "fail";
} catch (e) {
return "fail";
}
},
/**
* Blob 文件下载
* @author 油小猴
* @description 通过创建临时链接实现文件下载
* @param {Blob} blob - 要下载的 Blob 对象
* @param {string} filename - 下载时提示保存的文件名
*/
blobDownload(blob, filename) {
if (blob instanceof Blob) {
let url = URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = filename;
a.rel = "noopener"
a.click();
URL.revokeObjectURL(url);
}
},
/**
* 可跨域 xmlhttpRequest 请求
* @author hmjz100
* @description 封装 `GreaseMonkey-Compatible_xmlhttpRequest` 实现的跨域请求,与原始函数参数相同,支持回调和 await 两种用法
* @param {Object} option - 请求配置对象
* @returns {XMLHttpRequest|Promise} 请求对象实例或 Promise
*/
xmlHttpRequest(option) {
let xmlHttpRequest = (typeof GM_xmlhttpRequest === "function") ? GM_xmlhttpRequest : (typeof GM?.xmlHttpRequest === "function") ? GM.xmlHttpRequest : null;
if (!xmlHttpRequest || base.isType(xmlHttpRequest) !== "function") throw new Error("GreaseMonkey 兼容 XMLHttpRequest 不可用。");
return xmlHttpRequest({ withCredentials: true, ...option });;
},
/**
* 发送 POST 请求
* @author 油小猴
* @author hmjz100
* @description 一般用于请求 API,支持智能格式化数据、智能编码请求数据
* @param {string} url - 请求地址
* @param {Object|string} data - 请求数据
* @param {Object} headers - 请求头配置
* @param {string} [type="json"] - 响应类型(支持 `json`, `blob` 等)
* @returns {Promise} 包含响应数据的 `Promise` 对象
*/
async post(url, data, headers, type = "json") {
let _data = data;
if (this.isType(data) === "object" || this.isType(data) === "array") {
data = JSON.stringify(data);
} else if (this.isType(data) === "urlsearchparams") {
_data = Object.fromEntries(data);
}
headers = this.standHeaders(headers);
headers = { "Accept": "application/json;charset=utf-8", ...headers };
let request
let promise = new Promise((resolve, reject) => {
request = base.xmlHttpRequest({
url, headers, data,
method: "POST", responseType: type,
onloadstart: (res) => {
base.console.log("【LinkSwift】Post(start)\n请求地址:" + url + "\n请求数据:", _data, "\n请求头部:", headers);
},
onload: (res) => {
if (type === "blob") {
base.console.log("【LinkSwift】Post(load) Blob\n请求地址:" + url + "\n请求数据:", _data, "\n请求结果:", res);
resolve(res);
return;
}
// 尝试解析响应
res.responseDecode = res.responseText;
try { res.responseDecode = atob(res.responseDecode) } catch { }
try { res.responseDecode = escape(res.responseDecode) } catch { }
try { res.responseDecode = decodeURIComponent(res.responseDecode) } catch { }
try { res.responseDecode = JSON.parse(res.responseDecode) } catch { }
if (res.responseDecode === res.responseText) res.responseDecode = null;
if (this.isType(res.response) === "object") res.responseDecode = res.response;
base.console.log("【LinkSwift】Post(load)\n请求地址:" + url + "\n请求数据:", _data, "\n请求头部:", headers, "\n请求结果:", res);
resolve(res.responseDecode ?? res.response ?? res.responseText);
},
onerror: (error) => {
let msg = "请求失败";
if (error && typeof error === "object") msg += ": " + JSON.stringify(error, null, 2);
base.console.error("【LinkSwift】Post(error)\n请求出现错误,可能是网络问题。", error);
reject(new Error(msg));
}
});
})
let proto = request.prototype;
while (proto && proto !== Object.prototype) {
for (var key of Object.getOwnPropertyNames(proto)) {
if (typeof request[key] === "function") {
promise[key] = request[key].bind(request);
}
};
proto = Object.getPrototypeOf(proto); // 继续向上遍历
if (proto === request) break; // 防止循环
}
return promise;
},
/**
* 发送 GET 请求
* @author 油小猴
* @author hmjz100
* @description 一般用于请求 API,支持智能格式化数据
* @param {string} url - 请求地址
* @param {Object} headers - 请求头配置
* @param {string} [type="json"] - 响应类型
* @returns {Promise} 包含响应数据的 `Promise` 对象
*/
async get(url, headers, type = "json") {
headers = this.standHeaders(headers);
let request
let promise = new Promise((resolve, reject) => {
request = base.xmlHttpRequest({
url, headers,
method: "GET", responseType: type,
onloadstart: (res) => {
base.console.log("【LinkSwift】Get(start)\n请求地址:" + url + "\n请求头部:", headers);
},
onload: (res) => {
if (type === "blob") {
base.console.log("【LinkSwift】Get(load) Blob\n请求地址:" + url, "\n请求结果:", res);
resolve(res);
return;
}
// 尝试解析响应
res.responseDecode = res.responseText;
try { res.responseDecode = JSON.parse(res.responseDecode) } catch { }
if (res.responseDecode === res.responseText) res.responseDecode = null;
if (this.isType(res.response) === "object") res.responseDecode = res.response;
base.console.log("【LinkSwift】Get(load)\n请求地址:" + url + "\n请求头部:", headers, "\n请求结果:", res);
resolve(res.responseDecode ?? res.response ?? res.responseText);
},
onerror: (error) => {
let msg = "请求失败";
if (error && typeof error === "object") msg += ": " + JSON.stringify(error, null, 2);
base.console.error("【LinkSwift】Get(error)\n请求出现错误,可能是网络问题。", error);
reject(new Error(msg));
}
});
})
let proto = request.prototype;
while (proto && proto !== Object.prototype) {
for (var key of Object.getOwnPropertyNames(proto)) {
if (typeof request[key] === "function") {
promise[key] = request[key].bind(request);
}
};
proto = Object.getPrototypeOf(proto); // 继续向上遍历
if (proto === request) break; // 防止循环
}
return promise;
},
/**
* 发送 HEAD 请求
* @author hmjz100
* @description 用于获取请求地址返回的请求头,支持智能降级为轻量 GET (`Range: bytes=0-0`),返回结构化响应头
* @param {string} url - 请求地址
* @param {Object} headers - 请求头配置
* @param {boolean} usingGET - 是否使用 GET
* @returns {Promise} 包含响应数据的 `Promise` 对象
*/
async head(url, headers, usingGET) {
headers = this.standHeaders(headers);
return new Promise((resolve, reject) => {
var method = usingGET ? "Get" : "Head";
let _aborted = false;
let request = base.xmlHttpRequest({
method: method.toUpperCase(),
url,
headers,
onloadstart: () => {
base.console.log(`【LinkSwift】Head${usingGET ? " Get" : ""}(start)\n请求地址:${url}\n请求头部:`, headers);
},
onload: function (res) {
if (!_aborted) {
let head = {};
res.responseHeaders.trim().split("\r\n").forEach(line => {
var parts = line.split(": ");
if (parts.length >= 2) {
var key = parts[0].toLowerCase();
var value = parts.slice(1).join(": ");
head[key] = value;
}
});
res.responseHeaders = base.standHeaders(head, true);
base.console.log(`【LinkSwift】Head${usingGET ? " Get" : ""}(load)\n请求地址:${res.finalUrl}\n响应状态:${res.status}\n响应内容:`, res);
if (!usingGET && !res.responseHeaders.hasOwnProperty("Range") && !(res?.status >= 200 && res?.status < 400)) {
base.head(res.finalUrl, { ...headers, Range: "bytes=0-0" }, true).then(resolve).catch(reject);
return;
}
resolve(res);
}
},
onreadystatechange: function (res) {
if (res.readyState === 2) { // HEADERS_RECEIVED
_aborted = true;
if (request && request.abort) request.abort();
let head = {};
res.responseHeaders.trim().split("\r\n").forEach(line => {
var parts = line.split(": ");
if (parts.length >= 2) {
var key = parts[0].toLowerCase();
var value = parts.slice(1).join(": ");
head[key] = value;
}
});
res.responseHeaders = base.standHeaders(head, true);
base.console.log(`【LinkSwift】Head${usingGET ? " Get" : ""}(load) RS2\n请求地址:${res.finalUrl}\n响应状态:${res.status}\n响应内容:`, res);
if (!usingGET && !res.responseHeaders.hasOwnProperty("Range") && !(res?.status >= 200 && res?.status < 400)) {
base.head(res.finalUrl, { ...headers, Range: "bytes=0-0" }, true).then(resolve).catch(reject);
return;
}
resolve(res);
}
},
onerror: function (err) {
if (!_aborted) {
base.console.error(`【LinkSwift】Head${usingGET ? " Get" : ""}(error)\n请求出现错误,可能是网络问题。`, err);
reject(err);
}
}
});
});
},
/**
* 获取最终重定向
* @author 油小猴
* @author hmjz100
* @description 使用 GET、Head,智能追踪 HTTP 30x 重定向,返回最终访问地址
* @param {string} url - 初始请求地址
* @param {Object} headers - 请求头配置
* @param {boolean} usingGET - 是否使用 GET
* @param {boolean} returnURL - 是否只返回链接而不是 res
* @returns {Promise} 最终 URL 地址
*/
getFinal(url, headers = {}, usingGET = false, returnURL = true) {
return new Promise(async (resolve, reject) => {
var res = await this.head(url, headers, usingGET).catch(reject);
if (!res?.finalUrl) return reject(res);
if (res?.status == 204 && res?.statusText === "IDM") return reject(res);
if (res?.status >= 300 && res?.status < 400) {
base.getFinal(res.finalUrl, headers, usingGET, returnURL).then(resolve).catch(reject);
return;
}
if (returnURL) return resolve(res.finalUrl);
else return resolve(res);
});
},
/**
* 下载文件
* @author hmjz100
* @description 发送 GET 请求,一般用于文件下载,支持进度监控、自动重试、断点续传、非断回退
* @param {string} url - 请求地址
* @param {Object} headers - 请求头配置
* @param {number} [size=0] - 响应类型
* @param {Object} [extra] - 附加参数(必须 `name`、`index`、`size` 属性;可选 `thread`、`retry` 属性)
* @returns {Promise} 包含响应数据的 `Promise` 对象
*/
async download(url, headers, extra) {
headers = this.standHeaders(headers);
// 初始化全局共享状态
this.download.active = this.download.active || 0; // 全局活跃线程数
this.download.taskCount = this.download.taskCount || 0; // 当前正在运行的 download 任务数
var global_maxThreads = 8; // 整个允许的最大并发数
if (extra) base.console.log(`【LinkSwift】Download\n收到数据:`, extra);
if (!extra || !extra.index || !extra.name || !extra.size) throw new Error("extra 缺少内容。");
let status = {
aborted: false,
requests: new Set(),
results: [],
active: 0,
maxSpeed: 0
};
let promise = new Promise(async (resolve, reject) => {
this.download.taskCount++; // 任务进入
try {
var finalHead = await base.getFinal(url, headers, false, false).catch(reject);
if (!finalHead) return;
url = finalHead.finalUrl;
var responseHeaders = finalHead.responseHeaders;
let size = parseInt(extra.size || responseHeaders?.["Content-Length"] || 0, 10);
if (responseHeaders?.["Content-Range"]) {
size = parseInt((responseHeaders["Content-Range"]?.match(/\/(\d+)$/)?.[1] || size), 10);
}
if (!status.aborted && typeof extra?.onProgress === "function") extra.onProgress(0, 0, size);
if (!(finalHead.status >= 200 && finalHead.status < 400)) return reject(finalHead);
if (finalHead.status == 204 && finalHead.statusText === "IDM") return reject(finalHead);
var supportRange = finalHead.status == 206 && (responseHeaders?.["Accept-Ranges"]?.includes("bytes") || responseHeaders?.["Content-Range"]?.includes("bytes"));
if (!!supportRange || size > 0) {
base.console.log(`【LinkSwift】Download(Start)\n文件名称:${extra.name}\n断点续传:支持`);
var maxRetry = extra.retry || 10;
let index = 0;
let offset = 0;
let totalLoaded = 0;
var worker = async () => {
var minChunk = extra.minChunk || 50 * 1024; // 最小 50KB
var maxChunk = extra.maxChunk || 1 * 1024 * 1024; // 最大 1MB
let chunk = Math.floor(minChunk + (maxChunk - minChunk) * 0.37);
while (offset < size && !status.aborted) {
// 如果全局线程满了,且当前任务已经抢到了 1 条以上的线程,则 “让路” 给后来的任务
let fairShare = Math.max(1, Math.floor(global_maxThreads / this.download.taskCount));
while (!status.aborted && this.download.active >= global_maxThreads && status.active >= fairShare) {
await new Promise(r => setTimeout(r, 200)); // 等待,直到其他任务释放或有空位
}
if (status.aborted || offset >= size) break;
var _index = index++;
var start = offset;
var end = Math.min(start + chunk - 1, size - 1);
var _size = end - start + 1;
offset += _size;
let attempt = 0;
while (attempt <= maxRetry && !status.aborted) {
// 占用线程计数
status.active++;
this.download.active++;
try {
var startTime = Date.now();
let lastLoaded = 0;
var res = await new Promise((s, j) => {
var xhr = base.xmlHttpRequest({
url, method: "GET", responseType: "arraybuffer",
headers: { ...headers, "Range": `bytes=${start}-${end}` },
onloadstart() {
startTime = Date.now();
},
onprogress: (progress) => {
totalLoaded += (progress.loaded - lastLoaded);
lastLoaded = progress.loaded;
let prog = (totalLoaded * 100 / size);
if (!status.aborted && typeof extra?.onProgress === "function") extra.onProgress(prog, totalLoaded, size);
},
onload: (load) => {
status.requests.delete(xhr);
if (load.status == 204 && load.statusText === "IDM") return j(load);
if (load.status >= 200 && load.status < 300) s(load.response);
else j(load);
},
onerror: (error) => {
status.requests.delete(xhr);
j(error);
}
});
status.requests.add(xhr);
});
// 智能分块调整
var _duration = extra.duration || 1.5; // 目标
var duration = (Date.now() - startTime) / 1000 || 0.1;
var speed = _size / duration;
let nextChunk;
if (speed > status.maxSpeed * 0.9) {
// 如果速度在提升或维持高位,说明大块是有效的,即便超时也要大胆增加
// 目标是找到能让 speed 最大化的 chunk 大小
nextChunk = chunk * 1.5;
status.maxSpeed = Math.max(status.maxSpeed, speed);
} else if (duration < _duration * 0.5) {
// 跑得太快了,可以尝试再加一点
nextChunk = chunk * 1.2;
} else if (duration > _duration * 2) {
// 只有当耗时严重超过目标(比如超过 2 倍)且速度下降时,才收缩
nextChunk = chunk * 0.8;
} else {
// 稳定期
nextChunk = chunk;
}
chunk = Math.max(minChunk, Math.min(maxChunk, chunk * 0.7 + nextChunk * 0.3));
chunk = Math.floor(chunk);
status.results.push({ index: _index, data: res });
res = null;
break;
} catch (e) {
await new Promise(r => setTimeout(r, 1000 * attempt));
attempt++;
if (attempt > maxRetry) throw e;
} finally {
// 释放线程计数
status.active--;
this.download.active--;
}
}
}
};
// 启动当前任务的并发线程,单任务最高 3 个
var maxThreads = Math.min(extra.thread || 3, 3);
await Promise.all(Array(maxThreads).fill(0).map(worker));
if (status.aborted) return;
if (!status.aborted && typeof extra?.onProgress === "function") extra.onProgress(100, size, size);
await new Promise(resolve => setTimeout(resolve, 0));
status.results.sort((a, b) => a.index - b.index);
// 分段提取数据
async function getBlobData(results) {
var dataList = [];
var batchSize = 100; // 每处理 100 个分块释放一次主线程
for (let i = 0; i < results.length; i++) {
dataList.push(results[i].data);
if (i % batchSize === 0) {
await new Promise(resolve => setTimeout(resolve, 0));
}
}
return dataList;
};
var finalData = await getBlobData(status.results);
status.results = null; // 释放内存引用
resolve({
status: 200,
statusText: "Ok!",
readyState: 4,
response: new Blob(finalData),
finalUrl: url
});
} else {
// 不支持 Range,回退
var xhr = base.xmlHttpRequest({
url: url, headers, method: "GET", responseType: "blob",
onprogress: (progress) => {
if (!status.aborted && typeof extra?.onProgress === "function") extra.onProgress((progress.loaded * 100 / progress.total), progress.loaded, progress.total);
},
onload: (load) => resolve(load),
onerror: (error) => reject(error)
});
status.requests.add(xhr);
}
} catch (e) {
status.aborted = true;
reject(e);
} finally {
this.download.taskCount--; // 无论成功失败,任务退出
}
});
promise.abort = () => {
status.aborted = true;
status.requests.forEach(xhr => xhr?.abort?.());
status.requests.clear();
status.results = null;
};
if (extra.index) temp.request[extra.index] = promise;
return promise;
},
/**
* Aria2 RPC 服务测试
* @author hmjz100
* @description 验证 `JSON-RPC` 接口可用性
* @param {string} domain - 服务域名
* @param {string} port - 服务端口
* @param {string} path - RPC 路径
* @param {string} token - 认证令牌
* @returns {Promise<"success"|"fail">} 连接状态结果
*/
async testConnectToAria2(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: "aria2.getVersion",
params: [`token:${rpc.token}`]
};
base.xmlHttpRequest({
method: "POST", url, headers: {}, data: JSON.stringify(rpcData),
responseType: "json",
onloadstart() {
base.console.log("【LinkSwift】Post(start) Aria2Test\n请求地址:" + url + "\n请求内容:", rpcData);
},
onload: function (res) {
base.console.log("【LinkSwift】Post(load) Aria2Test\n请求地址:" + url + "\n请求结果:", res);
if (!res.response) return resolve("fail");
if (res.response?.error) {
resolve("fail");
} else {
resolve("success");
}
},
onerror: function (err) {
base.console.error("【LinkSwift】Post(error) Aria2Test\n请求失败", err);
resolve("fail");
},
});
});
},
/**
* AB Download Manager RPC 服务测试
* @author hmjz100
* @description 验证 `JSON-RPC` 接口可用性
* @param {string} domain - 服务域名
* @param {string} port - 服务端口
* @returns {Promise<"success"|"fail">} 连接状态结果
*/
async testConnectToABDM(domain, port) {
return new Promise((resolve, reject) => {
let rpc = { domain, port };
let url = `${rpc.domain}:${rpc.port}/ping`;
base.xmlHttpRequest({
method: "POST", url, headers: {}, data: new Date().getTime(),
responseType: "text",
onloadstart() {
base.console.log("【LinkSwift】Post(start) ABDMTest\n请求地址:" + url + "\n请求内容:", new Date().getTime());
},
onload: function (res) {
base.console.log("【LinkSwift】Post(load) ABDMTest\n请求地址:" + url + "\n请求结果:", res);
if (!res.response || res.response !== "pong") return resolve("fail");
resolve("success");
},
onerror: function (err) {
base.console.error("【LinkSwift】Post(error) ABDMTest\n请求失败", err);
resolve("fail");
},
});
});
},
/**
* 重置请求相关数据
* @author 油小猴
* @description 中止所有进行中的请求,清除进度记录和定时器
*/
_resetAllData() {
temp.links = [];
$.each(temp.request, function (key) {
(temp.request[key]).abort();
});
temp.request = {};
},
/**
* 重置请求相关数据
* @author 油小猴
* @description 中止指定的进行中的请求,清除进度记录和定时器
*/
_resetData(i) {
temp.request[i] && temp.request[i].abort();
},
/**
* 将对象转换为 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 = $(`[${mount}="${id}"], #${id}`);
let $style = $(`<${tag}>`, {
rel: "stylesheet",
id: id,
[mount]: id
});
tag === "style" ? $style.html(css.trim().replace(/\t/g, "").replace(/\r\n|\n\r|\n|\r/g, "\n").replace(/\n+/g, "\n")) : $style.attr("href", css);
if ($styleDom.length) {
$styleDom.replaceWith($style);
base.console.log($style[0])
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}`;
},
/**
* 自适应样式颜色替换器
* @author hmjz100
* @description 支持全局样式替换和资源路径修正,处理颜色渐变过渡效果等
* @param {string} cssText - 原始 CSS 内容
* @param {string} baseURI - 资源基础路径
* @param {"default"|"other"} type - 替换模式(默认模式包含过渡效果)
* @param {Array<[string, string]>} colorMap - 颜色映射表(旧颜色 → 新颜色)
* @returns {string} 处理后的 CSS 内容
*/
adaptiveStyleOverride(cssText, baseURI, type, colorMap) {
if (!cssText) return "";
if (baseURI) {
// 替换相对路径资源为绝对路径
cssText = cssText.replace(/url\s*\(\s*(['"]?)(.*?)\1\s*\)/g, (match, quote, 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;
});
}
// 处理默认颜色列表
config.base.dom.themes.forEach(item => {
let oldColor = item.color;
cssText = cssText.replace(new RegExp(base.hexToRgba(oldColor), "ig"), base.hexToRgba(temp.color));
cssText = cssText.replace(new RegExp(oldColor, "ig"), temp.color);
});
// 处理 colorMap
if (type === "other") {
colorMap.forEach(function (colorPair) {
let oldColor = colorPair[0];
let newColor = colorPair[1];
// 生成旧颜色的三种形式:原样、全大写、全小写
var variants = [
oldColor,
oldColor.toUpperCase(),
oldColor.toLowerCase()
];
// 使用 Set 去重
var uniqueVariants = [...new Set(variants)];
uniqueVariants.forEach(variant => {
var regex = new RegExp(variant, "g");
cssText = cssText.replace(regex, newColor);
});
});
return cssText;
}
if (colorMap) {
colorMap.forEach(function (colorPair) {
let oldColor = colorPair[0];
let newColor = colorPair[1];
// 生成三种形式
var variants = [
oldColor,
oldColor.toUpperCase(),
oldColor.toLowerCase()
];
var uniqueVariants = [...new Set(variants)];
if (oldColor.includes("#")) {
// 替换带属性块的情况(添加 transition)
uniqueVariants.forEach(variant => {
var regexWithBlock = new RegExp(variant + "(.*?)}", "gi");
cssText = cssText.replace(regexWithBlock, newColor + "$1; transition:all.2s}");
});
// 最后再统一替换剩下的
uniqueVariants.forEach(variant => {
cssText = cssText.replace(new RegExp(variant, "gi"), newColor);
});
} else {
// 普通字符串替换
uniqueVariants.forEach(variant => {
cssText = cssText.replace(new RegExp(variant, "gi"), newColor);
});
}
});
}
return cssText;
},
/**
* 自适应全局主题颜色修改器
* @author hmjz100
* @description 自动遍历并替换 `页面所有样式表` `SVG 元素` 的颜色值
* @param {Array<[string, string]>} colorMap - 颜色映射表
* @param {"default"|"other"} type - 替换模式
*/
adaptiveThemeOverride(colorMap, type) {
base.waitForKeyElements(`[${mount}^="${mount}-ColorUI-"], [id^="${mount}-ColorUI-"]`, function (tag) {
if (tag.html() === base.adaptiveStyleOverride(tag.text(), "", type, colorMap)) return;
let cssText = base.adaptiveStyleOverride(tag.text(), "", type, colorMap);
base.addStyle(tag.attr(mount), "style", cssText, tag[0]);
return true;
}, true)
base.waitForKeyElements(`[data-pl-colored]`, function (tag) {
if (tag.attr("data-pl-colored") === temp.color) return;
let originalStyle = tag.attr("style");
if (!originalStyle) return;
let newStyle = base.adaptiveStyleOverride(originalStyle, "", type, colorMap);
if (newStyle !== originalStyle) {
tag.attr("style", newStyle);
}
return true;
}, true);
let count = 0;
if (!temp.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.adaptiveStyleOverride(responseText, href, type, colorMap);
if (responseText === base.adaptiveStyleOverride(responseText, href, type, colorMap)) return;
base.addStyle(id, "style", cssText, tag[0], "after");
})
}, true);
base.waitForKeyElements(`style:not([${mount}^="${mount}-"],[id^="swal-pub"],[class^="darkreader"])`, function (tag) {
let id = tag.attr(mount);
let text = tag.html()
if (tag.data("styles") === text) return;
tag.data("styles", text);
// 替换颜色并添加样式
let cssText = base.adaptiveStyleOverride(text, "", type, colorMap);
if (text === cssText) return;
id = id ? id : `${mount}-ColorUI-${count++}`
base.addStyle(id, "style", cssText, tag[0], "after");
}, true)
base.waitForKeyElements("svg", function (element) {
element.find("*").each((index, element) => {
let fill = $(element).attr("fill");
let stroke = $(element).attr("stroke");
if (fill) {
let newFill = base.adaptiveStyleOverride(fill, "", type, colorMap);
if (newFill !== fill) {
$(element).attr("fill", newFill);
}
}
if (stroke) {
let newStroke = base.adaptiveStyleOverride(stroke, "", type, colorMap);
if (newStroke !== stroke) {
$(element).attr("stroke", newStroke);
}
}
});
}, true);
base.waitForKeyElements(`[style]:not([${mount}^="${mount}-"],[class*="listener-"])`, function (element) {
if (element.parent(`[class*="pl-"]`).length) return;
if (element.attr("data-pl-colored") === temp.color) return;
let originalStyle = element.attr("style");
if (!originalStyle) return;
let newStyle = base.adaptiveStyleOverride(originalStyle, "", type, colorMap);
if (newStyle !== originalStyle) {
element.attr("style", newStyle);
element.attr("data-pl-colored", temp.color);
}
}, true);
temp.colored = true;
}
},
/**
* 延时执行
* @author 油小猴
* @description 仅可于 `async` 函数中执行,否则无法倒计时。
* @param {number} time - 等待时间(毫秒)
* @returns {Promise} 延时完成的 `Promise`
*/
sleep(time) {
return new Promise(resolve => setTimeout(resolve, time));
},
/**
* 判断版本号新旧
* @author hmjz100
* @description 该函数将版本号按 `.` 分割为数字数组,逐段比较大小。
* 若某段 a 的数字大于 b,则 a 更新;
* 若所有段均相等,则版本相等(返回 false)。
* @param {string} a - 待比较的版本号
* @param {string} b - 基准版本号(如 "1.0.9.7")
* @returns {boolean} - 若 a 比 b 更新,返回 true;否则返回 false
*/
isNewerVersion(a, b) {
let partsA = a.split(".").map(Number);
let partsB = b.split(".").map(Number);
let maxLength = Math.max(partsA.length, partsB.length);
for (let i = 0; i < maxLength; i++) {
let numA = partsA[i] || 0;
let numB = partsB[i] || 0;
if (numA > numB) return true;
if (numA < numB) return false;
}
return false;
},
/**
* 提取版本号主版本
* @author 油小猴
* @param {string} version - 完整版本号(如 `1.2.3`)
* @returns {string|null} 主版本号(如 `1`)或 `null`(格式错误时)
*/
getMajorVersion(version) {
let [major] = (version || "").split(".");
return /^\d+$/.test(major) ? major : null;
},
/**
* 查找 React 组件实例
* @author 油小猴
* @description 支持 Fiber 架构遍历,可指定向上查找层级
* @param {HTMLElement} dom - 起始 DOM 元素
* @param {number} [traverseUp=0] - 向上遍历层级
* @returns {Object|null} React 组件实例或 `null`
*/
findReact(dom, traverseUp = 0) {
let key = Object.keys(dom).find(key => {
return key.startsWith("__reactFiber$")
|| key.startsWith("__reactInternalInstance$");
});
let domFiber = dom[key];
if (domFiber == null) return null;
if (domFiber._currentElement) {
let compFiber = domFiber._currentElement._owner;
for (let i = 0; i < traverseUp; i++) {
compFiber = compFiber._currentElement._owner;
}
return compFiber._instance;
}
let GetCompFiber = fiber => {
let parentFiber = fiber.return;
while (base.isType(parentFiber.type) == "string") {
parentFiber = parentFiber.return;
}
return parentFiber;
};
let compFiber = GetCompFiber(domFiber);
for (let i = 0; i < traverseUp; i++) {
compFiber = GetCompFiber(compFiber);
}
return compFiber.stateNode || compFiber;
},
/**
* 迁移旧版本配置
* @author hmjz100
* @description 将旧版配置项目迁移到新版配置
*/
initConfigMigration(latest) {
try {
if (latest === 1) {
let mapping = {
"setting_rpc_domain": ["setting_aria2_rpc", 0, "domain"],
"setting_rpc_port": ["setting_aria2_rpc", 0, "port"],
"setting_rpc_path": ["setting_aria2_rpc", 0, "path"],
"setting_rpc_token": ["setting_aria2_rpc", 0, "token"],
"setting_rpc_dir": ["setting_aria2_rpc", 0, "dir"],
"setting_terminal_type": ["setting_curl_terminal"],
"setting_init_code": ["setting_init", "code"],
"setting_init_license": ["setting_init", "license"],
"setting_init_version": ["setting_init", "version"],
"setting_theme_color": ["setting_ui_theme", "color"],
"setting_theme_baidu": ["setting_ui_theme", "custom", "$baidu"],
"setting_theme_ali": ["setting_ui_theme", "custom", "$aliyun"],
"setting_theme_mcloud": ["setting_ui_theme", "custom", "$mcloud"],
"setting_theme_tcloud": ["setting_ui_theme", "custom", "$tcloud"],
"setting_theme_xunlei": ["setting_ui_theme", "custom", "$xunlei"],
"setting_theme_quark": ["setting_ui_theme", "custom", "$quark"],
"setting_theme_uc": ["setting_ui_theme", "custom", "$uc"],
"setting_theme_123": ["setting_ui_theme", "custom", "$123pan"]
};
// 旧版配置执行迁移
for (let oldKey in mapping) {
let val = base.getValue(oldKey);
if (val === undefined || val === null) continue;
val = (val === "no" ? false : val === "yes" ? true : val);
let path = mapping[oldKey];
if (path.length === 1) {
base.setValue(path[0], val);
} else {
let [root, ...keys] = path;
let obj = base.getValue(root);
if (obj === undefined || obj === null) {
let firstKeyType = typeof keys[0];
let isIndex = firstKeyType === "number" || (firstKeyType === "string" && /^\d+$/.test(keys[0]));
obj = isIndex ? [] : {};
}
let ref = obj;
for (let i = 0; i < keys.length - 1; i++) {
let key = keys[i];
if (!ref[key]) {
let nextKey = keys[i + 1];
let hasNextIndex = nextKey !== undefined && (base.isType(nextKey === "number" || (typeof nextKey) === "string" && /^\d+$/.test(nextKey)));
ref[key] = hasNextIndex ? [] : {};
}
ref = ref[key];
}
ref[keys.slice(-1)[0]] = val;
base.setValue(root, obj);
}
base.delValue(oldKey);
}
}
} catch (e) {
base.console.error("【LinkSwift】迁移旧版本配置到新配置时出错", e);
}
},
/**
* 初始化默认配置
* @author 油小猴
* @author hmjz100
* @description 创建基础配置、主题设置等存储项(仅当不存在时)
*/
initDefaultConfig() {
if (base.getValue("setting_config_version") !== "1") base.initConfigMigration(1);
// 设置新结构的默认值(仅当未设置时)
let defaults = [
{
name: "setting_aria2_rpc",
value: [
{
domain: "http://localhost",
port: "16800",
path: "/jsonrpc",
token: "",
dir: "",
default: true
}
]
},
{
name: "setting_bitcomet_rpc",
value: [
{
domain: "http://localhost",
port: "8080",
path: "/panel/task_add_httpftp_result",
authName: "",
authPass: "",
dir: "",
default: true
}
]
},
{
name: "setting_abdm_rpc",
value: [
{
domain: "http://localhost",
port: "15151",
dir: "",
default: true
}
]
},
{
name: "setting_curl_terminal",
value: "wc"
},
{
name: "setting_init",
value: {
code: "",
license: "",
version: ""
}
},
{
name: "setting_ui_theme",
value: {
color: "#574AB8",
custom: {
$baidu: false,
$aliyun: false,
$mcloud: false,
$tcloud: false,
$xunlei: false,
$quark: false,
$uc: false,
$123pan: false
}
}
},
{
name: "setting_config_version",
value: "1"
}
];
function cloneDeep(item) {
return JSON.parse(JSON.stringify(item));
}
function fillMissingFields(target, source) {
// 如果 target 不存在,直接返回 source 的深拷贝
if (target === null || target === undefined) {
return cloneDeep(source);
}
// 如果类型不同,直接替换为 source
if (typeof source !== typeof target) {
return cloneDeep(source);
}
// 如果 source 是对象
if (base.isType(source) === "object" && !Array.isArray(source)) {
if (typeof target !== "object" || Array.isArray(target)) {
return cloneDeep(source);
}
let result = { ...target };
for (let key in source) {
if (!source.hasOwnProperty(key)) continue;
// 跳过 default 的自动合并
if (key === "default") continue;
if (key === "dir" && target[key] !== undefined) continue;
if (key === "token" && target[key] !== undefined) continue;
if (key === "authName" && target[key] !== undefined) continue;
if (key === "authPass" && target[key] !== undefined) continue;
result[key] = fillMissingFields(target[key], source[key]);
}
return result;
}
// 如果 source 是数组
if (Array.isArray(source)) {
if (!Array.isArray(target)) {
return cloneDeep(source);
}
let result = [...target];
if (source.length > 0 && base.isType(source[0]) === "object" && source[0] !== null) {
let template = source[0];
// 填充字段
for (let i = 0; i < result.length; i++) {
if (base.isType(result[i]) === "object" && result[i] !== null) {
result[i] = fillMissingFields(result[i], template);
} else {
result[i] = cloneDeep(template);
}
}
// 自动补充 default: true
if (
template.default === true &&
!result.some(item => item && item.default === true) &&
result.length > 0
) {
result[0].default = true;
}
}
return result;
}
// 基本类型,保留原始值
return target;
}
defaults.forEach(({ name, value }) => {
let current = base.getValue(name);
if (
current === null ||
current === undefined ||
(Array.isArray(current) && current.length === 0)
) {
base.setValue(name, cloneDeep(value));
} else {
base.setValue(name, fillMissingFields(current, value));
}
});
},
/**
* 显示设置界面
* @author 油小猴
* @author hmjz100
* @description 构建包含 RPC 配置、终端类型等设置项的交互界面
* @see {@link https://www.youxiaohou.com/zh-cn/motrix.html#使用指南 RPC 配置说明}、 {@link https://www.youxiaohou.com/zh-cn/curl.html cURL 使用教程}
*/
showSetting(event) {
let setting = $(`
带星号的设置项目将在网页刷新后生效
Aria2 服务器
配置
比特彗星服务器
配置
AB Download Manager 服务器
配置
终端类型
${Object.keys(temp.terminalType).map(i => `${temp.terminalType[i]} `).join("")}
熄灭已经点亮的按钮*
`);
Swal.fire({
...temp.swalDefault,
title: "(。•ᴗ•。) 助手设置",
html: setting.html(),
icon: "info",
iconHtml: "⚙︎",
allowOutsideClick: false,
showCloseButton: true,
showConfirmButton: false,
footer: ` LinkSwift 由 hmjz100 制作
${config.base.dom.footer}
`,
didOpen: (toast) => {
let element = $(toast);
if (event && Object.keys($(event.currentTarget).data()).some(key => key.startsWith("backTo"))) element.find(".swal2-close").addClass("listener-tip").attr("data-title", "返回上页").css({ "left": "0", "right": "auto" }).text("◃");
if (event && $(event.currentTarget).data("back-to-downloads")) element.find(".aria2, .bitcomet, .abdm, .other").hide();
},
willClose: () => {
if (event && $(event.currentTarget).data("back-to-downloads")) base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
},
});
},
/**
* 显示 Aria2 服务设置界面
* @author hmjz100
* @description 包含 RPC 配置的交互界面
* @see {@link https://www.youxiaohou.com/zh-cn/motrix.html#使用指南 RPC 配置说明}
*/
showAria2Setting(event) {
let AriaList = base.getValue("setting_aria2_rpc");
let AriaOptions = AriaList.map((item, index) => {
return `${item.domain ? item.domain : ""}:${item.port ? item.port : ""}${item.path ? item.path : ""} `;
}).join("");
let AriaSelected = AriaList.find(i => i.default);
let Aria2Setting = `
默认配置
${AriaOptions}+ 创建新项目
删除
测试
服务主机
服务端口
服务路径
服务密钥
存储路径
`;
Swal.fire({
...temp.swalDefault,
title: "Aria2 服务设置",
html: Aria2Setting,
icon: "info",
iconHtml: "⚙︎",
allowOutsideClick: false,
showCloseButton: true,
showConfirmButton: false,
footer: ` LinkSwift 由 hmjz100 制作
${config.base.dom.footer}
`,
didOpen: (toast) => {
let element = $(toast);
if (event && Object.keys($(event.currentTarget).data()).some(key => key.startsWith("backTo"))) element.find(".swal2-close").addClass("listener-tip").attr("data-title", "返回上页").css({ "left": "0", "right": "auto" }).text("◃");
if (AriaSelected) {
element.find(".listener-rpc-input").each(function () {
let type = $(this).data("type").split(".")[1];
$(this).val(AriaSelected[type] || "");
});
} else {
AriaList[0].default = true;
base.setValue("setting_aria2_rpc", AriaList);
AriaSelected = AriaList[0];
}
},
willClose: () => {
if (event && $(event.currentTarget).data("back-to-setting")) base.showSetting();
if (event && $(event.currentTarget).data("back-to-downloads")) base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
},
});
},
/**
* 显示比特彗星服务设置界面
* @author hmjz100
* @description 包含 RPC 配置的交互界面
*/
showBitcometSetting(event) {
let BCList = base.getValue("setting_bitcomet_rpc");
let BCOptions = BCList.map((item, index) => {
return `${item.domain ? item.domain : ""}:${item.port ? item.port : ""}${item.path ? item.path : ""} `;
}).join("");
let BCSelected = BCList.find(i => i.default);
let BitcometSetting = `适用于比特彗星推送下载
默认配置
${BCOptions}+ 创建新项目
删除
服务主机
服务端口
服务路径
服务账号
服务密码
存储路径
`;
Swal.fire({
...temp.swalDefault,
title: "比特彗星服务设置",
html: BitcometSetting,
icon: "info",
iconHtml: "⚙︎",
allowOutsideClick: false,
showCloseButton: true,
showConfirmButton: false,
footer: ` LinkSwift 由 hmjz100 制作
${config.base.dom.footer}
`,
didOpen: (toast) => {
let element = $(toast);
if (event && Object.keys($(event.currentTarget).data()).some(key => key.startsWith("backTo"))) element.find(".swal2-close").addClass("listener-tip").attr("data-title", "返回上页").css({ "left": "0", "right": "auto" }).text("◃");
if (BCSelected) {
element.find(".listener-rpc-input").each(function () {
let type = $(this).data("type").split(".")[1];
$(this).val(BCSelected[type] || "");
});
} else {
BCSelected[0].default = true;
base.setValue("setting_bitcomet_rpc", BCSelected);
BCSelected = BCList[0];
}
},
willClose: () => {
if (event && $(event.currentTarget).data("back-to-setting")) base.showSetting();
if (event && $(event.currentTarget).data("back-to-downloads")) base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
},
});
},
/**
* 显示 AB Download Manager 服务设置界面
* @author hmjz100
* @description 包含 RPC 配置的交互界面
*/
showABDMSetting(event) {
let ABList = base.getValue("setting_abdm_rpc");
let ABOptions = ABList.map((item, index) => {
return `${item.domain}:${item.port} `;
}).join("");
let ABSelected = ABList.find(i => i.default);
let ABSetting = `适用于 AB Download Manager 推送下载
默认配置
${ABOptions}+ 创建新项目
删除
测试
服务主机
服务端口
存储路径
`;
Swal.fire({
...temp.swalDefault,
title: "ABDM 服务设置",
html: ABSetting,
icon: "info",
iconHtml: "⚙︎",
allowOutsideClick: false,
showCloseButton: true,
showConfirmButton: false,
footer: ` LinkSwift 由 hmjz100 制作
${config.base.dom.footer}
`,
didOpen: (toast) => {
let element = $(toast);
if (event && Object.keys($(event.currentTarget).data()).some(key => key.startsWith("backTo"))) element.find(".swal2-close").addClass("listener-tip").attr("data-title", "返回上页").css({ "left": "0", "right": "auto" }).text("◃");
if (ABSelected) {
element.find(".listener-rpc-input").each(function () {
let type = $(this).data("type").split(".")[1];
$(this).val(ABSelected[type] || "");
});
} else {
ABSelected[0].default = true;
base.setValue("setting_abdm_rpc", ABSelected);
ABSelected = BCList[0];
}
},
willClose: () => {
if (event && $(event.currentTarget).data("back-to-setting")) base.showSetting();
if (event && $(event.currentTarget).data("back-to-downloads")) base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
},
});
},
/**
* 显示美化设置界面
* @author hmjz100
* @description 提供主题颜色选择器和各网盘界面美化配置
* @fires .listener-color - 主题色选择事件
* @fires .listener-theme - 网盘主题配置变更事件
*/
showBeautify() {
function changeColor() {
temp.color = base.getValue("setting_ui_theme").color;
return config.base.dom.themes.map(item => {
return `
${item.name.split("|").map(part => `
${part}
`).join("")}
${item.color === temp.color ? `
` : ""}
`;
}).join("")
}
function changeTheme() {
let themeList = [
{ name: "百度网盘", key: "$baidu" },
{ name: "阿里云盘", key: "$aliyun" },
{ name: "移动云盘", key: "$mcloud" },
{ name: "天翼云盘", key: "$tcloud" },
{ name: "迅雷云盘", key: "$xunlei" },
{ name: "夸克网盘", key: "$quark" },
{ name: "UC 网盘", key: "$uc" },
{ name: "123 云盘", key: "$123pan" }
];
return themeList.map(item => {
return `
${item.name}
`;
}).join("");
}
let beautify = $(`
带星号的美化项目将在网页刷新后生效
${changeColor()}
替换界面配色为主题颜色*
${changeTheme()}
`)
Swal.fire({
...temp.swalDefault,
title: "(✿ᴗ‿ᴗ) 助手美化",
html: beautify.html(),
icon: "success",
iconHtml: "🍃︎",
allowOutsideClick: false,
showCloseButton: true,
showConfirmButton: false,
footer: ` LinkSwift 由 hmjz100 制作
${config.base.dom.footer}
`,
});
},
/**
* 显示调试信息面板
* @description 展示脚本运行时环境、版本信息及依赖状态
* @author hmjz100
* @property{string} manageHandler - 外部管理器名称
* @property{string} manageVersion - 外部管理器版本
*/
showDebug() {
let debugInfo = "";
debugInfo += `以下内容均为脚本自检信息 本页面仅作为调试使用`;
debugInfo += `[外] 管理器名称
${info.mhandler ? info.mhandler : "无法获取"} `;
debugInfo += `[外] 管理器版本
${info.mversion ? info.mversion : "无法获取"} `;
debugInfo += `[内] 脚本挂载点
${mount ? `${mount.toLowerCase()}.${mount}` : "无法获取"} `;
debugInfo += `[外] 脚本名称
${info.name ? info.name : "无法获取"} `;
debugInfo += `[外] 脚本作者
${info.author ? info.author : "无法获取"} `;
debugInfo += `[外/内] 脚本版本
${info.version ? info.version : "无法获取"} `;
debugInfo += `[外/内] 脚本图标
${info.icon ? ` ` : "无法获取"} `;
debugInfo += `[内] 公众号二维码
${config.base?.service?.account ? ` ` : "无法获取"} `;
debugInfo = "" + debugInfo + "
";
Swal.fire({
...temp.swalDefault,
icon: "info",
title: "调试信息",
html: debugInfo,
allowOutsideClick: false,
showCloseButton: true,
footer: ` LinkSwift 由 hmjz100 制作
${config.base.dom.footer}
`,
});
},
/**
* 显示版本更新日志
* @author hmjz100
* @description 按时间倒序展示所有历史版本更新内容
*/
async showUpdate() {
await Swal.fire({
...temp.swalDefault,
icon: "info",
title: "更新日志",
html: `
风雨送春归,飞雪迎春到。已是悬崖百丈冰,犹有花枝俏。
俏也不争春,只把春来报。待到山花烂漫时,她在丛中笑。
(o゜▽゜)o☆ 觉得好用?来一同完善本项目吧~ 欢迎提交
拉取请求 为本项目做贡献~
V1.1.2.1
1、新增 - API 下载的推送到 IDM 功能;
2、修复 - 复制 Aria2、cURL 命令行错误。
V1.1.2
1、适配 - 123 云盘新策略;
2、适配 - 夸克、UC 网盘分享页;
3、新增 - 增强下载的多块多线程支持;
4、优化 - 页面绿化的部分匹配规则;
5、优化 - 增强下载进度条样式。
V1.1.1.7
1、修复 - 缺失声明 @connect 导致的问题。
V1.1.1.6
1、废弃 - 百度网盘 BDUSS Cookie 相关代码,转向使用更安全的 AccessToken ;
2、废弃 - 百度网盘分享页面下载相关代码;
3、优化 - 下载窗口可在设置改变后动态修改界面。
V1.1.1.5
1、新增 - AB Download Manager 下载方式;
2、优化 - 支持从设置页面一键返回下载窗口,无需重复获取链接。
V1.1.1.3
1、修复夸克网盘无法获取下载链接的 Bug;
2、修复 API 下载无法复制全部链接。
V1.1.1.1
1、修复推送至 Aria2 时推送成功但报错的 Bug。
V1.1.1
1、配置文件格式更新,支持添加、删除、切换多个服务配置 ;
2、支持比特彗星推送下载,原 RPC 已并入 Aria2 下载 ;
3、界面增加 Font Awesome 图标! 更好看啦;
4、优化脚本代码、界面,运行更轻快;
5、修复上个版本遗存的问题。
V1.1.0
1、支持 UC 网盘、123 云盘;
2、改进了网盘主题的注入方式;
3、聚合并重构了部分重复函数,对整体脚本逻辑进行了梳理和精简;
4、将脚本执行阶段从 document-body 适配为 document-start。
V1.0.9.7
1、修复移动云盘下载错误;
2、优化代码,更好的错误识别;
3、去除了游小猴云服务。
V1.0.9.6
1、支持在百度网盘中选择文件夹下载;
2、优化部分提示。
V1.0.9.4
1、修复因百度网盘 AccessToken 过期导致无法获取链接的 Bug。
V1.0.9.3
1、若网盘不支持在分享中下载,将仅显示保存网盘按钮;
2、优化下载界面,支持选择 Iframe 或 Blob 的方式来下载文件,增加按钮的提示文本;
3、优化 CSS 样式,统一了 SweetAlert2 按钮样式,同时适配了 Dark Reader 插件,界面更协调;
4、支持修改油小猴网站主题色;
5、原有主题相关设置现已移动至助手美化页面中。
V1.0.9.2
1、修复使用API 下载时有可能会导致IDM无限弹窗的Bug。
V1.0.9.1
1、修复在百度网盘旧版下脚本无法删除元素的Bug。
V1.0.9
1、跟进官方V6.2.7,修复因无法进行百度授权而导致获取直链报错 9019 的 Bug。
V1.0.8.9
1、跟进官方V6.2.3,优化保存到网盘提示,修复阿里云盘、移动云盘失效的问题;
2、优化修改网盘主题的代码,减少对页面的破坏。
V1.0.8.7
1、修复在阿里云盘分享页面下点击“未点亮”按钮时没有任何反应的Bug;
2、更新并优化网盘界面精简规则;
3、支持更换 百度网盘、阿里云盘、迅雷云盘、夸克网盘、移动云盘 界面的主题颜色。
V1.0.8.6
1、新增移动云盘会员中心页面,可在网盘中点击“会员中心”按钮查看(但无法使用第三方支付)。
V1.0.8.5
1、跟进官方V6.1.6,修复迅雷网盘分享页面无法选中文件,修复移动云盘无法判断页面。
V1.0.8.4
1、修复因重复绑定按钮而导致命令重复执行的Bug;
2、优化调试信息界面排版;
3、移除对百度网盘手机网页版的支持。
V1.0.8.1
1、修复因重复绑定按钮而导致 RPC 下载会发送多条下载请求的Bug;
2、选择不使用油小猴服务器时,“用ghproxy连接Github仓库”更换为“用jsdelivr连接Github仓库”;
3、跟进官方V6.1.4版本,修复移动网盘无法获取链接,支持阿里云盘新域名alipan.com。
V1.0.7.9
1、更新精简网盘元素匹配规则,防止因通知横条而导致不能点到“API 下载”以下的按钮。
V1.0.7.8
1、跟进官方V6.1.2,加入V2接口。
2、修复百度网盘下载时因为获取不到accessToken而一直转圈。
V1.0.7.7
1、修复百度网盘的按钮会因为主题不同而被改变颜色的Bug;
2、更新夸克网盘按钮与界面。
V1.0.7.6
1、修复“注入”功能;
2、黑暗模式支持随设置热切换。
V1.0.7.5
1、修复阿里云盘下载逻辑;
2、精简代码;
3、支持深色模式;
4、修改部分提示文本;
5、修改部分CSS;
6、设置可测试RPC连接。
V1.0.7.4
1、优化下载逻辑;
2、修复阿里云盘无法使用API 下载。
V1.0.7.3
1、如果出现网络请求错误时支持自动重新请求;
2、可选择是否使用油小猴服务器。
V1.0.7.2
1、修复使用 RPC 下载时会重复发送链接的Bug。
V1.0.7.1
[实验功能,不影响正常使用]支持百度网盘手机网页版,勾选文件后可在顶栏找到“下载助手”按钮。
V1.0.6.7
1、将百度网盘界面修改为主题色,可在设置选择是否修改;
2、增加主题色名称,更改部分内容颜色;
3、移动云盘API 下载支持批量复制;
4、优化控制台输出结果;
5、百度网盘API 下载不使用IDM时可以显示剩余时间;
6、“取消点亮按钮”按钮的位置现已移动到设置页面。
7、homo特有的彩蛋又回来力(喜)。
V1.0.6.5
1、修复即使输入正确暗号也不能成功点亮按钮的服务器错误。
V1.0.6.4
1、跟进官方V6.1.1版本,修复阿里云盘获取下载链接时的问题。
V1.0.6.3
1、照顾小屏幕用户,将始终显示复制全部链接的按钮;
2、增加取消下载时的动画。
V1.0.6.2
1、修复部分界面错位,实现CSS内置;
2、百度网盘界面将变得更加简洁。
V1.0.6.1
1、新增百度云盘API 下载支持复制链接;
2、为了照顾手机浏览器用户,增大项目之间间隙,新增隐藏IDM提示选项,可在助手设置中启用;
3、修改CSS,界面会出现更多的主题色;
4、支持在游小猴官网查看暗号;
5、修复部分语法错误。
V1.0.6
1、修复了打开阿里云盘分享连接时因下载移动端广告导致只能点击 API 下载;
2、跟进官方6.0.4版本,修复夸克网盘获取下载链接失效、支持移动云盘。
V1.0.5.4
1、小修小改css,让主题色出现在更多地方;
2、修改下载链接获取失败的提示;
3、增加更多的主题色,可在助手设置查看;
4、homo彩蛋被删去力(悲)。
V1.0.5.2
1、增加脚本信息菜单(没有用);
2、优化阿里云盘显示svg图片;
3、修改弹窗按钮颜色。
V1.0.5.1
1、修复在切换按钮主题后夸克网盘不能正常显示按钮。
V1.0.5
1、跟进官方V5.0.4版本;
2、小改动,照着官方版本更正文件名称检测;
3、保留彩蛋,但必须舍弃官方暗号。
V1.0.4
大改!
1、修复了原作者留下的夸克网盘切换文件夹就多一个“下载助手”按钮的大BUG;
2、终于来了,在下载菜单增加“助手设置”“更新日志”按钮;
【再也不用点进油猴管理再进设置了(保留油猴管理内设置)】
3、修改阿里云盘和夸克网盘下载助手按钮样式;
4、增加“取消点亮按钮”油猴菜单;
5、修改部分css,使其与选择的主题更贴切。
V1.0.3
1、增加一个小彩蛋; 提示:
homo(需在未点亮按钮状态触发)
【需要重新恢复按钮为未点亮状态请进入 已安装脚本->编辑->开发者->重置到出厂->确定】
2、修改/增加默认主题色。
V1.0.2
1、修改并加宽界面,调整部分css,使Sweetalert2界面更美观,更与原版相近;
2、修改部分提示文字,使文字更容易复制。
V1.0.1
1、去除更新提示;
2、更新Sweetalert2至11版本;
3、部分CDN节点更换为jsdelivr。
V1.0.0
1、增加“注入”功能(bushi);
2、去除广告。
`,
allowOutsideClick: false,
showCloseButton: true,
confirmButtonText: ` 我已阅`,
});
},
/**
* 创建浮动提示框
* @description 监听元素悬停事件,动态显示带文件大小的提示框
* @author 油小猴
* @author hmjz100
* @fires .listener-tip - 鼠标移动事件触发提示框定位
* @see {@link temp.color} 使用全局主题色渲染文件大小信息
*/
createTip() {
// 预缓存变量与状态
let tooltip = document.querySelector(".pl-tooltip");
let ticking = false; // 用于 rAF 节流
let currentTarget = null;
// 核心更新逻辑:使用 translate3d 触发 GPU 加速
var updatePosition = (x, y) => {
if (!tooltip) return;
// 使用 transform 性能远高于 top/left,因为它不触发布局计算
tooltip.style.transform = `translate3d(${x + 10}px, ${y + 20}px, 0)`;
};
// 内容渲染逻辑
var renderContent = (target) => {
var { title, size } = target.dataset;
let html = "";
if (title) {
html = `${title} `;
} else {
var nameEl = target.querySelector(".name");
var sizeEl = target.querySelector(".size");
var name = nameEl ? nameEl.textContent : "";
var sizeText = sizeEl ? sizeEl.textContent : "";
html = `${name} `;
if (sizeText) {
html += `${sizeText} `;
}
}
if (!tooltip) {
tooltip = document.createElement("div");
tooltip.className = "pl-tooltip";
tooltip.style.position = "absolute";
tooltip.style.willChange = "transform"; // 告知浏览器提前准备层合成
tooltip.style.pointerEvents = "none"; // 防止提示框挡住鼠标导致抖动
temp.mount[0].appendChild(tooltip);
}
tooltip.innerHTML = html;
tooltip.style.display = "flex";
};
// 事件处理
var handleMove = (e) => {
if (!currentTarget) return;
// 获取坐标,PointerEvent 统一了 clientX/Y
var x = e.pageX;
var y = e.pageY;
// 使用 requestAnimationFrame 节流,确保每帧只更新一次
if (!ticking) {
requestAnimationFrame(() => {
updatePosition(x, y);
ticking = false;
});
ticking = true;
}
};
var handleOver = (e) => {
var target = e.target.closest(".listener-tip");
if (!target) return;
currentTarget = target;
renderContent(target);
updatePosition(e.pageX, e.pageY);
};
var handleOut = (e) => {
// 只有离开到非 tooltip/listener-tip 区域才隐藏
var related = e.relatedTarget;
if (!related || !related.closest(".listener-tip, .pl-tooltip")) {
currentTarget = null;
if (tooltip) tooltip.style.display = "none";
}
};
// 使用原生事件监听
document.addEventListener("pointerover", handleOver);
document.addEventListener("pointermove", handleMove, { passive: true }); // 使用 passive: true 提升滚动性能
document.addEventListener("pointerout", handleOut);
},
/**
* 创建加载状态弹窗
* @author 油小猴
* @description 生成包含旋转动画的加载容器
*/
createLoading() {
return $(``);
},
/**
* 创建用于下载的隐藏 iframe
* @author 油小猴
* @description 该方法会创建一个隐藏的 iframe 元素,并将其插入到指定的挂载点中,用于后续的下载操作。
* iframe 的 src 设置为 "javascript:;" 以避免加载额外资源,提升性能。
*/
createIframe() {
let iframe = $(``);
temp.mount.append(iframe);
},
/**
* 创建用于下载页面的 HTML
* @author 油小猴
* @author hmjz100
* @param {Array} configs - 用于配置生成 HTML 的参数
* @returns {string} 生成的 HTML 内容
* @description 详见代码
*/
generateDom(configs) {
if (base.isType(configs) !== "array" && configs.length !== 2) return message.error("提示: 配置解析失败~");
let list = (Array.isArray(configs[0]) ? configs[0] : []);
if (!list.length) return message.error("提示: 获取下载链接失败,刷新网页后再试试吧~");
let {
isFolder,
getFileName,
getFileSize,
getFileLink,
getFileMirror,
convert = {},
tooltip = {}
} = (base.isType(configs[1]) === "object" ? configs[1] : {});
let content = $(``);
let allLink = [];
list.forEach((v, i) => {
i = i + 1;
if (isFolder(v)) return;
let filename = getFileName(v);
let size = getFileSize(v);
let dlink = getFileLink(v);
let mirror = base.isType(getFileMirror) !== "undefined" ? getFileMirror(getFileLink(v)) : undefined;
if (!dlink || !dlink.includes("http")) {
content.find(".pl-main").append(`
${filename}
${base.sizeFormat(size)}
${dlink ? dlink : "获取下载链接失败,刷新网页后再试试吧~"}
`)
} else {
if (temp.mode === "api") {
allLink.push(dlink);
content.find(".pl-main").append(`
${filename}
${base.sizeFormat(size)}
增强下载 (Beta)
直接下载
推送至 IDM (Beta)
复制名称
复制链接
`);
}
if (temp.mode === "curl") {
let finalink = base.convertLinkToCurl(dlink, filename, convert?.curl);
allLink.push(finalink);
content.find(".pl-main").append(``);
}
if (temp.mode === "aria2") {
let finalink = base.convertLinkToAria2(dlink, filename, convert?.aria2);
allLink.push(finalink);
content.find(".pl-main").append(`
${filename}
${base.sizeFormat(size)}
推送链接到 Aria2 下载器
复制下载命令行
`);
}
if (temp.mode === "bitcomet") {
let finalink = base.convertLinkToBitComet(dlink, filename, convert?.bitcomet);
allLink.push(finalink);
content.find(".pl-main").append(`
${filename}
${base.sizeFormat(size)}
使用 BC 链接下载
${mirror ? `
复制镜像` : ""}
推送至下载器
`);
}
if (temp.mode === "abdm") {
content.find(".pl-main").append(`
${filename}
${base.sizeFormat(size)}
推送链接到 ABDM 下载器
`);
}
}
});
allLink = (allLink ? allLink.join("\r\n") : "")
if (temp.mode === "api" && list.length >= 2) {
if (list.length >= 2) content.find(".pl-extra").append(` 全部增强下载 (Beta)
全部推送至 IDM (Beta)
复制全部链接 `);
} else if (temp.mode === "curl") {
content.find(".pl-extra").append(` 修改终端类型 `);
if (list.length >= 2) content.find(".pl-extra").append(` 复制全部命令行 `);
} else if (temp.mode === "aria2") {
let rpc = base.getValue("setting_aria2_rpc").find(i => i.default);
content.find(".pl-extra").append(` 修改服务参数 `);
content.find(".pl-extra").append(` 查看任务 (油小猴) `);
content.find(".pl-extra").append(` 查看任务 (AriaNg) `);
if (list.length >= 2) content.find(".pl-extra").append(` 全部推送至下载器 `);
if (list.length >= 2) content.find(".pl-extra").append(` 复制全部命令行 `);
} else if (temp.mode === "bitcomet") {
let rpc = base.getValue("setting_bitcomet_rpc").find(i => i.default);
content.find(".pl-extra").append(` 修改服务参数 `);
if (list.length >= 2) content.find(".pl-extra").append(` 复制全部 BC 链接 `);
if (list.length >= 2) content.find(".pl-extra").append(` 全部推送至下载器 `);
} else if (temp.mode === "abdm") {
let rpc = base.getValue("setting_abdm_rpc").find(i => i.default);
content.find(".pl-extra").append(` 修改服务参数 `);
}
function updateTooltip($element, value) {
if (!value) return;
$element.addClass("listener-tip");
if (value.startsWith("+")) {
// 追加模式:去掉开头的 "+",然后拼接到现有 data-title
var newValue = value.substring(1);
var existingTitle = $element.attr("data-title") || "";
$element.attr("data-title", existingTitle + newValue);
} else {
// 替换模式
$element.attr("data-title", value);
}
}
if (tooltip?.enhance) updateTooltip(content.find(".enhance"), tooltip.enhance);
if (tooltip?.normal) updateTooltip(content.find(".normal"), tooltip.normal);
if (tooltip?.copy) updateTooltip(content.find(".copy"), tooltip.copy);
if (tooltip?.filename) updateTooltip(content.find(".filename"), tooltip.filename);
let html = content.html();
content.remove();
return html;
},
/**
* 获取镜像列表
* @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) {
try {
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");
} catch {
return undefined
}
},
/**
* 添加页面元素监听
* @author 油小猴
* @author hmjz100
* @description 详见代码
*/
addPageListener() {
$doc.on("click", ".listener-open-setting", (e) => {
base.showSetting(e);
});
$doc.on("click", ".listener-open-aria2-setting", (e) => {
base.showAria2Setting(e);
});
$doc.on("click", ".listener-open-bitcomet-setting", (e) => {
base.showBitcometSetting(e);
});
$doc.on("click", ".listener-open-abdm-setting", (e) => {
base.showABDMSetting(e);
});
$doc.on("click", ".listener-open-updatelog", () => {
base.showUpdate();
});
$doc.on("click", ".listener-open-beautify", () => {
base.showBeautify();
});
$doc.on("click", ".listener-unregister", async function (e) {
message.warning("正在“注入”设置项目...");
let list = base.getValue("setting_init");
list.code = "";
list.license = "";
base.setValue("setting_init", list);
base.delValue("baidu_access_token");
location.reload();
});
$doc.on("change", ".listener-terminal", async function (e) {
base.setValue("setting_curl_terminal", e.currentTarget.value);
});
$doc.on("click", ".listener-color", async function (e) {
let element = $(e.currentTarget).closest(".listener-color").length > 0 ? $(e.currentTarget).closest(".listener-color") : $(e.currentTarget);
let parent = element.closest(".pl-color");
let mask = element.find(".mask");
let color = element.data("color");
if (color && parent.length > 0 && mask.length > 0) {
parent.find(".this").remove();
mask.append(`
`);
let list = base.getValue("setting_ui_theme")
list.color = color;
base.setValue("setting_ui_theme", list);
base.addPanLinkerStyle();
}
});
$doc.on("change", ".listener-theme", async function (e) {
let list = base.getValue("setting_ui_theme");
list.custom[e.currentTarget.dataset.type] = e.currentTarget.checked;
base.setValue("setting_ui_theme", list);
});
$doc.on("click", ".listener-api-download.normal", async function (e) {
e.preventDefault();
let dataset = e.currentTarget.dataset;
let link = new URL(dataset.link);
$("#downloadIframe").attr("src", link.href);
});
$doc.on("click", ".pl-item-downing .stop", async function (e) {
var status = base._EventFactory(e);
let index = status.item.data("index");
if (temp.request[index]) {
temp.request[index].abort();
status.down_enhance_downing.find(".pl-progress .text").text("正在取消...");
status.down_enhance_downing.find(".pl-progress").css("--width", "100%");
await base.sleep(1050);
status.down_enhance_downing.find(".back").click();
}
});
$doc.on("click", ".pl-item-downing .back", async function (e) {
var status = base._EventFactory(e);
status.down_enhance_downing.find(".pl-progress .text").text("正在加载...");
status.down_enhance_downing.find(".pl-progress .text").css("white-space", "");
status.down_enhance_downing.find(".pl-progress .header").css("background", "");
status.down_enhance.show();
status.down_enhance_downing.hide();
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").hide();
status.down_normal.show();
status.down_idm.show();
status.link_copy.show();
status.link_message.hide();
});
$doc.on("click", ".listener-download-all", async function (e) {
let target = $(e.currentTarget);
let originalHtml = target.html();
$(".pl-item-link.enhance").each((index, element) => {
if ($(element).css("display") !== "none") {
$(element).click();
}
});
target.text("下载开始,进度见上方按钮哦~").animate({ opacity: "0.5" }, "slow");
await base.sleep(2000);
target.css("opacity", "");
target.html(originalHtml);
});
$doc.on("click", ".listener-send-rpc", async function (e) {
let target = $(e.currentTarget);
let originalHtml = target.html();
$(`.listener-${target.data("type")}-download`).each((index, element) => {
if ($(element).attr("data-processing") !== "true") {
$(element).click();
}
});
target.text("发送完成,结果见上方按钮哦~").animate({ opacity: "0.5" }, "slow");
await base.sleep(2000);
target.css("opacity", "");
target.html(originalHtml);
});
$doc.on("click", ".listener-copy", async function (e) {
e.preventDefault();
let target = $(e.currentTarget);
let originalHtml = target.html();
let copy = target.data("copy");
if (copy) {
base.setClipboard(copy)
target.html(` 复制成功`).animate({ opacity: "0.5" }, "slow");
await base.sleep(2000);
target.css("opacity", "");
target.html(originalHtml);
}
});
$doc.on("click", ".listener-rpc-task.youxiaohou", function () {
let rpc = base.getValue("setting_aria2_rpc").find(i => i.default);
let isHttps = rpc.domain.startsWith("https://");
let url = `${isHttps ? "https" : "http"}://d.youxiaohou.com/?rpc=${base.encodeBase(JSON.stringify({ domain: rpc.domain, port: rpc.port }))}#${rpc.token}`;
GM_openInTab(url, { active: true, insert: true, setParent: true });
});
$doc.on("click", ".listener-rpc-task.ariang", function () {
let rpc = base.getValue("setting_aria2_rpc").find(i => i.default);
let isHttps = rpc.domain.startsWith("https://");
let url = `${isHttps ? "https" : "http"}://ariang.mayswind.net/latest/#!/settings/rpc/set?protocol=${isHttps ? "wss" : "ws"}&host=${rpc.domain.replace(/^(https?:\/\/)/, "")}&port=${rpc.port}&interface=${rpc.path.replace(/^\//, "")}&secret=${rpc.token}`;
GM_openInTab(url, { active: true, insert: true, setParent: true });
});
$doc.on("change", ".listener-rpc-select", async function (e) {
let element = $(this);
let selectedIndex = element.val();
let type = element.data("type");
let list = base.getValue(`setting_${type}_rpc`);
if (selectedIndex === "new") {
return $(".listener-rpc-input").val("");
} else if (list[selectedIndex]) {
list.forEach((item, index) => {
if (item.default) {
delete item.default;
}
});
list[selectedIndex].default = true;
base.setValue(`setting_${type}_rpc`, list);
$(".listener-rpc-input").each((index, element) => {
let type = $(element).data("type").split(".")[1];
$(element).val(list[selectedIndex][type] || "");
});
}
});
$doc.on("input", ".listener-rpc-input", async function (e) {
let type = $(this).data("type");
if (!type) return;
type = type.split(".")
let list = base.getValue(`setting_${type[0]}_rpc`);
let value = $(this).val();
let selectedIndex = $(".listener-rpc-select option:selected").val();
if (selectedIndex === "new") {
list.forEach((item, index) => {
if (item.default) {
delete item.default;
}
});
list.push({
domain: "",
port: "",
path: "",
default: true
});
base.setValue(`setting_${type[0]}_rpc`, list);
selectedIndex = list.length - 1
}
list[selectedIndex][type[1]] = value;
base.setValue(`setting_${type[0]}_rpc`, list)
let select = $(".listener-rpc-select");
let options = list.map((item, index) => {
return `${item.domain ? item.domain : ""}:${item.port ? item.port : ""}${item.path ? item.path : ""} `;
}).join("");
select.html(`${options}+ 创建新项目 `);
});
$doc.on("click", ".listener-rpc-delete", async function (e) {
let type = $(this).data("type");
let list = base.getValue(`setting_${type}_rpc`);
let selectedIndex = parseInt($(".listener-rpc-select option:selected").val(), 10);
if (selectedIndex === "new" || !confirm("您确定要删除此项目吗?")) return;
list = list.filter((_, i) => i !== selectedIndex);
if (list.length === 0) return alert("至少保留一个配置");
let newDefaultIndex = selectedIndex === 0 ? 0 : selectedIndex - 1;
list[newDefaultIndex].default = true;
base.setValue(`setting_${type}_rpc`, list);
let select = $(".listener-rpc-select");
let options = list.map((item, index) => {
return `${item.domain ? item.domain : ""}:${item.port ? item.port : ""}${item.path ? item.path : ""} `;
}).join("");
select.html(`${options}+ 创建新项目 `);
$(".listener-rpc-input").each(function () {
let key = $(this).data("type").split(".")[1];
$(this).val(list[newDefaultIndex][key] || "");
});
});
$doc.on("click", ".listener-rpc-test", async function (e) {
let element = $(this);
let type = element.data("type");
let selectedIndex = $(".listener-rpc-select option:selected").val();
let list = base.getValue(`setting_${type}_rpc`);
let text = element.find("span");
let originalHtml = text.html();
if (selectedIndex === "new" || element.data("testing") === "true") return;
if (list[selectedIndex]) {
element.data("testing", "true");
text.html("等待");
element.css({ "opacity": "0.9" });
let selected = list.find(i => i.default);
let result = "fail"
if (type === "aria2") {
let domain = selected.domain,
port = selected.port,
path = selected.path,
token = selected.token;
result = await base.testConnectToAria2(domain, port, path, token);
} else if (type === "abdm") {
let domain = selected.domain,
port = selected.port;
result = await base.testConnectToABDM(domain, port);
}
if (result === "success") {
text.html("成功");
element.css({ "background-color": "#52c41a" });
} else {
text.html("失败");
element.css({ "background-color": "#cb1616" });
}
element.css({ "opacity": "" });
await base.sleep(3000);
element.data("testing", "false");
text.html(originalHtml);
element.css({ "background-color": "" });
}
});
},
/**
* 创建基础样式
* @author 油小猴
* @author hmjz100
* @description 为组件添加默认的公共样式,包括浅色和深色模式适配样式。
*/
addPanLinkerStyle() {
temp.color = base.getValue("setting_ui_theme").color;
if ("beautifyPage" in temp.main) temp.main.beautifyPage();
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").replace(/#19191a/, "#222226")}}`);
base.addStyle("swal-pub-custom-style", "style", `
.swal2-container *{vertical-align:baseline}
.swal2-styled{transition:all.2s}
.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:${temp.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:${temp.color}33 }
.swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:${temp.color};color:#fff;line-height:2em;text-align:center}
.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:${temp.color} }
.swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:${temp.color}}
.swal2-html-container{padding:1em 1.6em 0.3em;margin:0}
.swal2-close,div:where(.swal2-container) button:where(.swal2-close){position:absolute;border-radius:10px;top:0;right:0;transition:all.2s}
.swal2-close:hover,div:where(.swal2-container) button:where(.swal2-close):hover{color:${temp.color};background-color:${temp.color}30;font-size:60px}
.swal2-styled{display:flex;justify-content:center;align-items:center;gap:5px}
.swal2-styled.swal2-confirm,div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){background-color:${temp.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 ${temp.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-backdrop-show,.swal2-noanimation,div:where(.swal2-container).swal2-backdrop-show, div:where(.swal2-container).swal2-noanimation{background:rgba(25,25,26,.75);transition:backdrop-filter.2s;backdrop-filter:blur(1px)}
body.swal2-toast-shown .swal2-container{backdrop-filter:none}
.swal2-popup,div:where(.swal2-container) div:where(.swal2-popup){padding-bottom:1em;border-radius:10px}
.swal2-title,div:where(.swal2-container) h2:where(.swal2-title){height:auto}
.swal2-html-container,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}
.swal2-footer p,div:where(.swal2-container) div:where(.swal2-footer) p{margin:0;padding:0}
.swal2-icon-content,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 ${temp.color};box-shadow:0 0 0 3px ${temp.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}
::-webkit-scrollbar-track{border-radius:10px;background:#fff}
::-webkit-scrollbar-thumb,::-webkit-scrollbar-thumb:hover{border-radius:10px}
::-webkit-scrollbar-thumb{background-color:${temp.color}90!important,transition:background-color.2s;will-change:background-color}
::-webkit-scrollbar-thumb:hover{background-color:${temp.color}D0!important}
.swal2-popup{font-size:16px}
.pl-popup{font-size:12px;min-width:70%;max-width:95%}
.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-footer{font-size:15px;text-align:center;display:block}
.pl-icon{width:15px;height:15px;vertical-align:-0.15em;fill:currentColor;overflow:hidden;font-size:18px}
.pl-main{background:${temp.color}15;border-radius:10px;display:flex;flex-direction:column;gap:8px;max-height:calc(${document.documentElement.clientHeight}px - 300px);overflow:auto;padding:8px 6px}
.pl-a{position:relative;vertical-align:baseline;color:${temp.color};border-bottom:2px solid ${temp.color};text-decoration:none!important;transition:color.3s,opacity.3s;will-change:color,opacity;overflow:hidden}
.pl-a::before{content:"";position:absolute;left:0;bottom:0;width:100%;height:100%;background-color:${temp.color};transform:scaleY(0);transform-origin:bottom center;transition:transform.15s,opacity.3s;will-change:transform;z-index:-1}
.pl-a:hover,.pl-a:focus{color:#fff}
.pl-a:hover::before,.pl-a:focus::before{transform:scaleY(1)}
.pl-a:active{color:#fff;opacity:0.8}
.pl-a .pl-icon{vertical-align:-0.06em}
.pl-item{display:flex;align-items:center;background:${temp.color}30;border-radius:8px;padding:5px;gap:10px}
.pl-item-name{width:15%;text-align:left;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:default}
.pl-item-name>*{text-align:left;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.pl-item-link{flex:1;cursor:pointer}
a.pl-item-link{color:${temp.color};text-align:left;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;transition:color.15s;will-change:color}
a.pl-item-link:hover{color:#fff}
.pl-item-message{display:flex;justify-content:space-between;flex:1}
.pl-item-downing{flex:1;display:flex;align-items:center;gap:10px}
.pl-progress{position:relative; display:flex; flex:1; height:33px; overflow:hidden; border-radius:50px; background-color:#ebebeb}
.pl-progress .progress{display:flex; align-items:center; justify-content:space-around; position:absolute; left:0; top:0; height:100%; width:var(--width,0); transition:width .4s linear; will-change:width}
.pl-progress .progress.header{z-index:2; border-radius:50px; color:#fff; background-color:${temp.color}; overflow:hidden}
.pl-progress .progress.footer{z-index:1; color:#333}
.pl-progress .progress .text{line-height:1; font-size:12px; font-weight:500; white-space:nowrap; padding:0 13px}
.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-extra{display:flex;justify-content:center;background-color:${temp.color}15;border-radius:10px;gap:10px}
.pl-extra:has(>*){margin-top:1.25em;padding:8px 6px}
.pl-extra>.api.listener-download-all,.pl-extra>.curl.listener-copy,.pl-extra>.aria2.listener-send-rpc,.pl-extra>.bitcomet.listener-copy,.pl-extra>.abdm{flex:1}
.pl-extra:not(:has(>.api.listener-download-all,>.curl.listener-copy,>.aria2.listener-send-rpc,>.bitcomet.listener-copy,>.abdm))>*{flex:1}
.pl-btn-primary{color:#ffffff!important;background:${temp.color};border:0;border-radius:50px;cursor:pointer;font-size:12px;outline:none;display:flex;align-items:center;justify-content:center;gap:5px;padding:0.625em 1.1em;transition:opacity.2s,box-shadow.2s;will-change:opacity,box-shadow}
.pl-btn-primary:hover{opacity:0.8!important}
.pl-btn-primary:focus{box-shadow:0 0 0 3px ${temp.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}
.pl-btn-opacity{animation:easeOpacity 1.2s 2;animation-fill-mode:forwards;will-change:opacity}
@keyframes easeOpacity{ from{opacity:1} 50%{opacity:0.35} to{opacity:1} }
.pl-button-mini{padding:5px 10px}
.pl-button,.pl-dropdown-menu{transition:all.2s}
.pl-button{position:relative}
.pl-button .pl-dropdown-menu{opacity:0;pointer-events:none;will-change:opacity}
.pl-button:hover .pl-dropdown-menu{opacity:1;pointer-events:auto}
.pl-button-init{opacity:0.5;animation:easeInitOpacity 1.2s 5;animation-fill-mode:forwards}
@keyframes easeInitOpacity{ from{opacity:0.5} 50%{opacity:1} to{opacity:0.5} }
.pl-dropdown-menu{position:absolute;padding:5px 0;color:${temp.color};background:#fff;z-index:999;min-width:110px;border-radius:5px;box-shadow:0 1px 6px ${temp.color}33;-webkit-box-shadow:0 1px 6px ${temp.color}33;text-align:center;border:none}
@media (prefers-color-scheme:dark){ .pl-dropdown-menu{color:#fff;background:#222226} }
.pl-button-mode{color:${temp.color}!important;height:30px;padding:0 10px!important;display:flex;align-items:center;justify-content:center;gap:5px;cursor:pointer;white-space:nowrap;transition:background-color.2s;will-change:background-color}
@media (prefers-color-scheme:dark){ .pl-dropdown-menu .pl-button-mode{color:#fff!important} }
.pl-button-mode:hover{background-color:${temp.color}33!important}
@media (prefers-color-scheme:dark){ .pl-button-mode:hover{color:#fff!important;background:${temp.color}!important} }
header[style="display:none;"]~.pl-button{display:inline-block;position:fixed;top:0.6em;left:65%;z-index:99999}
.color-button{background:${temp.color}!important;border-color:${temp.color}!important;border:1px solid ${temp.color}!important;display:inline-flex;transition:background.2s,border-color.2s;will-change:background,border-color}
.color-button:hover{background:${temp.color}b0!important;border-color:${temp.color}!important}
.ali-button{background:${temp.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:background.2s;will-change:background}
.ali-button:hover{background:${temp.color}D0}
.ali-btn-icon{vertical-align:-0.2em}
.mcloud-button{float:left;position:relative;margin:20px 24px 20px 0;width:110px;height:36px;background:${temp.color};border-radius:2px;font-size:14px;color:#fff;line-height:39px;text-align:center;cursor:pointer;will-change:background}
.mcloud-button:hover{background:${temp.color}b0}
.mcloud-share-button{display:inline-block;position:relative;font-size:14px;line-height:36px;height:36px;text-align:center;color:#fff;border:1px solid ${temp.color};border-radius:2px;padding:0 24px;background:${temp.color};will-change:background}
.mcloud-share-button:hover{background:${temp.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}
.tcloud-button{color:#fff;border:1px solid ${temp.color};background:${temp.color};position:relative;height:30px;padding:0 12px;margin-right:12px;font-size:12px;line-height:28px;cursor:pointer;will-change:background,border-color}
.tcloud-button:hover{border-color:${temp.color}b0;background:${temp.color}b0}
.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.2s,color.2s,border.2s,box-shadow.2s;color:#fff;background:${temp.color};margin-left:12px;padding:0px 12px;position:relative;cursor:pointer;height:36px;will-change:background}
.xunlei-button:hover{background:${temp.color}b0}
.quark-button,.uc-button{padding:0 14px;background:${temp.color}!important;background-color:${temp.color}!important;will-change:background,background-color}
.uc-btn-icon{width:20px;height:20px;vertical-align:-0.3em}
.uc-button{padding:10px 20px!important}
.pl-setting-item{display:flex;align-items:center;justify-content:space-between;margin-top:1em}
.pl-setting-item > *:nth-child(2){max-width:80%;display:flex;justify-content:space-between;align-items:center}
.pl-setting-item .pl-setting-item{margin:0;gap:5px}
.pl-input{padding:8px 10px!important;border:1px solid #c2c2c2;border-radius:5px;font-size:14px!important;margin:0;appearance:auto!important}
.pl-setting-item > .pl-input:not([type="checkbox"]){width:80%}
.center-input{text-align:center;font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Ubuntu,"Helvetica Neue",sans-serif;font-weight:300}
.pl-tooltip{position:absolute;z-index:110000;display:none;align-items:center;color:#ffffff;background:#333;font-size:12px;line-height:1.3;max-width:600px;border-radius:5px;word-break:break-all;will-change:display,top,left}
.pl-tooltip>*{padding:5px 10px}
.pl-tooltip>*:first-child{border:1px solid;border-top-left-radius:5px;border-bottom-left-radius:5px;border-top-color:#333;border-bottom-color:#333;border-left-color:#333;border-right-color:transparent}
.pl-tooltip>*:last-child{border:1px solid;border-top-right-radius:5px;border-bottom-right-radius:5px;border-top-color:#333;border-bottom-color:#333;border-left-color:transparent;border-right-color:#333}
.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:${temp.color};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-button-save{background-color:${temp.color}!important;color:#fff!important}
.pl-button-save:hover{background-color:${temp.color}D0!important;color:#fff!important}
.swal2-container{z-index:100000}
body.swal2-height-auto{height:inherit}
[class^="swal2-"],[class*="pl-btn"]{transition:all.2s}
/* 适配(改)百度网盘会员青春版 */
a.downloadSubtitle, button.downloadSubtitle{transition:all.2s;background-color:${temp.color}}
a.downloadSubtitle:hover, button.downloadSubtitle:hover{background-color:${temp.color}D0}
a.downloadSubtitle:disabled, button.downloadSubtitle:disabled{background-color:${temp.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{background-color:${temp.color}!important;background:${temp.color}!important;color:white!important}
`);
},
/**
* 初始化引导弹窗
* @author 油小猴
* @author hmjz100
* @description 显示初始化对话框,引导用户进行配置或跳过流程。
* 支持输入特定数字触发彩蛋,并自动注入默认设置点亮功能。
* @returns {Promise} 弹窗关闭后返回空值,可能触发页面刷新
*/
async showInitDialog() {
var dialog = await Swal.fire({
...temp.swalDefault,
title: `(◍•ᴗ•◍)/ 你好呀`,
html: `
我就直说了吧… 你可以按下下方的 红色按钮 跳过这一有趣的流程
或者继续输入一些神秘的 “恶臭数字” 解锁隐藏(大嘘)彩蛋
如果您喜欢这个脚本的话
请支持原版作者 ` : ""}"> 油小猴
并给此改版点个 Star ?
脚本不仅能精简网盘界面 点亮后还能修改多个网盘的主题色哦!
`,
input: "text",
inputAttributes: {
autocapitalize: "off",
placeholder: "输入内容..."
},
customClass: {
input: "center-input"
},
showLoaderOnConfirm: true,
preConfirm: async (code = "") => {
try {
if (!code?.trim?.()) return Swal.showValidationMessage("错误:提取码不能为空");
code = code.trim();
if (["114514", "1919810", "1145141919810"].includes(code)) return "homo";
return Swal.showValidationMessage(`错误:错误的神秘数字`);
} catch (error) {
return Swal.showValidationMessage(`错误:${error}`);
}
},
showCloseButton: true,
showDenyButton: true,
denyButtonText: ` 懒得输入...我要直接点亮!`,
allowOutsideClick: false,
});
if (dialog.isDenied) {
message.warning("正在“注入”设置项目...");
await base.sleep(2500);
let list = base.getValue("setting_init");
list.code = config.base.num;
list.license = config.base.license;
base.setValue("setting_init", list);
message.success("“注入”成功啦!");
await base.sleep(1500);
location.reload();
};
if (dialog.isConfirmed && dialog.value === "homo") {
// https://pic1.zhimg.com/v2-1b97a088e156c015108dec663bba8b04.avis
await Swal.fire({
...temp.swalDefault,
icon: "error",
title: "1145141919810",
html: "homo特有的数字当然不行啦 哼哼哼啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 ",
timer: 4000,
imageUrl: "data:image/png;base64,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",
allowOutsideClick: false,
timerProgressBar: true,
showConfirmButton: false,
showDenyButton: true,
denyButtonText: "哼哼哼啊啊啊啊啊啊啊啊啊啊",
});
message.info("成就:你触发了一个homo特有的彩蛋!");
await base.sleep(4000)
// https://lh1.hetaousercontent.com/img/7d4c1c0b4adb0e95.jpg
Swal.fire({
...temp.swalDefault,
title: "1145141919810",
text: "homo特有的数字当然不行啦...吗?",
icon: "question",
imageUrl: "data:image/jpeg;base64,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",
showConfirmButton: false,
allowOutsideClick: false,
});
await base.sleep(3000)
let list = base.getValue("setting_init");
list.code = config.base.num;
list.license = config.base.license;
base.setValue("setting_init", list);
message.success("成就:哼哼哼啊啊啊啊啊啊啊啊地注入成功(喜)");
await base.sleep(1500)
location.reload();
}
},
/**
* 显示主对话框
* @author 油小猴
* @author hmjz100
* @description 使用 SweetAlert2 显示一个自定义样式的对话框,用于展示信息或操作提示。
* @param {string} title - 对话框标题
* @param {string} html - 对话框内容的 HTML 字符串
* @param {string} footer - 对话框底部说明文字
*/
showMainDialog(title, html, footer) {
Swal.fire({
...temp.swalDefault,
title,
html,
footer: `${footer}${config.base.dom.footer}
`,
customClass: {
popup: "pl-popup",
header: "pl-header",
title: "pl-title",
closeButton: "pl-close",
content: "pl-content",
input: "pl-input",
footer: "pl-footer"
},
confirmButtonText: ` 关闭`,
showCloseButton: true,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
willClose: () => {
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) {
// 初始化管理器
var manager = this.waitForKeyElements.manager || (
this.waitForKeyElements.manager = {
observers: new WeakMap(),
tasks: new Map(),
instanceCounter: 0
}
);
var targetDoc = iframeSelector
? $(iframeSelector).get(0)?.contentDocument
: document;
if (!targetDoc) return; // 无效文档直接返回
// 生成唯一控制键
controlKey = controlKey || `wkfe_${manager.instanceCounter++}`;
// 清理重复任务
var existingTask = manager.tasks.get(controlKey);
if (existingTask) {
existingTask.observer.disconnect();
manager.tasks.delete(controlKey);
}
// 创建MutationObserver回调
var processElements = () => {
var elements = $(selectorElem, targetDoc);
let foundActive = false;
elements.each((i, el) => {
var jEl = $(el);
var isProcessed = jEl.data(controlKey);
if (isProcessed) return true; // 跳过已处理元素
var cancelAction = actionFunction(jEl);
if (cancelAction) {
foundActive = true;
} else if (bWaitOnce) {
jEl.data(controlKey, true); // 标记已处理
}
});
// 一次性任务且找到有效元素时清理
if (bWaitOnce && foundActive) {
observer.disconnect();
manager.tasks.delete(controlKey);
}
};
// 创建Observer实例
var observer = new MutationObserver(processElements);
// 配置并启动观察
observer.observe(targetDoc.documentElement, {
childList: true,
subtree: true,
attributes: true,
characterData: true
});
// 注册任务
manager.tasks.set(controlKey, {
observer,
targetDoc
});
// 立即执行初始检查
processElements();
},
/**
* 状态工厂
* @author 油小猴
* @author hmjz100
* @description 接受被监听的 DOM 元素的状态,根据状态确定元素是谁
* @param {Event} event - 元素状态
*/
_EventFactory(event) {
let target = $(event.target);
let item = target.parents(".pl-item");
return {
target, item,
down_normal: item.find(".pl-item-link.normal"),
down_enhance: item.find(".pl-item-link.enhance"),
down_enhance_downing: item.find(".pl-item-downing"),
down_idm: item.find(".listener-idm-download"),
link_message: item.find(".pl-item-message"),
link_copy: item.find(".pl-item-copy"),
};
}
};
/**
* 百度网盘
* @author 油小猴
* @author hmjz100
*/
let $baidu = {
async getToken() {
try {
$doc.find(".loading-popup .loading-title").html(`令牌获取中`);
$doc.find(".loading-popup .swal2-html-container").html(`正在获取授权状态~
`);
// 获取授权状态
let authorize = await base.getFinal(config.$baidu.api.getAccessToken, { Origin: "", Referer: "" }, true);
let accessToken = "";
// 判断授权情况
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, { Origin: "", Referer: "" }, "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 .swal2-html-container").html(`正在自动确认授权~
`);
// 发送请求达到自动进行授权
await base.post(config.$baidu.api.getAccessToken, base.stringify(data), { Origin: "", Referer: "", "Content-Type": "application/x-www-form-urlencoded" });
// 再次获取授权状态
let res2 = await base.getFinal(config.$baidu.api.getAccessToken, { Origin: "", Referer: "" }, true);
accessToken = res2.match(/access_token=([^&]+)/)?.[1];
} else if (authorize.includes("access_token=")) {
accessToken = authorize.match(/access_token=([^&]+)/)?.[1];
}
// 统一处理令牌结果
$doc.find(".loading-popup .loading-title").html(`令牌获取中`);
if (!!accessToken) {
$doc.find(".loading-popup .swal2-html-container").html(`授权成功,令牌已缓存~
`);
base.setValue("baidu_access_token", accessToken);
return accessToken;
} else return "";
} catch (error) {
return "";
}
},
addPageListener() {
$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", async function (e) {
temp.mode = e.currentTarget.dataset.mode;
if (!temp.mode) return;
temp.main.getLink();
});
$doc.on("click", ".pl-button-save", async function (e) {
e.preventDefault();
let selectList = temp.main.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-api-download.enhance", async function (e) {
e.preventDefault();
var status = base._EventFactory(e);
var file = {
index: status.item.data("index"),
link: status.item.data("link"),
name: status.item.data("name"),
size: status.item.data("size") || 0,
}
base._resetData(file.index);
// UI 初始化
status.down_normal.hide();
status.down_enhance.hide();
status.down_idm.hide();
status.link_message.hide();
status.link_copy.hide();
status.down_enhance_downing.find(".stop").show();
status.down_enhance_downing.show();
let startTime = Date.now();
let lastTime = startTime;
let lastLoaded = 0;
let emaSpeed = 0;
var tau = 2; // 时间常数(秒),数值越大速度显示越平稳,越小越灵敏。建议 1.5 - 3 之间。
base.download(file.link, { "User-Agent": config.$baidu.api.ua.downloadLink, "Origin": "", "Referer": "" }, {
...file,
onProgress: (prog, loaded, total) => {
var time = Date.now();
var insDiff = (time - lastTime) / 1000 || 0.001; // 瞬时耗时(秒)
var insSpeed = (loaded - lastLoaded) / insDiff; // 瞬时速度(B/s)
var avgDiff = (time - startTime) / 1000 || 0.1; // 总耗时(秒)
var avgSpeed = loaded / avgDiff; // 全局平均速度(B/s)
var alpha = 1 - Math.exp(-insDiff / tau);
if (emaSpeed === 0) {
emaSpeed = insSpeed; // 第一次采样,直接赋值
} else {
// EMA 公式:当前平滑值 = (1 - alpha) * 旧值 + alpha * 当前瞬时值
emaSpeed = (1 - alpha) * emaSpeed + alpha * insSpeed;
}
var rSize = total - loaded;
var predictionSpeed = (emaSpeed > 1024) ? emaSpeed : avgSpeed; // 兜底 - 如果 EMA 速度异常,则参考全局平均速度
var rTime = predictionSpeed > 0 ? rSize / predictionSpeed : 0;
lastLoaded = loaded;
lastTime = time;
var dprog = Math.min(prog, 100);
status.down_enhance_downing.find(".pl-progress").css("--width", `${dprog}%`);
status.down_enhance_downing.find(".pl-progress .text").text(`${dprog.toFixed(2)}% - ${base.sizeFormat(loaded)} | ${base.sizeFormat(emaSpeed)}/块 | ${base.rtimeFormat(rTime)}`);
}
})
.then(async (res) => {
status.down_enhance_downing.find(".pl-progress .header").css("background", "#55af28");
base.blobDownload(res.response, file.name);
await base.sleep(1000);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress .text").html(`下载完成~ 浏览器下载框应该弹出来了哦~`);
})
.catch(async (error) => {
base.console.error("【LinkSwift】Download(load)", error);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress").css("--width", "100%");
status.down_enhance_downing.find(".pl-progress .header").css("background", "#cc3235");
let estatus = `QAQ 下载出错~`;
if (!error?.status) estatus += ` 服务器未返回状态,若是下载一段时间后中断,可能是服务器返回文件长度不匹配,请重试;若是直接中断,请检查您的网络、脚本管理器扩展或浏览器~`;
if (error?.status == 403) estatus += ` 服务器说:链接已过期,关闭窗口重新获取试试吧~`;
if (error?.status == 204 || error?.statusText === "IDM") estatus += ` 服务说:链接已被 IDM 捕获~`;
status.down_enhance_downing.find(".pl-progress .text").html(estatus);
status.down_enhance_downing.find(".pl-progress .text").css("white-space", "break-spaces");
})
});
$doc.on("click", ".listener-idm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToIDM(target.data("link"), target.data("filename"), target.data("filesize"), { "User-Agent": config.$baidu.api.ua.downloadLink });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-aria2-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToAria2(target.data("link"), target.data("filename"), [`User-Agent:${config.$baidu.api.ua.downloadLink}`]);
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-bitcomet-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToBitcomet(target.data("link"), target.data("filename"), { "user_agent": config.$baidu.api.ua.downloadLink });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-abdm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToABDM(target.data("link"), target.data("filename"), { "User-Agent": config.$baidu.api.ua.downloadLink });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
},
greenerPage() {
temp.page = temp.main.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("div.dialog-gray:has(.dialog-close):has(.tip-body):has(~ .module-canvas)", function (tag) {
tag.find(".dialog-close").click();
$(".module-canvas").click();
}, true)
// back pc motivate 回端激励
base.waitForKeyElements(".wp-s-header ~ div:not([class]):has(.nd-custom-btn)", function (tag) {
if (!tag.text().includes("客户端")) return;
tag.remove();
}, true)
base.waitForKeyElements(".pc-client-fullscreen-modal", function (tag) {
tag.hide();
tag.find(".pc-client-modal-close").click();
}, true)
base.waitForKeyElements(".nd-bottom-right-popover:has(.nd-custom-popover-close)", function (tag) {
tag.hide();
tag.find(".nd-custom-popover-close").click();
}, true)
base.waitForKeyElements(".wp-s-aside-nav__sub-bottom > a.wp-aside-nav__pc-client-button", 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((index, element) => {
let tag = $(element);
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(``);
}, true)
// 美化分享页面
if (temp.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)
}
},
beautifyPage() {
if (base.getValue("setting_ui_theme").custom.$baidu !== true) return;
if (temp.main.detectPage() !== "home") {
base.adaptiveThemeOverride([
["#717fff", temp.color],
["#717FFF", temp.color],
["#06a8ff", temp.color],
["#06A8FF", temp.color],
["#06a7ff", temp.color],
["#06A7FF", temp.color],
["#dcdfe6", temp.color],
["#DCDFE6", temp.color],
["#0095ff", temp.color],
["#0095FF", temp.color],
["#09aaff", temp.color],
["#09AAFF", temp.color],
["#0ca6ff", temp.color],
["#0CA6FF", temp.color],
["#5040ff", temp.color],
["#5040FF", temp.color],
["#454d5a", temp.color],
["#454D5A", temp.color],
["#a2abbd", temp.color],
["#A2ABBD", temp.color],
["#030b1a", temp.color],
["#030B1A", temp.color],
["#afb3bf", temp.color],
["#AFB3BF", temp.color],
["#ff436a", temp.color],
["#FF436A", temp.color],
["#03081a", temp.color],
["#03081A", temp.color],
["#2974b6", temp.color],
["#2974B6", temp.color],
["#0596e6", temp.color],
["#0596E6", temp.color],
["#C3EAFF", temp.color],
["#c0d9fe", `${temp.color}50`],
["#0098EA", `${temp.color}D0`],
["#38b9ff", `${temp.color}D0`],
["#38B9FF", `${temp.color}D0`],
["#42d8ff", `${temp.color}D0`],
["#42D8FF", `${temp.color}D0`],
["#a48dff", `${temp.color}D0`],
["#A48DFF", `${temp.color}D0`],
["#6b79f2", `${temp.color}D0`],
["#6B79F2", `${temp.color}D0`],
["#9c86f2", `${temp.color}90`],
["#9C86F2", `${temp.color}90`],
["#83d3ff", `${temp.color}90`],
["#83D3FF", `${temp.color}90`],
["#C4D8F4", `${temp.color}90`],
["#fafafc", `${temp.color}20`],
["#FAFAFC", `${temp.color}20`],
["#f5fbff", `${temp.color}20`],
["#F5FBFF", `${temp.color}20`],
["#b4e5ff", `${temp.color}20`],
["#B4E5FF", `${temp.color}20`],
["#f0faff", `${temp.color}20`],
["#F0FAFF", `${temp.color}20`],
["#c4d8f4", `${temp.color}20`],
["#f1f3f8", `${temp.color}15`],
["#F1F3F8", `${temp.color}15`],
["#f2faff", `${temp.color}10`],
["#F2FAFF", `${temp.color}10`],
["#eef9fe", `${temp.color}10`],
["#EEF9FE", `${temp.color}10`],
["#f7f9fc", `${temp.color}10`],
["#F7F9FC", `${temp.color}10`],
["#f5f6fa", `${temp.color}10`],
["#F5F6FA", `${temp.color}10`],
["#b4e5ff", `${temp.color}10`],
["#B4E5FF", `${temp.color}10`],
["#e6f6ff", `${temp.color}10`],
["#E6F6FF", `${temp.color}10`],
["0,149,255", base.hexToRgba(temp.color)],
["30, 175, 255", base.hexToRgba(temp.color)],
["6, 167, 255, 0.1", base.hexToRgba(`${temp.color}1a`)],
["6,167,255,.1", base.hexToRgba(`${temp.color}1a`)],
["6,167,255,.23", base.hexToRgba(`${temp.color}3b`)],
["164,141,255,.2", base.hexToRgba(`${temp.color}30`)],
["196,182,255,.2", base.hexToRgba(`${temp.color}20`)],
["113,127,255,.2", base.hexToRgba(`${temp.color}40`)],
["3,8,26,.6", base.hexToRgba(`${temp.color}D0`)],
["255,32,102,.4", base.hexToRgba(`${temp.color}66`)],
["72,166,248,.7", base.hexToRgba(`${temp.color}66`)],
]);
};
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:${temp.color}!important;padding:8px 15px;line-height:15px;width:auto;height:auto}
a{transition:all.2s!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 ${temp.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.adaptiveThemeOverride([
["#717fff", temp.color],
["#717FFF", temp.color],
["#06a8ff", temp.color],
["#06A8FF", temp.color],
["#06a7ff", temp.color],
["#06A7FF", temp.color],
["#dcdfe6", temp.color],
["#DCDFE6", temp.color],
["#0095ff", temp.color],
["#0095FF", temp.color],
["#09aaff", temp.color],
["#09AAFF", temp.color],
["#0ca6ff", temp.color],
["#0CA6FF", temp.color],
["#5040ff", temp.color],
["#5040FF", temp.color],
["#454d5a", temp.color],
["#454D5A", temp.color],
["#a2abbd", temp.color],
["#A2ABBD", temp.color],
["#030b1a", temp.color],
["#030B1A", temp.color],
["#afb3bf", temp.color],
["#AFB3BF", temp.color],
["#ff436a", temp.color],
["#FF436A", temp.color],
["#03081a", temp.color],
["#03081A", temp.color],
["#2974b6", temp.color],
["#2974B6", temp.color],
["#0596e6", temp.color],
["#0596E6", temp.color],
["#C3EAFF", temp.color],
["#c0d9fe", `${temp.color}50`],
["#0098EA", `${temp.color}D0`],
["#38b9ff", `${temp.color}D0`],
["#38B9FF", `${temp.color}D0`],
["#42d8ff", `${temp.color}D0`],
["#42D8FF", `${temp.color}D0`],
["#a48dff", `${temp.color}D0`],
["#A48DFF", `${temp.color}D0`],
["#6b79f2", `${temp.color}D0`],
["#6B79F2", `${temp.color}D0`],
["#9c86f2", `${temp.color}90`],
["#9C86F2", `${temp.color}90`],
["#83d3ff", `${temp.color}90`],
["#83D3FF", `${temp.color}90`],
["#C4D8F4", `${temp.color}90`],
["#fafafc", `${temp.color}20`],
["#FAFAFC", `${temp.color}20`],
["#f5fbff", `${temp.color}20`],
["#F5FBFF", `${temp.color}20`],
["#b4e5ff", `${temp.color}20`],
["#B4E5FF", `${temp.color}20`],
["#f0faff", `${temp.color}20`],
["#F0FAFF", `${temp.color}20`],
["#c4d8f4", `${temp.color}20`],
["#f1f3f8", `${temp.color}15`],
["#F1F3F8", `${temp.color}15`],
["#f2faff", `${temp.color}10`],
["#F2FAFF", `${temp.color}10`],
["#eef9fe", `${temp.color}10`],
["#EEF9FE", `${temp.color}10`],
["#f7f9fc", `${temp.color}10`],
["#F7F9FC", `${temp.color}10`],
["#f5f6fa", `${temp.color}10`],
["#F5F6FA", `${temp.color}10`],
["#b4e5ff", `${temp.color}10`],
["#B4E5FF", `${temp.color}10`],
["#e6f6ff", `${temp.color}10`],
["#E6F6FF", `${temp.color}10`],
["0,149,255", base.hexToRgba(temp.color)],
["30, 175, 255", base.hexToRgba(temp.color)],
["6, 167, 255, 0.1", base.hexToRgba(`${temp.color}1a`)],
["6,167,255,.1", base.hexToRgba(`${temp.color}1a`)],
["6,167,255,.23", base.hexToRgba(`${temp.color}3b`)],
["164,141,255,.2", base.hexToRgba(`${temp.color}30`)],
["196,182,255,.2", base.hexToRgba(`${temp.color}20`)],
["113,127,255,.2", base.hexToRgba(`${temp.color}40`)],
["3,8,26,.6", base.hexToRgba(`${temp.color}D0`)],
["255,32,102,.4", base.hexToRgba(`${temp.color}66`)],
["72,166,248,.7", base.hexToRgba(`${temp.color}66`)],
], "other");
},
addButton() {
base.waitForKeyElements(config.$baidu.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "home") return;
let $button = $(``);
element.prepend($button);
})
base.waitForKeyElements(config.$baidu.mount.main, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "main") return;
let $button = $(``);
element.prepend($button);
})
base.waitForKeyElements(config.$baidu.mount.main, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "youth") return;
let $button = $(``);
element.prepend($button);
})
base.waitForKeyElements(config.$baidu.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(`
下载助手
`)
element.after($button);
})
},
addInitButton() {
base.waitForKeyElements(config.$baidu.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "home") return;
let $button = $(``);
$button.click(base.showInitDialog);
element.prepend($button);
})
base.waitForKeyElements(config.$baidu.mount.main, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || (temp.page !== "main" && temp.page !== "youth")) return;
let $button = $(``);
$button.click(base.showInitDialog);
element.prepend($button);
})
base.waitForKeyElements(config.$baidu.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(`
点我点亮
`)
$button.click(base.showInitDialog);
element.after($button);
})
},
async getLink() {
Swal.fire({
...temp.swalDefault,
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: () => {
Swal.showLoading();
},
});
// 获取选择的文件列表
let selectList = this.getSelectedList();
let accessToken = (base.getValue("baidu_access_token") || await temp.main.getToken());
if (!accessToken) {
message.info("提示: 稍后请在新标签页中授权助手哦~");
base.delValue("baidu_access_token");
await base.sleep(3300);
GM_openInTab(config.$baidu.api.getAccessToken, { active: true, insert: true, setParent: true })
let attempts = 0;
let interval = setInterval(() => {
if (!!base.getValue("baidu_access_token")) {
clearInterval(interval);
accessToken = base.getValue("baidu_access_token")
}
attempts++;
if (attempts > 120) {
clearInterval(interval);
return message.error("提示: 时间太长,我先撤下啦~");
}
}, 1000);
return;
}
if (selectList.length === 0) return message.error("提示: 请勾选要下载的文件哦~");
if (temp.page === "home" || temp.page === "main") {
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 = 50;
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 && res.list.length !== 0 && res.errno === 0) {
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.delValue("baidu_access_token");
return message.error("提示: 访问令牌已过期,刷新网页后再获取一次吧~ 代码:" + res.errno);
}
base.delValue("baidu_access_token");
return message.error("提示: 获取下载链接失败,刷新网页后再试试吧~ 代码:" + res.errno);
} else {
return message.error("提示: 获取下载链接失败,刷新网页后再试试吧~");
}
}
await base.sleep(1000);
}
if (linkList.length) {
temp.links = [linkList, {
isFolder: v => v.isdir === 1,
getFileName: v => (v.server_filename || v.filename),
getFileSize: v => v.size,
getFileLink: v => {
let url = new URL(v.dlink);
url.searchParams.set("access_token", accessToken);
return url.href;
},
convert: {
aria2: `--header "User-Agent:${config.$baidu.api.ua.downloadLink}"`,
curl: `-A "${config.$baidu.api.ua.downloadLink}"`,
bitcomet: `user_agent=${encodeURIComponent(config.$baidu.api.ua.downloadLink)}`
},
tooltip: config.$baidu.dom
}];
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
} else {
return message.error("提示: 获取下载链接失败,刷新网页后再试试吧~");
}
} else {
return message.error("提示: 页面错误~");
}
},
getSelectedList() {
let List, selectList
try {
List = require("system-core:context/context.js").instanceForSystem.list;
selectList = List.getSelected();
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) { }
},
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 initPanLinker() {
base.registerMenuCommand();
if (config.base.num === base.getValue("setting_init").code || config.base.license === base.getValue("setting_init").license) {
this.addButton();
} else {
this.addInitButton();
}
this.addPageListener();
},
};
let $baiduAuthorize = {
async initPanLinker() {
base.registerMenuCommand();
Swal.fire({
...temp.swalDefault,
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
html: `请稍后`,
willOpen: () => {
Swal.showLoading();
},
});
if (config.base.num === base.getValue("setting_init").code || config.base.license === base.getValue("setting_init").license) {
let url = new URL(location);
let auth = new URL(config.$baidu.api.getAccessToken);
let allowedClientIds = [
auth.searchParams.get("client_id"),
"L6g70tBRRIXLsY0Z3HwKqlRE", // pcstest_oauth
"NqOMXF6XGhGRIGemsQ9nG0Na", // ES 文件管理器,Secret:SVT6xpMdLcx6v4aCR4wT8BBOTbzFO8LM
"fSds3K4w43rw37tOqlQmTa2kDwaczK4U", // 小度智能词典笔专业版
"TFwtw8uwHxpdkvVqVKdIlx1XqXUnr1zG", // 印象笔记
"9dgBV9yesuBVOXaxls7aVHbLBLqU8yyg", // WPS文档
"l9DdBOG4RYroMscmzK5OChdaGelgd92M", // 小猴云印PC版
"Kyr013gHQBf2immy3fQt1jZ3nZVpiGAm", // 简单打印
"iYCeC9g08h5vuP9UqvPHKKSVrKFXGa1v", // Alist
"omiOnr2tYnN9vSyDErcVFWpPU2mZA7YO", // OpenList
"QHOuRXiepJBMjtk0esLhrPoNlQyYd0mF", // mcp_server
"IlLqBbU3GjQ0t46TRwFateTprHWl39zF", // 百度手机助手
"iG6ghsi9r0RR0jTFCrlvTjX9", // 百度云的小测试 https://github.com/scusjs/baiduyun/blob/43785cd7eaab6741fe2a7de7cd3391920b94c9c7/bdy/config.ini
"YgMAXXnP0Lziw0LPVbc6E4zm", // 我的目的地 https://github.com/ymgd/weixinopen/blob/2e1f9e3d32616c3623547a8f25d330598337ba04/wechat-weapp-union/zndg/app.js#L64
];
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"))
) {
var dialog = await Swal.fire({
...temp.swalDefault,
icon: "info",
title: `提示`,
html: `(◍•ᴗ•◍) 你好呀,为了获取百度网盘文件的下载直链 “下载助手” 需要你的授权,以获取网盘文件的访问令牌
由于在百度 OAuth 页面使用了其他应用的 Client ID 所以显示的应用名称可能会有所不同,敬请理解
获取到的令牌仅用于调用百度网盘 API 生成直链 不会用于其他用途,请放心授权
`,
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({
...temp.swalDefault,
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 () => {
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);
await Swal.fire({
...temp.swalDefault,
icon: "success",
title: `成功啦`,
html: `(◍•ᴗ•◍) 您已成功授权/授权过 脚本获取网盘访问令牌~
获取到的令牌仅用于调用百度网盘 API 生成直链 不会用于其他用途
等待 / 秒之后将关闭此页面
`,
timer: 5000,
timerProgressBar: true,
showConfirmButton: true,
showDenyButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
confirmButtonText: ` 关闭`,
willOpen: () => {
let secondSpan = document.getElementById("second");
let interval = setInterval(() => {
if (Swal.isVisible()) {
let timeLeft = Swal.getTimerLeft();
if (timeLeft !== null && timeLeft > 0) {
secondSpan.textContent = (timeLeft / 1000).toFixed(2);
}
} else {
clearInterval(interval);
}
}, 10);
},
didOpen: function (toast) {
toast.addEventListener("mouseenter", () => {
Swal.stopTimer();
});
toast.addEventListener("mouseleave", () => {
Swal.resumeTimer();
});
},
willClose: () => window.close()
});
return window.close();
} else {
clearInterval(int)
Swal.close()
}
}, 1)
} else {
Swal.close()
}
} else {
Swal.close()
}
}
}
/**
* 阿里云盘
* @author 油小猴
* @author hmjz100
*/
let $aliyun = {
addPageListener() {
$doc.on("click", ".pl-button-save", async function (e) {
e.preventDefault();
let reactDomGrid = document.querySelector(config.$aliyun.mount.grid);
if (reactDomGrid) {
var dialog = await Swal.fire({
...temp.swalDefault,
title: "提示",
html: `请先切换到 列表视图 后再获取下载链接哦
`,
icon: "info",
showCloseButton: true,
showDenyButton: true,
confirmButtonText: ` 切换`,
denyButtonText: ` 不要`,
});
if (dialog.isConfirmed) {
document.querySelector(config.$aliyun.mount.switch).click();
return message.success("提示: 切换为列表视图成功 请再获取一次下载链接吧~");
}
return false;
}
let selectList = temp.main.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) {
temp.mode = e.currentTarget.dataset.mode;
if (!temp.mode) return;
let reactDomGrid = document.querySelector(config.$aliyun.mount.grid);
if (reactDomGrid) {
var dialog = await Swal.fire({
...temp.swalDefault,
title: "提示",
html: `请先切换到 列表视图 后再获取下载链接哦
`,
icon: "info",
showCloseButton: true,
showDenyButton: true,
confirmButtonText: ` 切换`,
denyButtonText: ` 不要`,
});
if (dialog.isConfirmed) {
document.querySelector(config.$aliyun.mount.switch).click();
return message.success("提示: 切换为列表视图成功 请再获取一次下载链接吧~");
}
return false;
}
temp.main.getLink();
});
$doc.on("click", ".listener-api-download.enhance", async function (e) {
e.preventDefault();
var status = base._EventFactory(e);
var file = {
index: status.item.data("index"),
link: status.item.data("link"),
name: status.item.data("name"),
size: status.item.data("size") || 0,
}
base._resetData(file.index);
// UI 初始化
status.down_normal.hide();
status.down_enhance.hide();
status.down_idm.hide();
status.link_message.hide();
status.link_copy.hide();
status.down_enhance_downing.find(".stop").show();
status.down_enhance_downing.show();
let startTime = Date.now();
let lastTime = startTime;
let lastLoaded = 0;
let emaSpeed = 0;
var tau = 2; // 时间常数(秒),数值越大速度显示越平稳,越小越灵敏。建议 1.5 - 3 之间。
base.download(file.link, undefined, {
...file,
onProgress: (prog, loaded, total) => {
var time = Date.now();
var insDiff = (time - lastTime) / 1000 || 0.001; // 瞬时耗时(秒)
var insSpeed = (loaded - lastLoaded) / insDiff; // 瞬时速度(B/s)
var avgDiff = (time - startTime) / 1000 || 0.1; // 总耗时(秒)
var avgSpeed = loaded / avgDiff; // 全局平均速度(B/s)
var alpha = 1 - Math.exp(-insDiff / tau);
if (emaSpeed === 0) {
emaSpeed = insSpeed; // 第一次采样,直接赋值
} else {
// EMA 公式:当前平滑值 = (1 - alpha) * 旧值 + alpha * 当前瞬时值
emaSpeed = (1 - alpha) * emaSpeed + alpha * insSpeed;
}
var rSize = total - loaded;
var predictionSpeed = (emaSpeed > 1024) ? emaSpeed : avgSpeed; // 兜底 - 如果 EMA 速度异常,则参考全局平均速度
var rTime = predictionSpeed > 0 ? rSize / predictionSpeed : 0;
lastLoaded = loaded;
lastTime = time;
var dprog = Math.min(prog, 100);
status.down_enhance_downing.find(".pl-progress").css("--width", `${dprog}%`);
status.down_enhance_downing.find(".pl-progress .text").text(`${dprog.toFixed(2)}% - ${base.sizeFormat(loaded)} | ${base.sizeFormat(emaSpeed)}/块 | ${base.rtimeFormat(rTime)}`);
}
})
.then(async (res) => {
status.down_enhance_downing.find(".pl-progress .header").css("background", "#55af28");
base.blobDownload(res.response, file.name);
await base.sleep(1000);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress .text").html(`下载完成~ 浏览器下载框应该弹出来了哦~`);
})
.catch(async (error) => {
base.console.error("【LinkSwift】Download(load)", error);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress").css("--width", "100%");
status.down_enhance_downing.find(".pl-progress .header").css("background", "#cc3235");
let estatus = `QAQ 下载出错~`;
if (!error?.status) estatus += ` 服务器未返回状态,若是下载一段时间后中断,可能是服务器返回文件长度不匹配,请重试;若是直接中断,请检查您的网络、脚本管理器扩展或浏览器~`;
if (error?.status == 403) estatus += ` 服务器说:链接已过期,关闭窗口重新获取试试吧~`;
if (error?.status == 204 || error?.statusText === "IDM") estatus += ` 服务说:链接已被 IDM 捕获~`;
status.down_enhance_downing.find(".pl-progress .text").html(estatus);
status.down_enhance_downing.find(".pl-progress .text").css("white-space", "break-spaces");
})
});
$doc.on("click", ".listener-idm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToIDM(target.data("link"), target.data("filename"), target.data("filesize"), { "Referer": `https://${location.host}/` });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-aria2-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToAria2(target.data("link"), target.data("filename"), [`Referer:https://${location.host}/`]);
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-bitcomet-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToBitcomet(target.data("link"), target.data("filename"), { "referrer": `https://${location.host}/` });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-abdm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToABDM(target.data("link"), target.data("filename"), undefined);
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
},
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(`[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);
},
beautifyPage() {
if (base.getValue("setting_ui_theme").custom.$aliyun !== true) return;
base.adaptiveThemeOverride([
["#3763ff", temp.color],
["#8664ff", `${temp.color}D0`],
["99, 125, 255", base.hexToRgba(temp.color)],
["132, 133, 141", base.hexToRgba(temp.color)],
["112, 136, 255", base.hexToRgba(temp.color)],
["97, 122, 250", base.hexToRgba(temp.color)],
["68, 109, 255", base.hexToRgba(temp.color)],
["82, 110, 250", base.hexToRgba(`${temp.color}20`)],
["122, 144, 255", base.hexToRgba(`${temp.color}D0`)],
["138, 157, 255", base.hexToRgba(`${temp.color}D0`)],
]);
},
svg: ` `,
addButton() {
base.waitForKeyElements(config.$aliyun.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "home") return;
let $button = $(`
${temp.main.svg}下载助手
`);
element.append($button);
})
base.waitForKeyElements(config.$aliyun.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(`
${temp.main.svg}下载助手
`);
$button.css({ "margin-right": "10px", "height": "36px", "width": "auto", "padding": "1px 30px" });
element.prepend($button);
})
},
addInitButton() {
let $button = $(`${temp.main.svg}点我点亮
`);
$button.click(base.showInitDialog);
base.waitForKeyElements(config.$aliyun.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "home") return;
$button.css({ "width": "auto" });
element.append($button);
})
base.waitForKeyElements(config.$aliyun.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "share") return;
$button.css({ "margin-right": "10px", "height": "36px", "padding": "1px 30px", "width": "auto" });
element.prepend($button);
})
},
async getLink() {
Swal.fire({
...temp.swalDefault,
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: () => {
Swal.showLoading();
},
});
let selectList = this.getSelectedList();
if (selectList.length === 0) return message.error("提示: 请勾选要下载的文件哦~");
if (selectList.every(item => item.type !== "file")) return message.error("提示: 请打开文件夹后再勾选文件~");
if (temp.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} 个链接~
`);
});
// 等待本批次的请求结果
let res = await Promise.all(queue);
res.forEach((val, index) => {
noUrlSelectList[index].url = val;
});
// 每次处理完一个批次后,等待 1 秒
await base.sleep(1000);
}
} else {
return message.error("提示: 页面错误~");
}
temp.links = [selectList, {
isFolder: v => v.type === "folder",
getFileName: v => v.name,
getFileSize: v => v.size,
getFileLink: v => (v.downloadUrl || v.url),
convert: {
aria2: `--header "Referer:https://${location.host}/"`,
curl: `-e "https://${location.host}/"`,
bitcomet: `&refer=${encodeURIComponent(`https://${location.host}/`)}`
},
tooltip: config.$aliyun.dom
}];
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
},
async getFileUrlByOnce(d, f) {
let res = await base.post(config.$aliyun.api.getLink, { drive_id: d, file_id: f }, { "Authorization": `${base.getStorage("token").token_type} ${base.getStorage("token").access_token}`, "X-Canary": "client=windows,app=adrive,version=v6.0.0" });
if (res.code == "AccessTokenInvalid") {
return message.error("提示: 访问令牌过期了,请刷新网页后再试");
}
if (res.url) {
return res.url;
}
return "";
},
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 "";
},
async initPanLinker() {
base.registerMenuCommand();
if (config.base.num === base.getValue("setting_init").code || config.base.license === base.getValue("setting_init").license) {
this.addButton();
} else {
this.addInitButton();
}
this.addPageListener();
},
};
/**
* 中国移动云盘 / 和彩云
* @author 油小猴
* @author hmjz100
*/
let $mcloud = {
addPageListener() {
$doc.on("click", ".pl-button-mode", async function (e) {
temp.mode = e.currentTarget.dataset.mode;
if (!temp.mode) return;
temp.main.getLink();
});
$doc.on("click", ".pl-button-save", async function (e) {
e.preventDefault();
let selectList = temp.main.getSelectedList();
if (selectList.length === 0) return message.error("提示: 请勾选要下载的文件哦~");
if (selectList.every(item => !item.contentID && !item.contentName)) return message.error("提示: 请打开文件夹后再勾选文件~");
message.info("提示: 因网盘限制,只能够通过页面直接下载哦~");
await base.sleep(500);
document.querySelector(".btn-top.btn-top_dl").click();
});
$doc.on("click", ".listener-api-download.enhance", async function (e) {
e.preventDefault();
var status = base._EventFactory(e);
var file = {
index: status.item.data("index"),
link: status.item.data("link"),
name: status.item.data("name"),
size: status.item.data("size") || 0,
}
base._resetData(file.index);
// UI 初始化
status.down_normal.hide();
status.down_enhance.hide();
status.down_idm.hide();
status.link_message.hide();
status.link_copy.hide();
status.down_enhance_downing.find(".stop").show();
status.down_enhance_downing.show();
let startTime = Date.now();
let lastTime = startTime;
let lastLoaded = 0;
let emaSpeed = 0;
var tau = 2; // 时间常数(秒),数值越大速度显示越平稳,越小越灵敏。建议 1.5 - 3 之间。
base.download(file.link, undefined, {
...file,
onProgress: (prog, loaded, total) => {
var time = Date.now();
var insDiff = (time - lastTime) / 1000 || 0.001; // 瞬时耗时(秒)
var insSpeed = (loaded - lastLoaded) / insDiff; // 瞬时速度(B/s)
var avgDiff = (time - startTime) / 1000 || 0.1; // 总耗时(秒)
var avgSpeed = loaded / avgDiff; // 全局平均速度(B/s)
var alpha = 1 - Math.exp(-insDiff / tau);
if (emaSpeed === 0) {
emaSpeed = insSpeed; // 第一次采样,直接赋值
} else {
// EMA 公式:当前平滑值 = (1 - alpha) * 旧值 + alpha * 当前瞬时值
emaSpeed = (1 - alpha) * emaSpeed + alpha * insSpeed;
}
var rSize = total - loaded;
var predictionSpeed = (emaSpeed > 1024) ? emaSpeed : avgSpeed; // 兜底 - 如果 EMA 速度异常,则参考全局平均速度
var rTime = predictionSpeed > 0 ? rSize / predictionSpeed : 0;
lastLoaded = loaded;
lastTime = time;
var dprog = Math.min(prog, 100);
status.down_enhance_downing.find(".pl-progress").css("--width", `${dprog}%`);
status.down_enhance_downing.find(".pl-progress .text").text(`${dprog.toFixed(2)}% - ${base.sizeFormat(loaded)} | ${base.sizeFormat(emaSpeed)}/块 | ${base.rtimeFormat(rTime)}`);
}
})
.then(async (res) => {
status.down_enhance_downing.find(".pl-progress .header").css("background", "#55af28");
base.blobDownload(res.response, file.name);
await base.sleep(1000);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress .text").html(`下载完成~ 浏览器下载框应该弹出来了哦~`);
})
.catch(async (error) => {
base.console.error("【LinkSwift】Download(load)", error);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress").css("--width", "100%");
status.down_enhance_downing.find(".pl-progress .header").css("background", "#cc3235");
let estatus = `QAQ 下载出错~`;
if (!error?.status) estatus += ` 服务器未返回状态,若是下载一段时间后中断,可能是服务器返回文件长度不匹配,请重试;若是直接中断,请检查您的网络、脚本管理器扩展或浏览器~`;
if (error?.status == 403) estatus += ` 服务器说:链接已过期,关闭窗口重新获取试试吧~`;
if (error?.status == 204 || error?.statusText === "IDM") estatus += ` 服务说:链接已被 IDM 捕获~`;
status.down_enhance_downing.find(".pl-progress .text").html(estatus);
status.down_enhance_downing.find(".pl-progress .text").css("white-space", "break-spaces");
})
});
$doc.on("click", ".listener-idm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToIDM(target.data("link"), target.data("filename"), target.data("filesize"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-aria2-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToAria2(target.data("link"), target.data("filename"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-bitcomet-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToBitcomet(target.data("link"), target.data("filename"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-abdm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToABDM(target.data("link"), target.data("filename"), undefined);
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
},
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({
...temp.swalDefault,
html: ``,
allowOutsideClick: false,
showCloseButton: true,
showConfirmButton: false,
});
});
}, true);
},
beautifyPage() {
if (base.getValue("setting_ui_theme").custom.$mcloud !== true) return;
base.adaptiveThemeOverride([
["#3181f9", temp.color],
["#5a9afa", temp.color],
["#98c0fc", `${temp.color}D0`],
["#2d76e5", `${temp.color}D0`],
["49,129,249,.08", base.hexToRgba(`${temp.color}20`)],
]);
},
addButton() {
base.waitForKeyElements(config.$mcloud.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "home") return;
let $button = $(`
下载助手
`);
element.prepend($button);
})
base.waitForKeyElements(config.$mcloud.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(`
下载助手
`);
element.prepend($button);
})
},
addInitButton() {
let $button = $(`点我点亮
`);
$button.click(base.showInitDialog);
base.waitForKeyElements(config.$mcloud.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "home") return;
$button.addClass("mcloud-button");
element.prepend($button);
})
base.waitForKeyElements(config.$mcloud.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.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) {
let 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 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 "";
}
let res = await base.post(config.$mcloud.api.getLink, body, {
"Authorization": getCookie("authorization"),
"Caller": "web",
"Content-Type": "application/json;charset=UTF-8",
"CMS-DEVICE": "default",
"Mcloud-Channel": "1000101",
"Mcloud-Client": "10701",
"Mcloud-Sign": time + "," + key + "," + sign,
"Mcloud-Version": "7.14.2",
"X-DeviceInfo": "||9|7.17.0|edge||||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.17.0|edge||||windows 10||zh-CN|||||",
"X-Yun-Module-Type": "100",
"X-Yun-Svc-Type": "1",
"X-Yun-Url-Type": "3"
});
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({
...temp.swalDefault,
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();
},
});
let selectList = this.getSelectedList();
if (selectList.length === 0) return message.error("提示: 请勾选要下载的文件哦~");
if (selectList.every(item => !item.contentID && !item.contentName)) return message.error("提示: 请打开文件夹后再勾选文件~");
if (temp.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("提示: 页面错误~");
}
temp.links = [selectList, {
isFolder: v => (v.dirEtag || v.caName),
getFileName: v => (v.contentName || v.coName),
getFileSize: v => (v.contentSize || v.coSize),
getFileLink: v => v.downloadUrl,
tooltip: config.$mcloud.dom
}];
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
},
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 "";
},
async initPanLinker() {
base.registerMenuCommand();
if (config.base.num === base.getValue("setting_init").code || config.base.license === base.getValue("setting_init").license) {
this.addButton();
} else {
this.addInitButton();
}
this.addPageListener();
},
};
/**
* 天翼云盘
* @author 油小猴
* @author hmjz100
*/
let $tcloud = {
addPageListener() {
$doc.on("click", ".pl-button-mode", async function (e) {
temp.mode = e.currentTarget.dataset.mode;
if (!temp.mode) return;
temp.main.getLink();
});
$doc.on("click", ".listener-api-download.enhance", async function (e) {
e.preventDefault();
var status = base._EventFactory(e);
var file = {
index: status.item.data("index"),
link: status.item.data("link"),
name: status.item.data("name"),
size: status.item.data("size") || 0,
}
base._resetData(file.index);
// UI 初始化
status.down_normal.hide();
status.down_enhance.hide();
status.down_idm.hide();
status.link_message.hide();
status.link_copy.hide();
status.down_enhance_downing.find(".stop").show();
status.down_enhance_downing.show();
let startTime = Date.now();
let lastTime = startTime;
let lastLoaded = 0;
let emaSpeed = 0;
var tau = 2; // 时间常数(秒),数值越大速度显示越平稳,越小越灵敏。建议 1.5 - 3 之间。
base.download(file.link, undefined, {
...file,
onProgress: (prog, loaded, total) => {
var time = Date.now();
var insDiff = (time - lastTime) / 1000 || 0.001; // 瞬时耗时(秒)
var insSpeed = (loaded - lastLoaded) / insDiff; // 瞬时速度(B/s)
var avgDiff = (time - startTime) / 1000 || 0.1; // 总耗时(秒)
var avgSpeed = loaded / avgDiff; // 全局平均速度(B/s)
var alpha = 1 - Math.exp(-insDiff / tau);
if (emaSpeed === 0) {
emaSpeed = insSpeed; // 第一次采样,直接赋值
} else {
// EMA 公式:当前平滑值 = (1 - alpha) * 旧值 + alpha * 当前瞬时值
emaSpeed = (1 - alpha) * emaSpeed + alpha * insSpeed;
}
var rSize = total - loaded;
var predictionSpeed = (emaSpeed > 1024) ? emaSpeed : avgSpeed; // 兜底 - 如果 EMA 速度异常,则参考全局平均速度
var rTime = predictionSpeed > 0 ? rSize / predictionSpeed : 0;
lastLoaded = loaded;
lastTime = time;
var dprog = Math.min(prog, 100);
status.down_enhance_downing.find(".pl-progress").css("--width", `${dprog}%`);
status.down_enhance_downing.find(".pl-progress .text").text(`${dprog.toFixed(2)}% - ${base.sizeFormat(loaded)} | ${base.sizeFormat(emaSpeed)}/块 | ${base.rtimeFormat(rTime)}`);
}
})
.then(async (res) => {
status.down_enhance_downing.find(".pl-progress .header").css("background", "#55af28");
base.blobDownload(res.response, file.name);
await base.sleep(1000);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress .text").html(`下载完成~ 浏览器下载框应该弹出来了哦~`);
})
.catch(async (error) => {
base.console.error("【LinkSwift】Download(load)", error);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress").css("--width", "100%");
status.down_enhance_downing.find(".pl-progress .header").css("background", "#cc3235");
let estatus = `QAQ 下载出错~`;
if (!error?.status) estatus += ` 服务器未返回状态,若是下载一段时间后中断,可能是服务器返回文件长度不匹配,请重试;若是直接中断,请检查您的网络、脚本管理器扩展或浏览器~`;
if (error?.status == 403) estatus += ` 服务器说:链接已过期,关闭窗口重新获取试试吧~`;
if (error?.status == 204 || error?.statusText === "IDM") estatus += ` 服务说:链接已被 IDM 捕获~`;
status.down_enhance_downing.find(".pl-progress .text").html(estatus);
status.down_enhance_downing.find(".pl-progress .text").css("white-space", "break-spaces");
})
});
$doc.on("click", ".listener-idm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToIDM(target.data("link"), target.data("filename"), target.data("filesize"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-aria2-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToAria2(target.data("link"), target.data("filename"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-bitcomet-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToBitcomet(target.data("link"), target.data("filename"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-abdm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToABDM(target.data("link"), target.data("filename"), undefined);
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
},
greenerPage() {
base.waitForKeyElements(".advertising-mask", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements("a.client-download.nav-block", function (tag) {
tag.fadeOut();
}, true);
},
beautifyPage() {
if (base.getValue("setting_ui_theme").custom.$tcloud !== true) return;
base.adaptiveThemeOverride([
["#2b89ea", temp.color],
["#1874d3", `${temp.color}F0`],
["#1890ff", temp.color],
["#388fc9", temp.color],
["#0087ff", temp.color],
["#255697", temp.color],
["#3ea6ff", `${temp.color}80`],
["#1d52f2", temp.color],
["#3699ff", `${temp.color}D0`],
["#f4f9fe", `${temp.color}10`],
["#eaf5ff", `${temp.color}20`],
], "other");
},
addButton() {
let $button = $(``);
$button.find(".pl-dropdown-menu").css({ "position": "absolute", "left": "-1px" })
base.waitForKeyElements(config.$tcloud.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "home") return;
$button.find(".pl-dropdown-menu").css({ "top": "28px" })
element.prepend($button);
})
base.waitForKeyElements(config.$tcloud.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.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(base.showInitDialog);
base.waitForKeyElements(config.$tcloud.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "home") return;
element.prepend($button);
})
base.waitForKeyElements(config.$tcloud.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.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.getFinal(config.$tcloud.api.getAccessToken, undefined, true);
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();
let url = `${config.$tcloud.api.getLink}?fileId=${item.fileId}`;
let _sign = `AccessToken=${token}&Timestamp=${time}&fileId=${item.fileId}`;
if (item.shareId) {
url += `&dt=1&shareId=${item.shareId}`;
_sign += `&dt=1&shareId=${item.shareId}`;
}
let res = await base.get(url, { "Accept": "application/json;charset=UTF-8", "Sign-Type": 1, "Accesstoken": token, "Timestamp": time, "Signature": md5(_sign).toString() });
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({
...temp.swalDefault,
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();
},
});
let selectList = this.getSelectedList();
if (selectList.length === 0) return message.error("提示: 请勾选要下载的文件哦~");
if (selectList.every(item => item.isFolder)) 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);
}
temp.links = [selectList, {
isFolder: v => v.isFolder,
getFileName: v => v.fileName,
getFileSize: v => v.size,
getFileLink: v => v.downloadUrl,
tooltip: config.$mcloud.dom
}];
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
},
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 "";
},
async initPanLinker() {
base.registerMenuCommand();
if (config.base.num === base.getValue("setting_init").code || config.base.license === base.getValue("setting_init").license) {
this.addButton();
} else {
this.addInitButton();
}
this.addPageListener();
this.getToken();
},
};
/**
* 迅雷云盘
* @author 油小猴
* @author hmjz100
*/
let $xunlei = {
addPageListener() {
$doc.on("click", ".pl-button-mode", async function (e) {
temp.mode = e.currentTarget.dataset.mode;
if (!temp.mode) return;
temp.main.getLink();
});
$doc.on("click", ".pl-button-save", async function (e) {
e.preventDefault();
let selectList = temp.main.getSelectedList();
if (selectList.length === 0) {
return message.error("提示: 请勾选要保存到网盘的文件哦~");
}
message.info("提示: 因网盘限制,请保存到自己网盘后再去下载哦~");
await base.sleep(500);
document.querySelector(".saveToCloud").click();
});
$doc.on("click", ".listener-api-download.enhance", async function (e) {
e.preventDefault();
var status = base._EventFactory(e);
var file = {
index: status.item.data("index"),
link: status.item.data("link"),
name: status.item.data("name"),
size: status.item.data("size") || 0,
}
base._resetData(file.index);
// UI 初始化
status.down_normal.hide();
status.down_enhance.hide();
status.down_idm.hide();
status.link_message.hide();
status.link_copy.hide();
status.down_enhance_downing.find(".stop").show();
status.down_enhance_downing.show();
let startTime = Date.now();
let lastTime = startTime;
let lastLoaded = 0;
let emaSpeed = 0;
var tau = 2; // 时间常数(秒),数值越大速度显示越平稳,越小越灵敏。建议 1.5 - 3 之间。
base.download(file.link, undefined, {
...file,
onProgress: (prog, loaded, total) => {
var time = Date.now();
var insDiff = (time - lastTime) / 1000 || 0.001; // 瞬时耗时(秒)
var insSpeed = (loaded - lastLoaded) / insDiff; // 瞬时速度(B/s)
var avgDiff = (time - startTime) / 1000 || 0.1; // 总耗时(秒)
var avgSpeed = loaded / avgDiff; // 全局平均速度(B/s)
var alpha = 1 - Math.exp(-insDiff / tau);
if (emaSpeed === 0) {
emaSpeed = insSpeed; // 第一次采样,直接赋值
} else {
// EMA 公式:当前平滑值 = (1 - alpha) * 旧值 + alpha * 当前瞬时值
emaSpeed = (1 - alpha) * emaSpeed + alpha * insSpeed;
}
var rSize = total - loaded;
var predictionSpeed = (emaSpeed > 1024) ? emaSpeed : avgSpeed; // 兜底 - 如果 EMA 速度异常,则参考全局平均速度
var rTime = predictionSpeed > 0 ? rSize / predictionSpeed : 0;
lastLoaded = loaded;
lastTime = time;
var dprog = Math.min(prog, 100);
status.down_enhance_downing.find(".pl-progress").css("--width", `${dprog}%`);
status.down_enhance_downing.find(".pl-progress .text").text(`${dprog.toFixed(2)}% - ${base.sizeFormat(loaded)} | ${base.sizeFormat(emaSpeed)}/块 | ${base.rtimeFormat(rTime)}`);
}
})
.then(async (res) => {
status.down_enhance_downing.find(".pl-progress .header").css("background", "#55af28");
base.blobDownload(res.response, file.name);
await base.sleep(1000);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress .text").html(`下载完成~ 浏览器下载框应该弹出来了哦~`);
})
.catch(async (error) => {
base.console.error("【LinkSwift】Download(load)", error);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress").css("--width", "100%");
status.down_enhance_downing.find(".pl-progress .header").css("background", "#cc3235");
let estatus = `QAQ 下载出错~`;
if (!error?.status) estatus += ` 服务器未返回状态,若是下载一段时间后中断,可能是服务器返回文件长度不匹配,请重试;若是直接中断,请检查您的网络、脚本管理器扩展或浏览器~`;
if (error?.status == 403) estatus += ` 服务器说:链接已过期,关闭窗口重新获取试试吧~`;
if (error?.status == 204 || error?.statusText === "IDM") estatus += ` 服务说:链接已被 IDM 捕获~`;
status.down_enhance_downing.find(".pl-progress .text").html(estatus);
status.down_enhance_downing.find(".pl-progress .text").css("white-space", "break-spaces");
})
});
$doc.on("click", ".listener-idm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToIDM(target.data("link"), target.data("filename"), target.data("filesize"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-aria2-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToAria2(target.data("link"), target.data("filename"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-bitcomet-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToBitcomet(target.data("link"), target.data("filename"), { "mirror_url_list": base.getMirrorList(target.data("link"), config.$xunlei.api.mirror), "checkboxCustomHeadersForMirrors": "on" });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-abdm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToABDM(target.data("link"), target.data("filename"), undefined);
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
},
beautifyPage() {
if (base.getValue("setting_ui_theme").custom.$xunlei !== true) return;
base.adaptiveThemeOverride([
["#3f85ff", temp.color],
["63,133,255,.1", base.hexToRgba(`${temp.color}20`)],
["#2670ea", `${temp.color}D0`],
["#619bff", `${temp.color}D0`],
["#ecf3ff", `${temp.color}10`],
["#f6faff", `${temp.color}10`],
["#1a2845", `${temp.color}20`],
["#0f2035", `${temp.color}20`],
["#308bfd", `${temp.color}20`],
["#eee", `${temp.color}20`],
], "other");
base.addStyle(`${mount}-xunlei`, "style", `.web-header{background:linear-gradient(0deg,${temp.color}D0,${temp.color})}`);
},
addButton() {
base.waitForKeyElements(config.$xunlei.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "home") return;
let $button = $(`下载助手
`);
element.prepend($button);
})
base.waitForKeyElements(config.$xunlei.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(`
下载助手
`);
$button.css({ "margin-right": "10px" });
element.prepend($button);
})
},
addInitButton() {
let $button = $(`点我点亮
`);
$button.click(base.showInitDialog);
base.waitForKeyElements(config.$xunlei.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "home") return;
element.prepend($button);
})
base.waitForKeyElements(config.$xunlei.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.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 if (res?.error_code == 9) {
return {
index,
downloadUrl: "获取下载地址失败,服务器说:页面验证过期了,刷新后再获取吧~"
};
} else {
return {
index,
downloadUrl: `获取下载地址失败,${res?.error_description ? "服务器说:" + res.error_description + "。" : "刷新后再试试吧~"}`
};
}
} catch (e) {
return message.error("提示: 请先登录网盘后再刷新页面呢~");
}
},
async getLink() {
Swal.fire({
...temp.swalDefault,
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();
},
});
let selectList = this.getSelectedList();
if (selectList.length === 0) return message.error("提示: 请勾选要下载的文件哦~");
if (selectList.every(item => item.kind !== "drive#file")) return message.error("提示: 请打开文件夹后再勾选文件~");
if (temp.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("提示: 页面错误~");
}
temp.links = [selectList, {
isFolder: v => v.kind === "drive#folder",
getFileName: v => v.name,
getFileSize: v => v.size,
getFileLink: v => v.downloadUrl,
getFileMirror: v => base.getMirrorList(v, config.$xunlei.api.mirror),
tooltip: config.$xunlei.dom
}];
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
},
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 "";
},
async initPanLinker() {
base.registerMenuCommand();
if (config.base.num === base.getValue("setting_init").code || config.base.license === base.getValue("setting_init").license) {
this.addButton();
} else {
this.addInitButton();
}
this.addPageListener();
},
};
/**
* 夸克网盘
* @author 油小猴
* @author hmjz100
*/
let $quark = {
addPageListener() {
$doc.on("click", ".pl-button-mode", async function (e) {
temp.mode = e.currentTarget.dataset.mode;
if (!temp.mode) return;
temp.main.getLink();
});
$doc.on("click", ".pl-button-save", async function (e) {
e.preventDefault();
let selectList = temp.main.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-api-download.enhance", async function (e) {
e.preventDefault();
var status = base._EventFactory(e);
var file = {
index: status.item.data("index"),
link: status.item.data("link"),
name: status.item.data("name"),
size: status.item.data("size") || 0,
}
base._resetData(file.index);
// UI 初始化
status.down_normal.hide();
status.down_enhance.hide();
status.down_idm.hide();
status.link_message.hide();
status.link_copy.hide();
status.down_enhance_downing.find(".stop").show();
status.down_enhance_downing.show();
let startTime = Date.now();
let lastTime = startTime;
let lastLoaded = 0;
let emaSpeed = 0;
var tau = 2; // 时间常数(秒),数值越大速度显示越平稳,越小越灵敏。建议 1.5 - 3 之间。
base.download(file.link, { "User-Agent": config.$quark.api.ua.downloadLink }, {
...file,
onProgress: (prog, loaded, total) => {
var time = Date.now();
var insDiff = (time - lastTime) / 1000 || 0.001; // 瞬时耗时(秒)
var insSpeed = (loaded - lastLoaded) / insDiff; // 瞬时速度(B/s)
var avgDiff = (time - startTime) / 1000 || 0.1; // 总耗时(秒)
var avgSpeed = loaded / avgDiff; // 全局平均速度(B/s)
var alpha = 1 - Math.exp(-insDiff / tau);
if (emaSpeed === 0) {
emaSpeed = insSpeed; // 第一次采样,直接赋值
} else {
// EMA 公式:当前平滑值 = (1 - alpha) * 旧值 + alpha * 当前瞬时值
emaSpeed = (1 - alpha) * emaSpeed + alpha * insSpeed;
}
var rSize = total - loaded;
var predictionSpeed = (emaSpeed > 1024) ? emaSpeed : avgSpeed; // 兜底 - 如果 EMA 速度异常,则参考全局平均速度
var rTime = predictionSpeed > 0 ? rSize / predictionSpeed : 0;
lastLoaded = loaded;
lastTime = time;
var dprog = Math.min(prog, 100);
status.down_enhance_downing.find(".pl-progress").css("--width", `${dprog}%`);
status.down_enhance_downing.find(".pl-progress .text").text(`${dprog.toFixed(2)}% - ${base.sizeFormat(loaded)} | ${base.sizeFormat(emaSpeed)}/块 | ${base.rtimeFormat(rTime)}`);
}
})
.then(async (res) => {
status.down_enhance_downing.find(".pl-progress .header").css("background", "#55af28");
base.blobDownload(res.response, file.name);
await base.sleep(1000);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress .text").html(`下载完成~ 浏览器下载框应该弹出来了哦~`);
})
.catch(async (error) => {
base.console.error("【LinkSwift】Download(load)", error);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress").css("--width", "100%");
status.down_enhance_downing.find(".pl-progress .header").css("background", "#cc3235");
let estatus = `QAQ 下载出错~`;
if (!error?.status) estatus += ` 服务器未返回状态,若是下载一段时间后中断,可能是服务器返回文件长度不匹配,请重试;若是直接中断,请检查您的网络、脚本管理器扩展或浏览器~`;
if (error?.status == 403) estatus += ` 服务器说:链接已过期,关闭窗口重新获取试试吧~`;
if (error?.status == 204 || error?.statusText === "IDM") estatus += ` 服务说:链接已被 IDM 捕获~`;
if (error?.status == 412) estatus += ` 服务器说:需要登录才能下载~`;
status.down_enhance_downing.find(".pl-progress .text").html(estatus);
status.down_enhance_downing.find(".pl-progress .text").css("white-space", "break-spaces");
})
});
$doc.on("click", ".listener-idm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToIDM(target.data("link"), target.data("filename"), target.data("filesize"), { "User-Agent": config.$quark.api.ua.downloadLink, "Referer": `https://${location.host}/`, "Cookie": document.cookie });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-aria2-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToAria2(target.data("link"), target.data("filename"), [`User-Agent:${config.$quark.api.ua.downloadLink}`, `Referer:https://${location.host}/`, `Cookie:${document.cookie}`]);
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-bitcomet-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToBitcomet(target.data("link"), target.data("filename"), { "user_agent": config.$quark.api.ua.downloadLink, "referrer": `https://${location.host}/`, "cookie": document.cookie });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-abdm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToABDM(target.data("link"), target.data("filename"), { "User-Agent": config.$quark.api.ua.downloadLink, "Cookie": document.cookie });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
},
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);
},
beautifyPage() {
if (base.getValue("setting_ui_theme").custom.$quark !== true) return;
base.adaptiveThemeOverride([
["#0d53ff", temp.color],
["#e6f1ff", `${temp.color}20`],
["#f0faff", `${temp.color}20`],
["#7da3ff", `${temp.color}D0`],
["#ddd", `${temp.color}D0`],
["17,17,17,.9", base.hexToRgba(`${temp.color}D0`)],
["40,40,255,.04", base.hexToRgba(`${temp.color}20`)],
["#f7f7ff", "transparent"],
["238,247,255,0", base.hexToRgba(`${temp.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:${temp.color}!important}`);
},
svg: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbC1ydWxlPSJub256ZXJvIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSI+PHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNiA5bDIgMiAyLTJ6Ii8+PHBhdGggZD0iTTExIDVoMS41NTNjLjg1IDAgMS4xNi4wOTMgMS40Ny4yNjcuMzExLjE3NC41NTYuNDMuNzIyLjc1Ni4xNjYuMzI2LjI1NS42NS4yNTUgMS41NHY0Ljg3M2MwIC44OTItLjA4OSAxLjIxNS0uMjU1IDEuNTQtLjE2Ni4zMjctLjQxLjU4My0uNzIyLjc1Ny0uMzEuMTc0LS42Mi4yNjctMS40Ny4yNjdIMy40NDdjLS44NSAwLTEuMTYtLjA5My0xLjQ3LS4yNjdhMS43NzggMS43NzggMCAwMS0uNzIyLS43NTZjLS4xNjYtLjMyNi0uMjU1LS42NS0uMjU1LTEuNTRWNy41NjNjMC0uODkyLjA4OS0xLjIxNS4yNTUtMS41NC4xNjYtLjMyNy40MS0uNTgzLjcyMi0uNzU3LjMxLS4xNzQuNjItLjI2NyAxLjQ3LS4yNjdIOCIvPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTggMXY5Ii8+PC9nPjwvc3ZnPg==",
addButton() {
base.waitForKeyElements(config.$quark.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "home") return;
let $button = $(``);
$button.css({ "margin-right": "16px" });
element.prepend($button);
})
base.waitForKeyElements(config.$quark.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.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) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "home") return;
let $button = $(`点我点亮 `);
$button.css({ "margin-right": "16px", "display": "inline-block" });
$button.click(base.showInitDialog);
element.prepend($button);
})
base.waitForKeyElements(config.$quark.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(`点我点亮 `);
$button.css({ "height": "36px", "margin-left": "16px", "border-radius": "6px", "display": "inline-block" });
$button.click(base.showInitDialog);
element.append($button);
})
},
async getLink() {
Swal.fire({
...temp.swalDefault,
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();
},
});
let selectList = this.getSelectedList();
if (selectList.length === 0) return message.error("提示: 请勾选要下载的文件哦~");
if (selectList.every(item => !item.file)) return message.error("提示: 请打开文件夹后再勾选文件~");
if (temp.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);
let fids = batch.map(item => item.fid);
// 发起请求获取链接
let res = await base.post(config.$quark.api.getLink, { "fids": fids }, { "User-Agent": config.$quark.api.ua.downloadLink });
if (res?.code == 31001) {
return message.error("提示: 请先登录网盘~ 代码:" + res.code);
} else if (res?.code == 23018) {
let fid = res?.message?.match(/\[([a-f0-9]{32})\]/)?.[1];
let item = batch.find(item => item.fid === fid);
return message.error(`提示: 超出可获取大小限制~${item?.file_name ? ` 文件:${item.file_name}` : ""}`);
}
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);
}
temp.links = [data, {
isFolder: v => v.file === false,
getFileName: v => v.file_name,
getFileSize: v => v.size,
getFileLink: v => v.download_url,
convert: {
aria2: `--header "User-Agent:${config.$quark.api.ua.downloadLink}" --header "Referer:https://${location.host}/" --header "Cookie:${document.cookie}"`,
curl: `-A "${config.$quark.api.ua.downloadLink}" -e "https://${location.host}/" -b "${document.cookie}"`,
bitcomet: `user_agent=${encodeURIComponent(config.$quark.api.ua.downloadLink)}&refer=${encodeURIComponent(`https://${location.host}/`)}&cookie=${encodeURIComponent(document.cookie)}`
},
tooltip: config.$quark.dom
}];
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
} else if (temp.page === "share") {
let pwd_id = unsafeWindow.factStat?.ut?.baseParams?.pwd_id || // fast
unsafeWindow.factStat?.wa?.customStatParams?.pwd_id || // drive
location.pathname.match(/^\/(?:s|share)\/([a-zA-Z0-9]+)/)?.[1]; // 兜底
if (!pwd_id) return message.error("错误: 无法提取分享 ID~");
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);
let fids = batch.map(item => item.fid);
let fids_token = batch.map(item => item.share_fid_token);
// 发起请求获取链接
let res = await base.post(config.$quark.api.getLink, { "fids": fids, "fids_token": fids_token, pwd_id, "stoken": batch[0].stoken }, { "User-Agent": config.$quark.api.ua.downloadLink });
if (res?.code == 31001) {
return message.error("提示: 请先登录网盘~ 代码:" + res.code);
} else if (res?.code == 23018) {
let fid = res?.message?.match(/\[([a-f0-9]{32})\]/)?.[1];
let item = batch.find(item => item.fid === fid);
return message.error(`提示: 超出可获取大小限制~${item?.file_name ? ` 文件:${item.file_name}` : ""}`);
}
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);
}
temp.links = [data, {
isFolder: v => v.file === false,
getFileName: v => v.file_name,
getFileSize: v => v.size,
getFileLink: v => v.download_url,
convert: {
aria2: `--header "User-Agent:${config.$quark.api.ua.downloadLink}" --header "Referer:https://${location.host}/" --header "Cookie:${document.cookie}"`,
curl: `-A "${config.$quark.api.ua.downloadLink}" -e "https://${location.host}/" -b "${document.cookie}"`,
bitcomet: `user_agent=${encodeURIComponent(config.$quark.api.ua.downloadLink)}&refer=${encodeURIComponent(`https://${location.host}/`)}&cookie=${encodeURIComponent(document.cookie)}`
},
tooltip: config.$quark.dom
}];
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
} else {
return message.error("提示: 页面错误~");
}
},
getSelectedList() {
try {
let selectedList = [];
let reactDom = document.getElementsByClassName("file-list")[0];
let reactObj = base.findReact(reactDom);
let props = reactObj.props;
if (props) {
let stoken = props.stoken || "";
let fileList = props.list || [];
let selectedKeys = props.selectedRowKeys || [];
fileList.forEach(function (val) {
if (selectedKeys.includes(val.fid)) {
selectedList.push({ ...val, stoken });
}
});
}
return selectedList;
} catch (e) {
return [];
}
},
detectPage() {
let path = location.pathname;
if (/^\/(list)/.test(path)) return "home";
if (/^\/(s|share)\//.test(path)) return "share";
return "";
},
async initPanLinker() {
base.registerMenuCommand();
if (config.base.num === base.getValue("setting_init").code || config.base.license === base.getValue("setting_init").license) {
this.addButton();
} else {
this.addInitButton();
}
this.addPageListener();
},
};
/**
* UC网盘
* @author 油小猴
* @author hmjz100
*/
let $uc = {
addPageListener() {
$doc.on("click", ".pl-button-mode", async function (e) {
temp.mode = e.currentTarget.dataset.mode;
if (!temp.mode) return;
temp.main.getLink();
});
$doc.on("click", ".pl-button-save", async function (e) {
e.preventDefault();
let selectList = temp.main.getSelectedList();
if (selectList.length === 0) {
return message.error("提示: 请勾选要保存到网盘的文件哦~");
}
message.info("提示: 因网盘限制,请保存到自己网盘后再去下载哦~");
await base.sleep(500);
document.querySelector(".file-info_r").click();
});
$doc.on("click", ".listener-api-download.enhance", async function (e) {
e.preventDefault();
var status = base._EventFactory(e);
var file = {
index: status.item.data("index"),
link: status.item.data("link"),
name: status.item.data("name"),
size: status.item.data("size") || 0,
}
base._resetData(file.index);
// UI 初始化
status.down_normal.hide();
status.down_enhance.hide();
status.down_idm.hide();
status.link_message.hide();
status.link_copy.hide();
status.down_enhance_downing.find(".stop").show();
status.down_enhance_downing.show();
let startTime = Date.now();
let lastTime = startTime;
let lastLoaded = 0;
let emaSpeed = 0;
var tau = 2; // 时间常数(秒),数值越大速度显示越平稳,越小越灵敏。建议 1.5 - 3 之间。
base.download(file.link, { "User-Agent": config.$uc.api.ua.downloadLink }, {
...file,
onProgress: (prog, loaded, total) => {
var time = Date.now();
var insDiff = (time - lastTime) / 1000 || 0.001; // 瞬时耗时(秒)
var insSpeed = (loaded - lastLoaded) / insDiff; // 瞬时速度(B/s)
var avgDiff = (time - startTime) / 1000 || 0.1; // 总耗时(秒)
var avgSpeed = loaded / avgDiff; // 全局平均速度(B/s)
var alpha = 1 - Math.exp(-insDiff / tau);
if (emaSpeed === 0) {
emaSpeed = insSpeed; // 第一次采样,直接赋值
} else {
// EMA 公式:当前平滑值 = (1 - alpha) * 旧值 + alpha * 当前瞬时值
emaSpeed = (1 - alpha) * emaSpeed + alpha * insSpeed;
}
var rSize = total - loaded;
var predictionSpeed = (emaSpeed > 1024) ? emaSpeed : avgSpeed; // 兜底 - 如果 EMA 速度异常,则参考全局平均速度
var rTime = predictionSpeed > 0 ? rSize / predictionSpeed : 0;
lastLoaded = loaded;
lastTime = time;
var dprog = Math.min(prog, 100);
status.down_enhance_downing.find(".pl-progress").css("--width", `${dprog}%`);
status.down_enhance_downing.find(".pl-progress .text").text(`${dprog.toFixed(2)}% - ${base.sizeFormat(loaded)} | ${base.sizeFormat(emaSpeed)}/块 | ${base.rtimeFormat(rTime)}`);
}
})
.then(async (res) => {
status.down_enhance_downing.find(".pl-progress .header").css("background", "#55af28");
base.blobDownload(res.response, file.name);
await base.sleep(1000);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress .text").html(`下载完成~ 浏览器下载框应该弹出来了哦~`);
})
.catch(async (error) => {
base.console.error("【LinkSwift】Download(load)", error);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress").css("--width", "100%");
status.down_enhance_downing.find(".pl-progress .header").css("background", "#cc3235");
let estatus = `QAQ 下载出错~`;
if (!error?.status) estatus += ` 服务器未返回状态,若是下载一段时间后中断,可能是服务器返回文件长度不匹配,请重试;若是直接中断,请检查您的网络、脚本管理器扩展或浏览器~`;
if (error?.status == 403) estatus += ` 服务器说:链接已过期,关闭窗口重新获取试试吧~`;
if (error?.status == 204 || error?.statusText === "IDM") estatus += ` 服务说:链接已被 IDM 捕获~`;
if (error?.responseText?.includes?.("require login")) estatus += ` 服务器说:需要登录才能下载~`;
status.down_enhance_downing.find(".pl-progress .text").html(estatus);
status.down_enhance_downing.find(".pl-progress .text").css("white-space", "break-spaces");
})
});
$doc.on("click", ".listener-idm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToIDM(target.data("link"), target.data("filename"), target.data("filesize"), { "User-Agent": config.$uc.api.ua.downloadLink, "Referer": `https://${location.host}/`, "Cookie": document.cookie });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-aria2-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToAria2(target.data("link"), target.data("filename"), [`User-Agent:${config.$uc.api.ua.downloadLink}`, `Referer:https://${location.host}/`, `Cookie:${document.cookie}`]);
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-bitcomet-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToBitcomet(target.data("link"), target.data("filename"), { "user_agent": config.$uc.api.ua.downloadLink, "referrer": `https://${location.host}/`, "cookie": document.cookie });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-abdm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToABDM(target.data("link"), target.data("filename"), { "User-Agent": config.$uc.api.ua.downloadLink, "Cookie": document.cookie });
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
},
greenerPage() {
base.waitForKeyElements(`[class*="VideoDetail--content-footer"]`, function (tag) {
tag.children().each(function () {
let $child = $(this);
if ($child.text().includes("手机客户端")) {
$child.hide();
}
});
}, true);
base.waitForKeyElements(`[class*="PCLandingBanner--ad-block"]`, function (tag) {
tag.hide();
}, true);
},
beautifyPage() {
if (base.getValue("setting_ui_theme").custom.$uc !== true) return;
base.adaptiveThemeOverride([
["#12161a", temp.color],
["#e6f1ff", `${temp.color}20`],
["#f0faff", `${temp.color}20`],
["#7da3ff", `${temp.color}D0`],
["#ddd", `${temp.color}D0`],
["17,17,17,.9", base.hexToRgba(`${temp.color}D0`)],
["40,40,255,.04", base.hexToRgba(`${temp.color}20`)],
["#f7f7ff", "transparent"],
["238,247,255,0", base.hexToRgba(`${temp.color}00`)],
]);
base.addStyle(`${mount}-uc`, "style", `.file-list .hover-oper .hover-transparent-bg{background:transparent!important}`);
},
svg: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiI+PHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNOSAxMmwyIDIgMi0yeiIvPjxwYXRoIGQ9Ik0xNCA4aDEuNTUzYy44NSAwIDEuMTYuMDkzIDEuNDcuMjY3LjMxMS4xNzQuNTU2LjQzLjcyMi43NTYuMTY2LjMyNi4yNTUuNjUuMjU1IDEuNTR2NC44NzNjMCAuODkyLS4wODkgMS4yMTUtLjI1NSAxLjU0LS4xNjYuMzI3LS40MS41ODMtLjcyMi43NTctLjMxLjE3NC0uNjIuMjY3LTEuNDcuMjY3SDYuNDQ3Yy0uODUgMC0xLjE2LS4wOTMtMS40Ny0uMjY3YTEuNzc4IDEuNzc4IDAgMDEtLjcyMi0uNzU2Yy0uMTY2LS4zMjYtLjI1NS0uNjUtLjI1NS0xLjU0di00Ljg3M2MwLS44OTIuMDg5LTEuMjE1LjI1NS0xLjU0LjE2Ni0uMzI3LjQxLS41ODMuNzIyLS43NTcuMzEtLjE3NC42Mi0uMjY3IDEuNDctLjI2N0gxMSIvPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTExIDN2MTAiLz48L2c+PC9zdmc+",
addButton() {
base.waitForKeyElements(config.$uc.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "home") return;
let $button = $(``);
$button.css({ "margin-right": "10px", "display": "inline-block" });
element.prepend($button);
})
base.waitForKeyElements(config.$uc.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(``);
$button.css({ "margin-left": "10px", "display": "inline-block" });
element.append($button);
})
},
addInitButton() {
let $button = $(``);
$button.click(base.showInitDialog);
base.waitForKeyElements(config.$uc.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "home") return;
$button.css({ "margin-right": "10px", "display": "inline-block" });
element.prepend($button);
})
base.waitForKeyElements(config.$uc.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "share") return;
$button.css({ "margin-left": "10px", "display": "inline-block" });
element.append($button);
})
},
async getLink() {
Swal.fire({
...temp.swalDefault,
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();
},
});
let selectList = this.getSelectedList();
if (selectList.length === 0) return message.error("提示: 请勾选要下载的文件哦~");
if (selectList.every(item => !item.file)) return message.error("提示: 请打开文件夹后再勾选文件~");
if (temp.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);
let fids = batch.map(item => item.fid);
// 发起请求获取链接
let res = await base.post(config.$uc.api.getLink, { "fids": fids }, { "User-Agent": config.$uc.api.ua.downloadLink });
if (res?.code == 31001) {
return message.error("提示: 请先登录网盘~ 代码:" + res.code);
} else if (res?.code == 23018) {
let fid = res?.message?.match(/\[([a-f0-9]{32})\]/)?.[1];
let item = batch.find(item => item.fid === fid);
return message.error(`提示: 超出可获取大小限制~${item?.file_name ? ` 文件:${item.file_name}` : ""}`);
}
if (res?.code !== 0) {
return message.error(`提示: 获取链接失败了~ ${res.code ? res.code : ""} ${res.message ? res.message : ""}`);
}
// 合并响应数据
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);
}
temp.links = [data, {
isFolder: v => v.file === false,
getFileName: v => v.file_name,
getFileSize: v => v.size,
getFileLink: v => v.download_url,
convert: {
aria2: `--header "User-Agent:${config.$uc.api.ua.downloadLink}" --header "Referer:https://${location.host}/" --header "Cookie:${document.cookie}"`,
curl: `-A "${config.$uc.api.ua.downloadLink}" -e "https://${location.host}/" -b "${document.cookie}"`,
bitcomet: `user_agent=${encodeURIComponent(config.$uc.api.ua.downloadLink)}&refer=${encodeURIComponent(`https://${location.host}/`)}&cookie=${encodeURIComponent(document.cookie)}`
},
tooltip: config.$uc.dom
}];
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
} else if (temp.page === "share") {
let pwd_id = unsafeWindow.factStat?.ut?.baseParams?.pwd_id || // fast
unsafeWindow.factStat?.wa?.customStatParams?.pwd_id || // drive
location.pathname.match(/^\/(?:s|share)\/([a-zA-Z0-9]+)/)?.[1]; // 兜底
if (!pwd_id) return message.error("错误: 无法提取分享 ID~");
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);
let fids = batch.map(item => item.fid);
let fids_token = batch.map(item => item.share_fid_token);
// 发起请求获取链接
let res = await base.post(config.$uc.api.getLink, { "fids": fids, "fids_token": fids_token, pwd_id, "stoken": batch[0].stoken }, { "User-Agent": config.$uc.api.ua.downloadLink });
if (res?.code == 31001) {
return message.error("提示: 请先登录网盘~ 代码:" + res.code);
} else if (res?.code == 23018) {
let fid = res?.message?.match(/\[([a-f0-9]{32})\]/)?.[1];
let item = batch.find(item => item.fid === fid);
return message.error(`提示: 超出可获取大小限制~${item?.file_name ? ` 文件:${item.file_name}` : ""}`);
}
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);
}
temp.links = [data, {
isFolder: v => v.file === false,
getFileName: v => v.file_name,
getFileSize: v => v.size,
getFileLink: v => v.download_url,
convert: {
aria2: `--header "User-Agent:${config.$uc.api.ua.downloadLink}" --header "Referer:https://${location.host}/" --header "Cookie:${document.cookie}"`,
curl: `-A "${config.$uc.api.ua.downloadLink}" -e "https://${location.host}/" -b "${document.cookie}"`,
bitcomet: `user_agent=${encodeURIComponent(config.$uc.api.ua.downloadLink)}&refer=${encodeURIComponent(`https://${location.host}/`)}&cookie=${encodeURIComponent(document.cookie)}`
},
tooltip: config.$uc.dom
}];
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
} else {
return message.error("提示: 页面错误~");
}
},
getSelectedList() {
try {
let selectedList = [];
let reactDom = document.getElementsByClassName("file-list")[0];
let reactObj = base.findReact(reactDom);
let props = reactObj.props;
if (props) {
let stoken = props.stoken || "";
let fileList = props.list || [];
let selectedKeys = props.selectedRowKeys || [];
fileList.forEach(function (val) {
if (selectedKeys.includes(val.fid)) {
selectedList.push({ ...val, stoken });
}
});
}
return selectedList;
} catch (e) {
return [];
}
},
detectPage() {
let path = location.pathname;
if (/^\/(list)/.test(path)) return "home";
if (/^\/(s|share)\//.test(path)) return "share";
return "";
},
async initPanLinker() {
base.registerMenuCommand();
if (config.base.num === base.getValue("setting_init").code || config.base.license === base.getValue("setting_init").license) {
this.addButton();
} else {
this.addInitButton();
}
this.addPageListener();
},
};
/**
* 123云盘
* @author 油小猴
* @author hmjz100
*/
let $123pan = {
addPageListener() {
$doc.on("click", ".pl-button-mode", async function (e) {
temp.mode = e.currentTarget.dataset.mode;
if (!temp.mode) return;
temp.main.getLink();
});
$doc.on("click", ".listener-api-download.enhance", async function (e) {
e.preventDefault();
var status = base._EventFactory(e);
var file = {
index: status.item.data("index"),
link: status.item.data("link"),
name: status.item.data("name"),
size: status.item.data("size") || 0,
}
base._resetData(file.index);
// UI 初始化
status.down_normal.hide();
status.down_enhance.hide();
status.down_idm.hide();
status.link_message.hide();
status.link_copy.hide();
status.down_enhance_downing.find(".stop").show();
status.down_enhance_downing.show();
let startTime = Date.now();
let lastTime = startTime;
let lastLoaded = 0;
let emaSpeed = 0;
var tau = 2; // 时间常数(秒),数值越大速度显示越平稳,越小越灵敏。建议 1.5 - 3 之间。
base.download(file.link, undefined, {
...file,
onProgress: (prog, loaded, total) => {
var time = Date.now();
var insDiff = (time - lastTime) / 1000 || 0.001; // 瞬时耗时(秒)
var insSpeed = (loaded - lastLoaded) / insDiff; // 瞬时速度(B/s)
var avgDiff = (time - startTime) / 1000 || 0.1; // 总耗时(秒)
var avgSpeed = loaded / avgDiff; // 全局平均速度(B/s)
var alpha = 1 - Math.exp(-insDiff / tau);
if (emaSpeed === 0) {
emaSpeed = insSpeed; // 第一次采样,直接赋值
} else {
// EMA 公式:当前平滑值 = (1 - alpha) * 旧值 + alpha * 当前瞬时值
emaSpeed = (1 - alpha) * emaSpeed + alpha * insSpeed;
}
var rSize = total - loaded;
var predictionSpeed = (emaSpeed > 1024) ? emaSpeed : avgSpeed; // 兜底 - 如果 EMA 速度异常,则参考全局平均速度
var rTime = predictionSpeed > 0 ? rSize / predictionSpeed : 0;
lastLoaded = loaded;
lastTime = time;
var dprog = Math.min(prog, 100);
status.down_enhance_downing.find(".pl-progress").css("--width", `${dprog}%`);
status.down_enhance_downing.find(".pl-progress .text").text(`${dprog.toFixed(2)}% - ${base.sizeFormat(loaded)} | ${base.sizeFormat(emaSpeed)}/块 | ${base.rtimeFormat(rTime)}`);
}
})
.then(async (res) => {
status.down_enhance_downing.find(".pl-progress .header").css("background", "#55af28");
base.blobDownload(res.response, file.name);
await base.sleep(1000);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress .text").html(`下载完成~ 浏览器下载框应该弹出来了哦~`);
})
.catch(async (error) => {
base.console.error("【LinkSwift】Download(load)", error);
status.down_enhance_downing.find(".stop").hide();
status.down_enhance_downing.find(".back").show();
status.down_enhance_downing.find(".pl-progress").css("--width", "100%");
status.down_enhance_downing.find(".pl-progress .header").css("background", "#cc3235");
let estatus = `QAQ 下载出错~`;
if (!error?.status) estatus += ` 服务器未返回状态,若是下载一段时间后中断,可能是服务器返回文件长度不匹配,请重试;若是直接中断,请检查您的网络、脚本管理器扩展或浏览器~`;
if (error?.status == 403) estatus += ` 服务器说:链接已过期,关闭窗口重新获取试试吧~`;
if (error?.status == 204 || error?.statusText === "IDM") estatus += ` 服务说:链接已被 IDM 捕获~`;
status.down_enhance_downing.find(".pl-progress .text").html(estatus);
status.down_enhance_downing.find(".pl-progress .text").css("white-space", "break-spaces");
})
});
$doc.on("click", ".listener-idm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToIDM(target.data("link"), target.data("filename"), target.data("filesize"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-aria2-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToAria2(target.data("link"), target.data("filename"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-bitcomet-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToBitcomet(target.data("link"), target.data("filename"));
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
$doc.on("click", ".listener-abdm-download", async function (e) {
let target = $(e.currentTarget);
if (target.attr("data-processing") === "true") return;
target.attr("data-processing", "true");
let originalHtml = target.html();
target.find(".pl-icon").remove();
target.find(".pl-loading").remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToABDM(target.data("link"), target.data("filename"), undefined);
if (res === "success") {
target.removeClass("pl-btn-danger").html("发送成功啦!快去看看吧~").animate({ opacity: "0.5" }, "slow");
} else {
target.addClass("pl-btn-danger").text("发送失败,检查一下您的配置信息哦!").animate({ opacity: "0.5" }, "slow");
}
await base.sleep(3000);
target.removeClass("pl-btn-danger").removeAttr("data-processing").html(originalHtml).css("opacity", "");
});
},
greenerPage() {
// 旧版 分享 登录按钮
base.waitForKeyElements(".cent > .cent-not-login > .ant-btn", (tag) => {
if (tag.hasClass("reg") || tag.hasClass("log")) return;
tag.addClass("reg");
tag.removeClass("loginRight");
tag.find("span").text("注册");
if (tag.next().hasClass("log")) return;
let button = $(`登录 `);
button.on("click", () => {
let login = new URL(`https://login.123pan.com/centerlogin`);
login.searchParams.set("redirect_url", location.href);
location.href = login;
});
tag.after(button);
});
// 旧版 分享 按钮去除文本
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(".share-header_center > .share-header_center-not-login > .ant-btn", (tag) => {
if (tag.hasClass("reg") || tag.hasClass("log")) return;
tag.removeClass("ant-btn-variant-solid").addClass("ant-btn-variant-outlined");
tag.addClass("ant-btn-two-chinese-chars").addClass("reg");
tag.find("span").text("注册");
if (tag.next().hasClass("log")) return;
let button = $(` /^css-[a-z0-9]+$/.test(c))} ant-btn-primary ant-btn-color-primary ant-btn-variant-solid loginRight mfy-button ant-btn-two-chinese-chars log" style="margin-left:10px!important">登录 `);
// 加个跳转到原页面也不难吧?
button.on("click", () => {
let login = new URL(`https://login.123pan.com/centerlogin`);
login.searchParams.set("redirect_url", location.href);
location.href = login;
});
tag.after(button);
try {
let container = tag.closest(".share-header_center-not-login");
if (container.length && !container.data("logObserverAttached")) {
container.data("logObserverAttached", true);
let observer = new MutationObserver((mutations) => {
for (let m of mutations) {
if (!m.removedNodes) continue;
for (let n of m.removedNodes) {
if (!(n instanceof HTMLElement)) continue;
// 如果被移除的节点是注册按钮或其包含注册按钮的容器,则清理登录按钮
if (n.classList && (n.classList.contains("reg") || n.querySelector && n.querySelector(".reg"))) {
try { container.find(".log").remove(); } catch (e) { }
}
}
}
});
observer.observe(container[0], { childList: true, subtree: true });
container.data("logObserver", observer);
}
} catch (e) { }
});
// 新版 分享 超限登录
base.waitForKeyElements(".login-footer-240828", (tag) => {
if (tag.find(".replaced").length) return;
tag.children().each(function () {
let $child = $(this);
if ($child.hasClass("pointer-text")) {
let button = $(` /^css-[a-z0-9]+$/.test(c))} ant-btn-primary ant-btn-color-primary ant-btn-variant-solid loginRight mfy-button replaced">${$child.text()} `);
button.on("click", () => {
if ($child.text().includes("登录")) {
let login = new URL(`https://login.123pan.com/centerlogin`);
login.searchParams.set("redirect_url", location.href);
location.href = login;
} else {
return $child.click();
}
});
$child.after(button);
$child.hide();
}
});
}, true);
// 旧版 主页 播放器会员广告
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);
// 新版 主页 顶栏会员广告
base.waitForKeyElements(`.frontend-layout-header-right > span > [alt^="buttonMall"]`, (tag) => {
if (tag.parent().is(":hidden")) return;
tag.parent().hide();
let button = $(``);
button.on("click", () => { tag.click() });
tag.parent().after(button);
}, true);
// 分享 手机二维码
base.waitForKeyElements(".rightInfo .qrcode_btn", function (tag) {
tag.hide();
}, true);
base.waitForKeyElements(`#iqiyi-ad-overlay`, function (tag) {
tag.remove();
base.setStorage("iqiyi_ad_closed", {
date: '2099-12-31T23:59:59.999Z',
timestamp: Date.now()
});
}, true);
// 为页面主动添加 notoken 参数(token 太长影响观感,故不添加),以避免被新版页面屎山代码搞得二次刷新
setInterval(() => {
let url = new URL(location);
if (!url.searchParams.has("notoken") && !url.searchParams.has("token")) {
url.searchParams.delete("token");
url.searchParams.set("notoken", "1");
history.replaceState({}, "", url);
}
}, 500)
},
beautifyPage() {
if (base.getValue("setting_ui_theme").custom.$123pan !== true) return;
base.adaptiveThemeOverride([
["#597dfc", temp.color],
["#5a7cfc", temp.color],
["#2A82E4", temp.color],
["#51a1f0", temp.color],
["#597DFC", temp.color],
["#40a9ff", temp.color],
["#3c80ff", temp.color],
["#3C80FF", temp.color],
["#1677ff", temp.color],
["#1890ff", temp.color],
["#0958d9", temp.color],
["#F0F8FF", `${temp.color}10`],
["#f0f9ff", `${temp.color}20`],
["#F2F5FF", `${temp.color}20`],
["#C5E1FF", `${temp.color}20`],
["#2961D9", `${temp.color}20`],
["#b8d8ff", `${temp.color}20`],
["#325cf0", `${temp.color}D0`],
["#66A1FF", `${temp.color}D0`],
["#69b1ff", `${temp.color}D0`],
["60, 128, 255", base.hexToRgba(temp.color)],
["42, 130, 228", base.hexToRgba(temp.color)],
["89, 125, 252", base.hexToRgba(temp.color)],
]);
},
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({
...temp.swalDefault,
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();
},
});
let selectList = this.getSelectedList();
if (selectList.length === 0) return message.error("提示: 请勾选要下载的文件哦~");
if (selectList.every(item => item.Type !== 0)) return message.error("提示: 请打开文件夹后再勾选文件~");
if (temp.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);
}
temp.links = [selectList, {
isFolder: v => v.Type !== 0,
getFileName: v => v.FileName,
getFileSize: v => v.Size,
getFileLink: v => v.DownloadUrl || v.DownloadURL,
tooltip: config.$123pan.dom
}]
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
} else if (temp.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];
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);
}
temp.links = [selectList, {
isFolder: v => v.Type !== 0,
getFileName: v => v.FileName,
getFileSize: v => v.Size,
getFileLink: v => v.DownloadUrl || v.DownloadURL,
tooltip: config.$123pan.dom
}]
base.showMainDialog(config.base.dom.button[temp.mode].title, base.generateDom(temp.links), config.base.dom.button[temp.mode].footer);
} else {
return message.error("提示: 页面错误~");
}
},
async getFileUrlByOnce(item, index, token, ShareKey) {
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 }, { "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 }, { "Authorization": `Bearer ${token}`, "Platform": "ios" });
}
if (res.data?.DownloadUrl || res.data?.DownloadURL) {
let url = res.data.DownloadUrl ? res.data.DownloadUrl : 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 if (res?.code == 5113) {
return {
index,
downloadUrl: "获取下载地址失败,服务器说:本月免费流量不足,请开通网盘会员~"
};
} else {
return {
index,
downloadUrl: `获取下载地址失败,${res?.message ? "服务器说:" + res.message + "。" : "刷新后再试试吧~"}`
};
}
},
getSelectedList() {
try {
let selectedList = [];
let reactDom = $(".ant-table-wrapper, .tiled-list, .file-list, .single-file-sharing-container-content")[0];
let reactObj = base.findReact(reactDom);
let props = reactObj.pendingProps;
if (props) {
let fileList = props?.dataSource || props?.loadedFileList || props?.files || [];
let selectedKey = props?.rowSelection?.selectedRowKeys || [];
fileList.forEach(function (val) {
if (val?.checked === true) {
selectedList.push(val);
} else if (selectedKey.includes(val.FileId)) {
selectedList.push(val);
}
});
if (props?.file?.S3KeyFlag) selectedList.push(props.file);
}
return selectedList;
} catch (e) {
return [];
}
},
addButton() {
base.waitForKeyElements(config.$123pan.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "home") return;
let $button = $(` /^css-[a-z0-9]+$/.test(c))} ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-dropdown-trigger mfy-button upload-button pl-button color-button" style="user-select: text !important;">
下载助手
`);
element.prepend($button);
})
base.waitForKeyElements(config.$123pan.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(`
下载助手
`);
$button.css({ "width": "100px" });
element.append($button);
})
base.waitForKeyElements(config.$123pan.mount.shareNew, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(` /^css-[a-z0-9]+$/.test(c))} ant-btn-primary ant-btn-color-primary ant-btn-variant-solid mfy-button pl-button color-button" style="user-select: text !important;">
下载助手
`);
$(".single-file-sharing-container-content").css({ "width": "415px" });
element.append($button);
})
},
addInitButton() {
base.waitForKeyElements(config.$123pan.mount.home, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "home") return;
let $button = $(` /^css-[a-z0-9]+$/.test(c))} ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-dropdown-trigger mfy-button upload-button pl-button-init color-button" style="user-select: text !important;">
点我点亮
`);
$button.click(base.showInitDialog);
element.prepend($button);
})
base.waitForKeyElements(config.$123pan.mount.share, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(`
点我点亮
`);
$button.click(base.showInitDialog);
$button.css({ "width": "100px" });
element.append($button);
})
base.waitForKeyElements(config.$123pan.mount.shareNew, (element) => {
temp.page = temp.main.detectPage();
if ($(".pl-button-init").length > 0 || !temp.page || temp.page !== "share") return;
let $button = $(` /^css-[a-z0-9]+$/.test(c))} ant-btn-primary ant-btn-color-primary ant-btn-variant-solid mfy-button pl-button-init color-button" style="user-select: text !important;">
点我点亮
`);
$button.click(base.showInitDialog);
element.append($button);
})
},
detectPage() {
let path = location.pathname;
if (/^\/$/.test(path)) return "home";
if (/^\/s\//.test(path)) return "share";
return "";
},
async initPanLinker() {
base.registerMenuCommand();
if (config.base.num === base.getValue("setting_init").code || config.base.license === base.getValue("setting_init").license) {
this.addButton();
} else {
this.addInitButton();
}
this.addPageListener();
},
};
// 主代码
let main = {
async init() {
/**
* 控制台输出
* @author 油小猴
* @author hmjz100
* @description 来自【网盘智能识别助手】,有改动
*/
base.console.log(`%c %c LinkSwift\n一个基于 JavaScript 的网盘文件下载地址获取工具\n仓库:https://github.com/hmjz100/LinkSwift\n版本:${info.version}\n领域:${(window.self !== window.top ? "[iframe] " : "") + (document.title ? (document.title + " (" + location.origin + location.pathname + ")") : location.href)}`, `background:url(${info.icon}) center center no-repeat;background-size:12px;padding:3px`, `padding:2px`);
// 创建挂载点
let mountElem = $(`<${mount} class="${mount}" />`);
temp.mount = mountElem;
base.waitForKeyElements(`html:not(:has(> .${mount})) head`, (element) => {
if ($(`.${mount}`).length > 0) return;
element.after(temp.mount);
})
// 判断页面地址,定义主执行
if (/(pan|yun).baidu.com/.test(location.host)) temp.main = $baidu;
else if (/openapi.baidu.com\/oauth/.test(location.href)) temp.main = $baiduAuthorize;
else if (/www.(aliyundrive|alipan).com/.test(location.host)) temp.main = $aliyun;
else if (/(yun|caiyun).139.com/.test(location.host)) temp.main = $mcloud;
else if (/cloud.189.cn/.test(location.host)) temp.main = $tcloud;
else if (/pan.xunlei.com/.test(location.host)) temp.main = $xunlei;
else if (/pan.quark.cn/.test(location.host)) temp.main = $quark;
else if (/drive.uc.cn/.test(location.host)) temp.main = $uc;
else if (/(www|login).(123(pan|684|865|952|912).com|123pan.cn)/.test(location.host)) temp.main = $123pan;
// 智能默认设置
base.initDefaultConfig();
// 创建美化样式
base.addPanLinkerStyle();
// 创建按钮事件
base.addPageListener();
// 创建提示信息用的隐藏 tip
base.createTip();
// 创建下载用的隐藏 iframe
base.createIframe();
// 运行主程序
if ("initPanLinker" in temp.main) temp.main.initPanLinker();
// 运行绿化程序
if ("greenerPage" in temp.main) temp.main.greenerPage();
// 脚本更新后提示消息
let storedVersion = base.getValue("setting_init").version;
if (!storedVersion || base.isNewerVersion(info.version, storedVersion)) {
base.waitForKeyElements("body:not(.swal2-shown)", async () => {
await base.showUpdate();
let list = base.getValue("setting_init");
list.version = info.version;
base.setValue("setting_init", list);
return true;
}, true);
}
// 创建图标
temp.mount.append(`
`);
}
};
base.console = Object.fromEntries(Object.entries(console).filter(([key, value]) => typeof value === "function").map(([key, value]) => [key, value.bind(console)]));
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("");
}
})($ ?? jQuery);