B站直播自动抢辣条二代by十六夜

我的我的 都是我的

As of 2019-09-29. See the latest version.

// ==UserScript==
// @name         B站直播自动抢辣条二代by十六夜
// @namespace    http://tampermonkey.net/
// @version      4.3
// @description  我的我的 都是我的
// @author       逆回十六夜
// @include      /https?:\/\/live\.bilibili\.com\/\d+\??.*/
// @include      /https?:\/\/live\.bilibili\.com/blanc/\d+\??.*/
// @grant        window.close
// @require      https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js
// @require      https://cdn.bootcss.com/layer/2.3/layer.js
// @require      https://greasyfork.org/scripts/38140-bilibiliapi/code/BilibiliAPI.js
// ==/UserScript==
let NAME = 'IZAYOI';
let BAPI;
let server_host;
let test = false;
console.log = () => {};//关闭控制台输出
let Live_info = {room_id: undefined, uid: undefined};
$('head').append('<link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/layer/2.3/skin/layer.css">');//加载layer样式
$(function () {//DOM完毕,等待弹幕加载完成
    let loadInfo = (delay) => {
        setTimeout(function () {
            if (BilibiliLive === undefined || parseInt(BilibiliLive.UID) === 0 || isNaN(parseInt(BilibiliLive.UID))) {
                loadInfo(1000);
                console.log('无配置信息');
            } else {
                Live_info.room_id = BilibiliLive.ROOMID;
                Live_info.uid = BilibiliLive.UID;
                console.log(Live_info);
                init();
            }
        }, delay);
    };
    loadInfo(1000);

    setTimeout(function () {
        if (location.href.indexOf('mode=') >= 0) {
            let app = $('#app');
            if (app.length > 0) {//内嵌直播间的官方页面3s后强制关闭
                setTimeout(function () {
                    myClose();
                    window.close();
                }, 3000);
            }
        }
    }, 5000);
});

Array.prototype.remove = function (val) {
    let index = this.indexOf(val);
    if (index > -1) {
        this.splice(index, 1);
    }
};

