哔哩哔哩工具合集-开发中

注:练手作品,多多包涵,不接受恶意差评,有问题群内咨询(Q群1031014013):一键播放所有视频;一键拉黑。。。(友情天选群746790091 )

Version vom 05.03.2021. Aktuellste Version

Dieses Skript sollte nicht direkt installiert werden. Es handelt sich hier um eine Bibliothek für andere Skripte, welche über folgenden Befehl in den Metadaten eines Skriptes eingebunden wird // @require https://update.greasyfork.org/scripts/422731/907352/%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9%E5%B7%A5%E5%85%B7%E5%90%88%E9%9B%86-%E5%BC%80%E5%8F%91%E4%B8%AD.js

// ==UserScript==
// @name         哔哩哔哩工具合集-开发中
// @description  注:练手作品,多多包涵,不接受恶意差评,有问题群内咨询(Q群1031014013):一键播放所有视频;一键拉黑。。。(友情天选群746790091 )
// @namespace    http://tampermonkey.net/
// @version      1.1.6
// @description  try to take over the world!
// @author       荒年(QQ:2019676120)
// @match        *://space.bilibili.com/*
// @require      https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js
// @resource     animate http://cdn.javaex.cn/javaex/pc/css/animate.css
// @resource     common http://cdn.javaex.cn/javaex/pc/css/common.css
// @resource     defaultCss http://cdn.javaex.cn/javaex/pc/css/skin/default.css
// @grant        unsafeWindow
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @grant        GM_getResourceText
// @grant        GM_openInTab
// @grant        GM_addStyle
// @run-at       document-idle
// @license      MIT License
// @namespace http://tampermonkey.net/
// ==/UserScript==


GM_addStyle(`
    #left_navbar{
        z-index: 1000;
        position: absolute;
        top: 100px;
        left: 5px;
    }
   button[hnBtn="btn_open"] {
        z-index: 1001;
        z-index: 1000px;
        position: absolute;
        top: 58px;
        left: 220px;
    }
    .javaex-panel.javaex-panel-right.javaex-animated-zoom-in {
        top: 60px;
    }
    .javaex-menu-container {
        border: 1px solid #eee;
    }
    .javaex-panel-box p {
        text-align: center;
        background: #fb7299;
    }
    .fontbold{
        color: #00a1d6;
        font-weight: bold;
        cursor: pointer;
    }
`);

let Live_info = {
    author_uid: 99439379,
    room_id: undefined,
    uid: undefined,
    blocked: undefined,
    csrf_token: undefined,
    visit_id: undefined,
    rnd: undefined,
    ruid: undefined,
    uname: undefined,
    user_level: undefined,
    ruid: undefined,
};

let BILIBLI_PATH = {

    "passport": "https://passport.bilibili.com",
    "api": "https://api.bilibili.com",
    "video": "https://www.bilibili.com/video/",
    "single_unread": "http://api.vc.bilibili.com/"
}
/**
 * 参考 https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/login/login_info.md
 * @type {{nav: string}}
 */
let BILIBILI_URL = {
    // 导航栏用户信息
    "nav": BILIBLI_PATH.api + "/x/web-interface/nav",
}

let BiliData = {
    login_code: null,
    login_message: "",
    LoginData: {},
    CoinLog: {},
    Unread: null,
    Video: {},
    replyAction: {},
    upCard: {},
    BVList: [],
}


window.onload = function () {

    let script = document.createElement('script');
    script.setAttribute('type', 'text/javascript');
    script.src = "https://cdn.jsdelivr.net/gh/java-xiaoyi/HNGG-RES@main/javaex/pc/js/javaex.min.js";
    document.documentElement.appendChild(script);

    let script2 = document.createElement('script');
    script2.setAttribute('type', 'text/javascript');
    script2.src = "https://cdn.jsdelivr.net/gh/java-xiaoyi/HNGG-RES@main/javaex/pc/js/javaex-formVerify.js";
    document.documentElement.appendChild(script2);


    //界面显示
    init();

    document.getElementById("getAtMsg").click();

}


