B站油管showroom简易打尻装置

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

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

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

代码里两个\相当于一个\
*/
window.onload = (windows) => {
    let waitTime = 1;//等待1秒,如果加载比较慢的话,不等待可能获取不到元素。
    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) 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");
		if (!biliTextArea) {
			window.alert('打尻:找不到输入框');
			return;
		}
		const biliTextSender = window.document.querySelector(sendSelector)||window.document.querySelector("#send-button").querySelector("#button");
		if (!biliTextSender) {
			window.alert('打尻:找不到发送按钮');
			return;
		}
		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) {
		if(window.confirm('打尻:发生未知错误\n可能是在加载中无法获取元素\n' + e+"\n是否重新尝试打尻?")){
            setTimeout(main,1000*(waitTime+3));
        };
	  }
   }
    setTimeout(main, 1000 * waitTime);
};