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

我的我的 都是我的

As of 2019-08-27. See the latest version.

// ==UserScript==
// @name         B站直播自动抢辣条二代by十六夜
// @namespace    http://tampermonkey.net/
// @version      2.6
// @description  我的我的 都是我的
// @author       逆回十六夜
// @match        https://live.bilibili.com/*
// @grant        none
// ==/UserScript==
let NAME = 'IZAYOI';

$(document).ready(function () {//页面加载完毕执行
    const MY_API = {
        CONFIG_DEFAULT: {
            OPEN_WiN_TYPE: 0,
            TIME_FLASH: 10e3,
            TIME_GET: 100,
        },
        CONFIG: {
            OPEN_WiN_TYPE: 0,
            TIME_FLASH: 10e3,
            TIME_GET: 100,
        },
        init: function () {
            let p = $.Deferred();
            try {
                MY_API.loadConfig().then(function () {
                    MY_API.chatLog('脚本载入配置成功');
                    p.resolve()
                });
            } catch (e) {
                console.log('API初始化出错', e);
                MY_API.chatLog('脚本初始化出错');
                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': '130px',
                'left': 'calc(50% - 90px)',
                'background': 'rgba(240,240,240,.7)',
                'border': '1px solid',
                '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>
</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 style="width: 100%; background-color: black; height: 1px; margin: 3px 0;"></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>
`);
            $('.chat-history-panel').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.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()
            });
        },
        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)',
                        'background': 'rgb(245, 235, 221) none repeat scroll 0% 0%',
                    });
                    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);//滚动到底部
        }

    };
    MY_API.init().then(function () {
        console.log(MY_API.CONFIG);
        StartPlunder(MY_API);
    });
});

if (getUrlParam('close')) {
    window.close();//关闭弹窗测试的窗口
}

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
        }

        if (!getUrlParam('win') && !getUrlParam('close')) {
            window.open('https://live.bilibili.com/6498960?close=1', '_blank');// 弹窗测试
        }

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

        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;//流星雨延迟
                            }
                            number = number + ',' + delay;//直播间号和延迟
                            e_link.attr('number', number);
                            if (!isInArray(numberList, number)) {
                                numberList.push(number);
                                linkList.push(e_link);//加入需要打开的直播间列表
                                e_link.text('等待抽奖...');
                            } else {
                                e_link.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 (linkList.length > 0) {
                for (let l of linkList) {//延迟打开直播间
                    let count = l.attr('number').split(',')[1];
                    let index = setInterval(function () {
                        l.text('等待抽奖...' + count.toString() + 'S');
                        if (count <= 0) {
                            let myDate = new Date();
                            clearTimeout(index);//清除定时器
                            //参与抽奖
                            switch (API.CONFIG.OPEN_WiN_TYPE) {
                                case 0:
                                    window.open('https://live.bilibili.com' +
                                        l.attr('number').split(',')[0] + '?mode=Izayoi', '_blank');
                                    break;
                                case 1:
                                    window.open('https://live.bilibili.com' +
                                        l.attr('number').split(',')[0] + '?mode=Izayoi', '_blank');
                                    break;
                            }
                            l.text('辣条已抢~' + myDate.toLocaleString());
                        }
                        count--;
                    }, 1000);
                }
                console.log(linkList, numberList, 'list');
            }
        }, 10000);
        setInterval(function () {//重置直播间
            let href = location.href;
            if (href.indexOf('win') < 0) {
                if (href.indexOf('?') >= 0) {
                    href += '&win=off';
                } else {
                    href += '?win=off';
                }
            }
            location.href = href;
        }, 7200000);
    } else {
        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;
            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) {//已经抽过礼物并且没有了
                    setTimeout(function () {
                        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) {
                    window.close();//10s后如果没有礼物则关闭直播间
                }
            }, 10000);
            setTimeout(function () {
                window.close();//20s超时关闭直播间
            }, 20000);
        } else {
            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 = 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;
                }
            }
            //
            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;
}