// ==UserScript== // @name 网盘链接识别 // @namespace https://greasyfork.org/zh-CN/scripts/445489 // @version 2024.12.28 // @author WhiteSevs // @description 识别网页中显示的网盘链接,目前包括百度网盘、蓝奏云、天翼云、中国移动云盘(原:和彩云)、阿里云、文叔叔、奶牛快传、123盘、腾讯微云、迅雷网盘、115网盘、夸克网盘、城通网盘(部分)、坚果云、UC网盘、BT磁力,支持蓝奏云、天翼云(需登录)、123盘、奶牛、UC网盘(需登录)、坚果云(需登录)和阿里云盘(需登录,且限制在网盘页面解析)直链获取下载,页面动态监控加载的链接,可自定义规则来识别小众网盘/网赚网盘或其它自定义的链接。 // @license GPL-3.0-only // @icon data:image/png;base64,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 // @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.6/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_getResourceText // @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_getResourceText = /* @__PURE__ */ (() => typeof GM_getResourceText != "undefined" ? GM_getResourceText : 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*/ `