function init() {

    Live_info.csrf_token = HNTOOL.getCookie("bili_jct");
    Live_info.uid = HNTOOL.getCookie("DedeUserID");

    addStyle();
    addSetPage();

    $("#getCoinLog").bind("click", async function () {


        if (HNAPI.getCoinLog()) {

            await HNTOOL.Sleep(500);
            let html = '';
            html += '<div class="javaex-panel-box" style="width: 250px;">';
            html += '	<ul>';
            html += `       <p style="color: #FFF;">硬币使用记录</p>`;

            BiliData.CoinLog.list.forEach(function (item) {

                let BV = item.reason.replace(/[^a-z0-9]+/ig, "");
                if (BV.indexOf("BV") != -1) {
                    html += `<li><a href="${BILIBLI_PATH.video}${BV}">${item.reason}${item.delta}币 ${item.time}</a> </li> `;
                }
                html += `<li>${item.reason}${item.delta}币 ${item.time}</li> `;


            });
            html += '		<hr class="javaex-divider"></hr>';
            html += '	</ul>';
            html += '</div>';

            javaex.panel(this, {
                position: "right",
                //offsetTop: "104",
                content: html
            });
            javaex.tip({
                content: "获取用户成功!",
                type: "success"
            });

        } else {
            javaex.tip({
                content: "获取硬币记录失败,请稍后重试!",
                type: "error"
            });
        }


    });

    $("#getUnread").bind("click", async function () {

        javaex.tip({
            content: "获取中,请稍候...",
            type: "submit"
        });
        HNAPI.getUnread();


    });


    $("#likeInDynamicComments").bind("click", async function () {

        let prid = LocalData.get("likeInDynamic_PRID") == null ? "4015599048" : LocalData.get("likeInDynamic_PRID");
        let oid = LocalData.get("likeInDynamic_OID") == null ? "108928314" : LocalData.get("likeInDynamic_OID");

        let html = '';

        html += '<div  style="padding: 10px 10px 10px 0px;">'
        html += '<form id="likeInDynamic_form">'
        html += '    <div class="javaex-unit clear">'
        html += '        <div class="javaex-unit-left"><p class="subtitle required">评论RPID</p></div>'
        html += '        <div class="javaex-unit-right">'
        html += '            <input type="text" class="javaex-text" data-type="positive_int" error-msg="评论RPID格式错误"'
        html += `                   id="likeInDynamic_PRID" value=${prid} placeholder="请输入评论RPID"/>`
        html += '        </div>'
        html += '    </div>'
        html += '    <div class="javaex-unit clear">'
        html += '        <div class="javaex-unit-left"><p class="subtitle required">OID</p></div>'
        html += '        <div class="javaex-unit-right">'
        html += '            <input type="text" class="javaex-text" data-type="positive_int" error-msg="OID格式错误"'
        html += `                   id="likeInDynamic_OID" value=${oid} placeholder="请输入OID"/>`
        html += '        </div>'
        html += '    </div>'
        html += '    <div class="javaex-unit clear tc">'
        html += '        <input type="button" id="likeInDynamic_no" class="javaex-hover-pulse javaex-btn no " value="取消赞"/>'
        html += '        <input type="button" id="likeInDynamic_yes" class="javaex-hover-pulse javaex-btn yes" value="点赞"/>'
        html += '    </div>'
        html += '</form>';
        html += '<hr class="javaex-divider"></hr>';
        html += '</div>';


        javaex.panel(this, {
            position: "right",
            content: html
        });


        // 监听点击保存按钮事件
        $("#likeInDynamic_yes").click(async function () {
            // 表单验证函数
            if (javaexVerify()) {

                HNAPI.likeInDynamicComments(+javaex.getSelectVal("#likeInDynamic_OID"), +javaex.getSelectVal("#likeInDynamic_PRID"), 1);
                await HNTOOL.Sleep(1000);

                if (BiliData.replyAction.code == 0) {

                    LocalData.set("likeInDynamic_PRID", javaex.getSelectVal("#likeInDynamic_PRID"));
                    LocalData.set("likeInDynamic_OID", javaex.getSelectVal("#likeInDynamic_OID"));

                    javaex.tip({content: "评论区点赞成功!", type: "success"});
                } else {
                    javaex.tip({content: "评论区点赞失败!", type: "error"});
                }
                if (BiliData.replyAction.code == 65006) {
                    javaex.tip({content: "请勿重复点赞!", type: "error"});
                }
            }
        });

        // 监听点击返回按钮事件
        $("#likeInDynamic_no").click(async function () {

            if (javaexVerify()) {

                HNAPI.likeInDynamicComments(+javaex.getLocalStorage("#likeInDynamic_OID"), +javaex.getLocalStorage("#likeInDynamic_PRID"), 0);
                await HNTOOL.Sleep(500);

                if (BiliData.replyAction.code == 0) {

                    javaex.setLocalStorage("likeInDynamic_PRID", javaex.getSelectVal("#likeInDynamic_PRID"));
                    javaex.setLocalStorage("likeInDynamic_OID", javaex.getSelectVal("#likeInDynamic_OID"));

                    javaex.tip({content: "评论区取消点赞成功!", type: "success"});
                } else {
                    javaex.tip({content: "评论区取消点赞失败!", type: "error"});
                }
                if (BiliData.replyAction.code == 65006) {
                    javaex.tip({content: "请勿重复取消点赞!", type: "error"});
                }
            }
        });

    });

    $("#biliUserMsg").bind("click", async function () {


        //刷新信息
        HNAPI.getUserNav();
        await HNTOOL.Sleep(500);

        let isLogin = "未登录";
        let vipType = "无";
        //判断是否成功
        if (BiliData.login_code == 0) {


            if (BiliData.LoginData.isLogin) {
                isLogin = "已登录";
            }

            if (BiliData.LoginData.vipType == 1) {
                vipType = "月度大会员";
            } else if (BiliData.LoginData.vipType == 2) {
                vipType = "年度大会员";
            }

            let html = '';
            html += '<div class="javaex-panel-box" style="width: 250px;">';
            html += '	<ul>';
            html += `       <p style="color: #FFF;">用户信息</p>`;
            html += `		<li><a href="https://account.bilibili.com/account/home">当前用户:${BiliData.LoginData.uname}</a> </li> `;
            html += `		<li>用户状态:${isLogin} </li> `;
            html += `		<li>用户等级:${BiliData.LoginData.level_info.current_level}</li> `;
            html += `		<li>升级下一等级需:${BiliData.LoginData.level_info.next_exp - BiliData.LoginData.level_info.current_exp} 经验</li> `;
            html += `		<li>UID:${BiliData.LoginData.mid} </li> `;
            html += `		<li><a href="https://account.bilibili.com/account/coin">硬币:${BiliData.LoginData.money}</a> </li> `;
            html += `		<li>节操值:${BiliData.LoginData.moral} </li> `;
            html += `		<li>会员:${vipType} </li> `;
            html += '		<hr class="javaex-divider"></hr>';
            html += '	</ul>';
            html += '</div>';


            javaex.panel(this, {
                position: "right",
                content: html
            });

            javaex.tip({
                content: "获取用户成功!",
                type: "success"
            });

        } else {
            javaex.tip({
                content: "获取用户信息失败!",
                type: "error"
            });
        }


    });

    $("#getAtMsg").bind("click", async function () {

        if (HNAPI.getMsgfeed("at") && typeof (HNAPI.getMsgfeed("at")) != "undefined") {

            javaex.tip({
                content: "可能中奖了!!!",
                type: "success"
            });
        }
    });


    $("#disUser").bind("click", async function () {

        let html = '';
        html += '<div class="javaex-panel-box" style="width: 500px;">';
        html += '   <div class="javaex-unit clear">';
        html += '       <div class="javaex-unit-left ml-10 mt-10">*拉黑列表</div>';
        html += '       <div class="javaex-unit-right mr-10 mt-10">';
        html += '           <textarea id="disUser_uidList" class="javaex-desc" placeholder="请填写用户UID,多个用英文逗号,隔开"></textarea>';
        html += '       </div>';
        html += '   </div>';
        html += '   <div class="javaex-unit clear tc">';
        html += '       <input type="button" id="disUser_beg" class="javaex-btn yes" value="开始" />';
        html += '   </div>';
        html += '</div>';

        javaex.panel(this, {
            position: "right",
            content: html
        });

        $("#disUser_beg").bind("click", async function () {

            let disUser_str = javaex.getSelectVal("#disUser_uidList");
            let disUser_uidList = disUser_str.split(",");

            for (const vmid of disUser_uidList) {

                HNAPI.disUserByUid(vmid);

                await HNTOOL.Sleep(1500);

            }

        });

    });

    //
    $("#getUpMassage").bind("click", async function () {


        let html = '';

        html += '<div  style="padding: 10px 10px 10px 0px;">'
        html += '<form id="getUpMassage_form">'
        html += '    <div class="javaex-unit clear">'
        html += '        <div class="javaex-unit-left mr-10"><p class="subtitle required">用户uid</p></div>'
        html += '        <div class="javaex-unit-left mr-10">'
        html += '            <input type="text" class="javaex-text javaex-grid-4" data-type="positive_int" error-msg="用户uid"'
        html += `                   id="up_uid" value="4578433" placeholder="请输入评论uid"/>`
        html += '        </div>'
        html += '        <div class="javaex-unit-right mr-10">'
        html += '           <input type="button" id="getUpMsg" class="javaex-btn blue" value="查询"/>'
        html += '        </div>'
        html += '    </div>'
        html += '    <div class="javaex-unit clear tc" style="width: 500px;">'
        html += ' <table id="upMsgTable" class="javaex-table td-c-1">'
        html += '    <thead>'
        html += '    <tr><th>内容</th><th>详情</th></tr>'
        html += '    </thead>'
        html += '    <tbody id="upMsgTbody">'

        html += '    </tbody>'
        html += '</table> '
        html += '</div>'
        html += '</form>';
        html += '<hr class="javaex-divider"></hr>';
        html += '</div>';


        javaex.panel(this, {
            position: "right",
            content: html
        });

        javaex.table({
            id: "upMsgTable",
            isDragColWidth: true,      // 是否允许拖动改变列宽
            mode: "overflow",          // overflow表示允许使用父容器溢出来调整列的大小
            leftFixedColNum: 2,        // 左侧固定列数
            rightFixedColNum: 1,       // 右侧固定列数
            sort: {
                "1": "create_time",     // 4表示第几列(从1开始计)。create_time表示排序字段,回调函数会返回该值
                "2": "update_time"
            },
            sortCallback: function (rtn) {
                //console.log(rtn.sortArr);
            }
        });

        //
        $("#getUpMsg").click(async function () {

            let temp = HNAPI.getUpCard(parseInt(javaex.getSelectVal("#up_uid")));


            await HNTOOL.Sleep(500);


            if (temp != false) {
                let data = BiliData.upCard.data;

                let html = ``;
                html += `<tr><td>用户UID</td><td>${data.card.mid}</td></tr> `
                html += `<tr><td>用户等级</td><td>lv${data.card.level_info.current_level}</td></tr> `
                html += `<tr><td>用户昵称</td><td>${data.card.name}</td></tr> `
                html += `<tr><td>用户性别</td><td>${data.card.sex}</td></tr> `
                html += `<tr><td>用户头像</td><td><a href="javascript:;"><img src= ${data.card.face} width="50%"></a></td></tr> `
                html += `<tr><td>粉丝数</td><td>${data.follower}</td></tr> `
                html += `<tr><td>关注数</td><td>${data.card.friend}</td></tr> `
                html += `<tr><td>是否关注此用户</td><td>${data.following}</td></tr> `
                html += `<tr><td>用户稿件数</td><td>${data.archive_count}</td></tr> `
                html += `<tr><td>用户勋章</td><td>${data.card.nameplate.name}<a href="javascript:;"><img src= ${data.card.nameplate.image} width="50%"></a> </td></tr> `
                html += `<tr><td>用户勋章等级</td><td>${data.card.nameplate.level}</td></tr> `
                html += `<tr><td>认证信息</td><td>${data.card.Official.title}</td></tr> `


                $("#upMsgTbody").empty();
                $("#upMsgTbody").append(html);
            }


        });
        //点击放大
        /*        $("img").click(function() {
                    javaex.dialog({
                        type : "image",	// 弹出层类型
                        url : $(this).attr("src")	// 图片地址
                    });
                });*/

    });


    $("#addPlay").bind("click", async function () {


        let html = '';

        html += '<div  style="padding: 10px 10px 10px 0px;">'
        html += '<form id="getUpMassage_form">'

        html += '    <div class="javaex-unit clear">'
        html += '        <div class="javaex-unit-left"><p class="subtitle required">UID</p></div>'
        html += `        <div class="javaex-unit-right" tooltip="请输入用户UID,默认自己" tooltip-pos="up"> `
        html += '            <input type="text" class="javaex-text" data-type="positive_int|required" error-msg="请正确输入uid"'
        html += `                   id="addPlay_uid" value="${Live_info.uid}"  placeholder="默认${Live_info.author_uid}"/>`
        html += '        </div>'
        html += '    </div>'
        html += '    <div class="javaex-unit clear">'
        html += '        <div class="javaex-unit-left"><p class="subtitle required">BV</p></div>'
        html += '        <div class="javaex-unit-right" tooltip="请输入视频BV号 例如BV14r4y1A7Q9 (0表示全部)" tooltip-pos="up">'
        html += '            <input type="text" class="javaex-text" data-type="required|english_number" error-msg=""'
        html += `                   id="addPlay_bv" value="0"  placeholder="请输入视频BV号 例如BV14r4y1A7Q9 (0表示全部)"/>`
        html += '        </div>'
        html += '    </div>'
        html += '</form>';
        html += '    <div class="javaex-unit clear tc">'
        html += '        <button id="addPlay_bgn" class="javaex-btn blue radius-3">开始</button> '
        html += '    </div>'
        html += '<hr class="javaex-divider"></hr>';
        html += '</div>';


        javaex.panel(this, {
            position: "right",
            content: html
        });

        $("#addPlay_bgn").click(async function () {

            let MID = javaex.getSelectVal("#addPlay_uid")
            let BV = javaex.getSelectVal("#addPlay_bv");
            let bvArr = [];
            let bvArr2 = [];

            MID = javaex.ifnull(MID, Live_info.author_uid);


            if (BV == "0") {

                //1.查询up所有视频BV号 2.发送心跳间隔2s
                HNAPI.getUpAllBV(Live_info.author_uid, 1, 2);
                await HNTOOL.Sleep(500);
                bvArr2 = BiliData.BVList;

                for (let i = 1; i > 0; i++) {

                    HNAPI.getUpAllBV(MID, i);

                    await HNTOOL.Sleep(500);

                    if (BiliData.BVList.length == 0) {
                        if (bvArr.length == 0) {
                            javaex.tip({
                                content: "该用户无投稿视频,请确认是否有误!",
                                type: "success"
                            });
                            await HNTOOL.Sleep(2000);
                        }
                        //bvArr = bvArr.ifnull(bvArr2, bvArr.concat(bvArr2));
                        bvArr = bvArr.concat(bvArr2);
                        break;
                    }

                    bvArr = bvArr.concat(BiliData.BVList);
                }


                if (bvArr.length != 0) {

                    for (const emt of bvArr) {

                        HNAPI.playOneVideo(emt.bvid,MID);

                        await HNTOOL.Sleep(2000);

                    }

                    alert("播放完成!!!");

                }


            } else {
                //1.调用点击播放接口
                //2.发送心跳

                await HNTOOL.Sleep(500);

                HNAPI.playOneVideo(BV);
            }


        });


    });

}


