B站油管showroom简易打尻装置

啊B、油管或showroom打尻,需要用户已登录。若有滥用等问题概不负责,诶嘿。顺便关注一下小东人鱼和noworld吧~

目前为 2022-01-04 提交的版本。查看 最新版本

// ==UserScript==
// @name         B站油管showroom简易打尻装置
// @namespace    http://tampermonkey.net/
// @version      0.4.4
// @description  啊B、油管或showroom打尻,需要用户已登录。若有滥用等问题概不负责,诶嘿。顺便关注一下小东人鱼和noworld吧~
// @author       太陽闇の力
// @include      /https?:\/\/live\.bilibili\.com\/(blanc\/)?\d+\??.*/
// @match        https://www.youtube.com/live_chat*
// @exclude      https://www.youtube.com/live_chat_replay*
// @match        https://www.showroom-live.com/*
// @grant        none
// @license MIT
// ==/UserScript==

//界面参考自小东人鱼午安社五更耗纸 https://github.com/gokoururi-git/gachihelper/

//搜索找到代码中let countdown = "220"; let intervaltime = "6";这两句可以改开局的倒计时时间和发送间隔时间(油管和showroom的发送间隔在let intervaltime = "6";下面的代码中进行修改)。
//interval.min、interval.max、interval.step分别是滑动条的最小值、最大值和滑动间隔,根据平台区别设定了这三个值和interval的关系,尽量避免发送太猛吓到主播。
//B站直播五秒内同一句打call的话,会显示发送频率太快而无法发送成功。建议写多几句不一样的。
/*如果要添加默认打call语句,可以搜索【textArea.value=``;】,到这句的``里面添加内容,比如:
textArea=`\\小东/
         \\noir/
         ♪小东♪
         ♪noir♪`;

代码里两个\相当于一个\
*/

//如果想发一次

