Greasy Fork 支持简体中文。

BiliBili直播间独轮车

这是bilibili直播独轮车

// ==UserScript==
// @name         BiliBili直播间独轮车
// @version      1.0.5
// @author       quiet
// @match        *://live.bilibili.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js
// @description  这是bilibili直播独轮车
// @namespace https://greasyfork.org/users/1059296
// ==/UserScript==

var $ = window.jQuery;
var Msg = [];
const scriptInitVal = {Msg:'',MsgSendInterval:1}
for(let initVal in scriptInitVal) {
    if(GM_getValue(initVal)===undefined) GM_setValue(initVal,scriptInitVal[initVal]);
}

var sendMsg = false;

(function() {
    var check = setInterval(() => {
        var input = document.getElementsByClassName('chat-input border-box')[0];
        if (input !== undefined) {
            var div = document.getElementsByClassName('bottom-actions p-relative')[0];
            var btn = document.createElement('button');
            btn.innerHTML = '独轮车面版';
            btn.style.background = '#23ade5';
            btn.style.color = 'white';
            btn.style.cursor = 'pointer';;
            btn.style.padding = '6px 12px';
            btn.style.border = '0';
            btn.style.borderRadius = '4px';
            div.appendChild(btn);
            var list = document.createElement('fieldset');
            list.style.position = 'fixed';
            list.style.zIndex = '2147483647';
            list.style.background = 'white'
            list.style.display = 'none';
            list.style.minWidth = '50px';
            list.style.bottom = '200px';
            list.style.right = '200px';
            list.style.height = '300px';
            list.style.width = '250px';
            list.innerHTML = `<div style="margin:10px; height:80px; width: 200px;">
<button class="startSendBtn" style="background:#23ade5; cursor:pointer; border-radius: 4px; padding: 3px 6px;">开启独轮车</button>
<button class="splittext" style="background:#757575; cursor:pointer; border-radius: 4px; padding: 3px 6px;">分割文本</button>
<textarea class="MsgList" placeholder="在这输入弹幕,每一句不可超过20字(否则无法发送),每次发送一句。" style="height: 100px; width: 220px; resize: none;"></textarea>
<div class="MsgCount" style="display:inline;"></div><div style="display:inline;">  发送弹幕间隔:</div>
<input id="MsgSendInterval" style="display:inline; width:25px;" autocomplete="off" type="number" min="0" value="${GM_getValue('MsgSendInterval')}">
<div style="display:inline;">秒</div>
<br>
<div>日誌:</div>
<textarea class="MsgLogs" style="height: 100px; width: 220px; resize: none;" readonly></textarea>
</div>`;
            let i;
            document.body.appendChild(list);
            var startSendBtn = document.getElementsByClassName('startSendBtn')[0];
            startSendBtn.addEventListener('click',() => {
                if (!sendMsg) {
                    sendMsg = true;
                }else{
                    sendMsg = false;
                };
            });
            var splittextBtn = document.getElementsByClassName('splittext')[0];
            btn.addEventListener('click',() => {
                if (list.style.display === 'none') {$(list).show();}else{$(list).hide();};
            });
            var MsgInput = document.getElementsByClassName('MsgList')[0];
            var MsgCount = document.getElementsByClassName('MsgCount')[0];
            var MsgIntervalInput = document.getElementById('MsgSendInterval');

            splittextBtn.addEventListener('click',() => {
                var text=numToChinese(MsgInput.value)
                text=splittext(text)
                MsgInput.value=text
                MsgInput.dispatchEvent(new CustomEvent('input'));
            });

            MsgInput.addEventListener('input',() => {
                Msg = MsgInput.value.split('\n');
                if (MsgInput.value === '') {
                    MsgCount.textContent = `共0个弹幕`;
                }else{MsgCount.textContent = `共${Msg.length}个弹幕`;};
                GM_setValue('Msg', MsgInput.value);
            });
            MsgIntervalInput.addEventListener('input',()=>{
                if(!(parseInt(MsgIntervalInput.value)>=0)) MsgIntervalInput.value = 0;
                GM_setValue('MsgSendInterval',MsgIntervalInput.value);
            });
            let MsgValue = GM_getValue('Msg');
            MsgInput.value = MsgValue;
            MsgValue = MsgValue.split('\n');

            for (i = 0; i < MsgValue.length; i++) {
                Msg.push(MsgValue[i]);
            };
            if (MsgInput.value === '') {
                MsgCount.textContent = `共0个弹幕`;
            }else{MsgCount.textContent = `共${Msg.length}个弹幕`;};
            loop();
            clearInterval(check);

        };
    },100);
})();
async function loop() {
    let count = 0;
    let false_count=0;
    let i;
    let MsgLogs = document.getElementsByClassName('MsgLogs')[0];
    let shortUid = document.URL.split('live.bilibili.com/')[1];
    let nums = shortUid.match(/\d+/g);
    shortUid= nums[0];
    let room = await fetch(`http://api.live.bilibili.com/room/v1/Room/room_init?id=${shortUid}`,{
        method: 'GET',
        credentials: 'include'
    })
    let roomid = await room.json();
    console.log(document.URL)
    console.log(shortUid)
    console.log(roomid)
    roomid = roomid['data']['room_id'];
    let scrf = document.cookie.split(';').map(c=>c.trim()).filter(c => c.startsWith('bili_jct='))[0].split('bili_jct=')[1];
    while (true) {
        if (sendMsg === true) {
            let MsgSendInterval = GM_getValue('MsgSendInterval');
            for (i = 0; i < Msg.length; i++) {
                console.log(Msg[i],roomid,scrf)
                if (sendMsg === true) {
                    let send = await fetch('https://api.live.bilibili.com/msg/send',{
                        method: 'POST',
                        credentials: 'include',
                        headers: {
                            'accept': 'application/json, text/javascript, */*; q=0.01',
                            'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
                        },
                        body: `color=16777215&fontsize=25&mode=1&msg=${Msg[i]}&rnd=16082868&roomid=${roomid}&csrf_token=${scrf}&csrf=${scrf}`
                    });
                    let sendApiRes = await send.json();
                    if (sendApiRes['message'] !== "") {
                        console.log(sendApiRes)
                        MsgLogs.value = MsgLogs.value + `发送弹幕:【${Msg[i]}】失败,原因:${sendApiRes['message']},重复${false_count}次。\n`;
                        false_count++
                        if (false_count <1){
                            i--
                        }else{
                        false_count=0
                        }
                    }else{MsgLogs.value = MsgLogs.value + `发送弹幕:【${Msg[i]}】成功\n`;};
                    MsgLogs.scrollTop = MsgLogs.scrollHeight;
                    await new Promise(r => setTimeout(r,MsgSendInterval*1000));
                };
            };
            count += 1;
            MsgLogs.value = MsgLogs.value + `第${count}轮弹幕发送完成\n`;
            MsgLogs.scrollTop = MsgLogs.scrollHeight;
            sendMsg=false
        } else {let count = 0;;await new Promise(r => setTimeout(r,1000));};
    };
};
function splittext(text){
    let sentences = text.split(/[.!?,,!?。]+/);
    sentences = sentences.map(s => s.replace(/\n/g, '').trim());
    let new_sentences = [];
    for (let i = 0; i < sentences.length; i++) {
      let sentence = sentences[i];
      if (sentence.length <= 19) {
        new_sentences.push(sentence + ',');
      } else {
        while (sentence) {
            let part = sentence.substring(0, 19);
            new_sentences.push((part + ',').trim());
          sentence = sentence.substring(part.length).trim();
        }
      }
    }
    let new_sentences_ = [];
    let new_sentence = '';
    for (let i = 0; i < new_sentences.length; i++) {
      let part = new_sentences[i];
      if (new_sentence.length + part.length <= 20) {
        new_sentence += part;
      } else {
        new_sentences_.push(new_sentence.trim());
        new_sentence = part;
      }
    }
    if (new_sentence) {
      new_sentences_.push(new_sentence.trim());
    }
    return new_sentences_.join("\n");
    }
function numToChinese(str) {
    str = toHalfWidth(str)
    str = str.replace(/[\u3000\s\u201c\u201d\u0022]/g, '');
    const numMap = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
    let result = '';
    for (let i = 0; i < str.length; i++) {
      const char = str[i];
      if (/[0-9]/.test(char)) {
        result += numMap[parseInt(char)];
      } else {
        result += char;
      }
    }
    return result;
  }
  function toHalfWidth(str) {
    var result = '';
    for (var i = 0; i < str.length; i++) {
      var code = str.charCodeAt(i);
      if (code >= 65281 && code <= 65374) {
        result += String.fromCharCode(code - 65248);
      } else {
        result += str.charAt(i);
      }
    }
    return result;
  }