Greasy Fork

Greasy Fork is available in English.

斗鱼自动发送弹幕

循环弹幕

当前为 2020-04-25 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name			斗鱼自动发送弹幕
// @namespace		http://tampermonkey.net/
// @version			0.0.1
// @icon			http://www.douyutv.com/favicon.ico
// @description		循环弹幕
// @author			H2P
// @compatible		chrome
// @match			*://*.douyu.com/0*
// @match			*://*.douyu.com/1*
// @match			*://*.douyu.com/2*
// @match			*://*.douyu.com/3*
// @match			*://*.douyu.com/4*
// @match			*://*.douyu.com/5*
// @match			*://*.douyu.com/6*
// @match			*://*.douyu.com/7*
// @match			*://*.douyu.com/8*
// @match			*://*.douyu.com/9*
// @note			2020.04.26-V0.0.01 发送循环弹幕,设定自动保存
// ==/UserScript==

(() => {
    const LSChat = 'h2p-DY-config-chat';
    let config_chat = undefined;
    let [Chat, INVL_SendMsg, INVL_ShowCD] = [undefined, undefined, undefined];

    const $H2P = function (xpath, one = true) {
        if (one) { return document.querySelector(xpath); }
        else { return document.querySelectorAll(xpath); }
    }

    window.onload = function () {
        new Promise((resolve, reject) => {
            // 先添加样式
            let eleStyle = document.createElement('style');
            eleStyle.innerHTML = `
                .h2p-div-borad {
                    position: fixed;
                    z-index: 9999;
                    top: 35%;
                    right: -322px;
                    width: 300px;
                    min-height: 100px;
                    height: auto;
                    padding: 10px;
                    border: 1px solid rgb(255, 145, 26);
                    border-right: 0;
                    border-radius: 10px 0 0 10px;
                    font-size: 13px;
                    line-height: 15px;
                    background: #f8f8f8;
                    transition: all 1s ease;
                }
                .h2p-div-borad:hover {
                    right: 0px;
                }
                .h2p-left-out {
                    position: absolute;
                    top: 40%;
                    left: -16px;
                    width: 15px;
                    height: 80px;
                    border: 1px solid #ff9019;
                    border-right: 0;
                    border-radius: 15px 0 0 15px;
                    background-color: #f8f8f8;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    cursor: pointer;
                    opacity: 1;
                    transition: opacity 1s ease-in;
                }
                .h2p-div-borad:hover .h2p-left-out{
                    opacity: 0;
                    transition: opacity 0s;
                }
            `;
            document.head.append(eleStyle);
            resolve();
        })
        .then(() => {
            // 添加发送弹幕界面元素
            let eleBoard = document.createElement('div');
            eleBoard.id = 'h2p-div-borad';
            eleBoard.className = 'h2p-div-borad';
            eleBoard.innerHTML = `
                <div class="h2p-left-out">
                    <span><</span>
                </div>
            `;
            document.body.append(eleBoard);
        })
        .then(() => {
            // 开始在界面上添加元素
            initView_Chat();
        })
        .catch((error) => { console.log(error); })
    }

    function initView_Chat () {
        new Promise((resolve, reject) => {
            // 先添加样式
            let eleStyle = document.createElement('style');
            eleStyle.innerHTML = `
                .h2p-flex-main-center {
                    display: flex;
                    flex-flow: row wrap;
                    justify-content: center;
                }
                .h2p-flex-main-start {
                    display: flex;
                    justify-content: flex-end;
                }
                .h2p-flex-main-end {
                    display: flex;
                    justify-content: flex-end;
                }
                .h2p-flex-cross-center {
                    display: flex;
                    align-items: center;
                }

                .h2p-div-item-100p {
                    width: 100%;
                    margin: 5px 0;
                }
                .h2p-div-item-50p {
                    width: 50%;
                    margin: 5px 0;
                }

                .h2p-input-invl {
                    width: 23px;
                    min-height: 17px;
                    padding: 0 3px;
                    border: 1px solid #d0d0d0;
                    border-radius: 3px;
                }

                .h2p-ta-chat-loop {
                    width: 100%;
                    height: 60px;
                    padding: 0 4px;
                    border: 1px solid #d0d0d0;
                    border-radius: 5px;
                    resize: none;
                }

                .h2p-btn-send-chat {
                    width: 100%;
                    padding: 4px 0;
                    border-radius: 5px;
                    background: #66ddcc;
                    cursor: pointer;
                    outline: none;
                    transition: all 0.5s
                }
                .h2p-btn-send-chat span {
                    display: inline-block;
                    position: relative;
                    transition: all 0.5s
                }
                .h2p-btn-send-chat span:after {
                    content: '🔥';
                    position: absolute;
                    opacity: 0;
                    top: -2px;
                    right: -20px;
                    transition: 0.5s;
                }
                .h2p-btn-send-chat:hover span {
                    padding-right: 20px;
                }  
                .h2p-btn-send-chat:hover span:after {
                    opacity: 1;
                    right: 0;
                }
                .h2p-btn-sending-chat {
                    background: #ffbb77;
                }
            `;
            document.head.append(eleStyle);
            let board = $H2P('div#h2p-div-borad');
            resolve(board);
        })
        .then((board) => {
            // 添加发送弹幕界面元素
            let eleChat = document.createElement('div');
            eleChat.id = 'h2p-div-chat';
            eleChat.className = 'h2p-flex-main-center';
            eleChat.innerHTML = `
                <div class="h2p-div-item-50p" style="order: 0;">
                    <span>间隔:</span>
                    <input id="input-invl-start" class="h2p-input-invl" placeholder="≥3">
                    <span>~</span>
                    <input id="input-invl-end" class="h2p-input-invl">
                    <span>秒</span>
                </div>
                <div class="h2p-div-item-50p h2p-flex-main-end" style="order: 1;">
                    <input id="input-invl" class="h2p-input-invl" style="width: 33px" disabled>
                </div>
                <div class="h2p-div-item-100p" style="order: 2;">
                    <div class="h2p-flex-cross-center">
                        <input id="input-chat-loop" type="checkbox" style="margin: 3px;">
                        <textarea class="h2p-ta-chat-loop" placeholder="循环弹幕"></textarea>
                    </div>
                </div>
                <div class="h2p-div-item-100p" style="order: 20;">
                    <button id="btn-chat-send" class="h2p-btn-send-chat">
                        <span>发送</span>
                    </button>
                </div>
            `;
            eleChat.addEventListener('click', (event) => {

            }, false);
            board.append(eleChat);
        })
        .then(() => {
            // 给元素添加监听
            let eleChat = $H2P('div#h2p-div-chat');
            eleChat.addEventListener('click', (event) => {
                let target = event.target;
                if (target.id === 'input-chat-loop') {
                    config_chat.isLoop = target.checked;
                }
                localStorage.setItem(LSChat, JSON.stringify(config_chat));
            }, false)

            let eleInvlStart = $H2P('input#input-invl-start');
            eleInvlStart.addEventListener('input', () => { eleInvlStart.value = eleInvlStart.value.slice(0, 3); });
            eleInvlStart.addEventListener('keyup', () => { eleInvlStart.value = eleInvlStart.value.replace(/[^\d]/g, ''); });
            eleInvlStart.addEventListener('focusout', () => {
                eleInvlStart.value = Math.max(eleInvlStart.value, 3);
                config_chat.invlStart = eleInvlStart.value;
                localStorage.setItem(LSChat, JSON.stringify(config_chat));
            });

            let eleInvlEnd = $H2P('input#input-invl-end');
            eleInvlEnd.addEventListener('input', () => { eleInvlEnd.value = eleInvlEnd.value.slice(0, 3); });
            eleInvlEnd.addEventListener('keyup', () => { eleInvlEnd.value = eleInvlEnd.value.replace(/[^\d]/g, ''); });
            eleInvlEnd.addEventListener('focusout', () => {
                eleInvlEnd.value = Math.max(eleInvlEnd.value, Number(eleInvlStart.value) + 1, 4);
                config_chat.invlEnd = eleInvlEnd.value;
                localStorage.setItem(LSChat, JSON.stringify(config_chat));
            });
            
            let eleLoop = $H2P('textarea.h2p-ta-chat-loop');
            eleLoop.addEventListener('focusout', () => {
                if (eleLoop.value && eleLoop.value.replace(/\s/g, '')) {
                    config_chat.loopChat = eleLoop.value.split('\n');
                    localStorage.setItem(LSChat, JSON.stringify(config_chat));
                }
            });

            let eleSend = $H2P('button#btn-chat-send');
            eleSend.addEventListener('click', () => {
                config_chat.isSend = !config_chat.isSend;
                if (config_chat.isSend) {
                    setINVL_SendMsg();
                    eleSend.classList.add('h2p-btn-sending-chat');
                    eleSend.firstElementChild.textContent = "发送中";
                }
                else {
                    window.clearTimeout(INVL_SendMsg);
                    INVL_SendMsg = undefined;
                    window.clearInterval(INVL_ShowCD);
                    $H2P('input#input-invl').value = '';
                    INVL_ShowCD = undefined;
                    eleSend.classList.remove('h2p-btn-sending-chat');
                    eleSend.firstElementChild.textContent = "发送";
                }
                localStorage.setItem(LSChat, JSON.stringify(config_chat));
            }, false)
        })
        .catch((error) => { console.log(error); })
        .then(() => {
            if (!config_chat) { config_chat = JSON.parse(localStorage.getItem(LSChat)) || {}; }
            $H2P('input#input-invl-start').value = config_chat.invlStart || '';
            $H2P('input#input-invl-end').value = config_chat.invlEnd || '';
            $H2P('input#input-chat-loop').checked = config_chat.isLoop || false;
            $H2P('textarea.h2p-ta-chat-loop').value = config_chat.loopChat ? config_chat.loopChat.join('\n') : '';
            if (config_chat.isSend) {
                config_chat.isSend = false;
                $H2P('button#btn-chat-send').click();
            }
            if (!Chat) { Chat = setChat(); }
        })
        .catch((error) => {
            // 判断 localStorage 是否能够读取 h2p-DY-config-chat
            console.log(error);
            config_chat = config_chat || {};
            localStorage.removeItem(LSChat);
            localStorage.setItem(LSChat, JSON.stringify(config_chat));
        })
    }

    function getMsg () {
        let msg = undefined;
        if (!msg && config_chat.isLoop && Array.isArray(config_chat.loopChat)) {
            let index = Math.floor(Math.random() * (config_chat.loopChat.length));
            msg = config_chat.loopChat[index];
        }
        return msg;
    }

    function setINVL_SendMsg () {
        let {invlStart = 2, invlEnd = 2} = config_chat;
        let [start, end] = [Number(invlStart), Number(invlEnd)];
        let invl = Math.floor(Math.random() * (end - start)) + start;
        setINVL_ShowCD(invl);
        INVL_SendMsg = setTimeout(() => {
            Chat.setMsg(getMsg());
            Chat.sendMsg();
            setINVL_SendMsg();
        }, invl * 1000);
    }

    function setINVL_ShowCD (invl) {
        new Promise((resolve, reject) => {
            window.clearInterval(INVL_ShowCD);
            resolve(invl);
        }).then((invl)=> {
            let cd = invl + 0.3;
            INVL_ShowCD = setInterval(() => {
                cd = Math.max(Math.floor((cd - 0.1) * 10) / 10.0, 0);
                $H2P('input#input-invl').value = cd;
            }, 100);
        })
    }

    function setChat () {
        let [eleSetMsg, eleSendMsg] = [undefined, undefined];
        return {
            setMsg : (msg)=>{
                if (!eleSetMsg && $H2P('.ChatSend-txt')) { eleSetMsg = $H2P('.ChatSend-txt'); }
                if (eleSetMsg) {
                    eleSetMsg.value = msg;
                }
            },
            sendMsg : ()=>{
                if (!eleSendMsg && $H2P('.ChatSend-button')) { eleSendMsg = $H2P('.ChatSend-button'); }
                if (eleSendMsg) {
                    eleSendMsg.click();
                }
            }
        }
    }
})();