吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9088|回复: 78
上一主题 下一主题
收起左侧

[其他转载] 【油猴脚本】网盘快开助手+演示视频

  [复制链接]
跳转到指定楼层
楼主
麦米尔加弗德 发表于 2023-2-25 23:44 回帖奖励
本帖最后由 麦米尔加弗德 于 2023-2-27 17:30 编辑

自己写的油猴脚本,作为js练手的项目,里面加了很多的注释。变量名是因为我觉得下划线样式的好看,不要在意这种细节
大家可以提点意见和改进啥的,因为本人能力有限,所以尽量更新==

greasyfork下载地址:https://greasyfork.org/zh-CN/scripts/460184
演示视频:https://www.acfun.cn/v/ac40763378

快开快开,当然就是快啦!划一划,快速打开文本中的网盘链接!
支持20+网盘,能自动提取提取码和解压密码。同时为了防止忘记链接相关信息,还会整合提取码和解压密码在链接里面,更有解压密码提示助手,在浏览器的历史记录里面打开,就会跳出提醒框,一键复制解压密码!!!。以及有分享的KK链接,要说的都在链接里面,插件全帮你搞定,直接网址打开无需多言(对方也要装网盘快开插件才行)。还有前后台打开模式,快开和弹窗模式,设置最适合自己的。沉浸式上网冲浪!



[JavaScript] 纯文本查看 复制代码
// @name              网盘快开助手
// @namespace         https://github.com/maimierjiafude/KK_OpenPanHelper
// @version           1.1.0
// @author            龙龙龙
// @description       划一划,快速打开文本中的网盘链接,支持20+网盘,能自动提取提取码和解压密码。同时为了防止忘记链接相关信息,还会整合提取码和解压密码在链接里面,更有解压密码提示助手,在浏览器的历史记录里面打开,就会跳出提醒框,一键复制解压密码!!!。以及有分享的KK链接,要说的都在链接里面,插件全帮你搞定,直接网址打开无需多言(对方也要装网盘快开插件才行)。还有前后台打开模式,快开和弹窗模式,设置最适合自己的。沉浸式上网冲浪!
// @license           AGPL-3.0-or-later
// @supportURL        https://github.com/maimierjiafude/KK_OpenPanHelper
// @match             *://*/*
// @require           https://unpkg.com/sweetalert2@10.16.6/dist/sweetalert2.min.js
// @resource          swalStyle https://unpkg.com/sweetalert2@10.16.6/dist/sweetalert2.min.css
// @run-at            document-idle
// @grant             GM_openInTab
// @grant             GM_setValue
// @grant             GM_getValue
// @grant             GM_registerMenuCommand
// @grant             GM_getResourceText
// @grant             GM_setClipboard
// @grant             GM_info
// @icon              data:image/svg+xml;base64,PHN2ZyB0PSIxNjczOTcwMjM5NTk1IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE0MTMiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNNDcwLjIyOTMzMyA0NDkuMTA5MzMzbDY0IDAuMTA2NjY3TDUzMy4zMzMzMzMgOTQ5LjM5NzMzM2wtNjQtMC4xMjggMC44OTYtNTAwLjE2eiBtMzIuMjEzMzM0LTM4OC4yNjY2NjZsMTkwLjE4NjY2NiAxOTUuMDA4djE1Ni40OGwxOTUuNTYyNjY3IDE5NS41NjI2NjZWNzQ4LjhoLTE5NS45NDY2Njd2OTAuOTg2NjY3aC02NHYtMTE4Ljc0MTMzNGgwLjM4NFYyODEuODc3MzMzbC0xMjYuMTg2NjY2LTEyOS4zODY2NjYtMTI2LjE2NTMzNCAxMjkuMzY1MzMzIDAuOTE3MzM0IDQ2Ni4xMzMzMzNoLTAuMjk4NjY3djkxLjc5NzMzNGgtNjR2LTkxLjc5NzMzNEgxMTcuMzMzMzMzdi0xNDAuMDk2bDE5NS4yLTE5NS4yMjEzMzMtMC4yOTg2NjYtMTU2LjggMTkwLjIwOC0xOTUuMDI5MzMzeiBtMTkwLjE4NjY2NiA0NDIuMDA1MzMzVjY4NC44aDEzMS41NjI2Njd2LTUwLjM4OTMzM2wtMTMxLjU2MjY2Ny0xMzEuNTYyNjY3eiBtLTM3OS45MjUzMzMgMC4xNzA2NjdMMTgxLjMzMzMzMyA2MzQuMzg5MzMzdjQ5LjZoMTMxLjczMzMzNGwtMC4zNjI2NjctMTgwLjk3MDY2NnoiIGZpbGw9IiMxNjc3RkYiIHAtaWQ9IjE0MTQiPjwvcGF0aD48L3N2Zz4=
// ==/UserScript==

