Greasy Fork

Greasy Fork is available in English.

B站油管showroom简易打尻装置

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

当前为 2022-01-05 提交的版本,查看 最新版本

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

You will need to install an extension such as Tampermonkey to install this script.

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         B站油管showroom简易打尻装置
// @namespace    http://tampermonkey.net/
// @version      0.4.5
// @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 = 10;//尝试查询的次数


    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);
                }else{
                   clearInterval(maint);
                }
            };
        }
    }
    maint= setInterval(main, 1000 * waitTime);
})();