(function() {
    let waitTime = 1;//等待1秒,如果加载比较慢的话,不等待可能获取不到元素。
    let times = 5;//尝试查询的次数


    let timescopy = times;
    let maint;
    const main = () => {
        try {
            //-----------配置区-------------
            //0默认收起,1默认展开
            let isunfold = 0;
            let unfold = ["展开","收起"];
            //输入框选择符
            let inputSelector = 'textarea';
            //发送按钮选择符
            let sendSelector =
                '.bl-button';
            const isshowroom=window.location.href.indexOf("showroom")>-1;
            if(isshowroom){
                //判断是不是showroom的直播间
                const ogURL = document.querySelector("meta[property='og:url']").content;
                const showroomURL = 'https://www.showroom-live.com';
                if(ogURL==showroomURL) {
                    clearInterval(maint);
                    return;
                }

                //免费礼物点一下就能十连发
                const comboInterval=25;
                const list = window.document.querySelector("#room-gift-item-list");
                list.addEventListener('mouseup',(e)=>{
                    const num = e.target.parentNode.parentNode.querySelector("div").innerText.split(" ")[1]-1;
                    const comboNum = num > 9 ? 9 : num;
                    for(let i = 1;i<=comboNum;i++){
                        setTimeout(()=>{e.target.click();},i*comboInterval)
                    }
                })
                //评论栏和发送按钮
                inputSelector ='.comment-input-text';
                sendSelector = '.js-room-comment-btn';
            }
            const biliTextArea = window.document.querySelector(inputSelector)||window.document.querySelector("#input").querySelector("#input");
            const biliTextSender = window.document.querySelector(sendSelector)||window.document.querySelector("#send-button").querySelector("#button");
            clearInterval(maint);

            const callDealler = (call) => {
                let tempcallResult = [];
                call = call.trim();
                call = call.replace(/ /g, '');
                call = call.replace(/ /g, '');
                call = call.replace(/\n{2,}/g, '\n');
                tempcallResult = call.split('\n');
                return tempcallResult;
            }
            let countdown = "220";
            let intervaltime = "6";
            if(window.location.href.indexOf("live_chat")>-1){//如果在油管的话设置初始20,showroom为50,油管和showroom的初始发送间隔可以在这里改
                intervaltime="20";
            }else if(isshowroom){
                intervaltime="50";
            }
            let callResult = [];
            let currIndex = 0;
            let t = null;
            let ct = null;
            const inputEvent = document.createEvent("Event");
            inputEvent.initEvent("input",true, true);
            const next = function() {
                if (currIndex == callResult.length) currIndex = 0;
                if(window.location.href.indexOf("live_chat")>-1){
                    biliTextArea.innerText = callResult[currIndex++];
                }else{
                    biliTextArea.value = callResult[currIndex++];
                }
                biliTextArea.dispatchEvent(inputEvent);
                biliTextSender.click();
            }
            const init = function() {
                currIndex = 0;
                if(window.location.href.indexOf("live_chat")>-1){
                    biliTextArea.innerText = callResult[currIndex++];
                }else{
                    biliTextArea.value = callResult[currIndex++];
                }
                biliTextArea.dispatchEvent(inputEvent);
                biliTextSender.click();
                const intervalChoose = intervalValBox&&parseFloat(intervalValBox.value) > 0 ? intervalValBox.value : interval.value;
                timeLabel.innerText = intervalChoose;
                t = setInterval(next, intervalChoose * 1000);
            }
            // ------------------GUI设计开始---------------
            // 总容器
            const container = window.document.createElement('div');
            container.style.cssText = 'width:260px;position:fixed;bottom:5px;left:5px;z-index:999;box-sizing:border-box;';

            // 工具名称
            const topTool = window.document.createElement('div');
            topTool.innerText = 'call';
            topTool.style.cssText = 'text-align:center;line-height:20px;height:20px;width:100%;color:rgb(210,143,166);font-size:14px;';

            // 最小化按钮
            const collapseButton = window.document.createElement('button');
            collapseButton.innerText = unfold[isunfold];
            collapseButton.style.cssText = 'float:right;width:40px;height:20px;border:none;cursor:pointer;background-color:#1890ff;border-radius:1px;color:#ffffff;';

            // 主窗口
            const mainWindow = window.document.createElement('div');
            mainWindow.style.cssText = 'width:100%;background-color:rgba(220, 192, 221, .5);padding:10px;box-sizing:border-box;';
            if(isunfold==0){
                mainWindow.style.display = "none";
            }
            // call框
            const textArea = window.document.createElement('textarea');
            textArea.value=``;//如果有\的话,需要写成\\
            textArea.style.cssText = 'width:100%;height:50px;resize:none;outline:none;background-color:rgba(255,255,255,.5);';

            // 按钮区容器
            const buttonArea = window.document.createElement('div');
            buttonArea.style.cssText = 'width:100%;height:30px;box-sizing:border-box;display:flex; justify-content: center;';

            // 按钮区容器2
            const buttonArea2 = window.document.createElement('div');
            buttonArea2.style.cssText = 'width:100%;height:30px;box-sizing:border-box;display:flex;justify-content: space-around;';

            // 开始按钮
            const goButton = window.document.createElement('button');
            goButton.innerText = '开始';
            goButton.style.cssText = 'width:max-content;height:28px;padding:0 5px;margin-left:5px;';

            // 发送间隔提示文本
            const intervalLabel = window.document.createElement('div');
            intervalLabel.innerText = '发送间隔:'
            intervalLabel.style.cssText = 'width:70px;height:28px;line-height:28px;';

            // 选择延迟
            const interval = window.document.createElement('input');
            interval.type = "range";
            interval.step = "0.1";
            interval.min = (intervaltime-2)/2;
            interval.value = intervaltime;
            interval.max = (+intervaltime+14)*1.5;
            interval.style.cssText = 'width:max-content;padding:0 5px;height:28px;margin-left:5px;';

            const timeLabel = window.document.createElement('div');
            timeLabel.innerText = intervaltime;
            timeLabel.style.cssText = 'width:24px;height:28px;line-height:28px;';

            const secondLabel = window.document.createElement('div');
            secondLabel.innerText = '秒';
            secondLabel.style.cssText = 'width:max-content;height:28px;line-height:28px;';

            // 倒计时
            const countDownButton = window.document.createElement('button');
            countDownButton.setAttribute("contenteditable", "true");
            countDownButton.innerText = countdown;
            countDownButton.style.cssText = 'width:50px;height:28px;margin-left:5px;padding:0 5px;';

            // 组装
            topTool.appendChild(collapseButton);
            container.appendChild(topTool);

            mainWindow.appendChild(textArea);

            buttonArea.appendChild(intervalLabel);
            buttonArea.appendChild(interval);
            buttonArea.appendChild(timeLabel);
            buttonArea.appendChild(secondLabel);
            buttonArea2.appendChild(goButton);
            buttonArea2.appendChild(countDownButton);
            mainWindow.appendChild(buttonArea);
            mainWindow.appendChild(buttonArea2);
            container.appendChild(mainWindow);
            window.document.body.appendChild(container);
            // 显示逻辑控制
            collapseButton.addEventListener('click', () => {
                if (collapseButton.innerText === '收起') {
                    mainWindow.style.display = 'none';
                    collapseButton.innerText = '展开';
                    return;
                }
                if (collapseButton.innerText === '展开') {
                    mainWindow.style.display = 'block';
                    collapseButton.innerText = '收起';
                    return;
                }
            }, false);
            //显示滑动条数字
            interval.oninput = function() {
                timeLabel.innerText = interval.value;
            }

            if(isshowroom){
                container.style.width = "282px";
                timeLabel.style.width = "32px";
            }
            //-------------------gui设计结束------------------
            let intervalValBox ;
            function createInput(){
                intervalLabel.innerText = "";
                intervalValBox = document.createElement('input');
                intervalValBox.style.width = "100%";
                intervalValBox.placeholder = "输入数值";
                intervalLabel.appendChild(intervalValBox);
                intervalLabel.onclick = null;
            }
            intervalLabel.onclick =createInput;
            function pause(){
                clearInterval(t);
                clearInterval(ct);
                goButton.innerText = '开始';
                countDownButton.innerText = countDownButton.innerText==0?countdown:220;
                countDownButton.setAttribute("contenteditable", "true");
                if(isshowroom&&textArea.value.trim() === ''){
                    //showroom中如果输入为空,则进行50 count。
                    interval.min = (intervaltime-2)/2;
                    interval.value = intervaltime;
                    timeLabel.innerText = intervaltime;
                }
            }
            const countdownfunc = function() {
                if (countDownButton.innerText > 0) {
                    countDownButton.innerText -= 1;
                } else {
                    pause();
                }

            }
            goButton.addEventListener('click', () => {
                if (goButton.innerText == '暂停') {
                    pause()
                    return;
                }
                if(intervalValBox){
                    intervalValBox.remove();
                    intervalLabel.innerText = "发送间隔:";
                    intervalLabel.onclick = createInput;
                }
                const value = textArea.value;
                callResult = callDealler(value);
                if (value.trim() === '') {
                    if(!isshowroom){
                        window.alert('打尻:您还没有输入call语句');
                        return;
                    }else{
                        //设定50 count
                        countDownButton.innerText = 146;
                        interval.min = 3;
                        interval.value = 3;
                        timeLabel.innerText = 3;
                        callResult = Array.from({length:50}, (v,k) => k+1);
                    }
                }
                init();
                goButton.innerText = '暂停';
                countDownButton.setAttribute("contenteditable", "false");
                if (!isNaN(parseFloat(countDownButton.innerText))&&!(isshowroom&&textArea.value.trim() === '')) {
                    countdown = countDownButton.innerText;
                }
                ct = setInterval(countdownfunc, 1000);
            }, false);
        } catch (e) {
            times-=1;
            if(times==0){
                times = timescopy;
                if(window.confirm('打尻:发生未知错误\n可能是在加载中无法获取元素\n' + e+"\n是否重新尝试打尻?")){
                    maint= setInterval(main, 1000 * waitTime);
                }
            };
        }
    }
    maint= setInterval(main, 1000 * waitTime);
})();