function init() {//API初始化
    try {
        BAPI = BilibiliAPI;
    } catch (err) {
        console.error(`[${NAME}]`, err);
        return;
    }
    const MY_API = {
        CONFIG_DEFAULT: {
            OPEN_WiN_TYPE: 2,
            TIME_FLASH: 10e3,
            TIME_GET: 100,
            TIME_RELOAD: 60,
            TOP10_SWITCH: false,
        },
        CONFIG: {
            OPEN_WiN_TYPE: 2,
            TIME_FLASH: 10e3,
            TIME_GET: 100,
            TIME_RELOAD: 60,
            TOP10_SWITCH: false,
        },
        init: function () {
            let p = $.Deferred();
            try {
                MY_API.loadConfig().then(function () {
                    MY_API.chatLog('脚本载入配置成功', 'success');
                    p.resolve()
                });
            } catch (e) {
                console.log('API初始化出错', e);
                MY_API.chatLog('脚本初始化出错', 'warning');
                p.reject()
            }
            return p
        },
        loadConfig: function () {
            let p = $.Deferred();
            try {
                let config = JSON.parse(localStorage.getItem(`${NAME}_CONFIG`));
                for (let item in MY_API.CONFIG) {
                    if (!MY_API.CONFIG.hasOwnProperty(item)) continue;
                    if (config[item] !== undefined && config[item] !== null) MY_API.CONFIG[item] = config[item];
                }
                p.resolve()
            } catch (e) {
                console.log('API载入配置失败,加载默认配置', e);
                MY_API.setDefaults();
                p.reject()
            }
            return p
        },
        saveConfig: function () {
            try {
                localStorage.setItem(`${NAME}_CONFIG`, JSON.stringify(MY_API.CONFIG));
                MY_API.chatLog('配置已保存');
                return true
            } catch (e) {
                console.log('API保存出错', e);
                return false
            }
        },
        setDefaults: function () {
            MY_API.CONFIG = MY_API.CONFIG_DEFAULT;
            MY_API.saveConfig();
            MY_API.chatLog('配置已重置为默认');
        },
        creatSetBox: function () {//创建设置框
            let div = $('<div>');
            div.css({
                'width': '158px',
                'height': 'auto',
                'position': 'absolute',
                'top': '110px',
                'right': '10px',
                'background': 'rgba(240,240,240,.7)',
                'border': '1px solid darkviolet',
                'padding': '10px',
                'z-index': '100',
            });
            div.append(`
<div data-toggle="OPEN_WiN_TYPE">
跳转抽奖模式(更改请刷新!):<br>
<label style="cursor: pointer; margin: 5px auto">
<input style="vertical-align: text-top;" name="TYPE" type="radio" value="0">弹出窗口式
</label><br>
<label style="cursor: pointer; margin: 5px auto">
<input style="vertical-align: text-top;" name="TYPE" type="radio" value="1">内部弹窗(测试)
</label><br>
<label style="cursor: pointer; margin: 5px auto;color: rebeccapurple">
<input style="vertical-align: text-top;" name="TYPE" type="radio" value="2">静默请求式(强烈推荐)
</label>
</div>
<div style="width: 100%; background-color: black; height: 1px; margin: 3px 0;"></div>
<div data-toggle="TIME_FLASH">
刷小时榜直♂勃间停留时间:<br>
<input class="delay-seconds" type="text" style="width: 30px;vertical-align: top;">秒
<button data-action="save">保存</button>
</div>
<div data-toggle="TIME_GET">
礼物点击速♂度:<br>
<input class="delay-seconds" type="text" style="width: 30px;vertical-align: top;">毫秒
<button data-action="save">保存</button>
</div>
<div data-toggle="TOP10_SWITCH">
<label style="cursor: pointer; margin: 5px auto;color: green">
<input style="vertical-align: text-top;" type="checkbox">刷小时榜功能开关
</label>
</div>
<div style="width: 100%; background-color: black; height: 1px; margin: 3px 0;"></div>
<div data-toggle="TIME_RELOAD">
本直播间重载时间(刷新后生效)<br>
<input class="delay-seconds" type="text" style="width: 30px;vertical-align: top;">分
<button data-action="save">保存</button>
</div>
<span style="color: red">内部弹窗目前在火狐浏览器会爆炸,所以如果想要用内部弹窗模式请使用谷歌浏览器
,<span style="color: rebeccapurple">
请求式会监听所有分区能抢所有分区的礼物,以后版本不在维护弹窗式的抽奖模式后续可能会考虑删除,包括轮刷小时榜</span>
<span style="color: green;">如果使用请求式抢礼物,无需开启刷小时榜,开这个直播间就够了</span>
</span>
`);
            $('.player-ctnr').append(div);

            //对应配置状态
            div.find('div[data-toggle="OPEN_WiN_TYPE"] input:radio[value="' + MY_API.CONFIG.OPEN_WiN_TYPE.toString() + '"]')
                .attr('checked', '');
            div.find('div[data-toggle="TIME_FLASH"] .delay-seconds').val((parseInt(MY_API.CONFIG.TIME_FLASH) / 1000).toString());
            div.find('div[data-toggle="TIME_GET"] .delay-seconds').val((parseInt(MY_API.CONFIG.TIME_GET)).toString());
            div.find('div[data-toggle="TIME_RELOAD"] .delay-seconds').val((parseInt(MY_API.CONFIG.TIME_RELOAD)).toString());
            if (MY_API.CONFIG.TOP10_SWITCH) div.find('div[data-toggle="TOP10_SWITCH"] input').attr('checked', '');

            //事件绑定
            div.on('change', 'div[data-toggle="OPEN_WiN_TYPE"] input:radio', function () {//打开直播间方式radio事件
                MY_API.CONFIG.OPEN_WiN_TYPE = parseInt($(this).val());
                MY_API.saveConfig()
            });

            div.find('div[data-toggle="TIME_FLASH"] button').click(function () {//TIME_FLASH save按钮
                if (MY_API.CONFIG.TIME_FLASH === parseInt(parseInt(div.find('div[data-toggle="TIME_FLASH"] .delay-seconds').val()) * 1000)) {
                    MY_API.chatLog('改都没改保存尼玛呢');
                    return
                }
                MY_API.CONFIG.TIME_FLASH = parseInt(parseInt(div.find('div[data-toggle="TIME_FLASH"] .delay-seconds').val()) * 1000);
                MY_API.saveConfig()
            });

            div.find('div[data-toggle="TIME_GET"] button').click(function () {//TIME_GET save按钮
                if (MY_API.CONFIG.TIME_GET === parseInt(div.find('div[data-toggle="TIME_GET"] .delay-seconds').val())) {
                    MY_API.chatLog('改都没改保存尼玛呢');
                    return
                }
                MY_API.CONFIG.TIME_GET = parseInt(div.find('div[data-toggle="TIME_GET"] .delay-seconds').val());
                MY_API.saveConfig()
            });

            div.find('div[data-toggle="TIME_RELOAD"] button').click(function () {//TIME_GET save按钮
                if (MY_API.CONFIG.TIME_RELOAD === parseInt(div.find('div[data-toggle="TIME_RELOAD"] .delay-seconds').val())) {
                    MY_API.chatLog('改都没改保存尼玛呢');
                    return
                }
                MY_API.CONFIG.TIME_RELOAD = parseInt(div.find('div[data-toggle="TIME_RELOAD"] .delay-seconds').val());
                MY_API.saveConfig()
            });

            div.find('div[data-toggle="TOP10_SWITCH"] input').change(function () {//
                MY_API.CONFIG.TOP10_SWITCH = $(this).prop('checked');
                MY_API.saveConfig()
            });
        },
        chatLog: function (text, type = 'info') {//自定义提示
            let div = $("<div>");
            let msg = $("<div>");
            let ct = $('#chat-history-list');
            let myDate = new Date();
            msg.text(text);
            div.text(myDate.toLocaleString());
            div.append(msg);
            div.css({
                'text-align': 'center',
                'border-radius': '4px',
                'min-height': '30px',
                'width': '256px',
                'color': '#9585FF',
                'line-height': '30px',
                'padding': '0 10px',
                'margin': '10px auto',
            });
            msg.css({
                'word-wrap': 'break-word',
                'width': '100%',
                'line-height': '1em',
                'margin-bottom': '10px',
            });
            switch (type) {
                case 'warning':
                    div.css({
                        'border': '1px solid rgb(236, 221, 192)',
                        'color': 'rgb(218, 142, 36)',
                        'background': 'rgb(245, 235, 221) none repeat scroll 0% 0%',
                    });
                    break;
                case 'success':
                    div.css({
                        'border': '1px solid rgba(22, 140, 0, 0.28)',
                        'color': 'rgb(69, 171, 69)',
                        'background': 'none 0% 0% repeat scroll rgba(16, 255, 0, 0.18)',
                    });
                    break;
                default:
                    div.css({
                        'border': '1px solid rgb(203, 195, 255)',
                        'background': 'rgb(233, 230, 255) none repeat scroll 0% 0%',
                    });
            }
            ct.append(div);//向聊天框加入信息
            ct.animate({scrollTop: ct.prop("scrollHeight")}, 400);//滚动到底部
        },
        blocked: false,
        listen: (roomId, uid, area = '本直播间') => {
            BAPI.room.getConf(roomId).then((response) => {
                server_host = response.data.host;
                console.log('服务器地址', response);
                let wst = new BAPI.DanmuWebSocket(uid, roomId, response.data.host_server_list, response.data.token);
                wst.bind((ws) => {
                    MY_API.chatLog(`${area}弹幕服务器连接断开,尝试重连`, 'warning');
                }, () => {
                    MY_API.chatLog(`——————连接弹幕服务器成功——————\n房间号: ${roomId} 分区: ${area}`
                    , 'success');
                }, () => {
                    if (MY_API.blocked) {
                        wst.close();
                        MY_API.chatLog('进了小黑屋主动与弹幕服务器断开连接', 'warning')
                    }
                }, (obj) => {
                    console.log('弹幕公告' + area, obj);
                    switch (obj.cmd) {
                        case 'GUARD_MSG':
                            if (obj.roomid === obj.real_roomid) {
                                MY_API.checkRoom(obj.roomid, area);
                            } else {
                                MY_API.checkRoom(obj.roomid, area);
                                MY_API.checkRoom(obj.real_roomid, area);
                            }
                            break;
                        case 'PK_BATTLE_SETTLE_USER':
                            MY_API.checkRoom(obj.data.winner.room_id, area);
                            break;
                        case 'NOTICE_MSG':
                            if (obj.roomid === obj.real_roomid) {
                                MY_API.checkRoom(obj.roomid, area);
                            } else {
                                MY_API.checkRoom(obj.roomid, area);
                                MY_API.checkRoom(obj.real_roomid, area);
                            }
                            break;
                        default:
                            return;
                    }
                });
            }, () => {
                MY_API.chatLog('获取弹幕服务器地址错误', 'warning')
            });
        },
        RoomId_list: [],
        checkRoom: function (roomId, area = '本直播间') {
            if (MY_API.blocked) {
                return
            }
            if (MY_API.RoomId_list.indexOf(roomId) >= 0) {//防止重复检查直播间
                return
            } else {
                MY_API.RoomId_list.push(roomId);
            }
            $.get('https://api.live.bilibili.com/xlive/lottery-interface/v1/lottery/Check?roomid=' + roomId,
                function (re) {
                    MY_API.RoomId_list.remove(roomId);//移除房间号
                    console.log('检查房间返回信息', re);
                    let data = re.data;
                    if (re.code === 0) {
                        let list;
                        if (data.gift) {
                            list = data.gift;
                            for (let i in list) {
                                if (!list.hasOwnProperty(i)) continue;
                                MY_API.creat_join(roomId, list[i], 'gift', area)
                            }
                        }
                        if (data.guard) {
                            list = data.guard;
                            for (let i in list) {
                                if (!list.hasOwnProperty(i)) continue;
                                MY_API.creat_join(roomId, list[i], 'guard', area)
                            }
                        }
                        if (data.pk) {
                            list = data.pk;
                            for (let i in list) {
                                if (!list.hasOwnProperty(i)) continue;
                                MY_API.creat_join(roomId, list[i], 'pk', area)
                            }
                        }
                        let ct = $('#chat-history-list');
                        ct.animate({scrollTop: ct.prop("scrollHeight")}, 0);//滚动到底部

                    } else {
                        MY_API.chatLog(`[检查房间出错]${response.msg}`, 'warning');
                    }
                });
        },
        raffleId_list: [],
        raffleId_list_history: [],
        guardId_list: [],
        pkId_list: [],
        creat_join: function (roomId, data, type, area = '本直播间') {
            console.log('礼物信息', data);
            switch (type) {//防止重复抽奖上船PK
                case 'gift':
                    if (MY_API.raffleId_list_history.indexOf(data.raffleId) > -1) {
                        return
                    } else {
                        MY_API.raffleId_list.push(data.raffleId);
                        MY_API.raffleId_list_history.push(data.raffleId);
                    }
                    break;
                case 'guard':
                    if (MY_API.guardId_list.indexOf(data.id) >= 0) {
                        return
                    } else {
                        MY_API.guardId_list.push(data.id);
                    }
                    break;
                case 'pk':
                    if (MY_API.pkId_list.indexOf(data.id) >= 0) {
                        return
                    } else {
                        MY_API.pkId_list.push(data.id);
                    }
                    break;
            }

            let delay = data.time_wait || 0;
            let div = $("<div>");
            let msg = $("<div>");
            let aa = $("<div>");
            let ct = $('#chat-history-list');
            let myDate = new Date();
            msg.text(`[${area}]` + data.thank_text.split('<%')[1].split('%>')[0] + data.thank_text.split('%>')[1]);
            div.text(myDate.toLocaleString());
            div.append(msg);
            aa.css('color', 'red');
            aa.text('等待抽奖');
            msg.append(aa);
            div.css({
                'text-align': 'center',
                'border-radius': '4px',
                'min-height': '30px',
                'width': '256px',
                'color': '#9585FF',
                'line-height': '30px',
                'padding': '0 10px',
                'margin': '10px auto',
            });
            msg.css({
                'word-wrap': 'break-word',
                'width': '100%',
                'line-height': '1em',
                'margin-bottom': '10px',
            });

            div.css({
                'border': '1px solid rgb(203, 195, 255)',
                'background': 'rgb(233, 230, 255) none repeat scroll 0% 0%',
            });

            ct.append(div);//向聊天框加入信息
            let timer = setInterval(function () {
                aa.text(`等待抽奖倒计时${delay}秒`);
                if (delay <= 0) {
                    aa.text(`进行抽奖...`);
                    switch (type) {
                        case 'gift':
                            MY_API.gift_join(roomId, data.raffleId, data.type).then(function (msg) {
                                aa.text('获得' + msg);
                            });
                            break;
                        case 'guard':
                            MY_API.guard_join(roomId, data.id).then(function (msg) {
                                aa.text('获得' + msg);
                            });
                            break;
                        case 'pk':
                            MY_API.pk_join(roomId, data.id).then(function (msg) {
                                aa.text('获得' + msg);
                            });
                            break;
                    }
                    aa.css('color', 'green');
                    MY_API.raffleId_list.remove(data.raffleId);
                    clearInterval(timer)
                }
                delay--;
            }, 1000);


        },
        gift_join: function (roomid, raffleId, type) {
            let p = $.Deferred();
            BAPI.Lottery.Gift.join(roomid, raffleId, type).then((response) => {
                console.log('抽奖返回信息', response);
                switch (response.code) {
                    case 0:
                        if (response.data.award_text) {
                            p.resolve(response.data.award_text);
                        } else {
                            p.resolve(response.data.award_name + 'X' + response.data.award_num.toString());
                        }
                        break;
                    default:
                        if (response.msg.indexOf('拒绝') > -1) {
                            MY_API.blocked = true;//停止抽奖
                            p.resolve('访问被拒绝,您的帐号可能已经被关小黑屋,已停止');
                        } else {
                            p.resolve(`[礼物抽奖](roomid=${roomid},id=${raffleId},type=${type})${response.msg}`);
                        }
                }
            });
            return p
        },
        guard_join: function (roomid, Id) {
            let p = $.Deferred();
            BAPI.Lottery.Guard.join(roomid, Id).then((response) => {
                console.log('上船抽奖返回信息', response);
                switch (response.code) {
                    case 0:
                        if (response.data.award_text) {
                            p.resolve(response.data.award_text);
                        } else {
                            p.resolve(response.data.award_name + 'X' + response.data.award_num.toString());
                        }
                        break;
                    default:
                        if (response.msg.indexOf('拒绝') > -1) {
                            MY_API.blocked = true;//停止抽奖
                            p.resolve('访问被拒绝,您的帐号可能已经被关小黑屋,已停止');
                        } else {
                            p.resolve(`[上船](roomid=${roomid},id=${Id})${response.msg}`);
                        }
                        break;
                }
            });
            return p
        },
        pk_join: function (roomid, Id) {
            let p = $.Deferred();
            BAPI.Lottery.Pk.join(roomid, Id).then((response) => {
                console.log('PK抽奖返回信息', response);
                switch (response.code) {
                    case 0:
                        if (response.data.award_text) {
                            p.resolve(response.data.award_text);
                        } else {
                            p.resolve(response.data.award_name + 'X' + response.data.award_num.toString());
                        }
                        break;
                    default:
                        if (response.msg.indexOf('拒绝') > -1) {
                            MY_API.blocked = true;//停止抽奖
                            p.resolve('访问被拒绝,您的帐号可能已经被关小黑屋,已停止');
                        } else {
                            p.resolve(`[PK](roomid=${roomid},id=${Id})${response.msg}`);
                        }
                        break;
                }
            });
            return p
        },

    };
    MY_API.init().then(function () {
        if (parseInt(Live_info.uid) === 0 || isNaN(parseInt(Live_info.uid))) {
            MY_API.chatLog('未登录,请先登录再使用脚本', 'warning');
            return
        }
        console.log(MY_API.CONFIG);
        StartPlunder(MY_API);
        let h = $('html,body');
        h.animate({scrollLeft: h.prop('scrollWidth')}, 0);//画面最右边
    });
}

