Greasy Fork

Greasy Fork is available in English.

Bilibili直播间挂机助手

Bilibili直播间自动签到,领瓜子,参加抽奖,完成任务,送礼等

当前为 2018-01-07 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Bilibili直播间挂机助手
// @namespace    SeaLoong
// @version      1.1.1
// @description  Bilibili直播间自动签到,领瓜子,参加抽奖,完成任务,送礼等
// @author       SeaLoong
// @include      /https?:\/\/live\.bilibili\.com\/\d+/
// @grant        none
// @run-at       document-end
// @license      MIT License
// ==/UserScript==

(function() {
    'use strict';

    /* 可修改以下内容用以自定义功能 */

    var CONFIG = {
        USE_SIGN: true, // 自动签到: true:启用, false:不启用
        USE_AWARD: true, // 自动领取瓜子: true:启用, false:不启用
        USE_LOTTERY: true, // 自动参加抽奖: true:启用, false:不启用
        USE_TASK: true, // 自动完成任务: true:启用, false:不启用
        USE_GIFT: true, // 自动送礼物: true:启用, false:不启用
        GIFT_CONFIG: { // 若启用自动送礼物,则需要设置以下项
            SHORT_ROOMID: 0, // 指定直播间ID(即地址中live.bilibili.com/后面的数字), 设置为0则表示自动检查是否有当前直播间头衔,有则切换并送礼
            USE_SILVER: false, // 消耗银瓜子来送礼物: true:允许, false:不允许
            ONLY_AFTER_23: true // 只允许在23:00后消耗银瓜子送礼物
        }
    };

    /* 可修改以上内容用以自定义功能 */

    var NAME = 'Bilibili-LiveRoom-HangHelper';
    var TaskAward_Running = false;
    var ToastElement,
        ToastCount = 0;
    var room_id_list = [];
    var lottery_list_last = [],
        lottery_check_time = 20;
    var gift_list = null;
    /*
    1:辣条:亲密度+1
    3:B坷垃:亲密度+99
    4:喵娘:亲密度+52
    6:亿元:亲密度+10
    7:666:亲密度+?
    8:233:亲密度+?
    25:小电视:亲密度+12450?
    39:节奏风暴:亲密度+1000?
    105:火力票:亲密度+20
    106:哔哩星:亲密度+20
     */
    var Info = {
        short_id: null,
        uid: null,
        ruid: null,
        roomid: null,
        rnd: null,
        area_id: null, // area_v2_id
        area_parent_id: null,
        old_area_id: null, // areaId
        csrf_token: function() {
            return getCookie('bili_jct');
        },
        today_feed: null,
        day_limit: null,
        silver: null,
        gold: null,
        mobile_verified: null,
        medal_list: null,
        medal_target_id: null,
        task_list: null,
        bag_list: null
    };
    var DEBUG = function(arg) {
        // console.debug(arg);
    };
    var API = {
        ajax: function(settings) {
            // DEBUG('API.ajax: settings:' + JSON.stringify(settings));
            if (settings.xhrFields) {
                $.extend(settings.xhrFields, {
                    withCredentials: true
                });
            } else {
                settings.xhrFields = {
                    withCredentials: true
                };
            }
            $.extend(settings, {
                url: (settings.url.substr(0, 2) == '//' ? '' : '//api.live.bilibili.com/') + settings.url,
                type: settings.type || 'GET',
                crossDomain: true,
                dataType: settings.dataType || 'json'
            });
            return $.ajax(settings);
        },
        ajaxGetCaptchaKey: function() {
            return API.ajax({
                url: '//www.bilibili.com/plus/widget/ajaxGetCaptchaKey.php?js'
            });
        },
        msg: function(roomid, csrf_token) {
            return API.ajax({
                type: 'POST',
                url: 'ajax/msg',
                data: {
                    roomid: roomid,
                    csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token
                }
            });
        },
        ajaxCapsule: function(id, ts, platform, player_type) {
            return API.ajax({
                url: 'api/ajaxCapsule'
            });
        },
        player: function(id, ts, platform, player_type) { //获取直播流相关信息
            return API.ajax({
                url: 'api/player',
                data: {
                    id: id,
                    ts: ts, // HEX
                    platform: platform || 'pc',
                    player_type: player_type || 'web'
                },
                dataType: 'text'
            });
        },
        create: function(width, height) { // 生成一个验证码
            return API.ajax({
                url: 'captcha/v1/Captcha/create',
                data: {
                    width: width,
                    height: height,
                    _: Date.now()
                }
            });
        },
        topList: function(roomid, page, ruid) {
            return API.ajax({
                url: 'guard/topList',
                data: {
                    roomid: roomid,
                    page: page,
                    ruid: ruid
                }
            });
        },
        getSuser: function() {
            return API.ajax({
                url: 'msg/getSuser'
            });
        },
        refresh: function() {
            return API.ajax({
                url: 'index/refresh?area=all'
            });
        },
        get_ip_addr: function() {
            return API.ajax({
                url: 'ip_service/v1/ip_service/get_ip_addr'
            });
        },
        ajaxGetMyMedalList: function() {
            return API.ajax({
                url: '//live.bilibili.com/i/ajaxGetMyMedalList'
            });
        },
        getuserinfo: function() {
            return API.ajax({
                url: '//live.bilibili.com/user/getuserinfo'
            });
        },
        MyInfo: function() {
            return API.ajax({
                url: '//space.bilibili.com/ajax/member/MyInfo'
            });
        },
        activity: {
            mobileActivity: function() {
                return API.ajax({
                    url: 'activity/v1/Common/mobileActivity'
                });
            },
            roomInfo: function(roomid, ruid) {
                return API.ajax({
                    url: 'activity/v1/Common/roomInfo',
                    data: {
                        roomid: roomid,
                        ruid: ruid
                    }
                });
            },
            welcomeInfo: function(roomid) {
                return API.ajax({
                    url: 'activity/v1/Common/welcomeInfo?roomid=' + roomid
                });
            },
            master_invite_task: function() {
                return API.ajax({
                    url: 'activity/v1/invite/master_invite_task'
                });
            },
            check: function(roomid) {
                return API.ajax({
                    url: 'activity/v1/Raffle/check?roomid=' + roomid
                });
            },
            join: function(roomid, raffleId) {
                return API.ajax({
                    url: 'activity/v1/Raffle/join',
                    data: {
                        roomid: roomid,
                        raffleId: raffleId
                    }
                });
            },
            notice: function(roomid, raffleId) {
                return API.ajax({
                    url: 'activity/v1/Raffle/notice',
                    data: {
                        roomid: roomid,
                        raffleId: raffleId
                    }
                });
            },
            master_limit_tasks: function() {
                return API.ajax({
                    url: 'activity/v1/task/master_limit_tasks'
                });
            },
            receive_award: function(task_id, csrf_token) {
                return API.ajax({
                    type: 'POST',
                    url: 'activity/v1/task/receive_award',
                    data: {
                        task_id: task_id,
                        csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token
                    }
                });
            },
            user_limit_tasks: function() {
                return API.ajax({
                    url: 'activity/v1/task/user_limit_tasks'
                });
            }
        },
        feed: {
            getList: function(page, page_size) {
                return API.ajax({
                    url: 'feed/v1/feed/getList',
                    data: {
                        page: page,
                        page_size: page_size,
                        _: Date.now()
                    }
                });
            },
            heartBeat: function(_cb) {
                return API.ajax({
                    url: 'feed/v1/feed/heartBeat',
                    data: {
                        _cb: _cb
                    }
                });
            },
            GetUserFc: function(follow) { // follow: 主播uid==ruid
                return API.ajax({
                    url: 'feed/v1/Feed/GetUserFc?follow=' + follow
                });
            },
            IsUserFollow: function(follow) { // follow: 主播uid==ruid
                return API.ajax({
                    url: 'feed/v1/Feed/IsUserFollow?follow=' + follow
                });
            },
        },
        feed_svr: {
            notice: function(csrf_token) {
                return API.ajax({
                    type: 'POST',
                    url: 'feed_svr/v1/feed_svr/notice',
                    data: {
                        csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token
                    }
                });
            },
            my: function(page_size, csrf_token, live_status, type, offset) {
                return API.ajax({
                    type: 'POST',
                    url: 'feed_svr/v1/feed_svr/my',
                    data: {
                        live_status: live_status || 0,
                        type: type || 0,
                        page_size: page_size,
                        offset: offset || 0,
                        csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token
                    }
                });
            }
        },
        FreeSilver: {
            getSurplus: function() {
                return API.ajax({
                    url: 'FreeSilver/getSurplus'
                });
            },
            getAward: function(time_start, end_time, captcha) {
                return API.ajax({
                    url: 'FreeSilver/getAward',
                    data: {
                        time_start: time_start,
                        end_time: end_time,
                        captcha: captcha
                    }
                });
            },
            getCurrentTask: function() {
                return API.ajax({
                    url: 'FreeSilver/getCurrentTask'
                });
            },
            getCaptcha: function(ts, callback) {
                getBlobDataURL("//api.live.bilibili.com/freeSilver/getCaptcha?ts=" + ts, callback);
            }
        },
        gift: {
            bag_list: function() {
                return API.ajax({
                    url: 'gift/v2/gift/bag_list'
                });
            },
            send: function(uid, gift_id, ruid, gift_num, coin_type, biz_id, rnd, csrf_token, platform, biz_code, storm_beat_id) {
                return API.ajax({
                    type: 'POST',
                    url: 'gift/v2/gift/send',
                    data: {
                        uid: uid,
                        gift_id: gift_id,
                        ruid: ruid,
                        gift_num: gift_num,
                        coin_type: coin_type,
                        bag_id: 0,
                        platform: platform || 'pc',
                        biz_code: biz_code || 'live',
                        biz_id: biz_id, //roomid
                        rnd: rnd,
                        storm_beat_id: storm_beat_id || 0,
                        // metadata: metadata,
                        csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token
                    }
                });
            },
            bag_send: function(uid, gift_id, ruid, gift_num, bag_id, biz_id, rnd, csrf_token, platform, biz_code, storm_beat_id) {
                return API.ajax({
                    type: 'POST',
                    url: 'gift/v2/live/bag_send',
                    data: {
                        uid: uid,
                        gift_id: gift_id,
                        ruid: ruid,
                        gift_num: gift_num,
                        bag_id: bag_id,
                        platform: platform || 'pc',
                        biz_code: biz_code || 'live',
                        biz_id: biz_id, //roomid
                        rnd: rnd,
                        storm_beat_id: storm_beat_id || 0,
                        // metadata: metadata,
                        csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token
                    }
                });
            },
            heart_gift_receive: function(roomid, area_v2_id) {
                return API.ajax({
                    url: 'gift/v2/live/heart_gift_receive',
                    data: {
                        roomid: roomid,
                        area_v2_id: area_v2_id
                    }
                });
            },
            heart_gift_status: function(roomid, area_v2_id) {
                return API.ajax({
                    url: 'gift/v2/live/heart_gift_status',
                    data: {
                        roomid: roomid,
                        area_v2_id: area_v2_id
                    }
                });
            },
            receive_daily_bag: function() {
                return API.ajax({
                    url: 'gift/v2/live/receive_daily_bag'
                });
            },
            room_gift_list: function(roomid, area_v2_id) {
                return API.ajax({
                    url: 'gift/v2/live/room_gift_list',
                    data: {
                        roomid: roomid,
                        area_v2_id: area_v2_id
                    }
                });
            },
            smalltv: {
                check: function(roomid) {
                    return API.ajax({
                        url: 'gift/v2/smalltv/check',
                        data: {
                            roomid: roomid
                        }
                    });
                },
                join: function(roomid, raffleId) {
                    return API.ajax({
                        url: 'gift/v2/smalltv/join',
                        data: {
                            roomid: roomid,
                            raffleId: raffleId
                        }
                    });
                },
                notice: function(roomid, raffleId) {
                    return API.ajax({
                        url: 'gift/v2/smalltv/notice',
                        data: {
                            roomid: roomid,
                            raffleId: raffleId
                        }
                    });
                }
            }
        },
        giftBag: {
            getSendGift: function() {
                return API.ajax({
                    url: 'giftBag/getSendGift'
                });
            },
            sendDaily: function() {
                return API.ajax({
                    url: 'giftBag/sendDaily'
                });
            }
        },
        i: {
            ajaxGetAchieve: function(page, pageSize, type, status, category, keywords) {
                return API.ajax({
                    url: 'i/api/ajaxGetAchieve',
                    data: {
                        type: type || 'normal', // or'legend'
                        status: status || 0,
                        category: category || 'all',
                        keywords: keywords,
                        page: page,
                        pageSize: pageSize || 6
                    }
                });
            },
            ajaxCancelWear: function() {
                return API.ajax({
                    url: 'i/ajaxCancelWear'
                });
            },
            ajaxWearFansMedal: function(medal_id) {
                return API.ajax({
                    url: 'i/ajaxWearFansMedal?medal_id=' + medal_id
                });
            },
            following: function(page, pageSize) {
                return API.ajax({
                    url: 'i/api/following',
                    data: {
                        page: page,
                        pageSize: pageSize
                    }
                });
            },
            guard: function(page, pageSize) {
                return API.ajax({
                    url: 'i/api/guard',
                    data: {
                        page: page,
                        pageSize: pageSize
                    }
                });
            },
            liveinfo: function() {
                return API.ajax({
                    url: 'i/api/liveinfo'
                });
            },
            medal: function(page, pageSize) {
                return API.ajax({
                    url: 'i/api/medal',
                    data: {
                        page: page,
                        pageSize: pageSize
                    }
                });
            },
            operation: function(page) {
                return API.ajax({
                    url: 'i/api/operation?page=' + page
                });
            },
            taskInfo: function() {
                return API.ajax({
                    url: 'i/api/taskInfo'
                });
            }
        },
        live: {
            getRoomKanBanModel: function(roomid) {
                return API.ajax({
                    url: 'live/getRoomKanBanModel?roomid' + roomid
                });
            },
            rankTab: function(roomid) {
                return API.ajax({
                    url: 'live/rankTab?roomid=' + roomid
                });
            },
            roomAdList: function() {
                return API.ajax({
                    url: 'live/roomAdList'
                });
            }
        },
        live_user: {
            get_anchor_in_room: function(roomid) {
                return API.ajax({
                    url: 'live_user/v1/UserInfo/get_anchor_in_room?roomid=' + roomid
                });
            },
            get_info_in_room: function(roomid) {
                return API.ajax({
                    url: 'live_user/v1/UserInfo/get_info_in_room?roomid=' + roomid
                });
            },
            get_weared_medal: function(uid, target_id, csrf_token, source) {
                return API.ajax({
                    type: 'POST',
                    url: 'live_user/v1/UserInfo/get_weared_medal',
                    data: {
                        source: source || 1,
                        uid: uid,
                        target_id: target_id, // roomid
                        csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token
                    }
                });
            }
        },
        lottery: {
            getRoomActivityByRoomid: function(roomid) {
                return API.ajax({
                    url: 'lottery/v1/box/getRoomActivityByRoomid?roomid=' + roomid
                });
            },
            check: function(roomid) {
                return API.ajax({
                    url: 'lottery/v1/Storm/check?roomid=' + roomid
                });
            },
            join: function(id, color, captcha_token, captcha_phrase, csrf_token) { // 加入节奏风暴
                return API.ajax({
                    type: 'POST',
                    url: 'lottery/v1/Storm/join',
                    data: {
                        id: id,
                        color: color,
                        captcha_token: captcha_token,
                        captcha_phrase: captcha_phrase,
                        csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token
                    }
                });
            }
        },
        rankdb: {
            roomInfo: function(ruid, roomid, areaId) {
                return API.ajax({
                    url: 'rankdb/v1/Common/roomInfo',
                    data: {
                        ruid: ruid,
                        roomid: roomid,
                        areaId: areaId
                    }
                });
            }
        },
        room: {
            get_info: function(room_id, from) {
                return API.ajax({
                    url: 'room/v1/Room/get_info',
                    data: {
                        room_id: room_id,
                        from: from || 'room'
                    }
                });
            },
            playUrl: function(cid, quality, platform) {
                return API.ajax({
                    url: 'room/v1/Room/playUrl',
                    data: {
                        cid: cid, // roomid
                        quality: quality || '0',
                        platform: platform || 'web'
                    }
                });
            },
            room_entry_action: function(room_id, csrf_token, platform) {
                return API.ajax({
                    type: 'POST',
                    url: 'room/v1/Room/room_entry_action',
                    data: {
                        room_id: room_id,
                        platform: platform || 'pc',
                        csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token
                    }
                });
            },
            room_init: function(id) {
                return API.ajax({
                    url: 'room/v1/Room/room_init?id=' + id
                });
            }
        },
        sign: {
            doSign: function() {
                return API.ajax({
                    url: 'sign/doSign'
                });
            },
            GetSignInfo: function() {
                return API.ajax({
                    url: 'sign/GetSignInfo'
                });
            },
            getLastMonthSignDays: function() {
                return API.ajax({
                    url: 'sign/getLastMonthSignDays'
                });
            }
        },
        user: {
            getWear: function(uid) {
                return API.ajax({
                    url: 'user/v1/user_title/getWear?uid=' + uid
                });
            },
            userOnlineHeart: function() {
                return API.ajax({
                    type: 'POST',
                    url: 'User/userOnlineHeart'
                });
            },
            getUserInfo: function(ts) { // ms
                return API.ajax({
                    url: 'User/getUserInfo?ts=' + ts
                });
            }
        },
        YearWelfare: {
            checkFirstCharge: function() {
                return API.ajax({
                    url: 'YearWelfare/checkFirstCharge'
                });
            },
            inviteUserList: function() {
                return API.ajax({
                    url: 'YearWelfare/inviteUserList/1'
                });
            }
        }
    };

    function ts_s() {
        return Math.floor(Date.now() / 1000);
    }

    function ts_ms() {
        return Date.now();
    }

    function getCookie(name) {
        var arr, reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)');
        if ((arr = document.cookie.match(reg))) {
            return unescape(arr[2]);
        } else {
            return null;
        }
    }

    function setCookie(name, value, seconds) {
        seconds = seconds || 0;
        var expires = '';
        if (parseInt(seconds) !== 0) {
            var date = new Date();
            date.setTime(date.getTime() + (seconds * 1000));
            expires = '; expires=' + date.toGMTString();
        }
        document.cookie = name + '=' + escape(value) + expires + '; path=/';
    }

    function getBlobDataURL(url, callback) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.responseType = 'blob';
        xhr.withCredentials = true;
        xhr.onload = function() {
            var reader = new FileReader();
            reader.onload = function() {
                callback(reader.result);
            };
            reader.readAsDataURL(xhr.response);
        };
        xhr.send();
    }

    /*
    验证码识别算法来自互联网,作者未知
    该算法已被简单修改
    */
    function getChar(t) {
        if (t.sum <= 50) return '-';
        if (t.sum > 120 && t.sum < 135) return '+';
        if (t.sum > 155 && t.sum < 162) return 1;
        if (t.sum > 189 && t.sum < 195) return 7;
        if (t.sum > 228 && t.sum < 237) return 4;
        if (t.sum > 250 && t.sum < 260) return 2;
        if (t.sum > 286 && t.sum < 296) return 3;
        if (t.sum > 303 && t.sum < 313) return 5;
        if (t.sum > 335 && t.sum < 342) return 8;
        if (t.sum > 343 && t.sum < 350) {
            if (t.first > 24 && t.last > 24) return 0;
            if (t.first < 24 && t.last > 24) return 9;
            if (t.first > 24 && t.last < 24) return 6;
        }
    }

    function calcImg() {
        /*
         * 1.验证码图片->二维点阵
         * 2.二维点阵->横向一维压缩
         * 3.分析并计算
         */
        var ctx = $('#' + NAME + '_canvas')[0].getContext("2d");
        var img = $('#' + NAME + '_img')[0];
        ctx.drawImage(img, 0, 0, 120, 40);
        var pixels = ctx.getImageData(0, 0, 120, 40).data;
        var pix = [];
        var i = 0;
        var j = 0;
        var n = 0;
        for (i = 1; i <= 40; i++) {
            pix[i] = [];
            for (j = 1; j <= 120; j++) {
                var c = 1;
                if (pixels[n] - (-pixels[n + 1]) - (-pixels[n + 2]) > 200) { //判断RGB之和是否大于200(接近白色)
                    c = 0;
                }
                n += 4;
                pix[i][j] = c;
            }
        }
        //二维点阵pix[40][120]
        var line = [];
        line[0] = 0;
        for (i = 1; i <= 120; i++) {
            line[i] = 0;
            for (j = 1; j <= 40; j++) {
                line[i] += pix[j][i];
            }
        }
        //一维line[120]
        var temp = [];
        n = 0;
        for (i = 1; i <= 120; i++) {
            if (line[i] > 0 && line[i - 1] === 0) {
                n++;
                temp[n] = {};
                temp[n].first = line[i];
                temp[n].sum = 0;
            }
            if (line[i] > 0) {
                temp[n].sum += line[i];
            }
            if (line[i - 1] > 0 && line[i] === 0) {
                temp[n].last = line[i - 1];
            }
        }
        if (n == 4) {
            var result = 0;
            var a = getChar(temp[1]) * 10 - (-getChar(temp[2]));
            var b = getChar(temp[4]);
            if (getChar(temp[3]) == '+') {
                result = a - (-b);
            } else {
                result = a - b;
            }
            DEBUG('TaskAward: calcImg: 识别验证码: ' + getChar(temp[1]) + getChar(temp[2]) + ' ' + getChar(temp[3]) + ' ' + getChar(temp[4]) + ' = ' + result);
            return result;
        } else {
            return null;
        }
    }

    var liveQuickLogin = function() {
        if (!getCookie('DedeUserID') && !getCookie('LIVE_LOGIN_DATA')) {
            try {
                if (!window.biliQuickLogin) {
                    $.getScript('https://static-s.bilibili.com/account/bili_quick_login.js', function(response, status) {
                        if (status === 'success') login();
                    });
                } else {
                    login();
                }
            } catch (tryErr) {
                throw new Error(tryErr);
            }
        }

        function login() {
            if (window.biliQuickLogin) {
                window.biliQuickLogin(function() {
                    window.location.reload();
                });
                throw 'Bilibili Live: 您还未登陆.';
            } else {
                throw 'Bilibili Live: 快速登录脚本加载失败.';
            }
        }
    };

    function giftIDtoFeed(gift_id) {
        for (var i = gift_list.length - 1; i >= 0; i--) {
            if (gift_list[i].id === gift_id) {
                return Math.floor(gift_list[i].price / 100);
            }
        }
        return 0;
    }

    function toast(t, e, n, r) {
        if ('boolean' == typeof n) n = 'info';
        var o = document.createDocumentFragment(),
            a = document.createElement('div');
        if ('success' !== (n = n || 'info') && 'caution' !== n && 'error' !== n && 'info' !== n)
            throw new Error(i + ' 在使用 Link Toast 时必须指定正确的类型: success || caution || error || info');
        if (a.innerHTML = '<span class="toast-text">' + e + '</span>',
            a.className = 'link-toast ' + n + ' ' + (r ? 'fixed' : ''), !t.className && !t.attributes)
            throw new Error(i + ' 传入 element 不是有效节点.');
        var c = t.getBoundingClientRect(),
            s = c.left,
            u = c.top,
            l = c.width,
            f = c.height,
            p = document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft;
        a.style.left = s + l + p + 'px';
        var d = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop;
        a.style.top = u + f + d + ToastCount * 40 + 'px';
        setTimeout((function() {
            a.className += ' out';
            setTimeout((function() { // TODO
                ToastCount = 0;
                a.parentNode.removeChild(a);
            }), 350);
        }), 3e3);
        o.appendChild(a);
        document.body.appendChild(o);
        var h = document.body.offsetWidth,
            v = a.getBoundingClientRect().left,
            m = a.offsetWidth;
        if (h - m - v < 0) a.style.left = h - m - 10 + p + 'px';
        ToastCount += 1;
    }

    /*
    window.BilibiliLive.ANCHOR_UID
    window.BilibiliLive.COLORFUL_LOGGER
    window.BilibiliLive.INIT_TIME
    window.BilibiliLive.RND === window.DANMU_RND
    window.BilibiliLive.ROOMID
    window.BilibiliLive.SHORT_ROOMID
    window.BilibiliLive.UID
    window.captcha_key
    window.Yb
    */

    function Init() {
        // liveQuickLogin();
        var _interval = setInterval(function() {
            if (window.BilibiliLive) {
                DEBUG('Init: BilibiliLive: ' + JSON.stringify(window.BilibiliLive));
                if (parseInt(window.BilibiliLive.UID) !== 0) {
                    Info.short_id = window.BilibiliLive.SHORT_ROOMID;
                    Info.uid = window.BilibiliLive.UID;
                    Info.roomid = window.BilibiliLive.ROOMID;
                    Info.ruid = window.BilibiliLive.ANCHOR_UID;
                    Info.rnd = window.BilibiliLive.RND;
                    // API.MyInfo().done(function(response) {
                    //     if (response.status === true) {
                    //         Info.mobile_verified = response.data.mobile_verified;
                    //     }
                    // });
                    room_id_list[Info.short_id] = Info.roomid;
                    if (CONFIG.USE_AWARD) {
                        var _interval_treasure_box = setInterval(function() {
                            var _treasure_box = $('div.treasure-box.p-relative[id!=' + NAME + '_div_box]');
                            if (_treasure_box[0]) {
                                _treasure_box.attr('style', "display:none");
                                var div = $('<div id="' + NAME + '_div_box" class="treasure-box p-relative"></div>');
                                var b_box = $('<div id="' + NAME + '_div_b_box"class="t-center b-box none-select">自动<br>领取中</div>');
                                b_box.css({
                                    'max-width': '40px',
                                    'padding': '2px 3px',
                                    'margin-top': '3px',
                                    'font-size': '12px',
                                    'color': '#fff',
                                    'background-color': 'rgba(0,0,0,.5)',
                                    'border-radius': '10px'
                                });
                                var img = $('<img id="' + NAME + '_img" style="display:none">');
                                var canvas = $('<canvas id="' + NAME + '_canvas" style="display:none" height="40" width="120"></canvas>');
                                div.append(b_box);
                                div.append(img);
                                div.append(canvas);
                                $('div.vertical-middle.dp-table.section.left-part div.dp-table-cell.v-middle').append(div);
                                clearInterval(_interval_treasure_box);
                            }
                        }, 200);
                    }
                    if (CONFIG.USE_GIFT && (CONFIG.GIFT_CONFIG.SHORT_ROOMID === 0 || CONFIG.GIFT_CONFIG.SHORT_ROOMID == Info.short_id)) {
                        API.live_user.get_weared_medal(Info.uid, Info.roomid, Info.csrf_token).done(function(response) {
                            DEBUG('Init: get_weared_medal: ' + JSON.stringify(response));