// ==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 class=\"mtt\">\((.*)\)<\/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]*<span/i } }); } /** * 入口 * @param netDiskIndex * @param shareCode * @param accessCode */ async init(netDiskIndex, shareCode, accessCode) { log.info(netDiskIndex, shareCode, accessCode); this.netDiskIndex = netDiskIndex; this.shareCode = shareCode; this.accessCode = accessCode; this.regexp.unicode.isUnicode = Boolean( this.shareCode.match(this.regexp.unicode.match) ); if (netDiskIndex === 2) { await this.getMoreFile(this.router.root_s(this.shareCode)); } else { await this.getFileLink(); } } /** * 获取文件链接 * @param getShareCodeByPageAgain */ async getFileLink(getShareCodeByPageAgain = false) { var _a2, _b, _c, _d, _e, _f, _g, _h, _i; const that = this; let url = this.router.root(this.shareCode); log.info("蓝奏云-获取文件下载链接" + url); let getResp = await httpx.get({ url, headers: { Accept: "*/*", "User-Agent": utils.getRandomPCUA(), Referer: url }, allowInterceptConfig: false, onerror() { } }); if (!getResp.status) { log.error(getResp); if (getResp.type === "ontimeout") { return; } if (utils.isNull(getResp.data.responseText)) { Qmsg.error("请求异常"); return; } if (getResp.data.responseText.includes("div>文件不存在,或者已被删除</div>")) { 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>(.+?)<br>/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>(.+?)<br>/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 class="n_filesize">大小:(.+?)<\/div>/i); let fileUploadTime = pageText.match(that.regexp.uploadTime.match) || pageText.match(/<span class="n_file_infos">(.+?)<\/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未生成,是否前去登录?<br />    (注意,需要当前浏览器的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网盘,是否前去登录?<br />    (注意,需要当前浏览器的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("<h1>啊噢!")) { 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*/ ` <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> <path fill="currentColor" d="M874.119618 149.859922A510.816461 510.816461 0 0 0 511.997 0.00208a509.910462 509.910462 0 0 0-362.119618 149.857842c-199.817789 199.679789-199.817789 524.581447 0 724.260236a509.969462 509.969462 0 0 0 362.119618 149.857842A508.872463 508.872463 0 0 0 874.119618 874.120158c199.836789-199.679789 199.836789-524.581447 0-724.260236zM814.94268 378.210681L470.999043 744.132295a15.359984 15.359984 0 0 1-5.887994 4.095996c-1.751998 1.180999-2.913997 2.362998-5.276994 2.913997a34.499964 34.499964 0 0 1-13.469986 2.914997 45.547952 45.547952 0 0 1-12.897986-2.303998l-4.095996-2.363997a45.291952 45.291952 0 0 1-7.009992-4.095996l-196.902793-193.789796a34.126964 34.126964 0 0 1-10.555989-25.186973c0-9.37399 3.583996-18.74698 9.98399-25.186974a36.429962 36.429962 0 0 1 50.372947 0l169.98382 167.423824L763.389735 330.220732a37.059961 37.059961 0 0 1 50.371947-1.732998 33.647965 33.647965 0 0 1 11.165988 25.186973 35.544963 35.544963 0 0 1-9.98399 24.575974v-0.04z m0 0"></path> </svg> `; NetDiskCheckLinkValidity.setViewAgainCheckClickEvent($ele, checkInfo); } }, /** * 验证失败 */ error: { code: -404, msg: "网络异常", setView($ele, checkInfo, msg) { NetDiskCheckLinkValidity.setViewCheckValid( $ele, "error", msg ?? this.msg ); $ele.innerHTML = /*html*/ ` <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> <path fill="currentColor" d="M511.808 692.224c-18.048 0-35.136 3.968-50.432 11.392-25.472 12.416-46.528 33.92-57.792 60.032-5.632 14.144-9.024 29.504-9.024 45.952 0 65.152 52.672 117.824 117.248 117.824 65.28 0 117.952-52.672 117.952-117.824 0-64.64-52.672-117.376-117.952-117.376z m0 178.496c-33.408 0-60.608-27.712-60.608-61.12 0-33.472 27.2-60.672 60.608-60.672s61.248 27.2 61.248 60.672c0 33.472-27.776 61.12-61.248 61.12zM286.784 661.632c3.968 3.392 8.512 5.632 12.992 5.632L438.08 523.328c-60.032 14.72-114.432 49.344-155.328 98.624-9.536 11.84-7.872 30.08 4.032 39.68zM622.912 534.656l-43.008 45.312c45.312 13.056 86.72 40.256 117.376 78.208 5.632 6.784 13.568 10.24 22.08 10.24 6.272 0 12.416-2.24 18.176-6.784 11.904-9.6 13.568-27.84 3.392-39.68-31.808-39.104-72.704-69.12-118.016-87.296zM511.808 391.168c17.024 0 33.408 1.216 49.856 3.456l47.68-49.856c-31.744-6.848-64.064-10.24-97.536-10.24-142.784 0-277.12 63.488-367.232 174.656-10.24 11.904-8.576 30.08 3.904 39.68 5.12 4.48 11.328 6.784 18.176 6.784 7.936 0 15.872-3.968 21.568-10.816 79.872-97.536 197.76-153.664 323.584-153.664zM751.616 400.32l-40.256 41.92c47.04 24.96 89.536 60.032 124.096 102.592 10.24 12.48 27.84 14.208 40.256 3.968 11.968-9.6 13.632-27.84 3.968-39.68-36.16-44.8-79.872-81.088-128.064-108.8zM705.152 244.928l42.56-44.672c-73.664-28.992-153.6-44.224-235.904-44.224-196.672 0-380.864 87.872-505.6 239.744-9.6 12.48-7.872 30.08 3.968 40.256 5.632 3.968 11.904 6.208 18.112 6.208 7.936 0 16.448-3.392 22.144-10.176C163.84 292.608 332.096 212.672 511.808 212.672c66.944 0 132.16 10.752 193.344 32.256zM1017.472 395.776c-40.192-49.92-87.296-92.416-139.456-126.976l-39.68 41.344C889.408 343.04 935.36 383.808 973.888 432c9.6 11.904 27.776 13.568 39.68 3.968 11.84-10.176 14.144-27.712 3.904-40.192zM937.408 104.512c-11.328-10.944-29.312-10.496-40.064 0.832L179.008 854.72c-10.816 11.328-10.496 29.248 0.896 40.064 5.44 5.312 12.48 7.872 19.584 7.872 7.488 0 14.848-2.88 20.416-8.704L938.24 144.576c10.88-11.328 10.496-29.248-0.832-40.064z"></path> </svg> `; NetDiskCheckLinkValidity.setViewAgainCheckClickEvent($ele, checkInfo); } }, /** * 该链接已失效 */ failed: { code: 0, msg: "已失效", setView($ele, checkInfo, msg) { NetDiskCheckLinkValidity.setViewCheckValid( $ele, "failed", msg ?? this.msg ); $ele.innerHTML = /*html*/ ` <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> <path fill="currentColor" d="M549.044706 512l166.189176-166.249412a26.383059 26.383059 0 0 0 0-36.98447 26.383059 26.383059 0 0 0-37.044706 0L512 475.015529l-166.249412-166.249411a26.383059 26.383059 0 0 0-36.98447 0 26.383059 26.383059 0 0 0 0 37.044706L475.015529 512l-166.249411 166.249412a26.383059 26.383059 0 0 0 0 36.98447 26.383059 26.383059 0 0 0 37.044706 0L512 548.984471l166.249412 166.249411a26.383059 26.383059 0 0 0 36.98447 0 26.383059 26.383059 0 0 0 0-37.044706L548.984471 512zM512 1024a512 512 0 1 1 0-1024 512 512 0 0 1 0 1024z"></path> </svg> `; NetDiskCheckLinkValidity.setViewAgainCheckClickEvent($ele, checkInfo); } }, /** * 该链接需要密码 */ needAccessCode: { code: 201, msg: "需要提取码", setView($ele, checkInfo, msg) { NetDiskCheckLinkValidity.setViewCheckValid( $ele, "needAccessCode", msg ?? this.msg ); $ele.innerHTML = /*html*/ ` <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> <path fill="currentColor" d="M757.810429 373.751333 325.645708 373.751333l0-83.895759c0-103.694687 81.507362-184.922686 185.559183-184.922686 78.121242 0 146.053424 46.74565 173.062568 119.090329 3.865028 10.352789 15.384385 15.609513 25.742291 11.746532 10.351766-3.866051 15.609513-15.390525 11.744485-25.742291C688.844707 121.877815 606.198405 64.918545 511.204891 64.918545c-61.918211 0-119.246895 23.662933-161.423483 66.63156-41.3692 42.142819-64.151066 98.363262-64.151066 158.305469l0 83.895759-20.007683 0c-60.774155 0-110.042255 49.267077-110.042255 110.042255l0 366.139981c0 60.774155 49.267077 110.042255 110.042255 110.042255l492.187769 0c60.775178 0 110.042255-49.267077 110.042255-110.042255L867.852684 483.793588C867.852684 423.01841 818.585607 373.751333 757.810429 373.751333zM827.837318 849.933569c0 38.674834-31.352055 70.02689-70.02689 70.02689L265.62266 919.960459c-38.674834 0-70.02689-31.352055-70.02689-70.02689L195.59577 483.793588c0-38.674834 31.352055-70.02689 70.02689-70.02689l492.187769 0c38.674834 0 70.02689 31.352055 70.02689 70.02689L827.837318 849.933569z"></path> <path fill="currentColor" d="M509.715981 583.832002c-11.048637 0-20.007683 8.959046-20.007683 20.007683l0 110.042255c0 11.048637 8.958022 20.007683 20.007683 20.007683s20.007683-8.958022 20.007683-20.007683L529.723663 603.839685C529.723663 592.790024 520.765641 583.832002 509.715981 583.832002z"></path> </svg> `; NetDiskCheckLinkValidity.setViewAgainCheckClickEvent($ele, checkInfo); } }, /** * 存在部分违规文件 */ partialViolation: { code: 202, msg: "存在部分违规文件", setView($ele, checkInfo, msg) { NetDiskCheckLinkValidity.setViewCheckValid( $ele, "partial-violation", msg ?? this.msg ); $ele.innerHTML = /*html*/ ` <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path fill="currentColor" d="M954.963 810.267L543.112 96.919c-14.07-24.37-49.245-24.37-63.315 0L67.945 810.267c-14.07 24.37 3.518 54.832 31.657 54.832h823.703c28.141 0 45.728-30.463 31.658-54.832zM476.699 306.55c0-19.115 15.64-34.755 34.755-34.755 19.115 0 34.755 15.64 34.755 34.755v281.817c0 19.115-15.64 34.755-34.755 34.755-19.115 0-34.755-15.64-34.755-34.755V306.55z m34.755 445.293c-23.198 0-42.004-18.806-42.004-42.004s18.806-42.004 42.004-42.004c23.198 0 42.004 18.806 42.004 42.004s-18.806 42.004-42.004 42.004z"></path> </svg>`; } }, /** * 未知状态 */ unknown: { code: -200, msg: "未知检查情况", setView($ele, checkInfo, msg) { NetDiskCheckLinkValidity.setViewCheckValid( $ele, "unknown", msg ?? this.msg ); $ele.innerHTML = /*html*/ ` <svg viewBox="0 0 1025 1024" xmlns="http://www.w3.org/2000/svg"> <path fill="currentColor" d="M512.473172 1023.995242A511.814852 511.814852 0 0 1 313.545134 40.351073a512.244696 512.244696 0 0 1 398.855715 943.658633 508.815937 508.815937 0 0 1-199.927677 39.985536z m0-943.658634C274.559237 80.336608 80.629391 274.266455 80.629391 512.18039s193.929846 431.843781 431.843781 431.843781 431.843781-193.929846 431.843781-431.843781S751.386745 80.336608 512.473172 80.336608z"></path> <path fill="currentColor" d="M506.475342 716.10662a39.985535 39.985535 0 0 1-39.985536-39.985535v-76.972156c0-79.971071 64.976495-144.947566 144.947566-144.947565a77.971794 77.971794 0 0 0 0-155.943588H445.4974a56.979388 56.979388 0 0 0-56.979387 56.979388 39.985535 39.985535 0 0 1-79.971071 0c0-74.972879 60.977941-136.950458 136.950458-136.950459h164.940333c86.968539 0 157.942864 70.974325 157.942865 157.942865s-69.974687 157.942864-157.942865 157.942864a64.976495 64.976495 0 0 0-64.976494 64.976495v76.972156a39.985535 39.985535 0 0 1-38.985897 39.985535zM505.475703 742.097218a48.982281 48.982281 0 1 0 48.982281 48.982281 48.982281 48.982281 0 0 0-48.982281-48.982281z"></path> </svg> `; 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, // "开源项目:<a href='https://github.com/yuantuo666/baiduwp-php' target='_blank'>https://github.com/yuantuo666/baiduwp-php</a>" // ), // 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( "<a target='_blank' href='https://github.com/qinlili23333/ctfileGet/'>解析站</a>", "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*/ ` <div class="netdisk-aside-icon" style="background-image: url(${NetDiskUI.src.icon[ruleKey]});"></div> <div class="netdisk-aside-text">${ruleName}</div>`; } let headerTitleText = ruleName; if (netDiskRuleConfig.isUserRule) { headerTitleText += /*html*/ `<div class="netdisk-custom-rule-edit" data-key="${ruleKey}" data-type="${netDiskRuleConfig.setting.name}">${__pops.config.iconSVG.edit}</div>`; headerTitleText += /*html*/ `<div class="netdisk-custom-rule-delete" data-key="${ruleKey}" data-type="${netDiskRuleConfig.setting.name}">${__pops.config.iconSVG.delete}</div>`; } 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*/ ` <div class="netdiskrecord-search"> <input type="text" placeholder="搜索链接/网址/网址标题,可正则搜索"> </div> <div class="netdiskrecord-table"><ul>${dataHTML}</ul></div> <div class="netdiskrecord-page"> </div>`; 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*/ ` <div class="netdiskrecord-link"> <p>链接</p> <a href="javascript:;" isvisited="false">${netDiskURL}</a> </div> <div class="netdiskrecord-icon"> <p>网盘</p> <div class="netdisk-icon-img"></div> </div> <div class="netdiskrecord-url"> <p>网址</p> <a href="${data.url}" target="_blank">${data.url}</a> </div> <div class="netdiskrecord-url-title"> <p>网址标题</p> ${data.title} </div> <div class="netdiskrecord-add-time"> <p>记录时间</p> ${utils.formatTime(data.addTime)} </div> <div class="netdiskrecord-update-time"> <p>更新时间</p> ${utils.formatTime(data.updateTime)} </div> <div class="netdiskrecord-functions"> <p>功能</p> <button class="btn-delete">删除</button> </div> ` ) }); 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*/ ` <p>Top网址</p> <a href="${data.topURL}" target="_blank">${data.topURL}</a> ` ) }); 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*/ ` <div class="custom-rule-container"> <textarea class="custom-rule-match-text" placeholder="请输入需要测试匹配的字符串"></textarea> <div class="custom-rule-input-container"> <select class="custom-rule-select-regexp"></select> <button class="custom-rule-run-match-button" type="primary" data-icon="" data-righticon="false"> <span>执行</span> </button> </div> </div> <div class="custom-rule-match-log"> <div>匹配日志↓</div> <div class="custom-rule-match-log-container"></div> </div> ` ), 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*/ `<textarea class="netdisk-custom-rules" placeholder="请输入自定义规则"></textarea>` ), 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 type="text/css"> /* 动态生成z-index */ #whitesevSuspensionId{ z-index: ${utils.getMaxValue(4e4, utils.getMaxZIndex(10))};; } ${indexCSS$2} </style> <div class="whitesevSuspensionMain"> <div class="whitesevSuspensionFloor"> <div class="netdisk"></div> </div> </div> ` ) }, { 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*/ ` <textarea class="netdisk-match-paste-text"></textarea> ` ), 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*/ ` <div style="text-align: left;">旧: ${accessCode}</div> <div style="text-align: left;">新: ${option.accessCode}</div>`, { html: true } ); } else { Qmsg.error("修改失败"); } } else { event.target.setAttribute("data-accesscode", option.accessCode); if (option.isUpdatedMatchedDict) { Qmsg.success( /*html*/ ` <div style="text-align: left;">旧: ${accessCode}</div> <div style="text-align: left;">新: ${option.accessCode}</div>`, { 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*/ ` <form class="rule-form-container" onsubmit="return false"> <ul class="rule-form-ulist"> </ul> <input type="submit" style="display: none;" /> </form> ` ), 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*/ ` <div class="filter-container"></div> ` ) }, 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*/ ` <div class="rule-view-container"> </div> ` ), 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*/ ` <div class="rule-name">${name}</div> <div class="rule-controls"> <div class="rule-controls-enable"> <div class="pops-panel-switch"> <input class="pops-panel-switch__input" type="checkbox"> <span class="pops-panel-switch__core"> <div class="pops-panel-switch__action"> </div> </span> </div> </div> <div class="rule-controls-edit"> ${__pops.config.iconSVG.edit} </div> <div class="rule-controls-delete"> ${__pops.config.iconSVG.delete} </div> </div> ` ) }); 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兼容性查看:<a href='https://caniuse.com/mdn-api_permissions_permission_clipboard-read' target='_blank'>读取剪贴板权限申请</a>、<a href='https://caniuse.com/mdn-api_clipboard_readtext' target='_blank'>直接读取剪贴板</a>" ), 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);