let showUnreadMsg = function () {

    var html = '';
    html += '<div class="javaex-panel-box" style="width: 250px;">';
    html += '	<ul>';
    html += `       <p style="color: #FFF;">用户消息</p>`;
    html += `		<li><a href="https://message.bilibili.com/#/at">未读艾特数:${BiliData.Unread.at}</a> </li> `;
    html += `		<li><a href="https://message.bilibili.com/#/love">未读点赞数:${BiliData.Unread.like}</a> </li> `;
    html += `		<li><a href="https://message.bilibili.com/#/reply">未读回复数:${BiliData.Unread.reply}</a> </li> `;
    html += `		<li><a href="https://message.bilibili.com/#/system">未读系统通知数:${BiliData.Unread.sys_msg}</a> </li> `;
    html += `		<li><a href="">UP主助手信息数:${BiliData.Unread.up}</a> </li> `;
    html += '		<hr class="javaex-divider"></hr>';
    html += '	</ul>';
    html += '</div>';


    javaex.panel(document.getElementById("getUnread"), {
        position: "right",
        content: html
    });

    javaex.tip({
        content: "查询用户通知成功!",
        type: "success"
    });

}

/**
 * 检查 艾特信息
 * @returns {Promise<void>}
 */
let chackAtMsg = async function (items) {

    await HNTOOL.Sleep(500);

    if (items != false && typeof (items) != "undefined") {


        var html = '';
        html += '<div class="javaex-panel-box" style="width: auto;">';
        html += '	<ul>';
        html += `       <p style="color: #FFF;">@信息</p>`;
        items.forEach(function (item) {

            var atTime = javaex.dateFormat(item.at_time, 'yyyy-MM-dd HH:mm:ss');

            html += ` <li>${atTime} <a class="fontbold" href="https://space.bilibili.com/${item.user.mid}">:${item.user.nickname}</a>在动态中艾特了你!</li> `
            html += ` <li class="fontbold">内容:${item.item.source_content}</li> `;
            html += `  <li><a href="${item.item.uri}">---点击查看详情---</a> </li>   `;
            html += ' <hr class="javaex-divider"></hr>';
        });
        html += '	</ul>';
        html += '</div>';

        if (($("#chackList").attr("class")).indexOf("hover") > -1) {
            javaex.panel(document.getElementById("getAtMsg"), {
                position: "right",
                content: html
            });
        } else {
            javaex.panel(document.getElementById("chackList"), {
                position: "right",
                content: html
            });
        }


    }

}