(function () {
    'use strict';

    // 在addPluginStyle里面配置style
    // 对于一些部件自定义调节css样式,可以防止和其他插件撞样式
    const customClass = {
        container: 'KK-panai-container',
        popup: 'KK-panai-popup',
        htmlContainer: 'KK-panai-htmlContainer',
        title: 'KK-panai-title',
        actions: 'KK-panai-actions',
    };

    // 工具汇总
    let util = {

        // 控制台成组输出,便于查找到log
        clog(c) {
            console.group("%c %c [网盘快开助手]", `background:url(${GM_info.script.icon}) center center no-repeat;background-size:12px;padding:3px`, "");
            console.log(c);
            console.groupEnd();
        },


        // 弹出框添加样式
        addStyle(id, tag, css) {
            tag = tag || 'style';
            let styleDom = document.getElementById(id);
            if (styleDom) return;
            let style = document.createElement(tag);
            style.rel = 'stylesheet';
            style.id = id;
            tag === 'style' ? style.innerHTML = css : style.href = css;
            document.head.appendChild(style);
        },

        // 存值取值
        getValue(name) {
            return GM_getValue(name);
        },

        setValue(name, value) {
            GM_setValue(name, value);
        },

        // 睡眠时间,可以和await async 配合使用
        sleep(time) {
            return new Promise((resolve) => setTimeout(resolve, time));
        },

        isHidden(el) {
            try {
                return el.offsetParent === null;
            } catch (e) {
                return false;
            }
        },

        // 构造的querySelector选择器,传入的参数可以是数组或者字符串
        query(selector) {
            if (Array.isArray(selector)) {
                let obj = null;
                for (let i = 0; i < selector.length; i++) {
                    let o = document.querySelector(selector[i]);
                    if (o) {
                        obj = o;
                        break;
                    }
                }
                return obj;
            }
            return document.querySelector(selector);
        },

        formatPanText(pan_obj) {
            let pan_text =
                '网盘:' + pan_obj.pan_name + '\n' +
                '链接:' + pan_obj.link + '\n' +
                (!!pan_obj.pwd ? '提取码:' + pan_obj.pwd + '\n' : '\n') +
                (!!pan_obj.zip ? '解压密码:' + pan_obj.zip : '')

            return pan_text;
        }
    };

    //弹窗事件汇总
    let popupNotifications = {

        // 快开模式下的复制提示弹窗,便于复制,不然复制不到,选中就打开了,悲
        copyPN(pan_obj) {
            let formatText = util.formatPanText(pan_obj);
            Swal.fire({
                toast: true,
                showCancelButton: true,
                position: 'top',
                title: `<span style="color: #2778c4;margin: 0 5px;">网盘快开助手(此窗口可设置不显示)</span>`,
                html: `<span style="font-size: 0.8em;display:block">  ${formatText.replace(/\n/g, '<br>')}  </span>`,
                confirmButtonText: '复制KK链接',
                cancelButtonText: '关闭',
                customClass
            }).then((res) => {
                if (res.isConfirmed || res.dismiss === 'timer') {
                    GM_setClipboard(main.kkLink(pan_obj));
                };
            });
        },

        // 弹窗模式下的打开提示弹窗,检测到链接,是否打开
        // 按钮弹窗
        openPN(pan_obj) {
            Swal.fire({
                toast: true,
                showCancelButton: true,
                position: 'top',
                title: `发现<span style="color: #2778c4;margin: 0 5px;">${pan_obj.pan_name}</span>链接`,
                html: `<span style="font-size: 0.8em;">${!!pan_obj.pwd ? '密码:' + pan_obj.pwd : '是否打开?'}</span>`,
                confirmButtonText: '打开',
                cancelButtonText: '关闭',
                customClass
            }).then((res) => {
                if (res.isConfirmed || res.dismiss === 'timer') {
                    let url = main.kkLink(pan_obj)
                    main.openHTML(url);
                };
            });
        },

        zipPN(url, zip) {
            Swal.fire({
                toast: true,
                showCancelButton: true,
                showConfirmButton:true,
                confirmButtonText: '复制KK链接',
                cancelButtonText: '关闭',
                position: 'top-start',
                padding:'1px',
                width:'300px',
                title:`<span style="color: #2778c4;margin: 0px;font-weight:bold">解压密码:${zip} </span><button id="KK_zipButton" style="width:60px;height:25px;cursor: pointer;border:none;border-radius: 2px;background: red; text-align: center;color: white;positon:curser">复 制</button>`,
                customClass
            }).then((res) => {
                if (res.isConfirmed){
                    GM_setClipboard(url);
                }
            })

            document.getElementById("KK_zipButton").addEventListener('click', () => {
                GM_setClipboard(zip);
                document.getElementById("KK_zipButton").innerHTML = "已复制";
            });



        },

        contactPN(){
            Swal.fire({
                toast:false,
                title: '&#128172; 反馈 & 建议',
                icon: 'success',
                html:`
                    打开<a  target="_blank">Github</a>发Issue<br>
                    打开<a  target="_blank">Greasyfork</a>给我留言
                    `,
                showCloseButton: false,
                confirmButtonText:'好的',
                customClass
            })
        }
    };

    // 选项,网盘的正则,组件的打包内容
    // hash应该就是域名匹配,而local需要借助本地存储
    let opt = {
        'baidu': {
            reg: /((?:https?:\/\/)?(?:e?yun|pan)\.baidu\.com\/(doc\/|enterprise\/)?(?:s\/[\w~]*(((-)?\w*)*)?|share\/\S{4,}))/,
            host: /(pan|e?yun)\.baidu\.com/,
            input: ['#accessCode', '.share-access-code', '#wpdoc-share-page > .u-dialog__wrapper .u-input__inner'],
            button: ['#submitBtn', '.share-access .g-button', '#wpdoc-share-page > .u-dialog__wrapper .u-btn--primary'],
            name: '百度网盘',
            storage: 'hash'
        },
        'aliyun': {
            reg: /((?:https?:\/\/)?(?:(?:www\.)?aliyundrive\.com\/s|alywp\.net)\/[a-zA-Z\d]+)/,
            host: /www\.aliyundrive\.com|alywp\.net/,
            input: ['form .ant-input', 'form input[type="text"]'],
            button: ['form .button--fep7l', 'form button[type="submit"]'],
            name: '阿里云盘',
            storage: 'hash'
        },
        'weiyun': {
            reg: /((?:https?:\/\/)?share\.weiyun\.com\/[a-zA-Z\d]+)/,
            host: /share\.weiyun\.com/,
            input: ['.mod-card-s input[type=password]'],
            button: ['.mod-card-s .btn-main'],
            name: '微云',
            storage: 'hash'
        },
        'lanzou': {
            reg: /((?:https?:\/\/)?(?:[a-zA-Z0-9\-.]+)?lanzou[a-z]\.com\/[a-zA-Z\d_\-]+)/,
            host: /(?:[a-zA-Z\d-.]+)?lanzou[a-z]\.com/,
            input: ['#pwd'],
            button: ['.passwddiv-btn', '#sub'],
            name: '蓝奏云',
            storage: 'hash'
        },
        'tianyi': {
            reg: /((?:https?:\/\/)?cloud\.189\.cn\/(?:t\/|web\/share\?code=)?[a-zA-Z\d]+)/,
            host: /cloud\.189\.cn/,
            input: ['.access-code-item #code_txt'],
            button: ['.access-code-item .visit'],
            name: '天翼云盘',
            storage: 'hash'
        },
        'caiyun': {
            reg: /((?:https?:\/\/)?caiyun\.139\.com\/(?:m\/i|w\/i\/|web\/|front\/#\/detail)\??(?:linkID=)?[a-zA-Z\d]+)/,
            host: /caiyun\.139\.com/,
            input: ['.token-form input[type=text]'],
            button: ['.token-form .btn-token'],
            name: '移动云盘',
            storage: 'local',
            storagePwdName: 'tmp_caiyun_pwd'
        },
        'xunlei': {
            reg: /((?:https?:\/\/)?pan\.xunlei\.com\/s\/[\w-]{10,})/,
            host: /pan\.xunlei\.com/,
            input: ['.pass-input-wrap .td-input__inner'],
            button: ['.pass-input-wrap .td-button'],
            name: '迅雷云盘',
            storage: 'hash'
        },
        '123pan': {
            reg: /((?:https?:\/\/)?www\.123pan\.com\/s\/[\w-]{6,})/,
            host: /www\.123pan\.com/,
            input: ['.ca-fot input'],
            button: ['.ca-fot button'],
            name: '123云盘',
            storage: 'hash'
        },
        '360': {
            reg: /((?:https?:\/\/)?(?:[a-zA-Z\d\-.]+)?yunpan\.360\.cn(\/lk)?\/surl_\w{6,})/,
            host: /yunpan\.360\.cn/,
            input: ['.pwd-input'],
            button: ['.submit-btn'],
            name: '360云盘',
            storage: 'hash'
        },
        '115': {
            reg: /((?:https?:\/\/)?115\.com\/s\/[a-zA-Z\d]+)/,
            host: /115\.com/,
            input: ['.form-decode input'],
            button: ['.form-decode .submit a'],
            name: '115网盘',
            storage: 'hash'
        },
        'cowtransfer': {
            reg: /((?:https?:\/\/)?(?:[a-zA-Z\d-.]+)?cowtransfer\.com\/s\/[a-zA-Z\d]+)/,
            host: /(?:[a-zA-Z\d-.]+)?cowtransfer\.com/,
            input: ['.receive-code-input input'],
            button: ['.open-button'],
            name: '奶牛快传',
            storage: 'hash'
        },
        'ctfile': {
            reg: /((?:https?:\/\/)?(?:[a-zA-Z\d-.]+)?ctfile\.com\/\w+\/[a-zA-Z\d-]+)/,
            host: /(?:[a-zA-Z\d-.]+)?ctfile\.com/,
            input: ['#passcode'],
            button: ['.card-body button'],
            name: '城通网盘',
            storage: 'hash'
        },
        'quark': {
            reg: /((?:https?:\/\/)?pan\.quark\.cn\/s\/[a-zA-Z\d-]+)/,
            host: /pan\.quark\.cn/,
            input: ['.ant-input'],
            button: ['.ant-btn-primary'],
            name: '夸克网盘',
            storage: 'local',
            storagePwdName: 'tmp_quark_pwd'
        },
        'flowus': {
            reg: /((?:https?:\/\/)?flowus\.cn\/[\S ^\/]*\/?share\/[a-z\d]{8}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{12})/,
            host: /flowus\.cn/,
            name: 'FlowUs息流',
            storage: 'hash'
        },
        'chrome': {
            reg: /https?:\/\/chrome.google.com\/webstore\/.+\w/,
            host: /chrome\.google\.com/,
            replaceHost: "chrome.crxsoso.com",
            name: 'Chrome商店',
        },
        'edge': {
            reg: /^https?:\/\/microsoftedge.microsoft.com\/addons\/.+?\/([a-z]{32})(?=[\/#?]|$)/,
            host: /microsoftedge\.microsoft\.com/,
            replaceHost: "microsoftedge.crxsoso.com",
            name: 'Edge商店',
        },
        'firefox': {
            reg: /^https?:\/\/(reviewers\.)?(addons\.mozilla\.org|addons(?:-dev)?\.allizom\.org)\/.*?(?:addon|review)\/([^/<>"'?#]+)/,
            host: /addons\.mozilla\.org/,
            replaceHost: "addons.crxsoso.com",
            name: 'Firefox商店',
        },
        'microsoft': {
            reg: /^https?:\/\/(?:apps|www).microsoft.com\/(?:store|p)\/.+?\/([a-zA-Z\d]{10,})(?=[\/#?]|$)/,
            host: /(apps|www)\.microsoft\.com/,
            replaceHost: "apps.crxsoso.com",
            name: 'Windows商店',
        },
    };

    // 解析总类
    let parse = {

        // 记忆上一次的密码,从而防止选择完以后还触发相同事件
        lastText: "long",

        // 解析selection
        parseSelection(text) {
            let pan_obj = this.parseEngine(text);

            if (!pan_obj.link) {
                let nameAndLinkObj = this.parseALink(window.getSelection());
                if(nameAndLinkObj){
                    pan_obj.pan_name = nameAndLinkObj.pan_name;
                    pan_obj.link = nameAndLinkObj.link;
                }     
            };

            return pan_obj;
        },

        // 解析Clipboard
        parseClipboard(text) {
            let pan_obj = this.parseEngine(text);
            return pan_obj;
        },

        // 对于解析的总方法
        // 返回一个对象
        parseEngine(text) {
            let pan_obj = {
                pan_name: '',
                link: '',
                pwd: '',
                zip: '',
            };

            // 获取提取码
            pan_obj.pwd = this.parsePwd(text);

            // 获取解压码
            pan_obj.zip = this.parseZipPasswords(text);

            // 文字替换
            text = this.textFliter(text);

            // 获取pan的名字和text中的link
            // pan_obj.pan_name, pan_obj.link = this.parseLink(text);
            // 返回值只能有一个。
            let nameAndLinkObj = this.parseLink(text);
            pan_obj.pan_name = nameAndLinkObj.pan_name;
            pan_obj.link = nameAndLinkObj.link;

            return pan_obj;

        },

        //正则解析超链接类型网盘链接
        // &#9888;&#65039;可能会增加时间&#9888;&#65039; 如果有需要可以增加选项
        // 获取选择内容的HTML和文本(增加兼容性) 或 DOM(节点遍历)
        // 使用chatGPT生成并修改
        parseALink(selection) {           
            if (!selection.isCollapsed) {
                const range = selection.getRangeAt(0);
                const commonAncestor = range.commonAncestorContainer;
                if (typeof(commonAncestor.querySelector) !== 'undefined') {
                    const links = commonAncestor.querySelector('*[href]')
                    return this.parseLink(links ? links.href : "");
                }

            }
            return ;
        },

        // 选中文字的替换规则
        textFliter(text) {
            if (text) {
                try {
                    text = decodeURIComponent(text);
                } catch {
                }
            };
            text = text.replace(/[点點]/g, '.');
            text = text.replace(/[\u4e00-\u9fa5\u200B()(),,]/g, '');
            text = text.replace(/lanzous/g, 'lanzouw'); //修正lanzous打不开的问题
            return text
        },

        //正则解析提取码
        // 这里的?<=正向后发断言 看文档说JS不支持,但是目前呢能用,以后改吧
        parsePwd(text) {
            text = text.replace(/\u200B/g, '');
            let reg = /(?<=\s*(?:密|提取|访问|訪問|key|password|pwd|#)\s*[码碼]?\s*[::=]?\s*)[a-zA-Z0-9]{3,8}\w/i;
            if (reg.test(text)) {
                let match = text.match(reg);
                return match[0];
            }
            return '';
        },

        //正则解析解压密码
        parseZipPasswords(text) {
            let zip_reg = /(?<=\s*(?:解压|解压密)\s*[码碼]\s*)[::=]?\s*(.+?)\s/;
            if (zip_reg.test(text)) {
                let match = text.match(zip_reg);
                return match[1];
            }

            let zip_hash_reg = /#zip(.+)zip/;
            if (zip_hash_reg.test(text)){
                let match = text.match(zip_hash_reg);
                return match[1];
            }

            return '';
        },
        // 正则解析链接
        parseLink(text) {
            let nameAndLinkObj = { pan_name: '', link: '' };

            for (let pan_name in opt) {
                let val = opt[pan_name];
                if (val.reg.test(text)) {
                    let matches = text.match(val.reg);
                    nameAndLinkObj.pan_name = val.name;
                    nameAndLinkObj.link = matches[0];
                    if (val.replaceHost) {
                        nameAndLinkObj.link = nameAndLinkObj.link.replace(val.host, val.replaceHost);
                    }
                    return nameAndLinkObj;
                }
            };
            return nameAndLinkObj;
        },

        // 优化筛选输入的string,没有四个以上字母的通通抬走呢
        parsePreTextAndReturn(data) {

            let text_reg = /[A-z]{4,}/g;

            if (data == this.lastText || data == '') {
                return;
            } else if (data.length > 200) {
                return;
            } else if (!text_reg.test(data)) {
                return;
            }

            this.lastText = data;

            return true;
        },

        // 网址解析
        parseQuery(name) {
            let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
            let r = location.search.substring(1).match(reg);
            if (r != null) return (r[2]);

            return null;
        },

        // 专门为百度准备的解析,因为要本地存储比对
        parseBaidLink(url) {
            let baidu_reg = /(?:https?:\/\/)?(?:e?yun|pan)\.baidu\.com\/(?:s\/|share\/init\?surl=)(.+?)(?:\?|&)/;
            if (baidu_reg.test(url)){
                let match = url.match(baidu_reg);
                return match[1];
            }
            return;
        }

    };

    // 主要代码逻辑
    let main = {

        // 初始化配置数据
        // KK_setting_open_model false 快开模式;true 弹窗模式
        // KK_setting_active true 后台打开,false 新窗口打开
        // KK_setting_show_copyPN 是否显示快开模式的弹窗 yes 是
        // KK_local_data 需要本地保存的用于缓冲数据
        initValue() {
            let value = [{
                name: 'KK_setting_open_model',
                value: true
            }, {
                name: 'KK_setting_active',
                value: true
            }, {
                name: 'KK_setting_show_copyPN',
                value: true
            }, {
                name: 'KK_local_data',
                value: {
                    'url': '',
                    'code': '', 
                    'zip': ''
                }
            }];
            
            value.forEach((v) => {
                if (util.getValue(v.name) === undefined) {
                    util.setValue(v.name, v.value);
                }
            });
        },

        // 监听选择事件
        addPageListener() {

            // 监听,mouseup并绑定函数
            // 绑定函数 document.onmouseup = () => {} 
            //document.addEventListener("mouseup", this.getSelectionAndParse.bind(this), true);
            document.addEventListener("mouseup", () => {
                this.root('selection', window.getSelection().toString())
            });

            // 粘贴事件选择
            window.addEventListener("paste", (e) => {
                let clipdata = e.clipboardData || window.clipboardData;
                let cliptext = clipdata.getData("text/plain")
                this.root('paste', cliptext);
            });

            // 快捷按键操作
            document.addEventListener("keydown", (e) => {
                this.pressKey(e)
            });
        },

        // 读取模式,并与之打开网页
        openHTML(url){
            let active = util.getValue('KK_setting_active');
            GM_openInTab(url, { active });
        },

        // 构造kk链接,返回一个url
        kkLink(pan_obj) {
            let pan_name = pan_obj.pan_name;
            let link = pan_obj.link;
            let pwd = pan_obj.pwd;
            let zip = pan_obj.zip;

            if (pan_name === 'caiyun') {  //移动云盘无法携带参数和Hash
                util.setValue('tmp_caiyun_pwd', pwd);
            }
            if (pan_name === 'quark') {
                util.setValue('tmp_quark_pwd', pwd);
            }

            
            let url = link;

            if (pwd) {
                let extra = `${link}?pwd=${pwd}#${pwd}`;
                if (~link.indexOf('?')) {
                    extra = `${link}&pwd=${pwd}#${pwd}`;
                }
                url = extra;
            } 

            if (zip){
                url = `${url}#zip${encodeURI(zip)}zip`
            }

            return url;
        },

        // 事件入口
        root(event, data = '') {
            let pan_obj = {};

            if (!parse.parsePreTextAndReturn(data)) {
                return;
            }

            // 粘贴事件
            if (event == 'paste') {
                pan_obj = parse.parseClipboard(data);
            };

            // 鼠标选中事件
            if (event == 'selection') {
                pan_obj = parse.parseSelection(data);
            };

            // 熔断机制
            if (!pan_obj.link) {
                return
            };

            util.clog('获取到链接了!')
            parse.lastText = 'long';
            (event == 'selection' ) ? window.getSelection().empty():'';

            let KK_setting_open_model = util.getValue('KK_setting_open_model');
            let KK_setting_show_copyPN = util.getValue('KK_setting_show_copyPN');

            if (KK_setting_open_model) {
                let url = this.kkLink(pan_obj);
                this.openHTML(url)
                if (KK_setting_show_copyPN) { 
                    popupNotifications.copyPN(pan_obj)
                };
            } else {
                popupNotifications.openPN(pan_obj)
            };

        },

        // 快捷键操作,Enter确定,Esc退出
        pressKey(event) {
            if (event.key === 'Enter') {
                let confirmBtn = document.querySelector('.KK-panai-container .swal2-confirm');
                confirmBtn && confirmBtn.click();
            }
            if (event.key === 'Escape') {
                let cancelBtn = document.querySelector('.KK-panai-container .swal2-cancel');
                cancelBtn && cancelBtn.click();
            }
        },

        //根据域名检测网盘类型,返回值是opt的key
        panDetectReturnName() {
            let hostname = location.hostname;
            for (let name in opt) {
                let val = opt[name];
                if (val.host.test(hostname)) {
                    return name;
                }
            }
            return
        },

        // 本地存储百度的特征码和解压密码
        saveBaiduData(baidu_save_code, zip){
            if(baidu_save_code && zip){
                util.setValue('KK_local_data', {
                    'code':baidu_save_code, 
                    'zip':zip
                });
            }
        },

        // 监听url的hash变化,并且进行当前url的替换,在hash值里面加入解压密码
        watchUrlHashChange(zip){
            if( ("onhashchange" in window) && ((typeof document.documentMode==="undefined") || document.documentMode==8)) {
                window.onhashchange = () => {
                    if (location.hash.toString().indexOf("#zip") == -1) {
                        location.hash = '#zip' + zip + 'zip'+ location.hash
                    };
                };
            }
        },

        //自动填写密码
        autoFillPassword() {
            let panType = this.panDetectReturnName();
            if (!panType){
                return;
            };

            let url = location.href;
            let pwd_query = parse.parseQuery('pwd');
            let pwd_hash = location.hash.slice(1);
            
            let baidu_save_code = parse.parseBaidLink(url)

            let zip = '';
            let zip_hash_reg = /#zip(.+)zip/;
            if (zip_hash_reg.test(pwd_hash)){
                zip = pwd_hash.match(zip_hash_reg)[1];
                zip = decodeURI(zip);
                pwd_hash = pwd_hash.replace((pwd_hash.match(zip_hash_reg)[0]),'');
            }

            let pwd = pwd_query || pwd_hash;

            for (let name in opt) {
                let val = opt[name];
                if (panType === name) {
                    if (val.storage === 'local') {
                        pwd = util.getValue(val.storagePwdName) ? util.getValue(val.storagePwdName) : '';
                        pwd && this.doFillAction(val.input, val.button, pwd);
                    }

                    if (val.storage === 'hash') {
                        if (!/^[a-zA-Z0-9]{3,8}$/.test(pwd)) { //过滤掉不正常的Hash
                            return;
                        }
                        pwd && this.doFillAction(val.input, val.button, pwd);
                    }
                }
            }
            this.saveBaiduData(baidu_save_code, zip)
            let baidu_data = util.getValue('KK_local_data');
            if (url.indexOf(baidu_data.code) && !zip){
                zip = baidu_data.zip;
                location.hash = '#zip' + zip + 'zip'+ location.hash
                url = location.href;
            };

            if (zip && baidu_save_code){
                this.watchUrlHashChange(zip);  
            };

            zip && popupNotifications.zipPN(url,zip);

        },

        // 进行填写
        doFillAction(inputSelector, buttonSelector, pwd) {
            let maxTime = 10;
            // async函数才能使用await
            let ins = setInterval(async () => {
                maxTime--;
                let input = util.query(inputSelector);
                let button = util.query(buttonSelector);

                if (input && !util.isHidden(input)) {
                    clearInterval(ins);

                    let lastValue = input.value;
                    input.value = pwd;

                    //Vue & React 触发 input 事件
                    let event = new Event('input', { bubbles: true });
                    let tracker = input._valueTracker;
                    if (tracker) {
                        tracker.setValue(lastValue);
                    }
                    input.dispatchEvent(event);

                    await util.sleep(200); //0.2秒后点击按钮
                    button.click();

                } else {
                    maxTime === 0 && clearInterval(ins);
                }
            }, 800);
        },


        // 显示设置
        showSettingBox() {
            let html = `<div style="font-size: 1em;">
                            <label class="KK-panai-setting-label">插件运行模式
                                <select id="KK-Model" class="KK-panai-setting-select">
                                    <option>快开模式</option>
                                    <option>弹窗模式</option>
                                </select>
                            </label>
                            <label class="KK-panai-setting-label" id="KK-checkbox-show-copyPN" style="${util.getValue('KK_setting_open_model') ? 'display: flex' : 'display: none'}">快开模式显示复制弹窗
                                <input type="checkbox" class="KK-panai-setting-checkbox" ${util.getValue('KK_setting_show_copyPN') ? 'checked' : ''} >
                            </label>
                            <label class="KK-panai-setting-label">新窗口打开方式
                                <select id="KK-Active" class="KK-panai-setting-select">
                                    <option>新窗口打开</option>
                                    <option>后台打开</option>
                                </select>
                            </label>
                        </div>`;
            Swal.fire({
                title: '快开助手配置',
                html,
                icon: 'info',
                showCloseButton: true,
                confirmButtonText: '保存',
                footer: '<div style="text-align: center;font-size: 1em;">点击查看 <a  target="_blank">Github</a>,Powered by 龙龙龙</a></div>',
                customClass
            }).then((res) => {
                // history.go(0)刷新
                // location.reload()刷新
                res.isConfirmed && location.reload();
            });

            document.getElementById('KK-Model').selectedIndex = (util.getValue('KK_setting_open_model') ? 0 : 1);
            document.getElementById('KK-Model').addEventListener('change', () => {
                let KK_checkbox_show_copyPN = document.getElementById('KK-checkbox-show-copyPN');
                KK_checkbox_show_copyPN.style.display = (!util.getValue('KK_setting_open_model')? 'flex' : 'none')
                util.setValue('KK_setting_open_model', !util.getValue('KK_setting_open_model'));
            });

            document.getElementById('KK-Active').selectedIndex = (util.getValue('KK_setting_active') ? 0 : 1);
            document.getElementById('KK-Active').addEventListener('change', () => {
                util.setValue('KK_setting_active', !util.getValue('KK_setting_active'));
            });

            document.getElementById("KK-checkbox-show-copyPN").addEventListener('change', () => {
                util.setValue('KK_setting_show_copyPN', !util.getValue('KK_setting_show_copyPN'));
            });
        },

        // 菜单注册
        registerMenuCommand() {

            GM_registerMenuCommand('&#128172; 反馈 & 建议', () => {
                // 这里填我的联系方式
                // 弹出框,邮箱,github
                popupNotifications.contactPN()
            });

            GM_registerMenuCommand('&#9881;&#65039; 设置', () => {
                this.showSettingBox();
            });

        },

        // 样式总控制
        addPluginStyle() {
            let style = `
                .KK-panai-title {text-align: center !important; }
                .KK-panai-container { z-index: 99999!important; text-align: center !important; }
                .KK-panai-popup { font-size: 14px !important; text-align: center !important; }
                .KK-panai-htmlContainer{ margin: 2px !important; padding:1px !important;}
                .KK-panai-actions {justify-content: center!important; align-items: center;}
                .KK-panai-setting-label { display: flex;align-items: center;justify-content: space-between;padding-top: 20px; }
                .KK-panai-setting-select { width: 150px;height: 30px;font-size: 1em; }
                .KK-panai-setting-checkbox { width: 16px;height: 16px; }
            `;

            if (document.head) {
                util.addStyle('KK-swal-style', 'style', GM_getResourceText('swalStyle'));
                util.addStyle('KK-panai-style', 'style', style);
            }

            const headObserver = new MutationObserver(() => {
                util.addStyle('KK-swal-style', 'style', GM_getResourceText('swalStyle'));
                util.addStyle('KK-panai-style', 'style', style);
            });
            headObserver.observe(document.head, { childList: true, subtree: true });
        },

        // 是否最前
        isTopWindow() {
            return window.self === window.top;
        },

        init() {
            this.initValue();
            this.addPluginStyle();
            this.autoFillPassword();
            this.addPageListener();
            this.isTopWindow() && this.registerMenuCommand();
        },
    };

    main.init();
})();

免费评分

参与人数 30吾爱币 +32 热心值 +26 收起 理由
行酒令 + 1 + 1 谢谢@Thanks!
arsleeli + 1 + 1 我很赞同!
xxxxx777xxxx + 1 + 1 谢谢@Thanks!
ylym8888 + 1 鼓励转贴优秀软件安全工具和文档!
抱歉、 + 1 谢谢@Thanks!
Μs丶兄弟 + 2 + 1 热心回复!
weschan + 1 我很赞同!
junjia215 + 1 + 1 用心讨论,共获提升!
l146 + 1 用心讨论,共获提升!
zj1091953645 + 1 + 1 谢谢@Thanks!
知非胜改 + 1 + 1 太牛逼了,为大家节省了时间
Bob5230 + 1 + 1 我很赞同!
侃遍天下无二人 + 4 + 1 热心回复!
SBKK123456 + 1 + 1 我很赞同!
qwt99987 + 1 谢谢@Thanks!
小竹竿 + 1 + 1 谢谢@Thanks!
vinafule + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
yangtao868 + 1 + 1 我很赞同!
lztym + 1 + 1 谢谢@Thanks!
安道尔的鱼 + 1 + 1 热心回复!
ty256949 + 1 + 1 谢谢@Thanks!
w-c-f5522 + 1 + 1 谢谢@Thanks!
愚无尽 + 2 感谢发布原创作品,吾爱破解论坛因你更精彩!
mywebzone + 1 + 1 热心回复!
shiqiangge + 1 我很赞同!
cdwdz + 1 + 1 谢谢@Thanks!
Jxdm + 1 + 1 我很赞同!
jy00812995 + 1 + 1 谢谢@Thanks!
cntjgaowei + 1 + 1 谢谢@Thanks!
zzhaoxue + 1 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| 麦米尔加弗德 发表于 2023-2-26 17:57 |楼主
本帖最后由 麦米尔加弗德 于 2023-2-26 18:18 编辑
小小/ng 发表于 2023-2-26 17:27
https://greasyfork.org/zh-CN/scripts/422773-%E9%93%BE%E6%8E%A5%E5%8A%A9%E6%89%8B
文本转链接

我试了一下,对于这个链接没有反应
源碼:htt刪ps://ww刪gu.lanz刪ouh.刪com/ifaDD刪0mdwwuf
而且这个帖子下面的蓝奏云链接,点开不会自动填写密码
https://www.52pojie.cn/thread-1749826-1-1.html

而且我在我经常逛的论坛试了一下,没办法获取附近的提取码,还是要自己填写,另外也缺失对于解压密码的支持。不过里面还是有很多思路我可以借鉴的,我知道脚本后续更新一些什么内容会比较好了
再次感谢

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
小小/ng + 1 + 1 用心讨论,共获提升!

查看全部评分

推荐
初梦初笑 发表于 2023-3-6 04:05
麦米尔加弗德 发表于 2023-2-26 17:57
我试了一下,对于这个链接没有反应
源碼:htt刪ps://ww刪gu.lanz刪ouh.刪com/ifaDD刪0mdwwuf
而且这个 ...

用这个试试看
[Java] 纯文本查看 复制代码
// ==UserScript==
// [url=home.php?mod=space&uid=170990]@name[/url]              网盘智能识别助手
// [url=home.php?mod=space&uid=467642]@namespace[/url]         https://github.com/syhyz1990/panAI
// [url=home.php?mod=space&uid=1248337]@version[/url]           1.8.8
// [url=home.php?mod=space&uid=686208]@AuThor[/url]            YouXiaoHou
// @description       智能识别选中文字中的&#128279;网盘链接和&#128273;提取码,识别成功打开网盘链接并自动填写提取码,省去手动复制提取码在输入的烦恼。支持识别 &#9989;百度网盘 &#9989;阿里云盘 &#9989;腾讯微云 &#9989;蓝奏云 &#9989;天翼云盘 &#9989;移动云盘 &#9989;迅雷云盘 &#9989;123云盘 &#9989;360云盘 &#9989;115网盘 &#9989;奶牛快传 &#9989;城通网盘 &#9989;夸克网盘 &#9989;FlowUs息流 &#9989;Chrome 扩展商店 &#9989;Edge 扩展商店 &#9989;Firefox 扩展商店 &#9989;Windows 应用商店。
// @license           AGPL-3.0-or-later
// @homepage          https://www.youxiaohou.com/tool/install-panai.html
// @supportURL        https://github.com/syhyz1990/panAI
// [url=home.php?mod=space&uid=195849]@match[/url]             *://*/*
// @require           https://unpkg.com/sweetalert2@10.16.6/dist/sweetalert2.min.js
// @require           https://unpkg.com/hotkeys-js/dist/hotkeys.min.js
// @resource          swalStyle https://unpkg.com/sweetalert2@10.16.6/dist/sweetalert2.min.css
// @run-at            document-idle
// @grant             GM_openInTab
// @grant             GM_setValue
// @grant             GM_getValue
// @grant             GM_registerMenuCommand
// @grant             GM_getResourceText
// @grant             GM_info
// @icon              data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48cGF0aCBkPSJNMTAzLjYgMTA3LjRjMy41LTIuMiA4LjktNi4xIDEzLjgtMTIuNXM3LjMtMTIuNSA4LjUtMTYuNWMuNS0xLjcgMi4yLTcuNSAyLjItMTQuNyAwLTEwLjEtMy4zLTI1LjEtMTUuNC0zNi44LTE0LjUtMTQtMzIuMS0xNC4zLTM1LjctMTQuMy04IDAtMTUuNyAxLjktMjIuNiA1LjJDNDQgMjMgMzUuNyAzMS40IDMwLjggNDEuN2MtMS4zIDIuOC00IDQuNy03LjEgNS00IC4zLTcuNSA0LjQtOC45IDkuNi0uNSAxLjktMS42IDMuNS0zLjEgNC43QzQuNCA2Ni44IDAgNzUuNyAwIDg1YzAgNi44IDIuMyAxMy4xIDYuMSAxOC4yIDUuNSA3LjQgMTQuMiAxMi4yIDI0IDEyLjJoNDcuMWM0LjQgMCAxMS0uNSAxOC4zLTMuNSAzLjItMS40IDUuOS0zIDguMS00LjV6IiBmaWxsPSIjNDQ0Ii8+PHBhdGggZD0iTTExOS44IDY0LjNjLjEtMTcuMS0xMC40LTI4LTEyLjUtMzAuMUM5NSAyMi4xIDc5LjkgMjEuOCA3Ni45IDIxLjhjLTE3LjYgMC0zMy4zIDEwLjUtMzkuOSAyNi43LS42IDEuMy0xLjggMi4zLTMuNCAyLjNoLS40Yy01LjggMC0xMC42IDQuOC0xMC42IDEwLjd2LjVjMCAxLjQtLjggMi42LTEuOSAzLjNDMTMuNCA2OSA4LjggNzYuOCA4LjggODVjMCAxMi4yIDkuOSAyMi4zIDIyLjIgMjIuM2g0NS4yYzMuNi0uMSAxNy42LS45IDI5LjYtMTIgMi45LTIuOCAxMy45LTEzLjcgMTQtMzF6IiBmaWxsPSIjZGI4NDEyIi8+PHBhdGggZD0iTTExMC44IDU3LjRsLjIgMy4zYzAgMS4zLTEuMSAyLjQtMi4zIDIuNC0xLjMgMC0yLjMtMS4xLTIuMy0yLjRsLS4xLTIuOHYtLjNjMC0xLjIuOS0yLjIgMi4xLTIuM2guM2MuNyAwIDEuMy4zIDEuNy43LS4yLjEuMy41LjQgMS40em0tMy4zLTEwLjNjMCAxLjItMSAyLjMtMi4yIDIuM2gtLjFjLS44IDAtMS42LS41LTItMS4yLTQuNi04LjMtMTMuMy0xMy41LTIyLjgtMTMuNS0xLjIgMC0yLjMtMS0yLjMtMi4ydi0uMWMwLTEuMiAxLTIuMyAyLjItMi4zaC4xYTMwLjM3IDMwLjM3IDAgMCAxIDE1LjggNC40YzQuNiAyLjggOC40IDYuOCAxMS4xIDExLjUuMS4zLjIuNy4yIDEuMXpNNjkuMiA0OWwxOS40IDE0LjhjMS45IDEuNSAzLjEgMy41IDMuNSA1Ljd2LjJjLjEuNC4xLjguMSAxLjIgMCAuNi0uMSAxLjEtLjIgMS42LS40IDIuMi0xLjcgNC4yLTMuNSA1LjZMNjkuMyA5M2MtMi42IDItNS40IDIuNS03LjcgMS40LS4xLS4xLS4yLS4xLS4yLS4yLTItMS4yLTMuMi0zLjUtMy4yLTYuNHYtNi42aC01LjdjLTYuOCAwLTEyLTQuNy0xMi0xMC45IDAtNC44IDIuNi04LjUgNy4yLTEwLjMgMS4zLS41IDIuNy4yIDMuMiAxLjVzLS4xIDIuOC0xLjQgMy4zYy0yLjcgMS4xLTQgMi45LTQgNS41IDAgMy41IDMgNiA3IDZoOC4xYy41IDAgMSAuMiAxLjQuNi43LjYgMS4xIDEuNyAxLjEgMi42djguNGMwIDEuMy40IDIgLjcgMi4xLjQuMiAxLjMgMCAyLjQtLjlsMTkuMi0xNC45YzEuMi0uOSAxLjgtMi4xIDEuOC0zLjNzLS42LTIuMy0xLjctMy4xTDY2LjIgNTNjLTEuMS0uOS0yLTEuMS0yLjQtLjktLjMuMi0uNy45LS43IDIuMXY3LjZjMCAuOS0uNSAxLjctMS4yIDIuMS0uNC4zLS44LjQtMS4zLjQtMS40IDAtMi41LTEuMS0yLjUtMi41di03LjZjMC0zLjEgMS4zLTUuNSAzLjUtNi42bC43LS4zYzIuMS0uNyA0LjYtLjEgNi45IDEuN3oiIGZpbGw9IiM0NDQiLz48L3N2Zz4=
// ==/UserScript==

(function () {
    'use strict';

    const customClass = {
        container: 'panai-container',
        popup: 'panai-popup',
    };

    let toast = Swal.mixin({
        toast: true,
        position: 'top',
        showConfirmButton: false,
        timer: 3500,
        timerProgressBar: false,
        didOpen: (toast) => {
            toast.addEventListener('mouseenter', Swal.stopTimer);
            toast.addEventListener('mouseleave', Swal.resumeTimer);
        }
    });

    let util = {
        clog(c) {
            console.group("%c %c [网盘智能识别助手]", `background:url(${GM_info.script.icon}) center center no-repeat;background-size:12px;padding:3px`, "");
            console.log(c);
            console.groupEnd();
        },

        parseQuery(name) {
            let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
            let r = location.search.substr(1).match(reg);
            if (r != null) return (r[2]);
            return null;
        },

        getValue(name) {
            return GM_getValue(name);
        },

        setValue(name, value) {
            GM_setValue(name, value);
        },

        sleep(time) {
            return new Promise((resolve) => setTimeout(resolve, time));
        },

        addStyle(id, tag, css) {
            tag = tag || 'style';
            let doc = document, styleDom = doc.getElementById(id);
            if (styleDom) return;
            let style = doc.createElement(tag);
            style.rel = 'stylesheet';
            style.id = id;
            tag === 'style' ? style.innerHTML = css : style.href = css;
            document.head.appendChild(style);
        },

        isHidden(el) {
            try {
                return el.offsetParent === null;
            } catch (e) {
                return false;
            }
        },

        query(selector) {
            if (Array.isArray(selector)) {
                let obj = null;
                for (let i = 0; i < selector.length; i++) {
                    let o = document.querySelector(selector[i]);
                    if (o) {
                        obj = o;
                        break;
                    }
                }
                return obj;
            }
            return document.querySelector(selector);
        }
    };

    let opt = {
        'baidu': {
            reg: /((?:https?:\/\/)?(?:e?yun|pan)\.baidu\.com\/(doc\/|enterprise\/)?(?:s\/[\w~]*(((-)?\w*)*)?|share\/\S{4,}))/,
            host: /(pan|e?yun)\.baidu\.com/,
            input: ['#accessCode', '.share-access-code', '#wpdoc-share-page > .u-dialog__wrapper .u-input__inner'],
            button: ['#submitBtn', '.share-access .g-button', '#wpdoc-share-page > .u-dialog__wrapper .u-btn--primary'],
            name: '百度网盘',
            storage: 'hash'
        },
        'aliyun': {
            reg: /((?:https?:\/\/)?(?:(?:www\.)?aliyundrive\.com\/s|alywp\.net)\/[a-zA-Z\d]+)/,
            host: /www\.aliyundrive\.com|alywp\.net/,
            input: ['form .ant-input', 'form input[type="text"]'],
            button: ['form .button--fep7l', 'form button[type="submit"]'],
            name: '阿里云盘',
            storage: 'hash'
        },
        'weiyun': {
            reg: /((?:https?:\/\/)?share\.weiyun\.com\/[a-zA-Z\d]+)/,
            host: /share\.weiyun\.com/,
            input: ['.mod-card-s input[type=password]'],
            button: ['.mod-card-s .btn-main'],
            name: '微云',
            storage: 'hash'
        },
        'lanzou': {
            reg: /((?:https?:\/\/)?(?:[a-zA-Z0-9\-.]+)?lanzou[a-z]\.com\/[a-zA-Z\d_\-]+)/,
            host: /(?:[a-zA-Z\d-.]+)?lanzou[a-z]\.com/,
            input: ['#pwd'],
            button: ['.passwddiv-btn', '#sub'],
            name: '蓝奏云',
            storage: 'hash'
        },
        'tianyi': {
            reg: /((?:https?:\/\/)?cloud\.189\.cn\/(?:t\/|web\/share\?code=)?[a-zA-Z\d]+)/,
            host: /cloud\.189\.cn/,
            input: ['.access-code-item #code_txt'],
            button: ['.access-code-item .visit'],
            name: '天翼云盘',
            storage: 'hash'
        },
        'caiyun': {
            reg: /((?:https?:\/\/)?caiyun\.139\.com\/(?:m\/i|w\/i\/|web\/|front\/#\/detail)\??(?:linkID=)?[a-zA-Z\d]+)/,
            host: /caiyun\.139\.com/,
            input: ['.token-form input[type=text]'],
            button: ['.token-form .btn-token'],
            name: '移动云盘',
            storage: 'local',
            storagePwdName: 'tmp_caiyun_pwd'
        },
        'xunlei': {
            reg: /((?:https?:\/\/)?pan\.xunlei\.com\/s\/[\w-]{10,})/,
            host: /pan\.xunlei\.com/,
            input: ['.pass-input-wrap .td-input__inner'],
            button: ['.pass-input-wrap .td-button'],
            name: '迅雷云盘',
            storage: 'hash'
        },
        '123pan': {
            reg: /((?:https?:\/\/)?www\.123pan\.com\/s\/[\w-]{6,})/,
            host: /www\.123pan\.com/,
            input: ['.ca-fot input'],
            button: ['.ca-fot button'],
            name: '123云盘',
            storage: 'hash'
        },
        '360': {
            reg: /((?:https?:\/\/)?(?:[a-zA-Z\d\-.]+)?yunpan\.360\.cn(\/lk)?\/surl_\w{6,})/,
            host: /yunpan\.360\.cn/,
            input: ['.pwd-input'],
            button: ['.submit-btn'],
            name: '360云盘',
            storage: 'hash'
        },
        '115': {
            reg: /((?:https?:\/\/)?115\.com\/s\/[a-zA-Z\d]+)/,
            host: /115\.com/,
            input: ['.form-decode input'],
            button: ['.form-decode .submit a'],
            name: '115网盘',
            storage: 'hash'
        },
        'cowtransfer': {
            reg: /((?:https?:\/\/)?(?:[a-zA-Z\d-.]+)?cowtransfer\.com\/s\/[a-zA-Z\d]+)/,
            host: /(?:[a-zA-Z\d-.]+)?cowtransfer\.com/,
            input: ['.receive-code-input input'],
            button: ['.open-button'],
            name: '奶牛快传',
            storage: 'hash'
        },
        'ctfile': {
            reg: /((?:https?:\/\/)?(?:[a-zA-Z\d-.]+)?ctfile\.com\/\w+\/[a-zA-Z\d-]+)/,
            host: /(?:[a-zA-Z\d-.]+)?ctfile\.com/,
            input: ['#passcode'],
            button: ['.card-body button'],
            name: '城通网盘',
            storage: 'hash'
        },
        'quark': {
            reg: /((?:https?:\/\/)?pan\.quark\.cn\/s\/[a-zA-Z\d-]+)/,
            host: /pan\.quark\.cn/,
            input: ['.ant-input'],
            button: ['.ant-btn-primary'],
            name: '夸克网盘',
            storage: 'local',
            storagePwdName: 'tmp_quark_pwd'
        },
        'flowus': {
            reg: /((?:https?:\/\/)?flowus\.cn\/[\S ^\/]*\/?share\/[a-z\d]{8}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{12})/,
            host: /flowus\.cn/,
            name: 'FlowUs息流',
            storage: 'hash'
        },
        'chrome': {
            reg: /^https?:\/\/chrome.google.com\/webstore\/.+?\/([a-z]{32})(?=[\/#?]|$)/,
            host: /chrome\.google\.com/,
            replaceHost: "chrome.crxsoso.com",
            name: 'Chrome商店',
        },
        'edge': {
            reg: /^https?:\/\/microsoftedge.microsoft.com\/addons\/.+?\/([a-z]{32})(?=[\/#?]|$)/,
            host: /microsoftedge\.microsoft\.com/,
            replaceHost: "microsoftedge.crxsoso.com",
            name: 'Edge商店',
        },
        'firefox': {
            reg: /^https?:\/\/(reviewers\.)?(addons\.mozilla\.org|addons(?:-dev)?\.allizom\.org)\/.*?(?:addon|review)\/([^/<>"'?#]+)/,
            host: /addons\.mozilla\.org/,
            replaceHost: "addons.crxsoso.com",
            name: 'Firefox商店',
        },
        'microsoft': {
            reg: /^https?:\/\/(?:apps|www).microsoft.com\/(?:store|p)\/.+?\/([a-zA-Z\d]{10,})(?=[\/#?]|$)/,
            host: /(apps|www)\.microsoft\.com/,
            replaceHost: "apps.crxsoso.com",
            name: 'Windows商店',
        },
    };

    let main = {
        lastText: "lorem&",

        //初始化配置数据
        initValue() {
            let value = [{
                name: 'setting_success_times',
                value: 0
            }, {
                name: 'setting_auto_click_btn',
                value: true
            }, {
                name: 'setting_active_in_front',
                value: true
            }, {
                name: 'setting_timer_open',
                value: false
            }, {
                name: 'setting_timer',
                value: 5000
            }];

            value.forEach((v) => {
                if (util.getValue(v.name) === undefined) {
                    util.setValue(v.name, v.value);
                }
            });
        },

        // 监听选择事件
        addPageListener() {
            document.addEventListener("mouseup", this.smartIdentify.bind(this), true);
            document.addEventListener("keydown", this.pressKey.bind(this), true);
        },

        // &#9888;&#65039;可能会增加时间&#9888;&#65039; 如果有需要可以增加选项
        // 获取选择内容的HTML和文本(增加兼容性) 或 DOM(节点遍历)
        getSelectionHTML(selection, isDOM = false) {
            const testDiv = document.createElement("div");
            if (!selection.isCollapsed) {
                // Range 转 DocumentFragment
                const docFragment = selection.getRangeAt(0).cloneContents();
                testDiv.appendChild(docFragment);
            }
            // 拼接选中文本,增加兼容
            return isDOM ? testDiv : selection.toString();
        },

        smartIdentify(event, str = '') {
            let selection = window.getSelection();
            let text = str || this.getSelectionHTML(selection);
            if (text !== this.lastText && text !== '') { //选择相同文字或空不识别
                let start = performance.now();
                this.lastText = text;
                //util.clog(`当前选中文字:${text}`);
                let linkObj = this.parseLink(text);
                let link = linkObj.link;
                let name = linkObj.name;
                let pwd = this.parsePwd(text);
                if (!link) {
                    linkObj = this.parseParentLink(selection);
                    link = linkObj.link;
                    name = linkObj.name;
                }
                if (link) {
                    if (!/https?:\/\//.test(link)) {
                        link = 'https://' + link;
                    }
                    let end = performance.now();
                    let time = (end - start).toFixed(3);
                    util.clog(`文本识别结果:${name} 链接:${link} 密码:${pwd} 耗时:${time}毫秒`);
                    let option = {
                        toast: true,
                        showCancelButton: true,
                        position: 'top',
                        title: `发现<span style="color: #2778c4;margin: 0 5px;">${name}</span>链接`,
                        html: `<span style="font-size: 0.8em;">${!!pwd ? '密码:' + pwd : '是否打开?'}</span>`,
                        confirmButtonText: '打开',
                        cancelButtonText: '关闭',
                        customClass
                    };
                    if (util.getValue('setting_timer_open')) {
                        option.timer = util.getValue('setting_timer');
                        option.timerProgressBar = true;
                    }
                    util.setValue('setting_success_times', util.getValue('setting_success_times') + 1);

                    Swal.fire(option).then((res) => {
                        this.lastText = 'lorem&';
                        selection.empty();
                        if (res.isConfirmed || res.dismiss === 'timer') {
                            if (name === '移动云盘') {  //移动云盘无法携带参数和Hash
                                util.setValue('tmp_caiyun_pwd', pwd);
                            }
                            if (name === '夸克网盘') {
                                util.setValue('tmp_quark_pwd', pwd);
                            }
                            let active = util.getValue('setting_active_in_front');
                            if (pwd) {
                                let extra = `${link}?pwd=${pwd}#${pwd}`;
                                if (~link.indexOf('?')) {
                                    extra = `${link}&pwd=${pwd}#${pwd}`;
                                }
                                GM_openInTab(extra, {active});
                            } else {
                                GM_openInTab(`${link}`, {active});
                            }
                        }
                    });
                }
            }
        },

        pressKey(event) {
            if (event.key === 'Enter') {
                let confirmBtn = document.querySelector('.panai-container .swal2-confirm');
                confirmBtn && confirmBtn.click();
            }
            if (event.key === 'Escape') {
                let cancelBtn = document.querySelector('.panai-container .swal2-cancel');
                cancelBtn && cancelBtn.click();
            }
        },

        addHotKey() {
            hotkeys('f1', (event, handler) => {
                event.preventDefault();
                this.showIdentifyBox();
            });
        },

        //正则解析网盘链接
        parseLink(text = '') {
            let obj = {name: '', link: ''};
            if (text) {
                try {
                    text = decodeURIComponent(text);
                } catch {
                }
                text = text.replace(/[点點]/g, '.');
                text = text.replace(/[\u4e00-\u9fa5\u200B()(),,]/g, '');
                text = text.replace(/lanzous/g, 'lanzouw'); //修正lanzous打不开的问题
                for (let name in opt) {
                    let val = opt[name];
                    if (val.reg.test(text)) {
                        let matches = text.match(val.reg);
                        obj.name = val.name;
                        obj.link = matches[0];
                        if (val.replaceHost) {
                            obj.link = obj.link.replace(val.host, val.replaceHost);
                        }
                        return obj;
                    }
                }
            }
            return obj;
        },

        //正则解析超链接类型网盘链接
        parseParentLink(selection) {
            const dom = this.getSelectionHTML(selection, true).querySelector('*[href]');
            return this.parseLink(dom ? dom.href : "");
        },

        //正则解析提取码
        parsePwd(text) {
            text = text.replace(/\u200B/g, '');
            let reg = /(?<=\s*(?:密|提取|访问|訪問|key|password|pwd|#)\s*[码碼]?\s*[::=]?\s*)[a-zA-Z0-9]{3,8}/i;
            if (reg.test(text)) {
                let match = text.match(reg);
                return match[0];
            }
            return '';
        },

        //根据域名检测网盘类型
        panDetect() {
            let hostname = location.hostname;
            for (let name in opt) {
                let val = opt[name];
                if (val.host.test(hostname)) {
                    return name;
                }
            }
            return '';
        },

        //自动填写密码
        autoFillPassword() {
            let url = location.href;
            let query = util.parseQuery('pwd');
            let hash = location.hash.slice(1);
            let pwd = query || hash;
            let panType = this.panDetect();

            for (let name in opt) {
                let val = opt[name];
                if (panType === name) {
                    if (val.storage === 'local') {
                        pwd = util.getValue(val.storagePwdName) ? util.getValue(val.storagePwdName) : '';
                        pwd && this.doFillAction(val.input, val.button, pwd);
                    }
                    if (val.storage === 'hash') {
                        if (!/^[a-zA-Z0-9]{3,8}$/.test(pwd)) { //过滤掉不正常的Hash
                            return;
                        }
                        pwd && this.doFillAction(val.input, val.button, pwd);
                    }
                }
            }
        },

        doFillAction(inputSelector, buttonSelector, pwd) {
            let maxTime = 10;
            let ins = setInterval(async () => {
                maxTime--;
                let input = util.query(inputSelector);
                let button = util.query(buttonSelector);

                if (input && !util.isHidden(input)) {
                    clearInterval(ins);
                    Swal.fire({
                        toast: true,
                        position: 'top',
                        showCancelButton: false,
                        showConfirmButton: false,
                        title: 'AI已识别到密码!正自动帮您填写',
                        icon: 'success',
                        timer: 2000,
                        customClass
                    });

                    let lastValue = input.value;
                    input.value = pwd;
                    //Vue & React 触发 input 事件
                    let event = new Event('input', {bubbles: true});
                    let tracker = input._valueTracker;
                    if (tracker) {
                        tracker.setValue(lastValue);
                    }
                    input.dispatchEvent(event);

                    if (util.getValue('setting_auto_click_btn')) {
                        await util.sleep(1000); //1秒后点击按钮
                        button.click();
                    }
                } else {
                    maxTime === 0 && clearInterval(ins);
                }
            }, 800);
        },

        //重置识别次数
        clearIdentifyTimes() {
            let res = Swal.fire({
                showCancelButton: true,
                title: '确定要重置识别次数吗?',
                icon: 'warning',
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                customClass
            }).then(res => {
                this.lastText = 'lorem&';
                if (res.isConfirmed) {
                    util.setValue('setting_success_times', 0);
                    history.go(0);
                }
            });
        },

        //识别输入框中的内容
        showIdentifyBox() {
            Swal.fire({
                title: '识别剪切板中文字',
                input: 'textarea',
                inputPlaceholder: '若选方式一,请按 Ctrl+V 粘贴要识别的文字',
                html: `<div style="font-size: 12px;color: #999;margin-bottom: 8px;text-align: center;">提示:在任意网页按下 <span style="font-weight: 700;">F1</span> 键可快速打开本窗口。</div><div style="font-size: 14px;line-height: 22px;padding: 10px 0 5px;text-align: left;"><div style="font-size: 16px;margin-bottom: 8px;font-weight: 700;">支持以下两种方式:</div><div><b>方式一:</b>直接粘贴文字到输入框,点击“识别方框内容”按钮。</div><div><b>方式二:</b>点击“读取剪切板”按钮。<span style="color: #d14529;font-size: 12px;">会弹出“授予网站读取剪切板”权限,同意后会自动识别剪切板中的文字。</span></div></div>`,
                showCloseButton: false,
                showDenyButton: true,
                confirmButtonText: '识别方框内容',
                denyButtonText: '读取剪切板',
                customClass
            }).then(res => {
                if (res.isConfirmed) {
                    this.smartIdentify(null, res.value);
                }
                if (res.isDenied) {
                    navigator.clipboard.readText().then(text => {
                        this.smartIdentify(null, text);
                    }).catch(() => {
                        toast.fire({title: '读取剪切板失败,请先授权或手动粘贴后识别!', icon: 'error'});
                    });
                }
            });
        },

        //显示设置
        showSettingBox() {
            let html = `<div style="font-size: 1em;">
                              <label class="panai-setting-label">填写密码后自动提交<input type="checkbox" id="S-Auto" ${util.getValue('setting_auto_click_btn') ? 'checked' : ''} class="panai-setting-checkbox"></label>
                              <label class="panai-setting-label">前台打开网盘标签页<input type="checkbox" id="S-Active" ${util.getValue('setting_active_in_front') ? 'checked' : ''}
                              class="panai-setting-checkbox"></label>
                              <label class="panai-setting-label">倒计时结束自动打开<input type="checkbox" id="S-Timer-Open" ${util.getValue('setting_timer_open') ? 'checked' : ''} class="panai-setting-checkbox"></label>
                              <label class="panai-setting-label" id="Panai-Range-Wrapper" style="${util.getValue('setting_timer_open') ? '' : 'display: none'}"><span>倒计时 <span id="Timer-Value">(${util.getValue('setting_timer') / 1000}秒)</span></span><input type="range" id="S-Timer" min="0" max="10000" step="500" value="${util.getValue('setting_timer')}" style="width: 200px;"></label>
                            </div>`;
            Swal.fire({
                title: '识别助手配置',
                html,
                icon: 'info',
                showCloseButton: true,
                confirmButtonText: '保存',
                footer: '<div style="text-align: center;font-size: 1em;">点击查看 <a  target="_blank">使用说明</a>,助手免费开源,Powered by <a >油小猴</a></div>',
                customClass
            }).then((res) => {
                res.isConfirmed && history.go(0);
            });

            document.getElementById('S-Auto').addEventListener('change', (e) => {
                util.setValue('setting_auto_click_btn', e.target.checked);
            });
            document.getElementById('S-Active').addEventListener('change', (e) => {
                util.setValue('setting_active_in_front', e.target.checked);
            });
            document.getElementById('S-Timer-Open').addEventListener('change', (e) => {
                let rangeWrapper = document.getElementById('Panai-Range-Wrapper');
                e.target.checked ? rangeWrapper.style.display = 'flex' : rangeWrapper.style.display = 'none';
                util.setValue('setting_timer_open', e.target.checked);
            });
            document.getElementById('S-Timer').addEventListener('change', (e) => {
                util.setValue('setting_timer', e.target.value);
                document.getElementById('Timer-Value').innerText = `(${e.target.value / 1000}秒)`;
            });
        },

        registerMenuCommand() {
            GM_registerMenuCommand('&#128064; 已识别:' + util.getValue('setting_success_times') + '次', () => {
                this.clearIdentifyTimes();
            });
            GM_registerMenuCommand('&#128203;&#65039; 识别剪切板中文字(快捷键 F1)', () => {
                this.showIdentifyBox();
            });
            GM_registerMenuCommand('&#9881;&#65039; 设置', () => {
                this.showSettingBox();
            });
        },

        addPluginStyle() {
            let style = `
                .panai-container { z-index: 99999!important }
                .panai-popup { font-size: 14px !important }
                .panai-setting-label { display: flex;align-items: center;justify-content: space-between;padding-top: 20px; }
                .panai-setting-checkbox { width: 16px;height: 16px; }
            `;

            if (document.head) {
                util.addStyle('swal-pub-style', 'style', GM_getResourceText('swalStyle'));
                util.addStyle('panai-style', 'style', style);
            }

            const headObserver = new MutationObserver(() => {
                util.addStyle('swal-pub-style', 'style', GM_getResourceText('swalStyle'));
                util.addStyle('panai-style', 'style', style);
            });
            headObserver.observe(document.head, {childList: true, subtree: true});
        },

        isTopWindow() {
            return window.self === window.top;
        },

        init() {
            this.initValue();
            this.addPluginStyle();
            this.addHotKey();
            this.autoFillPassword();
            this.addPageListener();
            this.isTopWindow() && this.registerMenuCommand();
        },
    };

    main.init();
})();
沙发
青春莫相随 发表于 2023-2-26 01:21
3#
有为青年 发表于 2023-2-26 01:24
编完这些代码需要多久时间呢?
4#
seaxp 发表于 2023-2-26 02:14
多谢楼主分享!辛苦啦!
5#
whg118 发表于 2023-2-26 06:36
学习了网页正则,感谢。
6#
shszss 发表于 2023-2-26 07:54
前来学习,感谢分享
7#
ystx5288 发表于 2023-2-26 07:56
好东西,下载试用
8#
heyun129 发表于 2023-2-26 08:15
感谢分享,下载试用
9#
eboyang 发表于 2023-2-26 08:22
高手,下载试一下
10#
subney 发表于 2023-2-26 08:29
节约人生的工具
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 20:23

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表