Greasy Fork

Greasy Fork is available in English.

【小破站必备2022】 哔哩哔哩(bilibili|B站)自动增强--功能快捷键,观看进度保存,每日任务等

🔥🔥🔥推荐! 浸入式功能智能自动化,让你的 B站 比别人的更强。自动跳转多 P 视频(UP 上传视频)上次观看进度,快捷键增强,每日任务(签到&分享),视频已看标签等等,具体看脚本介绍~

当前为 2022-07-20 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         【小破站必备2022】 哔哩哔哩(bilibili|B站)自动增强--功能快捷键,观看进度保存,每日任务等
// @namespace    http://tampermonkey.net/
// @version      0.0.2
// @icon         https://cdn.jsdelivr.net/gh/Anjude/pubsrc@img/1.png
// @description  🔥🔥🔥推荐! 浸入式功能智能自动化,让你的 B站 比别人的更强。自动跳转多 P 视频(UP 上传视频)上次观看进度,快捷键增强,每日任务(签到&分享),视频已看标签等等,具体看脚本介绍~
// @author       anjude
// @match        https://*.bilibili.com/*
// @grant        GM_openInTab
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @grant        GM_xmlhttpRequest
// @original-script   https://github.com/Anjude/tampermonkey
// @require      https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.2.1/jquery.min.js
// @require     http://greasyfork.icu/scripts/412159-mydrag/code/MyDrag.js?version=858320
// ==/UserScript==