let addSetPage = async function () {

    HNTOOL.Sleep(1000);

    $('body').append('' +
        '<div id="left_navbar">' +
        '<div class="javaex-menu-container"> ' +
        ' <div id="menu" class="javaex-menu"> ' +
        '  <ul> ' +
        '   <li class="javaex-menu-item alone hover"  > ' +
        '    <a href="javaScript:;" style="background: #fb7299;padding-left: 0px;text-align: center;color: #ffffff;font-weight: bold;border-bottom: 1px solid #eee;" ' +
        `   tooltip="我是来测试的" tooltip-pos="right">管理中心 v${GM_info.script.version}</a> ` +
        '   </li> ' +
        '  </ul> ' +
        '  <ul> ' +
        '   <li class="javaex-menu-item"> ' +
        '    <a href="javascript:;">个人中心<i class="icon-angle-down"></i></a> ' +
        '    <ul> ' +
        '     <li id="biliUserMsg"  class="javaex-hover-pulse"><a href="javaScript:;">用户信息</a></li> ' +
        '    </ul> ' +
        '   </li> ' +
        '   <li id="chackList" class="javaex-menu-item"> ' +
        '    <a href="javaScript:;">查询<i class="icon-angle-down"></i></a> ' +
        '    <ul> ' +
        '     <li id="getUpMassage" ><a href="javaScript:;">查询用户详细信息</a></li> ' +
        '     <li><a href="javaScript:;">查询每日最热视频【禁用】</a></li> ' +
        '     <li id="getAtMsg"><a href="javaScript:;">查询动态艾特信息</a></li> ' +
        '     <li id="getCoinLog" class="javaex-hover-pulse"><a href="javaScript:;">查询硬币变化</a></li> ' +
        '     <li id="getUnread"  class="javaex-hover-pulse"><a href="javaScript:;">查询消息</a></li> ' +
        '    </ul> ' +
        '   </li> ' +
        '   <li class="javaex-menu-item"> ' +
        '    <a href="javascript:;">工具<i class="icon-angle-down"></i></a> ' +
        '    <ul> ' +
        '     <li class="javaex-hover-pulse"><a href="javaScript:;" >移动粉丝勋章【禁用】</a></li> ' +
        '     <li id="addPlay" class="javaex-hover-pulse"><a href="javaScript:;" >一键批量播放视频</a></li> ' +
        '     <li id="disUser" class="javaex-hover-pulse"><a href="javaScript:;" >一键批量拉黑</a></li> ' +
        '     <li id="" class="javaex-hover-pulse" ><a href="javaScript:;">动态评论区点赞【禁用】</a></li> ' +//likeInDynamicComments
        '     <li id="HNSetup" class="javaex-hover-pulse" ><span class="icon-cogs" style="font-size:50px;color:#ff0000;"></span><a href="javaScript:;">设置【禁用】</a></li> ' +
        '    </ul> ' +
        '   </li> ' +


        '  </ul> ' +
        ' </div> ' +
        '</div>' +
        '</div>');
    //$("#left_navbar").before('<button hnBtn="btn_open" class="javaex-btn green" onclick="openBar()">点我关闭</button>')

    javaex.menu({
        id: "menu",
        isShowAll: false
    });

}