function StartPlunder(API) {
    'use strict';
    let index, nowIndex;
    let LIVE_PLAYER_STATUS = window.localStorage["LIVE_PLAYER_STATUS"];


    let href = location.href;
    let id = /\/\d+/.exec(href).toString();//取本直播间号
    if (!id) {
        return
    }
    if (id === '/6498960') {
        if (LIVE_PLAYER_STATUS.indexOf("flash") >= 0) {
            window.localStorage["LIVE_PLAYER_STATUS"] = window.localStorage["LIVE_PLAYER_STATUS"].replace("flash", 'html5');
            window.location.reload();
            return
        }

        API.creatSetBox();//创建设置框

        if (API.CONFIG.OPEN_WiN_TYPE === 2) {//请求式抽奖
            BAPI.room.getList().then((response) => {
                console.log('直播间列表', response);
                for (const obj of response.data) {
                    BAPI.room.getRoomList(obj.id, 0, 0, 1, 1).then((response) => {
                        console.log('直播间号列表', response);
                        for (let j = 0; j < response.data.length; ++j) {
                            API.listen(response.data[j].roomid, Live_info.uid, `${obj.name}区`);
                        }
                    });
                }
            });
            let check_top_room = () => { //检查小时榜房间时钟
                if (API.blocked){//如果被禁用则停止
                    API.chatLog('已进小黑屋,检测小时榜已停止运行');
                    clearInterval(check_timer);
                    return
                }
                $.get("https://api.live.bilibili.com/rankdb/v1/Rank2018/" +
                    "getTop?type=master_realtime_hour&type_id=areaid_realtime_hour", function (data) {
                    let list = data.data.list;// [{id: ,link:}]
                    API.chatLog('检查小时榜房间的礼物', 'warning');
                    console.log(list);
                    for (let i of list) {
                        API.checkRoom(i.roomid, `小时榜-${i.area_v2_parent_name}区`);
                    }
                });
            };
            setTimeout(check_top_room, 6e3);
            let check_timer = setInterval(check_top_room, 600e3);

        } else {
            setInterval(function () {//打开链接时钟
                let link = $(".msg-content .link");
                let numberList = [];
                let linkList = [];
                if (link.length > 0) {
                    link.each(function () {
                        let e_link = $(this);
                        let link_href = e_link.attr('href');
                        let myDate = new Date();
                        if (link_href) {
                            link_href = link_href.split('?')[0];
                            let number, delay;
                            if (link_href.match(/\/\d+/) == null || e_link.text().indexOf('第一名') >= 0) {
                                e_link.text('这个不是礼物~' + myDate.toLocaleString());
                            } else {//是礼物
                                number = /\/\d+/.exec(link_href).toString();//取房间号
                                delay = 55;
                                if (e_link.text().indexOf('小电视飞船') >= 0) {
                                    delay = 115;//小电视延迟
                                }
                                if (e_link.text().indexOf('流星雨') >= 0) {
                                    delay = 115;//流星雨延迟
                                }
                                if (e_link.text().indexOf('月色真美') >= 0) {
                                    delay = 115;//延迟
                                }
                                if (e_link.text().indexOf('最终糕能') >= 0) {
                                    delay = 115;//延迟
                                }
                                if (e_link.text().indexOf('魔法光环') >= 0) {
                                    delay = 115;//延迟
                                }
                                if (e_link.text().indexOf('开通了总督') >= 0) {
                                    delay = 0;//延迟
                                }
                                if (e_link.text().indexOf('开通了舰长') >= 0) {
                                    delay = 0;//延迟
                                }
                                if (e_link.text().indexOf('开通了提督') >= 0) {
                                    delay = 0;//延迟
                                }
                                number = number + ',' + delay;//直播间号和延迟
                                let tips_div = $('<div>');
                                tips_div.attr('number', number);
                                tips_div.css('color', 'red');
                                e_link.parent().append(tips_div);
                                if (!isInArray(numberList, number)) {
                                    numberList.push(number);
                                    linkList.push(tips_div);//加入需要打开的直播间列表
                                    tips_div.text('等待抽奖...');
                                } else {
                                    tips_div.css('color', 'darkgray');
                                    tips_div.text('同上直播间同延迟礼物省略');
                                }
                            }
                            e_link.removeAttr('href');
                            e_link.removeAttr('class');
                        }
                    });
                }
                //检测任意门
                let a = $('.bilibili-live-player-video-operable-container div div div div a');
                let text = a.text();
                if (text.indexOf('任意门') >= 0) {
                    let number = /\/\d+/.exec(a.attr('href')).toString();//取房间号
                    let div = $("<div>");
                    let aa = $("<a>");
                    aa.text('等待...');
                    aa.attr('number', number + ',120');//任意门延迟
                    div.text('任意门');
                    div.append(aa);
                    div.css({
                        'text-align': 'center',
                        'border': '1px solid rgb(203, 195, 255)',
                        'background': 'rgb(233, 230, 255) none repeat scroll 0% 0%',
                        'border-radius': '4px',
                        'height': '72px',
                        'width': '276px',
                        'color': '#9585FF',
                        'line-height': '72px',
                    });
                    let ct = $('#chat-history-list');
                    ct.append(div);
                    ct.animate({scrollTop: ct.prop("scrollHeight")}, 400);
                    a.remove();
                    linkList.push(aa);
                }

                if (test) {//测试用
                    let div = $("<div>");
                    let aa = $("<a>");
                    aa.text('等待...');
                    aa.attr('number', '/76,5');//任意门延迟
                    div.text('测试');
                    div.append(aa);
                    div.css({
                        'text-align': 'center',
                        'border': '1px solid rgb(203, 195, 255)',
                        'background': 'rgb(233, 230, 255) none repeat scroll 0% 0%',
                        'border-radius': '4px',
                        'height': '72px',
                        'width': '276px',
                        'color': '#9585FF',
                        'line-height': '72px',
                    });
                    let ct = $('#chat-history-list');
                    ct.append(div);
                    ct.animate({scrollTop: ct.prop("scrollHeight")}, 400);
                    a.remove();
                    linkList.push(aa);
                    test = false;
                }

                if (linkList.length > 0) {
                    for (let l of linkList) {//延迟打开直播间
                        let delay = l.attr('number').split(',')[1];
                        let index = setInterval(function () {
                            l.text('等待抽奖...' + delay.toString() + 'S');
                            if (delay <= 0) {
                                let myDate = new Date();
                                clearTimeout(index);//清除定时器
                                //参与抽奖
                                l.css('color', 'brown');
                                l.text('正在抽奖...' + myDate.toLocaleString());
                                let url = 'https://live.bilibili.com' + l.attr('number').split(',')[0] + '?mode=Izayoi';
                                switch (API.CONFIG.OPEN_WiN_TYPE) {
                                    case 0:
                                        window.open(url, '_blank');
                                        l.css('color', 'green');
                                        l.text('辣条已抢~' + myDate.toLocaleString());
                                        break;
                                    case 1:
                                        layer.open({
                                            type: 2,
                                            shade: 0,
                                            title: '直勃间',
                                            content: [url],
                                            area: ['500px', '800px']
                                            , offset: [ //随机坐标
                                                Math.random() * ($(window).height() - 800)
                                                , Math.random() * ($(window).width() - 500)],
                                            success: function (DOM, index) {
                                                let iframe = $(DOM).find('iframe');
                                                let timer = setInterval(function () {
                                                    let flag = iframe.contents().find("#CloseCloseClose");
                                                    if (flag.length > 0) {
                                                        clearIframe(iframe[0]);
                                                        layer.close(index);//关闭layer弹窗
                                                        l.css('color', 'green');
                                                        l.text('辣条已抢~' + myDate.toLocaleString());
                                                        clearInterval(timer);
                                                    }
                                                }, 5e2);
                                                setTimeout(function () {
                                                    clearIframe(iframe[0]);
                                                    layer.close(index);//关闭layer弹窗
                                                    l.css('color', 'green');
                                                    l.text('辣条已抢~' + myDate.toLocaleString());
                                                    clearInterval(timer);
                                                }, 60000);
                                            }
                                        });
                                        break;
                                }
                            }
                            delay--;
                        }, 1000);
                    }
                    console.log(linkList, numberList, 'list');
                }
            }, 8000);
        }

        let reset = (delay) => {
            setTimeout(function () {//重置直播间
                if (API.raffleId_list.length > 0) {
                    console.log('还有礼物没抽 延迟30s后刷新直播间');
                    reset(30000);
                    return
                }
                if (API.blocked) {
                    return
                }
                window.location.reload();
            }, delay);
        };
        reset(API.CONFIG.TIME_RELOAD * 60000);
    } else {
        if (!API.CONFIG.TOP10_SWITCH && API.CONFIG.OPEN_WiN_TYPE === 2){
            API.chatLog('脚本未在此直播间启用', 'warning');
            return
        }
        if (LIVE_PLAYER_STATUS.indexOf("html5") >= 0) {
            window.localStorage["LIVE_PLAYER_STATUS"] = window.localStorage["LIVE_PLAYER_STATUS"].replace("html5", 'flash');
            window.location.reload();
            return
        }
        if (getUrlParam("mode")) {//弹出网页抽奖模式
            let count = 0;
            let timer = setInterval(function () {//点击抽奖时钟
                let old_btn = $(".main");
                let btn = $(".draw-full-cntr .function-bar");
                if (old_btn.length > 0 || btn.length > 0) {
                    count++;
                }
                old_btn.click();//点击抽奖
                btn.click();//点击抽奖
                if (old_btn.length <= 0 && btn.length <= 0 && count > 0) {//已经抽过礼物并且没有了
                    clearInterval(timer);
                    API.chatLog('抽完礼物,即将关闭直播间');
                    setTimeout(function () {
                        myClose();
                        window.close();//关闭直播间
                    }, 800);
                }
            }, parseInt(API.CONFIG.TIME_GET));

            setTimeout(function () {//十秒后
                let old_btn = $(".main");
                let btn = $(".draw-full-cntr .function-bar");
                if (old_btn.length <= 0 && btn.length <= 0) {
                    API.chatLog('没有礼物,即将关闭直播间');
                    setTimeout(function () {
                        myClose();
                        window.close();//关闭直播间
                    }, 800);
                } else if (btn.find('span:last').css('display') === 'none') {//礼物还在等待开奖
                    API.chatLog('礼物还在等待开奖,即将关闭直播间');
                    setTimeout(function () {
                        myClose();
                        window.close();//关闭直播间
                    }, 800);
                }
            }, 10000);

            setTimeout(function () {
                API.chatLog('超时,即将关闭直播间');
                setTimeout(function () {
                    myClose();
                    window.close();//关闭直播间
                }, 800);
            }, 60000);
        } else {
            if (API.CONFIG.TOP10_SWITCH) mode_old();
        }
    }

    function mode_old() {
        try {
            index = getUrlParam("index");
            nowIndex = parseInt(index) + 1;
            if (nowIndex === 12) {
                nowIndex = 0;
            }
            if (isNaN(nowIndex)) nowIndex = 0;
        } catch (error) {
            nowIndex = 0;
        }
        setInterval(function () {
            $(".main").click();//点击抽奖
            $(".draw-full-cntr .function-bar").click();//点击抽奖
        }, parseInt(API.CONFIG.TIME_GET));
        setInterval(function () {
            goTop(nowIndex);//跳转到下一个直播间
        }, API.CONFIG.TIME_FLASH);
    }

    function goTop(index) {
        $.get("https://api.live.bilibili.com/rankdb/v1/Rank2018/getTop?type=master_realtime_hour&type_id=areaid_realtime_hour", function (data) {
            let list = data.data.list;// [{id: ,link:}]
            let link = list[index].link;
            if (!link) {
                link = '/55356';
            }
            let href = parent.location.href;
            //
            if (href.match(/\/\d+/) != null) {
                href = href.replace(/\/\d+/, link);
            } else {
                href = 'https://live.bilibili.com' + link;
            }
            //
            if (href.indexOf('index') >= 0) {
                href = href.replace(/index=\d+/, 'index=' + nowIndex);
            } else {
                if (href.indexOf('?') >= 0) {
                    href += '&index=' + nowIndex;
                } else {
                    href += '?index=' + nowIndex;
                }
            }
            //
            parent.location.href = href;
        });
    }
}

function isInArray(arr, value) {
    for (let i of arr) {
        if (i == value) {
            return true;
        }
    }
    return false;
}

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

function myClose() {
    $('body').append('<div id="CloseCloseClose"></div>');
}

// 清除iframe内存空间
function clearIframe(el) {
    var _iframe = el.contentWindow;
    if (el) {
        el.src = 'about:blank';
        try {
            _iframe.document.write('');
            _iframe.document.clear();
        } catch (e) {
            console.log(e)
        }
        el.parentNode.removeChild(el);
    }
}