(function () {
    "use strict";
    // @require     https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
    // 检查版本
    const RELEASE_VERSION = "0.0.2";
    let ENV = "RELEASE";
    // ENV = 'DEBUG'
    const updateVersion =
        ENV === "DEBUG" || RELEASE_VERSION !== GM_getValue("RELEASE_VERSION");
    updateVersion && GM_setValue("RELEASE_VERSION", RELEASE_VERSION);
    // startHttpProxy();
    /**
     * 默认设置
     * `${e.altKey}${e.ctrlKey}${e.shiftKey}${pressKey}`
     */
    let defaultBili2sConf = {
        shortcutMap: {
            upToTop: "000U", // 回到顶部
            takeNote: "000N", // 打开视频笔记
            lightOff: "000L", // 开关宽屏模式
            notePicShot: "101P", // 笔记-视频截图
            noteTimePoint: "101T", // 笔记-时间标记
            // changeParseApi: "100V", // 解锁视频
            showMenu: "100M", // 打开菜单
        },
        videoRecordMap: {}, // 视频记录
        multiUnceasing: true, // 多集自动连播
        singleUncreasing: false, // 单集自动连播
        //   autoUnlockVideo: false, // 是否自动解锁视频
        shareDate: "2022/1/1",
        lastClearup: new Date().toLocaleString(),
        // parseApiIndex: 0, // 解析接口选择
        pretendVip: false,
        installTime: null,
    };

    // 网站配置
    const siteConfig = {
        delay2s: 2000,
        scrollBtnList: [
            "div.item.back-top", // 首页
            "button.primary-btn.top-btn", // 新版首页
            "div.item.backup", // up视频,
            "div.tool-item.backup.iconfont.icon-up", //
            "#app > div.to-top", // up主所有视频
            "#cheese_guide > div > div", // 课堂
        ],
        noteBtnList: [
            "div.note-btn", // 普通up视频
            "span.note-btn", // 课堂视频
        ],
        notePanelList: [
            "div.resizable-component.bili-note", // 普通up视频
        ],
        lightOffBtn: [
            "div.squirtle-single-setting-other-choice.squirtle-lightoff",
            "div.bilibili-player-fl.bilibili-player-video-btn-setting-right-others-content-lightoff.bui.bui-checkbox.bui-dark > input",
        ],
        wideScreenBtn: [
            "div.squirtle-widescreen-wrap.squirtle-block-wrap > div", // bangumi 视频
            "div.bilibili-player-video-btn.bilibili-player-video-btn-widescreen", // up 视频
        ],
        videoSettingBtn: [
            "div.bilibili-player-video-btn.bilibili-player-video-btn-setting",
        ],
        picBtnList: ["span.ql-capture-btn"],
        pointBtnList: ["span.ql-tag-btn"],
        multiPageBox: ["#multi_page > div.cur-list"],
        chapListItem: ["div.cur-list > ul > li.on"],
        trendBtnList: [
            // "div.box-bottom > div > div:nth-child(1)",
            "div.share-btns > div:nth-child(1)",
            "div.share-info > div > div > span",
        ],
        shareBtnList: ["div.share-info"],
        unceasingBtnList: ["span.switch-button"],
        searchResBox: [
            "#video-list > ul",
            "div.video-list", // 搜索页
            "div.video.search-all-list > div", // 搜索页
            "div.mixin-list > ul.video-list", // 番剧
            "div.flow-loader > ul",
            "div.rcmd-box", // 首页推荐
            "div.section.video > div.content", // UP主页
            "#submit-video-list > ul.list-list", // UP主页,更多视频
            "#submit-video-list > ul.cube-list", // UP主页,更多视频
            "#page-series-detail > div > div > div > ul"     // 专栏视频
            // '#reco_list > div.rec-list',  // 相关视频
        ],
        vipIcon: "bili-avatar-icon--big-vip",
        vipSpan: [
            "div.avatar-container > div > div > span",
            "div.big-avatar-container--default > a > div > span",
            "a.header-entry-avatar > div > span",
        ],
        vipLabel: "div.h-vipType",
        playerBox: ["#player_module"],
        videoBox: ["video"],
        vipAdClose: ["div.twp-mask > div > i"],
        parseApiList: [
            // 解析链接均收集自网络,经过简单测试
            // https://jx.bozrc.com:4433/player/?url=
            // {
            //   url: "https://vip.parwix.com:4433/player/?url=",
            //   name: "Parwix解析系统",
            // },
            { url: "https://jx.bozrc.com:4433/player/?url=", name: "夜幕解析" },
            { url: "https://z1.m1907.cn/?jx=", name: "m1907" },
            { url: "https://yparse.jn1.cc/index.php?url=", name: "云解析" },
            // { url: "https://www.yemu.xyz/?url=", name: "夜幕解析" },
            // { url: "https://vip.bljiex.cc/?v=", name: "BL解析" },
            // { url: "https://vip.mmkv.cn/tv.php?url=", name: "mmkv" },
            // { url: "https://vip5.jiexi.one/?url=", name: "爱爱蓝光解析" },
            // { url: 'https://www.1717yun.com/jx/ty.php?url=', name: '1717云解析' },
            // { url: 'https://jx.rdhk.net/?v=', name: '4080视频解析' },
            // { url: 'https://go.yh0523.cn/y.cy?url=', name: '盘古云解析' },
            // { url: 'https://17kyun.com/api.php?url=', name: '17kyun' },
            // { url: 'https://lecurl.cn/?url=', name: 'dplayer - by-le' },
        ],
        bangumiLi: ["li.ep-item.cursor.badge.visited"],
        watchroomvip: ["#paybar_module > div.vip"],
        shortcutList: {
            upToTop: "回到顶部",
            takeNote: "打开/关闭笔记",
            // changeParseApi: "切换视频解析接口",
            showMenu: "打开菜单",
            notePicShot: "笔记-视频截图",
            noteTimePoint: "笔记-时间标志",
            lightOff: "开关宽屏模式",
        }, // shortcut list
        scSetting: "",
    };

    let bili2sConf = GM_getValue("bili2sConf") || defaultBili2sConf;

    if (updateVersion) {
        let shortcutMap = Object.assign({}, defaultBili2sConf.shortcutMap);
        bili2sConf = Object.assign(defaultBili2sConf, bili2sConf);
        bili2sConf.shortcutMap = Object.assign(shortcutMap, bili2sConf.shortcutMap);
        console.log(
            shortcutMap,
            defaultBili2sConf.shortcutMap,
            bili2sConf.shortcutMap
        );
        GM_setValue("bili2sConf", bili2sConf);
        Toast("脚本已更新");
    }

    if (!bili2sConf.installTime) {
        bili2sConf.installTime = new Date().toLocaleString();
        GM_setValue("bili2sConf", bili2sConf);
        alert("首次使用,前往微信小程序,随时反馈!");
        window.GM_openInTab(
            "https://cdn.jsdelivr.net/gh/Anjude/pubsrc@img/TW-TamperMonkey.png",
            { active: true, insert: true, setParent: true }
        );
    }

    const delayExecute = (execution, delayMs) => {
        setTimeout(() => {
            execution();
        }, delayMs || siteConfig.delay2s);
    };

    const getElement = (list) => {
        if (typeof list === "string") return document.querySelector(list);
        let btn = document.querySelector(list[0]);
        list.forEach((e) => {
            btn = document.querySelector(e) || btn;
        });
        return btn;
    };

    const getBvid = (href) => {
        let res = /video\/([0-9|a-z|A-Z]*)/gi.exec(href || document.location.href);
        return res === null ? false : res[1];
    };

    // 改编自 github 网友贡献的代码,详情请参见 github 的提交记录
    const LightOff = () => {
        let settingBtn = getElement(siteConfig.videoSettingBtn);
        settingBtn?.dispatchEvent(new MouseEvent("mouseover"));
        settingBtn?.dispatchEvent(new MouseEvent("mouseout"));

        let wideScreenBtn = getElement(siteConfig.wideScreenBtn);
        let lightOffBtn = getElement(siteConfig.lightOffBtn);
        let scrollDistance = window.location.href.match("bangumi") ? 50 : 100;

        wideScreenBtn.click();
        lightOffBtn.click();
        window.scrollTo(0, scrollDistance);
    };

    const UpToTop = () => {
        // 回到顶部
        let scrollBtn = getElement(siteConfig.scrollBtnList);
        if (scrollBtn) scrollBtn.click();
    };

    const TakeNote = () => {
        let noteBtn = getElement(siteConfig.noteBtnList);
        let nodePanel = getElement(siteConfig.notePanelList);
        let res =
            nodePanel ||
            (() => {
                noteBtn.click();
                return false;
            })();
        if (!res) return;

        nodePanel.style.display = nodePanel.style.display === "none" ? "" : "none";
    };

    const NotePicShot = () => {
        let picBtn = getElement(siteConfig.picBtnList);
        picBtn.click();
    };

    const NoteTimePoint = () => {
        let pointBtn = getElement(siteConfig.pointBtnList);
        pointBtn.click();
    };

    const keyCtrl = () => { };

    const blockKey = (e) => {
        let isBlock = false;

        // do sth if isBlock should be true

        return isBlock;
    };

    const setShortcut = (command) => {
        let commandString = getShortCut(command);
        let scSetting = siteConfig.scSetting;
        let innerTextList = document
            .querySelector(`#${scSetting}`)
            .innerHTML.split(":");
        document.querySelector(`#${scSetting}`).innerHTML =
            innerTextList[0] + ": " + commandString;
        siteConfig.scm[scSetting] = command;
    };

    let focus = false; // 输入中
    $(document).ready(() => {
        $(document).delegate("input, textarea", "focus", () => {
            focus = true;
        });
        $(document).delegate("input, textarea", "blur", () => {
            focus = false;
        });
        $(document).keydown((e) => {
            // 如果正在打字或者特殊情况,屏蔽快捷键
            if (!e.altKey && !e.shiftKey && !e.ctrlKey && (focus || blockKey(e))) {
                return;
            }
            const k = (key) => (key ? 1 : 0);
            let pressKey = String.fromCharCode(e.keyCode);
            let command = `${k(e.altKey)}${k(e.ctrlKey)}${k(e.shiftKey)}${pressKey}`;
            let keyMap = bili2sConf.shortcutMap;

            // console.log('键盘:', command, siteConfig.scSetting)
            if (siteConfig.scSetting) {
                return setShortcut(command);
            }
            switch (command) {
                case keyMap.upToTop:
                    return UpToTop();
                case keyMap.lightOff:
                    return LightOff();
                case keyMap.takeNote:
                    return TakeNote();
                case keyMap.changeParseApi:
                    return ChangeParseApi();
                case keyMap.showMenu:
                    return (document.querySelector("#sc-box").style.display = "");
                case keyMap.notePicShot:
                    return NotePicShot();
                case keyMap.noteTimePoint:
                    return NoteTimePoint();
                default:
                    keyCtrl(command); // 一些不常用的小操作,集中一个函数处理
            }
        });
    });

    const chapListener = (res) => {
        let listItem = getElement(siteConfig.chapListItem)?.innerHTML;
        if (!listItem) {
            console.log("非多集视频");
            return;
        }
        let regxList = /video\/([0-9a-zA-Z]*)\?p=(\d+).*title=.(.*?).><div/i.exec(
            listItem
        );
        let bvid = regxList[1];
        bili2sConf.videoRecordMap[bvid] = Object.assign(
            bili2sConf.videoRecordMap[bvid] || {},
            {
                p: regxList[2],
                title: regxList[3],
                updateTime: new Date().toLocaleString(),
            }
        );
        GM_setValue("bili2sConf", bili2sConf);
    };

    const multiPageJump = async () => {
        let bvid = getBvid();
        let videoHis = bili2sConf.videoRecordMap[bvid];
        videoHis &&
            (() => {
                let hrefRegexp = new RegExp(`${bvid}\\?p=\\d+`, "i");
                if (hrefRegexp.test(window.location.href)) {
                    return;
                }
                let curChapLi = document.querySelector(
                    `div.cur-list > ul > li:nth-child(${videoHis.p}) > a > div`
                );
                if (!curChapLi) {
                    return delayExecute(multiPageJump);
                }
                curChapLi.click();
                Toast(`小助手: 跳转上次观看 P${videoHis.p}`);
            })();
    };

    const setVideoRecord = () => {
        let bvid = getBvid();
        let videoRecord = bili2sConf.videoRecordMap[bvid] || {
            docTitle: document.title,
            p: 1,
        };
        videoRecord.updateTime = new Date().toLocaleString();
        bili2sConf.videoRecordMap[bvid] = Object.assign(
            bili2sConf.videoRecordMap[bvid] || {},
            videoRecord
        );
        // console.log(bili2sConf.videoRecordMap[bvid], videoRecord)
        GM_setValue("bili2sConf", bili2sConf);
    };

    const dealUnceasing = (isMultiPage) => {
        // 处理连播
        let switchCase = isMultiPage ? "multiUnceasing" : "singleUncreasing";
        let unceasingBtn = getElement(siteConfig.unceasingBtnList);
        if (!unceasingBtn) {
            return delayExecute(dealUnceasing);
        }
        let curUnceasing = /switch-button on/.test(
            unceasingBtn.getAttribute("class")
        );
        curUnceasing === bili2sConf[switchCase] || unceasingBtn.click();
        unceasingBtn.addEventListener("click", (e) => {
            // 过滤脚本模拟点击
            if (e.isTrusted) {
                bili2sConf[switchCase] = !/switch-button on/.test(
                    unceasingBtn.getAttribute("class")
                );
                GM_setValue("bili2sConf", bili2sConf);
            }
        });
    };

    const doShare = () => {
        console.log("[B站小助手]: 开始分享!");
        // let shareBtn = getElement(siteConfig.shareBtnList);

        // console.log(111, shareBtn);
        // shareBtn?.dispatchEvent(new MouseEvent("mouseover"));

        let trendBtn = getElement(siteConfig.trendBtnList);
        if (!trendBtn) {
            return delayExecute(doShare);
        }
        trendBtn.click();
        document.body.lastChild.remove();
        // shareBtn?.dispatchEvent(new MouseEvent("mouseout"));
        bili2sConf.shareDate = new Date().toLocaleDateString();
        GM_setValue("bili2sConf", bili2sConf);
        console.log("[B站小助手]: 分享完成!");
        Toast("小助手: 今日分享任务达成");
    };

    const dealRead = (res) => {
        siteConfig.searchResBox.forEach((boxPath) => {
            let searchResBox = getElement(boxPath);
            console.log(searchResBox, boxPath)
            searchResBox &&
                searchResBox.childNodes.forEach((e) => {
                    if (!e.innerHTML) return;
                    e.style.position = "relative";
                    let bvid = getBvid(e.innerHTML);
                    if (!bvid) return;
                    let addDiv = document.createElement("div");
                    addDiv.className = "video-view";
                    if (bili2sConf.videoRecordMap[bvid]) {
                        addDiv.innerHTML = "已看";
                        addDiv.style.opacity = 0.9;
                        addDiv.style.color = "red";
                    } else {
                        // addDiv.innerHTML = "未看";
                    }
                    e.prepend(addDiv);
                });
        });
    };

    const ChangeParseApi = () => {
        return
        let curIndex = bili2sConf.parseApiIndex;
        bili2sConf.parseApiIndex = (curIndex + 1) % siteConfig.parseApiList.length;
        UnlockBangumi(bili2sConf.parseApiIndex, false, true);
        GM_setValue("bili2sConf", bili2sConf);
        Toast(
            `B站小助手: 解析接口${bili2sConf.parseApiIndex + 1} ${siteConfig.parseApiList[bili2sConf.parseApiIndex].name
            }`
        );
    };

    const UnlockBangumi = (parseApiIndex = 0, setAutoUnlock, forceUnlock) => {
        return
        if (setAutoUnlock) {
            let set = !bili2sConf.autoUnlockVideo;
            bili2sConf.autoUnlockVideo = set;
            GM_setValue("bili2sConf", bili2sConf);
            Toast(`B站小助手:${set ? "开启" : "关闭"}自动解锁!`);
        }
        parseApiIndex %= siteConfig.parseApiList.length;
        let videoInfo = getElement(siteConfig.bangumiLi)?.innerHTML;
        let href = window.location.href
        // 观看室独立逻辑
        if (/bilibili.com\/watchroom/.test(href)) {
            href = document.referrer
            videoInfo = getElement(siteConfig.watchroomvip)?.innerHTML
        }
        if (!forceUnlock) {
            if (!bili2sConf.autoUnlockVideo || (videoInfo && !/(会员|付费|受限)/.test(videoInfo)) || !videoInfo) {
                return $("#anjude-iframe").length && location.reload();
            }
        }

        let parseApi = siteConfig.parseApiList[parseApiIndex];
        let newPlayer = document.createElement("iframe");
        newPlayer.id = "anjude-iframe";
        newPlayer.height = "100%";
        newPlayer.width = "100%";
        newPlayer.src = parseApi.url + href;
        newPlayer.setAttribute("allow", "autoplay");
        newPlayer.setAttribute("frameborder", "no");
        newPlayer.setAttribute("border", "0");
        newPlayer.setAttribute("allowfullscreen", "true");
        newPlayer.setAttribute("webkitallowfullscreen", "webkitallowfullscreen");

        let playerBox = getElement(siteConfig.playerBox);
        let videoBox = getElement(siteConfig.videoBox);

        if (videoBox) {
            videoBox.muted = true;
            videoBox.pause();
        }

        playerBox.innerHTML = "";
        playerBox.append(newPlayer);

        let monitorTimes = 0;
        let vipAdMonitor = setInterval(() => {
            monitorTimes++;
            let closeAd = getElement(siteConfig.vipAdClose);
            if (closeAd || monitorTimes >= (5 * 60 * 1000) / 200) {
                closeAd.click();
                clearInterval(vipAdMonitor);
            }
        }, 200);
        Toast(`B站小助手: 解析完成`, 500);
    };

    const pretendVip = () => {
        siteConfig.vipSpan.forEach((e) => {
            let vipSpan = getElement(e);
            vipSpan && vipSpan.classList.add(siteConfig.vipIcon);
        });
        let vipLabel = getElement(siteConfig.vipLabel);
        if (vipLabel) {
            let newClass = vipLabel.getAttribute("class").replace("disable", "");
            vipLabel.setAttribute("class", newClass);
        }
    };

    const executeByUri = (responseURL, result) => {
        /\/player\/playurl/.test(responseURL) && chapListener(result);
        (/x\/web-interface\/search/.test(responseURL) ||
            /x\/web-interface\/index\/top\/rcmd/.test(responseURL) ||
            /x\/series\/archives/.test(responseURL) ||
            /x\/space\/arc/.test(responseURL)) &&
            dealRead(result);
        (/pgc\/view\/web\/section\/order/.test(responseURL) ||
            /pgc\/season\/episode\/web\/info/.test(responseURL)) &&
            UnlockBangumi(bili2sConf.parseApiIndex);
    };

    const runScript = () => {
        let date = new Date().toLocaleDateString();
        let href = window.location.href;
        let isMultiPage = getElement(siteConfig.multiPageBox);
        if (isMultiPage) {
            multiPageJump();
        }
        if (/\/video\//.test(href)) {
            setVideoRecord();
            dealUnceasing(isMultiPage);
            dealRead();
            date === bili2sConf.shareDate || doShare();
        }
        if (/bilibili.com\/bangumi/.test(href)) {
            addParseBtn();
        }
        if (/bilibili.com\/watchroom/.test(href)) {
            UnlockBangumi(bili2sConf.parseApiIndex)
        }
        if (/search.bilibili.com/.test(href)) {
            dealRead();
        }
        bili2sConf.pretendVip && pretendVip();
    };

    // 执行脚本
    try {
        // console.log('[B站小助手]:', bili2sConf)
        GM_addStyle(getCss());
        setCommand();
        setTimeout(() => {
            runScript();
        }, siteConfig.delay2s);
        clearupStore();
    } catch (err) {
        console.log("[B站小助手]:", err.name, err.message);
        if (confirm(`【B站小助手】: 请截图(到 我的 - 客服 处)反馈 ${err}`)) {
            window.GM_openInTab(
                "https://cdn.jsdelivr.net/gh/Anjude/pubsrc@img/TW-TamperMonkey.png",
                { active: true, insert: true, setParent: true }
            );
        }
    }

    function resetScript() {
        GM_deleteValue("bili2sConf");
    }

    function helper() {
        let str = ``;
        let list = str.match(/https?:\/\/[0-9a-zA-Z./?_-]*=/gi);
        list.forEach((e, i) => {
            setTimeout(() => {
                console.log(i, i === list.length - 1);
                window.open(
                    `${e}https://www.bilibili.com/bangumi/play/ep457778?spm_id_from=333.999.0.0`,
                    "target"
                );
            }, i * 15000);
        });
    }

    function clearupStore() {
        const getDayDiff = (d) => {
            return (new Date() - new Date(d)) / (1000 * 60 * 60 * 24);
        };
        let dayDiff = getDayDiff(bili2sConf.lastClearup);
        if (dayDiff < 30) return; // 每月清理一次数据
        console.log("[B站小助手]:开始清理!");

        let recordMapKeys = Object.keys(bili2sConf.videoRecordMap);
        recordMapKeys.forEach((e) => {
            let updateTime = bili2sConf.videoRecordMap[e].updateTime;
            if (getDayDiff(updateTime) > 365 * 2) {
                delete bili2sConf.videoRecordMap[e];
            }
        });
        bili2sConf.lastClearup = new Date().toLocaleString();
        GM_setValue("bili2sConf", bili2sConf);
    }

    function startHttpProxy() {
        XMLHttpRequest.prototype.send = new Proxy(XMLHttpRequest.prototype.send, {
            apply: (target, thisArg, args) => {
                thisArg.addEventListener("load", (event) => {
                    try {
                        // console.log(111, event.target.responseURL)
                        let { responseText, responseURL } = event.target;
                        if (/^{.*}$/.test(responseText)) {
                            const result = JSON.parse(responseText);
                            executeByUri(responseURL, result);
                        }
                    } catch (err) { }
                });
                return target.apply(thisArg, args);
            },
        });
    }

    function addParseBtn() {
        let ele = $(`
      <div id="anjude-parse" class="mobile-info">
      <i class="iconfont icon-play"></i>
      <span style="visibility:hidden">解析</span>
      </div>
      `);
        $("#toolbar_module").append(ele);
        document
            .querySelector("#anjude-parse")
            .addEventListener("click", ChangeParseApi);
    }

    function Toast(message = "已完成", time = 2000) {
        /*设置信息框停留的默认时间*/
        let el = document.createElement("div");
        el.setAttribute("class", "web-toast");
        el.innerHTML = message;
        document.body.appendChild(el);
        el.classList.add("fadeIn");
        setTimeout(() => {
            el.classList.remove("fadeIn");
            el.classList.add("fadeOut");
            /*监听动画结束,移除提示信息元素*/
            el.addEventListener("animationend", () => {
                document.body.removeChild(el);
            });
            el.addEventListener("webkitAnimationEnd", () => {
                document.body.removeChild(el);
            });
        }, time);
    }

    function getShortCut(command) {
        // console.log(command);
        let res = "";
        if (parseInt(command[0])) res += "Alt+";
        if (parseInt(command[1])) res += "Ctrl+";
        if (parseInt(command[2])) res += "Shift+";
        res += command[3];
        return res;
    }

    function clearCommandStatus(SL) {
        SL.forEach((e) => {
            document.querySelector(`#${e}`).style.color = "";
        });
    }

    function setCommand() {
        initSettingPanel();
        GM_registerMenuCommand("设置脚本", () => {
            document.querySelector("#sc-box").style.display = "";
        });
        GM_registerMenuCommand("重置脚本", () => {
            if (confirm("重置后观看记录、快捷键修改等数据将清空!")) {
                resetScript();
            }
        });
    }

    function initSettingPanel() {
        let SCL = siteConfig.shortcutList;
        siteConfig.scm = bili2sConf.shortcutMap;
        let scItem = "";
        Object.keys(SCL).forEach((e) => {
            scItem += `<div id="${e}">${SCL[e]}快捷键: ${getShortCut(
                siteConfig.scm[e]
            )}</div>`;
        });
        let boxHtml = $(`
  <div id="sc-box" style="display:none;width:300px;">
  <div id="sc-title" style="width: 100%;height: 20px;
  text-align: center;font-size: 16px;padding: 20px;">
  快捷键设置(点击选中设置)
  </div>
  <div style="display:flex; font-size: 15px;flex-direction: column;">
  <label>假装是大会员 <input type="checkbox" id="pretend-vip" ${bili2sConf.pretendVip ? "checked" : ""
            } /></label>
  <label style="visibility:hidden;">自动解锁会员视频 <input type="checkbox" id="auto-unlockvideo" ${bili2sConf.autoUnlockVideo ? "checked" : ""
            } /></label>
  </div>
  <div style="font-size: 15px;">
  ${scItem}
  </div>
  <div style="justify-content:center; display: flex; padding: 10px;">
  <button id="anjude-scok-btn" style="color: white; font-size:16px; border-radius: 2px;
  background: green;padding: 3px;">设置完成</button>
  </div>
  <a style="font-size: 12px; color: blue;" target="_blank" href="http://greasyfork.icu/zh-CN/scripts/437941/feedback">好用的话,去给个好评咯~</a>
  <a id="badguy" style="font-size: 12px; color: red;margin-left: 10px;">烂脚本,我要差评!</a>
  <img id="miniprogram" style="display: none;" src="https://cdn.jsdelivr.net/gh/Anjude/pubsrc@img/TW-TamperMonkey.png">
  </div>
      `);
        $(document.body).append(boxHtml);
        try {
            new MyDrag($("#sc-box")[0], { handle: $("#sc-title")[0] });
        } catch (err) {
            console.log(err);
            return
        }
        Object.keys(SCL).forEach((v) => {
            document.querySelector(`#${v}`).addEventListener("click", function (e) {
                siteConfig.scSetting = this.id;
                clearCommandStatus(Object.keys(SCL));
                this.style.color = "green";
            });
        });
        document
            .querySelector("#anjude-scok-btn")
            .addEventListener("click", function (e) {
                // 设置快捷键,缓存数据
                siteConfig.scSetting = "";
                bili2sConf.shortcutMap = siteConfig.scm;
                GM_setValue("bili2sConf", bili2sConf);
                document.querySelector("#sc-box").style.display = "none";
            });
        document
            .querySelector("#auto-unlockvideo")
            .addEventListener("click", function (e) {
                UnlockBangumi(bili2sConf.parseApiIndex, true);
            });
        document
            .querySelector("#pretend-vip")
            .addEventListener("click", function (e) {
                bili2sConf.pretendVip = !bili2sConf.pretendVip;
                GM_setValue("bili2sConf", bili2sConf);
                Toast("小助手: 刷新页面后生效");
            });
        document.querySelector("#badguy").addEventListener("click", function (e) {
            let cur = document.querySelector("#miniprogram").style.display;
            document.querySelector("#miniprogram").style.display = cur ? "" : "none";
        });
        updateVersion && (document.querySelector("#sc-box").style.display = "");
    }

    function getCss() {
        return `
      #anjude-parse{
        color: orange;
        margin-left: 20px;
      }
      a{text-decoration:none;}
      #pretend-vip,
      #auto-unlockvideo{
        background-color: initial;
          cursor: default;
          appearance: checkbox;
          box-sizing: border-box;
          padding: initial;
          border: initial;
      }
      #sc-box{
          padding: 10px;border-radius: 5px; 
          background: #F6F6F6;border: #44b549 2px solid;
      }
      .video-view{
        display:inline-block;
        position:absolute;
        left:0px; top:0px;
        background:#FFF; color:#666;
        opacity: 0.8; padding:1px 5px;
        z-index:999;
      }
      @keyframes fadeIn {
      0%    {opacity: 0}
          100%  {opacity: 1}
      }
      @keyframes fadeOut {
          0%    {opacity: 1}
          100%  {opacity: 0}
      }
      .web-toast{
          position: fixed;
          background: rgba(0, 0, 0, 0.7);
          color: #fff;
          font-size: 14px;
          line-height: 1;
          padding:10px;
          border-radius: 3px;
          left: 50%;
          top: 50%;
          transform: translate(-50%,-50%);
          z-index: 9999;
          white-space: nowrap;
      }
      .fadeOut{
          animation: fadeOut .5s;
      }
      .fadeIn{
          animation:fadeIn .5s;
      }
      `;
    }
})();