let addStyle = function () {
    const animate = GM_getResourceText('animate');
    const common = GM_getResourceText('common');
    const defaultCss = GM_getResourceText('defaultCss');
    //const icomoonex = GM_getResourceText('icomoonex');
    //const AllCss = animate + common + defaultCss + icomoonex;
    const AllCss = animate + common + defaultCss;
    const style = document.createElement('style');
    style.innerHTML = AllCss;
    return document.getElementsByTagName('head')[0].appendChild(style);
}

/*-----------------------------------------------点击事件绑定--------------------------------------------------*/


/*-----------------------------------------------常用API--------------------------------------------------*/

let HNAPI = {


    /**
     * //https://api.bilibili.com/x/relation/modify
     *
     * @param UID
     */
    disUserByUid:function (vmid) {

        Ajax.post({
            url: BILIBLI_PATH.api + '/x/relation/modify',
            data: {
                fid: parseInt(vmid),
                re_src: 11,
                act: 5,
                jsonp: "jsonp",
                csrf: Live_info.csrf_token,
            },
            hasCookies: true,
            dataType: 'application/x-www-form-urlencoded; charset=UTF-8',
            success: responseText => {

                var json = JSON.parse(responseText);

                if (json.code != 0) {

                    console.log("拉黑用户失败uid:" + vmid + " 错误信息"+ json.message);
                    javaex.tip({
                        content: "拉黑用户失败uid:" + vmid + " 错误信息"+ json.message,
                        type: "error"
                    });

                }else{
                    console.log("拉黑用户成功 uid:" + vmid);
                    javaex.tip({
                        content: "拉黑用户成功 uid:" + vmid,
                        type: "success"
                    });
                }
            }
        });

    },
    /**
     * http://api.bilibili.com/x/web-interface/view
     * @param BV
     * 心跳间隔15秒
     */
    playOneVideo: function (BV,MID) {

        //1.调用点击播放接口 https://api.bilibili.com/x/click-interface/click/web/h5
        Ajax.post({
            url: BILIBLI_PATH.api + "/x/click-interface/click/web/h5",
            hasCookies: true,
            dataType: 'application/x-www-form-urlencoded; charset=UTF-8',
            data: {

                "bvid": BV,
                "part": 1,
                "mid": Live_info.uid,
                "lv": 2,
                "jsonp": "jsonp",
                "type": 3,
                "sub_type": 0
            },
            success: responseText => {

                let json = JSON.parse(responseText);

                if (/^{"code":0/.test(responseText)) {
                    //发送一次心跳
                    HNAPI.sendHeartbeat(BV,MID);

                } else {
                    javaex.tip({
                        content: "视频" + data.bvid + "播放失败!" + json.message,
                        type: "error"
                    });
                }
            }
        })


    },

    //上报视频播放心跳(web端)
    /**
     * http://api.bilibili.com/x/click-interface/web/heartbeat
     * @param json
     */
    sendHeartbeat: function (bvid,MID) {

        Ajax.post({
            url: BILIBLI_PATH.api + "/x/click-interface/web/heartbeat",
            hasCookies: true,
            dataType: 'application/x-www-form-urlencoded; charset=UTF-8',
            //aid=756988764&bvid=BV1wr4y1P782&cid=304166326&page=1
            data: {
                "bvid": bvid,
                "type": 3,
                "dt": 2,
                "played_time": HNTOOL.random(12, 40),
                "realtime": HNTOOL.random(12, 40),
                "play_type": 0
            },
            success: responseText => {

                if (/^{"code":0/.test(responseText) && MID != Live_info.author_uid) {

                    javaex.tip({
                        content: "视频BV" + bvid + "播放一次!",
                        type: "success"
                    });
                }
            }
        })

    },

    //获取up所有投稿视频
    /**
     * https://api.bilibili.com/x/space/arc/search?mid=99439379&ps=30&tid=0&pn=1&keyword=&order=pubdate&jsonp=jsonp
     * @param mid
     */
    getUpAllBV: function (mid, pn, ps) {
        ps = (ps === undefined ? 30 : ps); // a默认值为1
        Ajax.get({
            url: BILIBLI_PATH.api + '/x/space/arc/search',
            queryStringsObj: {
                mid: mid,
                tid: 0,
                order: 'pubdate',
                jsonp: 'jsonp',
                pn: pn,
                ps: ps
            },
            hasCookies: true,
            success: responseText => {

                var json = JSON.parse(responseText);

                if (json.code != 0) {

                    javaex.tip({
                        content: "获取up所有投稿视频失败!" + json.message,
                        type: "success"
                    });

                } else {
                    BiliData.BVList = json.data.list.vlist;

                }
            }
        });

    },


    /**
     *
     * @param path
     * @param data
     * @param saveObj
     * @param Func
     */
    publicGet: function (path, queryStringsObj) {

        if (typeof (queryStringsObj) != "undefined") {
            queryStringsObj = {};
        }
        Ajax.get({
            url: BILIBLI_PATH.api + path,
            queryStringsObj: queryStringsObj,
            hasCookies: true,
            success: responseText => {

                let json = JSON.parse(responseText);
                if (chackCode(json.code) && json.code == 0) {

                    return json.data;
                }

                return false;

            }
        })

    },

    /**
     * 导航栏用户信息
     */
    getUserNav: async function () {

        GM_xmlhttpRequest({
            method: "GET",
            url: BILIBLI_PATH.api + "/x/web-interface/nav",
            //timeout:3000,
            onload: function (response) {

                let json = JSON.parse(response.response);
                console.log(json);
                BiliData.login_code = json.code;
                BiliData.login_message = json.message;
                BiliData.LoginData = json.data;

            }
        });

    },

    /**
     * 获取某up详细信息
     * http://api.bilibili.com/x/web-interface/card
     */
    getUpCard: function (mid) {

        Ajax.get({
            url: BILIBLI_PATH.api + '/x/web-interface/card',
            queryStringsObj: {
                mid: mid,
                photo: false
            },
            hasCookies: true,
            success: responseText => {

                var json = JSON.parse(responseText);

                if (json.code != 0) {

                    javaex.tip({
                        content: "查询失败!" + json.message,
                        type: "success"
                    });
                    return false;
                } else {
                    BiliData.upCard = json;

                }


            }
        })

    },

    /**
     *
     * @param uid 用户uid
     * @param ps 每页视频个数 默认30个
     * @param pn 第几页
     */
    getUpAllVideo: function (uid, ps, pn) {

    },
    getChallenge: async function () {


    },
    /**
     * 硬币记录
     * @returns {Promise<void>}
     */
    getCoinLog: async function () {

        GM_xmlhttpRequest({
            method: "GET",
            url: BILIBLI_PATH.api + "/x/member/web/coin/log",
            //url: "http://api.bilibili.com/x/member/web/coin/log",
            onload: function (response) {

                let json = JSON.parse(response.response);
                if (json.code == 0) {

                    console.log("硬币记录" + json);
                    BiliData.CoinLog = json.data;

                    return true;
                }

            }
        });
    },
    /**
     * 未读消息数 http://api.bilibili.com/x/msgfeed/unread
     * @returns {Promise<void>}
     */
    getUnread: async function () {

        Ajax.get({
            url: BILIBLI_PATH.api + "/x/msgfeed/unread",
            hasCookies: true,
            success: responseText => {

                let json = JSON.parse(responseText);
                if (chackCode(json.code) && json.code == 0) {

                    BiliData.Unread = json.data;
                    showUnreadMsg();
                }

                return false;

            }
        })

        /* GM_xmlhttpRequest({
             method: "GET",
             url: BILIBLI_PATH.api + "/x/msgfeed/unread",
             onload: function (response) {

                 let json = JSON.parse(response.response);

                 if (chackCode(json.code) && json.code == 0) {

                     BiliData.Unread = json.code;
                     showUnreadMsg();

                 }

             }
         });*/
    },
    /**
     *
     * @param type reply:回复我的 at @我的
     */
    getMsgfeed: function (type) {
        Ajax.get({
            url: BILIBLI_PATH.api + '/x/msgfeed/' + type,
            queryStringsObj: {
                build: 0,
                mobi_app: 'web'
            },
            hasCookies: true,
            success: responseText => {

                var json = JSON.parse(responseText);

                if (json.code != 0 || !json.data.cursor.is_end || json.data.items == null) {
                    return false;
                } else {
                    chackAtMsg(json.data.items);

                    return true;
                }


            }
        })

    },

    /** 未读消息数 http://api.bilibili.com/x/space/arc/search?mid=99439379&pn=1&ps=5
     * @returns {Promise<void>}
     */
    getUnrewad: async function () {

        GM_xmlhttpRequest({
            method: "GET",
            data: {
                "mid": 99439379,
                "pn": 1,
                "ps": 5,
            },
            url: BILIBLI_PATH.api + "/x/space/arc/search",
            onload: function (response) {

                let json = JSON.parse(response.response);
                if (json.code == 0) {

                    BiliData.Video = json.data;
                    console.log("未读消息数" + json);
                }

            }
        });
    },

    /** 动态评论区点赞 https://api.bilibili.com/x/v2/reply/action
     * @param {number} oid
     * @param {nbumber} rpid
     * @param {number} action
     * @returns {Promise<void>}
     * type: 11
     * ordering: heat
     * jsonp: jsonp
     * csrf: 54a******* CSRF Token(位于cookie)
     */

    likeInDynamicComments: async function (oid, rpid, action) {


        Ajax.post({
            url: BILIBLI_PATH.api + "/x/v2/reply/action",
            hasCookies: true,
            dataType: 'application/x-www-form-urlencoded; charset=UTF-8',
            data: {
                "oid": oid,
                "type": 11,
                "rpid": rpid,
                "action": action,
                "ordering": "heat",
                "jsonp": "jsonp",
                "csrf": Live_info.csrf_token,
            },
            success: responseText => {

                if (/^{"code":0/.test(responseText)) {

                    BiliData.replyAction = JSON.parse(responseText);
                    console.log("点赞成功!" + responseText);
                }
            }
        })

    },


}

/*-----------------------------------------------常用工具函数--------------------------------------------------*/


let HNTOOL = {

    /**
     *  获取cookie 中某个键对应的值
     * @param name
     */

    getCookie: function (name) {
        let arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"));
        if (arr != null) return unescape(arr[2]);
        return false;
    },
    /**
     * 得到一个字符串数组的中随机一个
     * @param {List} list
     */
    getRandomWordOfList: function (list) {
        var L = list.length;
        var i = Math.ceil(Math.random() * L);

        return list[i];
    },
    random: function (min, max) {

        return Math.floor(Math.random() * (max - min)) + min;
    },

    Sleep: function (ms) {
        return new Promise(resolve => setTimeout(() => resolve('sleep'), ms));
    }

}

let errorMsg = {
    "-1": "应用程序不存在或已被封禁!",
    "-2": "Access Key错误!",
    "-3": "API校验密匙错误!",
    "-4": "调用方对该Method没有权限!",
    "-101": "账号未登录!",
    "-102": "账号被封停!",
    "-103": "积分不足!",
    "-104": "硬币不足!",
    "-105": "验证码错误!",
    "-106": "账号非正式会员或在适应期!",
    "-107": "应用不存在或者被封禁!",
    "-108": "未绑定手机!",
    "-109": "未知!",
    "-110": "未绑定手机!",
    "-111": "csrf 校验失败!",
    "-112": "系统升级中!",
    "-113": "账号尚未实名认证!",
    "-114": "请先绑定手机!",
    "-115": "请先完成实名认证!",
    "-304": "木有改动!",
    "-307": "撞车跳转!",
    "-400": "请求错误!",
    "-401": "未认证!",
    "-403": "访问权限不足!",
    "-404": "啥都木有!",
}

/*-----------------------------------------------CODE 统一检查--------------------------------------------------*/
/**
 *
 * @param code
 * @constructor
 */
let chackCode = function (code) {

    let emsg = errorMsg[code + ""];
    if (emsg != null) {
        javaex.tip({content: emsg, type: "error"});

        return false;
    }

    return true;
}


/*-----------------------------------------------localStorage封装 (本地存储信息)--------------------------------------------------*/
//javaex.setLocalStorage(key, value); var str = javaex.getLocalStorage(key); javaex.deleteLocalStorage(key);

/*window.onbeforeunload = function() {
    if (!canLeavePage()) {
        return ('确认离开当前页面吗?未保存的数据将会丢失!');
    }
};*/


/**
 * Ajax请求对象
 */
const Ajax = (() => {
    /**
     * 检查options是否符合要求
     * @param {object} options
     * @returns {boolean}
     */
    function checkOptions(options) {
        let result = false;
        if (typeof options !== 'object') {
            console.warn('类型错误: typeof Options !== Object');
            return result;
        } else {
            if (typeof options.url !== 'string') {
                console.warn('类型错误: typeof Link !== Strings');
                return result;
            } else {
                const reg = /^https?:\/\/(?:\w+\.?)+(?:\/.*)*\/?$/i;
                if (!reg.test(options.url)) {
                    console.warn('url字符串须为完整http链接');
                    return result;
                }
                result = true;
            }
        }
        return result;
    }

    /**
     * 对象转URL编码
     * @param {object} data
     */
    function objToURLCode(data) {
        var _result = [];
        for (var key in data) {
            var value = data[key];
            if (value instanceof Array) {
                value.forEach(function (_value) {
                    _result.push(key + "=" + _value);
                });
            } else {
                _result.push(key + '=' + value);
            }
        }
        return _result.join('&');
    }

    /**
     * 请求
     * @param {string} method
     * @param {object} options
     */
    function request(method, options) {
        if (checkOptions(options)) {
            let xhr = new XMLHttpRequest();
            const {url: _url, queryStringsObj, data, dataType, hasCookies} = options
                , url = typeof queryStringsObj === 'object' ?
                _url + '?' + objToURLCode(queryStringsObj) : _url;
            switch (method) {
                case 'GET':
                    xhr.open("GET", url);
                    break;
                case 'POST':
                    xhr.open("POST", url);
                    xhr.setRequestHeader('Content-Type', dataType);
                    break;
                default:
                    break;
            }
            if (hasCookies) xhr.withCredentials = true;
            xhr.timeout = 3000;
            xhr.addEventListener('load', () => {
                if (xhr.status === 200) {
                    options.success(xhr.responseText)
                } else {
                    console.error(`status:${xhr.status}`);
                    options.success(`{"code":${xhr.status},"msg":"频繁访问"}`);
                }
            })
            xhr.addEventListener('error', () => {
                console.error('ajax请求出错')
                options.success('{"code":-1,"msg":"ajax请求出错"}');
            })
            xhr.addEventListener('timeout', () => {
                console.error('请求超时')
                options.success('{"code":-1,"msg":"请求超时"}');
            })
            switch (method) {
                case 'GET':
                    xhr.send()
                    break;
                case 'POST':
                    xhr.send((/urlencoded/.test(dataType)) ? objToURLCode(data) : data)
                    break;
                default:
                    break;
            }
        }
    }

    return {
        /**
         * 发送Get请求
         * @param {Object} options
         */
        get(options) {
            request("GET", options);
        },
        /**
         * 发送Post请求
         * @param {object} options
         */
        post(options) {
            request("POST", options);
        }
    }
})()