// ==UserScript==
// @name 网盘链接识别
// @namespace https://greasyfork.org/zh-CN/scripts/445489
// @version 2024.12.22
// @author WhiteSevs
// @description 识别网页中显示的网盘链接,目前包括百度网盘、蓝奏云、天翼云、中国移动云盘(原:和彩云)、阿里云、文叔叔、奶牛快传、123盘、腾讯微云、迅雷网盘、115网盘、夸克网盘、城通网盘(部分)、坚果云、UC网盘、BT磁力,支持蓝奏云、天翼云(需登录)、123盘、奶牛、UC网盘(需登录)、坚果云(需登录)和阿里云盘(需登录,且限制在网盘页面解析)直链获取下载,页面动态监控加载的链接,可自定义规则来识别小众网盘/网赚网盘或其它自定义的链接。
// @license GPL-3.0-only
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAACsJJREFUeF7tXW+IHdUVP2c2u8kHIQYL0TRIaK1SgrFFaZsvVkpAo6YR1LJpa9jUd++83SUpSrUNBFRCrVgxNOv+mTOvJBBNmtpamoQG9UNBKLHFDzEtFttKBdOYQENE/Lb75vZd2cVNum/uvXNnZt/MnoGQD+/c8+d3fu+c+2f2PgR+ljQCuKSj5+CBCbDEScAEYAIscQSWePhcAZgASxyBJR4+VwAmQHEIjIyM3DAzM/M1pdSXEfEWALgVANbkaPE0ABwhomdz1GmtSgixHxF3Wg8wC55HxPeVUu8DgP7/jRUrVvxpbGzsY/PQbBK5VwCd9Ha7vVkptRkA9L8yHiKisAxDczaklL8GgAfLsImIryql3gSAqBPnh3nazI0AjUZjbRAEjwLAI3k6aKtLKbUjjuODtvI+cs1m894kSY776Mg49hwAxHkSIRcCSCl10nXy12YMLI9hrxDR/XkoMukQQrQQ8WGTXIGfn0PEZ6IoGvO14U0AKeUJALjH15Ecxr9ARHn2464uCSEOI+K2HHz2VXGUiAZ9lHgRQEp5BgBu9nEgr7FBEGyZmprSZCz8EUIMIuKRwg3ZGfiAiK63E/1/qcwEkFJ+BAArsxrOedzLRPSdnHWmqgvD8EBntj5Ups0UWxeI6NosvmQigBDibUTckMVgAWNKXwHMxSClfBwAtgPA+gLiclX5GhHd6TrImQBhGO5RSu11MHQREY8nSXICEf/R399/bnx8/KLD+CUl2plf3BgEwa1JktyOiN8HgKscAHCuhE4EaDabQ0mSHLBxSCml5weHlFKHWq3WBZsxLHM5AlLKLwLAQwCwCwBWWeLzKBHts5S1fx9ASnkdALxluZPXIiJh6wTLpSMwPDx8U7vd/iEADFtgdTZJko2tVuushawTAZ4EgCdMSpVSW+M4PmaS48/dEZBSWuWgMznfR0R6X8b4WLUA228/Ig5GUXTUaJUFMiMghNiEiK+bFCxbtuxLExMT/zLJ2RLAhnmTRDRiMsif+yMQhuFupdTTaZoQcZfNTqEVAYQQf0TEO1IMXurr69s4OTn5rn94rMEGAYul+Ekiutuky0iAoaGhqwcGBi4ZFD1FRLpK8FMSAkKIHyHiz9PM2bQBIwGklPcBwO9SDH0CAF8hovdKip3NAECj0VgdBMHf05aHSqntcRwfSm0VJjSllD8DgJ90k1NKTcVxbLM8MZnizx0RkFL+BgC6noAi4nNRFD3mSwB96NH1xKnMc3hHfGovbnEoZdweNraAMAxPKaW+0Q1NRFwfRdE7tUe7BwOUUuqTWL3j2u0xHhIZCSCl1K8gdT1pIiKjjh7ErhYujY6OXjM9Pf3ftGBM+TEmT0qpfAzUAukeDsI3P0yAHk6ujWtMABuUaizDBKhxcm1CYwLYoFRjGSZAjZNrExoTwAalGsswAWqcXJvQmAA2KNVYhglQ4+TahMYEsEGpxjK1IYCU8vcAcJvlW8dVTqn+C9+3iGhrHkHUggCmIPIAqhd1mA5qbHw2YWeysehnAWVetGADaMkyzn/Jc6V/dSDAeQBYXTLwvWLOeF5vcrQOBEg9bjYBUPXPTSXaFB8TwIRQj3/OBDC8cNLj+fN2r+oEOE1EX/VBwVTCfHRXYWzBBDDmx7gKMNyF92PfO/pMBPAFKO9Zsyupio7PNz9GAuiAuyzVcrmZo2iA6k4A3/xYEUAb0Xfjtdvt+xBxlVLqeF538jEB8nmrOmt+rAngWvps5ZkA+RDAFu8r5XqBAP9J2f8/R0SfzxrcQuMWgXClxueKVS8QQB8CfbuL48fyOjSZ078IBCg1vsoRYHYSs+BuYN4rgDRbc8CVabMIW5UkwLyZ7O2zAbxR1MWPZVeAeZVH3y5eeHyVJYCr41nlF4sAWf0tetyizwGKDnCx9wHKjs/VHhPgCsR6oS+7JtFHngnABPDhT/XG8hzg8pxxBeAKUL1vsY/HXAG4AvCNJ/M4wC2AW4BPQa3eWG4B3AK4BXAL6F65eCOoelXdyWNuAdwCuAVwC+AWMIcALwN5GejUQisvzHMAngPwHIDnADwH4DlAFw7wPkDlu3x6ADwHyDgHCMPwLqXUJgCYDoLgpampqb9VkSt1JUDW/FgtA6WUvwSAH1yR8Bc7vxSmf9i4Uk8dCeCTHyMBDL8a9j0iOlwlBtSNAL75sSGA/v1Z/TPmCz3/JqIvMAEWDwEppVd+bAhQq3VzDSuAV36YABXfCvYlNBOACbC01s2+35jF6/YLW/aNhysAVwCuAPMRqNpWMFcAx5rsC5ijucLFfePhFsAtgFsAt4AUDviWmMJroKMBjsfxNJABc2RYyeK++VmKc4CevrfPlT9MAEfEZn+cqrR7CR3dcxZnAjhD9unl16XdS5jBPachTAAnuD4Tnr0Bvefu7XMNhwngiljN5JkANUuoazhMAFfEaia/6ATo7+//3Pj4+MWa4VqZcAwEOE9E16UFY7MPkLZu1ro3ENFfK4NYjRwVQtyIiO92CwkR34yiaKMvAY4BwJZuSpRSD8Rx/Nsa4VqZUMIw3KaUSnsr+1dEtM2LAEKIvYi4J4VlB6Mo2lEZ1GrkqBBiEhGbKSE9Q0S7vQggpfwuALyUouRikiTrW63WhRph2/OhSCn1q/qnAeCqlOp8dxzHJ70IMDIycsPMzMw/05QopR6L4/i5nketRg5KKZ8EgCfSQlq+fPnKsbGxj70IoAdLKf8AAJtTmHYmjuNbaoRvT4cyPDx8U7vdPgUAq1Ja86tRFN1lCsS4CtAKwjDcqZTab1DWIiJhMsif+yMgpZwAgGGDpqeISFeJ1MeKADZtQFtRSm2N41ivGvgpCAGb0t8p2ucA4DYi+tDkhhUBZtvA8wDwiFEh4mAURUdNcvy5OwJCiE2I+LrFSKtvv9ZjTYBGo7E2CALdd9ZaODDZ19f3i8nJya6bFBY6WGQeAmEY7lZKPW0BivW334kAs1VAVwBdCWyeSwCg5w2HOvcIvGczgGUuR6DRaKxGRH0Hw0OIuMEGH0TcFUXRmI2sMwFmSXACAO6xNQAAnyilXuysIv4cBMFfoih6x2HskhIdHR29Znp6eo1Saj0iPgAA30qb6S8AzlEiGnQBzboFzFcqpTwDADe7GCpIVm+EHCGiZwvSn6pWCLEfEXcuhu0FbH5ARNe7+pKJALOV4CMAWOlqsCB56sx4w4J0L6h29o2iB8u0mWLrAhFdm8WXzATQxoQQb9v2pizOuYxRSu2I4/igy5isss1m894kSY5nHZ/zuNeI6M6sOr0IoI2GYbhHKbU3qwM5jnulcyx9f476uqoSQrQQ8eEybBlsvOz7G8veBNAONpvNoSRJfgoAaxYRlBeIqJR+3DmHP9w5h089Zi0Yh7N6NUZE+3zt5EKA2TmBfvNE92G9HVw6EYIg2DI1NaVXKIU/QohBRDxSuKGFDexLkuT5VqulSeD95EaAOU+klJ8SQSn1TUS8w9tDOwXepdDOzGdSYRgeUEoNuY7LKH8SEU/29fWdnJiY0LeC5fbkToD5ng0NDV09MDCgSfB1AFiHiOuUUusAINOMtUvUpa8A5pH9cQDYDgDrc8sIgH6vQk+uzyRJcqa/v/9U3kmf72uhBMgRFFZVEAJMgIKArYpaJkBVMlWQn0yAgoCtilomQFUyVZCfTICCgK2KWiZAVTJVkJ9MgIKArYra/wGYigzMiqJYZwAAAABJRU5ErkJggg==
// @supportURL https://github.com/WhiteSevs/TamperMonkeyScript/issues
// @match *://*/*
// @require https://update.greasyfork.org/scripts/494167/1413255/CoverUMD.js
// @require https://update.greasyfork.org/scripts/465550/1448580/JS-%E5%88%86%E9%A1%B5%E6%8F%92%E4%BB%B6.js
// @require https://update.greasyfork.org/scripts/456470/1413242/%E7%BD%91%E7%9B%98%E9%93%BE%E6%8E%A5%E8%AF%86%E5%88%AB-%E5%9B%BE%E6%A0%87%E5%BA%93.js
// @require https://update.greasyfork.org/scripts/486152/1448081/Crypto-JS.js
// @require https://fastly.jsdelivr.net/npm/@whitesev/utils@2.5.5/dist/index.umd.js
// @require https://fastly.jsdelivr.net/npm/@whitesev/domutils@1.4.8/dist/index.umd.js
// @require https://fastly.jsdelivr.net/npm/@whitesev/pops@1.9.6/dist/index.umd.js
// @require https://fastly.jsdelivr.net/npm/qmsg@1.2.8/dist/index.umd.js
// @connect *
// @connect lanzoub.com
// @connect lanzouc.com
// @connect lanzoue.com
// @connect lanzouf.com
// @connect lanzoug.com
// @connect lanzouh.com
// @connect lanzoui.com
// @connect lanzouj.com
// @connect lanzouk.com
// @connect lanzoul.com
// @connect lanzoum.com
// @connect lanzouo.com
// @connect lanzoup.com
// @connect lanzouq.com
// @connect lanzous.com
// @connect lanzout.com
// @connect lanzouu.com
// @connect lanzouv.com
// @connect lanzouw.com
// @connect lanzoux.com
// @connect lanzouy.com
// @connect lanosso.com
// @connect lanzn.com
// @connect lanzog.com
// @connect lanpw.com
// @connect lanpv.com
// @connect lanzv.com
// @connect wwentua.com
// @connect ilanzou.com
// @connect 189.cn
// @connect 123pan.com
// @connect 123pan.cn
// @connect wenshushu.cn
// @connect jianguoyun.com
// @connect cowtransfer.com
// @connect cowcs.com
// @connect aliyundrive.com
// @connect baidu.com
// @connect 139.com
// @connect weiyun.com
// @connect xunlei.com
// @connect 115.com
// @connect quark.cn
// @connect jianguoyun.com
// @connect uc.cn
// @connect ctfile.com
// @connect sharepoint.com
// @grant GM_deleteValue
// @grant GM_download
// @grant GM_getValue
// @grant GM_info
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_unregisterMenuCommand
// @grant GM_xmlhttpRequest
// @grant unsafeWindow
// @run-at document-start
// ==/UserScript==
(function (Qmsg, DOMUtils, Utils, pops) {
'use strict';
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var _a;
var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)();
var _GM_download = /* @__PURE__ */ (() => typeof GM_download != "undefined" ? GM_download : void 0)();
var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
var _GM_info = /* @__PURE__ */ (() => typeof GM_info != "undefined" ? GM_info : void 0)();
var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
var _GM_unregisterMenuCommand = /* @__PURE__ */ (() => typeof GM_unregisterMenuCommand != "undefined" ? GM_unregisterMenuCommand : void 0)();
var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
var _monkeyWindow = /* @__PURE__ */ (() => window)();
const HttpxCookieManager = {
$data: {
/** 是否启用 */
get enable() {
return PopsPanel.getValue("httpx-use-cookie-enable");
},
/** 是否使用document.cookie */
get useDocumentCookie() {
return PopsPanel.getValue("httpx-use-document-cookie");
},
/**
* cookie规则,在这里填入
* @example
* {
* key: "",
* hostname: "",
* }
*/
cookieRule: []
},
/**
* 补充cookie末尾分号
*/
fixCookieSplit(str) {
if (utils.isNotNull(str) && !str.trim().endsWith(";")) {
str += ";";
}
return str;
},
/**
* 合并两个cookie
*/
concatCookie(targetCookie, newCookie) {
if (utils.isNull(targetCookie)) {
return newCookie;
}
targetCookie = targetCookie.trim();
newCookie = newCookie.trim();
targetCookie = this.fixCookieSplit(targetCookie);
if (newCookie.startsWith(";")) {
newCookie = newCookie.substring(1);
}
return targetCookie.concat(newCookie);
},
/**
* 处理cookie
* @param details
* @returns
*/
handle(details) {
if (details.fetch) {
return;
}
if (!this.$data.enable) {
return;
}
let ownCookie = "";
let url = details.url;
if (url.startsWith("//")) {
url = window.location.protocol + url;
}
let urlObj = new URL(url);
if (this.$data.useDocumentCookie && urlObj.hostname.endsWith(
window.location.hostname.split(".").slice(-2).join(".")
)) {
ownCookie = this.concatCookie(ownCookie, document.cookie.trim());
}
for (let index = 0; index < this.$data.cookieRule.length; index++) {
let rule = this.$data.cookieRule[index];
if (urlObj.hostname.match(rule.hostname)) {
let cookie = PopsPanel.getValue(rule.key);
if (utils.isNull(cookie)) {
break;
}
ownCookie = this.concatCookie(ownCookie, cookie);
}
}
if (utils.isNotNull(ownCookie)) {
if (details.headers && details.headers["Cookie"]) {
details.headers.Cookie = this.concatCookie(
details.headers.Cookie,
ownCookie
);
} else {
details.headers["Cookie"] = ownCookie;
}
log.info(["Httpx => 设置cookie:", details]);
}
if (details.headers && details.headers.Cookie != null && utils.isNull(details.headers.Cookie)) {
delete details.headers.Cookie;
}
}
};
class StorageUtils {
/**
* 存储的键名,可以是多层的,如:a.b.c
*
* 那就是
* {
* "a": {
* "b": {
* "c": {
* ...你的数据
* }
* }
* }
* }
* @param key
*/
constructor(key) {
/** 存储的键名 */
__publicField(this, "storageKey");
if (typeof key === "string") {
let trimKey = key.trim();
if (trimKey == "") {
throw new Error("key参数不能为空字符串");
}
this.storageKey = trimKey;
} else {
throw new Error("key参数类型错误,必须是字符串");
}
this.getLocalValue();
}
/**
* 获取本地值
*/
getLocalValue() {
let localValue = _GM_getValue(this.storageKey);
if (localValue == null) {
localValue = {};
this.setLocalValue(localValue);
}
return localValue;
}
/**
* 设置本地值
* @param value
*/
setLocalValue(value) {
_GM_setValue(this.storageKey, value);
}
/**
* 设置值
* @param key 键
* @param value 值
*/
set(key, value) {
let localValue = this.getLocalValue();
Reflect.set(localValue, key, value);
this.setLocalValue(localValue);
}
/**
* 获取值
* @param key 键
* @param defaultValue 默认值
*/
get(key, defaultValue) {
let localValue = this.getLocalValue();
return Reflect.get(localValue, key) ?? defaultValue;
}
/**
* 获取所有值
*/
getAll() {
let localValue = this.getLocalValue();
return localValue;
}
/**
* 删除值
* @param key 键
*/
delete(key) {
let localValue = this.getLocalValue();
Reflect.deleteProperty(localValue, key);
this.setLocalValue(localValue);
}
/**
* 判断是否存在该值
*/
has(key) {
let localValue = this.getLocalValue();
return Reflect.has(localValue, key);
}
/**
* 获取所有键
*/
keys() {
let localValue = this.getLocalValue();
return Reflect.ownKeys(localValue);
}
/**
* 获取所有值
*/
values() {
let localValue = this.getLocalValue();
return Reflect.ownKeys(localValue).map(
(key) => Reflect.get(localValue, key)
);
}
/**
* 清空所有值
*/
clear() {
_GM_deleteValue(this.storageKey);
}
}
const NetDiskRuleUtils = {
/**
* 获取点击动作的默认值
*/
getDefaultLinkClickMode() {
let data = {
copy: {
default: false,
enable: true,
text: "复制到剪贴板"
},
openBlank: {
default: false,
enable: true,
text: "新标签页打开"
},
parseFile: {
default: false,
enable: false,
text: "文件解析"
},
own: {
default: false,
enable: false,
text: "自定义动作"
}
};
return data;
},
/**
* 参数替换,区分大小写
*
* 例如
* + {#shareCode#} => xxxx
* + {#accessCode#} => xxxx
* + {#$1#} => xxxx
* @param text
* @param data
*/
replaceParam(text, data = {}) {
if (typeof text !== "string") {
return text;
}
Object.keys(data).forEach((key) => {
let replacedText = data[key];
if (utils.isNotNull(replacedText)) {
try {
text = text.replaceAll(
`{#encodeURI-${key}#}`,
encodeURI(replacedText)
);
} catch (error) {
log.error("encodeURI-替换的文本失败", [replacedText]);
}
try {
text = text.replaceAll(
`{#encodeURIComponent-${key}#}`,
encodeURIComponent(replacedText)
);
} catch (error) {
log.error("encodeURIComponent-替换的文本失败", [replacedText]);
}
try {
text = text.replaceAll(
`{#decodeURI-${key}#}`,
decodeURI(replacedText)
);
} catch (error) {
log.error("decodeURI-替换的文本失败", [replacedText]);
}
try {
text = text.replaceAll(
`{#decodeURIComponent-${key}#}`,
decodeURIComponent(replacedText)
);
} catch (error) {
log.error("encodeURIComponent-替换的文本失败", [replacedText]);
}
text = text.replaceAll(`{#${key}#}`, replacedText);
}
});
return text;
},
/**
* 删除掉所有中文
* @param text
*/
replaceChinese(text) {
return text.replace(/[\u4e00-\u9fa5]/g, "");
},
/**
* 获取已解码的当前url
* @param decodeUrl 当前url
*/
getDecodeComponentUrl(decodeUrl = window.location.href) {
try {
decodeUrl = decodeURIComponent(decodeUrl);
} catch (error) {
}
return decodeUrl;
}
};
const NetDiskRuleDataKEY = {
/** 匹配范围 text */
matchRange_text: {
before: (key) => `${key}-text-match-range-before`,
after: (key) => `${key}-text-match-range-after`
},
/** 匹配范围 html */
matchRange_html: {
before: (key) => `${key}-html-match-range-before`,
after: (key) => `${key}-html-match-range-after`
},
/** 功能 */
function: {
enable: (key) => `${key}-enable`,
checkLinkValidity: (key) => `${key}-check-link-valid`,
checkLinkValidityHoverTip: (key) => `${key}-check-link-valid-hover-tip`,
linkClickMode: (key) => `${key}-click-mode`
},
/** 点击动作 新标签页打开 */
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: (key) => `${key}-open-blank-with-copy-accesscode`
},
/** Scheme转发 */
schemeUri: {
enable: (key) => `${key}-scheme-uri-enable`,
isForwardLinearChain: (key) => `${key}-scheme-uri-forward-linear-chain`,
isForwardBlankLink: (key) => `${key}-scheme-uri-forward-blank-link`,
uri: (key) => `${key}-scheme-uri-uri`
}
};
const WebsiteRuleDataKey = {
/** 功能 */
features: {
/** 是否启用自定义访问码 */
customAccessCodeEnable: (key) => `${key}-custom-accesscode-enable`,
/** 自定义访问码 */
customAccessCode: (key) => `${key}-custom-accesscode`
}
};
const NetDiskHandlerUtil = {
/**
* 替换文字
* @param text 需要替换的文字
* @param pattern 需要替换的文字的正则表达式
* @param newText 替换为的文字
*/
replaceText(text, pattern, newText) {
if (Array.isArray(pattern)) {
for (const patternItem of pattern) {
text = text.replace(patternItem, newText);
}
} else {
text = text.replace(pattern, newText);
}
return text;
},
/**
* 获取剪贴板文本
*/
async getClipboardText() {
function readClipboardText(resolve) {
navigator.clipboard.readText().then((clipboardText) => {
resolve(clipboardText);
}).catch((error) => {
log.error("读取剪贴板内容失败👉", error);
resolve("");
});
}
function requestPermissionsWithClipboard(resolve) {
navigator.permissions.query({
// @ts-ignore
name: "clipboard-read"
}).then((permissionStatus) => {
readClipboardText(resolve);
}).catch((error) => {
log.error(
"申请剪贴板权限失败,尝试直接读取👉",
error.message ?? error.name ?? error.stack
);
readClipboardText(resolve);
});
}
function checkClipboardApi() {
var _a2, _b;
if (typeof ((_a2 = navigator == null ? void 0 : navigator.clipboard) == null ? void 0 : _a2.readText) !== "function") {
return false;
}
if (typeof ((_b = navigator == null ? void 0 : navigator.permissions) == null ? void 0 : _b.query) !== "function") {
return false;
}
return true;
}
return new Promise((resolve) => {
if (!checkClipboardApi()) {
resolve("");
return;
}
if (document.hasFocus()) {
requestPermissionsWithClipboard(resolve);
} else {
window.addEventListener(
"focus",
() => {
requestPermissionsWithClipboard(resolve);
},
{
once: true
}
);
}
});
}
};
const KEY = "GM_Panel";
const ATTRIBUTE_INIT = "data-init";
const ATTRIBUTE_KEY = "data-key";
const ATTRIBUTE_DEFAULT_VALUE = "data-default-value";
const ATTRIBUTE_INIT_MORE_VALUE = "data-init-more-value";
const PROPS_STORAGE_API = "data-storage-api";
const UIInput = function(text, key, defaultValue, description, changeCallBack, placeholder = "", isNumber, isPassword) {
let result = {
text,
type: "input",
isNumber: Boolean(isNumber),
isPassword: Boolean(isPassword),
props: {},
attributes: {},
description,
getValue() {
return this.props[PROPS_STORAGE_API].get(key, defaultValue);
},
callback(event, value) {
this.props[PROPS_STORAGE_API].set(key, value);
},
placeholder
};
Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
Reflect.set(result.props, PROPS_STORAGE_API, {
get(key2, defaultValue2) {
return _GM_getValue(key2, defaultValue2);
},
set(key2, value) {
_GM_setValue(key2, value);
}
});
return result;
};
const UISwitch = function(text, key, defaultValue, clickCallBack, description, afterAddToUListCallBack) {
let result = {
text,
type: "switch",
description,
attributes: {},
props: {},
getValue() {
return Boolean(
this.props[PROPS_STORAGE_API].get(key, defaultValue)
);
},
callback(event, __value) {
let value = Boolean(__value);
log.success(`${value ? "开启" : "关闭"} ${text}`);
if (typeof clickCallBack === "function") {
if (clickCallBack(event, value)) {
return;
}
}
this.props[PROPS_STORAGE_API].set(key, value);
},
afterAddToUListCallBack
};
Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
Reflect.set(result.props, PROPS_STORAGE_API, {
get(key2, defaultValue2) {
return _GM_getValue(key2, defaultValue2);
},
set(key2, value) {
_GM_setValue(key2, value);
}
});
return result;
};
const CharacterMapping = {
$key: {
STORAGE_KEY: "character-mapping"
},
/**
* 获取模板数据
*/
getTemplateData() {
return {
uuid: utils.generateUUID(),
enable: true,
name: "",
data: {
url: "",
isRegExp: true,
regExpFlag: "ig",
searchValue: "",
replaceValue: ""
}
};
},
/**
* 显示视图
*/
show() {
let popsPanelContentUtils = __pops.config.panelHandleContentUtils();
function generateStorageApi(data) {
return {
get(key, defaultValue) {
return data[key] ?? defaultValue;
},
set(key, value) {
data[key] = value;
}
};
}
let ruleView = new RuleView({
title: "字符映射",
data: () => {
return this.getData();
},
getAddData: () => {
return this.getTemplateData();
},
getDataItemName: (data) => {
return data["name"];
},
updateData: (data) => {
return this.updateData(data);
},
deleteData: (data) => {
return this.deleteData(data);
},
getData: (data) => {
let allData = this.getData();
let findValue = allData.find((item) => item.uuid === data.uuid);
return findValue ?? data;
},
itemControls: {
enable: {
enable: true,
getEnable(data) {
return data.enable;
},
callback: (data, enable) => {
data.enable = enable;
this.updateData(data);
}
},
edit: {
enable: true,
getView: (data, isEdit) => {
let $fragment = document.createDocumentFragment();
if (!isEdit) {
data = this.getTemplateData();
}
let enable_template = UISwitch("启用", "enable", true);
Reflect.set(
enable_template.props,
PROPS_STORAGE_API,
generateStorageApi(data)
);
let $enable = popsPanelContentUtils.createSectionContainerItem_switch(
enable_template
);
let name_template = UIInput(
"规则名称",
"name",
"",
"",
void 0,
"必填"
);
Reflect.set(
name_template.props,
PROPS_STORAGE_API,
generateStorageApi(data)
);
let $name = popsPanelContentUtils.createSectionContainerItem_input(
name_template
);
let url_template = UIInput(
"匹配网址",
"url",
"",
"",
void 0,
"必填,可正则"
);
Reflect.set(
url_template.props,
PROPS_STORAGE_API,
generateStorageApi(data.data)
);
let $data_url = popsPanelContentUtils.createSectionContainerItem_input(
url_template
);
let data_isRegExp_template = UISwitch(
"是否启用正则",
"isRegExp",
true
);
Reflect.set(
data_isRegExp_template.props,
PROPS_STORAGE_API,
generateStorageApi(data.data)
);
let $data_isRegExp = popsPanelContentUtils.createSectionContainerItem_switch(
data_isRegExp_template
);
let data_regExpFlag_template = UIInput(
"正则标识符",
"regExpFlag",
"ig",
"",
void 0,
"i:不区分大小写 g:全局"
);
Reflect.set(
data_regExpFlag_template.props,
PROPS_STORAGE_API,
generateStorageApi(data.data)
);
let $data_regExpFlag = popsPanelContentUtils.createSectionContainerItem_input(
data_regExpFlag_template
);
let data_searchValue_template = UIInput(
"字符规则",
"searchValue",
"",
"",
void 0,
"必填,可正则"
);
Reflect.set(
data_searchValue_template.props,
PROPS_STORAGE_API,
generateStorageApi(data.data)
);
let $data_searchValue = popsPanelContentUtils.createSectionContainerItem_input(
data_searchValue_template
);
let data_replaceValue_template = UIInput(
"映射为",
"replaceValue",
"",
"",
void 0,
""
);
Reflect.set(
data_replaceValue_template.props,
PROPS_STORAGE_API,
generateStorageApi(data.data)
);
let $data_replaceValue = popsPanelContentUtils.createSectionContainerItem_input(
data_replaceValue_template
);
$fragment.appendChild($enable);
$fragment.appendChild($name);
$fragment.appendChild($data_url);
$fragment.appendChild($data_isRegExp);
$fragment.appendChild($data_regExpFlag);
$fragment.appendChild($data_searchValue);
$fragment.appendChild($data_replaceValue);
return $fragment;
},
onsubmit: ($form, isEdit, editData) => {
let $ulist_li = $form.querySelectorAll(
".rule-form-ulist > li"
);
let data = this.getTemplateData();
if (isEdit) {
data.uuid = editData.uuid;
}
$ulist_li.forEach(($li) => {
let formConfig = Reflect.get($li, "__formConfig__");
let attrs = Reflect.get(formConfig, "attributes");
let storageApi = Reflect.get($li, PROPS_STORAGE_API);
let key = Reflect.get(attrs, ATTRIBUTE_KEY);
let defaultValue = Reflect.get(attrs, ATTRIBUTE_DEFAULT_VALUE);
let value = storageApi.get(key, defaultValue);
if (Reflect.has(data, key)) {
Reflect.set(data, key, value);
} else if (Reflect.has(data.data, key)) {
Reflect.set(data.data, key, value);
} else {
log.error(`${key}不在数据中`);
}
});
if (data.name.trim() === "") {
Qmsg.error("规则名称不能为空");
return {
success: false,
data
};
}
if (data.data.url.trim() === "") {
Qmsg.error("匹配网址不能为空");
return {
success: false,
data
};
}
if (data.data.searchValue.trim() === "") {
Qmsg.error("字符规则不能为空");
return {
success: false,
data
};
}
if (isEdit) {
return {
success: this.updateData(data),
data
};
} else {
return {
success: this.addData(data),
data
};
}
}
},
delete: {
enable: true,
deleteCallBack: (data) => {
return this.deleteData(data);
}
}
},
bottomControls: {
filter: {
enable: true,
title: "过滤规则",
option: [
{
name: "过滤【已启用】的规则",
filterCallBack(data) {
return data.enable;
}
},
{
name: "过滤【未启用】的规则",
filterCallBack(data) {
return !data.enable;
}
},
{
name: "过滤【在当前网址生效】的规则",
filterCallBack(data) {
return Boolean(window.location.href.match(data.data.url));
}
}
]
}
}
});
ruleView.showView();
},
/**
* 根据url获取匹配的规则
*
* 注意:不会处理是否启用的情况
* @param url 需要匹配的url
*/
getUrlMatchedRule(url = window.location.href) {
let allData = this.getData();
return allData.filter((rule) => {
return Boolean(url.match(rule.data.url));
});
},
/**
* 获取格式化可用的规则
* @param url 匹配网址
*/
getMappingData(url = window.location.href) {
let matchedRule = this.getUrlMatchedRule();
return matchedRule.map((data) => {
if (!data.enable) {
return;
}
if (data.data.isRegExp) {
try {
return {
searchValue: new RegExp(
data.data.searchValue,
data.data.regExpFlag
),
replaceValue: data.data.replaceValue
};
} catch (error) {
log.error("字符映射规则转换发生错误:", error);
}
} else {
return {
searchValue: data.data.searchValue,
replaceValue: data.data.replaceValue
};
}
}).filter((item) => item != null);
},
/**
* 获取数据
*/
getData() {
return _GM_getValue(this.$key.STORAGE_KEY, []);
},
/**
* 设置数据
* @param data
*/
setData(data) {
_GM_setValue(this.$key.STORAGE_KEY, data);
},
/**
* 添加数据
* @param data
*/
addData(data) {
let localData = this.getData();
let findIndex = localData.findIndex((item) => item.uuid == data.uuid);
if (findIndex === -1) {
localData.push(data);
_GM_setValue(this.$key.STORAGE_KEY, localData);
return true;
} else {
return false;
}
},
/**
* 更新数据
* @param data
*/
updateData(data) {
let localData = this.getData();
let index = localData.findIndex((item) => item.uuid == data.uuid);
let updateFlag = false;
if (index !== -1) {
updateFlag = true;
localData[index] = data;
}
this.setData(localData);
return updateFlag;
},
/**
* 删除数据
* @param data
*/
deleteData(data) {
let localData = this.getData();
let index = localData.findIndex((item) => item.uuid == data.uuid);
let deleteFlag = false;
if (index !== -1) {
deleteFlag = true;
localData.splice(index, 1);
}
this.setData(localData);
return deleteFlag;
},
/**
* 清空数据
*/
clearData() {
_GM_deleteValue(this.$key.STORAGE_KEY);
}
};
const NetDisk = {
$data: {
/**
* 是否成功匹配到链接
*/
isMatchedLink: false,
/**
* 剪贴板内容
*/
clipboardText: ""
},
/** 匹配信息 */
$match: {
/**
* 匹配到的链接信息
*
* Worker识别规则 -> 存储识别到的信息(访问码|分享码|规则下标...)
*/
matchedInfo: new Utils.Dictionary(),
/**
* 黑名单-识别到的信息
*
* 如果Worker识别到的信息能在这里面找到对应的shareCode,则不会被识别
*/
blackMatchedInfo: new Utils.Dictionary(),
/**
* (临时)链接字典
*/
tempMatchedInfo: new Utils.Dictionary(),
/**
* 用于存储已匹配到的网盘规则名
* 只有单独的名
*/
matchedInfoRuleKey: /* @__PURE__ */ new Set()
},
/** 规则 */
$rule: {
/** 执行匹配本文的规则 */
matchRule: {},
/** 各个网盘规则的设置项 */
ruleSetting: {},
/** 各个网盘规则 */
rule: []
},
/** 额外规则,用于辅助处理 */
$extraRule: {
/**
* 使用该正则判断提取到的shareCode是否正确
*/
shareCodeNotMatchRegexpList: [
/vipstyle|notexist|ajax|file|download|ptqrshow|xy-privacy/g,
/comp|web|undefined|1125|unproved|console|account|favicon|setc/g
],
/**
* 使用该正则判断提取到的accessCode是否正确
*/
accessCodeNotMatchRegexpList: [/^(font)/gi],
/**
* 当没有accessCode时,使用该正则去除不需要的字符串
*/
noAccessCodeRegExp: [
/( |提取码:|\n密码:)/gi,
/{#accessCode#}/gi,
/{#encodeURI-accessCode#}|{#encodeURIComponent-accessCode#}/gi,
/{#decodeURI-accessCode#}|{#decodeURIComponent-accessCode#}/gi,
/(\?pwd=|&pwd=|\?password=|\?p=)/gi
]
},
/**
* 初始化
*/
init() {
this.initLinkDict();
},
/**
* 初始化字典
*/
initLinkDict() {
Object.keys(this.$rule.matchRule).forEach((netDiskName) => {
this.$match.matchedInfo.set(netDiskName, new utils.Dictionary());
this.$match.blackMatchedInfo.set(netDiskName, new utils.Dictionary());
this.$match.tempMatchedInfo.set(netDiskName, new utils.Dictionary());
});
let matchedUrlRuleList = WebsiteRule.getUrlMatchedRule().filter(
(item) => item.enable
);
if (matchedUrlRuleList.length) {
log.info("成功命中网站规则 ==> ", matchedUrlRuleList);
GM_Menu.add({
key: "matchedUrlRuleList",
text: `🌏 命中网站规则 ${matchedUrlRuleList.length} 条`,
autoReload: false,
isStoreValue: false,
showText(text) {
return text;
},
callback: () => {
log.info("当前网址:" + self.location.href);
if (!PopsPanel.isTopWindow()) {
return;
}
alert(
"以下是命中的规则名:\n" + matchedUrlRuleList.map((item) => item.name).join("\n")
);
}
});
}
let characterMapping = CharacterMapping.getUrlMatchedRule().filter(
(item) => item.enable
);
if (characterMapping.length) {
log.info("成功命中字符规则 ==> ", characterMapping);
GM_Menu.add({
key: "characterMapping",
text: `🌏 命中字符规则 ${characterMapping.length} 条`,
autoReload: false,
isStoreValue: false,
showText(text) {
return text;
},
callback: () => {
log.info("当前网址:" + self.location.href);
if (!PopsPanel.isTopWindow()) {
return;
}
alert(
"以下是命中的规则名:\n" + characterMapping.map((item) => item.name).join("\n")
);
}
});
}
},
/**
* 处理链接,将匹配到的链接转为参数和密码存入字典中
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称的索引下标
* @param matchText 正在进行匹配的文本
*/
handleLink(netDiskName, netDiskIndex, matchText) {
let shareCode = this.handleShareCode(netDiskName, netDiskIndex, matchText);
if (utils.isNull(shareCode)) {
return;
}
let accessCode = this.handleAccessCode(
netDiskName,
netDiskIndex,
matchText
);
accessCode = this.handleAccessCodeByUserRule(
netDiskName,
accessCode,
matchText
);
return {
shareCode,
accessCode
};
},
/**
* 对传入的url进行处理,返回shareCode
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称索引下标
* @param matchText 正在进行匹配的文本
*/
handleShareCode(netDiskName, netDiskIndex, matchText) {
var _a2;
let netDiskMatchRegular = NetDisk.$rule.matchRule[netDiskName][netDiskIndex];
let shareCodeMatch = (_a2 = matchText.match(netDiskMatchRegular.shareCode)) == null ? void 0 : _a2.filter((item) => utils.isNotNull(item));
if (utils.isNull(shareCodeMatch)) {
log.error(`匹配shareCode为空`, {
匹配的文本: matchText,
规则: netDiskMatchRegular,
正在使用的规则: netDiskMatchRegular.shareCode,
网盘名称: netDiskName,
网盘名称索引下标: netDiskIndex
});
return;
}
let shareCode = shareCodeMatch[0];
if (netDiskMatchRegular.shareCodeNeedRemoveStr) {
shareCode = shareCode.replace(
netDiskMatchRegular.shareCodeNeedRemoveStr,
""
);
}
let shareCodeNotMatch = netDiskMatchRegular.shareCodeNotMatch;
if (shareCodeNotMatch != void 0 && shareCode.match(shareCodeNotMatch)) {
log.error(`不可能的shareCode => ${shareCode}`);
return;
}
for (const shareCodeNotMatchRegexp of NetDisk.$extraRule.shareCodeNotMatchRegexpList) {
if (shareCode.match(shareCodeNotMatchRegexp)) {
log.error(`不可能的shareCode => ${shareCode}`);
return;
}
}
shareCode = decodeURI(shareCode);
if (NetDiskGlobalData.shareCode.excludeIdenticalSharedCodes.value && utils.isSameChars(
shareCode,
NetDiskGlobalData.shareCode.excludeIdenticalSharedCodesCoefficient.value
)) {
return;
}
if (shareCode.endsWith("http") || shareCode.endsWith("https")) {
return;
}
return shareCode;
},
/**
* 对传入的url进行处理,返回accessCode
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称索引下标
* @param matchText 正在进行匹配的文本
* @returns "xxxx" || ""
*/
handleAccessCode(netDiskName, netDiskIndex, matchText) {
var _a2;
let netDiskMatchRegular = this.$rule.matchRule[netDiskName][netDiskIndex];
let accessCode = "";
if (!netDiskMatchRegular.checkAccessCode) {
return "";
}
let accessCodeMatch = matchText.match(netDiskMatchRegular.checkAccessCode);
if (accessCodeMatch) {
let accessCodeMatchValue = accessCodeMatch[accessCodeMatch.length - 1];
let accessCodeMatchArray = (_a2 = accessCodeMatchValue.match(netDiskMatchRegular.accessCode)) == null ? void 0 : _a2.filter((item) => utils.isNotNull(item));
if (utils.isNull(accessCodeMatchArray)) {
return "";
}
if (accessCodeMatchArray.length) {
accessCode = accessCodeMatchArray[0];
if (accessCode.startsWith("http")) {
accessCode = "";
}
}
}
if (utils.isNotNull(accessCode)) {
for (const accessCodeNotMatchRegexp of NetDisk.$extraRule.accessCodeNotMatchRegexpList) {
if (accessCode.match(accessCodeNotMatchRegexp)) {
accessCode = "";
break;
}
}
if (netDiskMatchRegular.acceesCodeNotMatch && accessCode.match(netDiskMatchRegular.acceesCodeNotMatch)) {
accessCode = "";
}
}
return accessCode;
},
/**
* 对accessCode二次处理,使用自定义的访问码规则
* @param netDiskName 网盘名称
* @param accessCode 访问码
* @param matchText 匹配到的文本
*/
handleAccessCodeByUserRule(netDiskName, accessCode, matchText) {
let matchedUrlRuleList = WebsiteRule.getUrlMatchedRule();
let result = accessCode;
for (let index = 0; index < matchedUrlRuleList.length; index++) {
const rule = matchedUrlRuleList[index];
let ruleData = WebsiteRule.getRuleData(rule);
let customAccessCode = Reflect.get(
ruleData,
WebsiteRuleDataKey.features.customAccessCode(netDiskName)
);
let customAccessCodeEnable = Reflect.get(
ruleData,
WebsiteRuleDataKey.features.customAccessCodeEnable(netDiskName)
);
if (customAccessCodeEnable && typeof customAccessCode === "string") {
result = customAccessCode;
log.success(`使用自定义网站规则中的提取码 ${netDiskName} ${result}`);
break;
}
}
return result;
},
/**
* 获取在弹窗中显示出的链接
* @param netDiskName 网盘名称,指NetDisk.regular的内部键名
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
* @param matchText 匹配到的文本
*/
handleLinkShow(netDiskName, netDiskIndex, shareCode, accessCode, matchText) {
let netDiskMatchRegular = NetDisk.$rule.matchRule[netDiskName][netDiskIndex];
if (netDiskMatchRegular == void 0) {
Qmsg.error("BUG: 获取uiLink规则失败");
log.error(
"BUG: 分析参数",
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
throw new TypeError("获取uiLink规则失败");
}
let uiLink = NetDiskRuleUtils.replaceParam(
netDiskMatchRegular["uiLinkShow"],
{
shareCode
}
);
if (typeof accessCode === "string" && accessCode.trim() != "") {
uiLink = NetDiskRuleUtils.replaceParam(uiLink, {
accessCode
});
} else {
uiLink = NetDiskHandlerUtil.replaceText(
uiLink,
NetDisk.$extraRule.noAccessCodeRegExp,
""
);
}
if (netDiskMatchRegular.paramMatch) {
let currentDict = NetDisk.$match.matchedInfo.get(netDiskName).get(shareCode);
matchText = matchText ?? (currentDict == null ? void 0 : currentDict.matchText);
if (utils.isNotNull(matchText)) {
let paramMatchArray = matchText.match(netDiskMatchRegular.paramMatch);
let replaceParamData = {};
if (paramMatchArray) {
for (let index = 0; index < paramMatchArray.length; index++) {
replaceParamData[`$${index}`] = paramMatchArray[index];
}
}
uiLink = NetDiskRuleUtils.replaceParam(uiLink, replaceParamData);
}
}
return uiLink;
},
/**
* 获取已匹配到的链接的存储的对象
* @param accessCode 访问码
* @param netDiskIndex 下标,默认0
* @param isForceAccessCode 是否锁定访问码不允许修改,默认false
* @param matchText 匹配到的文本
*/
getLinkDickObj(accessCode, netDiskIndex = 0, isForceAccessCode = false, matchText) {
return {
accessCode,
netDiskIndex,
isForceAccessCode,
matchText
};
}
};
const NetDiskUISizeConfig = {
/**
* 天翼云需要登录的提示
*/
tianYiYunLoginTip: {
PC: {
width: "30vw",
height: "280px"
},
Mobile: {
width: "80vw",
height: "250px"
}
},
/**
* 坚果云需要登录的提示
*/
jianGuoYunLoginTip: {
PC: {
width: "350px",
height: "200px"
},
Mobile: {
width: "350px",
height: "200px"
}
},
/**
* 设置
*/
settingView: {
PC: {
width: "800px",
height: "600px"
},
Mobile: {
width: "92vw",
height: "80vh"
}
},
/**
* 设置默认值的界面
*/
setDefaultValueView: {
PC: {
width: "350px",
height: "200px"
},
Mobile: {
width: "350px",
height: "200px"
}
},
/**
* (主)网盘链接界面
*/
mainView: {
PC: {
width: "500px",
height: "100%"
},
Mobile: {
width: "88vw",
height: "50vh"
}
},
/**
* (主)网盘链接界面-小窗
*/
mainViewSmallWindow: {
PC: {
get width() {
return NetDiskGlobalData.smallWindow["netdisk-ui-small-window-width"].value + "px";
},
height: "auto"
},
Mobile: {
get width() {
return NetDiskGlobalData.smallWindow["netdisk-ui-small-window-width"].value + "px";
},
height: "auto"
}
},
/**
* 单文件直链弹窗
*/
oneFileStaticView: {
PC: {
width: "550px",
height: "350px"
},
Mobile: {
width: "88vw",
height: "300px"
}
},
/**
* 多文件直链弹窗
*/
moreFileStaticView: {
PC: {
width: "700px",
height: "600px"
},
Mobile: {
width: "88vw",
height: "500px"
}
},
/**
* 新密码、错误密码输入弹窗
*/
inputNewAccessCodeView: {
PC: {
width: "400px",
height: "200px"
},
Mobile: {
width: "88vw",
height: "160px"
}
},
/**
* 历史存储记录弹窗
*/
historyMatchView: {
PC: {
width: "50vw",
height: "65vh"
},
Mobile: {
width: "88vw",
height: "60vh"
}
},
/**
* 自定义规则的弹窗
*/
customRulesView: {
PC: {
width: "50vw",
height: "65vh"
},
Mobile: {
width: "88vw",
height: "60vh"
}
},
/**
* 自定义规则的调试视图
*/
customRuleDebugView: {
PC: {
width: "55vw",
height: "70vh"
},
Mobile: {
width: "88vw",
height: "70vh"
}
},
/**
* 主动识别的弹窗
*/
matchPasteTextView: {
PC: {
width: "50vw",
height: "65vh"
},
Mobile: {
width: "88vw",
height: "60vh"
}
},
/**
* 访问码规则弹窗
*/
accessCodeRuleView: {
PC: {
width: "50vw",
height: "65vh"
},
Mobile: {
width: "88vw",
height: "60vh"
}
},
/**
* 访问码规则添加/修改/删除
*/
accessCodeRuleEditView: {
PC: {
width: "44vw",
height: "50vh"
},
Mobile: {
width: "70vw",
height: "45vh"
}
},
/**
* 网站规则弹窗
*/
websiteRuleView: {
PC: {
width: "45vw",
height: "65vh"
},
Mobile: {
width: "88vw",
height: "60vh"
}
},
/**
* 添加|编辑网站规则弹窗
*/
websiteEditRuleView: {
PC: {
width: "45vw",
height: "65vh"
},
Mobile: {
width: "88vw",
height: "60vh"
}
}
};
const NetDiskAutoFillAccessCode_baidu = function(netDiskInfo) {
if (window.location.hostname === "pan.baidu.com" && window.location.pathname === "/share/init" && window.location.search.startsWith("?surl=")) {
log.success("自动填写链接", netDiskInfo);
utils.waitNode("div.verify-form #accessCode").then(($ele) => {
var _a2;
if (!utils.isVisible($ele)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
$ele.value = netDiskInfo.accessCode;
utils.dispatchEvent($ele, "input");
(_a2 = document.querySelector("div.verify-form #submitBtn")) == null ? void 0 : _a2.click();
});
}
if (window.location.hostname === "pan.baidu.com" && window.location.pathname === "/wap/init" && window.location.search.startsWith("?surl=")) {
log.success("自动填写链接", netDiskInfo);
utils.waitNode(
"div.extractWrap div.extract-content div.extractInputWrap.extract input[type=text]"
).then(($input) => {
var _a2;
if (!utils.isVisible($input)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
$input.value = netDiskInfo.accessCode;
utils.dispatchEvent($input, "input");
(_a2 = document.querySelector(
"div.extractWrap div.extract-content button.m-button"
)) == null ? void 0 : _a2.click();
});
}
};
const NetDiskAutoFillAccessCode_lanzou = function(netDiskInfo) {
if (window.location.hostname.match(/lanzou[a-z]{1}.com/gi)) {
log.success("自动填写链接", netDiskInfo);
utils.waitNode("#pwd").then(($input) => {
var _a2, _b;
if (!utils.isVisible($input)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
$input.value = netDiskInfo.accessCode;
utils.dispatchEvent($input, "input");
(_a2 = document.querySelector(
"#passwddiv div.passwddiv-input > div"
) || $input.nextElementSibling) == null ? void 0 : _a2.click();
(_b = document.querySelector("#sub")) == null ? void 0 : _b.click();
});
utils.waitNode("#f_pwd").then((element) => {
utils.mutationObserver(element, {
config: {
attributes: true,
attributeFilter: ["style"]
},
callback: (mutations, observer) => {
var _a2;
let inputElement = document.querySelector("#f_pwd #pwd");
if (!utils.isVisible(inputElement)) {
log.error("输入框不可见,不输入密码");
return;
}
observer.disconnect();
log.success("自动填入访问码并关闭观察者");
Qmsg.success("自动填入访问码");
inputElement.value = netDiskInfo.accessCode;
utils.dispatchEvent(inputElement, "input");
(_a2 = document.querySelector("#f_pwd #sub")) == null ? void 0 : _a2.click();
}
});
});
}
};
const NetDiskAutoFillAccessCode_tianyiyun = function(netDiskInfo) {
function loopWaitElementShow(targetElement, callback) {
let loopCount = 0;
let maxLoopCount = 30;
let interval = setInterval(() => {
loopCount++;
if (loopCount > maxLoopCount) {
log.error("结束循环检查,退出。");
clearInterval(interval);
return;
}
if (!utils.isVisible(targetElement)) {
log.warn(`第 ${loopCount} 次:输入框不可见,不输入密码`);
return;
}
callback();
clearInterval(interval);
}, 500);
}
if (window.location.hostname === "cloud.189.cn") {
log.success("自动填写链接", netDiskInfo);
utils.waitNode("input#code_txt").then((codeTxtElement) => {
loopWaitElementShow(codeTxtElement, () => {
Qmsg.success("自动填入访问码");
let visitBtn = document.querySelector(
".btn.btn-primary.visit"
);
codeTxtElement.value = netDiskInfo.accessCode;
codeTxtElement._value = netDiskInfo.accessCode;
utils.dispatchEvent(codeTxtElement, "input");
utils.dispatchEvent(visitBtn, "click");
});
});
}
if (window.location.hostname === "h5.cloud.189.cn") {
log.success("自动填写链接", netDiskInfo);
utils.waitNode("input.access-code-input").then((accessInputElement) => {
loopWaitElementShow(accessInputElement, () => {
Qmsg.success("自动填入访问码");
accessInputElement.value = netDiskInfo.accessCode;
accessInputElement._value = netDiskInfo.accessCode;
utils.dispatchEvent(accessInputElement, "input");
utils.dispatchEvent(
document.querySelector("div.button"),
"click"
);
});
});
}
};
const NetDiskAutoFillAccessCode_hecaiyun = function(netDiskInfo) {
if (window.location.hostname === "caiyun.139.com") {
log.success("自动填写链接", netDiskInfo);
utils.waitNode("#token-input").then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
element.value = netDiskInfo.accessCode;
utils.dispatchEvent(element, "input");
document.querySelector("#homepage div.token div.token-form a").click();
});
utils.waitNode("#app div.token-form input[type=text]").then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
element.value = netDiskInfo.accessCode;
utils.dispatchEvent(element, "input");
document.querySelector("div.token-form a.btn-token").click();
});
}
};
const ReactUtils = {
/**
* 等待react某个属性并进行设置
*/
async waitReactPropsToSet($target, propName, needSetList) {
if (!Array.isArray(needSetList)) {
this.waitReactPropsToSet($target, propName, [needSetList]);
return;
}
function getTarget() {
let __target__ = null;
if (typeof $target === "string") {
__target__ = document.querySelector($target);
} else if (typeof $target === "function") {
__target__ = $target();
} else if ($target instanceof HTMLElement) {
__target__ = $target;
}
return __target__;
}
if (typeof $target === "string") {
let $ele = await utils.waitNode($target, 1e4);
if (!$ele) {
return;
}
}
needSetList.forEach((needSetOption) => {
if (typeof needSetOption.msg === "string") {
log.info(needSetOption.msg);
}
function checkObj() {
let target = getTarget();
if (target == null) {
return false;
}
let targetObj = utils.getReactObj(target);
if (targetObj == null) {
return false;
}
let targetObjProp = targetObj[propName];
if (targetObjProp == null) {
return false;
}
let needOwnCheck = needSetOption.check(targetObjProp);
return Boolean(needOwnCheck);
}
utils.waitPropertyByInterval(
() => {
return getTarget();
},
checkObj,
250,
1e4
).then(() => {
let target = getTarget();
if (target == null) {
return;
}
let targetObj = utils.getReactObj(target);
if (targetObj == null) {
return;
}
let targetObjProp = targetObj[propName];
if (targetObjProp == null) {
return;
}
needSetOption.set(targetObjProp);
});
});
}
};
const NetDiskAutoFillAccessCode_aliyun = function(netDiskInfo) {
if (window.location.hostname === "www.aliyundrive.com" || window.location.hostname === "www.alipan.com") {
log.success("自动填写链接", netDiskInfo);
utils.waitNode("#root input.ant-input").then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
element.value = netDiskInfo.accessCode;
ReactUtils.waitReactPropsToSet(element, "reactFiber", {
check(reactInstance) {
var _a2;
return typeof ((_a2 = reactInstance == null ? void 0 : reactInstance.memoizedProps) == null ? void 0 : _a2.onChange) === "function";
},
set(reactInstance) {
reactInstance.memoizedProps.onChange({
currentTarget: element,
target: element
});
}
});
document.querySelector('#root button[type="submit"]').click();
});
utils.waitNode("#root input[name=pwd]").then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
element.value = netDiskInfo.accessCode;
ReactUtils.waitReactPropsToSet(element, "reactFiber", {
check(reactInstance) {
var _a2;
return typeof ((_a2 = reactInstance == null ? void 0 : reactInstance.memoizedProps) == null ? void 0 : _a2.onChange) === "function";
},
set(reactInstance) {
reactInstance.memoizedProps.onChange({
currentTarget: element,
target: element
});
}
});
document.querySelector('#root button[type="submit"]').click();
});
}
};
const NetDiskAutoFillAccessCode_123pan = function(netDiskInfo) {
if (window.location.hostname === "www.123pan.com") {
log.success("自动填写链接", netDiskInfo);
utils.waitNode("#app .ca-fot input.ant-input[type=text]").then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
ReactUtils.waitReactPropsToSet(element, "reactProps", {
check(reactInstance) {
return typeof (reactInstance == null ? void 0 : reactInstance.onChange) === "function";
},
set(reactInstance) {
reactInstance.onChange({
target: {
value: netDiskInfo.accessCode
}
});
}
});
let $next = element.nextSibling;
$next == null ? void 0 : $next.click();
});
utils.waitNode("#app .appinput input.ant-input[type=text]").then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
ReactUtils.waitReactPropsToSet(element, "reactProps", {
check(reactInstance) {
return typeof (reactInstance == null ? void 0 : reactInstance.onChange) === "function";
},
set(reactInstance) {
reactInstance.onChange({
target: {
value: netDiskInfo.accessCode
}
});
}
});
let $next = element.nextSibling;
$next == null ? void 0 : $next.click();
});
}
};
const NetDiskAutoFillAccessCode_weiyun = function(netDiskInfo) {
if (window.location.hostname === "share.weiyun.com") {
log.success("自动填写链接", netDiskInfo);
utils.waitNode("#app input.input-txt").then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
element.value = netDiskInfo.accessCode;
utils.dispatchEvent(element, "input");
utils.dispatchEvent(element, "change");
setTimeout(() => {
document.querySelector(".form-item button.btn-main").click();
}, 500);
});
utils.waitNode(".input-wrap input.pw-input").then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
element.value = netDiskInfo.accessCode;
utils.dispatchEvent(element, "input");
utils.dispatchEvent(element, "change");
setTimeout(() => {
document.querySelector(".pw-btn-wrap button.btn").click();
}, 500);
});
}
};
const NetDiskAutoFillAccessCode_xunlei = function(netDiskInfo) {
if (window.location.hostname === "pan.xunlei.com") {
log.success("自动填写链接", netDiskInfo);
utils.waitNode(
"#__layout div.pass-input-wrap input.td-input__inner"
).then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
log.error("输入框不可见,不输入密码");
element.value = netDiskInfo.accessCode;
utils.dispatchEvent(element, "input");
utils.dispatchEvent(element, "change");
setTimeout(() => {
document.querySelector(
"#__layout div.pass-input-wrap button.td-button"
).click();
}, 500);
});
utils.waitNode(
"#__layout div.pass-wrapper input.td-input__inner"
).then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
log.error("输入框不可见,不输入密码");
element.value = netDiskInfo.accessCode;
utils.dispatchEvent(element, "input");
utils.dispatchEvent(element, "change");
setTimeout(() => {
document.querySelector(
"#__layout div.pass-wrapper button.td-button"
).click();
}, 500);
});
}
};
const NetDiskAutoFillAccessCode_kuake = function(netDiskInfo) {
if (window.location.hostname === "pan.quark.cn") {
log.success("自动填写链接", netDiskInfo);
utils.waitNode(
"#ice-container input.ant-input[class*=ShareReceive]"
).then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
ReactUtils.waitReactPropsToSet(element, "reactProps", {
check(reactInstance) {
return (reactInstance == null ? void 0 : reactInstance.onChange) === "function";
},
set(reactInstance) {
reactInstance.onChange({
target: {
value: netDiskInfo.accessCode
}
});
}
});
ReactUtils.waitReactPropsToSet(element, "reactEventHandlers", {
check(reactInstance) {
return (reactInstance == null ? void 0 : reactInstance.onChange) === "function";
},
set(reactInstance) {
reactInstance.onChange({
target: {
value: netDiskInfo.accessCode
}
});
}
});
});
}
};
const NetDiskAutoFillAccessCode_chengtong = function(netDiskInfo) {
log.success("自动填写链接", netDiskInfo);
utils.waitNode("#passcode").then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
element.value = netDiskInfo.accessCode;
utils.dispatchEvent(element, "input");
document.querySelector(
"#main-content .form-group button.btn[type=button]"
).click();
});
};
const NetDiskAutoFillAccessCode_115pan = function(netDiskInfo) {
if (window.location.hostname === "115.com") {
log.success("自动填写链接", netDiskInfo);
utils.waitNode("input.text").then((element) => {
if (!utils.isVisible(element)) {
log.error("输入框不可见,不输入密码");
return;
}
Qmsg.success("自动填入访问码");
element.value = netDiskInfo.accessCode;
utils.dispatchEvent(element, "input");
document.querySelector(
"#js-share_code div.form-decode div.submit a"
).click();
});
}
};
const NetDiskAutoFillAccessCode = {
key: "tempNetDiskInfo",
$data: {
/**
* 当前的网盘数据
*/
netDiskInfo: null,
/**
* 自动输入访问码是否开启
*/
get enable() {
return NetDiskGlobalData.features.autoFillAccessCode.value;
}
},
/**
* 初始化
*/
init() {
this.$data.netDiskInfo = this.getValue();
if (!this.$data.netDiskInfo) {
return;
}
if (!this.$data.enable) {
return;
}
if (utils.isNull(this.$data.netDiskInfo.accessCode)) {
return;
}
if (this.$data.netDiskInfo.netDiskName === "baidu" && this.$data.netDiskInfo.shareCode.startsWith("1")) {
if (!window.location.href.includes(
this.$data.netDiskInfo.shareCode.slice(
1,
this.$data.netDiskInfo.shareCode.length
)
)) {
return;
}
} else if (
// 网址路径中不包含shareCode的话,就跳过
!window.location.href.includes(this.$data.netDiskInfo.shareCode)
) {
return;
}
if (this.$data.netDiskInfo.netDiskName in NetDiskAutoFillAccessCode.netDisk) {
let autoFillFn = NetDiskAutoFillAccessCode.netDisk[this.$data.netDiskInfo.netDiskName];
if (typeof autoFillFn === "function") {
autoFillFn(this.$data.netDiskInfo);
} else {
log.warn(
"自动填写访问码失败:" + this.$data.netDiskInfo.netDiskName + ",原因:该网盘未适配"
);
}
} else {
log.error("网盘名未找到,跳过自动填写:" + this.$data.netDiskInfo);
}
},
netDisk: {
/**
* 百度网盘
*/
baidu: NetDiskAutoFillAccessCode_baidu,
/**
* 蓝奏云
*/
lanzou: NetDiskAutoFillAccessCode_lanzou,
/**
* 天翼云
*/
tianyiyun: NetDiskAutoFillAccessCode_tianyiyun,
/**
* 中国移动云盘
*/
hecaiyun: NetDiskAutoFillAccessCode_hecaiyun,
/**
* 阿里云盘
*/
aliyun: NetDiskAutoFillAccessCode_aliyun,
/**
* 文叔叔
* 暂时没找到有密码的链接
*/
wenshushu: () => {
},
/**
* 奶牛
* 暂时没找到有密码的链接
*/
nainiu: () => {
},
/**
* 123云盘
*/
_123pan: NetDiskAutoFillAccessCode_123pan,
/**
* 腾讯微云
*/
weiyun: NetDiskAutoFillAccessCode_weiyun,
/**
* 迅雷
*/
xunlei: NetDiskAutoFillAccessCode_xunlei,
/**
* 115网盘
*/
_115pan: NetDiskAutoFillAccessCode_115pan,
/**
* 城通网盘
*/
chengtong: NetDiskAutoFillAccessCode_chengtong,
/**
* 夸克网盘
*/
kuake: NetDiskAutoFillAccessCode_kuake,
/**
* 坚果云
* 暂时没找到有密码的链接
*/
jianguoyun: () => {
},
/**
* OneDrive
* 暂时没找到有密码的链接
*/
onedrive: () => {
}
},
/**
* 设置值
* @param value
*/
setValue(value) {
_GM_setValue(this.key, value);
},
/**
* 获取值
*/
getValue() {
return _GM_getValue(this.key);
}
};
const NetDiskAuthorization_Lanzouyx = function() {
return;
};
const NetDiskRuleData = {
/** innerText的提取码间隔 */
matchRange_text: {
/**
* 提取码间隔前的字符长度
* @param key 规则键名
* @param defaultValue 默认值: 20
*/
before(key, defaultValue = 20) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.matchRange_text.before(key),
defaultValue
);
return parseInt(panelData.value.toString());
},
/**
* 提取码间隔后的字符长度
* @param key 规则键名
* @param defaultValue 默认值: 10
*/
after(key, defaultValue = 10) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.matchRange_text.after(key),
defaultValue
);
return parseInt(panelData.value.toString());
}
},
/** innerHTML的提取码间隔 */
matchRange_html: {
/**
* 提取码间隔前的字符长度
* @param key 规则键名
* @param defaultValue 默认值: 100
*/
before(key, defaultValue = 100) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.matchRange_html.before(key),
defaultValue
);
return parseInt(panelData.value.toString());
},
/**
* 提取码间隔后的字符长度
* @param key 规则键名
* @param defaultValue 默认值: 15
*/
after(key, defaultValue = 15) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.matchRange_html.after(key),
defaultValue
);
return parseInt(panelData.value.toString());
}
},
/** 功能 */
function: {
/**
* 是否启用该规则
* @param key 规则键名
* @param defaultValue
*/
enable(key, defaultValue = true) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.function.enable(key),
defaultValue
);
return Boolean(panelData.value);
},
/**
* 点击动作
* @param key 规则键名
* @param defaultValue
*/
linkClickMode(key, defaultValue = "copy") {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.function.linkClickMode(key),
defaultValue
);
return panelData.value;
},
/**
* 是否进行校验链接有效性
* @param key 规则键名
* @param defaultValue
*/
checkLinkValidity(key, defaultValue = false) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.function.checkLinkValidity(key),
defaultValue
);
return Boolean(panelData.value);
},
/**
* 是否添加验证结果图标悬停提示
* @param key
* @param defaultValue
*/
checkLinlValidityHoverTip(key, defaultValue = true) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.function.checkLinkValidityHoverTip(key),
defaultValue
);
return Boolean(panelData.value);
}
},
linkClickMode_openBlank: {
/**
* 跳转时复制访问码
* @param key 规则键名
* @param defaultValue
*/
openBlankWithCopyAccessCode(key, defaultValue = false) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.linkClickMode_openBlank.openBlankWithCopyAccessCode(
key
),
defaultValue
);
return Boolean(panelData.value);
}
},
schemeUri: {
/**
* 是否启用
* @param key 规则键名
* @param defaultValue
*/
enable(key, defaultValue = false) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.schemeUri.enable(key),
defaultValue
);
return Boolean(panelData.value);
},
/**
* 转发直链(解析出的链接)
* @param key 规则键名
* @param defaultValue
*/
isForwardLinearChain(key, defaultValue = false) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.schemeUri.isForwardLinearChain(key),
defaultValue
);
return Boolean(panelData.value);
},
/**
* 转发新标签页链接
* @param key 规则键名
* @param defaultValue
*/
isForwardBlankLink(key, defaultValue = false) {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.schemeUri.isForwardBlankLink(key),
defaultValue
);
return Boolean(panelData.value);
},
/**
* Uri链接
* @param key 规则键名
* @param defaultValue
*/
uri(key, defaultValue = "") {
const panelData = GeneratePanelData(
NetDiskRuleDataKEY.schemeUri.uri(key),
defaultValue
);
return panelData.value;
}
}
};
const _123pan_Link_Host_Pattern = "(123pan|123865|123684|123652|123912).com";
const NetDiskRule_123pan = {
/** 规则 */
rule: [
{
link_innerText: `${_123pan_Link_Host_Pattern}/s/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `${_123pan_Link_Host_Pattern}/s/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: new RegExp(
`${_123pan_Link_Host_Pattern}/s/([a-zA-Z0-9_-]{8,14})`,
"gi"
),
shareCodeNeedRemoveStr: new RegExp(
`${_123pan_Link_Host_Pattern}/s/`,
"gi"
),
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "123pan.com/s/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://123pan.com/s/{#shareCode#}",
copyUrl: "https://123pan.com/s/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "123盘",
key: "_123pan",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
},
parseFile: {
enable: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardLinearChain: true,
isForwardBlankLink: true,
uri: ""
}
}
}
};
const NetDiskAuthorization_123pan_Authorization = {
KEY: "_123pan_User_Authorization",
set(value) {
_GM_setValue(this.KEY, value);
},
get() {
return _GM_getValue(this.KEY);
}
};
const NetDiskAuthorization_123pan = function() {
if (window.location.hostname !== "www.123pan.com") {
return;
}
if (NetDiskRuleData.function.linkClickMode(NetDiskRule_123pan.setting.key) !== "parseFile") {
return;
}
let authorToken = _unsafeWindow.localStorage.getItem("authorToken");
if (utils.isNull(authorToken)) {
return;
}
authorToken = authorToken.replace(/^\"/, "").replace(/\"$/, "");
log.success("获取123网盘已登录用户的authorToken值👇");
log.success(authorToken);
NetDiskAuthorization_123pan_Authorization.set(authorToken);
};
const NetDiskAuthorization = {
/**
* 运行于ready
*/
init() {
Object.keys(NetDiskAuthorization.netDisk).forEach((keyName) => {
this.netDisk[keyName]();
});
},
netDisk: {
/**
* 123网盘,一般用于>100MB的文件直链获取
*/
_123pan: NetDiskAuthorization_123pan,
/**
* 蓝奏优选
*/
lanzouyx: NetDiskAuthorization_Lanzouyx
}
};
const NetDiskFilterScheme = {
protocol: "jumpwsv",
pathname: "go",
/**
* 把链接转为scheme的uri链接
* @param key 规则名
* @param intentData 需要处理的数据
*/
parseDataToSchemeUri(key, intentData) {
let isEnable = this.isEnableForward(key);
if (!isEnable) {
return intentData;
}
let schemeUri = NetDiskRuleData.schemeUri.uri(key);
if (utils.isNull(schemeUri)) {
schemeUri = this.getSchemeUri(this.get1DMSchemeUriOption(intentData));
}
if (schemeUri.startsWith(this.protocol)) {
intentData = intentData.replace(/&/g, "{-and-}");
intentData = intentData.replace(/#/g, "{-number-}");
}
schemeUri = NetDiskRuleUtils.replaceParam(schemeUri, {
intentData
});
return schemeUri;
},
/**
* 是否启用转发
* @param key
* @returns
*/
isEnableForward(key) {
return NetDiskRuleData.schemeUri.enable(key);
},
/**
* 是否转发下载链接
* @param key
*/
isForwardDownloadLink(key) {
return this.isEnableForward(key) && NetDiskRuleData.schemeUri.isForwardLinearChain(key);
},
/**
* 是否转发新标签页的链接
* @param key
*/
isForwardBlankLink(key) {
return this.isEnableForward(key) && NetDiskRuleData.schemeUri.isForwardBlankLink(key);
},
/**
* 获取转发的uri链接
* @param option
*/
getSchemeUri(option) {
return `${this.protocol}://${this.pathname}?${utils.toSearchParamsStr(
option
)}`;
},
/**
* 获取1dm的intent的配置
* @param intentData
*/
get1DMSchemeUriOption(intentData = "") {
return {
package: "idm.internet.download.manager.plus",
activity: "idm.internet.download.manager.UrlHandlerDownloader",
intentAction: "android.intent.action.VIEW",
intentData,
intentExtra: ""
};
}
};
class NetDiskParseObject {
constructor() {
/** 所在规则的下标 */
__publicField(this, "netDiskIndex", 0);
/** 分享码 */
__publicField(this, "shareCode", "");
/** 提取码 */
__publicField(this, "accessCode", "");
}
}
class NetDiskParse_123pan extends NetDiskParseObject {
constructor() {
super(...arguments);
__publicField(this, "panelList", []);
__publicField(this, "Authorization", "");
__publicField(this, "code", {
5113: "您今日下载流量已超出10GB限制,购买VIP会员即可体验无限流量下载",
5103: "分享码错误或者分享地址错误",
5104: "分享已过期",
"-1000": "获取出错",
"-2000": "请求异常",
"-3000": "请求意外中止",
"-4000": "请求超时",
104: "文件已失效"
});
__publicField(this, "Headers", {
"user-agent": "123pan/v2.4.0(Android_7.1.2;Xiaomi)",
platform: "android",
"app-version": "61",
"x-app-version": "2.4.0"
});
}
async init(netDiskIndex, shareCode, accessCode) {
const that = this;
log.info(netDiskIndex, shareCode, accessCode);
that.netDiskIndex = netDiskIndex;
that.shareCode = shareCode;
that.accessCode = accessCode;
that.panelList = [];
that.Authorization = NetDiskAuthorization_123pan_Authorization.get();
let checkLinkValidityStatus = await that.checkLinkValidity();
if (!checkLinkValidityStatus) {
return;
}
let infoLists = await that.getFiles();
if (!infoLists) {
return;
}
if (infoLists.length === 1 && infoLists[0]["Type"] == 0) {
let fileInfo = infoLists[0];
if (fileInfo["Status"] == 104) {
Qmsg.error("文件已失效");
return;
}
let downloadUrl = fileInfo["DownloadUrl"];
let fileSize = "";
if (downloadUrl === "") {
let downloadInfo = await that.getFileDownloadInfo(
fileInfo["Etag"],
fileInfo["FileId"],
fileInfo["S3KeyFlag"],
that.shareCode,
fileInfo["Size"]
);
if (downloadInfo && downloadInfo["code"] === 0) {
downloadUrl = downloadInfo["data"]["DownloadURL"];
if (NetDiskFilterScheme.isForwardDownloadLink("_123pan")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"_123pan",
downloadUrl
);
}
fileSize = utils.formatByteToSize(fileInfo["Size"]);
} else if (downloadInfo && downloadInfo["code"] === 401) {
downloadUrl = "javascript:;";
fileSize = "请登录后下载";
} else {
downloadUrl = "javascript:;";
fileSize = "获取下载链接失败";
}
} else {
if (NetDiskFilterScheme.isForwardDownloadLink("_123pan")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"_123pan",
downloadUrl
);
}
fileSize = utils.formatByteToSize(fileInfo["Size"]);
}
let fileUploadTime = new Date(fileInfo["CreateAt"]).getTime();
let fileLatestTime = new Date(fileInfo["UpdateAt"]).getTime();
fileUploadTime = utils.formatTime(fileUploadTime);
fileLatestTime = utils.formatTime(fileLatestTime);
NetDiskUI.staticView.oneFile({
title: "123盘单文件直链",
fileName: fileInfo["FileName"],
fileSize,
downloadUrl,
fileUploadTime,
fileLatestTime
});
} else {
Qmsg.info("正在递归文件");
let QmsgLoading = Qmsg.loading(`正在解析多文件中,请稍后...`);
let folderInfoList = that.getFolderInfo(infoLists, 0);
QmsgLoading.close();
log.info("递归完毕");
NetDiskUI.staticView.moreFile("123盘文件解析", folderInfoList);
}
}
/**
* 校验链接有效性
*/
async checkLinkValidity() {
const that = this;
Qmsg.info("正在校验链接有效性");
let url = `https://www.123pan.com/s/${that.shareCode}`;
let getResp = await httpx.get({
url,
headers: {
"User-Agent": utils.getRandomPCUA(),
Referer: "https://www.123pan.com"
}
});
log.info(getResp);
if (!getResp.status) {
return false;
}
let respData = getResp.data;
let g_initialPropsMatch = respData.responseText.match(
/window.g_initialProps[\s]*=[\s]*\{(.+?)\};/s
);
if (g_initialPropsMatch) {
log.info(g_initialPropsMatch);
let g_initialProps = utils.toJSON(
`{${g_initialPropsMatch[g_initialPropsMatch.length - 1]}}`
);
log.info(g_initialProps);
if (g_initialProps.res.code !== 0) {
Qmsg.error(g_initialProps.res.message);
return false;
}
let HasPwd = g_initialProps.res.data.HasPwd;
if (HasPwd && (that.accessCode == void 0 || that.accessCode === "")) {
Qmsg.error("密码缺失!");
NetDiskUI.newAccessCodeView(
"密码缺失",
"_123pan",
that.netDiskIndex,
that.shareCode,
that.accessCode,
(option) => {
that.init(that.netDiskIndex, that.shareCode, option.accessCode);
}
);
} else {
return true;
}
} else {
Qmsg.error("校验链接-获取初始化内容失败");
}
}
/**
* 获取文件
* @param parentFileId
*/
async getFiles(parentFileId = 0) {
const that = this;
const getData = {
limit: 100,
next: 1,
orderBy: "share_id",
orderDirection: "desc",
shareKey: that.shareCode,
SharePwd: that.accessCode,
ParentFileId: parentFileId,
Page: 1
};
let url = `https://www.123pan.com/b/api/share/get?${utils.toSearchParamsStr(
getData
)}`;
let getResp = await httpx.get({
url,
headers: {
Accept: "*/*",
Referer: `https://www.123pan.com/s/${that.shareCode}`,
...that.Headers
}
});
log.info(getResp);
if (!getResp.status) {
return;
}
let respData = getResp.data;
let json_data = utils.toJSON(respData.responseText);
if (json_data["code"] === 0) {
let infoList = json_data["data"]["InfoList"];
return infoList;
} else if (json_data["code"] === 5103) {
NetDiskUI.newAccessCodeView(
void 0,
"_123pan",
that.netDiskIndex,
that.shareCode,
that.accessCode,
(option) => {
that.init(that.netDiskIndex, that.shareCode, option.accessCode);
}
);
} else if (that.code[json_data["code"]]) {
Qmsg.error(that.code[json_data["code"]]);
} else if ("message" in json_data) {
Qmsg.error(json_data["message"]);
} else {
Qmsg.error("123盘:未知的JSON格式");
}
}
/**
* 递归算法使用的请求
* @param parentFileId
*/
async getFilesByRec(parentFileId) {
const that = this;
let getResp = await httpx.get({
url: `https://www.123pan.com/b/api/share/get?limit=100&next=1&orderBy=share_id&orderDirection=desc&shareKey=${that.shareCode}&SharePwd=${that.accessCode}&ParentFileId=${parentFileId}&Page=1`,
headers: {
Accept: "*/*",
Referer: `https://www.123pan.com/s/${that.shareCode}`,
...that.Headers
}
});
if (!getResp.status) {
return;
}
let respData = getResp.data;
log.info(respData);
let jsonData = utils.toJSON(respData.responseText);
if (jsonData["code"] == 0) {
return jsonData["data"]["InfoList"];
}
}
/**
* 获取文件夹信息
* @param infoList
*/
getFolderInfo(infoList, index) {
const that = this;
let folderInfoList = [];
let tempFolderInfoList = [];
let tempFolderFileInfoList = [];
infoList.forEach((item) => {
if (item.Type) {
tempFolderInfoList.push({
fileName: item.FileName,
fileSize: 0,
fileType: "",
createTime: new Date(item.CreateAt).getTime(),
latestTime: new Date(item.UpdateAt).getTime(),
isFolder: true,
index,
async clickEvent() {
let resultFileInfoList = await that.getFilesByRec(item["FileId"]);
if (resultFileInfoList) {
return that.getFolderInfo(resultFileInfoList, index + 1);
} else {
return [];
}
}
});
} else {
tempFolderFileInfoList.push({
fileName: item.FileName,
fileSize: item.Size,
fileType: "",
createTime: new Date(item.CreateAt).getTime(),
latestTime: new Date(item.UpdateAt).getTime(),
isFolder: false,
index,
async clickEvent() {
if (item.Status == 104) {
Qmsg.error("文件已失效");
} else if (!Boolean(item.DownloadUrl)) {
let downloadInfo = await that.getFileDownloadInfo(
item["Etag"],
item["FileId"],
item["S3KeyFlag"],
that.shareCode,
item["Size"]
);
if (downloadInfo && downloadInfo["code"] === 0) {
return {
url: downloadInfo["data"]["DownloadURL"],
autoDownload: true,
mode: "aBlank"
};
} else if (downloadInfo && downloadInfo["code"] === 401) {
Qmsg.error("请登录后下载");
} else {
Qmsg.error((downloadInfo == null ? void 0 : downloadInfo["message"]) || "获取下载链接失败");
}
} else {
let downloadUrl = item.DownloadUrl;
if (NetDiskFilterScheme.isForwardDownloadLink("_123pan")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"_123pan",
downloadUrl
);
}
return {
url: downloadUrl,
autoDownload: true,
mode: "aBlank"
};
}
}
});
}
});
tempFolderInfoList.sort(
(a, b) => a["fileName"].localeCompare(b["fileName"])
);
tempFolderFileInfoList.sort(
(a, b) => a["fileName"].localeCompare(b["fileName"])
);
folderInfoList = folderInfoList.concat(tempFolderInfoList);
folderInfoList = folderInfoList.concat(tempFolderFileInfoList);
return folderInfoList;
}
/**
* 获取单文件下载链接
* 123云盘新增了下载验证
* @param Etag
* @param FileID
* @param S3keyFlag
* @param ShareKey
* @param Size
*/
async getFileDownloadInfo(Etag, FileID, S3keyFlag, ShareKey, Size) {
const that = this;
let authK_V = that.getFileDownloadAuth();
let headers = {
// "App-Version": "3",
// Platform: "web",
"Content-Type": "application/json;charset=UTF-8",
Host: "www.123pan.com",
Accept: "*/*",
Referer: "https://www.123pan.com/s/" + ShareKey,
Origin: "https://www.123pan.com",
...that.Headers
};
if (that.Authorization) {
Reflect.set(headers, "Authorization", "Bearer " + that.Authorization);
}
log.success("获取下载链接加密参数:" + authK_V);
let postResp = await httpx.post(
`https://www.123pan.com/a/api/share/download/info?${authK_V[0]}=${authK_V[1]}`,
{
data: JSON.stringify({
Etag,
FileID,
S3keyFlag,
ShareKey,
Size
}),
responseType: "json",
headers
}
);
if (!postResp.status) {
return;
}
let postData = postResp.data;
let jsonData = utils.toJSON(postData.responseText);
log.info(jsonData);
if (jsonData["code"] == 0) {
jsonData["data"]["DownloadURL"] = that.decodeDownloadUrl(
jsonData["data"]["DownloadURL"]
);
return jsonData;
} else {
return {
code: jsonData["code"],
message: jsonData["message"]
};
}
}
/**
* 获取单文件下载链接的加密参数
* 感谢:https://github.com/qaiu/netdisk-fast-download/
*/
getFileDownloadAuth() {
function encry_time(param) {
var param_time, param_other = arguments["length"] > 2 && void 0 !== arguments[2] ? arguments[2] : 8;
if (0 === arguments["length"]) return void 0;
"object" === typeof param ? param_time = param : (10 === ("" + param)["length"] && (param = 1e3 * parseInt(param)), param_time = new Date(param));
var param_timezoneoffset = param + 6e4 * new Date(param)["getTimezoneOffset"](), param_time_n = param_timezoneoffset + 36e5 * param_other;
return param_time = new Date(param_time_n), {
y: param_time["getFullYear"](),
m: param_time["getMonth"]() + 1 < 10 ? "0" + (param_time["getMonth"]() + 1) : param_time["getMonth"]() + 1,
d: param_time["getDate"]() < 10 ? "0" + param_time["getDate"]() : param_time["getDate"](),
h: param_time["getHours"]() < 10 ? "0" + param_time["getHours"]() : param_time["getHours"](),
f: param_time["getMinutes"]() < 10 ? "0" + param_time["getMinutes"]() : param_time["getMinutes"]()
};
}
function encry_join(param) {
for (var a = arguments["length"] > 1 && void 0 !== arguments[1] ? arguments[1] : 10, funcRun = function() {
for (var b, c = [], d = 0; d < 256; d++) {
b = d;
for (var index = 0; index < 8; index++)
b = 1 & b ? 3988292384 ^ b >>> 1 : b >>> 1;
c[d] = b;
}
return c;
}, _funcRun_ = funcRun(), _param = param, _param_1 = -1, _param_0 = 0; _param_0 < _param["length"]; _param_0++)
_param_1 = _param_1 >>> 8 ^ _funcRun_[255 & (_param_1 ^ _param.charCodeAt(_param_0))];
return _param_1 = (-1 ^ _param_1) >>> 0, _param_1.toString(a);
}
function getSign(urlPath) {
var param_web = "web";
var param_type = 3;
var param_time = Math.round(
((/* @__PURE__ */ new Date()).getTime() + 60 * (/* @__PURE__ */ new Date()).getTimezoneOffset() * 1e3 + 288e5) / 1e3
).toString();
var key = "a,d,e,f,g,h,l,m,y,i,j,n,o,p,k,q,r,s,t,u,b,c,v,w,s,z";
var randomRoundNum = Math["round"](1e7 * Math["random"]());
var number_split;
var time_a;
var time_y;
var time_m;
var time_d;
var time_h;
var time_f;
var time_array;
var time_push;
for (var number_item in number_split = key.split(","), time_a = encry_time(param_time), // @ts-ignore
time_y = time_a["y"], // @ts-ignore
time_m = time_a["m"], // @ts-ignore
time_d = time_a["d"], // @ts-ignore
time_h = time_a["h"], // @ts-ignore
time_f = time_a["f"], time_array = [time_y, time_m, time_d, time_h, time_f].join(""), time_push = [], time_array)
time_push["push"](number_split[Number(time_array[number_item])]);
var param_no;
var param_join_s;
return (
// @ts-ignore
param_no = encry_join(time_push["join"]("")), param_join_s = encry_join(
""["concat"](param_time, "|")[
// @ts-ignore
"concat"
// @ts-ignore
](randomRoundNum, "|")["concat"](urlPath, "|")["concat"](param_web, "|")[
// @ts-ignore
"concat"
// @ts-ignore
](param_type, "|")["concat"](param_no)
), [
param_no,
""["concat"](param_time, "-")[
// @ts-ignore
"concat"
// @ts-ignore
](randomRoundNum, "-")["concat"](param_join_s)
]
);
}
return getSign("/a/api/share/download/info");
}
/**
* 将直链的param参数解析成真正的直链
* @param url
*/
decodeDownloadUrl(url) {
if (url === "") {
return "";
}
return url;
}
}
class NetDiskParse_Aliyun extends NetDiskParseObject {
constructor() {
super(...arguments);
__publicField(this, "X_Share_Token_Data", {
expire_time: "2000-01-01T00:00:00.000Z",
expires_in: 7200,
share_token: ""
});
/**
* header请求头 X-Device-Id
*/
__publicField(this, "X_Device_Id", null);
/**
* header请求头 X-Canary
*/
__publicField(this, "X_Canary", "client=web,app=share,version=v2.3.1");
}
/**
* 入口
* @param netDiskIndex 网盘名称索引下标
* @param shareCode
* @param accessCode
*/
async init(netDiskIndex, shareCode, accessCode) {
const that = this;
log.info(netDiskIndex, shareCode, accessCode);
that.netDiskIndex = netDiskIndex;
that.shareCode = shareCode;
that.accessCode = accessCode;
that.X_Device_Id = that.get_X_Device_Id();
log.info("生成X_Device_Id:" + that.X_Device_Id);
if (globalThis.location.hostname !== "www.aliyundrive.com" && globalThis.location.hostname !== "www.alipan.com") {
let url = NetDiskLinkClickModeUtils.getBlankUrl(
"aliyun",
that.netDiskIndex,
that.shareCode,
that.accessCode
);
let $QmsgErrorTip = Qmsg.error(
`请在阿里云盘页面解析,点我前往`,
{
html: true,
timeout: 1e4
}
);
domUtils.on(
$QmsgErrorTip.$Qmsg.querySelector("a[href]"),
"click",
void 0,
(event) => {
utils.preventEvent(event);
NetDiskLinkClickMode.openBlank(
url,
"aliyun",
that.netDiskIndex,
that.shareCode,
that.accessCode
);
}
);
return;
}
let detail = await this.list_by_share(shareCode, "root");
if (!detail) {
return;
}
Qmsg.info("正在解析链接");
let QmsgLoading = Qmsg.loading(`正在解析多文件中,请稍后...`);
let folderInfoList = that.getFolderInfo(detail, 0);
QmsgLoading.close();
log.info("解析完毕");
NetDiskUI.staticView.moreFile("阿里云盘文件解析", folderInfoList);
}
/**
* 弹窗使用-获取文件夹信息
* @param infoList
*/
getFolderInfo(infoList, index = 0) {
const that = this;
let folderInfoList = [];
let tempFolderInfoList = [];
let tempFolderFileInfoList = [];
infoList.forEach((item) => {
if (item.type !== "folder") {
tempFolderFileInfoList.push({
fileName: item.name,
fileSize: item.size,
fileType: item.file_extension,
createTime: new Date(item.created_at).getTime(),
latestTime: new Date(item.updated_at).getTime(),
isFolder: false,
index,
async clickEvent() {
let fileDownloadUrl = await that.get_share_link_download_url(
item.share_id,
item.file_id
);
if (!fileDownloadUrl) {
return;
}
let schemeDownloadUrl = fileDownloadUrl;
if (NetDiskFilterScheme.isForwardDownloadLink("aliyun")) {
schemeDownloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"aliyun",
schemeDownloadUrl
);
}
return {
autoDownload: true,
mode: "aBlank",
url: schemeDownloadUrl
};
}
});
} else {
tempFolderInfoList.push({
fileName: item.name,
fileSize: 0,
fileType: "",
createTime: item.created_at,
latestTime: item.updated_at,
isFolder: true,
index,
async clickEvent() {
let newDetail = await that.list_by_share(
item.share_id,
item.file_id
);
if (newDetail) {
return that.getFolderInfo(newDetail, index + 1);
} else {
return [];
}
}
});
}
});
tempFolderInfoList.sort(
(a, b) => a["fileName"].localeCompare(b["fileName"])
);
tempFolderFileInfoList.sort(
(a, b) => a["fileName"].localeCompare(b["fileName"])
);
folderInfoList = folderInfoList.concat(tempFolderInfoList);
folderInfoList = folderInfoList.concat(tempFolderFileInfoList);
log.info("getFilesInfoByRec", folderInfoList);
return folderInfoList;
}
/**
* 列出文件列表
* @param share_id
* @param parent_file_id 父项,根是root
* @param order_by 根据xxx排序
* @param order_direction 排序规则(升序/降序)
*/
async list_by_share(share_id, parent_file_id, order_by = "name", order_direction = "DESC") {
const that = this;
let postResp = await httpx.post(
"https://api.aliyundrive.com/adrive/v2/file/list_by_share",
{
data: JSON.stringify({
share_id,
parent_file_id,
limit: 20,
image_thumbnail_process: "image/resize,w_256/format,jpeg",
image_url_process: "image/resize,w_1920/format,jpeg/interlace,1",
video_thumbnail_process: "video/snapshot,t_1000,f_jpg,ar_auto,w_256",
order_by,
order_direction
}),
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json",
Origin: "https://www.aliyundrive.com",
Referer: "https://www.aliyundrive.com/",
"X-Canary": that.X_Canary,
"X-Device-Id": that.X_Device_Id,
"X-Share-Token": await that.get_X_Share_Token(
that.shareCode,
that.accessCode
),
"User-Agent": utils.getRandomPCUA()
},
allowInterceptConfig: false,
onerror() {
}
}
);
if (!postResp.status) {
that.handle_request_error(postResp);
return;
}
let data = utils.toJSON(postResp.data.responseText);
log.info("列出文件列表:", data);
return data["items"];
}
/**
* 获取文件的下载链接
* @param share_id
* @param file_id
*/
async get_share_link_download_url(share_id, file_id) {
const that = this;
let postResp = await httpx.post(
"https://api.aliyundrive.com/v2/file/get_share_link_download_url",
{
data: JSON.stringify({
expire_sec: 600,
file_id,
share_id
}),
headers: {
Accept: "application/json, text/plain, */*",
Origin: "https://www.aliyundrive.com",
Referer: "https://www.aliyundrive.com/",
"Content-Type": "application/json;charset=UTF-8",
Authorization: "Bearer " + that.getAuthorization(),
"X-Share-Token": await that.get_X_Share_Token(
that.shareCode,
that.accessCode
),
"User-Agent": utils.getRandomPCUA()
},
responseType: "arraybuffer",
allowInterceptConfig: false,
onerror() {
}
}
);
if (!postResp.status) {
that.handle_request_error(postResp);
return;
}
let data = utils.toJSON(postResp.data.responseText);
log.info("获取文件的下载链接:", data);
return data["download_url"];
}
/**
* 处理请求的错误
* @param postResp
*/
handle_request_error(postResp) {
log.error(postResp);
let errData = utils.toJSON(postResp.data.responseText);
if (errData["message"] == "") {
Qmsg.error(postResp.msg);
} else {
Qmsg.error(errData["message"]);
}
}
/**
* 获取用户鉴权值
* 来源:localStorage => token.access_token
*/
getAuthorization() {
let token = _unsafeWindow.localStorage.getItem("token");
if (utils.isNotNull(token) && token != null) {
let tokenJSON = utils.toJSON(token);
let access_token = tokenJSON["access_token"];
log.success("获取阿里云盘的access_token:", access_token);
return access_token;
} else {
log.error("获取access_token失败,请先登录账号!");
Qmsg.error("获取access_token失败,请先登录账号!");
}
}
/**
* 获取header请求头 X-Share-Token
* 来源:localStorage => shareToken.share_token
* @param share_id
* @param share_pwd
*/
async get_X_Share_Token(share_id, share_pwd) {
const that = this;
if (/* @__PURE__ */ new Date() < new Date(that.X_Share_Token_Data.expire_time)) {
return that.X_Share_Token_Data.share_token;
}
let postResp = await httpx.post(
"https://api.aliyundrive.com/v2/share_link/get_share_token",
{
data: JSON.stringify({
share_id,
share_pwd
}),
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json",
Origin: "https://www.aliyundrive.com",
Referer: "https://www.aliyundrive.com/",
"X-Canary": that.X_Canary,
"X-Device-Id": that.X_Device_Id,
"User-Agent": utils.getRandomPCUA()
},
allowInterceptConfig: false,
onerror() {
}
}
);
if (!postResp.status) {
that.handle_request_error(postResp);
return;
}
let data = utils.toJSON(postResp.data.responseText);
that.X_Share_Token_Data = data;
log.info("获取share_token:", that.X_Share_Token_Data);
return that.X_Share_Token_Data["share_token"];
}
/**
* 获取header请求头 X-Device-Id
*/
get_X_Device_Id() {
for (var alipan_device_id_pattern = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i, alipan_s = [], alipan_l = 0; alipan_l < 256; ++alipan_l)
alipan_s.push((alipan_l + 256).toString(16).substr(1));
function alipan_o() {
return crypto.getRandomValues(new Uint8Array(16));
}
var alipan_c = function(args_e) {
var second_arg = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0, devices_id_string = (alipan_s[args_e[second_arg + 0]] + alipan_s[args_e[second_arg + 1]] + alipan_s[args_e[second_arg + 2]] + alipan_s[args_e[second_arg + 3]] + "-" + alipan_s[args_e[second_arg + 4]] + alipan_s[args_e[second_arg + 5]] + "-" + alipan_s[args_e[second_arg + 6]] + alipan_s[args_e[second_arg + 7]] + "-" + alipan_s[args_e[second_arg + 8]] + alipan_s[args_e[second_arg + 9]] + "-" + alipan_s[args_e[second_arg + 10]] + alipan_s[args_e[second_arg + 11]] + alipan_s[args_e[second_arg + 12]] + alipan_s[args_e[second_arg + 13]] + alipan_s[args_e[second_arg + 14]] + alipan_s[args_e[second_arg + 15]]).toLowerCase();
if (!function(e) {
return "string" == typeof e && alipan_device_id_pattern.test(e);
}(devices_id_string))
throw TypeError("Stringified UUID is invalid");
return devices_id_string;
}, alipan_u = function(args_e, args_t, args_n) {
var randomValue = (args_e = args_e || {}).random || (args_e.rng || alipan_o)();
if (randomValue[6] = 15 & randomValue[6] | 64, randomValue[8] = 63 & randomValue[8] | 128, args_t) ;
return alipan_c(randomValue);
};
return alipan_u();
}
}
class NetDiskParse_Baidu extends NetDiskParseObject {
/**
* 入口
* @param netDiskIndex 网盘名称索引下标
* @param shareCode
* @param accessCode
*/
init(netDiskIndex, shareCode, accessCode) {
log.info(netDiskIndex, shareCode, accessCode);
this.netDiskIndex = netDiskIndex;
this.shareCode = shareCode;
this.accessCode = accessCode;
let url = _GM_getValue("baidu-baiduwp-php-url");
let postForm = _GM_getValue("baidu-baiduwp-php-post-form");
let enableCopy = _GM_getValue("baidu-baiduwp-php-copy-url");
if (!url) {
Qmsg.error("请先在设置中配置百度网盘-网址");
return void 0;
}
if (!postForm) {
Qmsg.error("请先在设置中配置百度网盘-表单参数");
return void 0;
}
postForm = NetDiskRuleUtils.replaceParam(postForm, {
shareCode,
accessCode
});
let formElement = document.createElement("form");
let formData = {};
let urlParams = new URLSearchParams(postForm);
formElement.action = url;
formElement.method = "post";
formElement.style.display = "none";
formElement.target = "_blank";
for (let [key, value] of urlParams) {
let textAreaElement = document.createElement("textarea");
textAreaElement.name = key;
textAreaElement.value = value;
formElement.appendChild(textAreaElement);
formData[key] = value;
}
log.info("表单数据", formData);
document.body.appendChild(formElement);
log.info("访问网址", url);
if (enableCopy) {
NetDiskLinkClickMode.copy(
"baidu",
netDiskIndex,
shareCode,
accessCode,
"1.5秒后跳转至解析站"
);
setTimeout(() => {
formElement.submit();
}, 1500);
} else {
formElement.submit();
}
}
}
const indexCSS$4 = '.netdisk-url-box {\r\n border-bottom: 1px solid #e4e6eb;\r\n}\r\n.netdisk-url-div {\r\n display: flex;\r\n align-items: center;\r\n width: 100%;\r\n padding: 5px 0px 5px 0px;\r\n}\r\n.netdisk-icon {\r\n display: contents;\r\n}\r\n.netdisk-icon .netdisk-icon-img {\r\n cursor: pointer;\r\n width: 28px;\r\n height: 28px;\r\n min-width: 28px;\r\n min-height: 28px;\r\n font-size: 0.8em;\r\n margin: 0px 10px;\r\n}\r\n.netdisk-url-div .netdisk-icon,\r\n.netdisk-url-div .netdisk-status {\r\n flex: 0 0 auto;\r\n}\r\n.netdisk-url-div .netdisk-url {\r\n flex: 1;\r\n}\r\n.netdisk-icon .netdisk-icon-img {\r\n border-radius: 10px;\r\n box-shadow: 0 0.3px 0.6px rgb(0 0 0 / 6%), 0 0.7px 1.3px rgb(0 0 0 / 8%),\r\n 0 1.3px 2.5px rgb(0 0 0 / 10%), 0 2.2px 4.5px rgb(0 0 0 / 12%),\r\n 0 4.2px 8.4px rgb(0 0 0 / 14%), 0 10px 20px rgb(0 0 0 / 20%);\r\n}\r\n.netdisk-status[data-check-failed] {\r\n padding: 5px 5px;\r\n}\r\n.netdisk-url {\r\n padding: 5px 5px;\r\n}\r\n.netdisk-url a {\r\n color: #ff4848 !important;\r\n min-height: 28px;\r\n overflow-x: hidden;\r\n overflow-y: auto;\r\n font-size: 0.8em;\r\n border: none;\r\n display: flex;\r\n align-items: center;\r\n width: 100%;\r\n height: 100%;\r\n padding: 0px;\r\n word-break: break-word;\r\n text-align: left;\r\n}\r\n.netdisk-status {\r\n display: none;\r\n}\r\n.netdisk-status[data-check-valid] {\r\n display: flex;\r\n align-items: center;\r\n width: 15px;\r\n height: 15px;\r\n}\r\n\r\n.netdisk-status[data-check-valid="failed"] {\r\n color: red;\r\n}\r\n\r\n.netdisk-status[data-check-valid="partial-violation"] {\r\n color: orange;\r\n}\r\n\r\n.netdisk-status[data-check-valid="error"] {\r\n cursor: pointer;\r\n}\r\n\r\n.netdisk-status[data-check-valid="success"] {\r\n color: green;\r\n}\r\n\r\n.netdisk-status[data-check-valid="loading"] svg {\r\n animation: rotating 2s linear infinite;\r\n}\r\n\r\n.netdisk-url-box:has(.netdisk-status[data-check-valid="failed"]) {\r\n text-decoration: line-through;\r\n}\r\n\r\n.whitesevPop-whitesevPopSetting :focus-visible {\r\n outline-offset: 0;\r\n outline: 0;\r\n}\r\n.netdisk-url a[isvisited="true"] {\r\n color: #8b8888 !important;\r\n}\r\n.netdisk-url a:active {\r\n box-shadow: 0 0 0 1px #616161 inset;\r\n}\r\n.netdisk-url a:focus-visible {\r\n outline: 0;\r\n}\r\n.whitesevPop-content p[pop] {\r\n text-indent: 0;\r\n}\r\n.whitesevPop-button[type="primary"] {\r\n border-color: #2d8cf0;\r\n background-color: #2d8cf0;\r\n}\r\n';
const GenerateData = function(key, defaultValue) {
return {
/** 键名 */
KEY: key,
/** 默认值 */
default: defaultValue,
/** 获取值 */
get value() {
let currentValue = _GM_getValue(key, defaultValue);
return currentValue;
},
/** 设置值 */
set value(newValue) {
_GM_setValue(key, newValue);
}
};
};
const NetDiskView = {
show() {
if (NetDiskUI.Alias.uiLinkAlias == null) {
this.createView();
this.initViewEvent();
} else {
NetDiskUI.Alias.uiLinkAlias.show();
}
},
/**
* 创建视图
*/
createView() {
const NetDiskViewConfig = {
view: {
"netdisl-small-window-shrink-status": GenerateData(
"netdisl-small-window-shrink-status",
false
),
"netdisk-ui-small-window-position": GenerateData("netdisk-ui-small-window-position", null)
}
};
let viewAddHTML = "";
NetDiskUI.isMatchedNetDiskIconMap.forEach((netDiskName) => {
let netDiskDict = NetDisk.$match.matchedInfo.get(netDiskName);
let netDiskData = netDiskDict.getItems();
Object.keys(netDiskData).forEach((shareCode) => {
let accessCodeDict = netDiskData[shareCode];
let uiLink = NetDisk.handleLinkShow(
netDiskName,
accessCodeDict["netDiskIndex"],
shareCode,
accessCodeDict["accessCode"],
accessCodeDict["matchText"]
);
viewAddHTML = viewAddHTML + this.createViewBoxElementInfo(
NetDiskUI.src.icon[netDiskName],
netDiskName,
accessCodeDict["netDiskIndex"],
shareCode,
accessCodeDict["accessCode"],
uiLink
).html;
});
});
let viewHTML = (
/*html*/
`
${viewAddHTML}
`
);
if (NetDiskGlobalData.features["netdisk-behavior-mode"].value.toLowerCase().includes("smallwindow")) {
NetDiskUI.Alias.uiLinkAlias = NetDiskPops.alert(
{
title: {
text: "网盘",
position: "center"
},
content: {
text: viewHTML,
html: true
},
btn: {
ok: {
enable: false
},
close: {
callback(event) {
if (NetDiskGlobalData.features["netdisk-behavior-mode"].value.toLowerCase().includes("suspension")) {
NetDiskSuspensionConfig.mode.current_suspension_smallwindow_mode.value = "suspension";
event.hide();
NetDiskUI.suspension.show();
} else {
NetDiskUI.Alias.uiLinkAlias = void 0;
event.close();
}
}
}
},
mask: {
enable: false
},
// @ts-ignore
animation: "",
beforeAppendToPageCallBack($shadowRoot, $shadowContainer) {
let buttonHeaderControl = $shadowRoot.querySelector(
".pops-header-control"
);
let alertContent = $shadowRoot.querySelector(
".pops-alert-content"
);
let launchIcon = domUtils.createElement(
"button",
{
className: "pops-header-control",
innerHTML: (
/*html*/
`
`
)
},
{
type: "launch",
"data-header": true
}
);
let shrinkIcon = domUtils.createElement(
"button",
{
className: "pops-header-control",
innerHTML: (
/*html*/
`
`
)
},
{
type: "shrink",
"data-header": true
}
);
domUtils.before(buttonHeaderControl, launchIcon);
domUtils.before(buttonHeaderControl, shrinkIcon);
domUtils.on(
launchIcon,
"click",
void 0,
function() {
launchIcon.classList.add("pops-hide-important");
shrinkIcon.classList.remove("pops-hide-important");
alertContent.classList.remove("pops-hide-important");
NetDiskViewConfig.view["netdisl-small-window-shrink-status"].value = false;
},
{
capture: true
}
);
domUtils.on(
shrinkIcon,
"click",
void 0,
function() {
shrinkIcon.classList.add("pops-hide-important");
launchIcon.classList.remove("pops-hide-important");
alertContent.classList.add("pops-hide-important");
alertContent.classList.add("pops-no-border-important");
NetDiskViewConfig.view["netdisl-small-window-shrink-status"].value = true;
},
{
capture: true
}
);
if (NetDiskViewConfig.view["netdisl-small-window-shrink-status"].value) {
shrinkIcon.click();
} else {
launchIcon.click();
}
},
dragMoveCallBack(moveElement, left, top2) {
NetDiskViewConfig.view["netdisk-ui-small-window-position"].value = {
left,
top: top2
};
},
class: "whitesevPop",
style: (
/*css*/
`
${indexCSS$4}
.pops {
--container-title-height: 35px;
--content-max-height: ${NetDiskGlobalData.smallWindow["netdisk-ui-small-window-max-height"].value}px;
--netdisk-line-space: 8px;
--netdisk-icon-size: 24px;
}
.pops[type-value="alert"]{
transform: none;
}
.pops {
max-height: var(--content-max-height);
}
.pops[type-value=alert] .pops-alert-content{
max-height: calc(var(--content-max-height) - var(--container-title-height) - var(--container-bottom-btn-height));
}
.pops-header-controls button.pops-header-control[type][data-header]{
padding: 0px 5px;
}
.netdisk-url-div{
padding: 0px;
}
.netdisk-icon .netdisk-icon-img{
width: var(--netdisk-icon-size);
height: var(--netdisk-icon-size);
min-width: var(--netdisk-icon-size);
min-height: var(--netdisk-icon-size);
margin: 0px var(--netdisk-line-space);
}
.netdisk-status{
margin-right: var(--netdisk-line-space);
}
.netdisk-url{
padding: 2px 0px;
}
`
)
},
NetDiskUI.popsStyle.mainViewSmallWindow
);
let smallWindowPosition = NetDiskViewConfig.view["netdisk-ui-small-window-position"].value;
let popsElement = NetDiskUI.Alias.uiLinkAlias.popsElement;
if (smallWindowPosition) {
let viewWidth = domUtils.width(popsElement, true);
let viewHeight = domUtils.height(popsElement, true);
let maxWindowLeft = domUtils.width(window);
let maxWindowTop = domUtils.height(window);
const { transformLeft, transformTop } = domUtils.getTransform(popsElement);
let maxLeft = maxWindowLeft - viewWidth + transformLeft;
let maxTop = maxWindowTop - viewHeight + transformTop;
let minLeft = 0 + transformLeft;
let minTop = 0 + transformTop;
if (smallWindowPosition.top > maxTop) {
smallWindowPosition.top = maxTop;
} else if (smallWindowPosition.top < minTop) {
smallWindowPosition.top = minTop;
}
if (smallWindowPosition.left > maxLeft) {
smallWindowPosition.left = maxLeft;
} else if (smallWindowPosition.left < minLeft) {
smallWindowPosition.left = minLeft;
}
popsElement.style.transitionDuration = "0s";
popsElement.style.left = smallWindowPosition["left"] + "px";
popsElement.style.top = smallWindowPosition["top"] + "px";
setTimeout(() => {
popsElement.style.transitionDuration = "0s";
}, 300);
}
} else {
NetDiskUI.Alias.uiLinkAlias = NetDiskPops.alert(
{
title: {
text: "网盘",
position: "center"
},
content: {
text: viewHTML,
html: true
},
btn: {
ok: {
enable: false
},
close: {
callback(event) {
NetDiskUI.Alias.uiLinkAlias = void 0;
event.close();
}
}
},
mask: {
clickCallBack(originalRun) {
originalRun();
NetDiskUI.Alias.uiLinkAlias = void 0;
}
},
class: "whitesevPop",
style: (
/*css*/
`
${indexCSS$4}
.pops {
max-height: 60vh;
}
@media screen and (max-width: 600px) {
.pops {
max-height: 50vh;
}
}
`
)
},
NetDiskUI.popsStyle.mainView
);
}
NetDiskUI.Alias.uiLinkAlias.popsElement.querySelectorAll(".netdisk-url-box-all .netdisk-url-box").forEach(($netDiskBox) => {
let netDiskName = $netDiskBox.querySelector(".netdisk-link").getAttribute("data-netdisk");
let netDiskIndex = parseInt(
$netDiskBox.querySelector(".netdisk-link").getAttribute("data-netdisk-index")
);
let shareCode = $netDiskBox.querySelector(".netdisk-link").getAttribute("data-sharecode");
let accessCode = $netDiskBox.querySelector(".netdisk-link").getAttribute("data-accesscode");
NetDiskCheckLinkValidity.check(
$netDiskBox,
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
});
},
/**
* 初始化事件(在创建视图后)
*/
initViewEvent() {
NetDiskUI.setRightClickMenu(
NetDiskUI.Alias.uiLinkAlias.$shadowRoot,
".whitesevPop .netdisk-url a"
);
this.registerIconGotoPagePosition(NetDiskUI.Alias.uiLinkAlias.$shadowRoot);
this.setNetDiskUrlClickEvent(
NetDiskUI.Alias.uiLinkAlias.$shadowRoot,
".netdisk-url a"
);
NetDiskUI.setGlobalRightClickMenu(
NetDiskUI.Alias.uiLinkAlias.$shadowRoot.querySelector(
".pops .pops-alert-title > p"
)
);
},
/**
* 创建在元素属性上的attribute的数据JSON
*/
createElementAttributeRuleInfoJSON(data) {
return {
/** 网盘 */
"data-netdisk": data.netDisk,
/** 网盘索引 */
"data-netdisk-index": data.netDiskIndex,
/** 访问码 */
"data-sharecode": data.shareCode,
/** 访问码 */
"data-accesscode": data.accessCode
};
},
/**
* 创建在元素属性上的attribute的数据
* @param data 数据
* @param $ele 需要处理的元素
*/
handleElementAttributeRuleInfo(data, $ele) {
let ruleInfoJSON = this.createElementAttributeRuleInfoJSON(data);
for (const key in ruleInfoJSON) {
const value = ruleInfoJSON[key];
if (Array.isArray($ele)) {
$ele.forEach(($ele2) => {
$ele2.setAttribute(key, value.toString());
});
} else {
$ele.setAttribute(key, value.toString());
}
}
},
/**
* 解析创建在元素属性上的attribute的数据
*/
praseElementAttributeRuleInfo($ele) {
let result = {
/** 网盘名称 */
netDiskName: $ele.getAttribute("data-netdisk"),
/** 网盘索引 */
netDiskIndex: parseInt($ele.getAttribute("data-netdisk-index")),
/** 分享码 */
shareCode: $ele.getAttribute("data-sharecode"),
/** 提取码 */
accessCode: $ele.getAttribute("data-accesscode")
};
if (isNaN(result.netDiskIndex)) {
log.warn("元素上的netDiskIndex的值是NaN", $ele);
result.netDiskIndex = 0;
}
return result;
},
/**
* 创建每一项的网盘元素信息
* @param netDiskImgSrc 网盘图标src
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称索引下标
* @param shareCode
* @param accessCode
* @param uiLinkText 显示出来的链接文本
*/
createViewBoxElementInfo(netDiskImgSrc, netDiskName, netDiskIndex, shareCode, accessCode, uiLinkText) {
let $viewBox = domUtils.createElement("div", {
className: "netdisk-url-box",
innerHTML: (
/*html*/
`
`
)
});
let $urlDiv = $viewBox.querySelector(".netdisk-url-div");
let $icon = $viewBox.querySelector(".netdisk-icon");
let $iconImg = $viewBox.querySelector(".netdisk-icon-img");
let $checkValidStatus = $viewBox.querySelector(".netdisk-status");
let $url = $viewBox.querySelector(".netdisk-url");
let $link = $viewBox.querySelector(".netdisk-link");
$iconImg.style.cssText = `background: url(${netDiskImgSrc}) no-repeat;background-size: 100%;`;
$link.innerHTML = uiLinkText;
this.handleElementAttributeRuleInfo(
{
netDisk: netDiskName,
netDiskIndex,
shareCode,
accessCode
},
[$iconImg, $link]
);
return {
$viewBox,
$urlDiv,
$icon,
$iconImg,
$checkValidStatus,
$url,
$link,
html: $viewBox.outerHTML
};
},
/**
* 设置网盘链接点击事件
* @param target
* @param clickNodeSelector 元素选择器
*/
setNetDiskUrlClickEvent(target, clickNodeSelector) {
domUtils.on(target, "click", clickNodeSelector, (event) => {
let $click = event.target;
$click.setAttribute("isvisited", "true");
const data = NetDiskView.praseElementAttributeRuleInfo($click);
this.netDiskUrlClickEvent({
data
});
});
},
/**
* 网盘链接点击事件
* @param option
*/
netDiskUrlClickEvent(option) {
const { netDiskName, netDiskIndex, shareCode, accessCode } = option.data;
let linkClickMode = option.clickMode ?? NetDiskRuleData.function.linkClickMode(option.data.netDiskName);
if (linkClickMode === "copy") {
NetDiskLinkClickMode.copy(
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
} else if (linkClickMode === "openBlank") {
let url = NetDiskLinkClickModeUtils.getBlankUrl(
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
let isForwardBlankUrl = NetDiskFilterScheme.isForwardBlankLink(netDiskName);
if (isForwardBlankUrl) {
NetDiskLinkClickMode.openBlankWithScheme(
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
} else {
NetDiskLinkClickMode.openBlank(
url,
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
}
} else if (linkClickMode === "parseFile") {
NetDiskLinkClickMode.parseFile(
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
} else {
log.error("未知点击动作:" + linkClickMode);
Qmsg.error("未知点击动作:" + linkClickMode);
}
},
/**
* 注册右键菜单
* @param target
* @param selector
* @param showTextList 右键菜单的内容
* @param className className属性
*/
registerContextMenu(target, selector, showTextList = [], className = "whitesevSuspensionContextMenu") {
let data = [];
showTextList.forEach((item) => {
data.push({
icon: "",
iconIsLoading: false,
text: item.text,
callback: item.callback
});
});
let detail = {
target,
targetSelector: selector,
data,
isAnimation: false,
className,
only: true
};
NetDiskPops.rightClickMenu(detail);
},
/**
* 添加新的链接
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
* @param matchText 匹配到的文本
*/
addLinkView(netDiskName, netDiskIndex, shareCode, accessCode, matchText) {
NetDiskUI.netDiskHistoryMatch.changeMatchedData(
netDiskName,
netDiskIndex,
shareCode,
accessCode,
matchText
);
if (!NetDiskUI.Alias.uiLinkAlias) {
return;
}
log.info(netDiskName, netDiskIndex, shareCode, accessCode);
let icon = NetDiskUI.src.icon[netDiskName];
let uiLink = NetDisk.handleLinkShow(
netDiskName,
netDiskIndex,
shareCode,
accessCode,
matchText
);
let insertDOM = this.createViewBoxElementInfo(
icon,
netDiskName,
netDiskIndex,
shareCode,
accessCode,
uiLink
);
let $urlBoxAll = NetDiskUI.Alias.uiLinkAlias.popsElement.querySelector(
".netdisk-url-box-all"
);
domUtils.append($urlBoxAll, insertDOM.$viewBox);
let $urlBox = $urlBoxAll.children[$urlBoxAll.children.length - 1];
NetDiskCheckLinkValidity.check(
$urlBox,
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
},
/**
* 修改已存在的view
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
* @param matchText 匹配到的文本
*/
changeLinkView(netDiskName, netDiskIndex, shareCode, accessCode, matchText) {
NetDiskUI.netDiskHistoryMatch.changeMatchedData(
netDiskName,
netDiskIndex,
shareCode,
accessCode,
matchText
);
if (!NetDiskUI.Alias.uiLinkAlias) {
return;
}
let uiLink = NetDisk.handleLinkShow(
netDiskName,
netDiskIndex,
shareCode,
accessCode,
matchText
);
let needChangeDOM = NetDiskUI.Alias.uiLinkAlias.popsElement.querySelector(
`.netdisk-url a[data-sharecode='${shareCode}'][data-netdisk-index='${netDiskIndex}']`
);
log.info("修改网盘链接视图");
log.info(needChangeDOM);
needChangeDOM.setAttribute("data-accesscode", accessCode);
domUtils.html(needChangeDOM, uiLink);
},
/**
* 设置点击图标按钮导航至该网盘链接所在网页中位置
*/
registerIconGotoPagePosition(targetElement) {
let findGenerator = void 0;
let iterator = void 0;
let prevSearchShareCode = void 0;
domUtils.on(
targetElement,
"click",
".whitesevPop .netdisk-icon .netdisk-icon-img",
function(event) {
let $click = event.target;
let dataSharecode = $click.getAttribute("data-sharecode");
if (!NetDiskGlobalData.smallIconNavgiator["pops-netdisk-icon-click-event-find-sharecode"].value) {
return;
}
if (typeof dataSharecode !== "string") {
Qmsg.error("获取data-sharecode属性失败");
return;
}
if (prevSearchShareCode == void 0) {
prevSearchShareCode = dataSharecode;
} else if (prevSearchShareCode !== dataSharecode) {
log.info(
`上一个搜索:${prevSearchShareCode},切换至:${dataSharecode}`
);
findGenerator = void 0;
iterator = void 0;
prevSearchShareCode = dataSharecode;
}
if (findGenerator == void 0) {
findGenerator = utils.findElementsWithText(
document.documentElement,
dataSharecode
);
iterator = findGenerator.next();
}
if (iterator == null ? void 0 : iterator.value) {
log.success("定位元素", iterator);
if (iterator.value.nodeType === Node.ELEMENT_NODE && iterator.value.getClientRects().length) {
iterator.value.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "nearest"
});
if (NetDiskGlobalData.smallIconNavgiator["pops-netdisk-icon-click-event-find-sharecode-with-select"].value) {
let elementText = iterator.value.innerText || iterator.value.textContent;
let childTextNode = void 0;
let startIndex = void 0;
let endIndex = void 0;
if (elementText.includes(dataSharecode)) {
let textNodeList = Array.from(
iterator.value.childNodes
).filter((ele) => ele.nodeType === Node.TEXT_NODE);
for (const textNode of textNodeList) {
if (textNode.textContent.includes(
dataSharecode
)) {
childTextNode = textNode;
startIndex = textNode.textContent.indexOf(dataSharecode);
endIndex = startIndex + dataSharecode.length;
break;
}
}
}
try {
utils.selectElementText(
iterator.value,
childTextNode,
startIndex,
endIndex
);
} catch (error) {
log.error(error);
utils.selectElementText(iterator.value);
}
}
} else if (iterator.value.nodeType === Node.TEXT_NODE && iterator.value.parentElement.getClientRects().length) {
if (NetDiskGlobalData.smallIconNavgiator["pops-netdisk-icon-click-event-find-sharecode-with-select"].value) {
let elementText = iterator.value.textContent || iterator.value.nodeValue;
let childTextNode = iterator.value;
let startIndex = elementText.indexOf(dataSharecode);
let endIndex = startIndex + dataSharecode.length;
try {
utils.selectElementText(
iterator.value,
childTextNode,
startIndex,
endIndex
);
} catch (error) {
log.error(error);
utils.selectElementText(iterator.value.parentElement);
}
let selection = globalThis.getSelection();
if (selection.rangeCount > 0) {
let range = selection.getRangeAt(0);
let rect = range.getBoundingClientRect();
let scrollYOffset = globalThis.scrollY;
let position = rect.top + scrollYOffset - globalThis.innerHeight / 2;
globalThis.scrollTo({
behavior: "smooth",
top: position
});
} else {
iterator.value.parentElement.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "nearest"
});
}
} else {
try {
let range = new Range();
range.selectNodeContents(iterator.value);
let rect = range.getBoundingClientRect();
let scrollYOffset = globalThis.scrollY;
let position = rect.top + scrollYOffset - globalThis.innerHeight / 2;
globalThis.scrollTo({
behavior: "smooth",
top: position
});
} catch (error) {
log.error(error);
iterator.value.parentElement.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "nearest"
});
}
}
} else {
log.error("无法定位该元素位置", iterator.value);
Qmsg.error(
`无法定位该元素位置,类型:<${(iterator.value.nodeName || iterator.value.localName || iterator.value.tagName).toLowerCase()}>`,
{
html: false
}
);
}
}
iterator = findGenerator.next();
if (iterator.done) {
if (!NetDiskGlobalData.smallIconNavgiator["pops-netdisk-icon-click-event-loop-find-sharecode"].value) {
Qmsg.info("已经定位至最后一个元素了");
return;
}
findGenerator = void 0;
iterator = void 0;
}
}
);
}
};
class NetDiskParse_Chengtong extends NetDiskParseObject {
/**
* 入口
* @param netDiskIndex 网盘名称索引下标
* @param shareCode
* @param accessCode
*/
init(netDiskIndex, shareCode, accessCode) {
let netDiskName = "chengtong";
if (netDiskIndex !== 3) {
log.warn(
`解析站暂时只支持单文件解析,非单文件链接的点击动作为新标签页打开`
);
NetDiskView.netDiskUrlClickEvent({
data: {
netDiskName,
netDiskIndex,
shareCode,
accessCode
},
clickMode: "openBlank"
});
return;
}
let apiHost = _GM_getValue("chengtong-parse-file-api-host");
if (utils.isNull(apiHost)) {
Qmsg.error("请先配置文件解析接口地址");
return;
}
if (!apiHost.endsWith("/")) {
apiHost += "/";
}
let url = apiHost + "?file=" + shareCode;
if (utils.isNotNull(accessCode)) {
url += "&pass=" + accessCode;
}
window.open(url, "_blank");
}
}
class NetDiskParse_Jianguoyun extends NetDiskParseObject {
constructor() {
super(...arguments);
__publicField(this, "errorCode", {
UnAuthorized: "请先登录坚果云账号"
});
}
async init(netDiskIndex, shareCode, accessCode) {
const that = this;
log.info(netDiskIndex, shareCode, accessCode);
that.netDiskIndex = netDiskIndex;
that.shareCode = shareCode;
that.accessCode = accessCode;
let downloadParams = await that.getRequestDownloadParams();
if (!downloadParams) {
return;
}
if (downloadParams["isdir"]) {
let Qmsg_loading = Qmsg.loading("正在遍历多文件信息...");
let folderInfo = await that.getFolderInfo(downloadParams["hash"]);
if (!folderInfo) {
Qmsg_loading.close();
return;
}
let newFolderInfoList = that.parseMoreFile(
folderInfo,
downloadParams["hash"],
downloadParams["name"]
);
Qmsg_loading.close();
NetDiskUI.staticView.moreFile("坚果云文件解析", newFolderInfoList);
} else {
let fileSize = utils.formatByteToSize(downloadParams["size"]);
let downloadUrl = await that.getFileLink(
downloadParams.hash,
downloadParams.name
);
if (!downloadUrl) {
return;
}
if (NetDiskFilterScheme.isForwardDownloadLink("jianguoyun")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"jianguoyun",
downloadUrl
);
}
log.info(downloadUrl);
NetDiskUI.staticView.oneFile({
title: "坚果云盘单文件直链",
fileName: downloadParams["name"],
fileSize,
downloadUrl
});
}
}
/**
* 解析多文件信息
* @param {{
* mtime: number,
* relPath: string,
* size: number,
* tblUri: ?string,
* type: "file"|string,
* }[]} folderInfo
* @param {string} hash 文件hash值
* @param {string} fileName 文件名
* @returns {{
* fileName: string,
* fileSize: string|number,
* fileType: ?string,
* createTime: ?string,
* latestTime: ?string,
* isFolder: boolean,
* index: ?number,
* clickCallBack: ?(event:Event,_config_: object)=>{}
* }[]}
*/
parseMoreFile(folderInfo, hash = "", fileName = "") {
const that = this;
log.info("解析多文件信息", folderInfo);
let folderInfoList = [];
folderInfo.forEach((item) => {
let fileName2 = item.relPath;
if (fileName2.startsWith("/")) {
fileName2 = fileName2.replace(/^\//, "");
}
folderInfoList.push({
fileName: fileName2,
fileSize: item["size"],
fileType: "",
createTime: item.mtime,
latestTime: item.mtime,
isFolder: false,
index: 0,
async clickEvent() {
Qmsg.info("正在获取下载链接...");
let downloadUrl = await that.getDirLink(
hash,
fileName2,
item["relPath"]
);
if (!downloadUrl) {
return;
}
Qmsg.success("获取成功!");
if (NetDiskFilterScheme.isForwardDownloadLink("jianguoyun")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"jianguoyun",
downloadUrl
);
}
log.info(downloadUrl);
return {
autoDownload: true,
mode: "aBlank",
url: downloadUrl
};
}
});
});
return folderInfoList;
}
/**
* 获取下载链接所需要的hash值和name
*/
async getRequestDownloadParams() {
const that = this;
log.info("获取hash值");
Qmsg.info("正在获取请求信息");
let pageInfoRegexp = /var[\s]*PageInfo[\s]*=[\s]*{([\s\S]+)};/i;
let formData = new FormData();
formData.append("pd", that.accessCode);
let requestDetails = {
url: `https://www.jianguoyun.com/p/${that.shareCode}`,
data: that.accessCode === "" ? void 0 : `pd=${that.accessCode}`,
responseType: "html",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": utils.getRandomPCUA(),
Referer: `https://www.jianguoyun.com/p/${that.shareCode}`
}
};
let requestResp = void 0;
if (that.accessCode === "") {
requestResp = await httpx.get(requestDetails);
} else {
requestResp = await httpx.post(requestDetails);
}
if (!requestResp.status) {
return;
}
let respData = requestResp.data;
log.info("请求信息");
log.info(respData);
let pageInfoMatch = respData.responseText.match(pageInfoRegexp);
if (pageInfoMatch) {
let pageInfo = pageInfoMatch[pageInfoMatch.length - 1];
pageInfo = `({${pageInfo}})`;
pageInfo = window.eval(pageInfo);
log.info(pageInfo);
let fileName = pageInfo["name"];
let fileSize = pageInfo["size"];
let fileHash = pageInfo["hash"];
let fileNeedsPassword = pageInfo["needsPassword"];
let fileOwner = pageInfo["owner"];
let isdir = pageInfo["isdir"];
let fileErrorCode = pageInfo["errorCode"];
fileName = decodeURIComponent(fileName);
log.success("是否是文件夹 ===> " + isdir);
log.success("hash ===> " + fileHash);
log.success("name ===> " + fileName);
log.success("size ===> " + fileSize);
if (fileNeedsPassword && (that.accessCode == void 0 || that.accessCode === "")) {
Qmsg.error("密码不正确!");
NetDiskUI.newAccessCodeView(
"密码缺失",
"jianguoyun",
that.netDiskIndex,
that.shareCode,
that.accessCode,
(option) => {
that.init(that.netDiskIndex, that.shareCode, option.accessCode);
}
);
return;
}
if (fileErrorCode === "AuthenticationFailed") {
Qmsg.error("密码错误");
NetDiskUI.newAccessCodeView(
void 0,
"jianguoyun",
that.netDiskIndex,
that.shareCode,
that.accessCode,
(option) => {
that.init(that.netDiskIndex, that.shareCode, option.accessCode);
}
);
return;
}
if (fileHash === "" || fileHash == void 0) {
log.error("hash为空,可能文件被撤销分享了");
Qmsg.error(`文件分享已被撤销`);
return;
}
if (fileSize == void 0 && isdir == false) {
log.error("无size,可能文件被删除了");
Qmsg.error(`“${fileName}”文件已被拥有者(“${fileOwner}”)删除`);
return;
} else {
return {
name: fileName,
hash: fileHash,
size: fileSize,
needsPassword: fileNeedsPassword,
owner: fileOwner,
isdir
};
}
} else if (respData.responseText.match("对不起,找不到您指定的文件。")) {
log.error("啊噢! (404) 对不起,找不到您指定的文件。");
Qmsg.error("坚果云: 对不起,找不到您指定的文件。");
} else if (respData.responseText.match("对不起,您的某些输入不正确。")) {
log.error("可能该链接不需要访问码或者访问码有问题");
NetDiskUI.newAccessCodeView(
void 0,
"jianguoyun",
that.netDiskIndex,
that.shareCode,
that.accessCode,
(option) => {
that.init(that.netDiskIndex, that.shareCode, option.accessCode);
}
);
} else {
log.error("获取PageInfo失败");
Qmsg.error("坚果云: 获取PageInfo失败");
}
}
/**
* 获取下载链接
* @param {string} fileHash 文件hash值
* @param {string} fileName 文件名
* @returns {Promise}
*/
async getFileLink(fileHash = "", fileName = "") {
var _a2;
const that = this;
fileName = encodeURIComponent(fileName);
let getResp = await httpx.get({
url: `https://www.jianguoyun.com/d/ajax/fileops/pubFileLink?k=${fileHash}&name=${fileName}&wm=false${that.accessCode === "" ? "" : "&pd=" + that.accessCode}&forwin=1&_=${(/* @__PURE__ */ new Date()).getTime()}`,
responseType: "json",
headers: {
"User-Agent": utils.getRandomPCUA()
},
allowInterceptConfig: false,
onerror: function() {
}
});
if (!getResp.status) {
if (utils.isNotNull((_a2 = getResp.data) == null ? void 0 : _a2.responseText)) {
let errorData = utils.toJSON(getResp.data.responseText);
log.error("坚果云", errorData);
if (errorData["errorCode"] === "UnAuthorized") {
that.gotoLogin();
} else {
Qmsg.error(errorData["detailMsg"]);
}
} else {
Qmsg.error("请求异常");
}
return;
}
let respData = getResp.data;
log.info("请求信息", respData);
let resultJSON = utils.toJSON(respData.responseText);
log.info("解析JSON", resultJSON);
if (resultJSON.hasOwnProperty("errorCode")) {
Qmsg.error("坚果云: " + resultJSON["detailMsg"]);
return;
} else if (resultJSON.hasOwnProperty("url")) {
return resultJSON["url"];
} else {
Qmsg.error("坚果云: 处理下载链接异常");
}
}
/**
* 获取文件夹下的文件下载链接
* @param {string} fileHash
* @param {string} fileName
* @param {string} filePath
* @returns {Promise}
*/
async getDirLink(fileHash = "", fileName = "", filePath = "/") {
var _a2;
const that = this;
fileName = encodeURIComponent(fileName);
let getResp = await httpx.get({
url: `https://www.jianguoyun.com/d/ajax/dirops/pubDIRLink?k=${fileHash}&dn=${fileName}&p=${filePath}&forwin=1&_=${(/* @__PURE__ */ new Date()).getTime()}`,
responseType: "json",
headers: {
"User-Agent": utils.getRandomPCUA()
},
allowInterceptConfig: false,
onerror: function() {
}
});
if (!getResp.status) {
if (utils.isNotNull((_a2 = getResp.data) == null ? void 0 : _a2.responseText)) {
let errorData = utils.toJSON(getResp.data.responseText);
log.error("坚果云", errorData);
if (errorData["errorCode"] === "UnAuthorized") {
that.gotoLogin();
} else {
Qmsg.error(errorData["detailMsg"]);
}
} else {
Qmsg.error("请求异常");
}
return;
}
let respData = getResp.data;
log.info("请求信息", respData);
let resultJSON = utils.toJSON(respData.responseText);
log.info(resultJSON);
if (resultJSON.hasOwnProperty("errorCode")) {
Qmsg.error("坚果云: " + resultJSON["detailMsg"]);
return;
} else if (resultJSON.hasOwnProperty("url")) {
return resultJSON["url"];
} else {
Qmsg.error("坚果云: 处理下载链接异常");
}
}
/**
* 获取文件夹信息
* @param {string} hash
* @returns
*/
async getFolderInfo(hash = "") {
let getResp = await httpx.get({
url: `https://www.jianguoyun.com/d/ajax/dirops/pubDIRBrowse?hash=${hash}&relPath=%2F&_=${(/* @__PURE__ */ new Date()).getTime()}`,
responseType: "json",
headers: {
"User-Agent": utils.getRandomPCUA()
}
});
if (!getResp.status) {
return;
}
let respData = getResp.data;
log.info("请求信息", respData);
let resultJSON = utils.toJSON(respData.responseText);
log.info(resultJSON);
if ("objects" in resultJSON) {
return resultJSON["objects"];
} else {
Qmsg.error("坚果云: 处理多文件信息异常");
}
}
/**
* 前往登录
*/
gotoLogin() {
NetDiskPops.confirm(
{
title: {
text: "提示",
position: "center"
},
content: {
text: `解析失败,原因:当前尚未登录坚果云,是否前往登录?`
},
btn: {
reverse: true,
position: "end",
ok: {
text: "前往",
callback: function(_event_) {
window.open(
"https://www.jianguoyun.com/d/login#from=https%3A%2F%2Fwww.jianguoyun.com%2F",
"_blank"
);
}
}
}
},
NetDiskUI.popsStyle.jianGuoYunLoginTip
);
}
}
const NetDiskParse_Lanzou_Config = {
/* 蓝奏云默认域名 */
DEFAULT_HOST_NAME: "www.lanzout.com",
/** 菜单配置项的键名 */
MENU_KEY: "lanzou-host-name",
get hostname() {
let generateData = GeneratePanelData(this.MENU_KEY, this.DEFAULT_HOST_NAME);
return generateData.value;
}
};
class NetDiskParse_Lanzou extends NetDiskParseObject {
constructor() {
super(...arguments);
/**
* 路由
*/
__publicField(this, "router", {
/**
* 根路径
* + /
* @param pathName
*/
root(pathName = "") {
if (pathName.startsWith("/")) {
pathName = pathName.replace(/^\//, "");
}
return `https://${NetDiskParse_Lanzou_Config.hostname}/${pathName}`;
},
/**
* + /tp/
* @param pathName
*/
root_tp(pathName = "") {
if (pathName.startsWith("/")) {
pathName = pathName.replace(/^\//, "");
}
return `https://${NetDiskParse_Lanzou_Config.hostname}/tp/${pathName}`;
},
/**
* + /s/
* @param pathName
*/
root_s(pathName = "") {
if (pathName.startsWith("/")) {
pathName = pathName.replace(/^\//, "");
}
return `https://${NetDiskParse_Lanzou_Config.hostname}/s/${pathName}`;
}
});
__publicField(this, "regexp", {
unicode: {
/**
* 判断该链接是否是中文
*/
match: /[%\u4e00-\u9fa5]+/g,
tip: "中文链接",
isUnicode: false
},
/**
* 蓝奏文件取消分享
*/
noFile: {
match: /div>来晚啦...文件取消分享了<\/div>/g,
tip: "来晚啦...文件取消分享了"
},
/**
* 蓝奏文件链接错误
*/
noExists: {
match: /div>文件不存在,或已删除<\/div>/g,
tip: "文件不存在,或已删除"
},
/**
* 2023-9-19 蓝奏云修改分享规则,需要vip用户才可以分享 apk、ipa 链接
*/
needVipToShare: {
match: /class="fbox">非会员.+请先开通会员/gi,
tip: "该链接为非会员用户分享的文件,目前无法下载"
},
/**
* 蓝奏多文件
*/
moreFile: {
match: //g
},
/**
* 蓝奏设置了密码的单文件请求需要的sign值
*/
sign: {
match: /var[\s]*(posign|postsign|vidksek|skdklds)[\s]*=[\s]*'(.+?)';/
},
/**
* 蓝奏文件名
*/
fileName: {
match: /(.*)<\/title>/
},
/**
* 蓝奏文件大小
*/
fileSize: {
match: /\((.*)\)<\/span>/
},
/**
* 蓝奏文件直链host
*/
loadDownHost: {
match: /var[\s]*(vkjxld)[\s]*=[\s]*'(.+?)'/i
},
/**
* 蓝奏文件直链
*/
loadDown: {
match: /var[\s]*(loaddown|oreferr|spototo|domianload|hyggid)[\s]*=[\s]*'(.+?)'/i
},
/**
* 蓝奏云之苹果使用类型的文件
*/
appleDown: {
match: /var[\s]*appitem[\s]*=[\s]*'(.+?)'/i
},
/**
* 蓝奏云文件上传时间
*/
uploadTime: {
match: /mt2\"\>时间:<\/span>(.+?)[\s]*文件不存在,或者已被删除")) {
Qmsg.error("文件不存在,或者已被删除");
} else {
Qmsg.error("未知情况");
}
return;
}
let respData = getResp.data;
if (respData.readyState !== 4) {
log.error(respData);
Qmsg.error("请求失败,请重试");
return;
}
if (respData.responseText == void 0) {
log.error(respData);
Qmsg.error("获取网页内容为空");
return;
}
if (!that.checkPageCode(respData)) {
return;
}
if (that.isMoreFile(respData)) {
await that.getMoreFile();
} else {
log.info(respData);
let pageText = respData.responseText;
if (getShareCodeByPageAgain) {
let shareCodeNewMatch = pageText.match(
/var[\s]*link[\s]*=[\s]*\'tp\/(.+?)\';/i
);
that.shareCode = shareCodeNewMatch[shareCodeNewMatch.length - 1];
log.info(`新参数 => ${that.shareCode}`);
}
let pageDOM = domUtils.parseHTML(pageText, true, true);
let pageIframeElement = pageDOM.querySelector('iframe[class^="ifr"]') || pageDOM.querySelector('iframe[class^="n_downlink"]');
if (pageIframeElement) {
let iframeUrl = pageIframeElement.getAttribute("src");
log.error("该链接需要重新通过iframe地址访问获取信息", iframeUrl);
Qmsg.info("正在请求下载信息");
let fileName = ((_a2 = pageDOM.querySelector("body div.d > div")) == null ? void 0 : _a2.innerText) || ((_b = pageDOM.querySelector("#filenajax")) == null ? void 0 : _b.innerText) || ((_d = (_c = pageDOM.querySelector("title")) == null ? void 0 : _c.textContent) == null ? void 0 : _d.replace(/ - 蓝奏云$/i, ""));
let fileSize = pageText.match(/文件大小:<\/span>(.+?)
/i) || ((_e = pageDOM.querySelector(
"div.n_box div.n_file div.n_filesize"
)) == null ? void 0 : _e.innerText) || ((_f = pageDOM.querySelector(
".d2 table tr td .fileinfo:nth-child(1) .fileinforight"
)) == null ? void 0 : _f.innerText);
let fileUploadTime = pageText.match(/上传时间:<\/span>(.+?)
/i) || ((_g = pageDOM.querySelector(
"#file[class=''] .n_file_info span.n_file_infos"
)) == null ? void 0 : _g.innerText) || ((_h = pageDOM.querySelector(
".d2 table tr td .fileinfo:nth-child(3) .fileinforight"
)) == null ? void 0 : _h.innerText) || ((_i = pageDOM.querySelector(
"#file[class='filter'] .n_file_info span.n_file_infos"
)) == null ? void 0 : _i.innerText);
if (fileSize) {
if (Array.isArray(fileSize)) {
fileSize = fileSize[fileSize.length - 1];
}
if (typeof fileSize === "string") {
fileSize = fileSize.replaceAll("大小:", "");
}
} else {
log.error("解析文件大小信息失败");
}
if (fileUploadTime) {
if (Array.isArray(fileUploadTime)) {
fileUploadTime = fileUploadTime[fileUploadTime.length - 1];
}
if (fileUploadTime.toString().toLowerCase().startsWith("android")) {
log.error("解析出的文件上传时间信息是Android/xxxx开头");
fileUploadTime = void 0;
}
} else {
log.error("解析文件上传时间信息失败");
}
let downloadUrl = await that.getLinkByIframe(iframeUrl, {
fileName,
fileSize,
// @ts-ignore
fileUploadTime
});
if (downloadUrl) {
if (NetDiskFilterScheme.isForwardDownloadLink("lanzou")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"lanzou",
downloadUrl
);
}
NetDiskUI.staticView.oneFile({
title: "蓝奏云单文件直链",
fileName,
fileSize,
downloadUrl,
fileUploadTime
});
}
} else {
await that.getLink(respData);
}
}
}
/**
* 页面检查,看看是否存在文件失效情况
* @param response
* + true 未失效
* + false 已失效
*/
checkPageCode(response) {
const that = this;
let pageText = response.responseText;
if (pageText.match(that.regexp.noFile.match)) {
Qmsg.error(that.regexp.noFile.tip);
return false;
}
if (pageText.match(that.regexp.noExists.match)) {
Qmsg.error(that.regexp.noExists.tip);
return false;
}
if (pageText.match(that.regexp.needVipToShare.match)) {
Qmsg.error(that.regexp.needVipToShare.tip);
return false;
}
return true;
}
/**
* 判断是否是多文件的链接
* @param {object} response
* @returns {boolean}
* + true 多文件
* + false 单文件
*/
isMoreFile(response) {
const that = this;
let pageText = response.responseText;
if (pageText.match(that.regexp.moreFile.match)) {
log.info("该链接为多文件");
return true;
} else {
log.info("该链接为单文件");
return false;
}
}
/**
* 获取链接
* @param response
*/
async getLink(response) {
const that = this;
let pageText = response.responseText;
if (pageText == void 0) {
log.error("shareCode错误,重新从页面中获取");
await that.getFileLink(true);
return;
}
let sign = pageText.match(that.regexp.sign.match);
let postData_p = "";
let postData_sign = "";
let fileName = pageText.match(that.regexp.fileName.match);
let fileSize = pageText.match(that.regexp.fileSize.match) || pageText.match(/大小:(.+?)<\/div>/i);
let fileUploadTime = pageText.match(that.regexp.uploadTime.match) || pageText.match(/
(.+?)<\/span>/i);
if (fileName) {
fileName = fileName[fileName.length - 1].trim();
} else {
fileName = "";
}
if (fileSize) {
fileSize = fileSize[fileSize.length - 1].trim();
} else {
fileSize = "";
}
if (fileUploadTime) {
fileUploadTime = fileUploadTime[fileUploadTime.length - 1].trim();
}
if (sign) {
postData_sign = sign[sign.length - 1];
log.info(`获取Sign: ${postData_sign}`);
if (utils.isNotNull(that.accessCode)) {
log.info("传入参数=>有密码");
postData_p = that.accessCode;
} else {
log.info("传入参数=>无密码");
}
let postResp = await httpx.post({
url: that.router.root("ajaxm.php"),
responseType: "json",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"User-Agent": utils.getRandomAndroidUA(),
Referer: that.router.root(that.shareCode)
},
data: `action=downprocess&sign=${postData_sign}&p=${postData_p}`
});
if (!postResp.status) {
return;
}
let respData = postResp.data;
log.info(respData);
if (respData.readyState === 4) {
let json_data = utils.toJSON(respData.responseText);
let downloadUrl = `${json_data["dom"]}/file/${json_data["url"]}`;
if (typeof json_data["url"] === "string" && (json_data["url"].startsWith("http") || json_data["url"].startsWith(json_data["dom"]))) {
downloadUrl = json_data["url"];
}
json_data["zt"];
if ("密码不正确".indexOf(json_data["inf"]) != -1) {
Qmsg.error("密码不正确!");
NetDiskUI.newAccessCodeView(
void 0,
"lanzou",
that.netDiskIndex,
that.shareCode,
that.accessCode,
(option) => {
that.init(that.netDiskIndex, that.shareCode, option.accessCode);
}
);
} else {
fileName = json_data["inf"] ? json_data["inf"] : fileName;
log.info(downloadUrl);
if (NetDiskFilterScheme.isForwardDownloadLink("lanzou")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"lanzou",
downloadUrl
);
}
NetDiskUI.staticView.oneFile({
title: "蓝奏云单文件直链",
fileName,
fileSize,
downloadUrl,
fileUploadTime
});
}
} else {
Qmsg.error("请求失败,请重试");
}
} else {
let loadDownHost = pageText.match(that.regexp.loadDownHost.match);
let loadDown = pageText.match(that.regexp.loadDown.match);
let appleDown = pageText.match(that.regexp.appleDown.match);
if (utils.isNull(loadDown)) {
loadDown = pageText.match(/var[\s]*(cppat)[\s]*=[\s]*'(.+?)'/i);
}
if (utils.isNull(loadDownHost) && appleDown) {
appleDown = appleDown[appleDown.length - 1];
loadDownHost = [appleDown];
loadDown = [""];
log.success("多文件-当前链接猜测为苹果的文件", appleDown);
}
if (utils.isNull(loadDownHost)) {
Qmsg.error("蓝奏云直链:获取sign的域名失败,请反馈开发者", {
timeout: 3500
});
return;
}
if (utils.isNull(loadDown)) {
Qmsg.error("蓝奏云直链:获取sign失败,请反馈开发者", {
timeout: 3500
});
return;
}
let downloadUrl = `${loadDownHost[loadDownHost.length - 1]}${loadDown[loadDown.length - 1]}`;
log.info(fileName, fileSize, downloadUrl);
log.info(downloadUrl);
if (NetDiskFilterScheme.isForwardDownloadLink("lanzou")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"lanzou",
downloadUrl
);
}
NetDiskUI.staticView.oneFile({
title: "蓝奏云单文件直链",
fileName,
fileSize,
downloadUrl,
fileUploadTime
});
}
}
/**
* 通过iframe的链接来获取单文件直链
* @param urlPathName url路径
* @param fileInfo 文件信息
*/
async getLinkByIframe(urlPathName, fileInfo) {
const that = this;
log.info(urlPathName, fileInfo);
let iFrameUrl = that.router.root(urlPathName);
let getResp = await httpx.get({
url: iFrameUrl,
headers: {
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"User-Agent": utils.getRandomPCUA(),
Referer: that.router.root(that.shareCode)
}
});
if (!getResp.status) {
return;
}
let respData = getResp.data;
log.info(respData);
let pageText = respData.responseText;
let aihidcmsMatch = pageText.match(/var[\s]*aihidcms[\s]*=[\s]*'(.*)';/i);
let ciucjdsdcMatch = pageText.match(/var[\s]*ciucjdsdc[\s]*=[\s]*'(.*)';/i);
let ajaxdataMatch = pageText.match(/var[\s]*ajaxdata[\s]*=[\s]*'(.+)';/i);
let signMatch = pageText.match(/'sign':[\s]*'(.+)',/i);
let ajaxUrlMatch = pageText.match(/url[\s]*:[\s]*'(.+)'[\s]*,/);
let ajaxUrl = "ajaxm.php";
let aihidcms = "";
let ciucjdsdc = "";
let ajaxdata = "";
let sign = "";
if (ajaxUrlMatch) {
ajaxUrl = ajaxUrlMatch[ajaxUrlMatch.length - 1];
} else {
Qmsg.error("提取ajaxm.php的具体参数失败,使用默认的" + ajaxUrl);
}
if (aihidcmsMatch) {
aihidcms = aihidcmsMatch[aihidcmsMatch.length - 1];
} else {
Qmsg.error("ajaxm.php请求参数 websignkey 获取失败");
return;
}
if (ciucjdsdcMatch) {
ciucjdsdc = ciucjdsdcMatch[ciucjdsdcMatch.length - 1];
} else {
Qmsg.error("ajaxm.php请求参数 websign 获取失败");
return;
}
if (ajaxdataMatch) {
ajaxdata = ajaxdataMatch[ajaxdataMatch.length - 1];
} else {
Qmsg.error("ajaxm.php请求参数 signs 获取失败");
return;
}
if (signMatch) {
sign = signMatch[signMatch.length - 1];
} else {
Qmsg.error("ajaxm.php请求参数 sign 获取失败");
return;
}
let postData = {
action: "downprocess",
signs: ajaxdata,
sign,
websign: ciucjdsdc,
websignkey: aihidcms,
ves: 1,
// kdns
kd: 1
};
log.success("请求的路径参数:" + ajaxUrlMatch);
log.success("ajaxm.php的请求参数-> " + postData);
let postResp = await httpx.post(that.router.root(ajaxUrl), {
data: utils.toSearchParamsStr(postData),
headers: {
Accept: "application/json, text/javascript, */*",
"Content-Type": "application/x-www-form-urlencoded",
Referer: that.router.root(that.shareCode),
"User-Agent": utils.getRandomPCUA()
}
});
if (!postResp.status) {
return;
}
let postRespData = postResp.data;
log.info(postRespData);
let jsonData = utils.toJSON(postRespData.responseText);
let downloadUrl = `${jsonData["dom"]}/file/${jsonData["url"]}`;
jsonData["zt"];
await httpx.get("https://down-load.lanrar.com/file/kdns.js", {
allowInterceptConfig: false
});
let killdns2 = await httpx.get("https://boce.lanosso.com/file/kdns2.js", {
allowInterceptConfig: false
});
if (!killdns2.status) {
downloadUrl += "&lanosso";
log.info(`测试killdns2失败使用参数 lanosso`);
} else {
log.info("测试killdns2成功,不改变原downloadUrl");
}
log.success("直链", downloadUrl);
if ("密码不正确".indexOf(jsonData["inf"]) != -1) {
Qmsg.error("密码不正确!");
NetDiskUI.newAccessCodeView(
void 0,
"lanzou",
that.netDiskIndex,
that.shareCode,
that.accessCode,
(option) => {
that.init(that.netDiskIndex, that.shareCode, option.accessCode);
}
);
} else {
fileInfo.fileName = utils.isNotNull(jsonData["inf"]) ? jsonData["inf"] : fileInfo.fileName;
log.info(downloadUrl);
return downloadUrl;
}
}
/**
* 多文件获取
* @param url 链接
*/
async getMoreFile(url) {
const that = this;
if (url == null) {
url = that.router.root(that.shareCode);
}
let getResp = await httpx.get({
url,
headers: {
Accept: "*/*",
"User-Agent": utils.getRandomAndroidUA(),
Referer: url
}
});
if (!getResp.status) {
return;
}
let respData = getResp.data;
log.info(respData);
if (respData.readyState !== 4) {
Qmsg.error("请求失败,请重试");
return;
}
let pageText = respData.responseText;
let fid = pageText.match(/\'fid\':(.+?),/)[1].replaceAll("'", "");
let uid = pageText.match(/\'uid\':(.+?),/)[1].replaceAll("'", "");
let pgs = 1;
let t_name = pageText.match(/\'t\':(.+?),/)[1];
let t_rexp = new RegExp(t_name + `[\\s]*=[\\s]*('|")(.+?)('|");`);
let t = pageText.match(t_rexp)[2];
let k_name = pageText.match(/\'k\':(.+?),/)[1];
let k_rexp = new RegExp(k_name + `[\\s]*=[\\s]*('|")(.+?)('|");`);
let k = pageText.match(k_rexp)[2];
let lx = that.shareCode.match(that.regexp.unicode.match) ? 1 : 2;
let postData = `lx=${lx}&fid=${fid}&uid=${uid}&pg=${pgs}&rep=0&t=${t}&k=${k}&up=1&ls=1&pwd=${that.accessCode}`;
log.info(`多文件请求参数:${postData}`);
let postResp = await httpx.post({
url: that.router.root("filemoreajax.php"),
responseType: "json",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"User-Agent": utils.getRandomAndroidUA(),
Referer: url
},
data: postData
});
if (!postResp.status) {
return;
}
let postRespData = postResp.data;
log.info(postRespData);
let json_data = utils.toJSON(postRespData.responseText);
let zt = json_data["zt"];
let info = json_data["info"];
if (zt === 4) {
Qmsg.error(info);
} else if (zt === 1) {
let QmsgLoading = Qmsg.loading("获取文件夹成功,解析文件直链中...");
let folder = json_data["text"];
let folderList = [];
log.info(`本链接一共${folder.length}个文件`);
for (let index = 0; index < folder.length; index++) {
let folderInfo = folder[index];
let fileShareCode = folderInfo["id"];
let fileName = folderInfo["name_all"];
let fileSize = folderInfo["size"];
let fileType = folderInfo["icon"];
let uploadTime = folderInfo["time"];
folderList.push({
fileName,
fileSize,
fileType,
createTime: uploadTime,
latestTime: uploadTime,
isFolder: false,
index: 0,
async clickEvent() {
let folderDownloadInfo = await that.parseMoreFile(
fileShareCode,
fileName,
fileSize,
uploadTime
);
if (folderDownloadInfo.success) {
return {
autoDownload: true,
mode: "aBlank",
url: folderDownloadInfo.downloadUrl
};
} else {
log.error("获取下载信息失败:", folderDownloadInfo);
Qmsg.error(folderDownloadInfo.msg);
}
}
});
}
QmsgLoading.close();
NetDiskUI.staticView.moreFile("蓝奏云文件解析", folderList);
} else if ("密码不正确".indexOf(info) !== -1) {
Qmsg.error("密码不正确!");
NetDiskUI.newAccessCodeView(
void 0,
"lanzou",
that.netDiskIndex,
that.shareCode,
that.accessCode,
(option) => {
that.init(that.netDiskIndex, that.shareCode, option.accessCode);
}
);
} else if ("没有了".indexOf(info) !== -1) {
Qmsg.error("没有文件了");
} else {
Qmsg.error("未知错误");
}
}
/**
* 文件解析并返回html-vip
* @param paramShareCode 解析多文件获取的shareCode
* @param fileName 文件名
* @param fileSize 文件大小
* @param fileUploadTime 文件上传时间
*/
async parseMoreFile(paramShareCode, fileName, fileSize, fileUploadTime) {
const that = this;
let getResp = await httpx.get({
url: that.router.root(paramShareCode),
headers: {
Accept: "*/*",
"User-Agent": utils.getRandomPCUA(),
Referer: that.router.root(that.shareCode)
}
});
log.info(getResp);
if (!getResp.status) {
return {
success: false,
fileName,
fileSize,
fileUploadTime,
msg: `解析失败,${getResp.msg}`,
downloadUrl: void 0
};
}
let respData = getResp.data;
let pageText = respData.responseText;
let pageDOM = domUtils.parseHTML(pageText, true, true);
let pageIframeElement = pageDOM.querySelector('iframe[class^="ifr"]') || pageDOM.querySelector('iframe[class^="n_downlink"]');
if (!pageIframeElement) {
return {
success: false,
fileName,
fileSize,
fileUploadTime,
msg: `解析iframe链接失败`,
downloadUrl: void 0
};
}
let iframeUrl = pageIframeElement.getAttribute("src");
log.error("该链接需要重新通过iframe地址访问获取信息", iframeUrl);
Qmsg.info("正在请求下载信息");
let downloadUrl = await that.getLinkByIframe(iframeUrl, {
fileName,
fileSize,
fileUploadTime
});
if (downloadUrl) {
if (NetDiskFilterScheme.isForwardDownloadLink("lanzou")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"lanzou",
downloadUrl
);
}
return {
success: true,
fileName,
fileSize,
fileUploadTime,
msg: "success",
downloadUrl
};
} else {
return {
success: false,
fileName,
fileSize,
fileUploadTime,
msg: `获取下载链接失败`,
downloadUrl: void 0
};
}
}
}
const LanZouUtils = {
LanZouDiskApp: "lanZouY-disk-app",
EncryptList: [
"Y",
"y",
"0",
"Z",
"z",
"N",
"n",
"M",
"I",
"6",
"m",
"W",
"w",
"1",
"X",
"x",
"L",
"l",
"K",
"7",
"k",
"i",
"U",
"u",
"2",
"V",
"v",
"J",
"j",
"8",
"G",
"g",
"F",
"S",
"s",
"3",
"T",
"t",
"H",
"h",
"f",
"E",
"e",
"D",
"Q",
"q",
"4",
"R",
"r",
"9",
"d",
"a",
"C",
"c",
"B",
"O",
"o",
"5",
"P",
"p",
"b",
"A"
],
decodeChar(e) {
for (let t = 0; t < this.EncryptList.length; t++)
if (e == this.EncryptList[t]) return t;
return -1;
},
/**
* shareCode转id
* @param {string} shareCode
*/
idEncrypt(shareCode) {
let t = 1, n = 0;
if ("" != shareCode && shareCode.length > 4) {
let r;
shareCode = shareCode.substring(3, shareCode.length - 1);
for (let index = 0; index < shareCode.length; index++)
r = shareCode.charAt(shareCode.length - index - 1), n += this.decodeChar(r) * t, t *= 62;
}
return n;
},
encrypt(e) {
const t = Cryptojs.enc.Utf8.parse(this.LanZouDiskApp), n = Cryptojs.enc.Utf8.parse(e), r = Cryptojs.AES.encrypt(n, t, {
// @ts-ignore
mode: Cryptojs.mode.ECB,
// @ts-ignore
padding: Cryptojs.pad.Pkcs7
});
return r;
},
/**
* 用于时间戳转加密字符串
* @param {any} e
* @returns
*/
encryptHex(e) {
const t = this.encrypt(e, this.LanZouDiskApp);
return t.ciphertext.toString().toUpperCase();
}
};
class NetDiskParse_Lanzouyx extends NetDiskParseObject {
constructor() {
super(...arguments);
__publicField(this, "$data", {
devType: 6,
devModel: "Chrome",
extra: 2,
type: 0,
offset: 1,
limit: 60
});
/**
* 获取的uuid
*/
__publicField(this, "uuid");
/**
* 获取的userId
**/
__publicField(this, "userId");
/**
* 加密后的shareCode
*/
__publicField(this, "shareCodeId");
}
/**
* 入口
* @param netDiskIndex
* @param shareCode
* @param accessCode
*/
async init(netDiskIndex, shareCode, accessCode) {
var _a2, _b, _c, _d;
const that = this;
log.info(netDiskIndex, shareCode, accessCode);
that.netDiskIndex = netDiskIndex;
that.shareCode = shareCode;
that.accessCode = accessCode;
that.shareCodeId = that.getDecodeShareCodeId(shareCode);
that.uuid = that.getEncodeUUID();
let linkInfo = await this.recommendList(
that.$data.devType,
that.$data.devModel,
that.uuid,
that.$data.extra,
that.getEncodeTimeStamp(),
that.shareCode,
that.$data.type,
that.$data.offset,
that.$data.limit
);
if (!linkInfo) {
return;
}
if (!linkInfo["list"].length) {
return;
}
if ((_b = (_a2 = linkInfo["list"][0]) == null ? void 0 : _a2["map"]) == null ? void 0 : _b["userId"]) {
that.userId = (_d = (_c = linkInfo["list"][0]) == null ? void 0 : _c["map"]) == null ? void 0 : _d["userId"];
} else {
Qmsg.error("解析获取【userId】为空");
return;
}
if (linkInfo["list"][0]["folderIds"] == null) {
log.success("该链接是 单文件");
let fileInfo = linkInfo["list"][0]["fileList"][0];
let folderInfoList = that.parseFolderInfo(
linkInfo["list"][0]["fileList"],
0
);
let downloadInfo = await folderInfoList[0]["clickEvent"]();
if (downloadInfo && !Array.isArray(downloadInfo)) {
let downloadUrl = downloadInfo["url"];
if (NetDiskFilterScheme.isForwardDownloadLink("lanzouyx")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"lanzouyx",
downloadUrl
);
}
NetDiskUI.staticView.oneFile({
title: "蓝奏云优享单文件直链",
fileName: fileInfo["fileName"],
fileSize: fileInfo["fileSize"] * 1024,
downloadUrl,
fileUploadTime: utils.formatToTimeStamp(fileInfo["updTime"]),
fileLatestTime: utils.formatToTimeStamp(fileInfo["updTime"])
});
}
} else {
log.success("该链接是 多文件");
Qmsg.info("正在递归文件");
let QmsgLoading = Qmsg.loading(`正在解析多文件中,请稍后...`);
let folderInfoList = that.parseFolderInfo(
linkInfo["list"][0]["fileList"],
0
);
QmsgLoading.close();
log.info("递归完毕");
NetDiskUI.staticView.moreFile("蓝奏云优享解析", folderInfoList);
}
}
/**
* 获取直链弹窗的文件夹信息
* @param infoList
* @param index
*/
parseFolderInfo(infoList, index) {
const that = this;
let folderInfoList = [];
let tempFolderInfoList = [];
let tempFolderFileInfoList = [];
infoList.forEach((item) => {
if (item["fileType"] === 2) {
tempFolderInfoList.push({
fileName: item["folderName"],
fileSize: 0,
fileType: "",
createTime: new Date(item["updTime"]).getTime(),
latestTime: new Date(item["updTime"]).getTime(),
isFolder: true,
index,
async clickEvent(event, config) {
let timestamp = that.getEncodeTimeStamp();
let folderId = item["folderId"];
let folderInfo = await that.getFolderInfo(
that.$data.devType,
that.$data.devModel,
that.uuid,
that.$data.extra,
timestamp,
that.shareCode,
folderId,
that.$data.offset,
that.$data.limit
);
if (folderInfo && folderInfo["list"]) {
return that.parseFolderInfo(folderInfo["list"], index + 1);
} else {
return [];
}
}
});
} else {
tempFolderFileInfoList.push({
fileName: item["fileName"],
fileSize: item["fileSize"] * 1024,
fileType: "",
createTime: new Date(item["updTime"]).getTime(),
latestTime: new Date(item["updTime"]).getTime(),
isFolder: false,
index,
async clickEvent() {
let fileId = item["fileId"];
let userId = item["userId"] || that.userId;
let uuid = that.uuid;
if (utils.isNull(userId)) {
Qmsg.error("获取【userId】为空");
return;
}
if (utils.isNull(uuid)) {
Qmsg.error("获取【uuid】为空");
return;
}
let downloadUrl = await that.getDownloadFileUrl(
...that.getDownloadFileParams(fileId, userId, uuid)
);
if (downloadUrl) {
if (NetDiskFilterScheme.isForwardDownloadLink("lanzouyx")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"lanzouyx",
downloadUrl
);
}
return {
url: downloadUrl,
autoDownload: true,
mode: "aBlank"
};
}
}
});
}
});
tempFolderInfoList.sort(
(leftData, rightData) => leftData["fileName"].localeCompare(rightData["fileName"])
);
tempFolderFileInfoList.sort(
(leftData, rightData) => leftData["fileName"].localeCompare(rightData["fileName"])
);
folderInfoList = folderInfoList.concat(tempFolderInfoList);
folderInfoList = folderInfoList.concat(tempFolderFileInfoList);
return folderInfoList;
}
/**
* 获取列表信息
* @param devType
* @param devModel
* @param uuid
* @param extra
* @param timestamp
* @param shareId
* @param type
* @param offset
* @param limit
*/
async recommendList(devType = this.$data.devType, devModel = this.$data.devModel, uuid = "", extra = this.$data.extra, timestamp = "", shareId = "", type = this.$data.type, offset = this.$data.offset, limit = this.$data.limit) {
let response = await httpx.post(
`https://api.ilanzou.com/unproved/recommend/list?${utils.toSearchParamsStr(
{
devType,
devModel,
uuid,
extra,
timestamp,
shareId,
code: this.accessCode,
type,
offset,
limit
}
)}`,
{
headers: {
Accept: "application/json, text/plain, */*",
Origin: "https://www.ilanzou.com",
Referer: "https://www.ilanzou.com/",
"Sec-Fetch-Site": "same-site",
Host: "api.ilanzou.com",
"User-Agent": utils.getRandomPCUA()
},
responseType: "json"
}
);
if (!response.status) {
return;
}
let data = utils.toJSON(response.data.responseText);
log.success("获取链接信息:", data);
if (data["code"] !== 200) {
Qmsg.error("请求链接信息失败");
return;
}
if (!data["list"].length) {
Qmsg.error("获取链接信息为空");
return;
}
return data;
}
/**
* 获取文件夹信息
* @param devType
* @param devModel
* @param uuid
* @param extra
* @param timestamp
* @param shareId
* @param folderId
* @param offset
* @param limit
*/
async getFolderInfo(devType = this.$data.devType, devModel = this.$data.devModel, uuid = "", extra = this.$data.extra, timestamp = "", shareId = "", folderId = "", offset = this.$data.offset, limit = this.$data.limit) {
let response = await httpx.post(
`https://api.ilanzou.com/unproved/share/list?${utils.toSearchParamsStr({
devType,
devModel,
uuid,
extra,
timestamp,
shareId,
code: this.accessCode,
folderId,
offset,
limit
})}`,
{
headers: {
Accept: "application/json, text/plain, */*",
Origin: "https://www.ilanzou.com",
Referer: "https://www.ilanzou.com/",
"Sec-Fetch-Site": "same-site",
Host: "api.ilanzou.com",
"User-Agent": utils.getRandomPCUA()
}
}
);
if (!response.status) {
return;
}
let data = utils.toJSON(response.data.responseText);
log.success("获取文件列表信息:", data);
if (data["code"] === 200) {
return data;
} else {
Qmsg.error(data["msg"]);
}
}
/**
* 获取下载链接
*/
async getDownloadFileUrl(downloadId = "", enable = 1, devType = this.$data.devType, uuid = "", timestamp = "", auth = "", shareId = this.shareCode) {
let url = `https://api.ilanzou.com/unproved/file/redirect?${utils.toSearchParamsStr(
{
downloadId,
enable,
devType,
uuid,
timestamp,
auth,
shareId
}
)}`;
return url;
}
/**
* 获取加密的uuid
* @param timestamp
*/
getEncodeUUID(timestamp = 21) {
let r = (e = 21) => crypto.getRandomValues(new Uint8Array(e)).reduce(
(e2, t) => (t &= 63, e2 += t < 36 ? t.toString(36) : t < 62 ? (t - 26).toString(36).toUpperCase() : t > 62 ? "-" : "_", e2),
""
);
return r(timestamp);
}
/**
* 获取shareCode转换后的id
*/
getDecodeShareCodeId(shareCode) {
return LanZouUtils.idEncrypt(shareCode);
}
/**
* 获取加密后的timestamp
* @param time
*/
getEncodeTimeStamp(time = Date.now()) {
return LanZouUtils.encryptHex(time);
}
/**
* 获取下载文件的参数
* @param fileId 文件id
* @param userId 用户id
* @param uuid 用户登录生成的uuid
*/
getDownloadFileParams(fileId, userId = "", uuid) {
const that = this;
let nowTime = Date.now();
let downloadId = LanZouUtils.encryptHex(fileId + "|" + userId), enable = 1, timestamp = that.getEncodeTimeStamp(nowTime), auth = LanZouUtils.encryptHex(fileId + "|" + nowTime);
return [
downloadId,
enable,
this.$data.devType,
uuid,
timestamp,
auth,
that.shareCode
];
}
/**
* 前往登录
*/
gotoLogin() {
NetDiskPops.confirm(
{
title: {
position: "center",
text: "蓝奏云优享"
},
content: {
text: "必须先在【蓝奏云优享】进行登录,然后登录成功后刷新获取必备的下载参数【uuid】和【userId】。",
html: false
},
btn: {
reverse: true,
position: "end",
ok: {
text: "前往",
enable: true,
callback() {
window.open("https://www.ilanzou.com", "_blank");
}
}
}
},
NetDiskUI.popsStyle.tianYiYunLoginTip
);
}
}
class NetDiskParse_nainiu extends NetDiskParseObject {
constructor() {
super(...arguments);
__publicField(this, "panelList", []);
__publicField(this, "panelContent", "");
__publicField(this, "OK_CODE", "0000");
}
async init(netDiskIndex, shareCode, accessCode) {
const that = this;
log.info(netDiskIndex, shareCode, accessCode);
that.netDiskIndex = netDiskIndex;
that.shareCode = shareCode;
that.accessCode = accessCode;
that.panelList = [];
that.panelContent = "";
let checkLinkValidityInfo = await that.checkLinkValidity(
that.shareCode,
that.accessCode
);
if (!checkLinkValidityInfo) {
return;
}
if (checkLinkValidityInfo.isFolder) {
Qmsg.info("正在递归文件");
let QmsgLoading = Qmsg.loading(`正在解析多文件中,请稍后...`);
let firstFolderInfo = await that.getShareFolder(
checkLinkValidityInfo["data"]["guid"]
);
if (!firstFolderInfo) {
QmsgLoading.close();
return;
}
let firstFileInfo = await that.getShareFiles(
checkLinkValidityInfo["data"]["guid"]
);
if (!firstFileInfo) {
QmsgLoading.close();
return;
}
let folderInfoList = that.getFolderInfo(
checkLinkValidityInfo["data"]["guid"],
firstFolderInfo,
firstFileInfo,
0
);
QmsgLoading.close();
log.info("递归完毕");
NetDiskUI.staticView.moreFile("奶牛快传文件解析", folderInfoList);
} else {
let downloadUrl = void 0;
if (checkLinkValidityInfo["zipDownload"]) {
downloadUrl = await that.getZipFileDownloadUrl(
that.shareCode,
checkLinkValidityInfo["guid"],
checkLinkValidityInfo["fileName"]
);
} else {
downloadUrl = await that.getDownloadUrl(
that.shareCode,
checkLinkValidityInfo["guid"],
checkLinkValidityInfo["id"]
);
}
if (!downloadUrl) {
return;
}
if (NetDiskFilterScheme.isForwardDownloadLink("nainiu")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"nainiu",
downloadUrl
);
}
NetDiskUI.staticView.oneFile({
title: "奶牛快传单文件直链",
fileName: checkLinkValidityInfo["fileName"],
fileType: checkLinkValidityInfo["fileType"],
fileSize: checkLinkValidityInfo["fileSize"],
downloadUrl,
fileUploadTime: checkLinkValidityInfo["fileUploadTime"],
fileLatestTime: checkLinkValidityInfo["fileLatestTime"],
clickCallBack: (_fileDetails_) => {
that.downloadFile(checkLinkValidityInfo["fileName"], downloadUrl);
}
});
}
}
/**
* 校验链接有效性并解析获取信息
* @param shareCode
* @param accessCode
*/
async checkLinkValidity(shareCode, accessCode) {
const that = this;
let resultJSON = await that.getShareByUniqueUrl(shareCode);
if (!resultJSON) {
return false;
}
let code = resultJSON["code"];
let message = resultJSON["message"];
if (code !== that.OK_CODE) {
Qmsg.error(message);
return false;
} else {
let needPassword = resultJSON["data"]["needPassword"];
let zipDownload = resultJSON["data"]["zipDownload"];
if (needPassword && utils.isNull(accessCode)) {
Qmsg.error("密码缺失!");
NetDiskUI.newAccessCodeView(
"密码缺失",
"nainiu",
that.netDiskIndex,
that.shareCode,
that.accessCode,
(option) => {
that.init(that.netDiskIndex, that.shareCode, option.accessCode);
}
);
return false;
} else if (zipDownload) {
Qmsg.success("该链接为zip单文件");
return {
zipDownload,
guid: resultJSON["data"]["guid"],
fileSize: utils.formatByteToSize(
resultJSON["data"]["firstFolder"]["size"]
),
fileName: resultJSON["data"]["firstFolder"]["title"],
fileUploadTime: utils.formatTime(
resultJSON["data"]["firstFolder"]["created_at"]
),
fileLatestTime: utils.formatTime(
resultJSON["data"]["firstFolder"]["updated_at"]
)
};
} else if (resultJSON["data"]["firstFile"] == void 0) {
Qmsg.success("该链接为文件夹类型");
return {
isFolder: true,
guid: resultJSON["data"]["guid"],
firstFolder: resultJSON["data"]["firstFolder"],
data: resultJSON["data"]
};
}
return {
zipDownload,
guid: resultJSON["data"]["guid"],
id: resultJSON["data"]["firstFile"]["id"],
fileSize: utils.formatByteToSize(
resultJSON["data"]["firstFile"]["file_info"]["size"]
),
fileName: resultJSON["data"]["firstFile"]["file_info"]["title"],
fileType: resultJSON["data"]["firstFile"]["file_info"]["format"],
fileUploadTime: utils.formatTime(
resultJSON["data"]["firstFile"]["created_at"]
),
fileLatestTime: utils.formatTime(
resultJSON["data"]["firstFile"]["updated_at"]
)
};
}
}
/**
* 获取直链弹窗的文件夹信息
* @returns
*/
getFolderInfo(transferGuid, shareFolderInfoList, shareFileInfoList, index = 0) {
const that = this;
let folderInfoList = [];
let tempFolderInfoList = [];
let tempFolderFileInfoList = [];
shareFolderInfoList.forEach((folderInfo) => {
folderInfoList.push({
fileName: folderInfo["title"],
fileSize: 0,
fileType: "",
createTime: folderInfo["created_at"],
latestTime: folderInfo["updated_at"],
isFolder: true,
index,
async clickEvent() {
if (!folderInfo["child_folder_count"] && !folderInfo["content_count"]) {
return [];
}
let childFolderInfo = await that.getShareFolder(
transferGuid,
folderInfo["id"]
);
if (!childFolderInfo) {
return [];
}
let childFileInfo = await that.getShareFiles(
transferGuid,
folderInfo["id"]
);
if (!childFileInfo) {
return [];
}
let folderInfoList2 = that.getFolderInfo(
transferGuid,
childFolderInfo,
childFileInfo,
index + 1
);
return folderInfoList2;
}
});
});
shareFileInfoList.forEach((fileInfo) => {
let fileName = fileInfo["file_info"]["title"];
let fileType = fileInfo["file_info"]["format"] ?? "";
if (Boolean(fileType)) {
fileName = fileName + "." + fileType;
}
folderInfoList.push({
fileName,
fileSize: fileInfo["file_info"]["size"],
fileType,
createTime: fileInfo["created_at"],
latestTime: fileInfo["updated_at"],
isFolder: false,
index,
async clickEvent() {
let downloadUrl = await that.getDownloadUrl(
that.shareCode,
transferGuid,
fileInfo["id"]
);
if (!downloadUrl) {
return;
}
if (NetDiskFilterScheme.isForwardDownloadLink("nainiu")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"nainiu",
downloadUrl
);
}
that.downloadFile(fileName, downloadUrl);
}
});
});
tempFolderInfoList.sort(
(a, b) => a["fileName"].localeCompare(b["fileName"])
);
tempFolderFileInfoList.sort(
(a, b) => a["fileName"].localeCompare(b["fileName"])
);
folderInfoList = folderInfoList.concat(tempFolderInfoList);
folderInfoList = folderInfoList.concat(tempFolderFileInfoList);
log.info("getFolderInfo", folderInfoList);
return folderInfoList;
}
/**
* 文件解析
* @param shareCode
* @param accessCode
*/
async parseMoreFile(shareCode, accessCode) {
}
/**
* 获取文件夹信息
* @param transferGuid
* @param folderId
* @param page
* @param size
*/
async getShareFolder(transferGuid, folderId = "", page = 0, size = 100) {
const that = this;
let getResp = await httpx.get(
`https://cowtransfer.com/core/api/transfer/share/folders?transferGuid=${transferGuid}&folderId=${folderId}&page=${page}&size=${size}`,
{
headers: {
Accept: "application/json",
"User-Agent": utils.getRandomPCUA(),
Referer: "https://cowtransfer.com/"
}
}
);
log.success(getResp);
if (!getResp.status) {
return;
}
let data = utils.toJSON(getResp.data.responseText);
if (data.code !== that.OK_CODE) {
Qmsg.error(data["message"]);
return;
}
let folders = data["data"]["folders"];
if (!Array.isArray(folders)) {
Qmsg.error("data.folders不是数组");
return;
}
return folders;
}
/**
* 获取文件信息
* @param transferGuid
* @param folderId
* @param page
* @param size
* @param subContent
*/
async getShareFiles(transferGuid, folderId = "", page = 0, size = 20, subContent = false) {
const that = this;
let getResp = await httpx.get(
`https://cowtransfer.com/core/api/transfer/share/files?transferGuid=${transferGuid}&folderId=${folderId}&page=${page}&size=${size}&subContent=${subContent}`,
{
headers: {
Accept: "application/json",
"User-Agent": utils.getRandomPCUA(),
Referer: "https://cowtransfer.com/"
}
}
);
log.success(getResp);
if (!getResp.status) {
return;
}
let data = utils.toJSON(getResp.data.responseText);
if (data.code !== that.OK_CODE) {
Qmsg.error(data["message"]);
return;
}
let files = data["data"]["files"];
if (!Array.isArray(files)) {
Qmsg.error("data.files不是数组");
return;
}
return files;
}
/**
* 获取分享信息
* @param {string} shareCode
*/
async getShareByUniqueUrl(shareCode) {
let url = `https://cowtransfer.com/core/api/transfer/share?uniqueUrl=${shareCode}`;
let getResp = await httpx.get({
url,
headers: {
"User-Agent": utils.getRandomPCUA(),
Referer: "https://cowtransfer.com/s/" + shareCode
}
});
log.info(getResp);
if (!getResp.status) {
return;
}
let respData = getResp.data;
let resultJSON = utils.toJSON(respData.responseText);
log.info("转换的JSON", resultJSON);
return resultJSON;
}
/**
* 获取下载链接
* @param shareCode
* @param guid
* @param id
*/
async getDownloadUrl(shareCode, guid = "", id = "") {
const that = this;
let url = `https://cowtransfer.com/core/api/transfer/share/download?transferGuid=${guid}&fileId=${id}`;
let getResp = await httpx.get({
url,
headers: {
"User-Agent": utils.getRandomPCUA(),
Referer: "https://cowtransfer.com/s/" + shareCode
}
});
log.info(getResp);
if (!getResp.status) {
return;
}
let respData = getResp.data;
let resultJSON = utils.toJSON(respData.responseText);
log.info("转换的JSON", resultJSON);
if (resultJSON["code"] === that.OK_CODE) {
return resultJSON["data"]["downloadUrl"];
} else {
Qmsg.error(`奶牛快传-获取直链:${resultJSON["message"]}`);
return;
}
}
/**
* 获取zip文件的下载链接
* @param shareCode
* @param guid
* @param title 标题
*/
async getZipFileDownloadUrl(shareCode, guid = "", title = "") {
const that = this;
let url = `https://cowtransfer.com/core/api/transfer/share/download?transferGuid=${guid}&title=${title}`;
let getResp = await httpx.get({
url,
headers: {
"User-Agent": utils.getRandomPCUA(),
Referer: "https://cowtransfer.com/s/" + shareCode
}
});
log.info(getResp);
if (!getResp.status) {
return;
}
let respData = getResp.data;
let resultJSON = utils.toJSON(respData.responseText);
log.info("转换的JSON", resultJSON);
if (resultJSON["code"] === that.OK_CODE) {
return resultJSON["data"]["downloadUrl"];
} else {
Qmsg.error(`奶牛快传-获取直链:${resultJSON["message"]}`);
return;
}
}
/**
* 下载文件
* @param {string} fileName 文件名
* @param {string} fileDownloadUrl 下载地址
*/
async downloadFile(fileName, fileDownloadUrl) {
const that = this;
log.info("下载文件:", fileName, fileDownloadUrl);
Qmsg.info(`调用【GM_download】下载:${fileName}`);
if (typeof _GM_download === "undefined") {
Qmsg.error("当前脚本环境缺失API 【GM_download】");
return;
}
let abortDownload = void 0;
let downloadingQmsg = Qmsg.loading("下载中...", {
showClose: true,
onClose() {
if (typeof abortDownload === "function") {
abortDownload();
}
}
});
let isDownloadEnd = false;
let GM_download_Result = _GM_download({
url: fileDownloadUrl,
name: fileName,
headers: {
Referer: "https://cowtransfer.com/s/" + that.shareCode
},
onload() {
downloadingQmsg.close();
Qmsg.success(`下载 ${fileName} 已完成`);
},
onprogress(details) {
if (typeof details === "object" && "loaded" in details && "total" in details && !isDownloadEnd) {
let progressNum = details.loaded / details.total;
let formatProgressNum = (progressNum * 100).toFixed(2);
downloadingQmsg.setText(`下载中...${formatProgressNum}%`);
if (details.loaded === details.total) {
isDownloadEnd = true;
}
}
},
onerror(error) {
downloadingQmsg.close();
log.error("下载失败error👉", error);
if (typeof error === "object" && error["error"]) {
Qmsg.error(`下载 ${fileName} 失败或已取消 原因:${error["error"]}`, {
timeout: 6e3
});
} else {
Qmsg.error(`下载 ${fileName} 失败或已取消`);
}
},
ontimeout() {
downloadingQmsg.close();
Qmsg.error(`下载 ${fileName} 请求超时`);
}
});
if (typeof GM_download_Result === "object" && "abort" in GM_download_Result) {
abortDownload = GM_download_Result["abort"];
}
}
}
class NetDiskParse_Tianyiyun extends NetDiskParseObject {
constructor() {
super(...arguments);
__publicField(this, "shareId");
/* 猜测1是有密码,2是无密码 */
__publicField(this, "shareMode", 1);
__publicField(this, "code", {
ShareNotFoundFlatDir: "抱歉,该文件的分享平铺目录未找到",
ShareNotFound: "抱歉,您访问的页面地址有误,或者该页面不存在。",
ShareAuditNotPass: "抱歉,该内容审核不通过",
FileNotFound: "抱歉,文件不存在",
ShareExpiredError: "抱歉,您访问的页面地址有误,或者该页面不存在",
ShareAuditWaiting: "抱歉,该链接处于审核中",
ShareInfoNotFound: "抱歉,您访问的页面地址有误,或者该页面不存在",
FileTooLarge: "抱歉,文件太大,不支持下载",
InvalidSessionKey: "天翼云PC端Cookie未生成,是否前去登录?
(注意,需要当前浏览器的UA切换成PC且在登录后要等待进入个人云空间后生成Cookie,不是手机端浏览的个人云空间,那样生成的Cookie无法使用)"
});
}
async init(netDiskIndex, shareCode, accessCode) {
const that = this;
log.info(netDiskIndex, shareCode, accessCode);
that.netDiskIndex = netDiskIndex;
that.shareCode = shareCode;
that.accessCode = accessCode;
let shareInfoData = await that.getShareInfoByCodeV2(shareCode);
if (!shareInfoData) {
return;
}
log.info("解析的JSON信息", shareInfoData);
if (shareInfoData["needAccessCode"] && utils.isNull(that.accessCode)) {
Qmsg.error("密码不正确!");
NetDiskUI.newAccessCodeView(
void 0,
"tianyiyun",
that.netDiskIndex,
that.shareCode,
that.accessCode,
(option) => {
that.init(that.netDiskIndex, that.shareCode, option.accessCode);
}
);
return;
}
if ("shareId" in shareInfoData) {
this.shareId = shareInfoData["shareId"];
} else {
let newShareId = await that.getShareId(shareCode, accessCode);
if (newShareId) {
this.shareId = newShareId;
}
}
if ("shareMode" in shareInfoData) {
this.shareMode = shareInfoData["shareMode"];
}
if (this.shareId == null) {
return;
}
if (shareInfoData.isFolder) {
Qmsg.info("正在递归文件");
let QmsgLoading = Qmsg.loading(`正在解析多文件中,请稍后...`);
let fileId = shareInfoData["fileId"];
let folderInfo = await that.listShareDir(
shareCode,
accessCode,
void 0,
void 0,
fileId,
fileId,
void 0,
this.shareId,
void 0,
void 0,
void 0
);
if (!folderInfo) {
QmsgLoading.close();
return;
}
let folderInfoList = that.getFolderInfo(
shareCode,
accessCode,
folderInfo,
0
);
QmsgLoading.close();
log.info("递归完毕");
NetDiskUI.staticView.moreFile("天翼云文件解析", folderInfoList);
return;
} else {
let downloadUrl = await that.getDownloadUrl(
that.shareCode,
that.accessCode,
shareInfoData.fileId,
this.shareId
);
if (downloadUrl) {
if (NetDiskFilterScheme.isForwardDownloadLink("tianyiyun")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"tianyiyun",
downloadUrl
);
}
NetDiskUI.staticView.oneFile({
title: "天翼云单文件直链",
fileName: shareInfoData.fileName,
fileSize: utils.formatByteToSize(shareInfoData.fileSize),
downloadUrl,
fileUploadTime: shareInfoData.fileCreateDate,
fileLatestTime: shareInfoData.fileLastOpTime
});
}
}
}
/**
* 获取当前登录用户的信息
* @returns {Promise{
* encryptAccount: string,
* icon: string,
* nickname: string,
* res_code: string,
* res_message: string,
* sessionKey: string,
* userAccount: string
* }>}
*/
async getUserBriefInfo(shareCode) {
const that = this;
let getResp = await httpx.get(
"https://cloud.189.cn/api/portal/v2/getUserBriefInfo.action",
{
headers: {
Accept: "application/json;charset=UTF-8",
Referer: "https://cloud.189.cn/web/share?code=" + shareCode,
"User-Agent": utils.getRandomPCUA()
},
allowInterceptConfig: false,
onerror() {
}
}
);
log.info(getResp);
if (!getResp.status) {
let errorResultJSON = utils.toJSON(getResp.data.responseText);
if (errorResultJSON["res_code"] in that.code) {
Qmsg.error(
that.code[errorResultJSON["res_code"]]
);
} else {
Qmsg.error("请求异常");
}
return;
}
let data = utils.toJSON(getResp.data.responseText);
if (data["res_code"] === 0) {
return data;
}
}
/**
* 获取分享信息
* @param {string} shareCode
* @returns
*/
async getShareInfoByCodeV2(shareCode) {
const that = this;
let postResp = await httpx.post({
url: "https://cloud.189.cn/api/open/share/getShareInfoByCodeV2.action",
data: `shareCode=${shareCode}`,
headers: {
Accept: "application/json;charset=UTF-8",
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": utils.getRandomPCUA(),
"Sign-Type": 1,
Referer: "https://cloud.189.cn/web/share?code=" + shareCode,
Origin: "https://cloud.189.cn"
},
allowInterceptConfig: false,
onerror() {
}
});
if (!postResp.status) {
let errorData = utils.toJSON(postResp.data.responseText);
log.error("获取下载参数失败的JSON信息", errorData);
if (errorData["res_code"] in that.code) {
Qmsg.error(that.code[errorData["res_code"]]);
} else {
Qmsg.error(errorData["res_message"]);
}
return;
}
let postData = postResp.data;
log.info(postData);
let data = utils.toJSON(postData.responseText);
if (data["res_code"] == 0) {
return data;
} else {
if (that.code.hasOwnProperty(data["res_code"])) {
Qmsg.error(that.code[data["res_code"]]);
} else {
Qmsg.error("获取FileId失败");
}
}
}
/**
* 获取shareId
*/
async getShareId(shareCode, accessCode) {
let getResp = await httpx.get({
url: `https://cloud.189.cn/api/open/share/checkAccessCode.action?shareCode=${shareCode}&accessCode=${accessCode}`,
headers: {
Accept: "application/json;charset=UTF-8",
"Cache-Control": "no-cache",
"User-Agent": utils.getRandomPCUA(),
"Sign-Type": 1,
Referer: `https://cloud.189.cn/web/share?code=${shareCode}`
},
responseType: "json"
});
if (!getResp.status) {
return;
}
let respData = getResp.data;
log.info(respData);
let data = utils.toJSON(respData.responseText);
if (data["res_code"] === 0 && "shareId" in data) {
return data["shareId"];
} else {
Qmsg.error("获取shareId失败");
log.info(data);
}
}
/**
* 获取随机noCache
* @returns {string}
*/
getNoCacheValue() {
let result = "";
for (let index = 0; index < 17; index++) {
result += utils.getRandomValue(1, 9);
}
return "0." + result;
}
/**
* 获取下载链接
* @param {string} shareCode
* @param {string} accessCode
* @param {number} fileId
* @param {number} shareId
* @returns {Promise}
*/
async getDownloadUrl(shareCode, accessCode, fileId, shareId) {
const that = this;
let getResp = await httpx.get({
url: `https://cloud.189.cn/api/open/file/getFileDownloadUrl.action?fileId=${fileId}&dt=1&shareId=${shareId}`,
headers: {
Accept: "application/json;charset=UTF-8",
"Cache-Control": "no-cache",
"User-Agent": utils.getRandomPCUA(),
Referer: `https://cloud.189.cn/web/share?code=${shareCode}`,
"Sign-Type": 1
},
responseType: "json",
allowInterceptConfig: false,
onerror() {
}
});
log.info(getResp);
if (!getResp.status) {
let errorResultJSON = utils.toJSON(getResp.data.responseText);
if (errorResultJSON["errorCode"] === "InvalidSessionKey") {
that.gotoLogin(that.code["InvalidSessionKey"]);
} else if (errorResultJSON["res_code"] in that.code) {
Qmsg.error(
that.code[errorResultJSON["res_code"]]
);
} else {
Qmsg.error("请求异常");
}
return;
}
let respData = getResp.data;
let data = utils.toJSON(respData.responseText);
log.info(data);
if (data["res_code"] === 0) {
return data["fileDownloadUrl"];
} else if ("InvalidSessionKey" === data["res_code"] || "InvalidSessionKey" === data["errorCode"]) {
that.gotoLogin(that.code["InvalidSessionKey"]);
} else if (that.code.hasOwnProperty(data["res_code"])) {
Qmsg.error(that.code[data["res_code"]]);
} else {
Qmsg.error("请求失败");
log.error(respData);
}
}
/**
* 天翼云登录弹窗
* @param text 弹窗的显示的内容
*/
gotoLogin(text = "") {
NetDiskPops.confirm(
{
title: {
position: "center",
text: "天翼云"
},
content: {
text,
html: false
},
btn: {
reverse: true,
position: "end",
ok: {
text: "前往",
enable: true,
callback() {
window.open(
"https://cloud.189.cn/api/portal/loginUrl.action?redirectURL=https://cloud.189.cn/web/main",
"_blank"
);
}
}
}
},
NetDiskUI.popsStyle.tianYiYunLoginTip
);
}
/**
* 解析文件夹信息
*/
async listShareDir(shareCode, accessCode, pageNum = 1, pageSize = 60, fileId, shareDirFileId, isFolder = true, shareId, iconOption = 5, orderBy = "lastOpTime", descending = true) {
const that = this;
const getSearParamData = {
pageNum,
pageSize,
fileId,
shareDirFileId,
isFolder,
shareId,
shareMode: this.shareMode,
iconOption,
orderBy,
descending,
accessCode
};
let getResp = await httpx.get(
`https://cloud.189.cn/api/open/share/listShareDir.action?${utils.toSearchParamsStr(
getSearParamData
)}`,
{
headers: {
Accept: "application/json;charset=UTF-8",
Referer: `https://cloud.189.cn/web/share?code=${shareCode}`,
"Sign-Type": 1,
"User-Agent": utils.getRandomPCUA()
},
responseType: "json",
allowInterceptConfig: false,
onerror() {
}
}
);
if (!getResp.status) {
let errorData = utils.toJSON(getResp.data.responseText);
log.error("解析文件夹信息失败", errorData);
if (errorData["res_code"] in that.code) {
Qmsg.error(that.code[errorData["res_code"]]);
} else if ("res_message" in errorData) {
Qmsg.error(errorData["res_message"]);
} else {
Qmsg.error("解析文件夹信息失败");
}
return;
}
let getData = getResp.data;
log.info(getData);
let data = utils.toJSON(getData.responseText);
if (data["res_code"] == 0) {
return data["fileListAO"];
} else {
if (that.code.hasOwnProperty(data["res_code"])) {
Qmsg.error(that.code[data["res_code"]]);
} else {
Qmsg.error("获取FileId失败");
}
}
}
/**
* 获取直链弹窗的文件夹信息
*/
getFolderInfo(shareCode, accessCode, dirInfo, index = 0) {
const that = this;
let folderInfoList = [];
let tempFolderInfoList = [];
let tempFolderFileInfoList = [];
dirInfo["folderList"].forEach((folderInfo) => {
folderInfoList.push({
fileName: folderInfo["name"],
fileSize: 0,
fileType: "",
createTime: utils.formatToTimeStamp(folderInfo["createDate"]),
latestTime: utils.formatToTimeStamp(folderInfo["lastOpTime"]),
isFolder: true,
index,
async clickEvent() {
let _folderInfo_ = await that.listShareDir(
shareCode,
accessCode,
1,
100,
folderInfo["id"],
folderInfo["id"],
void 0,
that.shareId,
void 0,
void 0,
void 0
);
if (!_folderInfo_) {
return [];
}
return that.getFolderInfo(
shareCode,
accessCode,
_folderInfo_,
index + 1
);
}
});
});
dirInfo["fileList"].forEach((fileInfo) => {
folderInfoList.push({
fileName: fileInfo["name"],
fileSize: fileInfo["size"],
fileType: "",
createTime: utils.formatToTimeStamp(fileInfo["createDate"]),
latestTime: utils.formatToTimeStamp(fileInfo["lastOpTime"]),
isFolder: false,
index,
async clickEvent() {
let downloadUrl = await that.getDownloadUrl(
shareCode,
accessCode,
fileInfo["id"],
that.shareId
);
if (downloadUrl) {
if (NetDiskFilterScheme.isForwardDownloadLink("tianyiyun")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"tianyiyun",
downloadUrl
);
}
return {
autoDownload: true,
mode: "aBlank",
url: downloadUrl
};
}
}
});
});
tempFolderInfoList.sort(
(a, b) => a["fileName"].localeCompare(b["fileName"])
);
tempFolderFileInfoList.sort(
(a, b) => a["fileName"].localeCompare(b["fileName"])
);
folderInfoList = folderInfoList.concat(tempFolderInfoList);
folderInfoList = folderInfoList.concat(tempFolderFileInfoList);
log.info("getFolderInfo", folderInfoList);
return folderInfoList;
}
}
class NetDiskParse_UC extends NetDiskParseObject {
/**
* 入口
* @param netDiskIndex 网盘名称索引下标
* @param shareCode
* @param accessCode
*/
async init(netDiskIndex, shareCode, accessCode) {
const that = this;
log.info(netDiskIndex, shareCode, accessCode);
that.netDiskIndex = netDiskIndex;
that.shareCode = shareCode;
that.accessCode = accessCode;
Qmsg.info("检查是否已登录UC网盘");
let loginStatus = await that.isLogin();
if (!Boolean(loginStatus)) {
that.gotoLogin(
"检测到尚未登录UC网盘,是否前去登录?
(注意,需要当前浏览器的UA切换成PC才有登录选项)"
);
return;
}
let stoken = await that.getStoken(that.shareCode, that.accessCode);
if (!stoken) {
return;
}
let detail = await that.getDetail(that.shareCode, that.accessCode, stoken);
if (!detail) {
Qmsg.error("UC网盘:获取detail失败");
return;
}
if (detail.length === 1 && detail[0].dir == false && detail[0].file_type === 1) {
let oneFileDetail = detail[0];
let oneFileDownloadDetail = await that.getDownload(
that.shareCode,
stoken,
oneFileDetail.fid,
oneFileDetail.share_fid_token
);
if (!oneFileDownloadDetail) {
return;
}
if (!oneFileDownloadDetail[0].download_url) {
Qmsg.error("获取download_url失败");
return;
}
NetDiskUI.staticView.oneFile({
title: "UC网盘单文件直链",
fileName: oneFileDownloadDetail[0].file_name,
fileSize: utils.formatByteToSize(oneFileDownloadDetail[0].size),
downloadUrl: oneFileDownloadDetail[0].download_url,
fileUploadTime: utils.formatTime(oneFileDownloadDetail[0].created_at),
fileLatestTime: utils.formatTime(
oneFileDownloadDetail[0].last_update_at
),
clickCallBack() {
that.downloadFile(
oneFileDownloadDetail[0].file_name,
oneFileDownloadDetail[0].download_url
);
}
});
} else {
Qmsg.info("正在递归文件");
let QmsgLoading = Qmsg.loading(`正在解析多文件中,请稍后...`);
let folderInfoList = that.getFolderInfo(detail, stoken, 0);
QmsgLoading.close();
log.info("递归完毕");
NetDiskUI.staticView.moreFile("UC网盘文件解析", folderInfoList);
return;
}
}
/**
* 判断是否已登录UC网盘
*/
async isLogin() {
let getResp = await httpx.get("https://drive.uc.cn/", {
headers: {
"User-Agent": utils.getRandomPCUA()
}
});
log.success("判断是否已登录UC网盘", getResp);
if (!getResp.status) {
return;
}
if (getResp.data.finalUrl === "https://drive.uc.cn/list") {
return "已登录";
} else {
return false;
}
}
/**
* 下载文件
* @param fileName 文件名
* @param downloadUrl 下载链接
*/
downloadFile(fileName, downloadUrl) {
log.info(`调用【GM_download】下载:`, arguments);
Qmsg.info(`调用【GM_download】下载:${fileName}`);
if (typeof _GM_download === "undefined") {
Qmsg.error("当前脚本环境缺失API 【GM_download】");
return;
}
let downloadingQmsg = Qmsg.loading("下载中...");
let isDownloadEnd = false;
return _GM_download({
url: downloadUrl,
name: fileName,
headers: {
Referer: "https://drive.uc.cn/"
},
onload() {
downloadingQmsg.close();
Qmsg.success(`下载 ${fileName} 已完成`);
},
onprogress(details) {
if (typeof details === "object" && "loaded" in details && "total" in details && !isDownloadEnd) {
let progressNum = details.loaded / details.total;
let formatProgressNum = (progressNum * 100).toFixed(2);
downloadingQmsg.setText(`下载中...${formatProgressNum}%`);
if (details.loaded === details.total) {
isDownloadEnd = true;
}
}
},
onerror(error) {
downloadingQmsg.close();
log.error("下载失败error👉", error);
if (typeof error === "object" && error["error"]) {
Qmsg.error(`下载 ${fileName} 失败或已取消 原因:${error["error"]}`, {
timeout: 6e3
});
} else {
Qmsg.error(`下载 ${fileName} 失败或已取消`);
}
},
ontimeout() {
downloadingQmsg.close();
Qmsg.error(`下载 ${fileName} 请求超时`);
}
});
}
/**
* 前往登录
* @param text 弹窗的显示的内容
*/
gotoLogin(text = "") {
NetDiskPops.confirm(
{
title: {
position: "center",
text: "UC网盘"
},
content: {
text,
html: false
},
btn: {
reverse: true,
position: "end",
ok: {
text: "前往",
enable: true,
callback() {
window.open("https://drive.uc.cn", "_blank");
}
}
}
},
NetDiskUI.popsStyle.tianYiYunLoginTip
);
}
/**
* 获取stoken
* @param pwd_id 分享码
* @param passcode 访问码
*/
async getStoken(pwd_id, passcode) {
let postResp = await httpx.post(
"https://pc-api.uc.cn/1/clouddrive/share/sharepage/token?entry=ft&fr=pc&pr=UCBrowser",
{
data: JSON.stringify({
share_for_transfer: true,
passcode,
pwd_id
}),
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8",
"User-Agent": utils.getRandomPCUA(),
Origin: "https://drive.uc.cn",
Referer: "https://drive.uc.cn/"
},
allowInterceptConfig: false,
onerror() {
}
}
);
if (!postResp.status) {
let errorData = utils.toJSON(postResp.data.responseText);
log.error("获取stoken失败JSON信息", errorData);
if ("message" in errorData) {
Qmsg.error(errorData["message"]);
} else {
Qmsg.error("请求异常,获取stoken失败");
}
return;
}
let data = utils.toJSON(postResp.data.responseText);
log.info("获取stoken:", data);
if (data["code"] !== 0) {
log.error("获取stoken失败", data);
Qmsg.error("获取stoken失败");
return;
}
return data["data"]["stoken"];
}
/**
* 获取stoken
* @param pwd_id 分享码
* @param passcode 访问码
* @param stoken 获取的stoken
* @param pdir_fid 父fid,默认为0,如果为文件夹,那么它的fid就是这个值
* @param force
* @param _page
* @param _size=
* @param _fetch_banner
* @param _fetch_share
* @param _fetch_total
*/
async getDetail(pwd_id, passcode, stoken, pdir_fid = 0, force = 0, _page = 1, _size = 50, _fetch_banner = 0, _fetch_share = 0, _fetch_total = 1) {
let getResp = await httpx.get(
`https://pc-api.uc.cn/1/clouddrive/transfer_share/detail?pr=UCBrowser&fr=h5&pwd_id=${pwd_id}&__t=${(/* @__PURE__ */ new Date()).getTime()}&passcode=${passcode}&stoken=${encodeURIComponent(
stoken
)}&pdir_fid=${pdir_fid}&force=${force}&_page=${_page}&_size=${_size}&_fetch_banner=${_fetch_banner}&_fetch_share=${_fetch_share}&_fetch_total=${_fetch_total}&_sort=${encodeURIComponent(
"file_type:asc,file_name:asc"
)}`,
{
headers: {
Accept: "application/json, text/plain, */*",
"User-Agent": utils.getRandomPCUA(),
Origin: "https://drive.uc.cn",
Referer: "https://drive.uc.cn/"
}
}
);
if (!getResp.status) {
return;
}
let data = utils.toJSON(getResp.data.responseText);
log.info("获取detail:", data);
if (data["code"] !== 0) {
log.error("获取detail失败", data);
Qmsg.error("获取detail失败");
return;
}
let metadata = data["metadata"];
if (metadata && metadata["_total"] && metadata["_total"] > metadata["_size"]) {
return await this.getDetail(
pwd_id,
passcode,
stoken,
pdir_fid,
force,
_page,
metadata["_total"],
_fetch_banner,
_fetch_share,
_fetch_total
);
}
return data["data"]["list"];
}
/**
* 获取下载信息
* @param pwd_id 分享码
* @param stoken 获取的stoken
* @param fids 通过获取到的detail获取到的fid
* @param share_fid_token 通过获取到的detail获取到的share_fid_token
*/
async getDownload(pwd_id, stoken, fid, share_fid_token) {
let postResp = await httpx.post(
"https://pc-api.uc.cn/1/clouddrive/file/download?entry=ft&fr=pc&pr=UCBrowser",
{
data: JSON.stringify({
fids: [fid],
pwd_id,
stoken,
fids_token: [share_fid_token]
}),
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8",
"User-Agent": utils.getRandomPCUA(),
Origin: "https://drive.uc.cn",
Referer: "https://drive.uc.cn/"
}
}
);
if (!postResp.status) {
return;
}
let data = utils.toJSON(postResp.data.responseText);
log.info("获取download:", data);
if (data["code"] !== 0) {
log.error("获取download失败", data);
Qmsg.error("获取download失败");
return;
}
if (data["data"].length === 0) {
log.error("获取download detail失败", data);
Qmsg.error("获取download detail失败失败");
return;
}
return data["data"];
}
/**
* 获取文件夹信息
* @param infoList
*/
getFolderInfo(infoList, stoken, index = 0) {
const that = this;
let folderInfoList = [];
let tempFolderInfoList = [];
let tempFolderFileInfoList = [];
infoList.forEach((item) => {
if (item.dir == false && item.file_type === 1) {
tempFolderFileInfoList.push({
fileName: item.file_name,
fileSize: item.size,
fileType: "",
createTime: item.created_at,
latestTime: item.updated_at,
isFolder: false,
index,
async clickEvent() {
let fileDownloadUrl = "";
let fileDownloadUrlInfo = await that.getDownload(
that.shareCode,
stoken,
item.fid,
item.share_fid_token
);
if (fileDownloadUrlInfo) {
if (fileDownloadUrlInfo.length) {
fileDownloadUrl = fileDownloadUrlInfo[0].download_url;
} else {
fileDownloadUrl = "";
}
} else {
fileDownloadUrl = "";
}
if (item.ban) {
Qmsg.error("文件已被禁止下载");
} else {
let schemeDownloadUrl = fileDownloadUrl;
if (NetDiskFilterScheme.isForwardDownloadLink("uc")) {
schemeDownloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"uc",
schemeDownloadUrl
);
}
if (schemeDownloadUrl === fileDownloadUrl) {
that.downloadFile(item.file_name, fileDownloadUrl);
} else {
return {
autoDownload: true,
mode: "aBlank",
url: fileDownloadUrl
};
}
}
}
});
} else {
tempFolderInfoList.push({
fileName: item.file_name,
fileSize: item.size,
fileType: "",
createTime: item.created_at,
latestTime: item.updated_at,
isFolder: true,
index,
async clickEvent() {
if (item.include_items === 0) {
log.success("里面没有文件");
return [];
}
let newDetail = await that.getDetail(
that.shareCode,
that.accessCode,
stoken,
item.fid
);
if (newDetail) {
return that.getFolderInfo(newDetail, stoken, index + 1);
} else {
return [];
}
}
});
}
});
tempFolderInfoList.sort(
(a, b) => a["fileName"].localeCompare(b["fileName"])
);
tempFolderFileInfoList.sort(
(a, b) => a["fileName"].localeCompare(b["fileName"])
);
folderInfoList = folderInfoList.concat(tempFolderInfoList);
folderInfoList = folderInfoList.concat(tempFolderFileInfoList);
log.info("getFilesInfoByRec", folderInfoList);
return folderInfoList;
}
}
class NetDiskParse_Wenshushu extends NetDiskParseObject {
constructor() {
super(...arguments);
/**
* 用于header头x-token
* @type {string}
*/
__publicField(this, "token");
__publicField(this, "code", {
1004: "no token",
1008: "您没有权限访问",
1013: "糟糕,此任务已过期销毁,下次要记得续期",
1066: "对方设置的下载 / 预览次数已用完",
1088: "糟糕,您访问的页面不存在"
});
}
async init(netDiskIndex, shareCode, accessCode) {
const that = this;
log.info(netDiskIndex, shareCode, accessCode);
that.netDiskIndex = netDiskIndex;
that.shareCode = shareCode;
that.accessCode = accessCode;
Qmsg.info("正在请求直链中...");
let token = await this.getWssToken();
if (!token) {
return;
}
let pidInfo = await this.getPid();
if (!pidInfo) {
return;
}
await this.getFileNList(pidInfo.bid, pidInfo.pid);
}
/**
* 获取token
* wss:xxxxxx
*/
async getWssToken() {
const that = this;
let postResp = await httpx.post(
"https://www.wenshushu.cn/ap/login/anonymous",
{
responseType: "json",
data: JSON.stringify({
dev_info: "{}"
}),
headers: {
Accept: "application/json, text/plain, */*",
"User-Agent": utils.getRandomAndroidUA(),
Referer: "https://www.wenshushu.cn/f/" + that.shareCode
}
}
);
log.success(postResp);
if (!postResp.status) {
return;
}
let data = utils.toJSON(postResp.data.responseText);
if (data["code"] === 0) {
that.token = data["data"]["token"];
return data["data"]["token"];
} else if (data["code"] in that.code) {
Qmsg.error(that.code[data["code"]]);
} else {
Qmsg.error("获取wss失败");
}
}
/**
* 获取pid
*/
async getPid() {
const that = this;
let postResp = await httpx.post({
url: "https://www.wenshushu.cn/ap/task/mgrtask",
responseType: "json",
data: JSON.stringify({
tid: that.shareCode,
password: "",
ufileid: ""
}),
headers: {
Accept: "application/json, text/plain, */*",
"User-Agent": utils.getRandomAndroidUA(),
Referer: "https://www.wenshushu.cn/f/" + that.shareCode,
"x-token": that.token
}
});
log.success(postResp);
if (!postResp.status) {
return;
}
let respData = postResp.data;
let data = utils.toJSON(respData.responseText);
if (data["code"] === 0) {
return {
bid: data["data"]["boxid"],
pid: data["data"]["ufileid"]
};
} else if (data["code"] in that.code) {
Qmsg.error(that.code[data["code"]]);
} else {
Qmsg.error("获取pid失败");
}
}
/**
* 获取文件列表信息
* @param bid
* @param pid
*/
async getFileNList(bid, pid) {
const that = this;
let postResp = await httpx.post("https://www.wenshushu.cn/ap/ufile/nlist", {
responseType: "json",
data: JSON.stringify({
start: 0,
sort: {
name: "asc"
},
bid,
pid,
options: {
uploader: "true"
},
size: 50
}),
headers: {
Accept: "application/json, text/plain, */*",
"User-Agent": utils.getRandomAndroidUA(),
Referer: "https://www.wenshushu.cn/f/" + that.shareCode,
"x-token": that.token
}
});
log.success(postResp);
if (!postResp.status) {
return;
}
let respData = postResp.data;
let jsonData = utils.toJSON(respData.responseText);
if (jsonData["code"] === 0) {
if (jsonData["data"]["fileList"][0]["type"] === 2) {
Qmsg.error("该链接为多层级文件嵌套,跳转");
NetDiskLinkClickMode.openBlank(
NetDiskLinkClickModeUtils.getBlankUrl(
"wenshushu",
that.netDiskIndex,
that.shareCode,
that.accessCode
),
"wenshushu",
that.netDiskIndex,
that.shareCode,
that.accessCode
);
} else {
await that.getDownloadUrl(jsonData["data"]["fileList"][0]);
}
} else if (jsonData["code"] in that.code) {
Qmsg.error(that.code[jsonData["code"]]);
} else {
Qmsg.error("获取文件信息失败");
}
}
/**
* 获取下载链接
* @param {object} data
* @returns {Promise}
*/
async getDownloadUrl(data) {
const that = this;
let file_name = data.fname;
let file_size = utils.formatByteToSize(data.size);
let postResp = await httpx.post("https://www.wenshushu.cn/ap/dl/sign", {
responseType: "json",
data: JSON.stringify({
ufileid: data.fid,
consumeCode: 0
}),
headers: {
Accept: "application/json, text/plain, */*",
"User-Agent": utils.getRandomAndroidUA(),
Referer: "https://www.wenshushu.cn/f/" + that.shareCode,
"x-token": that.token
}
});
if (!postResp.status) {
return;
}
log.success(postResp);
let respData = postResp.data;
let jsonData = utils.toJSON(respData.responseText);
if (jsonData["code"] == 0) {
let downloadUrl = jsonData["data"]["url"];
if (downloadUrl === "") {
Qmsg.error("对方的分享流量不足");
} else {
if (NetDiskFilterScheme.isForwardDownloadLink("wenshushu")) {
downloadUrl = NetDiskFilterScheme.parseDataToSchemeUri(
"wenshushu",
downloadUrl
);
}
NetDiskUI.staticView.oneFile({
title: "文叔叔单文件直链",
fileName: file_name,
fileSize: file_size,
downloadUrl
});
}
} else if (jsonData["data"] in that.code) {
Qmsg.error(that.code[jsonData["data"]]);
} else {
Qmsg.error("获取下载链接失败");
}
}
}
const NetDiskParse = {
netDisk: {
/**
* 百度网盘
*/
baidu: NetDiskParse_Baidu,
/**
* 蓝奏云
*/
lanzou: NetDiskParse_Lanzou,
/**
* 蓝奏云优享
*/
lanzouyx: NetDiskParse_Lanzouyx,
/**
* 天翼云
* + 开发文档:https://id.dlife.cn/html/api_detail_696.html
*/
tianyiyun: NetDiskParse_Tianyiyun,
/**
* 文叔叔
*/
wenshushu: NetDiskParse_Wenshushu,
/**
* 123盘
*/
_123pan: NetDiskParse_123pan,
/**
* 坚果云
*/
jianguoyun: NetDiskParse_Jianguoyun,
/**
* 奶牛快传
* 感谢:https://github.com/qaiu/netdisk-fast-download
*/
nainiu: NetDiskParse_nainiu,
/**
* UC网盘
*/
uc: NetDiskParse_UC,
/**
* 阿里云盘
*/
aliyun: NetDiskParse_Aliyun,
/**
* 城通网盘
*
* + https://github.com/qinlili23333/ctfileGet
*/
chengtong: NetDiskParse_Chengtong
}
};
const NetDiskLinkClickModeUtils = {
/**
* 获取用于跳转的url
* @param netDiskName
* @param netDiskIndex
* @param shareCode
* @param accessCode
*/
getBlankUrl(netDiskName, netDiskIndex, shareCode, accessCode) {
let regularOption = NetDisk.$rule.matchRule[netDiskName][netDiskIndex];
let blankUrl = regularOption.blank;
if (shareCode) {
blankUrl = NetDiskRuleUtils.replaceParam(blankUrl, {
shareCode
});
}
if (accessCode && accessCode !== "") {
blankUrl = NetDiskRuleUtils.replaceParam(blankUrl, {
accessCode
});
} else {
blankUrl = NetDiskHandlerUtil.replaceText(
blankUrl,
NetDisk.$extraRule.noAccessCodeRegExp,
""
);
}
let currentDict = NetDisk.$match.matchedInfo.get(netDiskName).get(shareCode);
if (regularOption.paramMatch) {
let paramMatchArray = currentDict.matchText.match(
regularOption.paramMatch
);
let replaceParamData = {};
for (let index = 0; index < paramMatchArray.length; index++) {
replaceParamData[`$${index}`] = paramMatchArray[index];
}
blankUrl = NetDiskRuleUtils.replaceParam(blankUrl, replaceParamData);
}
return blankUrl;
},
/**
* 获取用于复制到剪贴板的网盘信息
* @param netDiskName
* @param netDiskIndex
* @param shareCode
* @param accessCode
*/
getCopyUrlInfo(netDiskName, netDiskIndex, shareCode, accessCode) {
let regularOption = NetDisk.$rule.matchRule[netDiskName][netDiskIndex];
let copyUrl = regularOption["copyUrl"];
if (shareCode) {
copyUrl = NetDiskRuleUtils.replaceParam(copyUrl, {
shareCode
});
}
if (accessCode && accessCode !== "") {
copyUrl = NetDiskRuleUtils.replaceParam(copyUrl, {
accessCode
});
} else {
copyUrl = NetDiskHandlerUtil.replaceText(
copyUrl,
NetDisk.$extraRule.noAccessCodeRegExp,
""
);
}
let currentDict = NetDisk.$match.matchedInfo.get(netDiskName).get(shareCode);
if (regularOption.paramMatch) {
let paramMatchArray = currentDict.matchText.match(
regularOption.paramMatch
);
let replaceParamData = {};
for (let index = 0; index < paramMatchArray.length; index++) {
replaceParamData[`$${index}`] = paramMatchArray[index];
}
copyUrl = NetDiskRuleUtils.replaceParam(copyUrl, replaceParamData);
}
return copyUrl;
}
};
const NetDiskLinkClickMode = {
/**
* 复制到剪贴板
* @param netDiskName 网盘名
* @param netDiskIndex 网盘索引
* @param shareCode 分享码
* @param accessCode 提取码
* @param toastText 复制成功的提示的文字
*/
copy(netDiskName, netDiskIndex, shareCode, accessCode, toastText = "已复制") {
utils.setClip(
NetDiskLinkClickModeUtils.getCopyUrlInfo(
netDiskName,
netDiskIndex,
shareCode,
accessCode
)
);
Qmsg.success(toastText);
},
/**
* 网盘链接解析
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 提取码
*/
async parseFile(netDiskName, netDiskIndex, shareCode, accessCode) {
if (NetDiskParse.netDisk[netDiskName]) {
let parseObj = new NetDiskParse.netDisk[netDiskName]();
await parseObj.init(netDiskIndex, shareCode, accessCode);
} else {
log.error(`${netDiskName} 未配置解析函数`);
Qmsg.error("该链接未配置解析函数");
}
},
/**
* 新标签页打开
* @param url 跳转的网址
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘索引
* @param shareCode 分享码
* @param accessCode 提取码
*/
openBlank(url, netDiskName, netDiskIndex, shareCode, accessCode) {
var _a2;
log.success("新标签页打开", arguments);
if (NetDiskAutoFillAccessCode.$data.enable) {
NetDiskAutoFillAccessCode.setValue({
url,
netDiskName,
netDiskIndex,
shareCode,
accessCode
});
}
if (NetDiskFilterScheme.isForwardBlankLink(netDiskName)) {
url = NetDiskFilterScheme.parseDataToSchemeUri(netDiskName, url);
}
(_a2 = document.querySelector("meta[name='referrer']")) == null ? void 0 : _a2.setAttribute("content", "no-referrer");
if (utils.isNotNull(accessCode) && NetDiskRuleData.linkClickMode_openBlank.openBlankWithCopyAccessCode(
netDiskName
)) {
utils.setClip(accessCode).then(() => {
window.open(url, "_blank");
});
} else {
window.open(url, "_blank");
}
},
/**
* 将链接转为Scheme格式并打开
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称索引下标
* @param shareCode
* @param accessCode
*/
openBlankWithScheme(netDiskName, netDiskIndex, shareCode, accessCode) {
log.success("scheme新标签页打开", arguments);
let url = NetDiskLinkClickModeUtils.getBlankUrl(
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
url = NetDiskFilterScheme.parseDataToSchemeUri(netDiskName, url);
window.open(url, "_blank");
}
};
const NetDiskCheckLinkValidity_baidu = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let url = NetDiskLinkClickModeUtils.getBlankUrl(
"baidu",
netDiskIndex,
shareCode,
accessCode
);
let response = await httpx.get(url, {
headers: {
"User-Agent": utils.getRandomPCUA(),
Host: "pan.baidu.com",
Referer: url,
Origin: "https://pan.baidu.com"
},
...NetDiskCheckLinkValidityRequestOption
});
let responseText = response.data.responseText;
if (!response.status) {
if (utils.isNull(responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
}
if (response.data.finalUrl.includes("404.html")) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
if (responseText.includes("过期时间:")) {
return {
...NetDiskCheckLinkValidity.status.success,
data: response
};
} else if (responseText.includes("输入提取")) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data: response
};
} else if (responseText.includes("不存在") || responseText.includes("已失效")) {
return {
...NetDiskCheckLinkValidity.status.failed,
data: response
};
} else {
return {
...NetDiskCheckLinkValidity.status.unknown,
data: response
};
}
}
};
const NetDiskCheckLinkValidity_lanzou = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let url = NetDiskLinkClickModeUtils.getBlankUrl(
"lanzou",
netDiskIndex,
shareCode,
accessCode
);
let urlObj = new URL(url);
let response = await httpx.get(url, {
headers: {
"User-Agent": utils.getRandomPCUA(),
Host: urlObj.hostname,
Origin: urlObj.origin,
Referer: url
},
...NetDiskCheckLinkValidityRequestOption
});
if (!response.status) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let data = response.data.responseText;
if (utils.isNull(data)) {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
} else if (data.includes("输入密码")) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data
};
} else if (data.includes("来晚啦") || data.includes("不存在")) {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
} else {
return {
...NetDiskCheckLinkValidity.status.success,
data
};
}
}
};
const NetDiskCheckLinkValidity_lanzouyx = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let LanZouYX = new NetDiskParse.netDisk.lanzouyx();
LanZouYX.shareCodeId = LanZouYX.getDecodeShareCodeId(shareCode);
let timestamp = LanZouYX.getEncodeTimeStamp();
let uuid = LanZouYX.getEncodeUUID();
let response = await httpx.post(
`https://api.ilanzou.com/unproved/recommend/list?${utils.toSearchParamsStr(
{
devType: LanZouYX.$data.devType,
devModel: LanZouYX.$data.devModel,
uuid,
extra: LanZouYX.$data.extra,
timestamp,
code: accessCode,
shareId: shareCode,
type: LanZouYX.$data.type,
offset: LanZouYX.$data.offset,
limit: LanZouYX.$data.limit
}
)}`,
{
headers: {
Accept: "application/json, text/plain, */*",
Origin: "https://www.ilanzou.com",
Referer: "https://www.ilanzou.com/",
"Sec-Fetch-Site": "same-site",
Host: "api.ilanzou.com",
"User-Agent": utils.getRandomPCUA()
},
responseType: "json",
...NetDiskCheckLinkValidityRequestOption
}
);
if (!response.status) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let data = utils.toJSON(response.data.responseText);
log.success("获取链接信息:", data);
if (data["code"] !== 200) {
return {
...NetDiskCheckLinkValidity.status.error,
data
};
}
if (!data["list"].length) {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
}
return {
...NetDiskCheckLinkValidity.status.success,
data
};
}
};
const NetDiskCheckLinkValidity_tianyiyun = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let response = await httpx.post(
"https://api.cloud.189.cn/open/share/getShareInfoByCodeV2.action",
{
data: `shareCode=${shareCode}`,
headers: {
Accept: "application/json;charset=UTF-8",
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": utils.getRandomPCUA(),
"Sign-Type": 1,
Referer: "https://cloud.189.cn/web/share?code=" + shareCode,
Origin: "https://cloud.189.cn"
},
...NetDiskCheckLinkValidityRequestOption
}
);
let responseText = response.data.responseText;
if (!response.status && utils.isNull(responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
if (responseText.includes("ShareInfoNotFound") || responseText.includes("ShareNotFound") || responseText.includes("FileNotFound") || responseText.includes("ShareAuditWaiting") || responseText.includes("ShareExpiredError") || responseText.includes("ShareAuditNotPass")) {
return {
...NetDiskCheckLinkValidity.status.failed,
data: response
};
}
if (responseText.includes("needAccessCode")) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data: response
};
}
return {
...NetDiskCheckLinkValidity.status.success,
data: response
};
}
};
const NetDiskCheckLinkValidity_aliyun = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
var _a2;
let response = await httpx.post(
"https://api.aliyundrive.com/adrive/v3/share_link/get_share_by_anonymous?share_id=" + shareCode,
{
data: JSON.stringify({
share_id: shareCode
}),
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json",
"User-Agent": utils.getRandomPCUA(),
Referer: "https://www.aliyundrive.com/",
Origin: "https://www.aliyundrive.com"
},
...NetDiskCheckLinkValidityRequestOption
}
);
let data = utils.toJSON(response.data.responseText);
if (!response.status && utils.isNull(data)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
if (data["code"] === "ParamFlowException" || data["code"] === "NotFound.ShareLink" || data["code"] === "ShareLink.Cancelled") {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
} else if (data["file_count"] === 0 || ((_a2 = data["file_infos"]) == null ? void 0 : _a2.length) === 0) {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
}
return {
...NetDiskCheckLinkValidity.status.success,
data
};
}
};
const NetDiskCheckLinkValidity_wenshushu = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let response = await httpx.post(
"https://www.wenshushu.cn/ap/task/mgrtask",
{
data: JSON.stringify({
tid: shareCode
}),
headers: {
"Content-Type": "application/json",
"User-Agent": utils.getRandomPCUA(),
"x-token": "wss:7pmakczzw6i",
Host: "www.wenshushu.cn",
Origin: "https://www.wenshushu.cn",
Referer: NetDiskLinkClickModeUtils.getBlankUrl(
"wenshushu",
netDiskIndex,
shareCode,
accessCode
)
},
responseType: "json",
...NetDiskCheckLinkValidityRequestOption
}
);
if (!response.status && utils.isNull(response.data.responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let data = utils.toJSON(response.data.responseText);
if (data.code !== 0) {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
}
return {
...NetDiskCheckLinkValidity.status.success,
data
};
}
};
const NetDiskCheckLinkValidity_nainiu = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let response = await httpx.get(
`https://cowtransfer.com/core/api/transfer/share?uniqueUrl=${shareCode}`,
{
headers: {
"User-Agent": utils.getRandomPCUA(),
Host: "cowtransfer.com",
Origin: "https://cowtransfer.com",
Referer: "https://cowtransfer.com/"
},
...NetDiskCheckLinkValidityRequestOption
}
);
if (!response.status && utils.isNull(response.data.responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let data = utils.toJSON(response.data.responseText);
if (data.code != "0000") {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
}
if (data.data.needPassword && data.data.needPassword) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data
};
}
return {
...NetDiskCheckLinkValidity.status.success,
data
};
}
};
const NetDiskCheckLinkValidity_123pan = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let response = await httpx.get(
"https://www.123pan.com/api/share/info?shareKey=" + shareCode,
{
headers: {
"User-Agent": utils.getRandomPCUA(),
Host: "www.123pan.com",
Origin: "https://www.123pan.com",
Referer: "https://www.123pan.com/"
},
responseType: "json",
...NetDiskCheckLinkValidityRequestOption
}
);
if (!response.status && utils.isNull(response.data.responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let data = utils.toJSON(response.data.responseText);
if (response.data.responseText.includes("分享页面不存在") || data["code"] !== 0) {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
}
if (data["data"]["HasPwd"]) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data
};
}
return {
...NetDiskCheckLinkValidity.status.success,
data
};
}
};
const NetDiskCheckLinkValidity_weiyun = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let url = NetDiskLinkClickModeUtils.getBlankUrl(
"weiyun",
netDiskIndex,
shareCode,
accessCode
);
let response = await httpx.get(url, {
headers: {
"User-Agent": utils.getRandomPCUA(),
Host: "share.weiyun.com",
Origin: "https://share.weiyun.com",
Referer: url
},
...NetDiskCheckLinkValidityRequestOption
});
if (!response.status && utils.isNull(response.data.responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let responseText = response.data.responseText;
if (responseText.includes("已删除") || responseText.includes("违反相关法规") || responseText.includes("已过期") || responseText.includes("已经删除") || responseText.includes("目录无效")) {
return {
...NetDiskCheckLinkValidity.status.failed,
data: response
};
}
if (responseText.includes('"need_pwd":1') || responseText.includes('"pwd":"')) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data: response
};
}
return {
...NetDiskCheckLinkValidity.status.success,
data: response
};
}
};
const NetDiskCheckLinkValidity_xunlei = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let postResponse = await httpx.post(
"https://xluser-ssl.xunlei.com/v1/shield/captcha/init",
{
data: JSON.stringify({
client_id: "Xqp0kJBXWhwaTpB6",
device_id: "925b7631473a13716b791d7f28289cad",
action: "get:/drive/v1/share",
meta: {
package_name: "pan.xunlei.com",
client_version: "1.45.0",
captcha_sign: "1.fe2108ad808a74c9ac0243309242726c",
timestamp: "1645241033384"
}
}),
headers: {
"User-Agent": utils.getRandomPCUA(),
Host: "pan.xunlei.com",
Referer: NetDiskLinkClickModeUtils.getBlankUrl(
"xunlei",
netDiskIndex,
shareCode,
accessCode
),
Origin: "https://pan.xunlei.com"
},
...NetDiskCheckLinkValidityRequestOption
}
);
if (!postResponse.status && utils.isNull(postResponse.data.responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: postResponse
};
}
let postResponseData = utils.toJSON(postResponse.data.responseText);
let token = postResponseData["captcha_token"];
let getResponse = await httpx.get(
"https://api-pan.xunlei.com/drive/v1/share?share_id=" + shareCode,
{
headers: {
"User-Agent": utils.getRandomPCUA(),
Host: "pan.xunlei.com",
Referer: NetDiskLinkClickModeUtils.getBlankUrl(
"xunlei",
netDiskIndex,
shareCode,
accessCode
),
Origin: "https://pan.xunlei.com",
"x-captcha-token": token,
"x-client-id": "Xqp0kJBXWhwaTpB6",
"x-device-id": "925b7631473a13716b791d7f28289cad"
},
...NetDiskCheckLinkValidityRequestOption
}
);
if (!getResponse.status && utils.isNull(getResponse.data.responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: [postResponse, getResponse]
};
}
let responseText = getResponse.data.responseText;
if (responseText.includes("NOT_FOUND") || responseText.includes("SENSITIVE_RESOURCE") || responseText.includes("EXPIRED") || responseText.includes("DELETED")) {
return {
...NetDiskCheckLinkValidity.status.failed,
data: getResponse
};
} else if (responseText.includes("PASS_CODE_EMPTY")) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data: getResponse
};
}
return {
...NetDiskCheckLinkValidity.status.success,
data: getResponse
};
}
};
const NetDiskCheckLinkValidity_chengtong = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let blankUrl = NetDiskLinkClickModeUtils.getBlankUrl(
"chengtong",
netDiskIndex,
shareCode,
accessCode
);
let blankUrlObj = new URL(blankUrl);
const path = blankUrlObj.pathname.split("/")[1].trim();
let url = "";
if (path === "f" || path === "file") {
url = `https://webapi.ctfile.com/getfile.php?path=${path}&f=${shareCode}&passcode=${accessCode}&token=0&r=${Math.random()}&ref=`;
} else if (path === "d" || path === "dir") {
url = `https://webapi.ctfile.com/getdir.php?path=${path}&d=${shareCode}&folder_id=&passcode=${accessCode}&token=0&r=${Math.random()}&ref=`;
} else {
log.warn("未知path", [netDiskIndex, shareCode, accessCode]);
return {
...NetDiskCheckLinkValidity.status.unknown,
data: null
};
}
let response = await httpx.get(url, {
headers: {
Host: "webapi.ctfile.com",
Origin: "https://url95.ctfile.com",
Referer: blankUrl,
Accept: "application/json, text/javascript, */*; q=0.01",
"User-Agent": utils.getRandomPCUA()
},
...NetDiskCheckLinkValidityRequestOption
});
let responseText = response.data.responseText;
if (!response.status && utils.isNull(responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let data = utils.toJSON(responseText);
if (data["code"] === 200) {
return {
...NetDiskCheckLinkValidity.status.success,
data
};
}
if (data["code"] === 401) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data
};
}
if (data["code"] === 404 || data["code"] === 503 || data["code"] === 504) {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
}
return {
...NetDiskCheckLinkValidity.status.unknown,
data
};
}
};
const NetDiskCheckLinkValidity_kuake = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let response = await httpx.post(
"https://drive.quark.cn/1/clouddrive/share/sharepage/token?pr=ucpro&fr=pc",
{
data: JSON.stringify({
pwd_id: shareCode,
passcode: ""
}),
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8",
"User-Agent": utils.getRandomPCUA(),
Origin: "https://pan.quark.cn",
Referer: NetDiskLinkClickModeUtils.getBlankUrl(
"kuake",
netDiskIndex,
shareCode,
accessCode
)
},
...NetDiskCheckLinkValidityRequestOption
}
);
if (!response.status && utils.isNull(response.data.responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let data = utils.toJSON(response.data.responseText);
if (data.message.includes("需要提取码")) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data
};
} else if (data.message.includes("ok")) {
let stoken = data["data"]["stoken"];
let getSearchParams = {
// pr: "ucpro",
// fr: "pc",
// uc_param_str: "",
pwd_id: shareCode,
stoken,
// pdir_fid: 0,
// force: 0,
// _page: 1,
// _size: 50,
// _fetch_banner: 1,
_fetch_share: 1,
// _fetch_total: 1,
// _sort: "file_type:asc,updated_at:desc",
// __dt: 2283,
__t: Date.now()
};
let getResponse = await httpx.get(
`https://drive-h.quark.cn/1/clouddrive/share/sharepage/detail?${utils.toSearchParamsStr(
getSearchParams
)}`,
{
headers: {
Accept: "application/json, text/plain, */*",
Origin: "https://pan.quark.cn",
Referer: "https://pan.quark.cn/",
"User-Agent": utils.getRandomPCUA()
},
...NetDiskCheckLinkValidityRequestOption
}
);
if (!getResponse.status || utils.isNull(getResponse.data.responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: getResponse
};
}
let detailJSON = utils.toJSON(getResponse.data.responseText);
if (detailJSON["data"]["share"]["status"] == 1) {
if (detailJSON["data"]["share"]["partial_violation"]) {
return {
...NetDiskCheckLinkValidity.status.partialViolation,
data: [data, detailJSON]
};
} else {
return {
...NetDiskCheckLinkValidity.status.success,
data: [data, detailJSON]
};
}
} else {
return {
...NetDiskCheckLinkValidity.status.failed,
data: [data, detailJSON]
};
}
} else {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
}
}
};
const NetDiskCheckLinkValidity_jianguoyun = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let url = NetDiskLinkClickModeUtils.getBlankUrl(
"jianguoyun",
netDiskIndex,
shareCode,
accessCode
);
let response = await httpx.get(url, {
headers: {
"User-Agent": utils.getRandomPCUA(),
Host: "www.jianguoyun.com",
Referer: NetDiskLinkClickModeUtils.getBlankUrl(
"jianguoyun",
netDiskIndex,
shareCode,
accessCode
),
Origin: "https://www.jianguoyun.com"
},
...NetDiskCheckLinkValidityRequestOption
});
let responseText = response.data.responseText;
if (!response.status && utils.isNull(responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
if (responseText.includes("啊噢!")) {
return {
...NetDiskCheckLinkValidity.status.failed,
data: response
};
}
return {
...NetDiskCheckLinkValidity.status.success,
data: response
};
}
};
const NetDiskCheckLinkValidity_onedrive = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
var _a2, _b, _c, _d;
let url = NetDiskLinkClickModeUtils.getBlankUrl(
"onedrive",
netDiskIndex,
shareCode,
accessCode
);
let urlObj = new URL(url);
let response = await httpx.get(url, {
headers: {
"User-Agent": utils.getRandomPCUA(),
Host: urlObj.hostname,
Referer: url,
Origin: urlObj.origin
},
...NetDiskCheckLinkValidityRequestOption
});
if (!response.status) {
let status = (_b = (_a2 = response.data) == null ? void 0 : _a2.status) == null ? void 0 : _b.toString();
if (status === "429") {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
} else if (status === "404") {
return {
...NetDiskCheckLinkValidity.status.failed,
data: response
};
}
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let responseText = response.data.responseText;
if (utils.isNotNull(responseText)) {
try {
let respDOM = domUtils.parseHTML(responseText, true, true);
if ((_d = (_c = respDOM.querySelector("title")) == null ? void 0 : _c.innerHTML) == null ? void 0 : _d.includes("错误")) {
return {
...NetDiskCheckLinkValidity.status.failed,
data: response
};
}
} catch (error) {
}
}
return {
...NetDiskCheckLinkValidity.status.success,
data: response
};
}
};
const NetDiskCheckLinkValidity_uc = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let response = await httpx.get("https://drive.uc.cn/s/" + shareCode, {
headers: {
"User-Agent": utils.getRandomAndroidUA(),
Host: "drive.uc.cn",
Referer: NetDiskLinkClickModeUtils.getBlankUrl(
"uc",
netDiskIndex,
shareCode,
accessCode
),
Origin: "https://drive.uc.cn"
},
...NetDiskCheckLinkValidityRequestOption
});
let responseText = response.data.responseText;
if (!response.status && utils.isNull(responseText)) {
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let responseDocument = domUtils.parseHTML(responseText, true, true);
if (responseDocument.querySelector(".h5-page-main")) {
let $h5PageMain = responseDocument.querySelector(".h5-page-main");
let errorText = $h5PageMain.textContent || $h5PageMain.innerText;
if (errorText.includes("失效") || errorText.includes("不存在") || errorText.includes("违规") || errorText.includes("删除")) {
return {
...NetDiskCheckLinkValidity.status.failed,
data: response
};
} else {
return {
...NetDiskCheckLinkValidity.status.unknown,
data: response
};
}
} else if (responseDocument.querySelector(".main-body .input-wrap input")) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data: response
};
} else {
return {
...NetDiskCheckLinkValidity.status.success,
data: response
};
}
}
};
const NetDiskCheckLinkValidity_115pan = {
/**
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
*/
async init(netDiskIndex, shareCode, accessCode) {
let response = await httpx.get(
`https://webapi.115.com/share/snap?share_code=${shareCode}&offset=0&limit=20&receive_code=&cid=`,
{
headers: {
Accept: "application/json, text/javascript, */*;",
"User-Agent": utils.getRandomPCUA(),
Host: "webapi.115.com",
Referer: "https://115.com/",
Origin: "https://115.com"
},
...NetDiskCheckLinkValidityRequestOption
}
);
if (!response.status) {
if (utils.isNull(response.data.responseText)) {
return {
...NetDiskCheckLinkValidity.status.failed,
data: response
};
}
return {
...NetDiskCheckLinkValidity.status.error,
data: response
};
}
let data = utils.toJSON(response.data.responseText);
if (data.state) {
return {
...NetDiskCheckLinkValidity.status.success,
data
};
}
if (typeof data.error === "string") {
if (data.error.includes("访问码")) {
return {
...NetDiskCheckLinkValidity.status.needAccessCode,
data
};
} else if (data.error.includes("链接") || data.error.includes("分享已取消")) {
return {
...NetDiskCheckLinkValidity.status.failed,
data
};
}
}
return {
...NetDiskCheckLinkValidity.status.unknown,
data
};
}
};
const NetDiskCheckLinkValidityStatus = {
/**
* 验证中
*/
loading: {
code: 1,
msg: "验证中...",
setView($ele, checkInfo, msg) {
NetDiskCheckLinkValidity.setViewCheckValid(
$ele,
"loading",
msg ?? this.msg
);
$ele.innerHTML = __pops.config.iconSVG.loading;
}
},
/**
* 验证成功
*/
success: {
code: 200,
msg: "有效",
setView($ele, checkInfo, msg) {
NetDiskCheckLinkValidity.setViewCheckValid(
$ele,
"success",
msg ?? this.msg
);
$ele.innerHTML = /*html*/
`
`;
NetDiskCheckLinkValidity.setViewAgainCheckClickEvent($ele, checkInfo);
}
},
/**
* 验证失败
*/
error: {
code: -404,
msg: "网络异常",
setView($ele, checkInfo, msg) {
NetDiskCheckLinkValidity.setViewCheckValid(
$ele,
"error",
msg ?? this.msg
);
$ele.innerHTML = /*html*/
`
`;
NetDiskCheckLinkValidity.setViewAgainCheckClickEvent($ele, checkInfo);
}
},
/**
* 该链接已失效
*/
failed: {
code: 0,
msg: "已失效",
setView($ele, checkInfo, msg) {
NetDiskCheckLinkValidity.setViewCheckValid(
$ele,
"failed",
msg ?? this.msg
);
$ele.innerHTML = /*html*/
`
`;
NetDiskCheckLinkValidity.setViewAgainCheckClickEvent($ele, checkInfo);
}
},
/**
* 该链接需要密码
*/
needAccessCode: {
code: 201,
msg: "需要提取码",
setView($ele, checkInfo, msg) {
NetDiskCheckLinkValidity.setViewCheckValid(
$ele,
"needAccessCode",
msg ?? this.msg
);
$ele.innerHTML = /*html*/
`
`;
NetDiskCheckLinkValidity.setViewAgainCheckClickEvent($ele, checkInfo);
}
},
/**
* 存在部分违规文件
*/
partialViolation: {
code: 202,
msg: "存在部分违规文件",
setView($ele, checkInfo, msg) {
NetDiskCheckLinkValidity.setViewCheckValid(
$ele,
"partial-violation",
msg ?? this.msg
);
$ele.innerHTML = /*html*/
`
`;
}
},
/**
* 未知状态
*/
unknown: {
code: -200,
msg: "未知检查情况",
setView($ele, checkInfo, msg) {
NetDiskCheckLinkValidity.setViewCheckValid(
$ele,
"unknown",
msg ?? this.msg
);
$ele.innerHTML = /*html*/
`
`;
NetDiskCheckLinkValidity.setViewAgainCheckClickEvent($ele, checkInfo);
}
}
};
const NetDiskCheckLinkValidityNetDisk = {
baidu: NetDiskCheckLinkValidity_baidu,
lanzou: NetDiskCheckLinkValidity_lanzou,
lanzouyx: NetDiskCheckLinkValidity_lanzouyx,
tianyiyun: NetDiskCheckLinkValidity_tianyiyun,
// 和彩云校验已失效,需要验证参数
// hecaiyun: NetDiskCheckLinkValidity_hecaiyun,
aliyun: NetDiskCheckLinkValidity_aliyun,
wenshushu: NetDiskCheckLinkValidity_wenshushu,
nainiu: NetDiskCheckLinkValidity_nainiu,
_123pan: NetDiskCheckLinkValidity_123pan,
weiyun: NetDiskCheckLinkValidity_weiyun,
xunlei: NetDiskCheckLinkValidity_xunlei,
_115pan: NetDiskCheckLinkValidity_115pan,
chengtong: NetDiskCheckLinkValidity_chengtong,
kuake: NetDiskCheckLinkValidity_kuake,
jianguoyun: NetDiskCheckLinkValidity_jianguoyun,
onedrive: NetDiskCheckLinkValidity_onedrive,
uc: NetDiskCheckLinkValidity_uc
};
const NetDiskCheckLinkValidityRequestOption = {
// 有效性校验时,如果请求错误,禁止Qmsg弹出
allowInterceptConfig: false,
// 有效性校验时,如果请求错误,禁止Qmsg弹出
onerror() {
},
// 有效性校验时,如果请求错误,禁止Qmsg弹出
ontimeout() {
}
};
const NetDiskCheckLinkValidity = {
$data: {
/** 是否正在消费中(验证有效性中) */
isConsuming: false,
/** 待检测有有效性的列表 */
subscribe: []
},
/**
* 网盘检查的状态码
*/
status: NetDiskCheckLinkValidityStatus,
/**
* 所有的规则的校验函数
*/
netDisk: NetDiskCheckLinkValidityNetDisk,
/**
* 校验链接的有效性,这里是用于订阅-消费
* @param netDiskViewBox
* @param netDiskName
* @param netDiskIndex
* @param shareCode
* @param accessCode
*/
async check(netDiskViewBox, netDiskName, netDiskIndex, shareCode, accessCode) {
this.$data.subscribe.push({
netDiskViewBox,
netDiskName,
netDiskIndex,
shareCode,
accessCode
});
if (this.$data.isConsuming) {
return;
}
this.$data.isConsuming = true;
for (let index = 0; index < this.$data.subscribe.length; index++) {
const checkInfo = this.$data.subscribe[index];
await this.checkLinkValidity(checkInfo, true);
await utils.sleep(250);
this.$data.subscribe.splice(index, 1);
index--;
}
this.$data.isConsuming = false;
},
/**
* 开始校验链接的有效性
* @param checkInfo
* @param isForceCheck 是否强制检测
*/
async checkLinkValidity(checkInfo, isForceCheck) {
let $netDiskStatus = checkInfo.netDiskViewBox.querySelector(
".netdisk-status"
);
if (this.isViewCheckValid($netDiskStatus) && !isForceCheck) {
return;
}
this.setCheckStatusElementToolTip(checkInfo);
let netDiskName = checkInfo.netDiskName;
if (!NetDiskRuleData.function.checkLinkValidity(netDiskName)) {
log.error("未开启checkLinkValidity功能", checkInfo);
return;
}
let netDiskCheck = this.netDisk[checkInfo.netDiskName];
if (!netDiskCheck || netDiskCheck && typeof netDiskCheck.init !== "function") {
log.error("没有配置该网盘的校验有效性", checkInfo);
return;
}
this.status.loading.setView($netDiskStatus, checkInfo);
let checkStatusResult = await netDiskCheck.init(
checkInfo.netDiskIndex,
checkInfo.shareCode,
checkInfo.accessCode
);
if (!checkStatusResult) {
log.error("该验证函数的返回值不是有效值", [checkStatusResult, checkInfo]);
return;
}
checkStatusResult.setView(
$netDiskStatus,
checkInfo,
checkStatusResult.tipMsg
);
if (checkStatusResult.data) {
Reflect.set(
$netDiskStatus,
"data-httpx-response",
checkStatusResult.data
);
}
},
/**
* 添加重复检查的点击事件(只触发一次)
* @param $ele 目标元素
* @param checkInfo 检查信息
*/
setViewAgainCheckClickEvent($ele, checkInfo) {
domUtils.on(
$ele,
"click",
void 0,
() => {
const $netDiskUrlDiv = $ele.closest(".netdisk-url-div");
const $netDiskLink = $netDiskUrlDiv.querySelector(".netdisk-link");
const ruleInfo = NetDiskView.praseElementAttributeRuleInfo($netDiskLink);
let newCheckInfo = {
netDiskViewBox: $netDiskUrlDiv,
netDiskName: ruleInfo.netDiskName,
netDiskIndex: ruleInfo.netDiskIndex,
shareCode: ruleInfo.shareCode,
accessCode: ruleInfo.accessCode
};
this.checkLinkValidity(newCheckInfo, true);
},
{ once: true }
);
},
/**
* 判断元素当前是否处于验证状态且验证是error或未验证状态
*
* 简而言之。验证成功的图标点击后将不触发验证请求
* + true 已验证(成功/需要密码)
* + false 尚未验证/验证超时/验证网络异常
* @param ele
*/
isViewCheckValid(ele) {
if (!ele.hasAttribute("data-check-valid")) {
return false;
}
if (ele.getAttribute("data-check-valid") === "error") {
return false;
}
return true;
},
/**
* 设置当前的验证状态
* @param $ele
* @param value
* @param msg
*/
setViewCheckValid($ele, value, msg) {
$ele.setAttribute("data-check-valid", value);
$ele.setAttribute("data-msg", msg);
},
/**
* 取消设置当前的验证状态
* @param $ele
*/
removeViewCheckValid($ele) {
$ele.removeAttribute("data-check-valid");
$ele.removeAttribute("data-msg");
},
/**
* 判断状态码是成功的
* @param statusInfo
*/
isStatusSuccess(statusInfo) {
if (Math.floor(statusInfo.code / 100) === 2) {
return true;
}
return false;
},
/**
* 根据code获取code的名字
* @param statusInfo
*/
getStatusName(statusInfo) {
for (const statusName of Object.keys(NetDiskCheckLinkValidity.status)) {
let _statusInfo_ = this.status[statusName];
if (statusInfo.code === _statusInfo_.code) {
return statusName;
}
}
},
/**
* 设置鼠标悬浮事件
*/
setCheckStatusElementToolTip(checkInfo) {
if (!NetDiskRuleData.function.checkLinlValidityHoverTip(checkInfo.netDiskName)) {
return;
}
function getNetDiskStatus() {
return checkInfo.netDiskViewBox.querySelector(
".netdisk-status"
);
}
let $netDiskStatus = getNetDiskStatus();
if ($netDiskStatus.hasAttribute("data-pops-tooltip")) {
return;
}
$netDiskStatus.setAttribute("data-pops-tooltip", "true");
__pops.tooltip({
target: $netDiskStatus,
className: "github-tooltip",
isFixed: true,
content() {
let msg = $netDiskStatus.getAttribute("data-msg");
return msg ?? "";
},
showBeforeCallBack() {
let msg = $netDiskStatus.getAttribute("data-msg");
if (msg == null || typeof msg === "string" && msg.trim() === "") {
return false;
}
},
zIndex() {
let maxZIndex = utils.getMaxZIndex(10);
let popsMaxZIndex = __pops.config.InstanceUtils.getPopsMaxZIndex(10).zIndex;
return utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100;
}
});
}
};
const NetDiskRequire = {
requiredFileMap: /* @__PURE__ */ new Map(),
/**
* 网络加载文件
* @param url 网络文件路径
* @param options
*/
async file(url, options) {
if (utils.isNull(url)) {
log.error("NetDiskRequire.file的参数path为空", url);
return false;
}
if (this.requiredFileMap.has(url)) {
log.warn("NetDiskRequire.file的参数path已引入过", url);
return true;
}
let getResp = await httpx.get(url, options);
if (!getResp.status) {
return false;
}
let jsText = getResp.data.responseText;
let count = this.requiredFileMap.get(url);
this.requiredFileMap.set(url, count++);
log.info("加载js文件", url);
_unsafeWindow.eval(
`
let exports = void 0;
let module = void 0;
let define = void 0;
` + jsText
);
await utils.sleep(300);
return true;
}
};
const NetDiskUserRuleReplaceParam_matchRange_text = (key) => {
return {
"matchRange-text-before": NetDiskRuleData.matchRange_text.before(key).toString(),
"matchRange-text-after": NetDiskRuleData.matchRange_text.after(key).toString()
};
};
const NetDiskUserRuleReplaceParam_matchRange_html = (key) => {
return {
"matchRange-html-before": NetDiskRuleData.matchRange_html.before(key).toString(),
"matchRange-html-after": NetDiskRuleData.matchRange_html.after(key).toString()
};
};
const NetDiskUserRule = {
KEY: "userRule",
/** 用户规则上下文存储的数据 */
userRuleContextDataKey: "userRuleContextData",
$data: {
__userRule: null,
get userRule() {
if (this.__userRule == null) {
this.__userRule = new utils.Dictionary();
}
return this.__userRule;
}
},
/**
* 初始化
*/
init() {
let userRule = this.parseRule(this.getAllRule());
userRule.forEach((item) => {
this.$data.userRule.set(item.setting.key, item);
});
},
/**
* 把输入的规则字符串解析为规则对象
*/
parseRuleStrToRule(ruleText) {
function checkRegExp(ruleRegExp) {
if (typeof ruleRegExp["link_innerText"] !== "string") {
return {
success: false,
msg: "regexp缺失的键名: link_innerText,类型: string"
};
}
if (typeof ruleRegExp["link_innerHTML"] !== "string") {
return {
success: false,
msg: "regexp缺失的键名: link_innerHTML,类型: string"
};
}
if (typeof ruleRegExp["shareCode"] !== "string") {
return {
success: false,
msg: "regexp缺失的键名: shareCode,类型: string"
};
}
if (typeof ruleRegExp["shareCodeNeedRemoveStr"] !== "string") {
return {
success: false,
msg: "regexp缺失的键名: shareCodeNeedRemoveStr,类型: string"
};
}
if (typeof ruleRegExp["uiLinkShow"] !== "string") {
return {
success: false,
msg: "regexp缺失的键名: uiLinkShow,类型: string"
};
}
if (typeof ruleRegExp["blank"] !== "string") {
return {
success: false,
msg: "regexp缺失的键名: blank,类型: string"
};
}
if (typeof ruleRegExp["copyUrl"] !== "string") {
return {
success: false,
msg: "regexp缺失的键名: copyUrl,类型: string"
};
}
if (typeof ruleRegExp["accessCode"] === "string" && typeof ruleRegExp["checkAccessCode"] !== "string") {
return {
success: false,
msg: "regexp设置了accessCode但是没有设置checkAccessCode"
};
}
if (typeof ruleRegExp["accessCode"] !== "string" && typeof ruleRegExp["checkAccessCode"] === "string") {
return {
success: false,
msg: "regexp设置了checkAccessCode但是没有设置accessCode"
};
}
return {
success: true,
msg: "校验rule成功"
};
}
function checkSetting(ruleSetting) {
if (typeof ruleSetting["name"] !== "string") {
return {
success: false,
msg: "setting缺失的键名: name,类型: string"
};
}
if (typeof ruleSetting["enable"] !== "boolean") {
return {
success: false,
msg: "setting缺失的键名: enable,类型: boolean"
};
}
return {
success: true,
msg: "校验setting成功"
};
}
try {
let ruleJSON = JSON.parse(ruleText);
if (typeof ruleJSON !== "object") {
return {
success: false,
msg: "该规则不是object类型"
};
}
if (typeof ruleJSON["key"] !== "string") {
return {
success: false,
msg: "缺失的键名: key,类型: string"
};
}
if (typeof ruleJSON["regexp"] !== "object") {
return {
success: false,
msg: "缺失的键名: regexp,类型: object|Arrany"
};
}
if (typeof ruleJSON["setting"] !== "object") {
return {
success: false,
msg: "缺失的键名: setting,类型: object"
};
}
if (Array.isArray(ruleJSON["regexp"])) {
for (const regexpItem of ruleJSON["regexp"]) {
let result = checkRegExp(regexpItem);
if (!result.success) {
return result;
}
}
} else {
let result = checkRegExp(ruleJSON["regexp"]);
if (!result.success) {
return result;
}
}
let checkSettingResult = checkSetting(ruleJSON["setting"]);
if (!checkSettingResult.success) {
return checkSettingResult;
}
return {
success: true,
msg: "解析成功",
data: ruleJSON
};
} catch (error) {
log.error(error);
return {
success: false,
msg: error.message
};
}
},
/**
* 上下文环境
* @param rule
*/
getBindContext(rule) {
let storageUtils = new StorageUtils(NetDiskUserRule.userRuleContextDataKey);
return {
rule,
NetDiskRequire,
CryptoJS: Cryptojs,
httpx,
utils,
DOMUtils: domUtils,
window,
unsafeWindow: _unsafeWindow,
NetDiskCheckLinkValidity,
log,
Qmsg,
pops: __pops,
setValue: storageUtils.set.bind(storageUtils),
getValue: storageUtils.get.bind(storageUtils),
deleteValue: storageUtils.delete.bind(storageUtils)
};
},
/**
* 把用户自定义规则进行转换成脚本规则
* @param localRule 用户的规则
*/
parseRule(localRule) {
function parseUserRuleToScriptRule(ruleKey, userRuleConfig, ruleRegExp) {
const {
shareCode,
shareCodeNeedRemoveStr,
shareCodeNotMatch,
checkAccessCode,
accessCode,
acceesCodeNotMatch,
paramMatch,
...otherRuleParams
} = ruleRegExp;
let netDiskRegularOption = {
...otherRuleParams
};
netDiskRegularOption.link_innerText = NetDiskRuleUtils.replaceParam(
netDiskRegularOption.link_innerText,
NetDiskUserRuleReplaceParam_matchRange_text(ruleKey)
);
netDiskRegularOption.link_innerHTML = NetDiskRuleUtils.replaceParam(
netDiskRegularOption.link_innerText,
NetDiskUserRuleReplaceParam_matchRange_html(ruleKey)
);
if (typeof shareCode === "string") {
netDiskRegularOption.shareCode = new RegExp(shareCode, "ig");
}
if (typeof shareCodeNeedRemoveStr === "string") {
netDiskRegularOption.shareCodeNeedRemoveStr = new RegExp(
shareCodeNeedRemoveStr,
"ig"
);
}
if (typeof shareCodeNotMatch === "string") {
netDiskRegularOption.shareCodeNotMatch = new RegExp(
shareCodeNotMatch,
"ig"
);
}
if (typeof checkAccessCode === "string") {
netDiskRegularOption.checkAccessCode = new RegExp(
checkAccessCode,
"ig"
);
}
if (typeof accessCode === "string") {
netDiskRegularOption.accessCode = new RegExp(accessCode, "ig");
}
if (typeof acceesCodeNotMatch === "string") {
netDiskRegularOption.acceesCodeNotMatch = new RegExp(
acceesCodeNotMatch,
"ig"
);
}
if (typeof paramMatch === "string") {
netDiskRegularOption.paramMatch = new RegExp(paramMatch, "i");
}
return netDiskRegularOption;
}
let netDiskRuleConfigList = [];
for (const userRuleItemConfig of localRule) {
let netDiskRuleConfig = {
rule: [],
setting: {
name: userRuleItemConfig.setting.name,
key: userRuleItemConfig.key,
configurationInterface: {
matchRange_text: {},
matchRange_html: {},
function: {},
linkClickMode_openBlank: {},
schemeUri: {},
ownFormList: []
}
},
isUserRule: true
};
const userRuleList = userRuleItemConfig.regexp;
const ruleKey = userRuleItemConfig.key;
if (Array.isArray(userRuleList)) {
userRuleList.forEach((userRuleItem) => {
netDiskRuleConfig.rule.push(
parseUserRuleToScriptRule(ruleKey, userRuleItemConfig, userRuleItem)
);
});
} else {
netDiskRuleConfig.rule.push(
parseUserRuleToScriptRule(ruleKey, userRuleItemConfig, userRuleList)
);
}
if (userRuleItemConfig.setting) {
this.initDefaultValue(
NetDiskRuleDataKEY.function.enable(ruleKey),
Boolean(userRuleItemConfig.setting.enable)
);
netDiskRuleConfig.setting.configurationInterface.function.enable = Boolean(userRuleItemConfig.setting.enable);
if (typeof userRuleItemConfig.setting["isBlank"] === "boolean") {
this.initDefaultValue(
NetDiskRuleDataKEY.function.linkClickMode(ruleKey),
"openBlank"
);
netDiskRuleConfig.setting.configurationInterface.function.linkClickMode = {
openBlank: {
default: true,
enable: true
}
};
}
if (typeof userRuleItemConfig.setting.linkClickMode === "object") {
let data = utils.assign(
NetDiskRuleUtils.getDefaultLinkClickMode(),
userRuleItemConfig.setting.linkClickMode || {}
);
let default_value = null;
let selectData = Object.keys(data).map((keyName) => {
let itemData = data[keyName];
if (!itemData.enable) {
return;
}
if (itemData.default) {
default_value = keyName;
}
return {
value: keyName,
text: itemData.text
};
}).filter((item) => item != null);
if (default_value == null) {
default_value = selectData[0].value;
}
this.initDefaultValue(
NetDiskRuleDataKEY.function.linkClickMode(ruleKey),
default_value
);
}
if (typeof userRuleItemConfig.setting["openBlankWithCopyAccessCode"] === "boolean") {
this.initDefaultValue(
NetDiskRuleDataKEY.linkClickMode_openBlank.openBlankWithCopyAccessCode(
ruleKey
),
Boolean(userRuleItemConfig.setting["openBlankWithCopyAccessCode"])
);
netDiskRuleConfig.setting.configurationInterface.linkClickMode_openBlank.openBlankWithCopyAccessCode = Boolean(userRuleItemConfig.setting["openBlankWithCopyAccessCode"]);
}
if (typeof userRuleItemConfig.setting["checkLinkValidity"] === "boolean") {
this.initDefaultValue(
NetDiskRuleDataKEY.function.checkLinkValidity(ruleKey),
Boolean(userRuleItemConfig.setting["checkLinkValidity"])
);
netDiskRuleConfig.setting.configurationInterface.function.checkLinkValidity = Boolean(userRuleItemConfig.setting["checkLinkValidity"]);
}
if (typeof userRuleItemConfig.setting["checkLinkValidityHoverTip"] === "boolean") {
this.initDefaultValue(
NetDiskRuleDataKEY.function.checkLinkValidityHoverTip(ruleKey),
Boolean(userRuleItemConfig.setting["checkLinkValidityHoverTip"])
);
}
if (typeof userRuleItemConfig.setting["isForward"] === "boolean") {
this.initDefaultValue(
NetDiskRuleDataKEY.schemeUri.enable(ruleKey),
Boolean(userRuleItemConfig.setting["isForward"])
);
netDiskRuleConfig.setting.configurationInterface.schemeUri.enable = Boolean(userRuleItemConfig.setting["isForward"]);
}
if (typeof userRuleItemConfig.setting["schemeUri"] === "string") {
this.initDefaultValue(
NetDiskRuleDataKEY.schemeUri.uri(ruleKey),
userRuleItemConfig.setting["schemeUri"]
);
netDiskRuleConfig.setting.configurationInterface.schemeUri.uri = userRuleItemConfig.setting["schemeUri"];
}
if (typeof userRuleItemConfig.setting["innerTextAccessCodeBeforeMaxRange"] === "number") {
this.initDefaultValue(
NetDiskRuleDataKEY.matchRange_text.before(ruleKey),
userRuleItemConfig.setting["innerTextAccessCodeBeforeMaxRange"]
);
netDiskRuleConfig.setting.configurationInterface.matchRange_text.before = userRuleItemConfig.setting["innerTextAccessCodeBeforeMaxRange"];
}
if (typeof userRuleItemConfig.setting["innerTextAccessCodeAfterMaxRange"] === "number") {
this.initDefaultValue(
NetDiskRuleDataKEY.matchRange_text.after(ruleKey),
userRuleItemConfig.setting["innerTextAccessCodeAfterMaxRange"]
);
netDiskRuleConfig.setting.configurationInterface.matchRange_text.after = userRuleItemConfig.setting["innerTextAccessCodeAfterMaxRange"];
}
if (typeof userRuleItemConfig.setting["innerHTMLAccessCodeBeforeMaxRange"] === "number") {
this.initDefaultValue(
NetDiskRuleDataKEY.matchRange_html.before(ruleKey),
userRuleItemConfig.setting["innerHTMLAccessCodeBeforeMaxRange"]
);
netDiskRuleConfig.setting.configurationInterface.matchRange_html.before = userRuleItemConfig.setting["innerHTMLAccessCodeBeforeMaxRange"];
}
if (typeof userRuleItemConfig.setting["innerHTMLAccessCodeAfterMaxRange"] === "number") {
this.initDefaultValue(
NetDiskRuleDataKEY.matchRange_html.after(ruleKey),
userRuleItemConfig.setting["innerHTMLAccessCodeAfterMaxRange"]
);
netDiskRuleConfig.setting.configurationInterface.matchRange_html.after = userRuleItemConfig.setting["innerHTMLAccessCodeAfterMaxRange"];
}
}
if (typeof userRuleItemConfig.icon === "string") {
let ruleIcon = userRuleItemConfig.icon;
NetDiskUI.src.addIcon(ruleKey, ruleIcon);
}
const AsyncFunction = Object.getPrototypeOf(
async function() {
}
).constructor;
if (typeof userRuleItemConfig.checkLinkValidityFunction === "string") {
try {
Reflect.set(NetDiskCheckLinkValidity.netDisk, ruleKey, {
init: new AsyncFunction(
"netDiskIndex",
"shareCode",
"accessCode",
userRuleItemConfig.checkLinkValidityFunction
// 绑定作用域
).bind(this.getBindContext(userRuleItemConfig))
});
} catch (error) {
log.error(error);
}
}
if (typeof userRuleItemConfig.AuthorizationFunction === "string") {
try {
NetDiskAuthorization.netDisk[ruleKey] = new AsyncFunction(
userRuleItemConfig.AuthorizationFunction
).bind(
// 绑定作用域
this.getBindContext(userRuleItemConfig)
);
} catch (error) {
log.error(error);
}
}
if (typeof userRuleItemConfig.AutoFillAccessCodeFunction === "string") {
try {
NetDiskAutoFillAccessCode.netDisk[ruleKey] = new AsyncFunction(
"netDiskInfo",
userRuleItemConfig.AutoFillAccessCodeFunction
// 绑定作用域
).bind(this.getBindContext(userRuleItemConfig));
} catch (error) {
log.error(error);
}
}
if (typeof userRuleItemConfig.parseFunction === "string") {
try {
Reflect.set(
NetDiskParse.netDisk,
ruleKey,
new Function(userRuleItemConfig.parseFunction).bind(
this.getBindContext(userRuleItemConfig)
)
);
} catch (error) {
log.error(error);
}
}
let findValue = netDiskRuleConfigList.find(
(item) => item.setting.key === netDiskRuleConfig.setting.key
);
if (findValue) {
findValue.rule = findValue.rule.concat(netDiskRuleConfig.rule);
} else {
netDiskRuleConfigList.push(netDiskRuleConfig);
}
}
return netDiskRuleConfigList;
},
/**
* 获取配置
*/
getNetDiskRuleConfig() {
return this.$data.userRule.values();
},
/**
* 初始化默认值
*/
initDefaultValue(key, value) {
let localValue = _GM_getValue(key);
if (localValue == null) {
_GM_setValue(key, value);
}
},
/**
* 获取模板规则
*/
getTemplateRule() {
let templateRule = {
key: "规则名",
icon: "图标链接字符串或图片的base64字符串",
regexp: [
{
link_innerText: "",
link_innerHTML: "",
shareCode: "",
shareCodeNeedRemoveStr: "",
uiLinkShow: "",
blank: "",
copyUrl: ""
}
],
setting: {
name: "设置界面的名字",
enable: true,
linkClickMode: "openBlank",
openBlankWithCopyAccessCode: true
}
};
return this.getFormatRule(templateRule);
},
/**
* 添加规则
* @param userRule
*/
addRule(userRule) {
let localRule = this.getAllRule();
localRule.push(userRule);
_GM_setValue(NetDiskUserRule.KEY, localRule);
},
/**
* 设置规则到本地
* @param oldRuleKey 旧规则的键名
* @param userRule
*/
setRule(oldRuleKey, userRule) {
if (Array.isArray(userRule)) {
_GM_setValue(NetDiskUserRule.KEY, userRule);
} else {
let localRule = this.getAllRule();
let findRuleIndex = localRule.findIndex(
(item) => item.key === oldRuleKey
);
if (findRuleIndex !== -1) {
localRule[findRuleIndex] = null;
localRule[findRuleIndex] = userRule;
} else {
log.error("覆盖规则失败", userRule);
Qmsg.error("覆盖规则失败");
return false;
}
this.setRule(oldRuleKey, localRule);
}
},
/**
* 删除单条规则
* @param ruleKey 规则的key名
*/
deleteRule(ruleKey) {
let localRule = this.getAllRule();
let findIndex = localRule.findIndex((rule) => rule.key === ruleKey);
if (findIndex !== -1) {
localRule.splice(findIndex, 1);
this.setRule(ruleKey, localRule);
return true;
} else {
return false;
}
},
/**
* 清空规则
*/
clearRule() {
_GM_deleteValue(NetDiskUserRule.KEY);
},
/**
* 获取本地所有的规则
*/
getAllRule() {
let result = _GM_getValue(
NetDiskUserRule.KEY,
[]
);
return result;
},
/**
* 获取规则
*/
getRule(key) {
let localRule = _GM_getValue(NetDiskUserRule.KEY, []);
return localRule.find((item) => item.key === key);
},
/**
* 获取格式化后的规则
* @param rule
*/
getFormatRule(rule) {
return JSON.stringify(rule || this.getAllRule(), void 0, 4);
}
};
const NetDiskRule_baidu = {
/** 规则 */
rule: [
{
link_innerText: `pan.baidu.com/s/[0-9a-zA-Z-_]{6,24}([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码|\\?pwd=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `pan.baidu.com/s/[0-9a-zA-Z-_]{6,24}([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码|\\?pwd=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /pan\.baidu\.com\/s\/([0-9a-zA-Z-_]+)/gi,
shareCodeNeedRemoveStr: /pan\.baidu\.com\/s\//gi,
checkAccessCode: /(密码|访问码|提取码|pwd=)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "pan.baidu.com/s/{#shareCode#}?pwd={#accessCode#}",
blank: "https://pan.baidu.com/s/{#shareCode#}?pwd={#accessCode#}",
copyUrl: "https://pan.baidu.com/s/{#shareCode#}?pwd={#accessCode#}"
},
{
link_innerText: `pan.baidu.com/(share|wap)/init\\?surl=[0-9a-zA-Z-_]{5,24}([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码|&pwd=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `pan.baidu.com/(share|wap)/init\\?surl=[0-9a-zA-Z-_]{5,24}([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码|&pwd=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /pan\.baidu\.com\/(share|wap)\/init\?surl=([0-9a-zA-Z-_]+)/gi,
shareCodeNeedRemoveStr: /pan\.baidu\.com\/(share|wap)\/init\?surl=/gi,
checkAccessCode: /(密码|访问码|提取码|&pwd=)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "pan.baidu.com/share/init?surl={#shareCode#}&pwd={#accessCode#}",
blank: "https://pan.baidu.com/share/init?surl={#shareCode#}&pwd={#accessCode#}",
copyUrl: "https://pan.baidu.com/share/init?surl={#shareCode#}&pwd={#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "百度网盘",
key: "baidu",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardBlankLink: true,
uri: ""
}
// ownFormList: [
// {
// text: "第三方解析站",
// type: "forms",
// forms: [
// UISwitch(
// "启用解析站",
// "baidu-static-enable",
// false,
// void 0,
// "开源项目:https://github.com/yuantuo666/baiduwp-php"
// ),
// UISwitch(
// "跳转时复制链接",
// "baidu-baiduwp-php-copy-url",
// false,
// void 0,
// "跳转至解析站时复制百度网盘链接"
// ),
// UIInput(
// "网址",
// "baidu-baiduwp-php-url",
// "",
// "解析站的网址Url",
// void 0,
// "使用了baiduwp-php源码的网站,例如:https://www.example.com/"
// ),
// UIInput(
// "表单参数",
// "baidu-baiduwp-php-post-form",
// "",
// "解析站的网址Url",
// void 0,
// "POST表单,例如:surl={#shareCode#}&pwd={#accessCode#}&password="
// ),
// ],
// },
// ],
}
}
};
const NetDiskRule_lanzou = () => {
return {
/** 规则 */
rule: [
{
link_innerText: `(lanzou[a-z]{0,1}|lan[a-z]{2}).com/(tp/|u/|)([a-zA-Z0-9_-]{5,22}|[%0-9a-zA-Z]{4,90}|[\\u4e00-\\u9fa5]{1,20})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[a-zA-Z0-9]{3,6}|)`,
link_innerHTML: `(lanzou[a-z]{0,1}|lan[a-z]{2}).com/(tp/|u/|)([a-zA-Z0-9_-]{5,22}|[%0-9a-zA-Z]{4,90}|[\\u4e00-\\u9fa5]{1,20})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[a-zA-Z0-9]{3,6}|)`,
shareCode: /(lanzou[a-z]{0,1}|lan[a-z]{2}).com\/(tp\/|u\/|)([a-zA-Z0-9_\-]{5,22}|[%0-9a-zA-Z]{4,90}|[\u4e00-\u9fa5]{1,20})/gi,
shareCodeNeedRemoveStr: /(lanzou[a-z]{0,1}|lan[a-z]{2}).com\/(tp\/|u\/|)/gi,
shareCodeExcludeRegular: ["lanzouyx"],
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{3,})/gi,
uiLinkShow: `${NetDiskParse_Lanzou_Config.hostname}/{#shareCode#} 提取码: {#accessCode#}`,
blank: `https://${NetDiskParse_Lanzou_Config.hostname}/{#shareCode#}`,
copyUrl: `https://${NetDiskParse_Lanzou_Config.hostname}/{#shareCode#}
密码:{#accessCode#}`
},
{
link_innerText: `(lanzou[a-z]{0,1}|lan[a-z]{2}).com/s/([a-zA-Z0-9_-]{5,22}|[%0-9a-zA-Z]{4,90}|[\\u4e00-\\u9fa5]{1,20})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[a-zA-Z0-9]{3,6}|)`,
link_innerHTML: `(lanzou[a-z]{0,1}|lan[a-z]{2}).com/s/([a-zA-Z0-9_-]{5,22}|[%0-9a-zA-Z]{4,90}|[\\u4e00-\\u9fa5]{1,20})([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[a-zA-Z0-9]{3,6}|)`,
shareCode: /(lanzou[a-z]{0,1}|lan[a-z]{2}).com\/s\/([a-zA-Z0-9_\-]{5,22}|[%0-9a-zA-Z]{4,90}|[\u4e00-\u9fa5]{1,20})/gi,
shareCodeNeedRemoveStr: /(lanzou[a-z]{0,1}|lan[a-z]{2}).com\/s\//gi,
shareCodeExcludeRegular: ["lanzouyx"],
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{3,})/gi,
uiLinkShow: `${NetDiskParse_Lanzou_Config.hostname}/s/{#shareCode#} 提取码: {#accessCode#}`,
blank: `https://${NetDiskParse_Lanzou_Config.hostname}/s/{#shareCode#}`,
copyUrl: `https://${NetDiskParse_Lanzou_Config.hostname}/s/{#shareCode#}
密码:{#accessCode#}`
}
],
/** 设置项 */
setting: {
name: "蓝奏云",
key: "lanzou",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
},
parseFile: {
enable: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardLinearChain: false,
isForwardBlankLink: false,
uri: ""
},
ownFormList: [
{
text: "其它配置",
type: "forms",
forms: [
UIInput(
"蓝奏云域名",
NetDiskParse_Lanzou_Config.MENU_KEY,
NetDiskParse_Lanzou_Config.DEFAULT_HOST_NAME,
"",
void 0,
`例如:${NetDiskParse_Lanzou_Config.DEFAULT_HOST_NAME}`
)
]
}
]
}
}
};
};
const NetDiskRule_lanzouyx = {
/** 规则 */
rule: [
{
link_innerText: `ilanzou.com/s/([a-zA-Z0-9_-]{5,22})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码|\\?code=)[\\s\\S]{0,{#matchRange-text-after#}}[a-zA-Z0-9]{3,6}|)`,
link_innerHTML: `ilanzou.com/s/([a-zA-Z0-9_-]{5,22})([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码|\\?code=)[\\s\\S]{0,{#matchRange-html-after#}}[a-zA-Z0-9]{3,6}|)`,
shareCode: /ilanzou.com\/s\/([a-zA-Z0-9_\-]{5,22})/gi,
shareCodeNeedRemoveStr: /ilanzou.com\/s\//gi,
checkAccessCode: /(密码|访问码|提取码|\?code=)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{3,})/gi,
uiLinkShow: `www.ilanzou.com/s/{#shareCode#} 提取码: {#accessCode#}`,
blank: `https://www.ilanzou.com/s/{#shareCode#}?code={#accessCode#}`,
copyUrl: `https://www.ilanzou.com/s/{#shareCode#}?code={#accessCode#}`
}
],
/** 设置项 */
setting: {
name: "蓝奏云优享",
key: "lanzouyx",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
},
parseFile: {
enable: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardLinearChain: false,
isForwardBlankLink: false,
uri: ""
}
}
}
};
const NetDiskRule_tianyiyun = {
/** 规则 */
rule: [
{
link_innerText: `(cloud.189.cn/web/share\\?code=([0-9a-zA-Z_-]){8,14}|cloud.189.cn/t/([a-zA-Z0-9_-]{8,14}))([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `(cloud.189.cn/web/share\\?code=([0-9a-zA-Z_-]){8,14}|cloud.189.cn/t/([a-zA-Z0-9_-]{8,14}))([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /cloud.189.cn\/web\/share\?code=([0-9a-zA-Z_\-]){8,14}|cloud.189.cn\/t\/([a-zA-Z0-9_\-]{8,14})/gi,
shareCodeNeedRemoveStr: /cloud\.189\.cn\/t\/|cloud.189.cn\/web\/share\?code=/gi,
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "cloud.189.cn/t/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://cloud.189.cn/t/{#shareCode#}",
copyUrl: "https://cloud.189.cn/t/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "天翼云",
key: "tianyiyun",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
},
parseFile: {
enable: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardLinearChain: false,
isForwardBlankLink: false,
uri: ""
}
}
}
};
const NetDiskRule_hecaiyun = {
/** 规则 */
rule: [
{
link_innerText: `caiyun.139.com/m/i\\?([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `caiyun.139.com/m/i\\?([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /caiyun\.139\.com\/m\/i\?([a-zA-Z0-9_\-]{8,14})/gi,
shareCodeNeedRemoveStr: /caiyun\.139\.com\/m\/i\?/gi,
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "caiyun.139.com/m/i?{#shareCode#} 提取码: {#accessCode#}",
blank: "https://caiyun.139.com/m/i?{#shareCode#}",
copyUrl: "https://caiyun.139.com/m/i?{#shareCode#}\n密码:{#accessCode#}"
},
{
link_innerText: `yun.139.com/link/w/i/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `yun.139.com/link/w/i/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /yun\.139\.com\/link\/w\/i\/([a-zA-Z0-9_\-]{8,14})/gi,
shareCodeNeedRemoveStr: /yun\.139\.com\/link\/w\/i\//gi,
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "yun.139.com/link/w/i/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://yun.139.com/link/w/i/{#shareCode#}",
copyUrl: "https://yun.139.com/link/w/i/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "中国移动云盘",
key: "hecaiyun",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
}
}
// checkLinkValidity: true,
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardBlankLink: false,
uri: ""
}
}
}
};
const NetDiskRule_aliyun = {
/** 规则 */
rule: [
{
link_innerText: `aliyundrive.com/s/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `aliyundrive.com/s/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /aliyundrive\.com\/s\/([a-zA-Z0-9_\-]{8,14})/g,
shareCodeNeedRemoveStr: /aliyundrive\.com\/s\//gi,
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "aliyundrive.com/s/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://www.aliyundrive.com/s/{#shareCode#}",
copyUrl: "https://www.aliyundrive.com/s/{#shareCode#}\n密码:{#accessCode#}"
},
{
link_innerText: `aliyundrive.com/t/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `aliyundrive.com/t/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /aliyundrive\.com\/t\/([a-zA-Z0-9_\-]{8,14})/g,
shareCodeNeedRemoveStr: /aliyundrive\.com\/t\//gi,
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "aliyundrive.com/t/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://www.aliyundrive.com/t/{#shareCode#}",
copyUrl: "https://www.aliyundrive.com/t/{#shareCode#}\n密码:{#accessCode#}"
},
{
link_innerText: `alipan.com/s/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `alipan.com/s/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /alipan\.com\/s\/([a-zA-Z0-9_\-]{8,14})/g,
shareCodeNeedRemoveStr: /alipan\.com\/s\//gi,
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "alipan.com/s/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://www.alipan.com/s/{#shareCode#}",
copyUrl: "https://www.alipan.com/s/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "阿里云",
key: "aliyun",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
},
parseFile: {
enable: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardLinearChain: true,
isForwardBlankLink: true,
uri: ""
}
}
}
};
const NetDiskRule_wenshushu = {
/** 规则 */
rule: [
{
link_innerText: `(wenshushu.cn/f/([a-zA-Z0-9_-]{8,14})|wenshushu.cn/k/([a-zA-Z0-9_-]{8,14}))([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `(wenshushu.cn/f/([a-zA-Z0-9_-]{8,14})|wenshushu.cn/k/([a-zA-Z0-9_-]{8,14}))([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /wenshushu.cn\/f\/([a-zA-Z0-9_-]{8,14})|wenshushu.cn\/k\/([a-zA-Z0-9_-]{8,14})/gi,
shareCodeNeedRemoveStr: /wenshushu.cn\/f\/|wenshushu.cn\/k\//gi,
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /[0-9a-zA-Z]{4}/gi,
uiLinkShow: "www.wenshushu.cn/f/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://www.wenshushu.cn/f/{#shareCode#}",
copyUrl: "https://www.wenshushu.cn/f/{#shareCode#}\n密码:{#accessCode#}"
},
{
link_innerText: `(wss.ink/f/([a-zA-Z0-9_-]{8,14})|ws28.cn/f/([a-zA-Z0-9_-]{8,14})|wss1.cn/f/([a-zA-Z0-9_-]{8,14})|ws59.cn/f/([a-zA-Z0-9_-]{8,14}))([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `(wss.ink/f/([a-zA-Z0-9_-]{8,14})|ws28.cn/f/([a-zA-Z0-9_-]{8,14})|wss1.cn/f/([a-zA-Z0-9_-]{8,14})|ws59.cn/f/([a-zA-Z0-9_-]{8,14}))([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /wss.ink\/f\/([a-zA-Z0-9_-]{8,14})|ws28.cn\/f\/([a-zA-Z0-9_-]{8,14})|wss1.cn\/f\/([a-zA-Z0-9_-]{8,14})|ws59.cn\/f\/([a-zA-Z0-9_-]{8,14})/gi,
shareCodeNeedRemoveStr: /wss.ink\/f\/|ws28.cn\/f\/|wss1.cn\/f\/|ws59.cn\/f\//gi,
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /[0-9a-zA-Z]{4}/gi,
uiLinkShow: "www.wenshushu.cn/f/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://www.wenshushu.cn/f/{#shareCode#}",
copyUrl: "https://www.wenshushu.cn/f/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "文叔叔",
key: "wenshushu",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
},
parseFile: {
enable: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardLinearChain: true,
isForwardBlankLink: true,
uri: ""
}
}
}
};
const NetDiskRule_nainiu = {
/** 规则 */
rule: [
{
link_innerText: `cowtransfer.com/s/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-text-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4,6}|)`,
link_innerHTML: `cowtransfer.com/s/([a-zA-Z0-9_-]{8,14})([\\s\\S]{0,{#matchRange-html-before#}}(密码|访问码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4,6}|)`,
shareCode: /cowtransfer.com\/s\/([a-zA-Z0-9_\-]{8,14})/gi,
shareCodeNeedRemoveStr: /cowtransfer\.com\/s\//gi,
checkAccessCode: /(密码|访问码|提取码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4,6})/gi,
uiLinkShow: "cowtransfer.com/s/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://cowtransfer.com/s/{#shareCode#}",
copyUrl: "https://cowtransfer.com/s/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "奶牛",
key: "nainiu",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
},
parseFile: {
enable: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardLinearChain: true,
isForwardBlankLink: true,
uri: ""
}
}
}
};
const NetDiskRule_weiyun = {
/** 规则 */
rule: [
{
link_innerText: `weiyun.com/[0-9a-zA-Z-_]{7,24}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4,6}|)`,
link_innerHTML: `weiyun.com/[0-9a-zA-Z-_]{7,24}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4,6}|)`,
shareCode: /weiyun.com\/([0-9a-zA-Z\-_]{7,24})/gi,
shareCodeNeedRemoveStr: /weiyun.com\//gi,
checkAccessCode: /(提取码|密码|访问码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4,6})/gi,
uiLinkShow: "share.weiyun.com/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://share.weiyun.com/{#shareCode#}",
copyUrl: "https://share.weiyun.com/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "微云",
key: "weiyun",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardBlankLink: true,
uri: ""
}
}
}
};
const NetDiskRule_xunlei = {
/** 规则 */
rule: [
{
link_innerText: `xunlei.com/s/[0-9a-zA-Z-_]{8,30}([\\s\\S]{0,{#matchRange-text-before#}}(\\?pwd=|访问码|提取码|密码|)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `xunlei.com/s/[0-9a-zA-Z-_]{8,30}([\\s\\S]{0,{#matchRange-html-before#}}(\\?pwd=|访问码|提取码|密码|)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /xunlei.com\/s\/([0-9a-zA-Z\-_]{8,30})/gi,
shareCodeNeedRemoveStr: /xunlei.com\/s\//gi,
checkAccessCode: /(\?pwd=|提取码|密码|访问码)[\s\S]+/g,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "pan.xunlei.com/s/{#shareCode#}?pwd={#accessCode#} 提取码: {#accessCode#}",
blank: "https://pan.xunlei.com/s/{#shareCode#}?pwd={#accessCode#}",
copyUrl: "https://pan.xunlei.com/s/{#shareCode#}?pwd={#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "迅雷云盘",
key: "xunlei",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardBlankLink: true,
uri: ""
}
}
}
};
const NetDiskRule_chengtong = {
/** 规则 */
rule: [
/* d */
{
link_innerText: `(pan.jc-box.com|download.jamcz.com|545c.com)/d/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4,6}|)`,
link_innerHTML: `(pan.jc-box.com|download.jamcz.com|545c.com)/d/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4,6}|)`,
shareCode: /(pan.jc-box.com|download.jamcz.com|545c.com)\/d\/([0-9a-zA-Z\-_]{8,26})/gi,
shareCodeNeedRemoveStr: /(pan.jc-box.com|download.jamcz.com|545c.com)\/d\//gi,
checkAccessCode: /(提取码|密码|访问码|\\?password=|\\?p=)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{4,6})/gi,
paramMatch: /([a-zA-Z0-9\.]+)\/d\//i,
uiLinkShow: "{#$1#}/d/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://{#$1#}/d/{#shareCode#}?p={#accessCode#}",
copyUrl: "https://{#$1#}/d/{#shareCode#}?p={#accessCode#}\n密码:{#accessCode#}"
},
/* d ==> http */
{
link_innerText: `ct.ghpym.com/d/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4,6}|)`,
link_innerHTML: `ct.ghpym.com/d/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4,6}|)`,
shareCode: /ct.ghpym.com\/d\/([0-9a-zA-Z\-_]{8,26})/gi,
shareCodeNeedRemoveStr: /ct.ghpym.com\/d\//gi,
checkAccessCode: /(提取码|密码|访问码|\\?password=|\\?p=)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{4,6})/gi,
paramMatch: /([a-zA-Z0-9\.]+)\/d\//i,
uiLinkShow: "{#$1#}/d/{#shareCode#} 提取码: {#accessCode#}",
blank: "http://{#$1#}/d/{#shareCode#}?p={#accessCode#}",
copyUrl: "http://{#$1#}/d/{#shareCode#}?p={#accessCode#}\n密码:{#accessCode#}"
},
/* d */
{
link_innerText: `ctfile.com/d/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4,6}|)`,
link_innerHTML: `ctfile.com/d/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4,6}|)`,
shareCode: /ctfile.com\/d\/([0-9a-zA-Z\-_]{8,26})/gi,
shareCodeNeedRemoveStr: /ctfile.com\/d\//gi,
checkAccessCode: /(提取码|密码|访问码|\\?password=|\\?p=)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{4,6})/gi,
uiLinkShow: "url95.ctfile.com/d/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://url95.ctfile.com/d/{#shareCode#}?p={#accessCode#}",
copyUrl: "https://url95.ctfile.com/d/{#shareCode#}?p={#accessCode#}\n密码:{#accessCode#}"
},
/* file */
{
link_innerText: `(2k.us|u062.com|545c.com|t00y.com|tc5.us)/file/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4,6}|)`,
link_innerHTML: `(2k.us|u062.com|545c.com|t00y.com|tc5.us)/file/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4,6}|)`,
shareCode: /(2k.us|u062.com|545c.com|t00y.com|tc5.us)\/file\/([0-9a-zA-Z\-_]{8,26})/gi,
shareCodeNeedRemoveStr: /(2k.us|u062.com|545c.com|t00y.com|tc5.us)\/file\//gi,
checkAccessCode: /(提取码|密码|访问码|\\?password=|\\?p=)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{4,6})/gi,
uiLinkShow: "u062.com/file/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://u062.com/file/{#shareCode#}?p={#accessCode#}",
copyUrl: "https://u062.com/file/{#shareCode#}?p={#accessCode#}\n密码:{#accessCode#}"
},
/* f ==> http */
{
link_innerText: `(pan.jc-box.com|545c.com|down.jc-box.com|download.cx05.cc|download.jamcz.com|download.macenjoy.co)/f/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4,6}|)`,
link_innerHTML: `(pan.jc-box.com|545c.com|down.jc-box.com|download.cx05.cc|download.jamcz.com|download.macenjoy.co)/f/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4,6}|)`,
shareCode: /(pan.jc-box.com|545c.com|down.jc-box.com|download.cx05.cc|download.jamcz.com|download.macenjoy.co)\/f\/([0-9a-zA-Z\-_]{8,26})/gi,
shareCodeNeedRemoveStr: /(pan.jc-box.com|545c.com|down.jc-box.com|download.cx05.cc|download.jamcz.com|download.macenjoy.co)\/f\//gi,
checkAccessCode: /(提取码|密码|访问码|\\?password=|\\?p=)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{4,6})/gi,
paramMatch: /([0-9a-zA-Z\.]+)\/f\//i,
uiLinkShow: "{#$1#}/f/{#shareCode#} 提取码: {#accessCode#}",
blank: "http://{#$1#}/f/{#shareCode#}?p={#accessCode#}",
copyUrl: "http://{#$1#}/f/{#shareCode#}?p={#accessCode#}\n密码:{#accessCode#}"
},
/* f ==> http */
{
link_innerText: `url[0-9]{2}.com/f/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4,6}|)`,
link_innerHTML: `url[0-9]{2}.com/f/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4,6}|)`,
shareCode: /url[0-9]{2}.com\/f\/([0-9a-zA-Z\-_]{8,26})/gi,
shareCodeNeedRemoveStr: /url[0-9]{2}.com\/f\//gi,
checkAccessCode: /(提取码|密码|访问码|\\?password=|\\?p=)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{4,6})/gi,
paramMatch: /([0-9a-zA-Z\.]+)\/f\//i,
uiLinkShow: "{#$1#}/f/{#shareCode#} 提取码: {#accessCode#}",
blank: "http://{#$1#}/f/{#shareCode#}?p={#accessCode#}",
copyUrl: "http://{#$1#}/f/{#shareCode#}?p={#accessCode#}\n密码:{#accessCode#}"
},
/* f */
{
link_innerText: `(ctfile.com|089u.com)/f/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4,6}|)`,
link_innerHTML: `(ctfile.com|089u.com)/f/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4,6}|)`,
shareCode: /(ctfile.com|089u.com)\/f\/([0-9a-zA-Z\-_]{8,26})/gi,
shareCodeNeedRemoveStr: /(ctfile.com|089u.com)\/f\//gi,
checkAccessCode: /(提取码|密码|访问码|\\?password=|\\?p=)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{4,6})/gi,
uiLinkShow: "url95.ctfile.com/f/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://url95.ctfile.com/f/{#shareCode#}?p={#accessCode#}",
copyUrl: "https://url95.ctfile.com/f/{#shareCode#}?p={#accessCode#}\n密码:{#accessCode#}"
},
/* dir */
{
link_innerText: `(089u.com|474b.com)/dir/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4,6}|)`,
link_innerHTML: `(089u.com|474b.com)/dir/[0-9a-zA-Z-_]{8,26}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=|\\?p=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{6}|)`,
shareCode: /(089u.com|474b.com)\/dir\/([0-9a-zA-Z\-_]{8,26})/gi,
shareCodeNeedRemoveStr: /(089u.com|474b.com)\/dir\//gi,
checkAccessCode: /(提取码|密码|访问码|\\?password=|\\?p=)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{6})/gi,
uiLinkShow: "089u.com/dir/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://089u.com/dir/{#shareCode#}?p={#accessCode#}",
copyUrl: "https://089u.com/dir/{#shareCode#}?p={#accessCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "城通网盘",
key: "chengtong",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
},
parseFile: {
enable: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardBlankLink: true,
uri: ""
},
ownFormList: [
{
type: "forms",
text: "文件解析配置",
forms: [
UIInput(
"解析站",
"chengtong-parse-file-api-host",
"https://ctfile.qinlili.bid",
"解析站配置,暂时只支持file,非file为新标签页打开",
void 0,
""
)
]
}
]
}
}
};
const NetDiskRule_kuake = {
/** 规则 */
rule: [
{
link_innerText: `quark.cn/s/[0-9a-zA-Z-_]{8,24}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `quark.cn/s/[0-9a-zA-Z-_]{8,24}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /quark.cn\/s\/([0-9a-zA-Z\-_]{8,24})/gi,
shareCodeNeedRemoveStr: /quark.cn\/s\//gi,
checkAccessCode: /(提取码|密码|访问码)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "quark.cn/s/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://pan.quark.cn/s/{#shareCode#}",
copyUrl: "https://pan.quark.cn/s/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "夸克网盘",
key: "kuake",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardBlankLink: true,
uri: ""
}
}
}
};
const NetDiskRule_magnet = {
/** 规则 */
rule: [
{
link_innerText: `magnet:\\?xt=urn:btih:[0-9a-fA-F]{32,40}`,
link_innerHTML: `magnet:\\?xt=urn:btih:[0-9a-fA-F]{32,40}`,
shareCode: /magnet:\?xt=urn:btih:([0-9a-fA-F]{32,40})/gi,
shareCodeNeedRemoveStr: /magnet:\?xt=urn:btih:/gi,
checkAccessCode: /(提取码|密码|访问码)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{4})/gi,
uiLinkShow: "magnet:?xt=urn:btih:{#shareCode#}",
blank: "magnet:?xt=urn:btih:{#shareCode#}",
copyUrl: "magnet:?xt=urn:btih:{#shareCode#}"
}
],
/** 设置项 */
setting: {
name: "BT磁力",
key: "magnet",
configurationInterface: {
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
}
}
},
schemeUri: {
enable: false,
isForwardBlankLink: true,
uri: ""
}
}
}
};
const NetDiskRule_jianguoyun = {
/** 规则 */
rule: [
{
link_innerText: `jianguoyun.com/p/[0-9a-zA-Z-_]{16,24}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]+|)`,
link_innerHTML: `jianguoyun.com/p/[0-9a-zA-Z-_]{16,24}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]+|)`,
shareCode: /jianguoyun.com\/p\/([0-9a-zA-Z\-_]{16,24})/gi,
shareCodeNeedRemoveStr: /jianguoyun.com\/p\//gi,
checkAccessCode: /(提取码|密码|访问码)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{3,6})/gi,
uiLinkShow: "jianguoyun.com/p/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://www.jianguoyun.com/p/{#shareCode#}",
copyUrl: "https://www.jianguoyun.com/p/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "坚果云",
key: "jianguoyun",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
},
parseFile: {
enable: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardLinearChain: false,
isForwardBlankLink: false,
uri: ""
}
}
}
};
const NetDiskRule_onedrive = {
/** 规则 */
rule: [
{
link_innerText: `[0-9a-zA-Z-_]+.sharepoint.com/[0-9a-zA-Z-_:]+/[0-9a-zA-Z-_:]+/personal/[0-9a-zA-Z-_]+/[0-9a-zA-Z-_]+([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=\\?e=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]+|)`,
link_innerHTML: `[0-9a-zA-Z-_]+.sharepoint.com/[0-9a-zA-Z-_:]+/[0-9a-zA-Z-_:]+/personal/[0-9a-zA-Z-_]+/[0-9a-zA-Z-_]+([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=\\?e=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]+|)`,
shareCode: /[0-9a-zA-Z-_]+\/[0-9a-zA-Z-_:]+\/[0-9a-zA-Z-_:]+\/personal\/[0-9a-zA-Z-_]+\/([0-9a-zA-Z\-_]+)/gi,
shareCodeNeedRemoveStr: /[0-9a-zA-Z-_]+\/[0-9a-zA-Z-_:]+\/[0-9a-zA-Z-_:]+\/personal\/[0-9a-zA-Z-_]+\//gi,
checkAccessCode: /(提取码|密码|访问码|\?password=|\?e=)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]{4,8})/gi,
paramMatch: /([0-9a-zA-Z-_]+).sharepoint.com\/([0-9a-zA-Z-_:]+)\/([0-9a-zA-Z-_:]+)\/personal\/([0-9a-zA-Z-_]+)\/([0-9a-zA-Z-_]+)/i,
uiLinkShow: "{#$1#}.sharepoint.com/{#$2#}/{#$3#}/personal/{#$4#}/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://{#$1#}.sharepoint.com/{#$2#}/{#$3#}/personal/{#$4#}/{#shareCode#}?e={#accessCode#}",
copyUrl: "https://{#$1#}.sharepoint.com/{#$2#}/{#$3#}/personal/{#$4#}/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "OneDrive",
key: "onedrive",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardBlankLink: false,
uri: ""
}
}
}
};
const NetDiskRule_uc = {
/** 规则 */
rule: [
{
link_innerText: `(drive|fast).uc.cn/s/[0-9a-zA-Z]{8,24}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]+|)`,
link_innerHTML: `(drive|fast).uc.cn/s/[0-9a-zA-Z]{8,24}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]+|)`,
shareCode: /(drive|fast).uc.cn\/s\/([0-9a-zA-Z]{8,24})/gi,
shareCodeNeedRemoveStr: /(drive|fast).uc.cn\/s\//gi,
checkAccessCode: /(提取码|密码|访问码)[\s\S]+/gi,
accessCode: /([0-9a-zA-Z]+)/gi,
uiLinkShow: "drive.uc.cn/s/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://drive.uc.cn/s/{#shareCode#}",
copyUrl: "https://drive.uc.cn/s/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "UC网盘",
key: "uc",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
},
parseFile: {
enable: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardLinearChain: false,
isForwardBlankLink: false,
uri: ""
}
}
}
};
const UISlider = function(text, key, defaultValue, min, max, changeCallBack, getToolTipContent, description, step) {
let result = {
text,
type: "slider",
description,
attributes: {},
props: {},
getValue() {
return this.props[PROPS_STORAGE_API].get(key, defaultValue);
},
getToolTipContent(value) {
if (typeof getToolTipContent === "function") {
return getToolTipContent(value);
} else {
return `${value}`;
}
},
callback(event, value) {
if (typeof changeCallBack === "function") {
if (changeCallBack(event, value)) {
return;
}
}
this.props[PROPS_STORAGE_API].set(key, value);
},
min,
max,
step
};
Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
Reflect.set(result.props, PROPS_STORAGE_API, {
get(key2, defaultValue2) {
return _GM_getValue(key2, defaultValue2);
},
set(key2, value) {
_GM_setValue(key2, value);
}
});
return result;
};
const UISelect = function(text, key, defaultValue, data, callback, description) {
let selectData = [];
if (typeof data === "function") {
selectData = data();
} else {
selectData = data;
}
let result = {
text,
type: "select",
description,
attributes: {},
props: {},
getValue() {
return this.props[PROPS_STORAGE_API].get(key, defaultValue);
},
callback(event, isSelectedValue, isSelectedText) {
let value = isSelectedValue;
log.info(`选择:${isSelectedText}`);
this.props[PROPS_STORAGE_API].set(key, value);
},
data: selectData
};
Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
Reflect.set(result.props, PROPS_STORAGE_API, {
get(key2, defaultValue2) {
return _GM_getValue(key2, defaultValue2);
},
set(key2, value) {
_GM_setValue(key2, value);
}
});
return result;
};
const NetDiskRule_115pan = {
/** 规则 */
rule: [
{
link_innerText: `115.com/s/[0-9a-zA-Z-_]{8,24}([\\s\\S]{0,{#matchRange-text-before#}}(访问码|密码|提取码|\\?password=)[\\s\\S]{0,{#matchRange-text-after#}}[0-9a-zA-Z]{4}|)`,
link_innerHTML: `115.com/s/[0-9a-zA-Z-_]{8,24}([\\s\\S]{0,{#matchRange-html-before#}}(访问码|密码|提取码|\\?password=)[\\s\\S]{0,{#matchRange-html-after#}}[0-9a-zA-Z]{4}|)`,
shareCode: /115.com\/s\/([0-9a-zA-Z\-_]{8,24})/gi,
shareCodeNeedRemoveStr: /115.com\/s\//gi,
checkAccessCode: /(提取码|密码|\?password=|访问码)[\s\S]+/gi,
accessCode: /(\?password=|)([0-9a-zA-Z]{4})/i,
uiLinkShow: "115.com/s/{#shareCode#} 提取码: {#accessCode#}",
blank: "https://115.com/s/{#shareCode#}",
copyUrl: "https://115.com/s/{#shareCode#}\n密码:{#accessCode#}"
}
],
/** 设置项 */
setting: {
name: "115网盘",
key: "_115pan",
configurationInterface: {
matchRange_text: {
before: 20,
after: 10
},
matchRange_html: {
before: 100,
after: 15
},
function: {
enable: true,
linkClickMode: {
openBlank: {
default: true
}
},
checkLinkValidity: true,
checkLinkValidityHoverTip: true
},
linkClickMode_openBlank: {
openBlankWithCopyAccessCode: true
},
schemeUri: {
enable: false,
isForwardBlankLink: true,
uri: ""
}
}
}
};
const NetDiskRule = {
/** 规则存储的数据 */
dataKey: "ruleData",
$data: {
/** 规则的配置界面信息 */
ruleContent: []
},
init() {
this.initRule();
},
/**
* 初始化规则的内容
* 1. 动态添加rule到NetDisk.regular
* 2. 生成pops.panel适用的配置
*/
initRule() {
let defaultRuleList = [
NetDiskRule_baidu,
NetDiskRule_lanzou(),
NetDiskRule_lanzouyx,
NetDiskRule_tianyiyun,
NetDiskRule_hecaiyun,
NetDiskRule_aliyun,
NetDiskRule_wenshushu,
NetDiskRule_nainiu,
NetDiskRule_123pan,
NetDiskRule_weiyun,
NetDiskRule_xunlei,
NetDiskRule_115pan,
NetDiskRule_chengtong,
NetDiskRule_kuake,
NetDiskRule_magnet,
NetDiskRule_jianguoyun,
NetDiskRule_onedrive,
NetDiskRule_uc
];
let userRuleList = NetDiskUserRule.getNetDiskRuleConfig();
[...defaultRuleList, ...userRuleList].forEach((netDiskRuleConfig) => {
if (typeof netDiskRuleConfig.setting.key !== "string") {
throw new TypeError("规则未设置key");
}
if (netDiskRuleConfig.rule == null) {
throw new TypeError("规则未设置rule");
}
const ruleKey = netDiskRuleConfig.setting.key;
const ruleName = netDiskRuleConfig.setting.name;
const netDiskRule = netDiskRuleConfig.rule;
if (Reflect.has(NetDisk.$rule.matchRule, ruleKey)) {
let commonRule = NetDisk.$rule.matchRule[ruleKey];
if (netDiskRuleConfig.isUserRule) {
commonRule = [...netDiskRule, ...commonRule];
} else {
commonRule = [...commonRule, ...netDiskRule];
}
let findValue = NetDisk.$rule.rule.find(
(item) => item.setting.key === ruleKey
);
findValue.rule = commonRule;
} else {
Reflect.set(NetDisk.$rule.matchRule, ruleKey, netDiskRuleConfig.rule);
NetDisk.$rule.rule.push(netDiskRuleConfig);
}
Reflect.set(
NetDisk.$rule.ruleSetting,
ruleKey,
netDiskRuleConfig.setting
);
netDiskRuleConfig.rule = this.parseRuleMatchRule(netDiskRuleConfig);
let viewConfig = this.parseRuleSetting(netDiskRuleConfig);
let asideTitle = netDiskRuleConfig.setting.name;
if (NetDiskUI.src.hasIcon(ruleKey)) {
asideTitle = /*html*/
`
${ruleName}
`;
}
let headerTitleText = ruleName;
if (netDiskRuleConfig.isUserRule) {
headerTitleText += /*html*/
`${__pops.config.iconSVG.edit}
`;
headerTitleText += /*html*/
`${__pops.config.iconSVG.delete}
`;
}
this.$data.ruleContent.push({
id: "netdisk-panel-config-" + ruleKey,
title: asideTitle,
headerTitle: headerTitleText,
attributes: {
"data-key": ruleKey
},
forms: viewConfig,
afterRender: (data) => {
data.$asideLiElement.setAttribute(
"data-function-enable",
NetDiskRuleData.function.enable(ruleKey, true).toString()
);
}
});
});
},
/**
* 解析规则的匹配规则
*
* 解析以下内容
*
* 1. 替换字符串类型的内部关键字
*/
parseRuleMatchRule(netDiskRuleConfig) {
let netDiskMatchRule = netDiskRuleConfig.rule;
let netDiskMatchRuleHandler = [];
let ruleKey = netDiskRuleConfig.setting.key;
for (let index = 0; index < netDiskMatchRule.length; index++) {
const netDiskMatchRuleOption = netDiskMatchRule[index];
if (typeof netDiskMatchRuleOption.link_innerText === "string") {
netDiskMatchRuleOption.link_innerText = NetDiskRuleUtils.replaceParam(
netDiskMatchRuleOption.link_innerText,
NetDiskUserRuleReplaceParam_matchRange_text(ruleKey)
);
}
if (typeof netDiskMatchRuleOption.link_innerHTML === "string") {
netDiskMatchRuleOption.link_innerHTML = NetDiskRuleUtils.replaceParam(
netDiskMatchRuleOption.link_innerHTML,
NetDiskUserRuleReplaceParam_matchRange_html(ruleKey)
);
}
netDiskMatchRuleHandler.push(netDiskMatchRuleOption);
}
return netDiskMatchRuleHandler;
},
/**
* 解析规则的设置项
*
* 解析出以下内容:
*
* 1. 视图配置
* 2. 获取设置的最新的值并进行覆盖
* @param netDiskRuleConfig 规则配置
*/
parseRuleSetting(netDiskRuleConfig) {
let formConfigList = [];
const settingConfig = netDiskRuleConfig.setting.configurationInterface;
const ruleKey = netDiskRuleConfig.setting.key;
if (settingConfig == null) {
return [];
}
if (settingConfig.function) {
let function_form = [];
if ("enable" in settingConfig.function) {
let default_value = typeof settingConfig.function.enable === "boolean" ? settingConfig.function.enable : false;
function_form.push(
UISwitch(
"启用",
NetDiskRuleDataKEY.function.enable(ruleKey),
default_value,
(event, value) => {
const notUnableAttrName = "data-function-enable";
let $click = event.target;
let $shadowRoot = $click.getRootNode();
let $currentPanelAside = $shadowRoot.querySelector(
`.pops-panel-aside li[data-key="${ruleKey}"]`
);
if (!$currentPanelAside) {
return;
}
$currentPanelAside.setAttribute(
notUnableAttrName,
value.toString()
);
},
"开启可允许匹配该规则"
)
);
settingConfig.function.enable = NetDiskRuleData.function.enable(ruleKey);
}
if ("linkClickMode" in settingConfig.function) {
let data = utils.assign(
NetDiskRuleUtils.getDefaultLinkClickMode(),
settingConfig.function.linkClickMode || {}
);
let default_value = null;
let selectData = Object.keys(data).map((keyName) => {
let itemData = data[keyName];
if (!itemData.enable) {
return;
}
if (itemData.default) {
default_value = keyName;
}
return {
value: keyName,
text: itemData.text
};
}).filter((item) => item != null);
if (default_value == null) {
default_value = selectData[0].value;
}
function_form.push(
UISelect(
"点击动作",
NetDiskRuleDataKEY.function.linkClickMode(ruleKey),
default_value,
selectData,
void 0,
"点击匹配到的链接的执行的动作"
)
);
for (const linkClickModeKey in settingConfig.function.linkClickMode) {
const linkClickModeItem = settingConfig.function.linkClickMode[linkClickModeKey];
if (linkClickModeKey === NetDiskRuleData.function.linkClickMode(ruleKey)) {
linkClickModeItem.default = true;
} else {
linkClickModeItem.default = false;
}
}
}
if ("checkLinkValidity" in settingConfig.function) {
const default_value = typeof settingConfig.function.checkLinkValidity === "boolean" ? settingConfig.function.checkLinkValidity : true;
function_form.push(
UISwitch(
"验证链接有效性",
NetDiskRuleDataKEY.function.checkLinkValidity(ruleKey),
default_value,
void 0,
"自动请求链接,判断该链接是否有效,在大/小窗内显示验证结果图标"
)
);
settingConfig.function.checkLinkValidity = NetDiskRuleData.function.checkLinkValidity(ruleKey);
}
if ("checkLinkValidityHoverTip" in settingConfig.function) {
const default_value = typeof settingConfig.function.checkLinkValidityHoverTip === "boolean" ? settingConfig.function.checkLinkValidityHoverTip : true;
function_form.push(
UISwitch(
"验证链接有效性-悬停提示",
NetDiskRuleDataKEY.function.checkLinkValidityHoverTip(ruleKey),
default_value,
void 0,
"当鼠标悬停在验证结果图标上时会显示相关验证信息"
)
);
}
if (function_form.length) {
formConfigList.push({
text: "功能",
type: "forms",
forms: function_form
});
}
}
if (settingConfig.linkClickMode_openBlank) {
let linkClickMode_openBlank_form = [];
if ("openBlankWithCopyAccessCode" in settingConfig.linkClickMode_openBlank) {
const default_value = typeof settingConfig.linkClickMode_openBlank.openBlankWithCopyAccessCode === "boolean" ? settingConfig.linkClickMode_openBlank.openBlankWithCopyAccessCode : false;
linkClickMode_openBlank_form.push(
UISwitch(
"跳转时复制访问码",
NetDiskRuleDataKEY.linkClickMode_openBlank.openBlankWithCopyAccessCode(
ruleKey
),
default_value,
void 0,
"当点击动作是【新标签页打开】时且存在访问码,那就会复制访问码到剪贴板"
)
);
settingConfig.linkClickMode_openBlank.openBlankWithCopyAccessCode = NetDiskRuleData.linkClickMode_openBlank.openBlankWithCopyAccessCode(
ruleKey
);
}
if (linkClickMode_openBlank_form.length) {
formConfigList.push({
text: "点击动作-新标签页打开",
type: "forms",
forms: linkClickMode_openBlank_form
});
}
}
if (settingConfig.schemeUri) {
const schemeUri_form = [];
if ("enable" in settingConfig.schemeUri) {
const default_value = typeof settingConfig.schemeUri.enable === "boolean" ? settingConfig.schemeUri.enable : false;
schemeUri_form.push(
UISwitch(
"启用",
NetDiskRuleDataKEY.schemeUri.enable(ruleKey),
default_value,
void 0,
"开启后可进行scheme uri转发"
)
);
settingConfig.schemeUri.enable = NetDiskRuleData.schemeUri.enable(ruleKey);
}
if ("isForwardBlankLink" in settingConfig.schemeUri) {
const default_value = typeof settingConfig.schemeUri.isForwardBlankLink === "boolean" ? settingConfig.schemeUri.isForwardBlankLink : false;
schemeUri_form.push(
UISwitch(
"转发新标签页链接",
NetDiskRuleDataKEY.schemeUri.isForwardBlankLink(ruleKey),
default_value,
void 0,
"对新标签页打开的链接进行scheme转换"
)
);
settingConfig.schemeUri.isForwardBlankLink = NetDiskRuleData.schemeUri.isForwardBlankLink(ruleKey);
}
if ("isForwardLinearChain" in settingConfig.schemeUri) {
const default_value = typeof settingConfig.schemeUri.isForwardLinearChain === "boolean" ? settingConfig.schemeUri.isForwardLinearChain : false;
schemeUri_form.push(
UISwitch(
"转发直链",
NetDiskRuleDataKEY.schemeUri.isForwardLinearChain(ruleKey),
default_value,
void 0,
"对解析的直链进行scheme转换"
)
);
settingConfig.schemeUri.isForwardLinearChain = NetDiskRuleData.schemeUri.isForwardLinearChain(ruleKey);
}
if ("uri" in settingConfig.schemeUri) {
const default_value = typeof settingConfig.schemeUri.uri === "string" ? settingConfig.schemeUri.uri : "";
schemeUri_form.push(
UIInput(
"Uri链接",
NetDiskRuleDataKEY.schemeUri.uri(ruleKey),
default_value,
"自定义的Scheme的Uri链接",
void 0,
"jumpwsv://go?package=xx&activity=xx&intentAction=xx&intentData=xx&intentExtra=xx"
)
);
settingConfig.schemeUri.uri = NetDiskRuleData.schemeUri.uri(ruleKey);
}
if (schemeUri_form.length) {
formConfigList.push({
text: "Scheme Uri转发",
type: "forms",
isFold: true,
forms: schemeUri_form
});
}
}
if (settingConfig.matchRange_text) {
let matchRange_text_form = [];
if ("before" in settingConfig.matchRange_text) {
const default_value = typeof settingConfig.matchRange_text.before === "number" ? settingConfig.matchRange_text.before : 0;
matchRange_text_form.push(
UISlider(
"间隔前",
NetDiskRuleDataKEY.matchRange_text.before(ruleKey),
default_value,
0,
100,
void 0,
void 0,
"提取码间隔前的字符长度"
)
);
settingConfig.matchRange_text.before = NetDiskRuleData.matchRange_text.before(ruleKey);
}
if ("after" in settingConfig.matchRange_text) {
const default_value = typeof settingConfig.matchRange_text.after === "number" ? settingConfig.matchRange_text.after : 0;
matchRange_text_form.push(
UISlider(
"间隔后",
NetDiskRuleDataKEY.matchRange_text.after(ruleKey),
default_value,
0,
100,
void 0,
void 0,
"提取码间隔后的字符长度"
)
);
settingConfig.matchRange_text.after = NetDiskRuleData.matchRange_text.after(ruleKey);
}
if (matchRange_text_form.length) {
formConfigList.push({
text: "提取码文本匹配Text",
type: "forms",
forms: matchRange_text_form
});
}
}
if (settingConfig.matchRange_html) {
let matchRange_html_form = [];
if ("before" in settingConfig.matchRange_html) {
const default_value = typeof settingConfig.matchRange_html.before === "number" ? settingConfig.matchRange_html.before : 0;
matchRange_html_form.push(
UISlider(
"间隔前",
NetDiskRuleDataKEY.matchRange_html.before(ruleKey),
default_value,
0,
100,
void 0,
void 0,
"提取码间隔前的字符长度"
)
);
settingConfig.matchRange_html.before = NetDiskRuleData.matchRange_html.before(ruleKey);
}
if ("after" in settingConfig.matchRange_html) {
const default_value = typeof settingConfig.matchRange_html.after === "number" ? settingConfig.matchRange_html.after : 0;
matchRange_html_form.push(
UISlider(
"间隔后",
NetDiskRuleDataKEY.matchRange_html.after(ruleKey),
default_value,
0,
100,
void 0,
void 0,
"提取码间隔后的字符长度"
)
);
settingConfig.matchRange_html.after = NetDiskRuleData.matchRange_html.after(ruleKey);
}
if (matchRange_html_form.length) {
formConfigList.push({
text: "提取码文本匹配HTML",
type: "forms",
forms: matchRange_html_form
});
}
}
if (settingConfig.ownFormList) {
formConfigList.push(...settingConfig.ownFormList);
}
return formConfigList;
},
/**
* 获取规则界面配置的内容
*/
getRulePanelContent() {
return this.$data.ruleContent;
}
};
const NetDiskDebug = {
/**
* 对传入的url进行处理,返回shareCode
* @param {string} matchText 正在进行匹配的文本
* @param {NetDiskMatchRuleOption} regular 当前执行的规则
* @param {(logData: NetDiskDebugLogData)=>void} logCallBack 日志回调
*/
handleShareCode(matchText, regular, logCallBack) {
var _a2;
let shareCodeMatch = (_a2 = matchText.match(regular.shareCode)) == null ? void 0 : _a2.filter((item) => utils.isNotNull(item));
logCallBack({
status: true,
msg: [
`正则: shareCode`,
"作用: 获取shareCode",
"结果: ",
JSON.stringify(shareCodeMatch)
]
});
if (utils.isNull(shareCodeMatch)) {
logCallBack({
status: false,
msg: `匹配shareCode为空`
});
return;
}
let shareCode = shareCodeMatch[0];
logCallBack({
status: true,
msg: [`取第一个值: ` + shareCode]
});
if (regular.shareCodeNeedRemoveStr) {
shareCode = shareCode.replace(regular.shareCodeNeedRemoveStr, "");
logCallBack({
status: true,
msg: [
`正则: shareCodeNeedRemoveStr`,
"作用: 删除ShareCode前面不需要的字符串",
`结果: ${shareCode}`
]
});
}
let shareCodeNotMatch = regular.shareCodeNotMatch;
if (shareCodeNotMatch != void 0 && shareCode.match(shareCodeNotMatch)) {
log.error(`不可能的shareCode => ${shareCode}`);
logCallBack({
status: false,
msg: [
`正则: shareCodeNotMatch`,
"作用: 用于判断提取到的shareCode是否是错误的shareCode",
`结果: true 该shareCode不是正确的`
]
});
return;
}
for (const shareCodeNotMatchRegexp of NetDisk.$extraRule.shareCodeNotMatchRegexpList) {
if (shareCode.match(shareCodeNotMatchRegexp)) {
log.error(`不可能的shareCode => ${shareCode}`);
logCallBack({
status: false,
msg: [
`正则: 内置的shareCodeNotMatchRegexpList`,
"作用: 使用该正则判断提取到的shareCode是否正确",
`结果: true 该shareCode不是正确的`
]
});
return;
}
}
shareCode = decodeURI(shareCode);
logCallBack({
status: true,
msg: ["对shareCode进行解码: " + shareCode]
});
if (NetDiskGlobalData.shareCode.excludeIdenticalSharedCodes.value && utils.isSameChars(
shareCode,
NetDiskGlobalData.shareCode.excludeIdenticalSharedCodesCoefficient.value
)) {
logCallBack({
status: false,
msg: ["已开启【排除分享码】且该分享码命中该规则"]
});
return;
}
if (shareCode.endsWith("http") || shareCode.endsWith("https")) {
logCallBack({
status: false,
msg: ["该分享码以http|https结尾"]
});
return;
}
logCallBack({
status: true,
msg: "处理完毕的shareCode: " + shareCode
});
return shareCode;
},
/**
* 对传入的url进行处理,返回accessCode
* @param {string} matchText 正在进行匹配的文本
* @param {NetDiskMatchRuleOption} regular 当前执行的规则
* @param {(logData: NetDiskDebugLogData)=>void} logCallBack 日志回调
*/
handleAccessCode(matchText, regular, logCallBack) {
var _a2;
let accessCode = "";
if (!regular.checkAccessCode) {
logCallBack({
status: true,
msg: "因未配置规则checkAccessCode,默认accessCode的值为空"
});
return "";
}
let accessCodeMatch = matchText.match(regular.checkAccessCode);
logCallBack({
status: true,
msg: [
`正则: checkAccessCode`,
"作用: 用来判断link_innerText或者link_innerHTML匹配到的字符串中是否存在密码",
`结果: `,
JSON.stringify(accessCodeMatch)
]
});
if (accessCodeMatch) {
let accessCodeMatchValue = accessCodeMatch[accessCodeMatch.length - 1];
logCallBack({
status: true,
msg: "取最后一个值: " + accessCodeMatchValue
});
let accessCodeMatchArray = (_a2 = accessCodeMatchValue.match(regular.accessCode)) == null ? void 0 : _a2.filter((item) => utils.isNotNull(item));
logCallBack({
status: true,
msg: [
`正则: accessCode`,
"作用: 用来提取link_innerText或者link_innerHTML匹配到的字符串中的密码",
`结果: `,
JSON.stringify(accessCodeMatchArray)
]
});
if (utils.isNull(accessCodeMatchArray)) {
logCallBack({
status: true,
msg: "因↑匹配到的结果为空,默认accessCode的值为空"
});
return "";
}
if (accessCodeMatchArray.length) {
accessCode = accessCodeMatchArray[0];
logCallBack({
status: true,
msg: "取第一个值: " + accessCode
});
if (accessCode.startsWith("http")) {
logCallBack({
status: true,
msg: "排除不可能的accessCode,重置accessCode的值为空"
});
accessCode = "";
}
}
}
if (utils.isNotNull(accessCode)) {
for (const accessCodeNotMatchRegexp of NetDisk.$extraRule.accessCodeNotMatchRegexpList) {
if (accessCode.match(accessCodeNotMatchRegexp)) {
accessCode = "";
logCallBack({
status: true,
msg: [
`正则: 内置的accessCodeNotMatchRegexpList`,
"作用: 使用该正则判断提取到的accessCode是否正确",
`结果: true 重置accessCode为空`
]
});
break;
}
}
if (regular.acceesCodeNotMatch && accessCode.match(regular.acceesCodeNotMatch)) {
accessCode = "";
logCallBack({
status: true,
msg: [
`正则: acceesCodeNotMatch`,
"作用: 用于判断提取到的accessCode是否是错误的accessCode",
`结果: true 重置accessCode为空`
]
});
}
}
logCallBack({
status: true,
msg: "处理完毕的accessCode: " + accessCode
});
return accessCode;
},
/**
* 获取在弹窗中显示出的链接
* @param {string} matchText 匹配到的文本
* @param {NetDiskMatchRuleOption} regular 当前执行的规则
* @param {string} shareCode 分享码
* @param {string} accessCode 访问码
* @param {(logData: NetDiskDebugLogData)=>void} logCallBack 日志回调
*/
handleLinkShow(matchText, regular, shareCode, accessCode, logCallBack) {
let uiLink = NetDiskRuleUtils.replaceParam(regular["uiLinkShow"], {
shareCode
});
logCallBack({
status: true,
msg: [
`正则: uiLinkShow`,
"作用: 用于显示在弹窗中的字符串",
"备注: 对shareCode进行参数替换",
`结果: ${uiLink}`
]
});
if (accessCode && accessCode != "") {
uiLink = NetDiskRuleUtils.replaceParam(uiLink, {
accessCode
});
logCallBack({
status: true,
msg: [
`正则: uiLinkShow`,
"作用: 用于显示在弹窗中的字符串",
"备注: 对accessCode进行参数替换",
`结果: ${uiLink}`
]
});
} else {
uiLink = NetDiskHandlerUtil.replaceText(
uiLink,
NetDisk.$extraRule.noAccessCodeRegExp,
""
);
logCallBack({
status: true,
msg: [
`正则: 内置的noAccessCodeRegExp`,
"作用: 因accessCode为空,使用该正则去除不需要的字符串",
`结果: ${uiLink}`
]
});
}
if (regular.paramMatch) {
if (utils.isNotNull(matchText)) {
let paramMatchArray = matchText.match(regular.paramMatch);
let replaceParamData = {};
if (paramMatchArray) {
for (let index = 0; index < paramMatchArray.length; index++) {
replaceParamData[`$${index}`] = paramMatchArray[index];
}
}
uiLink = NetDiskRuleUtils.replaceParam(uiLink, replaceParamData);
logCallBack({
status: true,
msg: [
`正则: paramMatch`,
`作用: 用于对matchText进行提取需要的关键内容,替换关键字:{#$1#}、{#$2#}...`,
`参数: ` + JSON.stringify(replaceParamData, void 0, 4),
`结果: ${uiLink}`
]
});
}
}
logCallBack({
status: true,
msg: "处理完毕的uiLink: " + uiLink
});
return uiLink;
},
/**
* 获取新标签页打开的URL
* @param {string} matchText 匹配到的文本
* @param {NetDiskMatchRuleOption} regular 当前执行的规则
* @param {string} shareCode 分享码
* @param {string} accessCode 访问码
* @param {(logData: NetDiskDebugLogData)=>void} logCallBack 日志回调
*/
handleBlank(matchText, regular, shareCode, accessCode, logCallBack) {
let blankUrl = NetDiskRuleUtils.replaceParam(regular["blank"], {
shareCode
});
logCallBack({
status: true,
msg: [
`正则: blank`,
"作用: 用于点击跳转的链接",
"备注: 对shareCode进行参数替换",
`结果: ${blankUrl}`
]
});
if (accessCode && accessCode != "") {
blankUrl = NetDiskRuleUtils.replaceParam(blankUrl, {
accessCode
});
logCallBack({
status: true,
msg: [
`正则: blank`,
"作用: 用于点击跳转的链接",
"备注: 对accessCode进行参数替换",
`结果: ${blankUrl}`
]
});
} else {
blankUrl = NetDiskHandlerUtil.replaceText(
blankUrl,
NetDisk.$extraRule.noAccessCodeRegExp,
""
);
logCallBack({
status: true,
msg: [
`正则: 内置的noAccessCodeRegExp`,
"作用: 因accessCode为空,使用该正则去除不需要的字符串",
`结果: ${blankUrl}`
]
});
}
if (regular.paramMatch) {
if (utils.isNotNull(matchText)) {
let paramMatchArray = matchText.match(regular.paramMatch);
let replaceParamData = {};
if (paramMatchArray) {
for (let index = 0; index < paramMatchArray.length; index++) {
replaceParamData[`$${index}`] = paramMatchArray[index];
}
}
blankUrl = NetDiskRuleUtils.replaceParam(blankUrl, replaceParamData);
logCallBack({
status: true,
msg: [
`正则: paramMatch`,
`作用: 用于对matchText进行提取需要的关键内容,替换关键字:{#$1#}、{#$2#}...`,
`参数: ` + JSON.stringify(replaceParamData, void 0, 4),
`结果: ${blankUrl}`
]
});
}
}
logCallBack({
status: true,
msg: "处理完毕的blank: " + blankUrl
});
return blankUrl;
},
/**
* 获取复制到剪贴板的字符串
* @param {string} matchText 匹配到的文本
* @param {NetDiskMatchRuleOption} regular 当前执行的规则
* @param {string} shareCode 分享码
* @param {string} accessCode 访问码
* @param {(logData: NetDiskDebugLogData)=>void} logCallBack 日志回调
*/
handleCopyUrl(matchText, regular, shareCode, accessCode, logCallBack) {
let copyUrl = NetDiskRuleUtils.replaceParam(regular["copyUrl"], {
shareCode
});
logCallBack({
status: true,
msg: [
`正则: copyUrl`,
"作用: 用于复制到剪贴板的链接",
"备注: 对shareCode进行参数替换",
`结果: ${copyUrl}`
]
});
if (accessCode && accessCode != "") {
copyUrl = NetDiskRuleUtils.replaceParam(copyUrl, {
accessCode
});
logCallBack({
status: true,
msg: [
`正则: copyUrl`,
"作用: 用于复制到剪贴板的链接",
"备注: 对accessCode进行参数替换",
`结果: ${copyUrl}`
]
});
} else {
copyUrl = NetDiskHandlerUtil.replaceText(
copyUrl,
NetDisk.$extraRule.noAccessCodeRegExp,
""
);
logCallBack({
status: true,
msg: [
`正则: 内置的noAccessCodeRegExp`,
"作用: 因accessCode为空,使用该正则去除不需要的字符串",
`结果: ${copyUrl}`
]
});
}
if (regular.paramMatch) {
if (utils.isNotNull(matchText)) {
let paramMatchArray = matchText.match(regular.paramMatch);
let replaceParamData = {};
if (paramMatchArray) {
for (let index = 0; index < paramMatchArray.length; index++) {
replaceParamData[`$${index}`] = paramMatchArray[index];
}
}
copyUrl = NetDiskRuleUtils.replaceParam(copyUrl, replaceParamData);
logCallBack({
status: true,
msg: [
`正则: paramMatch`,
`作用: 用于对matchText进行提取需要的关键内容,替换关键字:{#$1#}、{#$2#}...`,
`参数: ` + JSON.stringify(replaceParamData, void 0, 4),
`结果: ${copyUrl}`
]
});
}
}
logCallBack({
status: true,
msg: "处理完毕的copyUrl: " + copyUrl
});
return copyUrl;
}
};
const NetDiskWorkerUtils = {
/**
* 检索目标元素内所有可访问的ShadowRoot的所有节点的信息
*/
depthQueryShadowRootAllNode($target) {
let result = [];
function queryShadowRoot($ele) {
let $queryChildNodeList = Array.from($ele.querySelectorAll("*"));
$queryChildNodeList.forEach(($childNode) => {
if ($childNode.classList && $childNode.classList.contains("pops-shadow-container")) {
return;
}
let $childNodeShadowRoot = $childNode.shadowRoot;
if ($childNodeShadowRoot && $childNodeShadowRoot instanceof ShadowRoot) {
result.push({
shadowRoot: $childNodeShadowRoot,
childNode: queryShadowRoot($childNodeShadowRoot)
});
}
});
return $queryChildNodeList;
}
queryShadowRoot($target);
return result;
},
/**
* 删除某些需要忽略的text或html,如:设置、直链弹窗
* @param text 需要进行处理的字符串
* @param isHTML 是否是html属性
*/
ignoreStrRemove(text, isHTML = false) {
let ignoreNodeList = [];
if (ignoreNodeList.length) {
ignoreNodeList.forEach(($ignore) => {
if ($ignore == void 0) {
return;
}
if (isHTML) {
if ($ignore.innerHTML != void 0) {
text = text.replaceAll($ignore.innerHTML, "");
}
} else {
let text2 = $ignore.innerText || $ignore.textContent;
if (text2 != void 0) {
text2 = text2.replaceAll(text2, "");
}
}
});
}
return text;
},
/**
* 获取页面上所有文本
* @param target 目标元素
* @param isCheckShadowRoot 是否检索ShadowRoot
*/
getPageText(target = document.documentElement, isCheckShadowRoot) {
let strList = [];
strList.push((target == null ? void 0 : target.textContent) || (target == null ? void 0 : target.innerText) || "");
if (isCheckShadowRoot) {
let queryShadowRootAllNodeInfo = this.depthQueryShadowRootAllNode(target);
if (queryShadowRootAllNodeInfo.length) {
queryShadowRootAllNodeInfo.forEach((queryShadowRootInfo) => {
let shadowRootText = queryShadowRootInfo.shadowRoot.textContent;
if (shadowRootText) {
strList.push(shadowRootText);
}
});
}
}
strList = strList.filter((item) => item !== "");
return strList;
},
/**
* 获取页面上所有超文本
* @param target 目标元素
* @param isCheckShadowRoot 是否检索ShadowRoot
*/
getPageHTML(target = document.documentElement, isCheckShadowRoot) {
let strList = [];
strList.push(target.innerHTML);
if (isCheckShadowRoot) {
let queryShadowRootAllNodeInfo = this.depthQueryShadowRootAllNode(target);
if (queryShadowRootAllNodeInfo.length) {
queryShadowRootAllNodeInfo.forEach((queryShadowRootInfo) => {
let shadowRootHTML = queryShadowRootInfo.shadowRoot.innerHTML;
if (shadowRootHTML) {
strList.push(shadowRootHTML);
}
});
}
}
strList = strList.filter((item) => item !== "");
return strList;
},
/**
* 获取页面上所有input的值
* @param target 目标元素
* @param isCheckShadowRoot 是否检索ShadowRoot
*/
getInputElementValue(target = document.documentElement, isCheckShadowRoot) {
let result = [];
Array.from(target.querySelectorAll("input")).forEach(($input) => {
result.push($input.value);
});
if (isCheckShadowRoot) {
let queryShadowRootAllNodeInfo = this.depthQueryShadowRootAllNode(target);
if (queryShadowRootAllNodeInfo.length) {
queryShadowRootAllNodeInfo.forEach((queryShadowRootInfo) => {
for (let index = 0; index < queryShadowRootInfo.childNode.length; index++) {
const $childNode = queryShadowRootInfo.childNode[index];
if ($childNode instanceof HTMLInputElement && $childNode.value) {
result.push($childNode.value);
}
}
});
}
}
return result;
},
/**
* 获取页面上所有textarea的值
* @param target 目标元素
* @param isCheckShadowRoot 是否检索ShadowRoot
*/
getTextAreaElementValue(target = document.documentElement, isCheckShadowRoot) {
let result = [];
Array.from(target.querySelectorAll("textarea")).forEach(($textarea) => {
result.push($textarea.value);
});
if (isCheckShadowRoot) {
let queryShadowRootAllNodeInfo = this.depthQueryShadowRootAllNode(target);
if (queryShadowRootAllNodeInfo.length) {
queryShadowRootAllNodeInfo.forEach((queryShadowRootInfo) => {
for (let index = 0; index < queryShadowRootInfo.childNode.length; index++) {
const $childNode = queryShadowRootInfo.childNode[index];
if ($childNode instanceof HTMLTextAreaElement && $childNode.value) {
result.push($childNode.value);
}
}
});
}
}
return result;
}
};
const indexCSS$3 = '.whitesevPopNetDiskHistoryMatch .pops-confirm-content ul {\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content li {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n border-radius: 10px;\r\n box-shadow: 0 0.3px 0.6px rgb(0 0 0 / 6%), 0 0.7px 1.3px rgb(0 0 0 / 8%),\r\n 0 1.3px 2.5px rgb(0 0 0 / 10%), 0 2.2px 4.5px rgb(0 0 0 / 12%),\r\n 0 4.2px 8.4px rgb(0 0 0 / 14%), 0 10px 20px rgb(0 0 0 / 20%);\r\n margin: 20px 10px;\r\n padding: 10px;\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-search {\r\n height: 11%;\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-table {\r\n height: calc(85% - 40px);\r\n overflow: auto;\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-page {\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n margin-top: 10px;\r\n}\r\n.whitesevPopNetDiskHistoryMatch\r\n .pops-confirm-content\r\n .netdiskrecord-search\r\n input {\r\n border: none;\r\n border-bottom: 1px solid #000000;\r\n padding: 0px 5px;\r\n line-height: normal;\r\n width: -moz-available;\r\n width: -webkit-fill-available;\r\n width: fill-available;\r\n margin: 5px 5px 0px 5px;\r\n background: none;\r\n}\r\n.whitesevPopNetDiskHistoryMatch\r\n .pops-confirm-content\r\n .netdiskrecord-search\r\n input:focus-visible {\r\n outline: none;\r\n border-bottom: 1px solid #0009ff;\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-link {\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-link a {\r\n color: #ff4848;\r\n font-size: 0.8em;\r\n border: none;\r\n word-break: break-word;\r\n}\r\n.whitesevPopNetDiskHistoryMatch\r\n .pops-confirm-content\r\n .netdiskrecord-link\r\n a[isvisited="true"] {\r\n color: #8b8888;\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-icon {\r\n}\r\n.whitesevPopNetDiskHistoryMatch\r\n .pops-confirm-content\r\n .netdiskrecord-icon\r\n .netdisk-icon-img {\r\n width: 28px;\r\n height: 28px;\r\n min-width: 28px;\r\n min-height: 28px;\r\n font-size: 0.8em;\r\n border-radius: 10px;\r\n box-shadow: 0 0.3px 0.6px rgb(0 0 0 / 6%), 0 0.7px 1.3px rgb(0 0 0 / 8%),\r\n 0 1.3px 2.5px rgb(0 0 0 / 10%), 0 2.2px 4.5px rgb(0 0 0 / 12%),\r\n 0 4.2px 8.4px rgb(0 0 0 / 14%), 0 10px 20px rgb(0 0 0 / 20%);\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-url {\r\n color: #000;\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-top-url {\r\n color: #000;\r\n}\r\n.whitesevPopNetDiskHistoryMatch\r\n .pops-confirm-content\r\n .netdiskrecord-functions\r\n button.btn-delete {\r\n background: #263cf3;\r\n color: #fff;\r\n}\r\n.whitesevPopNetDiskHistoryMatch\r\n .pops-confirm-content\r\n .netdiskrecord-functions\r\n button.btn-delete:active {\r\n background: #6e7be8;\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-link,\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-icon,\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-url,\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-top-url,\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-add-time,\r\n.whitesevPopNetDiskHistoryMatch\r\n .pops-confirm-content\r\n .netdiskrecord-update-time,\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-url-title,\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-functions {\r\n display: flex;\r\n margin: 5px 0px;\r\n}\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-link p,\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-icon p,\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-url p,\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-top-url p,\r\n.whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-add-time p,\r\n.whitesevPopNetDiskHistoryMatch\r\n .pops-confirm-content\r\n .netdiskrecord-update-time\r\n p,\r\n.whitesevPopNetDiskHistoryMatch\r\n .pops-confirm-content\r\n .netdiskrecord-url-title\r\n p,\r\n.whitesevPopNetDiskHistoryMatch\r\n .pops-confirm-content\r\n .netdiskrecord-functions\r\n p {\r\n min-width: 80px;\r\n max-width: 80px;\r\n align-self: center;\r\n}\r\n';
const NetDiskHistoryMatchView = {
/**
* 本地存储的keyName
*/
storageKey: "netDiskHistoryMatch",
/**
* 是否已设置其它DOM事件
*/
isSetOtherEvent: false,
/**
* 分页
*/
dataPaging: void 0,
/**
* 显示弹窗
*/
show() {
let data = this.getStorageData();
let dataHTML = "";
let that = this;
data = this.orderNetDiskHistoryMatchData(data);
for (let index = 0; index < 10; index++) {
if (data[index]) {
dataHTML += that.getTableHTML(data[index]).html;
}
}
dataHTML = /*html*/
`
`;
NetDiskUI.Alias.historyAlias = NetDiskPops.confirm(
{
title: {
text: "历史匹配记录",
position: "center"
},
content: {
text: dataHTML,
html: true
},
btn: {
reverse: true,
position: "space-between",
ok: {
enable: true,
callback(event) {
event.close();
NetDiskUI.Alias.historyAlias = void 0;
}
},
close: {
callback(event) {
event.close();
NetDiskUI.Alias.historyAlias = void 0;
}
},
cancel: {
enable: false
},
other: {
enable: true,
text: `清空所有(${data.length})`,
type: "xiaomi-primary",
callback: (event) => {
NetDiskPops.confirm({
title: {
text: "删除",
position: "center"
},
content: {
text: "确定清空所有的记录?",
html: false
},
btn: {
ok: {
enable: true,
callback(okEvent) {
that.clearStorageData();
domUtils.remove(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelectorAll(
".whitesevPopNetDiskHistoryMatch .pops-confirm-content ul li"
)
);
okEvent.close();
domUtils.html(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-page"
),
""
);
domUtils.text(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch .pops-confirm-btn-other"
),
domUtils.text(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch .pops-confirm-btn-other"
)
).replace(/[\d]+/gi, "0")
);
}
},
cancel: {
text: "取消",
enable: true
}
}
});
}
}
},
mask: {
clickCallBack(originalRun) {
originalRun();
NetDiskUI.Alias.historyAlias = null;
}
},
class: "whitesevPopNetDiskHistoryMatch",
style: indexCSS$3
},
NetDiskUI.popsStyle.historyMatchView
);
this.setDataPaging(data);
this.setEvent(NetDiskUI.Alias.historyAlias.$shadowRoot);
this.setSearchEvent();
NetDiskUI.setRightClickMenu(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch"
),
".netdiskrecord-link a",
true
);
},
/**
* 获取CSS
*/
getCSS() {
},
/**
* 获取显示出的每一项的html
* @param data
*/
getTableHTML(data) {
let netDiskURL = NetDisk.handleLinkShow(
data.netDiskName,
data.netDiskIndex,
data.shareCode,
data.accessCode,
data.matchText
);
let $liItemContainer = domUtils.createElement("li", {
innerHTML: (
/*html*/
`
记录时间
${utils.formatTime(data.addTime)}
更新时间
${utils.formatTime(data.updateTime)}
`
)
});
let $link = $liItemContainer.querySelector(
".netdiskrecord-link"
);
let $linkAnchor = $link.querySelector("a");
let $icon = $liItemContainer.querySelector(
".netdiskrecord-icon"
);
let $iconImg = $liItemContainer.querySelector(".netdisk-icon-img");
let $url = $liItemContainer.querySelector(".netdiskrecord-url");
let $urlTitle = $liItemContainer.querySelector(
".netdiskrecord-url-title"
);
let $addTime = $liItemContainer.querySelector(
".netdiskrecord-add-time"
);
let $updateTime = $liItemContainer.querySelector(
".netdiskrecord-update-time"
);
let $features = $liItemContainer.querySelector(
".netdiskrecord-functions"
);
let $featuresBtnDelete = $features.querySelector(".btn-delete");
NetDiskView.handleElementAttributeRuleInfo(
{
netDisk: data.netDiskName,
netDiskIndex: data.netDiskIndex,
shareCode: data.shareCode,
accessCode: data.accessCode
},
$linkAnchor
);
$iconImg.style.cssText = `background: url(${NetDiskUI.src.icon[data.netDiskName]}) no-repeat;background-size:100%`;
if (data.url !== data.topURL) {
let $topUrl = domUtils.createElement("div", {
className: "netdiskrecord-top-url",
innerHTML: (
/*html*/
`
Top网址
${data.topURL}
`
)
});
domUtils.after($url, $topUrl);
}
$featuresBtnDelete.setAttribute("data-json", JSON.stringify(data));
Reflect.set($featuresBtnDelete, "data-json", data);
return {
$liItemContainer,
$link,
$linkAnchor,
$icon,
$iconImg,
$url,
$urlTitle,
$addTime,
$updateTime,
$features,
$featuresBtnDelete,
html: $liItemContainer.outerHTML
};
},
/**
* 设置只执行一次的事件
* @param target
*/
setEvent(target) {
let that = this;
NetDiskUI.view.setNetDiskUrlClickEvent(
target,
".whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-link a"
);
domUtils.on(
target,
"click",
".whitesevPopNetDiskHistoryMatch .pops-confirm-content .netdiskrecord-functions button.btn-delete",
function(event) {
var _a2;
let deleteLoading = NetDiskPops.loading({
parent: target.querySelector(
".whitesevPopNetDiskHistoryMatch .pops-confirm-content ul"
),
content: {
text: "删除中..."
},
only: true,
addIndexCSS: false
});
let clickNode = event.target;
let dataJSON = clickNode.getAttribute("data-json");
(_a2 = clickNode.closest("li")) == null ? void 0 : _a2.remove();
that.deleteStorageData(dataJSON);
deleteLoading == null ? void 0 : deleteLoading.close();
let totalNumberText = domUtils.text(
target.querySelector(
".whitesevPopNetDiskHistoryMatch .pops-confirm-btn-other"
)
);
let totalNumberMatch = totalNumberText.match(/[\d]+/gi);
let totalNumber = parseInt(
totalNumberMatch[totalNumberMatch.length - 1]
);
totalNumber--;
totalNumberText = totalNumberText.replace(
/[\d]+/gi,
totalNumber.toString()
);
domUtils.text(
target.querySelector(
".whitesevPopNetDiskHistoryMatch .pops-confirm-btn-other"
),
totalNumberText
);
let data = that.getStorageData();
data = that.orderNetDiskHistoryMatchData(data);
that.dataPaging.refresh(data);
that.pageChangeCallBack(data, that.dataPaging.CONFIG.currentPage);
}
);
},
/**
* 页码改变的回调
* @param data
* @param page
*/
pageChangeCallBack(data, page) {
let startIndex = (page - 1) * 10;
let dataHTML = "";
for (let index = 0; index < 10; index++) {
if (data[startIndex]) {
dataHTML += this.getTableHTML(data[startIndex]).html;
} else {
break;
}
startIndex++;
}
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelectorAll(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-table ul li"
).forEach((ele) => ele.remove());
domUtils.append(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-table ul"
),
dataHTML
);
},
/**
* 设置分页
* @param data
*/
setDataPaging(data) {
let that = this;
let dataPaging = new __DataPaging({
data,
pageCount: 10,
pageStep: __pops.isPhone() ? 2 : 4,
currentPage: 1,
pageChangeCallBack: function(page) {
that.pageChangeCallBack(data, page);
}
});
this.dataPaging = dataPaging;
dataPaging.addCSS(NetDiskUI.Alias.historyAlias.$shadowRoot);
dataPaging.append(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-page"
)
);
},
/**
* 设置搜索框的回车事件
*/
setSearchEvent() {
let isSeaching = false;
let searchLoading = void 0;
let that = this;
function searchEvent() {
if (isSeaching) {
return;
}
isSeaching = true;
searchLoading = NetDiskPops.loading({
parent: NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch .pops-confirm-content ul"
),
content: {
text: "搜索中..."
},
only: true,
addIndexCSS: false
});
let inputText = NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-search input"
).value.trim();
let data = that.getStorageData();
data = that.orderNetDiskHistoryMatchData(data);
if (inputText === "") {
let historyDataHTML = "";
data.forEach((item, index) => {
if (index > 9) {
return;
}
historyDataHTML += that.getTableHTML(item).html;
});
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelectorAll(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-table ul li"
).forEach((ele) => ele.remove());
domUtils.append(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-table ul"
),
historyDataHTML
);
searchLoading == null ? void 0 : searchLoading.close();
isSeaching = false;
that.setDataPaging(data);
return;
}
let isFindHTML = "";
data.forEach((item) => {
let netDiskURL = NetDisk.handleLinkShow(
item.netDiskName,
item.netDiskIndex,
item.shareCode,
item.accessCode,
item.matchText
);
if (netDiskURL.match(new RegExp(inputText, "ig")) || item.url.match(new RegExp(inputText, "ig")) || item.topURL.match(new RegExp(inputText, "ig")) || item.title.match(new RegExp(inputText, "ig"))) {
isFindHTML += that.getTableHTML(item).html;
}
});
domUtils.remove(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelectorAll(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-table ul li"
)
);
domUtils.append(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-table ul"
),
isFindHTML
);
domUtils.remove(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelectorAll(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-page > *"
)
);
searchLoading == null ? void 0 : searchLoading.close();
searchLoading = void 0;
isSeaching = false;
}
domUtils.listenKeyboard(
NetDiskUI.Alias.historyAlias.$shadowRoot.querySelector(
".whitesevPopNetDiskHistoryMatch .netdiskrecord-search input"
),
"keypress",
(keyName) => {
if (keyName === "Enter") {
searchEvent();
}
}
);
},
/**
* 排序数据
* @param data
*/
orderNetDiskHistoryMatchData(data) {
let localOrder = NetDiskGlobalData.historyMatch["netdisk-history-match-ordering-rule"].value;
let isDesc = localOrder.indexOf("降序") !== -1 ? true : false;
let orderField = localOrder.indexOf("记录时间") !== -1 ? "addTime" : "updateTime";
utils.sortListByProperty(
data,
(item) => {
return item[orderField];
},
isDesc
);
return data;
},
/**
* 查询访问码
* @param netDiskName
* @param shareCode
* @param isNotNull 查询的访问码是否不为空
* + true 不能是空的
* + false 允许为空
*/
queryAccessCode(netDiskName, shareCode, isNotNull) {
let storageDataList = this.getStorageData();
for (let index = 0; index < storageDataList.length; index++) {
const localData = storageDataList[index];
if (localData.netDiskName === netDiskName && localData.shareCode === shareCode) {
if (isNotNull && utils.isNotNull(localData.accessCode)) {
return localData.accessCode;
}
return localData.accessCode;
}
}
},
/**
* 同步访问码
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 新的访问码
*/
syncAccessCode(netDiskName, netDiskIndex, shareCode, accessCode) {
if (NetDiskGlobalData.historyMatch.saveMatchNetDisk.value) {
let flag = NetDiskHistoryMatchView.changeMatchedDataAccessCode(
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
if (flag) {
log.success("已成功同步访问码至历史匹配记录");
return true;
} else {
log.error("同步访问码至历史匹配记录失败");
}
}
return false;
},
/**
* 修改存储的数据的访问码
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 新的访问码
*/
changeMatchedDataAccessCode(netDiskName, netDiskIndex, shareCode, accessCode) {
let storageDataList = this.getStorageData();
let flag = false;
for (let index = 0; index < storageDataList.length; index++) {
const localData = storageDataList[index];
if (localData.netDiskName === netDiskName && String(localData.netDiskIndex) === String(netDiskIndex) && localData.shareCode === shareCode) {
flag = true;
storageDataList[index].accessCode = accessCode;
storageDataList[index].updateTime = Date.now();
}
}
if (flag) {
this.saveStorageData(storageDataList);
}
return flag;
},
/**
* 存储匹配到的链接
* @param netDiskName 网盘名称
* @param netDiskIndex 网盘名称索引下标
* @param shareCode 分享码
* @param accessCode 访问码
* @param matchText 匹配到的文本
*/
changeMatchedData(netDiskName, netDiskIndex, shareCode, accessCode, matchText) {
if (!NetDiskGlobalData.historyMatch.saveMatchNetDisk.value) {
return false;
}
let storageDataList = this.getStorageData();
let flag = false;
for (let index = 0; index < storageDataList.length; index++) {
const localData = storageDataList[index];
if (localData.netDiskName === netDiskName && shareCode.startsWith(localData.shareCode) && localData.netDiskIndex === netDiskIndex) {
if (NetDiskGlobalData.historyMatch["netdisk-history-match-merge-same-link"].value || localData.url === window.location.href && localData.topURL === top.window.location.href) {
flag = true;
let editFlag = false;
if (matchText.trim() !== "" && localData.matchText !== matchText) {
editFlag = true;
log.success("匹配历史记录 -> 设置新的matchText", [matchText]);
storageDataList[index].matchText = matchText;
}
if (utils.isNotNull(accessCode) && localData.accessCode !== accessCode) {
editFlag = true;
log.success("匹配历史记录 -> 修改accessCode");
storageDataList[index].accessCode = accessCode;
}
if (editFlag) {
storageDataList[index].updateTime = Date.now();
if (storageDataList[index].title) {
storageDataList[index].title = document.title;
}
if (NetDiskGlobalData.historyMatch["netdisk-history-match-merge-same-link"].value) {
storageDataList[index].url = window.location.href;
storageDataList[index].topURL = top.window.location.href;
}
break;
}
}
}
}
if (!flag) {
flag = true;
log.success("匹配历史记录 -> 增加新的");
let time = Date.now();
storageDataList = [
...storageDataList,
{
url: window.location.href,
topURL: top.window.location.href,
netDiskName,
netDiskIndex,
shareCode,
accessCode,
addTime: time,
updateTime: time,
title: document.title || top.document.title,
matchText
}
];
}
this.saveStorageData(storageDataList);
return true;
},
/**
* 检测并尝试修复本地的数据
*/
checkAndRepairLocalData() {
let repairCount = 0;
let data = _GM_getValue(this.storageKey);
if (Array.isArray(data)) {
for (let index = 0; index < data.length; index++) {
const itemData = data[index];
if (typeof itemData["matchText"] !== "string") {
itemData["matchText"] = "";
repairCount++;
}
}
} else {
data = [];
}
this.saveStorageData(data);
return {
count: data.length,
repairCount
};
},
/**
* 获取历史匹配到的链接
*/
getStorageData() {
let data = _GM_getValue(this.storageKey, []);
if (data == null) {
data = [];
this.saveStorageData(data);
}
return data;
},
/**
* 保存数据到本地存储的链接数据
*/
saveStorageData(data) {
_GM_setValue(this.storageKey, data);
},
/**
* 删除存储的某个项
* @param dataJSONText
*/
deleteStorageData(dataJSONText) {
let isSuccess = false;
let data = this.getStorageData();
for (let index = 0; index < data.length; index++) {
if (JSON.stringify(data[index]) === dataJSONText) {
log.success("删除 ===> ", data[index]);
data.splice(index, 1);
isSuccess = true;
break;
}
}
if (isSuccess) {
this.saveStorageData(data);
}
return isSuccess;
},
/**
* 清空所有配置
*/
clearStorageData() {
this.saveStorageData([]);
}
};
const NetDiskWorker = {
/** 是否正在匹配中 */
isHandleMatch: false,
/** 触发匹配,但是处于匹配中,计数器保存匹配数,等待完成匹配后再执行一次匹配 */
delayNotMatchCount: 0,
/** 主动触发监听DOM变化的事件 */
dispatchMonitorDOMChange: false,
/** worker的Blob链接 */
blobUrl: "",
/** worker对象 */
GM_matchWorker: void 0,
init() {
this.initWorkerBlobLink();
this.initWorker();
this.monitorDOMChange();
},
/** 初始化Worker的Blob链接 */
initWorkerBlobLink() {
const handleMatch = (
/*js*/
`
(() => {
function ${NetDiskWorker.handleRegularMatch.toString()}
function ${NetDiskWorker.uniqueArr}
this.addEventListener(
"message",
function (event) {
const data = event.data;
let matchedList = [];
${NetDiskWorker.handleRegularMatch.name}(data,(matchData)=>{
matchedList.push(matchData);
})
matchedList = ${NetDiskWorker.uniqueArr.name}(matchedList);
this.postMessage({
options: data,
msg: "Match End",
data: matchedList,
startTime: data.startTime,
endTime: Date.now(),
});
},
{
capture: true,
}
);
})();
`
);
let blob = new Blob([handleMatch]);
NetDiskWorker.blobUrl = window.URL.createObjectURL(blob);
log.info(`Worker Blob Link ===> ${NetDiskWorker.blobUrl}`);
},
/**
* 处理规则匹配
*
* 传入的规则肯定是允许执行匹配的规则
* @param workerOptionData 数据
* @param callback 成功匹配到的回调
*/
handleRegularMatch(workerOptionData, callback) {
const NetDiskRegularNameList = Object.keys(workerOptionData.regular);
const matchTextList = workerOptionData.textList.map((matchTextItem) => {
for (let index = 0; index < workerOptionData.characterMapping.length; index++) {
const characterMapping = workerOptionData.characterMapping[index];
try {
if (typeof characterMapping.searchValue === "string") {
matchTextItem = matchTextItem.replaceAll(
characterMapping.searchValue,
characterMapping.replaceValue
);
} else {
matchTextItem = matchTextItem.replace(
characterMapping.searchValue,
characterMapping.replaceValue
);
}
} catch (error) {
}
}
return matchTextItem;
});
for (const netDiskName of NetDiskRegularNameList) {
const netDiskRegular = workerOptionData.regular[netDiskName];
for (let index = 0; index < netDiskRegular.length; index++) {
const netDiskRegularItem = netDiskRegular[index];
let matchRegExpList = [];
if (workerOptionData.matchTextRange.includes("innerText")) {
matchRegExpList.push(
new RegExp(netDiskRegularItem["link_innerText"], "gi")
);
}
if (workerOptionData.matchTextRange.includes("innerHTML")) {
matchRegExpList.push(
new RegExp(netDiskRegularItem["link_innerHTML"], "gi")
);
}
if (!workerOptionData.matchTextRange.length) {
console.error(workerOptionData);
throw new TypeError("未设置匹配范围");
}
if (!matchRegExpList.length) {
throw new TypeError(
"未知的匹配范围: " + workerOptionData.matchTextRange
);
}
for (let matchRegExpIndex = 0; matchRegExpIndex < matchRegExpList.length; matchRegExpIndex++) {
const matchRegExp = matchRegExpList[matchRegExpIndex];
for (let textIndex = 0; textIndex < matchTextList.length; textIndex++) {
let text = matchTextList[textIndex];
let matchArray = text.match(matchRegExp);
if (matchArray && matchArray.length) {
callback({
netDiskName,
netDiskIndex: index,
data: matchArray
});
}
}
}
}
}
},
/**
* 数组去重
* @param arr 待去重的数组
*/
uniqueArr(arr) {
return arr.filter((obj, index, selfArray) => {
return index === selfArray.findIndex((item) => {
return JSON.stringify(item) === JSON.stringify(obj);
});
});
},
/**
* 初始化Worker对象
*/
initWorker() {
try {
NetDiskWorker.GM_matchWorker = new Worker(NetDiskWorker.blobUrl);
NetDiskWorker.GM_matchWorker.onmessage = NetDiskWorker.onMessage;
NetDiskWorker.GM_matchWorker.onerror = NetDiskWorker.onError;
} catch (error) {
log.error(
"初始化Worker失败,可能页面使用了Content-Security-Policy策略,使用代替函数,该函数执行匹配时如果内容过大会导致页面卡死",
error.message
);
NetDiskWorker.GM_matchWorker = {
postMessage(data) {
return new Promise((resolve, reject) => {
let matchedList = [];
try {
NetDiskWorker.handleRegularMatch(data, (matchData) => {
matchedList.push(matchData);
});
} catch (error2) {
NetDiskWorker.onError(error2);
} finally {
matchedList = NetDiskWorker.uniqueArr(matchedList);
NetDiskWorker.onMessage(
new MessageEvent("message", {
data: {
options: data,
msg: "Match End",
data: matchedList,
startTime: data.startTime,
endTime: Date.now()
}
})
);
resolve(null);
}
});
}
};
}
},
/**
* 传递数据给worker内进行处理匹配
* @param message 数据
* @param options 配置
*/
postMessage(message, options) {
NetDiskWorker.GM_matchWorker.postMessage(message, options);
},
/**
* Worker的onmessage
* 这里的this指向会被修改
* @param event
*/
onMessage(event) {
const data = event.data;
if (data.data.length) {
log.success(
`成功匹配${data.data.length}个,用时${Date.now() - data.startTime}ms`
);
}
if (data.options.from === "PasteText") {
NetDiskUI.matchPasteText.workerMatchEndCallBack(data);
}
if (data.options.from.startsWith("FirstLoad")) {
NetDiskWorker.delayNotMatchCount++;
}
NetDiskWorker.successCallBack(data);
},
/**
* Worker的onerror
* @param error
*/
onError(error) {
NetDiskWorker.errorCallBack(error);
},
/**
* worker处理文件匹配后的回调
* @param options
*/
successCallBack(options) {
if (!options.data.length) {
NetDiskWorker.matchingEndCallBack();
return;
}
const handleNetDiskList = [];
for (const matchData of options.data) {
NetDisk.$match.matchedInfoRuleKey.add(matchData.netDiskName);
let matchLinkSet = /* @__PURE__ */ new Set();
matchData.data.forEach((item) => {
matchLinkSet.add(item);
});
matchLinkSet.forEach((item) => {
let handleLink = NetDisk.handleLink(
matchData.netDiskName,
matchData.netDiskIndex,
item
);
if (handleLink) {
handleNetDiskList.push({
shareCode: handleLink.shareCode,
accessCode: handleLink.accessCode,
netDiskName: matchData.netDiskName,
netDiskIndex: matchData.netDiskIndex,
matchText: item
});
}
});
}
let filterHandleNetDiskList = handleNetDiskList.filter(
(value, index, selfArray) => {
let isFind = selfArray.findIndex((obj) => {
return (
//JSON.stringify(obj) === JSON.stringify(value)
obj.accessCode === value.accessCode && obj.netDiskIndex === value.netDiskIndex && obj.netDiskName === value.netDiskName && obj.shareCode === value.shareCode
);
}) === index;
return isFind;
}
);
filterHandleNetDiskList.forEach((item) => {
if (NetDisk.$match.tempMatchedInfo.has(item.netDiskName)) {
let currentTempDict = NetDisk.$match.tempMatchedInfo.get(
item.netDiskName
);
currentTempDict.set(item.shareCode, item);
}
});
filterHandleNetDiskList.forEach((item) => {
let { shareCode, accessCode, netDiskName, netDiskIndex, matchText } = item;
const currentRule = NetDisk.$rule.rule.find(
(item2) => item2.setting.key === netDiskName
);
const currentRegular = currentRule.rule[netDiskIndex];
let isBlackShareCode = false;
NetDisk.$match.blackMatchedInfo.forEach(
(blackMatchInfoItem, blackNetDiskName) => {
if (blackNetDiskName !== item.netDiskName) {
return;
}
let isFindBlackShareCode = blackMatchInfoItem.has(shareCode);
if (isFindBlackShareCode) {
isBlackShareCode = true;
log.warn(
`匹配到黑名单分享码,已过滤:${shareCode}`,
JSON.stringify(item)
);
}
}
);
if (isBlackShareCode) {
return;
}
if (currentRegular.shareCodeExcludeRegular && Array.isArray(currentRegular.shareCodeExcludeRegular)) {
for (const excludeRegularName of currentRegular.shareCodeExcludeRegular) {
let excludeDict = NetDisk.$match.matchedInfo.get(excludeRegularName);
let currentTempDict = NetDisk.$match.tempMatchedInfo.get(excludeRegularName);
if (excludeDict.startsWith(shareCode) || currentTempDict.startsWith(shareCode)) {
log.warn(
`${netDiskName}:该分享码【${shareCode}】与已匹配到该分享码的规则【${excludeRegularName}】冲突`
);
return;
}
}
}
const currentDict = NetDisk.$match.matchedInfo.get(netDiskName);
NetDisk.$data.isMatchedLink = true;
if (currentDict.startsWith(shareCode)) {
let shareCodeDict = currentDict.getStartsWith(shareCode);
if (typeof shareCodeDict.isForceAccessCode === "boolean" && shareCodeDict.isForceAccessCode) {
return;
}
if (utils.isNotNull(shareCodeDict.accessCode)) {
return;
}
if (utils.isNull(accessCode)) {
return;
}
currentDict.set(
shareCode,
NetDisk.getLinkDickObj(accessCode, netDiskIndex, false, matchText)
);
NetDiskUI.view.changeLinkView(
netDiskName,
netDiskIndex,
shareCode,
accessCode,
matchText
);
log.info(
`该匹配项无密码,设置密码 ${netDiskName} ${netDiskIndex}: ${shareCode} ===> ${accessCode}`
);
} else {
if (utils.isNull(accessCode) && NetDiskGlobalData.accessCode.allowQueryHistoryMatchingAccessCode.value) {
let historyMatchAccessCode = NetDiskHistoryMatchView.queryAccessCode(
netDiskName,
shareCode,
true
);
if (historyMatchAccessCode) {
log.info(
"历史匹配记录 ==> 查询到访问码:" + historyMatchAccessCode
);
accessCode = historyMatchAccessCode;
}
}
currentDict.set(
shareCode,
NetDisk.getLinkDickObj(accessCode, netDiskIndex, false, matchText)
);
NetDiskUI.isMatchedNetDiskIconMap.add(netDiskName);
NetDiskUI.view.addLinkView(
netDiskName,
netDiskIndex,
shareCode,
accessCode,
matchText
);
log.success(
`添加链接 ${netDiskName} ${netDiskIndex}: ${shareCode} ===> ${accessCode}`
);
}
});
Object.keys(NetDisk.$match.tempMatchedInfo.getItems()).forEach(
(keyName) => {
NetDisk.$match.tempMatchedInfo.get(keyName).clear();
}
);
if (NetDisk.$data.isMatchedLink) {
switch (NetDiskGlobalData.features["netdisk-behavior-mode"].value) {
case "suspension_smallwindow".toLowerCase():
if (NetDiskSuspensionConfig.mode.current_suspension_smallwindow_mode.value === "suspension") {
NetDiskUI.suspension.show();
} else {
NetDiskUI.view.show();
}
break;
case "suspension_window".toLowerCase():
NetDiskUI.suspension.show();
break;
case "smallwindow".toLowerCase():
NetDiskUI.view.show();
break;
default:
log.error(
"未知的行为模式:" + NetDiskGlobalData.features["netdisk-behavior-mode"].value
);
}
}
NetDiskWorker.matchingEndCallBack();
},
/**
* Worker失败回调
* @param error
*/
errorCallBack(error) {
NetDiskWorker.matchingEndCallBack(true);
log.error("Worker Error", error);
},
/**
* 匹配结束回调
* @param isNow 是否立刻释放锁
*/
matchingEndCallBack(isNow) {
if (isNow) {
NetDiskWorker.isHandleMatch = false;
if (NetDiskWorker.delayNotMatchCount > 0) {
NetDiskWorker.delayNotMatchCount = 0;
NetDiskWorker.dispatchMonitorDOMChange = true;
}
} else {
const delaytime = parseFloat(NetDiskGlobalData.match.delaytime.value.toString()) * 1e3;
setTimeout(() => {
NetDiskWorker.matchingEndCallBack(true);
}, delaytime);
}
},
/**
* 监听页面节点内容或节点文本的变动,从而进行匹配网盘链接
*/
monitorDOMChange() {
const isAddedNodeToMatch = NetDiskGlobalData.match.isAddedNodesToMatch.value;
const readClipboard = NetDiskGlobalData.match.readClipboard.value;
const matchRange = NetDiskGlobalData.match.pageMatchRange.value;
let isFirstLoad = true;
let isFirstLoadPageText = true;
let isFirstLoadPageHTML = true;
let isDepthAcquisitionWithShadowRoot = NetDiskGlobalData.match.depthQueryWithShadowRoot.value;
const matchRegular = {};
const characterMapping = CharacterMapping.getMappingData();
NetDisk.$rule.rule.forEach((item) => {
let netDiskName = item.setting.key;
let netDiskRuleEnable = NetDiskRuleData.function.enable(netDiskName);
if (!netDiskRuleEnable) {
return;
}
if (Reflect.has(matchRegular, netDiskName)) {
matchRegular[netDiskName] = [
...matchRegular[netDiskName],
...item.rule
];
} else {
Reflect.set(matchRegular, netDiskName, item.rule);
}
});
async function observeEvent(mutations) {
if (NetDiskWorker.isHandleMatch) {
NetDiskWorker.delayNotMatchCount++;
return;
}
if (isAddedNodeToMatch && mutations && mutations.length) {
let hasAddedNode = false;
for (let index = 0; index < mutations.length; index++) {
const mutation = mutations[index];
if (mutation.addedNodes && mutation.addedNodes instanceof NodeList) {
if (mutation.addedNodes.length) {
hasAddedNode = true;
break;
}
}
}
if (!hasAddedNode) {
return;
}
}
NetDiskWorker.isHandleMatch = true;
const startTime = Date.now();
if (readClipboard) {
try {
NetDisk.$data.clipboardText = await NetDiskHandlerUtil.getClipboardText();
} catch (error) {
}
}
if (typeof NetDisk.$data.clipboardText !== "string") {
NetDisk.$data.clipboardText = "";
}
const toMatchedTextList = [];
if (utils.isNotNull(NetDisk.$data.clipboardText)) {
let clipboardText = NetDisk.$data.clipboardText;
toMatchedTextList.push(clipboardText);
}
if (NetDiskGlobalData.match.allowMatchLocationHref) {
let decodeComponentUrl = NetDiskRuleUtils.getDecodeComponentUrl();
toMatchedTextList.push(decodeComponentUrl);
}
if (isFirstLoad) {
isFirstLoad = false;
if (toMatchedTextList.length) {
NetDiskWorker.postMessage({
characterMapping,
textList: toMatchedTextList,
matchTextRange: matchRange,
regular: matchRegular,
startTime,
from: "FirstLoad-DOMChange"
});
return;
}
}
if (matchRange.includes("innerText")) {
let pageTextList = NetDiskWorkerUtils.getPageText(
document.documentElement,
isDepthAcquisitionWithShadowRoot
);
toMatchedTextList.push(...pageTextList);
if (isFirstLoadPageText) {
isFirstLoadPageText = false;
NetDiskWorker.postMessage({
characterMapping,
textList: toMatchedTextList,
matchTextRange: matchRange,
regular: matchRegular,
startTime,
from: "FirstLoad-Text-DOMChange"
});
return;
}
}
if (matchRange.includes("innerHTML")) {
let pageHTMLList = NetDiskWorkerUtils.getPageHTML(
document.documentElement,
isDepthAcquisitionWithShadowRoot
);
toMatchedTextList.push(...pageHTMLList);
if (isFirstLoadPageHTML) {
isFirstLoadPageHTML = false;
NetDiskWorker.postMessage({
characterMapping,
textList: toMatchedTextList,
matchTextRange: matchRange,
regular: matchRegular,
startTime,
from: "FirstLoad-HTML-DOMChange"
});
return;
}
}
if (NetDiskGlobalData.match.toBeMatchedWithInputElementValue) {
let inputValueList = NetDiskWorkerUtils.getInputElementValue(
document.documentElement,
isDepthAcquisitionWithShadowRoot
);
toMatchedTextList.push(...inputValueList);
}
if (NetDiskGlobalData.match.toBeMatchedTextAreaElementValue) {
let textAreaValueList = NetDiskWorkerUtils.getTextAreaElementValue(
document.documentElement,
isDepthAcquisitionWithShadowRoot
);
toMatchedTextList.push(...textAreaValueList);
}
NetDiskWorker.postMessage({
characterMapping,
textList: toMatchedTextList,
matchTextRange: matchRange,
regular: matchRegular,
startTime,
from: "DOMChange"
});
}
let dispatchMonitorDOMChange = NetDiskWorker.dispatchMonitorDOMChange;
Object.defineProperty(NetDiskWorker, "dispatchMonitorDOMChange", {
set: function(value) {
dispatchMonitorDOMChange = value;
if (value) {
let addedNodes = document.querySelectorAll(
"html"
);
observeEvent([
{
addedNodes,
attributeName: null,
attributeNamespace: null,
nextSibling: null,
oldValue: null,
previousSibling: null,
removedNodes: addedNodes,
target: addedNodes[0],
type: "attributes"
}
]);
}
},
get: function() {
return dispatchMonitorDOMChange;
}
});
if (NetDiskGlobalData.features["netdisk-match-mode"].value === "MutationObserver") {
utils.mutationObserver(document.documentElement, {
callback: observeEvent,
config: {
/* 子节点的变动(新增、删除或者更改) */
childList: NetDiskGlobalData.match["mutationObserver-childList"].value,
/* 节点内容或节点文本的变动 */
characterData: NetDiskGlobalData.match["mutationObserver-characterData"].value,
/* 是否将观察器应用于该节点的所有后代节点 */
subtree: NetDiskGlobalData.match["mutationObserver-subtree"].value
}
});
this.dispatchMonitorDOMChange = true;
} else if (NetDiskGlobalData.features["netdisk-match-mode"].value === "Menu") {
GM_Menu.add({
key: "performPageTextMatchingManually",
text: "点击执行文本匹配",
autoReload: false,
isStoreValue: false,
showText(text) {
return text;
},
callback: () => {
this.dispatchMonitorDOMChange = true;
}
});
} else {
log.error(
"未知匹配模式:" + NetDiskGlobalData.features["netdisk-match-mode"].value
);
}
}
};
const NetDiskUserRuleDebug = {
$el: {
$select: null,
$log: null,
$matchText: null,
$button: null
},
/**
* 重置环境变量
*/
reset() {
Object.keys(this.$el).forEach((keyName) => {
Reflect.deleteProperty(this.$el, keyName);
});
},
/**
* 设置日志输出
* @param {"info"|"error"|"success"|"warn"} tag 日志等级
* @param {...any[]} args
*/
setLog(tag, ...args) {
let text = "";
args.forEach((item) => {
if (text !== "") {
text += "\n";
}
if (typeof item !== "string") {
text += JSON.stringify(item, void 0, 4);
} else {
text += item;
}
});
let logElement = domUtils.createElement(
"p",
{
innerText: text
},
{
"data-tag": tag
}
);
domUtils.append(this.$el.$log, logElement);
},
/**
* 清空日志
*/
clearLog() {
this.$el.$log.innerHTML = "";
},
/**
* 显示调试规则的界面
* @param ruleJSON
*/
showUI(ruleJSON) {
this.reset();
if (utils.isNull(ruleJSON.regexp)) {
Qmsg.error("请先配置regexp");
return;
}
let that = this;
let customRule = NetDiskUserRule.parseRule([ruleJSON]);
let regexp = customRule[0].rule;
let dialog = NetDiskPops.confirm(
{
title: {
text: `调试规则 ${ruleJSON.key}`,
position: "center"
},
content: {
text: (
/*html*/
`
`
),
html: true
},
btn: {
ok: {
enable: false
}
},
style: (
/*css*/
`
.custom-rule-container{
display: flex;
align-items: center;
}
.custom-rule-select-regexp{
width: 100%;
height: 32px;
line-height: normal;
border: 1px solid rgb(184, 184, 184, var(--pops-bd-opacity));
border-radius: 5px;
text-align: center;
outline: 0;
background: rgb(255, 255, 255, var(--pops-bg-opacity));
box-shadow: none;
}
.custom-rule-input-container{
display: flex;
flex-wrap: wrap;
justify-content: center;
margin: 5px;
width: 30%;
}
.custom-rule-select-regexp-item{
}
button.custom-rule-run-match-button{
margin-top: 5px;
}
textarea.custom-rule-match-text{
width: 100%;
min-height: 70px;
outline: none;
margin: 0px;
background-image: none;
background-color: transparent;
display: inline-block;
resize: vertical;
padding: 5px;
line-height: normal;
box-sizing: border-box;
border: 1px solid rgb(220, 223, 230);
appearance: none;
}
.custom-rule-match-log{
}
.custom-rule-match-log-container{
padding: 5px;
background: rgb(229, 229, 229);
}
.custom-rule-match-log-container p{
margin: 2px 0px;
border-bottom: 1px solid #000000;
}
.custom-rule-match-log-container p:last-child{
border-bottom: 0px;
margin-bottom: 0px;
}
.custom-rule-match-log-container p[data-tag]{
}
.custom-rule-match-log-container p[data-tag="info"]{
}
.custom-rule-match-log-container p[data-tag="success"]{
color: green;
}
.custom-rule-match-log-container p[data-tag="warn"]{
color: yellow;
}
.custom-rule-match-log-container p[data-tag="error"]{
color: red;
}
`
)
},
NetDiskUI.popsStyle.customRuleDebugView
);
this.$el.$select = dialog.$shadowRoot.querySelector(
".custom-rule-select-regexp"
);
this.$el.$matchText = dialog.$shadowRoot.querySelector(
".custom-rule-match-text"
);
this.$el.$log = dialog.$shadowRoot.querySelector(
".custom-rule-match-log-container"
);
this.$el.$button = dialog.$shadowRoot.querySelector(
".custom-rule-run-match-button"
);
regexp.forEach((regExpItem, index) => {
this.$el.$select.appendChild(
domUtils.createElement("option", {
className: "custom-rule-select-regexp-item",
innerText: "regexp下标:" + index,
"data-value": regExpItem
})
);
});
function logCallBack(logData) {
if (Array.isArray(logData.msg)) {
that.setLog(logData.status ? "info" : "error", ...logData.msg);
} else {
that.setLog(logData.status ? "info" : "error", logData.msg);
}
if (!logData.status) {
that.setLog("error", "执行完毕");
}
}
function debugRunClickEvent() {
try {
if (utils.isNull(that.$el.$matchText.value)) {
Qmsg.error("请先输入待匹配的字符串");
return;
}
that.clearLog();
let netDiskName = ruleJSON.key;
let netDiskIndex = that.$el.$select.selectedIndex;
let selectRegularOption = that.$el.$select.selectedOptions[netDiskIndex]["data-value"];
log.info("当前选中的规则: ", selectRegularOption);
let testCustomRule = {};
testCustomRule[ruleJSON.key] = [selectRegularOption];
let matchTextList = [];
NetDiskWorker.handleRegularMatch(
{
characterMapping: CharacterMapping.getMappingData(),
regular: testCustomRule,
textList: [that.$el.$matchText.value],
matchTextRange: ["innerText", "innerHTML"],
startTime: Date.now(),
from: "Debug"
},
(matchData) => {
matchTextList.push(...matchData.data);
}
);
if (!matchTextList.length) {
that.setLog("error", "未成功匹配到数据");
return;
}
matchTextList = NetDiskWorker.uniqueArr(matchTextList);
that.setLog("info", "成功匹配到的数据 ==> ", matchTextList);
matchTextList.forEach((matchText, index) => {
that.setLog("success", "当前处理的字符串: " + matchText);
that.setLog("success", "当前执行: 对shareCode进行处理获取");
let shareCode = NetDiskDebug.handleShareCode(
matchText,
selectRegularOption,
logCallBack
);
if (utils.isNull(shareCode)) {
return;
}
that.setLog("info", " ");
that.setLog("info", `================分割线================`);
that.setLog("info", " ");
that.setLog("success", "当前执行: 对accessCode进行处理获取");
let accessCode = NetDiskDebug.handleAccessCode(
matchText,
selectRegularOption,
logCallBack
);
that.setLog("info", " ");
that.setLog("info", `================分割线================`);
that.setLog("info", " ");
that.setLog("success", "当前执行: 对uiLinkShow进行处理获取");
let uiLinkShow = NetDiskDebug.handleLinkShow(
matchText,
selectRegularOption,
shareCode,
accessCode,
logCallBack
);
that.setLog("info", " ");
that.setLog("info", `================分割线================`);
that.setLog("info", " ");
that.setLog("success", "当前执行: 对blank进行处理获取");
let blankUrl = NetDiskDebug.handleBlank(
matchText,
selectRegularOption,
shareCode,
accessCode,
logCallBack
);
that.setLog("info", " ");
that.setLog("info", `================分割线================`);
that.setLog("info", " ");
that.setLog("success", "当前执行: 对copyUrl进行处理获取");
let copyUrl = NetDiskDebug.handleCopyUrl(
matchText,
selectRegularOption,
shareCode,
accessCode,
logCallBack
);
that.setLog("success", "执行完毕");
});
} catch (error) {
log.error(error);
that.setLog(error.toString());
}
}
domUtils.on(that.$el.$button, "click", void 0, debugRunClickEvent);
}
};
const dialogCSS = '.pops[type-value="confirm"] .pops-confirm-content {\r\n overflow: hidden;\r\n}\r\n/* textarea美化 */\r\n.pops.whitesevPopNetDiskCustomRules[type-value="confirm"]\r\n .pops-confirm-content\r\n textarea {\r\n width: 100%;\r\n height: 100%;\r\n border: none;\r\n outline: none;\r\n padding: 0;\r\n margin: 0;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n appearance: none;\r\n background-image: none;\r\n background-color: transparent;\r\n\r\n display: inline-block;\r\n resize: vertical;\r\n padding: 5px 15px;\r\n line-height: normal;\r\n box-sizing: border-box;\r\n border: 1px solid #dcdfe6;\r\n transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);\r\n appearance: none;\r\n resize: none;\r\n}\r\n/* 获得焦点 */\r\n.pops.whitesevPopNetDiskCustomRules[type-value="confirm"]\r\n .pops-confirm-content\r\n textarea:focus {\r\n outline: none;\r\n border-color: #3677f0;\r\n}\r\n/* 提示文字 */\r\n.pops.whitesevPopNetDiskCustomRules[type-value="confirm"]\r\n .pops-confirm-content\r\n textarea::placeholder {\r\n color: #c0c4cc;\r\n}\r\n/* 鼠标hover */\r\n.pops.whitesevPopNetDiskCustomRules[type-value="confirm"]\r\n .pops-confirm-content\r\n textarea:hover {\r\n border-color: #c0c4cc;\r\n}\r\n';
const NetDiskUserRuleUI = {
/**
* 添加/编辑规则
* @param isEdit
* @param ruleKey 当isEdit为true时,传入该值
*/
show(isEdit, ruleKey) {
let titleText = "添加";
if (isEdit) {
titleText = "编辑";
}
titleText += "自定义规则";
let $ruleInput = null;
function saveCallBack(event, isDebug2) {
let ruleText = $ruleInput.value.trim();
let parseRuleResult = NetDiskUserRule.parseRuleStrToRule(ruleText);
if (parseRuleResult.success) {
let userRule = parseRuleResult.data;
if (isEdit) {
NetDiskUserRule.setRule(ruleKey, userRule);
} else {
NetDiskUserRule.addRule(userRule);
}
Qmsg.success("保存成功");
} else {
Qmsg.error(parseRuleResult.msg);
}
}
function debugCallBack(event) {
let ruleText = $ruleInput.value.trim();
let parseRuleResult = NetDiskUserRule.parseRuleStrToRule(ruleText);
if (parseRuleResult.success) {
let userRule = parseRuleResult.data;
NetDiskUserRuleDebug.showUI(userRule);
} else {
Qmsg.error(parseRuleResult.msg);
}
}
function formatCallBack(event) {
try {
let ruleJSON = JSON.parse($ruleInput.value);
let ruleJSONString = NetDiskUserRule.getFormatRule(ruleJSON);
$ruleInput.value = ruleJSONString;
Qmsg.success("格式化成功");
} catch (error) {
log.error(error);
Qmsg.error(error.message, {
html: true,
timeout: 3500
});
}
}
let dialog = NetDiskPops.confirm(
{
title: {
text: titleText,
position: "center"
},
content: {
text: (
/*html*/
``
),
html: true
},
btn: {
merge: true,
mergeReverse: false,
reverse: false,
position: "space-between",
ok: {
text: "保存",
callback: (eventDetails, event) => {
saveCallBack();
}
},
cancel: {
text: "调试",
callback: (eventDetails, event) => {
debugCallBack();
}
},
other: {
enable: true,
text: "格式化",
type: "xiaomi-primary",
callback: (eventDetails, event) => {
formatCallBack();
}
}
},
class: "whitesevPopNetDiskCustomRules",
style: dialogCSS
},
NetDiskUI.popsStyle.customRulesView
);
$ruleInput = dialog.$shadowRoot.querySelector("textarea");
if (isEdit) {
let rule = NetDiskUserRule.getRule(ruleKey);
$ruleInput.value = NetDiskUserRule.getFormatRule(rule);
} else {
$ruleInput.value = NetDiskUserRule.getTemplateRule();
}
}
};
const panelIndexCSS = 'div[class^="netdisk-custom-rule-"] {\r\n display: flex;\r\n align-items: center;\r\n margin-left: 10px;\r\n cursor: pointer;\r\n}\r\ndiv[class^="netdisk-custom-rule-"] svg,\r\ndiv[class^="netdisk-custom-rule-"] svg {\r\n width: 1.2em;\r\n height: 1.2em;\r\n}\r\n/* 控件被禁用的颜色 */\r\naside.pops-panel-aside li[data-key][data-function-enable="false"] {\r\n color: #a8abb2;\r\n filter: grayscale(100%);\r\n}\r\n/* 左侧网盘图标 */\r\naside.pops-panel-aside .netdisk-aside-icon {\r\n width: 20px;\r\n height: 20px;\r\n background-size: 100% 100%;\r\n background-repeat: no-repeat;\r\n}\r\n/* 设置间隔 */\r\naside.pops-panel-aside ul li {\r\n gap: 4px;\r\n}\r\n\r\n/* mobile模式 */\r\n@media screen and (max-width: 600px) {\r\n /* 隐藏左侧网盘图标 */\r\n aside.pops-panel-aside .netdisk-aside-text {\r\n display: none;\r\n }\r\n}\r\n';
const NetDiskGlobalSettingView = {
show() {
var _a2;
if (NetDiskUI.Alias.settingAlias) {
log.error("设置界面已存在");
Qmsg.error("设置界面已存在");
return;
}
let content = PopsPanel.getPanelContentConfig();
let ruleContent = NetDiskRule.getRulePanelContent();
content = content.concat(ruleContent);
let $panel = NetDiskPops.panel(
{
title: {
text: `${((_a2 = _GM_info == null ? void 0 : _GM_info.script) == null ? void 0 : _a2.name) || SCRIPT_NAME}-设置`,
position: "center"
},
content,
btn: {
close: {
enable: true,
callback(event) {
event.close();
NetDiskUI.Alias.settingAlias = void 0;
}
}
},
mask: {
clickCallBack(originalRun) {
originalRun();
NetDiskUI.Alias.settingAlias = void 0;
}
},
class: "whitesevPopSetting",
style: panelIndexCSS
},
NetDiskUI.popsStyle.settingView
);
NetDiskUI.Alias.settingAlias = $panel;
this.setRuleHeaderControlsClickEvent($panel.$shadowRoot);
},
showPanel(details = {}) {
},
/**
* 设置自定义规则顶部的编辑|删除的点击事件
*/
setRuleHeaderControlsClickEvent($shadowRoot) {
domUtils.on(
$shadowRoot,
"click",
".netdisk-custom-rule-edit",
function(event) {
let $click = event.target;
let ruleKey = $click.getAttribute("data-key");
$click.getAttribute("data-type");
NetDiskUserRuleUI.show(true, ruleKey);
}
);
domUtils.on(
$shadowRoot,
"click",
".netdisk-custom-rule-delete",
function(event) {
let $click = event.target;
let ruleKey = $click.getAttribute("data-key");
let ruleName = $click.getAttribute("data-type");
NetDiskPops.alert({
title: {
text: "提示",
position: "center"
},
content: {
text: `确定删除自定义规则 ${ruleName}(${ruleKey}) 吗?`
},
btn: {
ok: {
callback(okEvent) {
let deleteStatus = NetDiskUserRule.deleteRule(ruleKey);
if (deleteStatus) {
let asideElement = NetDiskUI.Alias.settingAlias.$shadowRoot.querySelector(
`.pops-panel-aside > ul > li[data-key="${ruleKey}"]`
);
let $prev = asideElement.previousElementSibling;
let $next = asideElement.nextElementSibling;
if ($prev) {
$prev.click();
} else if ($next) {
$next.click();
}
asideElement == null ? void 0 : asideElement.remove();
Qmsg.success("删除成功");
okEvent.close();
} else {
Qmsg.error("删除自定义规则失败");
}
}
}
}
});
}
);
}
};
const indexCSS$2 = ".whitesevSuspension {\r\n top: 0;\r\n position: fixed;\r\n right: 10px;\r\n border-radius: 12px;\r\n}\r\n.whitesevSuspension .whitesevSuspensionMain {\r\n background: #fff;\r\n border: 1px solid #f2f2f2;\r\n box-shadow: 0 0 15px #e4e4e4;\r\n box-sizing: border-box;\r\n border-radius: inherit;\r\n height: inherit;\r\n width: inherit;\r\n}\r\n.whitesevSuspension .whitesevSuspensionFloor {\r\n border-bottom: 1px solid #f2f2f2;\r\n position: relative;\r\n box-sizing: border-box;\r\n border-radius: inherit;\r\n height: inherit;\r\n width: inherit;\r\n}\r\n.whitesevSuspension .whitesevSuspensionFloor .netdisk {\r\n background-position: center center;\r\n background-size: 115% 115%;\r\n background-repeat: no-repeat;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: inherit;\r\n height: inherit;\r\n width: inherit;\r\n}\r\n.whitesevSuspension .whitesevSuspensionFloor .netdisk:hover {\r\n transition: all 300ms linear;\r\n background-color: #e4e4e4;\r\n transform: scale(1.1);\r\n}\r\n.whitesevPop-content p[pop] {\r\n height: 100%;\r\n}\r\n";
const NetDiskSuspensionConfig = {
position: {
/** 悬浮按钮位置的x坐标 */
suspensionX: GenerateData("suspensionX", DOMUtils.width(window) - 50),
/** 悬浮按钮位置的y坐标 */
suspensionY: GenerateData(
"suspensionY",
(DOMUtils.height(window) - 50) / 2
),
/** 悬浮按钮所在位置的最大x */
suspensionMaxX: GenerateData(
"susponsionMax-x",
DOMUtils.width(window) - 50
),
/** 悬浮按钮所在位置的最小y */
suspensionMaxY: GenerateData(
"suspensionMax-y",
DOMUtils.height(window) - 50
),
/** 悬浮按钮是否在右边 */
isRight: GenerateData("isRight", false)
},
mode: {
current_suspension_smallwindow_mode: GenerateData(
"current_suspension_smallwindow_mode",
"suspension"
)
}
};
const NetDiskSuspension = {
suspensionNode: null,
/** 是否已显示 */
isShow: false,
/** 是否已设置事件 */
isSetEvent: false,
/** 是否正在切换背景 */
isRandBg: false,
/**
* 显示悬浮按钮
*/
show() {
if (!this.isShow) {
this.isShow = true;
this.createUI();
this.setSuspensionPosition();
}
if (!this.isSetEvent) {
this.isSetEvent = true;
this.setSuspensionEvent();
this.setResizeEventListener();
}
this.backgroundSwitch();
this.showSuspension();
},
showSuspension() {
this.suspensionNode.style.display = "";
},
hideSuspension() {
this.suspensionNode.style.display = "none";
},
/**
* 判断当前是否是顶部窗口
* @returns {boolean}
*/
isTopWindow() {
return _unsafeWindow.self.window === _unsafeWindow.top.window;
},
/**
* 创建UI界面
*/
createUI() {
if (NetDiskGlobalData.suspension.size.value < 15) {
NetDiskGlobalData.suspension.size.value = 15;
}
if (NetDiskGlobalData.suspension.size.value > 250) {
NetDiskGlobalData.suspension.size.value = 250;
}
if (NetDiskGlobalData.suspension.opacity.value < 0.1) {
NetDiskGlobalData.suspension.opacity.value = 0.1;
}
if (NetDiskGlobalData.suspension.opacity.value > 1) {
NetDiskGlobalData.suspension.opacity.value = 1;
}
let $shadowContainer = DOMUtils.createElement("div", {
className: "whitesev-suspension-shadow-container"
});
let $shadowRoot = $shadowContainer.attachShadow({ mode: "open" });
this.suspensionNode = DOMUtils.createElement(
"div",
{
id: "whitesevSuspensionId",
className: "whitesevSuspension",
innerHTML: (
/*html*/
`
`
)
},
{
style: `
width: ${NetDiskGlobalData.suspension.size.value}px;
height: ${NetDiskGlobalData.suspension.size.value}px;
opacity: ${NetDiskGlobalData.suspension.opacity.value}
`
}
);
$shadowRoot.appendChild(this.suspensionNode);
document.body.appendChild($shadowContainer);
},
/**
* 设置 悬浮按钮所有事件
*/
setSuspensionEvent() {
let needDragElement = NetDiskUI.suspension.suspensionNode;
let dragNode = new AnyTouch(needDragElement);
let netDiskLinkViewTimer = void 0;
let moveFlag = false;
let isDouble = false;
let clickElementLeftOffset = 0;
let clickElementTopOffset = 0;
dragNode.on("pan", function(event) {
if (!moveFlag) {
moveFlag = true;
let rect = needDragElement.getBoundingClientRect();
clickElementLeftOffset = event.x - rect.left;
clickElementTopOffset = event.y - rect.top;
DOMUtils.css(needDragElement, {
cursor: "move",
transition: "none"
});
}
if (event.phase === "move") {
let maxLeftOffset = DOMUtils.width(window) - NetDiskGlobalData.suspension.size.value;
let maxTopOffset = DOMUtils.height(window) - NetDiskGlobalData.suspension.size.value;
let currentSuspensionLeftOffset = event.x - clickElementLeftOffset;
let currentSuspensionTopOffset = event.y - clickElementTopOffset;
currentSuspensionLeftOffset = currentSuspensionLeftOffset > maxLeftOffset ? maxLeftOffset : currentSuspensionLeftOffset;
currentSuspensionTopOffset = currentSuspensionTopOffset > maxTopOffset ? maxTopOffset : currentSuspensionTopOffset;
currentSuspensionLeftOffset = currentSuspensionLeftOffset < 0 ? 0 : currentSuspensionLeftOffset;
currentSuspensionTopOffset = currentSuspensionTopOffset < 0 ? 0 : currentSuspensionTopOffset;
NetDiskSuspension.saveSuspensionPosition({
x: currentSuspensionLeftOffset,
y: currentSuspensionTopOffset
});
DOMUtils.css(needDragElement, {
left: currentSuspensionLeftOffset + "px",
top: currentSuspensionTopOffset + "px"
});
}
if (event.phase === "end") {
moveFlag = false;
DOMUtils.css(needDragElement, {
cursor: "auto"
});
let currentSuspensionLeftOffset = parseInt(
DOMUtils.css(needDragElement, "left")
);
if (NetDiskGlobalData.suspension["suspended-button-adsorption-edge"].value) {
let setCSSLeft = 0;
if (currentSuspensionLeftOffset >= DOMUtils.width(window) / 2) {
setCSSLeft = DOMUtils.width(window) - NetDiskGlobalData.suspension.size.value;
if (NetDiskUI.suspension.isTopWindow()) {
NetDiskSuspensionConfig.position.isRight.value = true;
}
} else {
if (NetDiskUI.suspension.isTopWindow()) {
NetDiskSuspensionConfig.position.isRight.value = false;
}
}
NetDiskSuspension.saveSuspensionPosition({
x: setCSSLeft
});
DOMUtils.css(needDragElement, {
left: setCSSLeft + "px"
});
}
DOMUtils.css(needDragElement, {
transition: "left 300ms ease 0s"
});
}
});
dragNode.on("tap", function(event) {
clearTimeout(netDiskLinkViewTimer);
netDiskLinkViewTimer = void 0;
if (isDouble) {
isDouble = false;
NetDiskGlobalSettingView.show();
} else {
netDiskLinkViewTimer = setTimeout(() => {
isDouble = false;
if (NetDiskGlobalData.features["netdisk-behavior-mode"].value.includes(
"smallwindow"
)) {
NetDiskSuspensionConfig.mode.current_suspension_smallwindow_mode.value = "smallwindow";
NetDiskUI.suspension.hideSuspension();
}
NetDiskUI.view.show();
}, 200);
isDouble = true;
}
});
NetDiskUI.setGlobalRightClickMenu(needDragElement);
},
/**
* 保存悬浮按钮位置
* @param position
*/
saveSuspensionPosition(position) {
if (!NetDiskUI.suspension.isTopWindow()) {
return;
}
if (position == null) {
return;
}
if (typeof position.x === "number") {
NetDiskSuspensionConfig.position.suspensionX.value = position.x;
}
if (typeof position.y === "number") {
NetDiskSuspensionConfig.position.suspensionY.value = position.y;
}
NetDiskSuspensionConfig.position.suspensionMaxX.value = NetDiskSuspensionConfig.position.suspensionMaxX.default;
NetDiskSuspensionConfig.position.suspensionMaxY.value = NetDiskSuspensionConfig.position.suspensionMaxY.default;
},
/**
* 设置window的resize事件监听,来重新设置悬浮按钮的位置
*/
setResizeEventListener() {
DOMUtils.on(globalThis, "resize", void 0, () => {
let activeElement = document.activeElement;
if (utils.isPhone()) {
if (["input", "textarea"].includes(activeElement.localName)) {
return;
} else if (activeElement.hasAttribute("contenteditable") && activeElement.getAttribute("contenteditable") === "true" || activeElement.closest("[contenteditable='true']")) {
return;
} else if (!document.hasFocus()) {
return;
}
}
this.setSuspensionPosition();
});
},
/**
* 设置悬浮按钮位置
*/
setSuspensionPosition() {
const MAX_X = DOMUtils.width(window) - NetDiskGlobalData.suspension.size.value;
const MAX_Y = DOMUtils.height(window) - NetDiskGlobalData.suspension.size.value;
const LAST_MAX_X = NetDiskSuspensionConfig.position.suspensionMaxX.value;
const LAST_MAX_Y = NetDiskSuspensionConfig.position.suspensionMaxY.value;
NetDiskSuspensionConfig.position.suspensionMaxX.default = MAX_X;
NetDiskSuspensionConfig.position.suspensionMaxY.default = MAX_Y;
let suspension_X = NetDiskSuspensionConfig.position.suspensionX.value;
let suspension_Y = NetDiskSuspensionConfig.position.suspensionY.value;
if (MAX_X !== LAST_MAX_X) {
let percent_X = suspension_X / LAST_MAX_X;
let recalculate_suspension_X = MAX_X * percent_X;
suspension_X = recalculate_suspension_X;
}
if (MAX_Y !== LAST_MAX_Y) {
let percent_Y = suspension_Y / LAST_MAX_Y;
let recalculate_suspension_Y = MAX_Y * percent_Y;
suspension_Y = recalculate_suspension_Y;
}
if (suspension_X > MAX_X) {
suspension_X = MAX_X;
} else if (suspension_X < 0) {
suspension_X = 0;
}
if (suspension_Y > MAX_Y) {
suspension_Y = MAX_Y;
} else if (suspension_Y < 0) {
suspension_Y = 0;
}
if (NetDiskGlobalData.suspension["suspended-button-adsorption-edge"].value) {
if (NetDiskSuspensionConfig.position.isRight.value) {
suspension_X = MAX_X;
} else {
suspension_X = 0;
}
}
NetDiskSuspension.saveSuspensionPosition({
x: suspension_X,
y: suspension_Y
});
DOMUtils.css(NetDiskUI.suspension.suspensionNode, {
left: suspension_X + "px",
top: suspension_Y + "px"
});
},
/**
* 悬浮按钮背景轮播 效果为淡入淡出
*/
backgroundSwitch() {
if (this.isRandBg) {
return;
}
function getRandBgList() {
let resultList = [];
NetDiskUI.isMatchedNetDiskIconMap.forEach((item) => {
resultList = [...resultList, NetDiskUI.src.icon[item]];
});
return resultList;
}
function startSwitch(fadeTime, currentBackgroundSrc) {
currentList = getRandBgList();
DOMUtils.fadeOut(randBgNode, fadeTime, function() {
currentIndex++;
currentIndex = currentIndex < currentList.length ? currentIndex : 0;
currentBackgroundSrc = currentList[currentIndex];
DOMUtils.css(randBgNode, {
"background-image": `url(${currentBackgroundSrc})`
});
DOMUtils.fadeIn(randBgNode, fadeTime, function() {
setTimeout(() => {
startSwitch(
parseInt(
NetDiskGlobalData.suspension["randbg-time"].value.toString()
),
currentBackgroundSrc
);
}, parseInt(NetDiskGlobalData.suspension["randbg-show-time"].value.toString()));
});
});
}
let currentList = [];
let currentIndex = 0;
currentList = getRandBgList();
let randBgSrc = currentList[currentIndex];
let randBgNode = NetDiskUI.suspension.suspensionNode.querySelector(
".whitesevSuspension .netdisk"
);
DOMUtils.css(randBgNode, {
"background-image": `url(${randBgSrc})`
});
if (currentList.length < 2 || NetDiskGlobalData.suspension["randbg-time"].value <= 0) {
return;
}
this.isRandBg = true;
startSwitch(
parseInt(
NetDiskGlobalData.suspension["randbg-time"].value.toString().toString()
),
randBgSrc
);
}
};
const indexCSS$1 = ".pops-folder-list .list-name-text {\r\n max-width: 300px;\r\n}\r\n.netdisk-static-link-onefile .pops-folder-list .list-name-text {\r\n max-width: 220px;\r\n}\r\n.netdisk-static-link-onefile\r\n .pops-mobile-folder-content\r\n .pops-folder-list\r\n .list-name-text {\r\n max-width: unset;\r\n}\r\n";
const NetDiskLinearChainDialogView = {
/**
* 单文件直链弹窗
* @param fileDetails 配置
*/
oneFile(fileDetails) {
log.success("成功获取单文件直链", fileDetails);
NetDiskPops.folder(
{
title: {
text: fileDetails.title
},
folder: [
{
fileName: fileDetails.fileName,
fileSize: fileDetails.fileSize,
fileType: fileDetails.fileType ?? "",
// @ts-ignore
createTime: fileDetails.fileUploadTime || fileDetails.fileLatestTime,
// @ts-ignore
latestTime: fileDetails.fileLatestTime || fileDetails.fileUploadTime,
isFolder: false,
index: 0,
async clickEvent() {
if (typeof fileDetails.clickCallBack === "function") {
fileDetails.clickCallBack(fileDetails);
} else {
return {
autoDownload: true,
mode: "aBlank",
url: fileDetails.downloadUrl
};
}
}
}
],
btn: {
ok: {
text: "下载",
callback() {
if (typeof fileDetails.clickCallBack === "function") {
fileDetails.clickCallBack(fileDetails);
} else {
window.open(fileDetails.downloadUrl, "_blank");
}
}
}
},
class: "netdisk-static-link-onefile",
style: indexCSS$1
},
NetDiskUI.popsStyle.oneFileStaticView
);
},
/**
* 多文件直链弹窗
* @param title 标题
* @param folderInfoList文件夹信息
*/
moreFile(title, folderInfoList = []) {
log.success("文件解析信息", folderInfoList);
NetDiskPops.folder(
{
title: {
text: title
},
folder: folderInfoList,
style: indexCSS$1
},
NetDiskUI.popsStyle.moreFileStaticView
);
}
};
const NetDiskNewAccessCodeView = function(title = "密码错误", netDiskName = "", netDiskIndex, shareCode, accessCode, okCallBack = () => {
}) {
const accessCodeConfirm = NetDiskPops.prompt(
{
title: {
text: title,
position: "center",
html: false
},
btn: {
reverse: true,
position: "end",
cancel: {
text: "取消",
callback(eventDetails, event) {
accessCodeConfirm.close();
}
},
ok: {
callback: (event) => {
var _a2, _b, _c, _d;
let userInputAccessCode = event.text.replace(/[\s]*/gi, "");
let uiLink = NetDisk.handleLinkShow(
netDiskName,
netDiskIndex,
shareCode,
userInputAccessCode,
void 0
);
let currentItemSelector = `.netdisk-url a[data-netdisk='${netDiskName}'][data-sharecode='${shareCode}']`;
let currentHistoryItemSelector = `.netdiskrecord-link a[data-netdisk='${netDiskName}'][data-sharecode='${shareCode}']`;
let currentItemElement = (_b = (_a2 = NetDiskUI.Alias.uiLinkAlias) == null ? void 0 : _a2.$shadowRoot) == null ? void 0 : _b.querySelector(
currentItemSelector
);
let currentHistoryItemElement = (_d = (_c = NetDiskUI.Alias.historyAlias) == null ? void 0 : _c.$shadowRoot) == null ? void 0 : _d.querySelector(
currentHistoryItemSelector
);
if (currentItemElement) {
currentItemElement.setAttribute(
"data-accesscode",
userInputAccessCode
);
domUtils.html(currentItemElement, uiLink);
}
if (currentHistoryItemElement) {
currentHistoryItemElement.setAttribute(
"data-accesscode",
userInputAccessCode
);
domUtils.html(currentHistoryItemElement, uiLink);
}
log.info(`${netDiskName} 重新输入的密码:${userInputAccessCode}`);
let callbackOption = {
/** 该分享码是否在已匹配的字典中 */
isFindInMatchedDict: false,
/** 是否成功同步至已匹配的字典 */
isUpdatedMatchedDict: false,
/** 是否成功同步至历史匹配记录 */
isUpdatedHistoryMatched: false,
/** 新的访问码 */
accessCode: userInputAccessCode
};
let netDiskDict = NetDisk.$match.matchedInfo.get(netDiskName);
if (netDiskDict.has(shareCode)) {
callbackOption.isFindInMatchedDict = true;
callbackOption.isUpdatedMatchedDict = true;
let currentDict = netDiskDict.get(shareCode);
netDiskDict.set(
shareCode,
NetDisk.getLinkDickObj(
userInputAccessCode,
netDiskIndex,
true,
currentDict.matchText
)
);
}
callbackOption.isUpdatedHistoryMatched = NetDiskHistoryMatchView.syncAccessCode(
netDiskName,
netDiskIndex,
shareCode,
userInputAccessCode
);
okCallBack(callbackOption);
event.close();
}
}
},
content: {
placeholder: "请重新输入密码",
focus: true,
select: true,
text: accessCode == null ? "" : typeof accessCode === "string" ? accessCode : ""
},
style: (
/*css*/
`
input{
font-size: larger;
}
`
)
},
NetDiskUI.popsStyle.inputNewAccessCodeView
);
domUtils.listenKeyboard(
accessCodeConfirm.$shadowRoot,
"keypress",
(keyName) => {
if (keyName === "Enter") {
const $ok = accessCodeConfirm.$shadowRoot.querySelector(
".pops-prompt-btn-ok"
);
$ok.click();
}
}
);
};
const indexCSS = '.pops[type-value="confirm"] .pops-confirm-content {\r\n overflow: hidden;\r\n}\r\n.netdisk-match-paste-text {\r\n --textarea-bd-color: #dcdfe6;\r\n display: inline-block;\r\n resize: vertical;\r\n padding: 5px 15px;\r\n line-height: normal;\r\n box-sizing: border-box;\r\n color: #606266;\r\n border: 1px solid var(--textarea-bd-color);\r\n border-radius: 4px;\r\n transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);\r\n outline: none;\r\n margin: 0;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n appearance: none;\r\n background: none;\r\n width: 100%;\r\n height: 100%;\r\n appearance: none;\r\n resize: none;\r\n}\r\n.netdisk-match-paste-text:hover {\r\n --textarea-bd-color: #c0c4cc;\r\n}\r\n.netdisk-match-paste-text:focus {\r\n --textarea-bd-color: #3677f0;\r\n}\r\n';
const NetDiskMatchPasteText = {
show() {
let popsConfirm = NetDiskPops.confirm(
{
title: {
text: "主动识别文本",
position: "center"
},
content: {
text: (
/*html*/
`
`
),
html: true
},
btn: {
ok: {
text: "识别",
callback() {
var _a2, _b;
let inputText = ((_b = (_a2 = popsConfirm.popsElement) == null ? void 0 : _a2.querySelector(
".netdisk-match-paste-text"
)) == null ? void 0 : _b.value) || "";
if (inputText.trim() !== "") {
inputText = NetDiskRuleUtils.replaceChinese(inputText);
NetDiskWorker.postMessage({
characterMapping: [
// 删除中文
{
searchValue: /[\u4e00-\u9fa5]/g,
replaceValue: ""
}
],
textList: [inputText],
matchTextRange: NetDiskGlobalData.match.pageMatchRange.value,
// 剪贴板匹配的话直接使用全部规则来进行匹配
regular: NetDisk.$rule.matchRule,
startTime: Date.now(),
from: "PasteText"
});
}
}
}
},
class: "whitesevPopNetDiskMatchPasteText",
style: indexCSS
},
NetDiskUI.popsStyle.matchPasteTextView
);
popsConfirm.popsElement.querySelector("textarea").focus();
},
/**
* Worker匹配完毕后执行的回调函数
* @param data
*/
workerMatchEndCallBack(data) {
if (data.data.length) {
Qmsg.success(
`成功匹配${data.data.length}个,用时${Date.now() - data.startTime}ms`
);
} else {
Qmsg.error("未识别到链接");
}
}
};
const NetDiskUI = {
/** 元素对象实例 */
Alias: {
/**
* 链接弹窗的对象
*/
uiLinkAlias: void 0,
/**
* 历史匹配记录弹窗的对象
*/
historyAlias: void 0,
/**
* 设置弹窗的对象
*/
settingAlias: void 0
},
/**
* 已匹配到的网盘图标字典
*/
isMatchedNetDiskIconMap: /* @__PURE__ */ new Set(),
/**
* 是否默认禁用弹窗弹出后背景可以滚动
*/
defaultForbiddenScroll: false,
/**
* 弹窗的配置
* 规定格式
* {
* PC:{
* width: "",
* height: "",
* },
* Mobile: {
* width: "",
* height: "",
* }
* }
*/
popsStyle: NetDiskUISizeConfig,
src: {
/**
* 图标RESOURCE_ICON
* 从图标库中引入并覆盖
*/
icon: {},
/**
* 判断图标字典中是否存在该键
* @param iconKey
*/
hasIcon(iconKey) {
return Reflect.has(this.icon, iconKey);
},
/**
* 添加图标数据
* @param iconKey
* @param iconValue
*/
addIcon(iconKey, iconValue) {
if (this.hasIcon(iconKey)) {
log.warn("图标字典中已存在该icon:" + iconKey);
return false;
} else {
return Reflect.set(this.icon, iconKey, iconValue);
}
}
},
/**
* 悬浮按钮 双击打开主界面,长按打开设置(不能移动,移动就不打开,只是移动按钮
*/
suspension: NetDiskSuspension,
/**
* 主视图
*/
view: NetDiskView,
/**
* 显示直链的弹窗
*/
staticView: NetDiskLinearChainDialogView,
/**
* 需要重新输入新密码的弹窗
*/
newAccessCodeView: NetDiskNewAccessCodeView,
/**
* 网盘历史匹配到的记录弹窗
*/
netDiskHistoryMatch: NetDiskHistoryMatchView,
/**
* 主动识别文本
*/
matchPasteText: NetDiskMatchPasteText,
/**
* 设置标题的右键菜单
* @param element
*/
setGlobalRightClickMenu(element) {
NetDiskUI.view.registerContextMenu(element, void 0, [
{
text: "设置",
callback() {
log.info("打开-设置");
NetDiskGlobalSettingView.show();
}
},
{
text: "历史匹配记录",
callback() {
log.info("打开-历史匹配记录");
NetDiskUI.netDiskHistoryMatch.show();
}
},
{
text: "自定义规则",
callback() {
log.info("打开-自定义规则");
NetDiskUserRuleUI.show(false);
}
},
{
text: "网站规则",
callback() {
log.info("打开-网站规则");
WebsiteRule.show();
}
},
{
text: "字符映射",
callback() {
log.info("打开-字符映射");
CharacterMapping.show();
}
},
{
text: "主动识别文本",
callback() {
log.info("打开-主动识别文本");
NetDiskUI.matchPasteText.show();
}
}
]);
},
/**
* 设置右键菜单
* @param target
* @param selector
* @param isHistoryView 是否是历史界面的
*/
setRightClickMenu(target, selector, isHistoryView) {
let showTextList = [
{
text: "复制链接",
callback: function(event, contextMenuEvent) {
let linkElement = contextMenuEvent.target;
const { netDiskName, netDiskIndex, shareCode, accessCode } = NetDiskView.praseElementAttributeRuleInfo(linkElement);
NetDiskLinkClickMode.copy(
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
}
},
{
text: "访问链接",
callback: function(event, contextMenuEvent) {
let linkElement = contextMenuEvent.target;
const { netDiskName, netDiskIndex, shareCode, accessCode } = NetDiskView.praseElementAttributeRuleInfo(linkElement);
let url = NetDiskLinkClickModeUtils.getBlankUrl(
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
NetDiskLinkClickMode.openBlank(
url,
netDiskName,
netDiskIndex,
shareCode,
accessCode
);
}
},
{
text: "修改访问码",
callback: function(event, contextMenuEvent) {
let $link = contextMenuEvent.target;
const { netDiskName, netDiskIndex, shareCode, accessCode } = NetDiskView.praseElementAttributeRuleInfo($link);
NetDiskUI.newAccessCodeView(
this.text,
netDiskName,
netDiskIndex,
shareCode,
accessCode,
(option) => {
if (isHistoryView) {
if (option.isUpdatedMatchedDict) {
let currentTime = (/* @__PURE__ */ new Date()).getTime();
$link.closest("li").querySelector(
".netdiskrecord-update-time"
).lastChild.textContent = utils.formatTime(currentTime);
$link.setAttribute("data-accesscode", option.accessCode);
Qmsg.success(
/*html*/
`
旧: ${accessCode}
新: ${option.accessCode}
`,
{
html: true
}
);
} else {
Qmsg.error("修改失败");
}
} else {
event.target.setAttribute("data-accesscode", option.accessCode);
if (option.isUpdatedMatchedDict) {
Qmsg.success(
/*html*/
`
旧: ${accessCode}
新: ${option.accessCode}
`,
{
html: true
}
);
} else {
if (option.isFindInMatchedDict) {
Qmsg.error("修改访问码失败");
} else {
Qmsg.error(
"修改访问码失败,因为当前已匹配字典中未找到对应的访问码"
);
}
}
}
}
);
}
}
];
if (!isHistoryView) {
showTextList.push({
text: "删除当前项",
callback: function(event, contextMenuEvent) {
let $linkElement = contextMenuEvent.target;
let $box = $linkElement.closest(".netdisk-url-box");
const { netDiskName, netDiskIndex, shareCode, accessCode } = NetDiskView.praseElementAttributeRuleInfo($linkElement);
let flag = false;
NetDisk.$match.matchedInfo.forEach((netDiskItem, netDiskKeyName) => {
if (netDiskKeyName !== netDiskName) {
return;
}
netDiskItem.forEach((matchedInfo, matchedShareCode) => {
if (matchedShareCode === shareCode) {
flag = true;
netDiskItem.delete(matchedShareCode);
log.info(`删除:`, netDiskKeyName, JSON.stringify(matchedInfo));
}
});
});
NetDisk.$match.matchedInfoRuleKey.clear();
NetDisk.$match.matchedInfo.forEach((netDiskItem, netDiskKeyName) => {
if (netDiskItem.length) {
NetDisk.$match.matchedInfoRuleKey.add(netDiskKeyName);
}
});
if (flag) {
$box.remove();
} else {
Qmsg.error("发生意外情况,未在已匹配到的信息中到对应的网盘信息");
}
}
});
showTextList.push({
text: "删除所有项",
callback: function(event, contextMenuEvent) {
let $linkElement = contextMenuEvent.target;
let $boxAll = $linkElement.closest(
".netdisk-url-box-all"
);
NetDiskView.praseElementAttributeRuleInfo($linkElement);
NetDisk.$match.matchedInfo.forEach((netDiskItem, netDiskKeyName) => {
netDiskItem.clear();
});
NetDisk.$match.matchedInfoRuleKey.clear();
$boxAll.innerHTML = "";
}
});
}
NetDiskUI.view.registerContextMenu(target, selector, showTextList);
}
};
const NetDiskPops = {
/**
* 普通信息框
* @param details 配置
* @param sizeConfig 大小配置
*/
alert(details, sizeConfig) {
details = this.handleDetails(details, sizeConfig);
return __pops.alert(details);
},
/**
* 询问框
* @param details 配置
* @param sizeConfig 大小配置
*/
confirm(details, sizeConfig) {
details = this.handleDetails(details, sizeConfig);
return __pops.confirm(details);
},
/**
* 加载层
* @param details 配置
*/
loading(details) {
if (typeof details["animation"] === "undefined") {
details["animation"] = NetDiskGlobalData.pops.popsAnimation.value;
}
if (typeof details["forbiddenScroll"] === "undefined") {
details["forbiddenScroll"] = NetDiskUI.defaultForbiddenScroll;
}
return __pops.loading(details);
},
/**
* 输入框
* @param details 配置
* @param sizeConfig 大小配置
*/
prompt(details, sizeConfig) {
details = this.handleDetails(details, sizeConfig);
return __pops.prompt(details);
},
/**
* 文件夹
* @param details 配置
*/
folder(details, sizeConfig) {
details = this.handleDetails(details, sizeConfig);
details["sort"] = {
name: NetDiskGlobalData.popsFolder["pops-folder-sort-name"].value,
isDesc: NetDiskGlobalData.popsFolder["pops-folder-sort-is-desc"].value,
// @ts-ignore
callback(target, event, sortName, sortDesc) {
NetDiskGlobalData.popsFolder["pops-folder-sort-name"].value = sortName;
NetDiskGlobalData.popsFolder["pops-folder-sort-is-desc"].value = sortDesc;
}
};
return __pops.folder(details);
},
/**
* 菜单面板
* @param details 配置
*/
panel(details, sizeConfig) {
details = this.handleDetails(details, sizeConfig);
return __pops.panel(details);
},
/**
* 右键菜单
*/
rightClickMenu(details) {
details = this.handleDetails(details);
return __pops.rightClickMenu(details);
},
/**
*
* @param details
* @param sizeConfig 大小配置
*/
handleDetails(details, sizeConfig) {
details = Object.assign(
{
animation: NetDiskGlobalData.pops.popsAnimation.value,
drag: NetDiskGlobalData.pops.pcDrag.value,
dragLimit: NetDiskGlobalData.pops.pcDragLimit.value,
forbiddenScroll: NetDiskUI.defaultForbiddenScroll
},
details
);
if (sizeConfig != null) {
if (__pops.isPhone()) {
let popsWidth = typeof sizeConfig.Mobile.width === "function" ? sizeConfig.Mobile.width() : sizeConfig.Mobile.width;
let popsHeight = typeof sizeConfig.Mobile.height === "function" ? sizeConfig.Mobile.height() : sizeConfig.Mobile.height;
details.width = popsWidth;
details.height = popsHeight;
} else {
let popsWidth = typeof sizeConfig.PC.width === "function" ? sizeConfig.PC.width() : sizeConfig.PC.width;
let popsHeight = typeof sizeConfig.PC.height === "function" ? sizeConfig.PC.height() : sizeConfig.PC.height;
details.width = popsWidth;
details.height = popsHeight;
}
}
if (details.mask == null) {
details.mask = {};
}
if (typeof details.mask.enable !== "boolean") {
details.mask.enable = true;
}
if (details.mask.clickEvent == null) {
details.mask.clickEvent = {};
}
if (typeof details.mask.clickEvent.toClose !== "boolean") {
details.mask.clickEvent.toClose = NetDiskGlobalData.pops.clickMaskToCloseDialog.value;
}
if (NetDiskGlobalData.pops.popsAcrylic.value) {
let acrylicCSS = (
/*css*/
`
.pops {
--acrylic-opacity: 0.7;
--acrylic-color: rgba(232, 232, 232, var(--acrylic-opacity));
--acrylic-blur: 30px;
--acrylic-saturate: 125%;
--pops-bg-opacity: var(--acrylic-opacity);
}
.pops {
backdrop-filter: blur(var(--acrylic-blur)) saturate(var(--acrylic-saturate)) !important;
background-color: var(--acrylic-color) !important;
}
.pops[type-value=panel]{
--aside-bg-color: rgba(221, 221, 221, var(--acrylic-opacity));
--pops-bg-color: #f2f2f2;
--title-bg-color: var(--acrylic-color);
--aside-bg-color: var(--acrylic-color);
--container-item-bg-color: var(--acrylic-color);
}
`
);
if (typeof details.style === "string") {
details.style += acrylicCSS;
} else {
details.style = acrylicCSS;
}
}
details.zIndex = () => {
const deviation = 10;
let maxZIndex = utils.getMaxZIndex(deviation);
let popsMaxZIndex = __pops.config.InstanceUtils.getPopsMaxZIndex(deviation).zIndex;
let zIndex = utils.getMaxValue(99999, maxZIndex, popsMaxZIndex) + deviation;
return zIndex;
};
return details;
}
};
class RuleEditView {
constructor(option) {
__publicField(this, "option");
this.option = option;
}
/**
* 显示视图
*/
async showView() {
var _a2;
let $dialog = NetDiskPops.confirm({
title: {
text: this.option.title,
position: "center"
},
content: {
text: (
/*html*/
`
`
),
html: true
},
btn: utils.assign(
{
ok: {
callback: async () => {
await submitSaveOption();
}
}
},
this.option.btn || {},
true
),
mask: {
enable: true
},
style: (
/*css*/
`
${__pops.config.cssText.panelCSS}
.rule-form-container {
}
.rule-form-container li{
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px 20px;
gap: 10px;
}
.pops-panel-item-left-main-text{
max-width: 150px;
}
.pops-panel-item-right-text{
padding-left: 30px;
}
.pops-panel-item-right-text,
.pops-panel-item-right-main-text{
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
${((_a2 = this.option) == null ? void 0 : _a2.style) ?? ""}
`
),
width: window.innerWidth > 500 ? "500px" : "88vw",
height: window.innerHeight > 500 ? "500px" : "80vh"
});
let $form = $dialog.$shadowRoot.querySelector(
".rule-form-container"
);
$dialog.$shadowRoot.querySelector(
"input[type=submit]"
);
let $ulist = $dialog.$shadowRoot.querySelector(".rule-form-ulist");
let view = await this.option.getView(await this.option.data());
$ulist.appendChild(view);
const submitSaveOption = async () => {
let result = await this.option.onsubmit($form, await this.option.data());
if (!result.success) {
return;
}
$dialog.close();
await this.option.dialogCloseCallBack(true);
};
}
}
class RuleFilterView {
constructor(option) {
__publicField(this, "option");
this.option = option;
}
showView() {
let $alert = NetDiskPops.alert({
title: {
text: this.option.title,
position: "center"
},
content: {
text: (
/*html*/
`
`
)
},
btn: {
ok: {
text: "关闭",
type: "default"
}
},
mask: {
enable: true
},
width: window.innerWidth > 500 ? "350px" : "80vw",
height: window.innerHeight > 500 ? "300px" : "70vh",
style: (
/*css*/
`
.filter-container{
height: 100%;
display: flex;
flex-direction: column;
gap: 20px;
}
.filter-container button{
text-wrap: wrap;
padding: 8px;
height: auto;
text-align: left;
}
`
)
});
let $filterContainer = $alert.$shadowRoot.querySelector(".filter-container");
let $fragment = document.createDocumentFragment();
this.option.filterOption.forEach((filterOption) => {
let $button = document.createElement("button");
$button.innerText = filterOption.name;
let execFilterAndCloseDialog = async () => {
let allRuleInfo = await this.option.getAllRuleInfo();
allRuleInfo.forEach(async (ruleInfo) => {
let filterResult = await filterOption.filterCallBack(ruleInfo.data);
if (!filterResult) {
domUtils.hide(ruleInfo.$el, false);
} else {
domUtils.show(ruleInfo.$el, false);
}
});
if (typeof this.option.execFilterCallBack === "function") {
await this.option.execFilterCallBack();
}
$alert.close();
};
domUtils.on($button, "click", async (event) => {
utils.preventEvent(event);
if (typeof filterOption.callback === "function") {
let result = await filterOption.callback(
event,
execFilterAndCloseDialog
);
if (!result) {
return;
}
}
await execFilterAndCloseDialog();
});
$fragment.appendChild($button);
});
$filterContainer.appendChild($fragment);
}
}
class RuleView {
constructor(option) {
__publicField(this, "option");
this.option = option;
}
/**
* 显示视图
*/
async showView() {
var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
let $popsConfirm = NetDiskPops.confirm({
title: {
text: this.option.title,
position: "center"
},
content: {
text: (
/*html*/
`
`
),
html: true
},
btn: {
merge: true,
reverse: false,
position: "space-between",
ok: {
enable: ((_c = (_b = (_a2 = this.option) == null ? void 0 : _a2.bottomControls) == null ? void 0 : _b.add) == null ? void 0 : _c.enable) || true,
type: "primary",
text: "添加",
callback: async (event) => {
this.showEditView(
$popsConfirm.$shadowRoot,
false,
await this.option.getAddData()
);
}
},
close: {
enable: true,
callback(event) {
$popsConfirm.close();
}
},
cancel: {
enable: ((_f = (_e = (_d = this.option) == null ? void 0 : _d.bottomControls) == null ? void 0 : _e.filter) == null ? void 0 : _f.enable) || false,
type: "default",
text: "过滤",
callback: (details, event) => {
var _a3, _b2, _c2, _d2, _e2, _f2, _g2;
if (typeof ((_c2 = (_b2 = (_a3 = this.option) == null ? void 0 : _a3.bottomControls) == null ? void 0 : _b2.filter) == null ? void 0 : _c2.callback) === "function") {
this.option.bottomControls.filter.callback();
}
let getAllRuleElement = () => {
return Array.from(
$popsConfirm.$shadowRoot.querySelectorAll(
".rule-view-container .rule-item"
)
);
};
let $button = event.target.closest(".pops-confirm-btn").querySelector(".pops-confirm-btn-cancel span");
if (domUtils.text($button).includes("取消")) {
getAllRuleElement().forEach(($el) => {
domUtils.show($el, false);
});
domUtils.text($button, "过滤");
} else {
let ruleFilterView = new RuleFilterView({
title: ((_e2 = (_d2 = this.option.bottomControls) == null ? void 0 : _d2.filter) == null ? void 0 : _e2.title) ?? "过滤规则",
filterOption: ((_g2 = (_f2 = this.option.bottomControls) == null ? void 0 : _f2.filter) == null ? void 0 : _g2.option) || [],
execFilterCallBack() {
domUtils.text($button, "取消过滤");
},
getAllRuleInfo: () => {
return getAllRuleElement().map(($el) => {
return {
data: this.parseRuleItemElement($el).data,
$el
};
});
}
});
ruleFilterView.showView();
}
}
},
other: {
enable: ((_i = (_h = (_g = this.option) == null ? void 0 : _g.bottomControls) == null ? void 0 : _h.clear) == null ? void 0 : _i.enable) || true,
type: "xiaomi-primary",
text: `清空所有(${(await this.option.data()).length})`,
callback: (event) => {
let $askDialog = NetDiskPops.confirm({
title: {
text: "提示",
position: "center"
},
content: {
text: "确定清空所有的数据?",
html: false
},
btn: {
ok: {
enable: true,
callback: async (popsEvent) => {
var _a3, _b2, _c2;
log.success("清空所有");
if (typeof ((_c2 = (_b2 = (_a3 = this.option) == null ? void 0 : _a3.bottomControls) == null ? void 0 : _b2.clear) == null ? void 0 : _c2.callback) === "function") {
this.option.bottomControls.clear.callback();
}
let data = await this.option.data();
if (data.length) {
Qmsg.error("清理失败");
return;
} else {
Qmsg.success("清理成功");
}
await this.updateDeleteAllBtnText($popsConfirm.$shadowRoot);
this.clearContent($popsConfirm.$shadowRoot);
$askDialog.close();
}
},
cancel: {
text: "取消",
enable: true
}
},
mask: { enable: true },
width: "300px",
height: "200px"
});
}
}
},
mask: {
enable: true
},
width: window.innerWidth > 500 ? "500px" : "88vw",
height: window.innerHeight > 500 ? "500px" : "80vh",
style: (
/*css*/
`
${__pops.config.cssText.panelCSS}
.rule-item{
display: flex;
align-items: center;
line-height: normal;
font-size: 16px;
padding: 4px 4px;
gap: 6px;
}
.rule-name{
flex: 1;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.rule-controls{
display: flex;
align-items: center;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
gap: 8px;
padding: 0px 4px;
}
.rule-controls-enable{
}
.rule-controls-edit{
}
.rule-controls-delete{
}
.rule-controls-edit,
.rule-controls-delete{
width: 16px;
height: 16px;
cursor: pointer;
}
`
)
});
let allData = await this.option.data();
for (let index = 0; index < allData.length; index++) {
await this.appendRuleItemElement(
$popsConfirm.$shadowRoot,
allData[index]
);
}
}
/**
* 解析弹窗内的各个元素
*/
parseViewElement($shadowRoot) {
let $container = $shadowRoot.querySelector(
".rule-view-container"
);
let $deleteBtn = $shadowRoot.querySelector(
".pops-confirm-btn button.pops-confirm-btn-other"
);
return {
/** 容器 */
$container,
/** 左下角的清空按钮 */
$deleteBtn
};
}
/**
* 解析每一项的元素
*/
parseRuleItemElement($ruleElement) {
let $enable = $ruleElement.querySelector(
".rule-controls-enable"
);
let $enableSwitch = $enable.querySelector(".pops-panel-switch");
let $enableSwitchInput = $enable.querySelector(
".pops-panel-switch__input"
);
let $enableSwitchCore = $enable.querySelector(
".pops-panel-switch__core"
);
let $edit = $ruleElement.querySelector(".rule-controls-edit");
let $delete = $ruleElement.querySelector(
".rule-controls-delete"
);
return {
/** 启用开关 */
$enable,
/** 启用开关的container */
$enableSwitch,
/** 启用开关的input */
$enableSwitchInput,
/** 启用开关的core */
$enableSwitchCore,
/** 编辑按钮 */
$edit,
/** 删除按钮 */
$delete,
/** 存储在元素上的数据 */
data: Reflect.get($ruleElement, "data-rule")
};
}
/**
* 创建一条规则元素
*/
async createRuleItemElement(data, $shadowRoot) {
let name = await this.option.getDataItemName(data);
let $ruleItem = domUtils.createElement("div", {
className: "rule-item",
innerHTML: (
/*html*/
`
${name}
${__pops.config.iconSVG.edit}
${__pops.config.iconSVG.delete}
`
)
});
Reflect.set($ruleItem, "data-rule", data);
let switchCheckedClassName = "pops-panel-switch-is-checked";
const {
$enable,
$enableSwitch,
$enableSwitchCore,
$enableSwitchInput,
$delete,
$edit
} = this.parseRuleItemElement($ruleItem);
if (this.option.itemControls.enable.enable) {
domUtils.on($enableSwitchCore, "click", async (event) => {
let isChecked = false;
if ($enableSwitch.classList.contains(switchCheckedClassName)) {
$enableSwitch.classList.remove(switchCheckedClassName);
isChecked = false;
} else {
$enableSwitch.classList.add(switchCheckedClassName);
isChecked = true;
}
$enableSwitchInput.checked = isChecked;
await this.option.itemControls.enable.callback(data, isChecked);
});
if (await this.option.itemControls.enable.getEnable(data)) {
$enableSwitch.classList.add(switchCheckedClassName);
}
} else {
$enable.remove();
}
if (this.option.itemControls.edit.enable) {
domUtils.on($edit, "click", (event) => {
utils.preventEvent(event);
this.showEditView($shadowRoot, true, data, $ruleItem, (newData) => {
data = null;
data = newData;
});
});
} else {
$edit.remove();
}
if (this.option.itemControls.delete.enable) {
domUtils.on($delete, "click", (event) => {
utils.preventEvent(event);
let $askDialog = NetDiskPops.confirm({
title: {
text: "提示",
position: "center"
},
content: {
text: "确定删除该条数据?",
html: false
},
btn: {
ok: {
enable: true,
callback: async (popsEvent) => {
log.success("删除数据");
let flag = await this.option.itemControls.delete.deleteCallBack(
data
);
if (flag) {
Qmsg.success("成功删除该数据");
$ruleItem.remove();
await this.updateDeleteAllBtnText($shadowRoot);
$askDialog.close();
} else {
Qmsg.error("删除该数据失败");
}
}
},
cancel: {
text: "取消",
enable: true
}
},
mask: {
enable: true
},
width: "300px",
height: "200px"
});
});
} else {
$delete.remove();
}
return $ruleItem;
}
/**
* 添加一个规则元素
*/
async appendRuleItemElement($shadowRoot, data) {
const { $container } = this.parseViewElement($shadowRoot);
if (Array.isArray(data)) {
for (let index = 0; index < data.length; index++) {
const item = data[index];
$container.appendChild(
await this.createRuleItemElement(item, $shadowRoot)
);
}
} else {
$container.appendChild(
await this.createRuleItemElement(data, $shadowRoot)
);
}
await this.updateDeleteAllBtnText($shadowRoot);
}
/**
* 更新弹窗内容的元素
*/
async updateRuleContaienrElement($shadowRoot) {
this.clearContent($shadowRoot);
this.parseViewElement($shadowRoot);
let data = await this.option.data();
await this.appendRuleItemElement($shadowRoot, data);
await this.updateDeleteAllBtnText($shadowRoot);
}
/**
* 更新规则元素
*/
async updateRuleItemElement(data, $oldRuleItem, $shadowRoot) {
let $newRuleItem = await this.createRuleItemElement(data, $shadowRoot);
$oldRuleItem.after($newRuleItem);
$oldRuleItem.remove();
}
/**
* 清空内容
*/
clearContent($shadowRoot) {
const { $container } = this.parseViewElement($shadowRoot);
domUtils.html($container, "");
}
/**
* 设置删除按钮的文字
*/
setDeleteBtnText($shadowRoot, text, isHTML = false) {
const { $deleteBtn } = this.parseViewElement($shadowRoot);
if (isHTML) {
domUtils.html($deleteBtn, text);
} else {
domUtils.text($deleteBtn, text);
}
}
/**
* 更新【清空所有】的按钮的文字
*/
async updateDeleteAllBtnText($shadowRoot) {
let data = await this.option.data();
this.setDeleteBtnText($shadowRoot, `清空所有(${data.length})`);
}
/**
* 显示编辑视图
* @param isEdit 是否是编辑状态
*/
showEditView($parentShadowRoot, isEdit, editData, $editRuleItemElement, updateDataCallBack) {
let dialogCloseCallBack = async (isSubmit) => {
if (isSubmit) ;
else {
if (!isEdit) {
await this.option.deleteData(editData);
}
if (typeof updateDataCallBack === "function") {
let newData = await this.option.getData(editData);
updateDataCallBack(newData);
}
}
};
let editView = new RuleEditView({
title: isEdit ? "编辑" : "添加",
data: () => {
return editData;
},
dialogCloseCallBack,
getView: async (data) => {
return await this.option.itemControls.edit.getView(data, isEdit);
},
btn: {
ok: {
enable: true,
text: isEdit ? "修改" : "添加"
},
cancel: {
callback: async (detail, event) => {
detail.close();
await dialogCloseCallBack(false);
}
},
close: {
callback: async (detail, event) => {
detail.close();
await dialogCloseCallBack(false);
}
}
},
onsubmit: async ($form, data) => {
let result = await this.option.itemControls.edit.onsubmit(
$form,
isEdit,
data
);
if (result.success) {
if (isEdit) {
Qmsg.success("修改成功");
await this.updateRuleItemElement(
result.data,
$editRuleItemElement,
$parentShadowRoot
);
} else {
await this.appendRuleItemElement($parentShadowRoot, result.data);
}
} else {
if (isEdit) {
Qmsg.error("修改失败");
}
}
return result;
},
style: this.option.itemControls.edit.style
});
editView.showView();
}
}
const UIButton = function(text, description, buttonText, buttonIcon, buttonIsRightIcon, buttonIconIsLoading, buttonType, clickCallBack, afterAddToUListCallBack) {
let result = {
text,
type: "button",
description,
attributes: {},
props: {},
buttonIcon,
buttonIsRightIcon,
buttonIconIsLoading,
buttonType,
buttonText,
callback(event) {
if (typeof clickCallBack === "function") {
clickCallBack(event);
}
},
afterAddToUListCallBack
};
return result;
};
const panelSettingCSS = "/* 容器 */\r\n.website-rule-container {\r\n}\r\n/* 每一条规则 */\r\n.website-rule-item {\r\n display: flex;\r\n align-items: center;\r\n line-height: normal;\r\n font-size: 16px;\r\n padding: 4px 4px;\r\n gap: 6px;\r\n}\r\n/* 规则名 */\r\n.website-rule-item .website-rule-name {\r\n flex: 1;\r\n white-space: nowrap;\r\n text-overflow: ellipsis;\r\n overflow: hidden;\r\n}\r\n/* 操作按钮 */\r\n.website-rule-item .website-controls {\r\n display: flex;\r\n align-items: center;\r\n text-overflow: ellipsis;\r\n overflow: hidden;\r\n white-space: nowrap;\r\n gap: 8px;\r\n padding: 0px 4px;\r\n}\r\n/* 编辑和删除按钮 */\r\n.website-rule-item .website-rule-edit,\r\n.website-rule-item .website-rule-delete {\r\n width: 16px;\r\n height: 16px;\r\n cursor: pointer;\r\n}\r\n/* 启用按钮 */\r\n.website-rule-item .website-rule-enable {\r\n}\r\n/* 编辑按钮 */\r\n.website-rule-item .website-rule-edit {\r\n}\r\n/* 删除按钮 */\r\n.website-rule-item .website-rule-delete {\r\n}\r\n";
function deepCopy(obj) {
if (obj === null || typeof obj !== "object") {
return obj;
}
let copy = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCopy(obj[key]);
}
}
return copy;
}
const WebsiteRule = {
$data: {
STORAGE_KEY: "rule",
/** 是否正在显示编辑视图 */
isShowEditView: false
},
init() {
},
/**
* 获取默认数据
*/
getTemplateData() {
return {
uuid: utils.generateUUID(),
enable: true,
name: "",
url: "",
data: {}
};
},
/**
* 显示视图
*/
show() {
const that = this;
let popsPanelContentUtils = __pops.config.panelHandleContentUtils();
let addData = this.getTemplateData();
function generateStorageApi(data) {
return {
get(key, defaultValue) {
return data[key] ?? defaultValue;
},
set(key, value) {
data[key] = value;
}
};
}
function generatePanelStorageApi(uuid) {
return {
get(key, defaultValue) {
let currentRule = WebsiteRule.getRule(uuid) ?? addData;
let panelValue = PopsPanel.getValue(key, defaultValue);
return (currentRule && Reflect.get(currentRule.data, key)) ?? panelValue;
},
set(key, value) {
let currentRule = WebsiteRule.getRule(uuid) ?? addData;
Reflect.set(currentRule.data, key, value);
WebsiteRule.updateRule(currentRule);
}
};
}
let ruleView = new RuleView({
title: "网站规则",
data: () => {
return this.getAllRule();
},
getAddData: () => {
return addData;
},
getDataItemName: (data) => {
return data["name"] ?? data.url;
},
updateData: (data) => {
return this.updateRule(data);
},
deleteData: (data) => {
that.$data.isShowEditView = false;
return this.deleteRule(data.uuid);
},
getData: (data) => {
let allData = this.getAllRule();
let findValue = allData.find((item) => item.uuid === data.uuid);
return findValue ?? data;
},
itemControls: {
enable: {
enable: true,
getEnable(data) {
return data.enable;
},
callback: (data, enable) => {
data.enable = enable;
this.updateRule(data);
}
},
edit: {
enable: true,
getView: (data, isEdit) => {
that.$data.isShowEditView = true;
let $fragment = document.createDocumentFragment();
if (!isEdit) {
data = addData;
}
let enable_template = UISwitch("启用", "enable", true);
Reflect.set(
enable_template.props,
PROPS_STORAGE_API,
generateStorageApi(data)
);
let $enable = popsPanelContentUtils.createSectionContainerItem_switch(
enable_template
);
let name_template = UIInput(
"规则名称",
"name",
"",
"",
void 0,
"必填"
);
Reflect.set(
name_template.props,
PROPS_STORAGE_API,
generateStorageApi(data)
);
let $name = popsPanelContentUtils.createSectionContainerItem_input(
name_template
);
let url_template = UIInput(
"匹配网址",
"url",
"",
"",
void 0,
"必填,可正则"
);
Reflect.set(
url_template.props,
PROPS_STORAGE_API,
generateStorageApi(data)
);
let $data_url = popsPanelContentUtils.createSectionContainerItem_input(
url_template
);
let coverSetting_template = UIButton(
"覆盖设置",
"",
"自定义",
void 0,
false,
false,
"primary",
() => {
let originPanelContentConfig = PopsPanel.getPanelContentConfig().concat(
NetDiskRule.getRulePanelContent()
);
let newPanelContentConfig = deepCopy(originPanelContentConfig);
function iterativeTraversal(configList) {
configList.forEach((configItem) => {
if (typeof (configItem == null ? void 0 : configItem.props) === "object" && Reflect.has(configItem.props, PROPS_STORAGE_API)) {
let panelStorageApi = generatePanelStorageApi(data.uuid);
Reflect.set(
configItem.props,
PROPS_STORAGE_API,
panelStorageApi
);
}
let childForms = configItem.forms;
if (childForms && Array.isArray(childForms)) {
iterativeTraversal(childForms);
}
});
}
for (let index = 0; index < newPanelContentConfig.length; index++) {
let leftContentConfigItem = newPanelContentConfig[index];
if (!leftContentConfigItem.forms) {
continue;
}
if (typeof leftContentConfigItem.afterRender === "function" && (leftContentConfigItem == null ? void 0 : leftContentConfigItem.id.toString().startsWith("netdisk-panel-config-"))) {
leftContentConfigItem.afterRender = (__data) => {
let ruleKey = __data.asideConfig.attributes["data-key"];
let enableKey = NetDiskRuleDataKEY.function.enable(ruleKey);
__data.$asideLiElement.setAttribute(
"data-function-enable",
WebsiteRule.getRuleDataValue(data.uuid, enableKey, true)
);
};
}
if (typeof leftContentConfigItem.attributes === "object" && leftContentConfigItem.forms != null && ATTRIBUTE_KEY in leftContentConfigItem.attributes) {
let ruleKey = leftContentConfigItem.attributes[ATTRIBUTE_KEY];
let custom_accessCode_enable_template = UISwitch(
"启用",
WebsiteRuleDataKey.features.customAccessCodeEnable(
ruleKey
),
false,
void 0,
"启用后将允许执行下面的功能",
void 0
);
Reflect.set(
custom_accessCode_enable_template.props,
PROPS_STORAGE_API,
generatePanelStorageApi(data.uuid)
);
let custom_accessCode_template = UIInput(
"自定义访问码",
WebsiteRuleDataKey.features.customAccessCode(ruleKey),
"",
"让获取的到的链接的访问码都为自定义的访问码",
void 0,
"请输入自定义访问码",
false,
false
);
Reflect.set(
custom_accessCode_template.props,
PROPS_STORAGE_API,
generatePanelStorageApi(data.uuid)
);
let custom_accessCode_container = {
text: "额外功能",
type: "forms",
forms: [
custom_accessCode_enable_template,
custom_accessCode_template
]
};
if (leftContentConfigItem.forms.length) {
leftContentConfigItem.forms.splice(
1,
0,
custom_accessCode_container
);
} else {
leftContentConfigItem.forms.push(
custom_accessCode_container
);
}
}
let rightContentConfigList = leftContentConfigItem.forms;
if (rightContentConfigList && Array.isArray(rightContentConfigList)) {
iterativeTraversal(rightContentConfigList);
}
}
NetDiskPops.panel(
{
title: {
text: `覆盖设置`,
position: "center"
},
content: newPanelContentConfig,
btn: {
close: {
enable: true,
callback(event) {
event.close();
}
}
},
mask: {
clickCallBack(originalRun) {
originalRun();
}
},
only: false,
class: "whitesevPopSetting",
style: (
/*css*/
`
${panelIndexCSS}
${panelSettingCSS}
/* 隐藏顶部的图标 */
.netdisk-custom-rule-edit,
.netdisk-custom-rule-delete,
/* 隐藏快捷键设置菜单,因为这个是全局唯一的 */
.netdisk-panel-forms-shortcut-keys-deepMenu{
display: none !important;
}
`
)
},
NetDiskUI.popsStyle.settingView
);
},
void 0
);
let $coverSetting_template = popsPanelContentUtils.createSectionContainerItem_button(
coverSetting_template
);
$fragment.appendChild($enable);
$fragment.appendChild($name);
$fragment.appendChild($data_url);
$fragment.appendChild($coverSetting_template);
return $fragment;
},
onsubmit: ($form, isEdit, editData) => {
let $ulist_li = $form.querySelectorAll(
".rule-form-ulist > li"
);
let data = addData;
if (isEdit) {
data.uuid = editData.uuid;
}
$ulist_li.forEach(($li) => {
let formConfig = Reflect.get($li, "__formConfig__");
let attrs = Reflect.get(formConfig, "attributes");
let storageApi = Reflect.get($li, PROPS_STORAGE_API);
let key = Reflect.get(attrs, ATTRIBUTE_KEY);
if (key == null) {
return;
}
let defaultValue = Reflect.get(attrs, ATTRIBUTE_DEFAULT_VALUE);
let value = storageApi.get(key, defaultValue);
if (Reflect.has(data, key)) {
Reflect.set(data, key, value);
} else if (Reflect.has(data.data, key)) {
Reflect.set(data.data, key, value);
} else {
log.error(`${key}不在数据中`);
}
});
if (data.name == null || data.name.trim() === "") {
Qmsg.error("规则名称不能为空");
return {
success: false,
data
};
}
if (data.url.trim() === "") {
Qmsg.error("匹配网址不能为空");
return {
success: false,
data
};
}
if (isEdit) {
return {
success: this.updateRule(data),
data
};
} else {
return {
success: this.addRule(data),
data
};
}
}
},
delete: {
enable: true,
deleteCallBack: (data) => {
return this.deleteRule(data.uuid);
}
}
},
bottomControls: {
filter: {
enable: true,
title: "过滤规则",
option: [
{
name: "过滤【已启用】的规则",
filterCallBack(data) {
return data.enable;
}
},
{
name: "过滤【未启用】的规则",
filterCallBack(data) {
return !data.enable;
}
},
{
name: "过滤【在当前网址生效】的规则",
filterCallBack(data) {
let matchRegExp = new RegExp(data.url, "ig");
return Boolean(window.location.href.match(matchRegExp));
}
}
]
}
}
});
ruleView.showView();
},
/**
* 添加单个规则
*/
addRule(rule) {
let allRule = this.getAllRule();
allRule.push(rule);
WebsiteRuleStorage.set(this.$data.STORAGE_KEY, allRule);
return true;
},
/**
* 根据uuid获取单个规则的数据
* @param uuid
*/
getRule(uuid) {
return this.getAllRule().find((rule) => rule.uuid === uuid);
},
/**
* 根据uuid获取单个规则的存储数据
* @param uuid
*/
getRuleData(uuid) {
var _a2;
if (typeof uuid === "string") {
return (_a2 = this.getRule(uuid)) == null ? void 0 : _a2.data;
} else {
return uuid.data;
}
},
/**
* 根据uuid获取单个规则的存储数据的值
* @param uuid
* @param key 键
* @param defaultValue 默认值
*/
getRuleDataValue(uuid, key, defaultValue) {
let ruleData = this.getRuleData(uuid);
return (ruleData && Reflect.get(ruleData, key)) ?? defaultValue;
},
/**
* 更新单个规则
* @param rule
*/
updateRule(rule) {
let allRule = this.getAllRule();
let flag = false;
for (let index = 0; index < allRule.length; index++) {
const localRule = allRule[index];
if (localRule.uuid === rule.uuid) {
allRule[index] = rule;
flag = true;
break;
}
}
WebsiteRuleStorage.set(this.$data.STORAGE_KEY, allRule);
return flag;
},
/**
* 更新单个规则的值
*/
updateRuleValue(uuid, key, value) {
let allRule = this.getAllRule();
for (let index = 0; index < allRule.length; index++) {
const localRule = allRule[index];
if (localRule.uuid === uuid) {
Reflect.set(localRule, key, value);
break;
}
}
WebsiteRuleStorage.set(this.$data.STORAGE_KEY, allRule);
},
/**
* 删除单个规则
* @param uuid 整个规则或者规则的uuid
*/
deleteRule(uuid) {
let allRule = this.getAllRule();
let flag = false;
let needDeleteRuleUUID = typeof uuid === "string" ? uuid : uuid.uuid;
for (let index = 0; index < allRule.length; index++) {
const localRule = allRule[index];
if (localRule.uuid === needDeleteRuleUUID) {
allRule.splice(index, 1);
flag = true;
break;
}
}
WebsiteRuleStorage.set(this.$data.STORAGE_KEY, allRule);
return flag;
},
/**
* 清空所有规则
*/
deleteAllRule() {
WebsiteRuleStorage.delete(this.$data.STORAGE_KEY);
},
/**
* 获取所有规则
*/
getAllRule() {
let allRule = WebsiteRuleStorage.get(
this.$data.STORAGE_KEY,
[]
);
return allRule;
},
/**
* 根据url获取匹配的规则
*
* 注意:不会处理是否启用的情况
* @param url 需要匹配的url
*/
getUrlMatchedRule(url = window.location.href) {
let allRule = this.getAllRule();
return allRule.filter((rule) => {
let matchRegExp = new RegExp(rule.url, "ig");
if (url.match(matchRegExp)) {
return true;
} else {
return false;
}
});
}
};
const WebsiteRuleStorage = new StorageUtils("websiteRule");
const WebsiteProxyGlobalValue = (key, value, defaultValue) => {
if (WebsiteRule.$data.isShowEditView) {
return value;
}
let matchedUrlRuleList = WebsiteRule.getUrlMatchedRule();
let findValue = matchedUrlRuleList.find((item) => {
let data = WebsiteRule.getRuleData(item);
return Reflect.has(data, key);
});
if (findValue) {
return Reflect.get(WebsiteRule.getRuleData(findValue), key);
} else {
return value;
}
};
const GenerateProxyData = function(key, defaultValue, proxyValueCallBack) {
return {
/** 键名 */
KEY: key,
/** 默认值 */
default: defaultValue,
/** 获取值 */
get value() {
let currentValue = _GM_getValue(key, defaultValue);
if (typeof proxyValueCallBack === "function") {
return proxyValueCallBack(key, currentValue, defaultValue);
}
return currentValue;
},
/** 设置值 */
set value(newValue) {
_GM_setValue(key, newValue);
}
};
};
const GeneratePanelData = function(key, defaultValue) {
return GenerateProxyData(key, defaultValue, WebsiteProxyGlobalValue);
};
const NetDiskGlobalData = {
/** Toast */
toast: {
/** 位置 */
position: GeneratePanelData("qmsg-config-position", "top"),
/** 同时最多显示的数量 */
maxnums: GeneratePanelData("qmsg-config-maxnums", 3),
/** 逆序弹出 */
showreverse: GeneratePanelData("qmsg-config-showreverse", true)
},
/** 弹窗 */
pops: {
/** 动画 */
popsAnimation: GeneratePanelData("popsAnimation", "pops-anim-fadein-zoom"),
/** 点击弹窗遮罩层是否可以关闭弹窗 */
clickMaskToCloseDialog: GeneratePanelData("clickMaskToCloseDialog", true),
/** 窗口拖拽 */
pcDrag: GeneratePanelData("pcDrag", true),
/** 限制拖拽距离 */
pcDragLimit: GeneratePanelData("pcDragLimit", true),
/** 亚克力效果 */
popsAcrylic: GeneratePanelData("popsAcrylic", false)
},
/** 文件弹窗 */
popsFolder: {
/** 排序名 */
"pops-folder-sort-name": GeneratePanelData(
"pops-folder-sort-name",
"fileName"
),
/** 排序规则 */
"pops-folder-sort-is-desc": GeneratePanelData(
"pops-folder-sort-is-desc",
false
)
},
/** 小图标导航 */
smallIconNavgiator: {
/** 点击定位分享码 */
"pops-netdisk-icon-click-event-find-sharecode": GeneratePanelData(
"pops-netdisk-icon-click-event-find-sharecode",
true
),
/** 选中分享码 */
"pops-netdisk-icon-click-event-find-sharecode-with-select": GeneratePanelData(
"pops-netdisk-icon-click-event-find-sharecode-with-select",
true
),
/** 循环定位 */
"pops-netdisk-icon-click-event-loop-find-sharecode": GeneratePanelData(
"pops-netdisk-icon-click-event-loop-find-sharecode",
true
)
},
/** 悬浮按钮 */
suspension: {
/** 大小 */
size: GeneratePanelData("size", 50),
/** 透明度 */
opacity: GeneratePanelData("opacity", 1),
/** 背景轮播时间 */
"randbg-time": GeneratePanelData("randbg-time", 1500),
/** 背景显示时间 */
"randbg-show-time": GeneratePanelData("randbg-show-time", 1200),
/** 吸附边缘 */
"suspended-button-adsorption-edge": GeneratePanelData(
"suspended-button-adsorption-edge",
false
)
},
/** 小窗模式 */
smallWindow: {
/** 宽度 */
"netdisk-ui-small-window-width": GeneratePanelData(
"netdisk-ui-small-window-width",
250
),
/** 高度 */
"netdisk-ui-small-window-max-height": GeneratePanelData(
"netdisk-ui-small-window-max-height",
200
)
},
/** 历史匹配记录 */
historyMatch: {
/** 保存匹配记录 */
saveMatchNetDisk: GeneratePanelData("saveMatchNetDisk", false),
/** 排序规则 */
"netdisk-history-match-ordering-rule": GeneratePanelData(
"netdisk-history-match-ordering-rule",
"按 更新时间 - 降序"
),
/** 合并相同链接 */
"netdisk-history-match-merge-same-link": GeneratePanelData(
"netdisk-history-match-merge-same-link",
true
)
},
/** 匹配设置 */
match: {
/** 匹配类型 */
pageMatchRange: GeneratePanelData("pageMatchRange", [
"innerText",
"innerHTML"
]),
/** 深入ShadowRoot获取匹配文本 */
depthQueryWithShadowRoot: GeneratePanelData(
"depthQueryWithShadowRoot",
false
),
/** 匹配剪贴板 */
readClipboard: GeneratePanelData("readClipboard", false),
/** 匹配当前URL */
allowMatchLocationHref: GeneratePanelData("allowMatchLocationHref", true),
/** 匹配input标签的内容 */
toBeMatchedWithInputElementValue: GeneratePanelData(
"to-be-matched-inputElementValue",
false
),
/** 匹配textarea标签的内容 */
toBeMatchedTextAreaElementValue: GeneratePanelData(
"to-be-matched-textAreaElementValue",
false
),
/** 匹配间隔 */
delaytime: GeneratePanelData("delaytime", 0.8),
/** 添加元素时进行匹配 */
isAddedNodesToMatch: GeneratePanelData("isAddedNodesToMatch", false),
/** 观察器:childList */
"mutationObserver-childList": GeneratePanelData(
"mutationObserver-childList",
true
),
/** 观察器:characterData */
"mutationObserver-characterData": GeneratePanelData(
"mutationObserver-characterData",
true
),
/** 观察器:subtree */
"mutationObserver-subtree": GeneratePanelData(
"mutationObserver-subtree",
true
)
},
/** 功能 */
features: {
/** 匹配模式 */
"netdisk-match-mode": GeneratePanelData(
"netdisk-match-mode",
"MutationObserver"
),
/** 行为模式 */
"netdisk-behavior-mode": GeneratePanelData(
"netdisk-behavior-mode",
"suspension_smallwindow"
),
/** 自动输入访问码 */
autoFillAccessCode: GeneratePanelData("autoFillAccessCode", true)
},
/** 分享码相关 */
shareCode: {
/** 相同系数 */
excludeIdenticalSharedCodesCoefficient: GeneratePanelData(
"excludeIdenticalSharedCodesCoefficient",
1
),
/** 排除分享码 */
excludeIdenticalSharedCodes: GeneratePanelData(
"excludeIdenticalSharedCodes",
false
)
},
/** 访问码 */
accessCode: {
/** 允许查询历史匹配记录 */
allowQueryHistoryMatchingAccessCode: GeneratePanelData(
"allowQueryHistoryMatchingAccessCode",
true
)
}
};
const _SCRIPT_NAME_ = "网盘链接识别";
const isDebug = false;
const utils = Utils.noConflict();
const domUtils = DOMUtils.noConflict();
const __pops = pops;
const Cryptojs = CryptoJS ?? window.CryptoJS ?? _unsafeWindow.CryptoJS;
const __DataPaging = (
// @ts-ignore
DataPaging ?? window.DataPaging ?? _unsafeWindow.DataPaging
);
const log = new utils.Log(
_GM_info,
_unsafeWindow.console || _monkeyWindow.console
);
const SCRIPT_NAME = ((_a = _GM_info == null ? void 0 : _GM_info.script) == null ? void 0 : _a.name) || _SCRIPT_NAME_;
const AnyTouch = pops.config.Utils.AnyTouch();
log.config({
debug: isDebug,
logMaxCount: 1e3,
autoClearConsole: true,
tag: true
});
Qmsg.config(
Object.defineProperties(
{
html: true,
autoClose: true,
showClose: false
},
{
position: {
get() {
return NetDiskGlobalData.toast.position.value;
}
},
maxNums: {
get() {
return NetDiskGlobalData.toast.maxnums.value;
}
},
showReverse: {
get() {
return NetDiskGlobalData.toast.showreverse.value;
}
},
zIndex: {
get() {
let maxZIndex = Utils.getMaxZIndex(10);
let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex(10).zIndex;
return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100;
}
}
}
)
);
const GM_Menu = new utils.GM_Menu({
GM_getValue: _GM_getValue,
GM_setValue: _GM_setValue,
GM_registerMenuCommand: _GM_registerMenuCommand,
GM_unregisterMenuCommand: _GM_unregisterMenuCommand
});
const httpx = new utils.Httpx(_GM_xmlhttpRequest);
httpx.interceptors.request.use((data) => {
HttpxCookieManager.handle(data);
return data;
});
httpx.interceptors.response.use(void 0, (data) => {
log.error("拦截器-请求错误", data);
if (data.type === "onabort") {
Qmsg.warning("请求取消");
} else if (data.type === "onerror") {
Qmsg.error("请求异常");
} else if (data.type === "ontimeout") {
Qmsg.error("请求超时");
} else {
Qmsg.error("其它错误");
}
return data;
});
httpx.config({
logDetails: isDebug,
headers: {
"User-Agent": utils.getRandomPCUA()
}
});
({
Object: {
defineProperty: _unsafeWindow.Object.defineProperty
},
Function: {
apply: _unsafeWindow.Function.prototype.apply,
call: _unsafeWindow.Function.prototype.call
},
Element: {
appendChild: _unsafeWindow.Element.prototype.appendChild
},
setTimeout: _unsafeWindow.setTimeout
});
utils.addStyle.bind(utils);
document.querySelector.bind(document);
document.querySelectorAll.bind(document);
const UIButtonShortCut = function(text, description, key, defaultValue, defaultButtonText, buttonType = "default", shortCut) {
let __defaultButtonText = defaultButtonText;
let getButtonText = () => {
return shortCut.getShowText(key, __defaultButtonText);
};
let result = UIButton(
text,
description,
getButtonText,
"keyboard",
false,
false,
buttonType,
async (event) => {
var _a2;
let $click = event.target;
let $btn = (_a2 = $click.closest(".pops-panel-button")) == null ? void 0 : _a2.querySelector("span");
if (shortCut.isWaitPress) {
Qmsg.warning("请先执行当前的录入操作");
return;
}
if (shortCut.hasOptionValue(key)) {
shortCut.emptyOption(key);
Qmsg.success("清空快捷键");
} else {
let loadingQmsg = Qmsg.loading("请按下快捷键...", {
showClose: true
});
let {
status,
option,
key: isUsedKey
} = await shortCut.enterShortcutKeys(key);
loadingQmsg.close();
if (status) {
log.success("成功录入快捷键", option);
Qmsg.success("成功录入");
} else {
Qmsg.error(
`快捷键 ${shortCut.translateKeyboardValueToButtonText(
option
)} 已被 ${isUsedKey} 占用`
);
}
}
$btn.innerHTML = getButtonText();
}
);
result.attributes = {};
Reflect.set(result.attributes, ATTRIBUTE_INIT, () => {
return false;
});
return result;
};
class ShortCut {
constructor(key) {
/** 存储的键 */
__publicField(this, "key", "short-cut");
/** 是否存在等待按下的按键 */
__publicField(this, "isWaitPress", false);
if (typeof key === "string") {
this.key = key;
}
}
/**
* 初始化配置默认值
*/
initConfig(key, option) {
if (this.hasOption(key)) ;
else {
this.setOption(key, option);
}
}
/** 获取存储的键 */
getStorageKey() {
return this.key;
}
/**
* 获取本地存储的所有值
*/
getLocalAllOptions() {
return _GM_getValue(this.key, []);
}
/**
* 判断是否存在该配置
* @param key 键
*/
hasOption(key) {
let localOptions = this.getLocalAllOptions();
let findOption = localOptions.find((item) => item.key === key);
return !!findOption;
}
/**
* 判断是否存在该配置的value值
* @param key 键
*/
hasOptionValue(key) {
if (this.hasOption(key)) {
let option = this.getOption(key);
return !((option == null ? void 0 : option.value) == null);
} else {
return false;
}
}
/**
* 获取配置
* @param key 键
* @param defaultValue 默认值
*/
getOption(key, defaultValue) {
let localOptions = this.getLocalAllOptions();
let findOption = localOptions.find((item) => item.key === key);
return findOption ?? defaultValue;
}
/**
* 设置配置
* @param key 键
* @param value 配置
*/
setOption(key, value) {
let localOptions = this.getLocalAllOptions();
let findIndex = localOptions.findIndex((item) => item.key === key);
if (findIndex == -1) {
localOptions.push({
key,
value
});
} else {
Reflect.set(localOptions[findIndex], "value", value);
}
_GM_setValue(this.key, localOptions);
}
/**
* 清空当前已有配置录入的值
* @param key
*/
emptyOption(key) {
let result = false;
let localOptions = this.getLocalAllOptions();
let findIndex = localOptions.findIndex((item) => item.key === key);
if (findIndex !== -1) {
localOptions[findIndex].value = null;
result = true;
}
_GM_setValue(this.key, localOptions);
return result;
}
/**
* 删除配置
* @param key 键
*/
deleteOption(key) {
let result = false;
let localValue = this.getLocalAllOptions();
let findValueIndex = localValue.findIndex((item) => item.key === key);
if (findValueIndex !== -1) {
localValue.splice(findValueIndex, 1);
result = true;
}
_GM_setValue(this.key, localValue);
return result;
}
/**
* 把配置的快捷键转成文字
* @param keyboardValue
* @returns
*/
translateKeyboardValueToButtonText(keyboardValue) {
let result = "";
keyboardValue.ohterCodeList.forEach((ohterCodeKey) => {
result += utils.stringTitleToUpperCase(ohterCodeKey, true) + " + ";
});
result += utils.stringTitleToUpperCase(keyboardValue.keyName);
return result;
}
/**
* 获取快捷键显示的文字
* @param key 本地存储的快捷键键名
* @param defaultShowText 默认显示的文字
*/
getShowText(key, defaultShowText) {
if (this.hasOption(key)) {
let localOption = this.getOption(key);
if (localOption.value == null) {
return defaultShowText;
} else {
return this.translateKeyboardValueToButtonText(localOption.value);
}
} else {
return defaultShowText;
}
}
/**
* 录入快捷键
* @param key 本地存储的快捷键键名
*/
async enterShortcutKeys(key) {
return new Promise((resolve) => {
this.isWaitPress = true;
let keyboardListener = domUtils.listenKeyboard(
window,
"keyup",
(keyName, keyValue, ohterCodeList) => {
const currentOption = {
keyName,
keyValue,
ohterCodeList
};
const shortcutJSONString = JSON.stringify(currentOption);
const allOptions = this.getLocalAllOptions();
for (let index = 0; index < allOptions.length; index++) {
let localValue = allOptions[index];
if (localValue.key === key) {
continue;
}
const localShortCutJSONString = JSON.stringify(localValue.value);
let isUsedByOtherOption = false;
if (localValue.value != null && shortcutJSONString === localShortCutJSONString) {
isUsedByOtherOption = true;
}
if (isUsedByOtherOption) {
this.isWaitPress = false;
keyboardListener.removeListen();
resolve({
status: false,
key: localValue.key,
option: currentOption
});
return;
}
}
this.setOption(key, currentOption);
this.isWaitPress = false;
keyboardListener.removeListen();
resolve({
status: true,
key,
option: currentOption
});
}
);
});
}
/**
* 初始化全局键盘监听
* @param shortCutOption 快捷键配置 一般是{ "键名": { callback: ()=>{}}},键名是本地存储的自定义快捷键的键名
*/
initGlobalKeyboardListener(shortCutOption) {
let localOptions = this.getLocalAllOptions();
if (!localOptions.length) {
log.warn("没有设置快捷键");
return;
}
let that = this;
function setListenKeyboard($ele, option) {
domUtils.listenKeyboard(
$ele,
"keydown",
(keyName, keyValue, ohterCodeList) => {
if (that.isWaitPress) {
return;
}
localOptions = that.getLocalAllOptions();
let findShortcutIndex = localOptions.findIndex((item) => {
let option2 = item.value;
let tempOption = {
keyName,
keyValue,
ohterCodeList
};
if (JSON.stringify(option2) === JSON.stringify(tempOption)) {
return item;
}
});
if (findShortcutIndex != -1) {
let findShortcut = localOptions[findShortcutIndex];
log.info("调用快捷键", findShortcut);
if (findShortcut.key in option) {
option[findShortcut.key].callback();
}
}
}
);
}
let WindowShortCutOption = {};
let ElementShortCutOption = {};
Object.keys(shortCutOption).forEach((localKey) => {
let option = shortCutOption[localKey];
if (option.target == null || typeof option.target === "string" && option.target === "") {
option.target = "window";
}
if (option.target === "window") {
Reflect.set(WindowShortCutOption, localKey, option);
} else {
Reflect.set(ElementShortCutOption, localKey, option);
}
});
setListenKeyboard(window, WindowShortCutOption);
domUtils.ready(() => {
Object.keys(ElementShortCutOption).forEach(async (localKey) => {
let option = ElementShortCutOption[localKey];
if (typeof option.target === "string") {
utils.waitNode(option.target, 1e4).then(($ele) => {
if (!$ele) {
return;
}
let __option = {};
Reflect.set(__option, localKey, option);
setListenKeyboard($ele, __option);
});
} else if (typeof option.target === "function") {
let target = await option.target();
if (target == null) {
return;
}
let __option = {};
Reflect.set(__option, localKey, option);
setListenKeyboard(target, __option);
} else {
let __option = {};
Reflect.set(__option, localKey, option);
setListenKeyboard(option.target, __option);
}
});
});
}
}
const NetDiskShortcut = {
shortCut: new ShortCut("GM_shortcut"),
init() {
this.shortCut.initGlobalKeyboardListener(this.getShortCutMap());
},
getShortCutMap() {
return {
"netdisk-keyboard-open-setting": {
target: "window",
callback: () => {
log.info("快捷键 ==> 【打开】⚙ 设置");
NetDiskGlobalSettingView.show();
}
},
"netdisk-keyboard-open-history-matching-records": {
target: "window",
callback: () => {
log.info("快捷键 ==> 【打开】⚙ 历史匹配记录");
NetDiskUI.netDiskHistoryMatch.show();
}
},
"netdisk-keyboard-open-user-rule": {
target: "window",
callback: () => {
log.info("快捷键 ==> 【打开】⚙ 用户自定义规则");
NetDiskUserRuleUI.show(false);
}
},
"netdisk-keyboard-open-proactively-recognize-text": {
target: "window",
callback: () => {
log.info("快捷键 ==> 【打开】⚙ 主动识别文本");
NetDiskUI.matchPasteText.show();
}
},
"netdisk-keyboard-performPageTextMatchingManually": {
target: "window",
callback() {
log.info("快捷键 ==> 执行文本匹配");
NetDiskWorker.dispatchMonitorDOMChange = true;
}
},
"netdisk-keyboard-character-mapping": {
target: "window",
callback() {
log.info("快捷键 ==> 【打开】⚙ 字符映射");
CharacterMapping.show();
}
}
};
}
};
const UISelectMultiple = function(text, key, defaultValue, data, callback, description, placeholder = "请至少选择一个选项", selectConfirmDialogDetails) {
let selectData = [];
if (typeof data === "function") {
selectData = data();
} else {
selectData = data;
}
let result = {
text,
type: "select-multiple",
description,
placeholder,
attributes: {},
props: {},
getValue() {
return this.props[PROPS_STORAGE_API].get(key, defaultValue);
},
selectConfirmDialogDetails,
callback(selectInfo) {
let value = [];
selectInfo.forEach((selectedInfo) => {
value.push(selectedInfo.value);
});
this.props[PROPS_STORAGE_API].set(key, value);
log.info(`多选-选择:`, value);
},
data: selectData
};
Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
Reflect.set(result.props, PROPS_STORAGE_API, {
get(key2, defaultValue2) {
return _GM_getValue(key2, defaultValue2);
},
set(key2, value) {
_GM_setValue(key2, value);
}
});
return result;
};
const PanelUI_allSetting = {
id: "netdisk-panel-config-all-setting",
title: "总设置",
isDefault: true,
forms: [
{
type: "forms",
text: "",
forms: [
{
type: "deepMenu",
text: "Toast",
forms: [
{
type: "forms",
text: "",
className: "netdisk-panel-forms-toast",
forms: [
UISelect(
"位置",
NetDiskGlobalData.toast.position.KEY,
NetDiskGlobalData.toast.position.default,
[
{
value: "topleft",
text: "左上角"
},
{
value: "top",
text: "顶部"
},
{
value: "topright",
text: "右上角"
},
{
value: "left",
text: "左边"
},
{
value: "center",
text: "中间"
},
{
value: "right",
text: "右边"
},
{
value: "bottomleft",
text: "左下角"
},
{
value: "bottom",
text: "底部"
},
{
value: "bottomright",
text: "右下角"
}
],
void 0,
`Toast显示在九宫格的位置,默认: ${NetDiskGlobalData.toast.position.default}`
),
UISelect(
"同时最多显示的数量",
NetDiskGlobalData.toast.maxnums.KEY,
NetDiskGlobalData.toast.maxnums.default,
[
{
value: 1,
text: "1"
},
{
value: 2,
text: "2"
},
{
value: 3,
text: "3"
},
{
value: 4,
text: "4"
},
{
value: 5,
text: "5"
}
],
void 0,
`默认: ${NetDiskGlobalData.toast.maxnums.default}`
),
UISwitch(
"逆序弹出",
NetDiskGlobalData.toast.showreverse.KEY,
NetDiskGlobalData.toast.showreverse.value,
void 0,
"默认是自上往下显示Toast,逆序则是自下往上显示Toast"
)
]
}
]
},
{
type: "deepMenu",
text: "弹窗",
forms: [
{
className: "netdisk-panel-forms-pops",
type: "forms",
text: "",
forms: [
UISelect(
"动画",
NetDiskGlobalData.pops.popsAnimation.KEY,
NetDiskGlobalData.pops.popsAnimation.default,
[
{
value: "",
text: "无"
},
{
value: "pops-anim-spread",
text: "spread"
},
{
value: "pops-anim-shake",
text: "shake"
},
{
value: "pops-anim-rolling-left",
text: "rolling-left"
},
{
value: "pops-anim-rolling-right",
text: "rolling-right"
},
{
value: "pops-anim-slide-top",
text: "slide-top"
},
{
value: "pops-anim-slide-bottom",
text: "slide-bottom"
},
{
value: "pops-anim-slide-left",
text: "slide-left"
},
{
value: "pops-anim-slide-right",
text: "slide-right"
},
{
value: "pops-anim-fadein",
text: "fadein"
},
{
value: "pops-anim-fadein-zoom",
text: "fadein-zoom"
},
{
value: "pops-anim-fadein-alert",
text: "fadein-alert"
},
{
value: "pops-anim-don",
text: "don"
},
{
value: "pops-anim-roll",
text: "roll"
},
{
value: "pops-anim-sandra",
text: "sandra"
},
{
value: "pops-anim-gather",
text: "gather"
}
],
void 0,
`显示/关闭的动画效果,默认: ${NetDiskGlobalData.pops.popsAnimation.default}`
),
UISwitch(
"点击弹窗遮罩层关闭弹窗",
NetDiskGlobalData.pops.clickMaskToCloseDialog.KEY,
NetDiskGlobalData.pops.clickMaskToCloseDialog.default,
void 0,
"点击遮罩层触发关闭弹窗事件"
),
UISwitch(
"窗口拖拽",
NetDiskGlobalData.pops.pcDrag.KEY,
NetDiskGlobalData.pops.pcDrag.default,
void 0,
"长按标题栏可拖拽移动弹窗"
),
UISwitch(
"限制拖拽距离",
NetDiskGlobalData.pops.pcDragLimit.KEY,
NetDiskGlobalData.pops.pcDragLimit.default,
void 0,
"只能在浏览器的可视窗口内拖动"
),
UISwitch(
"亚克力效果",
NetDiskGlobalData.pops.popsAcrylic.KEY,
NetDiskGlobalData.pops.popsAcrylic.default,
void 0,
""
)
]
}
]
},
{
type: "deepMenu",
text: "文件弹窗",
forms: [
{
type: "forms",
text: "",
className: "netdisk-panel-forms-pops-folder",
forms: [
UISelect(
"排序名",
NetDiskGlobalData.popsFolder["pops-folder-sort-name"].KEY,
NetDiskGlobalData.popsFolder["pops-folder-sort-name"].default,
[
{
value: "fileName",
text: "文件名"
},
{
value: "latestTime",
text: "修改时间"
},
{
value: "fileSize",
text: "大小"
}
],
void 0,
"当前的规则"
),
UISelect(
"排序规则",
NetDiskGlobalData.popsFolder["pops-folder-sort-is-desc"].KEY,
NetDiskGlobalData.popsFolder["pops-folder-sort-is-desc"].default,
[
{
value: false,
text: "升序"
},
{
value: true,
text: "降序"
}
],
void 0,
"当前的规则"
)
]
}
]
},
{
type: "deepMenu",
text: "悬浮按钮",
forms: [
{
type: "forms",
text: "",
forms: [
UISlider(
"大小",
NetDiskGlobalData.suspension.size.KEY,
NetDiskGlobalData.suspension.size.default,
15,
250,
(event, value) => {
NetDiskGlobalData.suspension.size.value = parseInt(
value.toString()
);
if (NetDiskUI.suspension.isShow) {
domUtils.css(NetDiskUI.suspension.suspensionNode, {
width: NetDiskGlobalData.suspension.size.value,
height: NetDiskGlobalData.suspension.size.value
});
NetDiskUI.suspension.setSuspensionPosition();
}
},
(value) => {
return `${value}px`;
},
"悬浮按钮的大小,默认: " + NetDiskGlobalData.suspension.size.default
),
UISlider(
"透明度",
NetDiskGlobalData.suspension.opacity.KEY,
NetDiskGlobalData.suspension.opacity.default,
0.1,
1,
(event, value) => {
NetDiskGlobalData.suspension.opacity.value = parseFloat(
value.toString()
);
if (NetDiskUI.suspension.isShow) {
domUtils.css(NetDiskUI.suspension.suspensionNode, {
opacity: NetDiskGlobalData.suspension.opacity.value
});
}
},
void 0,
"值越小越透明,默认: " + NetDiskGlobalData.suspension.opacity.default,
0.1
),
UISlider(
"背景轮播时间",
NetDiskGlobalData.suspension["randbg-time"].KEY,
NetDiskGlobalData.suspension["randbg-time"].default,
0,
1e4,
void 0,
(value) => {
return `${value}ms`;
},
"淡入/淡出的时间,默认: " + NetDiskGlobalData.suspension["randbg-time"].default + "ms",
100
),
UISlider(
"背景显示时间",
NetDiskGlobalData.suspension["randbg-show-time"].KEY,
NetDiskGlobalData.suspension["randbg-show-time"].default,
0,
1e4,
void 0,
(value) => {
return `${value}ms`;
},
"图标显示的持续时间,默认: 1200",
100
),
UISwitch(
"吸附边缘",
NetDiskGlobalData.suspension["suspended-button-adsorption-edge"].KEY,
NetDiskGlobalData.suspension["suspended-button-adsorption-edge"].default,
void 0,
"移动悬浮按钮松开后自动吸附边缘"
)
]
}
]
},
{
type: "deepMenu",
text: "小窗模式",
forms: [
{
type: "forms",
text: "",
className: "netdisk-panel-forms-small-window",
forms: [
UISlider(
"宽度",
NetDiskGlobalData.smallWindow["netdisk-ui-small-window-width"].KEY,
NetDiskGlobalData.smallWindow["netdisk-ui-small-window-width"].default,
50,
domUtils.width(window),
void 0,
(value) => {
return `${value}px`;
},
"设置小窗宽度(px),默认: 250",
1
),
UISlider(
"高度",
NetDiskGlobalData.smallWindow["netdisk-ui-small-window-max-height"].KEY,
NetDiskGlobalData.smallWindow["netdisk-ui-small-window-max-height"].default,
50,
domUtils.height(window),
void 0,
(value) => {
return `${value}px`;
},
"设置小窗最大高度(px),默认: " + NetDiskGlobalData.smallWindow["netdisk-ui-small-window-max-height"].default,
1
)
]
}
]
}
]
},
{
type: "forms",
text: "",
forms: [
{
type: "deepMenu",
text: "功能",
forms: [
{
type: "forms",
text: "",
className: "netdisk-panel-forms-function",
forms: [
UISelect(
"匹配模式",
NetDiskGlobalData.features["netdisk-match-mode"].KEY,
NetDiskGlobalData.features["netdisk-match-mode"].default,
[
{
text: "MutationObserver",
value: "MutationObserver"
},
{
text: "Menu",
value: "Menu"
}
],
void 0,
"MutationObserver是网页加载完毕后自动监听识别链接,Menu是油猴菜单点击进行识别"
),
UISelect(
"行为模式",
NetDiskGlobalData.features["netdisk-behavior-mode"].KEY,
NetDiskGlobalData.features["netdisk-behavior-mode"].default,
[
{
text: "悬浮按钮+小窗",
value: "suspension_smallwindow"
},
{
text: "悬浮按钮+大窗",
value: "suspension_window"
},
{
text: "小窗",
value: "smallwindow"
}
],
void 0,
"匹配到链接时触发的UI执行"
),
UISwitch(
"自动输入访问码",
NetDiskGlobalData.features.autoFillAccessCode.KEY,
NetDiskGlobalData.features.autoFillAccessCode.default,
void 0,
"通过主动点击链接跳转时,会自动输入网盘访问码"
)
]
}
]
},
{
type: "deepMenu",
text: "匹配设置",
forms: [
{
type: "forms",
text: "文本匹配范围",
forms: [
UISelectMultiple(
"匹配规则类型",
NetDiskGlobalData.match.pageMatchRange.KEY,
NetDiskGlobalData.match.pageMatchRange.default,
[
{
value: "innerText",
text: "普通文本"
},
{
value: "innerHTML",
text: "超文本"
}
],
void 0,
"执行的文本匹配规则",
void 0,
{
height: "auto"
}
),
UISwitch(
"深入ShadowRoot获取匹配文本",
NetDiskGlobalData.match.depthQueryWithShadowRoot.KEY,
NetDiskGlobalData.match.depthQueryWithShadowRoot.default,
void 0,
"遍历ShadowRoot,获取匹配的内容"
),
UISwitch(
"匹配剪贴板",
NetDiskGlobalData.match.readClipboard.KEY,
NetDiskGlobalData.match.readClipboard.default,
void 0,
"Api兼容性查看:读取剪贴板权限申请、直接读取剪贴板"
),
UISwitch(
"匹配当前URL",
NetDiskGlobalData.match.allowMatchLocationHref.KEY,
NetDiskGlobalData.match.allowMatchLocationHref.default,
void 0,
"提取window.location.href进行匹配"
),
UISwitch(
"匹配input标签的内容",
NetDiskGlobalData.match.toBeMatchedWithInputElementValue.KEY,
NetDiskGlobalData.match.toBeMatchedWithInputElementValue.default,
void 0,
"提取页面中的<input>的内容进行匹配"
),
UISwitch(
"匹配textarea标签的内容",
NetDiskGlobalData.match.toBeMatchedTextAreaElementValue.KEY,
NetDiskGlobalData.match.toBeMatchedTextAreaElementValue.default,
void 0,
"提取页面中的<textarea>的内容进行匹配"
)
]
},
{
type: "forms",
text: "MutationObserver观察器",
forms: [
UISlider(
"匹配间隔",
NetDiskGlobalData.match.delaytime.KEY,
NetDiskGlobalData.match.delaytime.default,
0,
5,
void 0,
(value) => {
return `${value}s`;
},
"匹配文本完毕后的延迟xxx秒允许下一次匹配",
0.1
),
UISwitch(
"添加元素时进行匹配",
NetDiskGlobalData.match.isAddedNodesToMatch.KEY,
NetDiskGlobalData.match.isAddedNodesToMatch.default,
void 0,
"当监听到页面添加元素时才进行匹配文本"
),
UISwitch(
"观察器:childList",
NetDiskGlobalData.match["mutationObserver-childList"].KEY,
NetDiskGlobalData.match["mutationObserver-childList"].default,
void 0,
"子节点的变动(新增、删除或者更改)"
),
UISwitch(
"观察器:characterData",
NetDiskGlobalData.match["mutationObserver-characterData"].KEY,
NetDiskGlobalData.match["mutationObserver-characterData"].default,
void 0,
"节点内容或节点文本的变动"
),
UISwitch(
"观察器:subtree",
NetDiskGlobalData.match["mutationObserver-subtree"].KEY,
NetDiskGlobalData.match["mutationObserver-subtree"].default,
void 0,
"是否将观察器应用于该节点的所有后代节点"
)
]
}
]
},
{
type: "deepMenu",
text: "网盘图标",
forms: [
{
type: "forms",
text: "",
forms: [
UISwitch(
"点击定位分享码",
NetDiskGlobalData.smallIconNavgiator["pops-netdisk-icon-click-event-find-sharecode"].KEY,
NetDiskGlobalData.smallIconNavgiator["pops-netdisk-icon-click-event-find-sharecode"].default,
void 0,
"自动滚动页面至包含分享码的元素"
),
UISwitch(
"选中分享码",
NetDiskGlobalData.smallIconNavgiator["pops-netdisk-icon-click-event-find-sharecode-with-select"].KEY,
NetDiskGlobalData.smallIconNavgiator["pops-netdisk-icon-click-event-find-sharecode-with-select"].default,
void 0,
"使用光标选中分享码/元素"
),
UISwitch(
"循环定位",
NetDiskGlobalData.smallIconNavgiator["pops-netdisk-icon-click-event-loop-find-sharecode"].KEY,
NetDiskGlobalData.smallIconNavgiator["pops-netdisk-icon-click-event-loop-find-sharecode"].default,
void 0,
"关闭则是每一个元素只定位一次"
)
]
}
]
},
{
type: "deepMenu",
text: "历史匹配记录",
forms: [
{
type: "forms",
text: "",
className: "netdisk-panel-history-match",
forms: [
UISwitch(
"保存匹配记录",
NetDiskGlobalData.historyMatch.saveMatchNetDisk.KEY,
NetDiskGlobalData.historyMatch.saveMatchNetDisk.default,
void 0,
"将匹配到的链接信息进行本地存储,可点击【油猴菜单-⚙ 历史匹配记录】进行查看"
),
UISwitch(
"合并相同链接",
NetDiskGlobalData.historyMatch["netdisk-history-match-merge-same-link"].KEY,
NetDiskGlobalData.historyMatch["netdisk-history-match-merge-same-link"].default,
void 0,
"将合并匹配到的相同链接,并更新它最后一次匹配到的更新时间、网址信息"
),
UISelect(
"排序规则",
NetDiskGlobalData.historyMatch["netdisk-history-match-ordering-rule"].KEY,
NetDiskGlobalData.historyMatch["netdisk-history-match-ordering-rule"].default,
[
{
value: "按 记录时间 - 升序",
text: "按 记录时间 - 升序"
},
{
value: "按 记录时间 - 降序",
text: "按 记录时间 - 降序"
},
{
value: "按 更新时间 - 升序",
text: "按 更新时间 - 升序"
},
{
value: "按 更新时间 - 降序",
text: "按 更新时间 - 降序"
}
]
),
UIButton(
"修复存储记录",
"如果【匹配记录】弹窗打不开,可能是存储的数据缺失某些字段,可尝试点击此处进行修复",
"修复",
void 0,
void 0,
false,
"primary",
() => {
try {
const { count, repairCount } = NetDiskUI.netDiskHistoryMatch.checkAndRepairLocalData();
if (repairCount === 0) {
Qmsg.info(`不存在需要修复的数据`);
} else {
Qmsg.success(`共计: ${count} 条,修复${repairCount}条`);
}
} catch (error) {
Qmsg.error("修复异常:" + error.toString());
}
}
)
]
}
]
},
{
type: "deepMenu",
text: "分享码",
forms: [
{
type: "forms",
text: "",
className: "netdisk-panel-forms-share-code",
forms: [
UISwitch(
"排除分享码",
NetDiskGlobalData.shareCode.excludeIdenticalSharedCodes.KEY,
NetDiskGlobalData.shareCode.excludeIdenticalSharedCodes.default,
void 0,
"启用后会根据【相同系数】排除掉匹配到的分享码"
),
UISlider(
"相同系数",
NetDiskGlobalData.shareCode.excludeIdenticalSharedCodesCoefficient.KEY,
NetDiskGlobalData.shareCode.excludeIdenticalSharedCodesCoefficient.default,
0,
1,
void 0,
(value) => {
return value.toString();
},
"例如分享码: aaaaaaaabb,它的相同系数是0.8,设置相同系数≥0.8时会被排除",
0.01
)
]
}
]
},
{
type: "deepMenu",
text: "访问码",
forms: [
{
className: "netdisk-panel-forms-access-code",
text: "",
type: "forms",
forms: [
UISwitch(
"允许查询历史匹配记录",
NetDiskGlobalData.accessCode.allowQueryHistoryMatchingAccessCode.KEY,
NetDiskGlobalData.accessCode.allowQueryHistoryMatchingAccessCode.default,
void 0,
"当访问码为空时,访问码将从历史匹配记录中查询,优先级:页面匹配 < 历史匹配记录 < 网站规则 < 黑名单"
)
]
}
]
},
{
type: "deepMenu",
className: "netdisk-panel-forms-shortcut-keys-deepMenu",
text: "快捷键",
forms: [
{
className: "netdisk-panel-forms-shortcut-keys",
text: "",
type: "forms",
forms: [
UIButtonShortCut(
"【打开】⚙ 设置",
"",
"netdisk-keyboard-open-setting",
void 0,
"暂无快捷键",
"default",
NetDiskShortcut.shortCut
),
UIButtonShortCut(
"【打开】⚙ 历史匹配记录",
"",
"netdisk-keyboard-open-history-matching-records",
void 0,
"暂无快捷键",
"default",
NetDiskShortcut.shortCut
),
UIButtonShortCut(
"【打开】⚙ 访问码规则",
"",
"netdisk-keyboard-open-accesscode-rule",
void 0,
"暂无快捷键",
"default",
NetDiskShortcut.shortCut
),
UIButtonShortCut(
"【打开】⚙ 自定义规则",
"",
"netdisk-keyboard-open-user-rule",
void 0,
"暂无快捷键",
"default",
NetDiskShortcut.shortCut
),
UIButtonShortCut(
"【打开】⚙ 网站规则",
"",
"netdisk-keyboard-website-rule",
void 0,
"暂无快捷键",
"default",
NetDiskShortcut.shortCut
),
UIButtonShortCut(
"【打开】⚙ 字符映射",
"",
"netdisk-keyboard-character-mapping",
void 0,
"暂无快捷键",
"default",
NetDiskShortcut.shortCut
),
UIButtonShortCut(
"【打开】⚙ 识别文本",
"",
"netdisk-keyboard-open-proactively-recognize-text",
void 0,
"暂无快捷键",
"default",
NetDiskShortcut.shortCut
),
UIButtonShortCut(
"执行文本匹配",
"",
"netdisk-keyboard-performPageTextMatchingManually",
void 0,
"暂无快捷键",
"default",
NetDiskShortcut.shortCut
)
]
}
]
}
]
}
]
};
const PopsPanel = {
/** 数据 */
$data: {
__data: null,
__oneSuccessExecMenu: null,
__onceExec: null,
__listenData: null,
/**
* 菜单项的默认值
*/
get data() {
if (PopsPanel.$data.__data == null) {
PopsPanel.$data.__data = new utils.Dictionary();
}
return PopsPanel.$data.__data;
},
/**
* 成功只执行了一次的项
*/
get oneSuccessExecMenu() {
if (PopsPanel.$data.__oneSuccessExecMenu == null) {
PopsPanel.$data.__oneSuccessExecMenu = new utils.Dictionary();
}
return PopsPanel.$data.__oneSuccessExecMenu;
},
/**
* 成功只执行了一次的项
*/
get onceExec() {
if (PopsPanel.$data.__onceExec == null) {
PopsPanel.$data.__onceExec = new utils.Dictionary();
}
return PopsPanel.$data.__onceExec;
},
/** 脚本名,一般用在设置的标题上 */
get scriptName() {
return SCRIPT_NAME;
},
/** 菜单项的总值在本地数据配置的键名 */
key: KEY,
/** 菜单项在attributes上配置的菜单键 */
attributeKeyName: ATTRIBUTE_KEY,
/** 菜单项在attributes上配置的菜单默认值 */
attributeDefaultValueName: ATTRIBUTE_DEFAULT_VALUE
},
/** 监听器 */
$listener: {
/**
* 值改变的监听器
*/
get listenData() {
if (PopsPanel.$data.__listenData == null) {
PopsPanel.$data.__listenData = new utils.Dictionary();
}
return PopsPanel.$data.__listenData;
}
},
init() {
this.initPanelDefaultValue(
this.getPanelContentConfig().concat(NetDiskRule.getRulePanelContent())
);
this.initExtensionsMenu();
},
/** 判断是否是顶层窗口 */
isTopWindow() {
return _unsafeWindow.top === _unsafeWindow.self;
},
/** 初始化进行注册油猴菜单 */
initExtensionsMenu() {
if (!this.isTopWindow()) {
return;
}
GM_Menu.add([
{
key: "show_pops_panel_setting",
text: "⚙ 设置",
autoReload: false,
isStoreValue: false,
showText(text) {
return text;
},
callback: () => {
NetDiskGlobalSettingView.show();
}
},
{
key: "showNetDiskHistoryMatch",
text: "⚙ 历史匹配记录",
autoReload: false,
isStoreValue: false,
showText(text) {
return text;
},
callback() {
NetDiskUI.netDiskHistoryMatch.show();
}
},
{
key: "websiteRule",
text: "⚙ 网站规则",
autoReload: false,
isStoreValue: false,
showText(text) {
return text;
},
callback() {
WebsiteRule.show();
}
},
{
key: "charater-mapping",
text: "⚙ 字符映射",
autoReload: false,
isStoreValue: false,
showText(text) {
return text;
},
callback() {
CharacterMapping.show();
}
},
{
key: "showUserRule",
text: "⚙ 自定义规则",
autoReload: false,
isStoreValue: false,
showText(text) {
return text;
},
callback() {
NetDiskUserRuleUI.show(false);
}
},
{
key: "showMatchPasteText",
text: "⚙ 识别文本",
autoReload: false,
isStoreValue: false,
showText(text) {
return text;
},
callback() {
NetDiskUI.matchPasteText.show();
}
}
]);
},
/** 初始化菜单项的默认值保存到本地数据中 */
initPanelDefaultValue(contentConfigList) {
function initDefaultValue(config) {
if (!config.attributes) {
return;
}
if (config.type === "button") {
return;
}
let needInitConfig = {};
let key = config.attributes[ATTRIBUTE_KEY];
if (key != null) {
needInitConfig[key] = config.attributes[ATTRIBUTE_DEFAULT_VALUE];
}
let __attr_init__ = config.attributes[ATTRIBUTE_INIT];
if (typeof __attr_init__ === "function") {
let __attr_result__ = __attr_init__();
if (typeof __attr_result__ === "boolean" && !__attr_result__) {
return;
}
}
let initMoreValue = config.attributes[ATTRIBUTE_INIT_MORE_VALUE];
if (initMoreValue && typeof initMoreValue === "object") {
Object.assign(needInitConfig, initMoreValue);
}
let needInitConfigList = Object.keys(needInitConfig);
if (!needInitConfigList.length) {
log.warn("请先配置键", config);
return;
}
needInitConfigList.forEach((iteratorKey) => {
let iteratorDefaultValue = needInitConfig[iteratorKey];
if (_GM_getValue(iteratorKey) == null) {
_GM_setValue(iteratorKey, iteratorDefaultValue);
}
});
}
function loopInitDefaultValue(configList) {
for (let index = 0; index < configList.length; index++) {
let configItem = configList[index];
initDefaultValue(configItem);
let childForms = configItem.forms;
if (childForms && Array.isArray(childForms)) {
loopInitDefaultValue(childForms);
}
}
}
for (let index = 0; index < contentConfigList.length; index++) {
let leftContentConfigItem = contentConfigList[index];
if (!leftContentConfigItem.forms) {
continue;
}
let rightContentConfigList = leftContentConfigItem.forms;
if (rightContentConfigList && Array.isArray(rightContentConfigList)) {
loopInitDefaultValue(rightContentConfigList);
}
}
},
/**
* 设置值
* @param key 键
* @param value 值
*/
setValue(key, value) {
let locaData = _GM_getValue(KEY, {});
let oldValue = locaData[key];
locaData[key] = value;
_GM_setValue(KEY, locaData);
if (this.$listener.listenData.has(key)) {
this.$listener.listenData.get(key).callback(key, oldValue, value);
}
},
/**
* 获取值
* @param key 键
* @param defaultValue 默认值
*/
getValue(key, defaultValue) {
let locaData = _GM_getValue(KEY, {});
let localValue = locaData[key];
if (localValue == null) {
if (this.$data.data.has(key)) {
return this.$data.data.get(key);
}
return defaultValue;
}
return localValue;
},
/**
* 删除值
* @param key 键
*/
deleteValue(key) {
let locaData = _GM_getValue(KEY, {});
let oldValue = locaData[key];
Reflect.deleteProperty(locaData, key);
_GM_setValue(KEY, locaData);
if (this.$listener.listenData.has(key)) {
this.$listener.listenData.get(key).callback(key, oldValue, void 0);
}
},
/**
* 监听调用setValue、deleteValue
* @param key 需要监听的键
* @param callback
*/
addValueChangeListener(key, callback, option) {
let listenerId = Math.random();
this.$listener.listenData.set(key, {
id: listenerId,
key,
callback
});
if (option) {
if (option.immediate) {
callback(key, this.getValue(key), this.getValue(key));
}
}
return listenerId;
},
/**
* 移除监听
* @param listenerId 监听的id
*/
removeValueChangeListener(listenerId) {
let deleteKey = null;
for (const [key, value] of this.$listener.listenData.entries()) {
if (value.id === listenerId) {
deleteKey = key;
break;
}
}
if (typeof deleteKey === "string") {
this.$listener.listenData.delete(deleteKey);
} else {
console.warn("没有找到对应的监听器");
}
},
/**
* 主动触发菜单值改变的回调
* @param key 菜单键
* @param newValue 想要触发的新值,默认使用当前值
* @param oldValue 想要触发的旧值,默认使用当前值
*/
triggerMenuValueChange(key, newValue, oldValue) {
if (this.$listener.listenData.has(key)) {
let listenData = this.$listener.listenData.get(key);
if (typeof listenData.callback === "function") {
let value = this.getValue(key);
let __newValue = value;
let __oldValue = value;
if (typeof newValue !== "undefined" && arguments.length > 1) {
__newValue = newValue;
}
if (typeof oldValue !== "undefined" && arguments.length > 2) {
__oldValue = oldValue;
}
listenData.callback(key, __oldValue, __newValue);
}
}
},
/**
* 判断该键是否存在
* @param key 键
*/
hasKey(key) {
let locaData = _GM_getValue(KEY, {});
return key in locaData;
},
/**
* 自动判断菜单是否启用,然后执行回调
* @param key
* @param callback 回调
* @param [isReverse=false] 逆反判断菜单启用
*/
execMenu(key, callback, isReverse = false) {
if (!(typeof key === "string" || typeof key === "object" && Array.isArray(key))) {
throw new TypeError("key 必须是字符串或者字符串数组");
}
let runKeyList = [];
if (typeof key === "object" && Array.isArray(key)) {
runKeyList = [...key];
} else {
runKeyList.push(key);
}
let value = void 0;
for (let index = 0; index < runKeyList.length; index++) {
const runKey = runKeyList[index];
if (!this.$data.data.has(runKey)) {
log.warn(`${key} 键不存在`);
return;
}
let runValue = PopsPanel.getValue(runKey);
if (isReverse) {
runValue = !runValue;
}
if (!runValue) {
break;
}
value = runValue;
}
if (value) {
callback(value);
}
},
/**
* 自动判断菜单是否启用,然后执行回调,只会执行一次
* @param key
* @param callback 回调
* @param getValueFn 自定义处理获取当前值,值true是启用并执行回调,值false是不执行回调
* @param handleValueChangeFn 自定义处理值改变时的回调,值true是启用并执行回调,值false是不执行回调
*/
execMenuOnce(key, callback, getValueFn, handleValueChangeFn) {
if (typeof key !== "string") {
throw new TypeError("key 必须是字符串");
}
if (!this.$data.data.has(key)) {
log.warn(`${key} 键不存在`);
return;
}
if (this.$data.oneSuccessExecMenu.has(key)) {
return;
}
this.$data.oneSuccessExecMenu.set(key, 1);
let __getValue = () => {
let localValue = PopsPanel.getValue(key);
return typeof getValueFn === "function" ? getValueFn(key, localValue) : localValue;
};
let resultStyleList = [];
let dynamicPushStyleNode = ($style) => {
let __value = __getValue();
let dynamicResultList = [];
if ($style instanceof HTMLStyleElement) {
dynamicResultList = [$style];
} else if (Array.isArray($style)) {
dynamicResultList = [
...$style.filter(
(item) => item != null && item instanceof HTMLStyleElement
)
];
}
if (__value) {
resultStyleList = resultStyleList.concat(dynamicResultList);
} else {
for (let index = 0; index < dynamicResultList.length; index++) {
let $css = dynamicResultList[index];
$css.remove();
dynamicResultList.splice(index, 1);
index--;
}
}
};
let changeCallBack = (currentValue) => {
let resultList = [];
if (currentValue) {
let result = callback(currentValue, dynamicPushStyleNode);
if (result instanceof HTMLStyleElement) {
resultList = [result];
} else if (Array.isArray(result)) {
resultList = [
...result.filter(
(item) => item != null && item instanceof HTMLStyleElement
)
];
}
}
for (let index = 0; index < resultStyleList.length; index++) {
let $css = resultStyleList[index];
$css.remove();
resultStyleList.splice(index, 1);
index--;
}
resultStyleList = [...resultList];
};
this.addValueChangeListener(
key,
(__key, oldValue, newValue) => {
let __newValue = newValue;
if (typeof handleValueChangeFn === "function") {
__newValue = handleValueChangeFn(__key, newValue, oldValue);
}
changeCallBack(__newValue);
}
);
let value = __getValue();
if (value) {
changeCallBack(value);
}
},
/**
* 父子菜单联动,自动判断菜单是否启用,然后执行回调,只会执行一次
* @param key 菜单键
* @param childKey 子菜单键
* @param callback 回调
* @param replaceValueFn 用于修改mainValue,返回undefined则不做处理
*/
execInheritMenuOnce(key, childKey, callback, replaceValueFn) {
let that = this;
const handleInheritValue = (key2, childKey2) => {
let mainValue = that.getValue(key2);
let childValue = that.getValue(childKey2);
if (typeof replaceValueFn === "function") {
let changedMainValue = replaceValueFn(mainValue, childValue);
if (changedMainValue !== void 0) {
return changedMainValue;
}
}
return mainValue;
};
this.execMenuOnce(
key,
callback,
() => {
return handleInheritValue(key, childKey);
},
() => {
return handleInheritValue(key, childKey);
}
);
this.execMenuOnce(
childKey,
() => {
},
() => false,
() => {
this.triggerMenuValueChange(key);
return false;
}
);
},
/**
* 根据自定义key只执行一次
* @param key 自定义key
*/
onceExec(key, callback) {
if (typeof key !== "string") {
throw new TypeError("key 必须是字符串");
}
if (this.$data.onceExec.has(key)) {
return;
}
callback();
this.$data.onceExec.set(key, 1);
},
/**
* 获取配置内容
*/
getPanelContentConfig() {
let configList = [PanelUI_allSetting];
return configList;
}
};
Object.assign(
NetDiskUI.src.icon,
// @ts-ignore
typeof RESOURCE_ICON === "undefined" ? {} : RESOURCE_ICON
);
WebsiteRule.init();
NetDiskUserRule.init();
NetDiskRule.init();
PopsPanel.init();
NetDisk.init();
NetDiskShortcut.init();
domUtils.ready(() => {
NetDiskAutoFillAccessCode.init();
NetDiskAuthorization.init();
NetDiskWorker.init();
});
})(Qmsg, DOMUtils, Utils, pops);