您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
暗中做个机器人岂不美哉_(¦3」∠)_
当前为
// ==UserScript== // @name Cutemon机器人 Rebuild // @namespace Cutemon // @version 4.43 // @description 暗中做个机器人岂不美哉_(¦3」∠)_ // @author Cutemon // @include /https?:\/\/live\.bilibili\.com\/h5\/\d+\/rebuild\??.*/ // @require https://static.hdslb.com/live-static/libs/jquery/jquery-1.11.3.min.js // @grant none // ==/UserScript== (function() { console.log(`Cutemon机器人ver_4.43|・ω・`)`); let CUTE_ROBOT = { init: () => { try { // 拦截弹幕服务器连接 const webSocketConstructor = WebSocket.prototype.constructor; WebSocket.prototype.constructor = (url, protocols) => { if (url === 'wss://broadcastlv.chat.bilibili.com/sub') return webSocketConstructor(url, protocols); throw new Error(); }; } catch (err) {} try { // 拦截直播流 window.fetch = () => new Promise(() => { throw new Error(); }); } catch (err) {} try { // 清空页面元素和节点 // $('html').remove(); $('body').html(CUTE_INTERFACE.html); } catch (err) {} try { // 获取用户token CUTE_DATA.USER_INFO.token = CUTE_API.getCookie('bili_jct'); // $.ajaxSetup({ // crossDomain: true, // xhrFields: { // withCredentials: true // }, // data: { // csrf: CUTE_DATA.USER_INFO.token, // csrf_token: CUTE_DATA.USER_INFO.token // } // }); } catch (err) {} try { } catch (err) {} }, // 连接弹幕websocket connect: { common: () => { CUTE_DATA.reconnect = true; if ( CUTE_API.danmakuWebSocket.room && CUTE_API.danmakuWebSocket.room.roomid ) { // console.log(typeof CUTE_API.danmakuWebSocket.room); CUTE_ROBOT.disconnect(); setTimeout(() => { CUTE_ROBOT.connect.common(); }, 3e3); } else { // 为textarea添加新行数的插件 $.fn.autoHeightTextareaDefaults = { rows: 0, minRows: 0, maxRows: null, HIDDEN_STYLE: ` height:0 !important; visibility:hidden !important; overflow:hidden !important; position:absolute !important; z-index:-1000 !important; top:0 !important; right:0 !important; `, CONTEXT_STYLE: [ 'letter-spacing', 'line-height', 'padding-top', 'padding-bottom', 'font-family', 'font-weight', 'font-size', 'text-rendering', 'text-transform', 'width', 'text-indent', 'padding-left', 'padding-right', 'border-width', 'box-sizing' ], calculateNodeStyling: function(targetElement) { var _this = this; // 获取设置在当前textarea上的css属性 var style = window.getComputedStyle(targetElement); var boxSizing = style.getPropertyValue( 'box-sizing' ); var paddingSize = parseFloat( style.getPropertyValue('padding-bottom') ) + parseFloat( style.getPropertyValue('padding-top') ); var borderSize = parseFloat( style.getPropertyValue( 'border-bottom-width' ) ) + parseFloat( style.getPropertyValue('border-top-width') ); var contextStyle = _this.CONTEXT_STYLE .map(function(value) { return ( value + ':' + style.getPropertyValue(value) ); }) .join(';'); return { contextStyle, paddingSize, borderSize, boxSizing }; }, mainAlgorithm: function( hiddenTextarea, textareaElement ) { var _this = this; /** * 主要的算法依据 * @param {string} textareaElement : textarea的DOM对象 */ var { paddingSize, borderSize, boxSizing, contextStyle } = _this.calculateNodeStyling(textareaElement); // 将获取到得当前得textarea的css属性作用于隐藏的textarea hiddenTextarea.setAttribute( 'style', _this.HIDDEN_STYLE + contextStyle ); // 将当前的textarea的value设置到隐藏的textarea上面 hiddenTextarea.value = textareaElement.value || textareaElement.placeholder || ''; // 获取隐藏的textarea的height var height = hiddenTextarea.scrollHeight; if (boxSizing === 'border-box') { height = height + borderSize; } else if (boxSizing === 'content-box') { height = height - paddingSize; } hiddenTextarea.value = ''; var singleRowHeight = hiddenTextarea.scrollHeight - paddingSize; // 如果设置有最小行数和最大行数时的判断条件,如果没有设置则取rows为最小行数 var minRows; var dataRows = $(textareaElement).attr('rows'); var dataMinRows = $(textareaElement).attr( 'data-min-rows' ); if (dataRows > 0 && dataMinRows > 0) { minRows = Math.max(dataRows, dataMinRows); } else if (dataRows > 0) { minRows = dataRows; } else if (dataMinRows > 0) { minRows = dataMinRows; } else { minRows = 1; } var maxRows = $(textareaElement).attr( 'data-max-rows' ) ? $(textareaElement).attr('data-max-rows') : null; if (_this.rows && _this.minRows) { minRows = Math.max( _this.rows, _this.minRows, minRows ); } else if (_this.rows) { minRows = Math.max(_this.rows, minRows); } else if (_this.minRows) { minRows = Math.max(_this.minRows, minRows); } if (_this.maxRows && maxRows !== null) { maxRows = Math.min(_this.maxRows, maxRows); } else if (_this.maxRows) { maxRows = _this.maxRows; } if (minRows !== null) { var minHeight = singleRowHeight * minRows; if (boxSizing === 'border-box') { minHeight = minHeight + paddingSize + borderSize; } height = Math.max(minHeight, height); } if (maxRows !== null) { var maxHeight = singleRowHeight * maxRows; if (boxSizing === 'border-box') { maxHeight = maxHeight + paddingSize + borderSize; } height = Math.min(maxHeight, height); } // 将得到的height的高度设置到当前的textarea上面 $(textareaElement).css('height', height + 'px'); } }; $.fn.autoHeightTextarea = function(options) { options = $.extend( {}, $.fn.autoHeightTextareaDefaults, options ); this.each(function(index, textareaElement) { var hiddenTextarea; // 进入页面的初始化操作 if (!hiddenTextarea) { hiddenTextarea = document.createElement( 'textarea' ); document.body.appendChild(hiddenTextarea); } options.mainAlgorithm( hiddenTextarea, textareaElement ); hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild( hiddenTextarea ); hiddenTextarea = null; $(textareaElement) .on('focus', function() { if (!hiddenTextarea) { hiddenTextarea = document.createElement( 'textarea' ); document.body.appendChild( hiddenTextarea ); hiddenTextarea.setAttribute( 'style', options.HIDDEN_STYLE ); } }) .on('input', function() { options.mainAlgorithm( hiddenTextarea, textareaElement ); }) .on('blur', function() { // 删除掉无用的隐藏的textarea hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild( hiddenTextarea ); hiddenTextarea = null; }); }); return this; }; // 获取房间信息 CUTE_MODULE.room.info(); // 获取用户信息 CUTE_MODULE.user.info(); // 获取循环广告列表 CUTE_MODULE.ad.get(); // 获取关键词自动回复列表 CUTE_MODULE.keyword.reply.get(); // 连接弹幕服务器 CUTE_API.danmakuWebSocket .start(CUTE_DATA.ROOM_INFO.room_id) .then(CUTE_DANMAKU_MGR); // 启动感谢关注循环 if ( CUTE_DATA.ROOM_INFO.short_id != 164725 && CUTE_DATA.ROOM_INFO.short_id != 22557 && CUTE_DATA.ROOM_INFO.short_id != 3 && CUTE_DATA.ROOM_INFO.short_id != 8324350 ) { CUTE_DATA.INTERVAL.checkFollowerItv = setInterval( CUTE_MODULE.room.follower.latest, 10e3 ); } // 第二天0点执行记录粉丝数 let waitTime = new Date().setHours(24, 0, 0, 0) - new Date() + 10000; setTimeout(CUTE_MODULE.room.follower.record, waitTime); return CUTE_ROBOT.connect; } }, sleep_mode: () => { // console.log(this); CUTE_DATA.reconnect = true; if ( CUTE_API.danmakuWebSocket.room && CUTE_API.danmakuWebSocket.room.roomid ) { // console.log(typeof CUTE_API.danmakuWebSocket.room); CUTE_ROBOT.disconnect(); setTimeout(() => { CUTE_ROBOT.connect.sleep_mode(); }, 3e3); } else { CUTE_MODULE.room.info(); CUTE_MODULE.user.info(); CUTE_API.danmakuWebSocket .start(CUTE_DATA.ROOM_INFO.room_id) .then(CUTE_SLEEP_MODE_MGR); // 第二天0点执行记录粉丝数 let waitTime = new Date().setHours(24, 0, 0, 0) - new Date() + 10000; setTimeout(CUTE_MODULE.room.follower.record, waitTime); } }, chat_mode: () => { // console.log(this); CUTE_DATA.reconnect = true; if ( CUTE_API.danmakuWebSocket.room && CUTE_API.danmakuWebSocket.room.roomid ) { // console.log(typeof CUTE_API.danmakuWebSocket.room); CUTE_ROBOT.disconnect(); setTimeout(() => { CUTE_ROBOT.connect.chat_mode(); }, 3e3); } else { CUTE_MODULE.room.info(); CUTE_MODULE.user.info(); CUTE_API.danmakuWebSocket .start(CUTE_DATA.ROOM_INFO.room_id) .then(CUTE_CHAT_MODE_MGR); } } }, // 断开弹幕websocket disconnect: () => { CUTE_API.danmakuWebSocket.disconnect(); CUTE_DATA.replyCD = 0; CUTE_DATA.reconnect = false; return; }, reconnect: (waiting = 3) => { CUTE_DATA.reconnect = true; CUTE_API.room.info().then(response => { if (response.code === 0) { CUTE_DATA.ROOM_INFO.live_status = response.data.live_status; setTimeout(() => { if (CUTE_DATA.ROOM_INFO.live_status == 1) { CUTE_ROBOT.connect.common(); } else { CUTE_ROBOT.connect.sleep_mode(); } }, waiting * 1e3); } }); } }; let CUTE_DATA = { ROOM_INFO: { entry_id: window.location.pathname.split('/')[2], short_id: undefined, room_id: undefined, ruid: undefined, // 主播的uid uname: undefined, // 主播昵称 medal_name: undefined, // 主播勋章名 medal_id: undefined, // 主播勋章id guard_list: [], // 主播舰队列表 live_status: undefined, // 直播状态 follower: { // 最新关注者 latest: { ts: undefined, // 关注时间 name: undefined // 昵称 }, record: { ts: undefined, // 上次记录时间 num: undefined // 上次记录关注数 }, repeat: {} // 重复关注 } }, USER_INFO: { uid: undefined, token: undefined }, INTERVAL: { reconnectItv: undefined, checkFollowerItv: undefined, cooldownItv: undefined, replyItv: undefined, queueItv: undefined, adItv: undefined }, danmaku_filter: [`哔哩哔哩 (゜-゜)つロ 干杯~`, `哔哩哔哩干杯( ゜- ゜)つロ`], connecting: false, connect_error: false, reconnect: false, replyText: undefined, replyCD: undefined, blockIgnore: undefined, send_gift_ts: undefined }; let CUTE_INTERFACE = { html: ` <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="https://cdn.bootcss.com/jquery-toast-plugin/1.3.2/jquery.toast.min.css"> <link rel="stylesheet" href="https://s1.hdslb.com/bfs/static/blive/blfe-live-room/static/css/2.ee9e4634828b7352b7e3.vip.css"> <style type="text/css"> .color { display: inline-block; vertical-align: middle; cursor: pointer; box-sizing: border-box-box; border: 1px solid #d0d7dd; border-radius: 50%; width: 20px; height: 20px; } .level-0 { border-color: #000; } .level-0 .label{ background-color: #000; } .level-0 .level { color: #000; } .guard-icon { width: 18px; height: 18px; background-size: cover; } .guard-level-1{ background-image: url('//s1.hdslb.com/bfs/static/blive/blfe-live-room/static/img/icon.guard-thumb-01.e630a67.png'); } .guard-level-2 { background-image: url(data:image/png;base64,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) } .guard-level-3 { background-image: url(data:image/png;base64,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); } #danmu_send { width: 500px; } .container { margin: 20px 0 0 20px; } // .container div { // margin-bottom: 10px; // } .m-b-10 { margin-bottom: 10px; } .chat-history-panel .chat-history-list .chat-item.danmaku-item .admin-icon, .chat-history-panel .chat-history-list .chat-item.danmaku-item .anchor-icon, .chat-history-panel .chat-history-list .chat-item.danmaku-item .fans-medal-item-ctnr, .chat-history-panel .chat-history-list .chat-item.danmaku-item .guard-icon, .chat-history-panel .chat-history-list .chat-item.danmaku-item .title-label, .chat-history-panel .chat-history-list .chat-item.danmaku-item .user-level-icon { margin-right: 5px; } .dp-i-block { display: inline-block; } .v-middle { vertical-align: middle; } .p-relative { position: relative; } .u-name { line-height: 20px; } .admin-icon { background-color: #ffa340; margin-right: 3px; height: 14px; padding: 0 6px; border: 1px solid #ea9336; border-radius: 2px; line-height: 16px; font-size: 12px; color: #fff; } .admin-icon:before { content: "房管"; } .jq-toast-wrap { width: 320px; max-height: 80%; overflow-y: auto; pointer-events: auto!important; } .jq-toast-wrap.top-right { top: 20px; right: 20px; } .jq-toast-single{ width: initial; } .jq-toast-single button{ position: relative; cursor: pointer; background-color: #444; color: #fff; font-size: 12px; padding: 2px 5px; border: 1px solid #fff; } // .jq-toast-single .danmuContent{ // width: 75%; // } // .jq-toast-single div button:nth-of-type(1){ // right: 40px; // top: 35px; // } // .jq-toast-single div button:nth-of-type(2){ // right: 2px; // top: 35px; // } .jq-toast-heading { font-weight: normal; } </style> </head> <body> <div class="container"> <div class="m-b-10"> <h1>接入秘密指挥中心</h1> 指挥中心代号:<input type="number" placeholder="请输入指挥中心代号" id="room_entry" value=""> <button id="connect">全功能启动</button> <button id="sleep_mode_connect">休眠模式</button> <button id="chat_mode_connect">聊天模式</button> <button id="disconnect">断开</button> <button id="goToRoom">前往指挥中心</button> <button id="guard" style="display: none;">开船</button><br /><br /> 弹幕颜色: <span class="color white" color="16777215" style="background-color: rgb(255, 255, 255);"></span> <span class="color red" color="16738408" style="background-color: rgb(255, 104, 104);"></span> <span class="color blue" color="6737151" style="background-color: rgb(102, 204, 255);"></span> <span class="color purple" color="14893055" style="background-color: rgb(227, 63, 255);"></span> <span class="color cyan" color="65532" style="background-color: rgb(0, 255, 252);"></span> <span class="color green" color="8322816" style="background-color: rgb(126, 266, 0);"></span> <span class="color yellow" color="16772431" style="background-color: rgb(255, 237, 79);"></span> <span class="color orange" color="16750592" style="background-color: rgb(255, 152, 0);"></span> <span class="color pink" color="16741274" style="background-color: rgb(255, 115, 154);"></span> </div> <div class="m-b-10"> <span id="setColor" style="color: #EB3941;">默认弹幕颜色为 <span class="color" style="background-color: rgb(255, 255, 255);"></span></span><br /> </div> <div> 弹幕发送:<input type="text" id="danmu_send" placeholder="这是弹幕发射池……" maxlength="30" /> </div> <div> <h1>功能开关</h1> <div> 感谢关注: <input type="radio" name="follow" value="1" />开 <input type="radio" name="follow" value="0" />关 </div> <div> 感谢礼物: <input type="radio" name="gift" value="2" />所有礼物 <input type="radio" name="gift" value="1" />金瓜子礼物 <input type="radio" name="gift" value="0" />关 </div> <div> 循环公告: <input type="radio" name="ad" value="1" />开 <input type="radio" name="ad" value="0" />关 </div> <div> 自动回复: <input type="radio" name="reply" value="1" />开 <input type="radio" name="reply" value="0" />关 </div> <div> 自动禁言: <input type="radio" name="ban" value="1" />开 <input type="radio" name="ban" value="0" />关 </div> <div> 复读机: <input type="radio" name="repeat" value="1" />开 <input type="radio" name="repeat" value="0" />关 </div> </div> <div> <h1>定时轰炸系统</h1> 轰炸间隔:<input style="width: 50px;" type="number" id="intervalTime" value="300"> 秒 <span id="setTime" style="color: #EB3941; margin-left: 10px;">默认轰炸间隔为300秒</span><br /><br /> <button id="start">轰炸开启</button> <button id="clear">任务终止</button> <span id="switch"></span><br /><br /> 投放内容:<input id="ad_new_content" style="width: 500px; margin-bottom: 5px;" type="text" value="" placeholder="请输入投放内容,最多30个字符" maxlength="30" /> <br /> <button id="ad_new_submit">新增</button><br /> </div> <div id="ad_arr"> </div> <div id="log" style="position: absolute; left: 45%; top: 0; margin: 0;"> </div> <div> <h1>智能精确打击</h1> 打击目标:<input id="keyword" style="width: 200px; margin-bottom: 5px;" type="text" value="" maxlength="20" /><br /> 智能打击内容:<input id="reply" style="width: 500px; margin-bottom: 5px;" type="text" value="" maxlength="30" /><br /> <button id="autoreply_add">新增</button><br /> </div> <div id="autoreply_arr"> </div> </div> </body> <script src="https://cdn.bootcss.com/jquery-toast-plugin/1.3.2/jquery.toast.min.js"></script> ` }; let CUTE_API = { baseURL: `//api.live.bilibili.com/`, // websocket danmakuWebSocket: (() => { var dataStruct = [ { name: 'Header Length', key: 'headerLen', bytes: 2, offset: 4, value: 16 }, { name: 'Protocol Version', key: 'ver', bytes: 2, offset: 6, value: 1 }, { name: 'Operation', key: 'op', bytes: 4, offset: 8, value: 1 }, { name: 'Sequence Id', key: 'seq', bytes: 4, offset: 12, value: 1 } ]; var protocol = location.origin.match(/^(.+):\/\//)[1]; var wsUrl = 'ws://broadcastlv.chat.bilibili.com:2244/sub'; if (protocol === 'https') { wsUrl = 'wss://broadcastlv.chat.bilibili.com:2245/sub'; } function str2bytes(str) { var bytes = new Array(); var len, c; len = str.length; for (var i = 0; i < len; i++) { c = str.charCodeAt(i); if (c >= 0x010000 && c <= 0x10ffff) { bytes.push(((c >> 18) & 0x07) | 0xf0); bytes.push(((c >> 12) & 0x3f) | 0x80); bytes.push(((c >> 6) & 0x3f) | 0x80); bytes.push((c & 0x3f) | 0x80); } else if (c >= 0x000800 && c <= 0x00ffff) { bytes.push(((c >> 12) & 0x0f) | 0xe0); bytes.push(((c >> 6) & 0x3f) | 0x80); bytes.push((c & 0x3f) | 0x80); } else if (c >= 0x000080 && c <= 0x0007ff) { bytes.push(((c >> 6) & 0x1f) | 0xc0); bytes.push((c & 0x3f) | 0x80); } else { bytes.push(c & 0xff); } } return bytes; } function bytes2str(array) { var __array = array.slice(0); var j; var filterArray = [ [0x7f], [0x1f, 0x3f], [0x0f, 0x3f, 0x3f], [0x07, 0x3f, 0x3f, 0x3f] ]; var str = ''; for (var i = 0; i < __array.length; i = i + j) { var item = __array[i]; var number = ''; if (item >= 240) { j = 4; } else if (item >= 224) { j = 3; } else if (item >= 192) { j = 2; } else if (item < 128) { j = 1; } var filter = filterArray[j - 1]; for (var k = 0; k < j; k++) { var r = (__array[i + k] & filter[k]).toString(2); var l = r.length; if (l > 6) { number = r; break; } for (var n = 0; n < 6 - l; n++) { r = '0' + r; } number = number + r; } str = str + String.fromCharCode(parseInt(number, 2)); } return str; } function getPacket(payload) { return str2bytes(payload); } function generatePacket(action, payload) { action = action || 2; // 2心跳 或 7加入房间 payload = payload || ''; var packet = getPacket(payload); var buff = new ArrayBuffer(packet.length + 16); var dataBuf = new DataView(buff); dataBuf.setUint32(0, packet.length + 16); dataBuf.setUint16(4, 16); dataBuf.setUint16(6, 1); dataBuf.setUint32(8, action); dataBuf.setUint32(12, 1); for (var i = 0; i < packet.length; i++) { dataBuf.setUint8(16 + i, packet[i]); } return dataBuf; } function Room() { this.timer = null; this.socket = null; this.roomid = null; } Room.prototype = { sendBeat: function() { var self = this; self.timer = setInterval(function() { self.socket.send(generatePacket()); }, 3000); }, close: function() { this.socket.close(); }, destroy: function() { clearInterval(this.timer); this.socket = null; this.timer = null; this.roomid = null; }, joinRoom: function(rid, uid) { rid = rid || 22557; uid = uid || 193351; var packet = JSON.stringify({ uid: uid, roomid: rid }); return generatePacket(7, packet); }, init: function(roomid) { var self = this; self.roomid = roomid; var socket = new WebSocket(wsUrl); socket.binaryType = 'arraybuffer'; socket.onopen = function(event) { if (socket.readyState == 1) { CUTE_MODULE.toast.success(`弹幕服务器连接成功`); CUTE_DATA.connecting = true; // $.toast({ // text: '弹幕服务器连接成功', // Optional heading to be shown on the toast // icon: 'success', // showHideTransition: 'fade', // fade, slide or plain // allowToastClose: true, // Boolean value true or false // hideAfter: 3000, // false to make it sticky or number representing the miliseconds as time after which toast needs to be hidden // stack: 10, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time // position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values // textAlign: 'left', // Text alignment i.e. left, right or center // loader: false // Whether to show loader or not. True by default // }); console.log('%c 弹幕服务器连接成功', 'color: blue'); } else { console.log( '%c 连接失败了,错误码:' + readyState, 'color: red' ); CUTE_API.danmakuWebSocket.disconnect(); return; } var join = self.joinRoom(roomid); socket.send(join.buffer); self.sendBeat(socket); }; socket.onmessage = function(event) { var dataView = new DataView(event.data); // console.log(event.data); var data = {}; data.packetLen = dataView.getUint32(0); dataStruct.forEach(function(item) { if (item.bytes === 4) { data[item.key] = dataView.getUint32( item.offset ); } else if (item.bytes === 2) { data[item.key] = dataView.getUint16( item.offset ); } }); if (data.op && data.op === 5) { data.body = []; var packetLen = data.packetLen; for ( var offset = 0; offset < dataView.byteLength; offset += packetLen ) { packetLen = dataView.getUint32(offset); headerLen = dataView.getUint16(offset + 4); // console.log(dataView.byteLength,offset,packetLen,headerLen); var recData = []; for ( var i = offset + headerLen; i < offset + packetLen; i++ ) { recData.push(dataView.getUint8(i)); } // console.log(recData); try { // console.log(bytes2str(recData)) let body = JSON.parse(bytes2str(recData)); console.log(body); // 弹幕、礼物、系统公告 if ( body.cmd === 'DANMU_MSG' || body.cmd === 'DANMU_MSG:4:0:2:2:2:0' ) { // console.log(body.info[2][1], ':', body.info[1]) // 用户:弹幕内容 self.fn.call(null, { cmd: body.cmd, color: body.info[0][3], uid: body.info[2][0], name: body.info[2][1], admin: body.info[2][2], vip: body.info[2][3], svip: body.info[2][4], text: body.info[1], medal_name: body.info[3][1] || '没勋章', medal_level: body.info[3][0] || '0', user_level: body.info[4][0], guard: body.info[7], roomid: self.roomid }); } else if (body.cmd === 'GUARD_BUY') { self.fn.call(null, { cmd: body.cmd, uid: body.data.uid, username: body.data.username, gift_name: body.data.gift_name, price: body.data.price, roomid: self.roomid }); } else if (body.cmd === 'SEND_GIFT') { self.fn.call(null, { cmd: body.cmd, coin_type: body.data.coin_type, giftName: body.data.giftName, uname: body.data.uname, num: body.data.num, roomid: self.roomid }); } else if (body.cmd === 'SPECIAL_GIFT') { self.fn.call(null, { cmd: body.cmd, storm: body.data[39], storm_id: body.data[39].id, storm_content: body.data[39].content, storm_action: body.data[39].action, roomid: self.roomid }); } else if (body.cmd === 'ROOM_BLOCK_MSG') { self.fn.call(null, { cmd: body.cmd, block_uid: body.data.uid, block_uname: body.data.uname, roomid: self.roomid }); } else if ( body.cmd === 'LIVE' || body.cmd === 'PREPARING' ) { self.fn.call(null, { cmd: body.cmd, roomid: body.roomid }); } data.body.push(body); // console.log(data.body); } catch (e) { // console.log('tcp 校验失败,重新发送') } } } }; socket.onclose = function() { // console.log(e); clearInterval(self.timer); clearInterval(CUTE_DATA.INTERVAL.reconnectItv); clearInterval(CUTE_DATA.INTERVAL.checkFollowerItv); clearInterval(CUTE_DATA.INTERVAL.cooldownItv); clearInterval(CUTE_DATA.INTERVAL.replyItv); clearInterval(CUTE_DATA.INTERVAL.adItv); CUTE_DATA.connecting = false; if (self) { if (CUTE_DATA.reconnect) { let waiting = 3; if (CUTE_DATA.connect_error) { waiting = 30; CUTE_DATA.connect_error = false; } CUTE_API.danmakuWebSocket.reconnect(waiting); console.log( `%c 弹幕服务器已关闭,${waiting}秒后尝试重连`, 'color: red' ); } else { console.log( `%c 弹幕服务器被手动关闭了,不会进行重连`, 'color: red' ); } self.destroy(); // console.log(self); self = null; } // CUTE_API.danmakuWebSocket.disconnect(); }; socket.onerror = function() { CUTE_DATA.connect_error = true; self.close(); console.log(`%c 与弹幕服务器的连接发生了错误`, 'color: red'); }; self.socket = socket; }, then: function(fn) { this.fn = fn; } }; return { room: null, start: function(roomid) { console.log('%c 正在进入房间:' + roomid + '...', 'color: blue'); this.room = new Room(); this.room.init(roomid); return this.room; }, disconnect: function() { if (this.room) { this.room.close(); } }, reconnect: function(waiting = 3) { let timer = setTimeout(() => { if (!CUTE_DATA.connecting) { CUTE_ROBOT.reconnect(waiting); } else { timer(); } }, waiting * 1e3); } }; })(), // ajax调用B站API last_ajax: 0, cnt_frequently_ajax: 0, ajax: settings => { if (Date.now() - CUTE_API.last_ajax < 10) { CUTE_API.cnt_frequently_ajax++; } else { CUTE_API.cnt_frequently_ajax = 0; } CUTE_API.last_ajax = Date.now(); if (CUTE_API.cnt_frequently_ajax > 20) throw new Error('调用BilibiliAPI太快,可能出现了bug'); if (settings.xhrFields) { jQuery.extend(settings.xhrFields, { withCredentials: true }); } else { settings.xhrFields = { withCredentials: true }; } jQuery.extend(settings, { url: (settings.url.substr(0, 2) === '//' ? '' : CUTE_API.baseURL) + settings.url, method: settings.method || 'GET', crossDomain: true, dataType: settings.dataType || 'json' }); return jQuery.ajax(settings); }, // 获取用户cookie getCookie: Name => { var search = Name + '='; //查询检索的值 var returnvalue = ''; //返回值 if (document.cookie.length > 0) { var sd = document.cookie.indexOf(search); if (sd != -1) { sd += search.length; var end = document.cookie.indexOf(';', sd); if (end == -1) end = document.cookie.length; //unescape() 函数可对通过 escape() 编码的字符串进行解码。 returnvalue = unescape(document.cookie.substring(sd, end)); } } return returnvalue; }, // 连接直播间初始化 user: { info: () => { return CUTE_API.ajax({ url: 'User/getUserInfo' }); }, // search: uid => { return CUTE_API.ajax({ url: '//api.bilibili.com/x/space/acc/info', data: { mid: uid } }); }, // 勋章切换/直播间勋章 medal: { check: () => { return CUTE_API.ajax({ url: 'i/api/medal', data: { page: 1, pageSize: 25 } }); }, wear: () => { CUTE_API.ajax({ url: 'i/ajaxWearFansMedal', data: { medal_id: CUTE_DATA.ROOM_INFO.medal_id } }); }, cancel: () => { CUTE_API.ajax({ url: 'i/ajaxCancelWear' }); } }, // 发送 send: { // 发送私信 msg: (receiver_id, content) => { return CUTE_API.ajax({ method: 'POST', url: '//api.vc.bilibili.com/web_im/v1/web_im/send_msg', data: { msg: { sender_uid: CUTE_DATA.USER_INFO.uid, receiver_id: receiver_id, receiver_type: 1, msg_type: 1, content: content }, csrf_token: CUTE_DATA.USER_INFO.token, csrf: CUTE_DATA.USER_INFO.token } }); }, // 发送弹幕 danmaku: msg => { return CUTE_API.ajax({ method: 'POST', url: 'msg/send', data: { // 字体颜色:默认白色:16777215 | 姥爷红:16738408 | 姥爷蓝:6737151 | 青色:65532 | 绿色:8322816 | 黄色:16772431 | 橙色:16750592 color: 16750592, fontsize: 25, mode: 1, msg: msg, rnd: new Date().getTime(), roomid: CUTE_DATA.ROOM_INFO.room_id, bubble: 0, csrf_token: CUTE_DATA.USER_INFO.token, csrf: CUTE_DATA.USER_INFO.token } }); }, config: colorhex => { return CUTE_API.ajax({ method: 'POST', url: 'api/ajaxSetConfig', data: { room_id: CUTE_DATA.ROOM_INFO.room_id, color: colorhex, csrf_token: CUTE_DATA.USER_INFO.token, csrf: CUTE_DATA.USER_INFO.token } }); } }, // 送礼 gift: { // 送礼物 send: msg => { return CUTE_API.ajax({ method: 'POST', url: 'gift/v2/gift/send', data: { uid: CUTE_DATA.USER_INFO.uid, gift_id: gift_id, ruid: CUTE_DATA.ROOM_INFO.ruid, gift_num: gift_num, coin_type: 'silver', bag_id: 0, platform: 'pc', biz_code: 'live', biz_id: CUTE_DATA.ROOM_INFO.room_id, rnd: new Date().getTime(), storm_beat_id: 0, metadata: '', price: 0, csrf_token: CUTE_DATA.USER_INFO.token, csrf: CUTE_DATA.USER_INFO.token } }); }, // 送礼物(从包裹) send_bag: (gift_id, gift_num, bag_id) => { return CUTE_API.ajax({ method: 'POST', url: 'gift/v2/live/bag_send', data: { uid: CUTE_DATA.USER_INFO.uid, gift_id: gift_id, ruid: CUTE_DATA.ROOM_INFO.ruid, gift_num: gift_num, coin_type: 'silver', bag_id: bag_id, platform: 'pc', biz_code: 'live', biz_id: CUTE_DATA.ROOM_INFO.room_id, rnd: new Date().getTime(), storm_beat_id: 0, metadata: '', price: 0, csrf_token: CUTE_DATA.USER_INFO.token, csrf: CUTE_DATA.USER_INFO.token } }); }, bag_list: () => { return CUTE_API.ajax({ method: 'GET', url: 'xlive/web-room/v1/gift/bag_list', data: { t: new Date().getTime() } }); } } }, room: { info: () => { return CUTE_API.ajax({ url: 'room/v1/Room/get_info', async: false, data: { platform: 'android', room_id: CUTE_DATA.ROOM_INFO.entry_id } }); }, medal: () => { return CUTE_API.ajax({ url: 'rankdb/v1/RoomRank/webMedalRank', data: { roomid: CUTE_DATA.ROOM_INFO.room_id, ruid: CUTE_DATA.ROOM_INFO.ruid } }); }, guard: (page = 1) => { return CUTE_API.ajax({ url: 'guard/topList', data: { page: page, roomid: CUTE_DATA.ROOM_INFO.room_id, ruid: CUTE_DATA.ROOM_INFO.ruid } }); }, followers: () => { return CUTE_API.ajax({ url: '//api.bilibili.com/x/relation/followers', data: { vmid: CUTE_DATA.ROOM_INFO.ruid } }); }, block_user: { check: page => { return CUTE_API.ajax({ url: 'liveact/ajaxGetBlockList', data: { roomid: CUTE_DATA.ROOM_INFO.room_id, page: page } }); }, search: search => { return CUTE_API.ajax({ url: 'banned_service/v2/Silent/search_user', data: { search: search } }); }, add: (block_uid, hour) => { return CUTE_API.ajax({ method: 'POST', url: 'banned_service/v2/Silent/add_block_user', data: { roomid: CUTE_DATA.ROOM_INFO.room_id, block_uid: block_uid, hour: hour, csrf_token: CUTE_DATA.USER_INFO.token, csrf: CUTE_DATA.USER_INFO.token } }); // 旧接口 // return CUTE_API.ajax({ // method: 'POST', // url: 'liveact/room_block_user', // data: { // roomid: CUTE_DATA.ROOM_INFO.room_id, // method: 1, // content: block_user, // hour: hour, // csrf_token: CUTE_DATA.USER_INFO.token, // csrf: CUTE_DATA.USER_INFO.token // } // }); }, del: id => { return CUTE_API.ajax({ method: 'POST', url: 'banned_service/v1/Silent/del_room_block_user', data: { id: id, roomid: CUTE_DATA.ROOM_INFO.room_id, csrf_token: CUTE_DATA.USER_INFO.token, csrf: CUTE_DATA.USER_INFO.token } }); }, del_old: id => { // 旧接口 return CUTE_API.ajax({ method: 'POST', url: 'live_user/v1/RoomSilent/del', data: { uid: uid, id: id, csrf_token: CUTE_DATA.USER_INFO.token, csrf: CUTE_DATA.USER_INFO.token } }); } }, silent: (minute, type, level) => { return CUTE_API.ajax({ method: 'POST', url: 'liveact/room_silent', data: { minute: minute, room_id: CUTE_DATA.ROOM_INFO.room_id, method: type, level: level, csrf_token: CUTE_DATA.USER_INFO.token, csrf: CUTE_DATA.USER_INFO.token } }); } } }; let CUTE_MODULE = { // 配置初始化 config: { init: () => { if ( Boolean( localStorage.getItem( `CUTE_CONFIG_${CUTE_DATA.ROOM_INFO.room_id}` ) ) ) { CUTE_CONFIG = JSON.parse( localStorage.getItem( `CUTE_CONFIG_${CUTE_DATA.ROOM_INFO.room_id}` ) ); // let switch_name = ['gift', 'follow', 'ad', 'reply', 'ban', 'coin_type']; let radios = $('input[type="radio"]'); // console.log(radios); for (let i = 0; i < radios.length; i++) { // console.log(radios[i].attr('name')); radios.eq(i).click(function() { // console.log($(this).attr('name')); // console.log($(this).val()); CUTE_CONFIG.MODULE_SWITCH[ $(this).attr('name') ] = Number($(this).val()); localStorage.setItem( `CUTE_CONFIG_${CUTE_DATA.ROOM_INFO.room_id}`, JSON.stringify(CUTE_CONFIG) ); }); if ( CUTE_CONFIG.MODULE_SWITCH[ radios.eq(i).attr('name') ] == radios.eq(i).val() ) { console.log(i); radios.eq(i).prop('checked', true); } } } else { // 配置从旧的localstorage中转移 CUTE_CONFIG.KEYWORD.replyArr = JSON.parse( localStorage.getItem( `auto_keyword_reply_${CUTE_DATA.ROOM_INFO .room_id}` ) ) || []; CUTE_CONFIG.KEYWORD.banArr = JSON.parse( localStorage.getItem( `ban_keyword_${CUTE_DATA.ROOM_INFO.room_id}` ) ) || []; CUTE_CONFIG.AD.replyArr = JSON.parse( localStorage.getItem( `auto_ad_danmu_${CUTE_DATA.ROOM_INFO.room_id}` ) ) || []; // 将配置信息存入localstorage CUTE_MODULE.config.update(); } // 更新主播勋章信息 CUTE_MODULE.room.medal.id(); CUTE_MODULE.room.medal.name(); // 更新房间内舰队信息 CUTE_MODULE.room.guard(); }, update: () => { localStorage.setItem( `CUTE_CONFIG_${CUTE_DATA.ROOM_INFO.room_id}`, JSON.stringify(CUTE_CONFIG) ); } }, user: { // 获取用户uid info: () => { console.log(`读取用户信息`); return CUTE_API.user.info().then(response => { if (response.code == 'REPONSE_OK') { CUTE_DATA.USER_INFO.uid = response.data.uid; } }); } }, room: { // 获取room基本信息 info: () => { console.log(`读取房间信息`); return CUTE_API.room.info().then(response => { if (response.code === 0) { // 获取房间原id CUTE_DATA.ROOM_INFO.room_id = response.data.room_id; // 更新房间信息 CUTE_DATA.ROOM_INFO.room_id = response.data.room_id; CUTE_DATA.ROOM_INFO.short_id = response.data.short_id; CUTE_DATA.ROOM_INFO.ruid = response.data.uid; CUTE_DATA.ROOM_INFO.live_status = response.data.live_status; // CUTE_DATA.ROOM_INFO.uname = response.data.uname; // 执行配置初始化 CUTE_MODULE.config.init(); // gift_recorder = // JSON.parse( // localStorage.getItem(`gift_${CUTE_DATA.ROOM_INFO.room_id}`) // ) || {}; console.log( `主播uid:${CUTE_DATA.ROOM_INFO.ruid}, 直播间号:${CUTE_DATA .ROOM_INFO.room_id}` ); // CUTE_DATA.INTERVAL.reconnectItv = setInterval(CUTE_MODULE.reconnect(), 10e3); } }); }, // 获取medal_id medal: { id: () => { try { return CUTE_API.medal.check().then(response => { if ( response.code === 0 && response.data.list.length > 0 ) { for ( let i = 0; i < response.data.fansMedalList.length; i++ ) { if ( CUTE_DATA.ROOM_INFO.short_id == response.data.fansMedalList[i].roomid ) { CUTE_DATA.ROOM_INFO.medal_id = response.data.fansMedalList[ i ].medal_id; } } } }); } catch (err) {} }, name: () => { try { return CUTE_API.room.medal().then(response => { if (response.data.list.length > 0) { CUTE_DATA.ROOM_INFO.medal_name = response.data.list[0].medal_name; console.log(CUTE_DATA.ROOM_INFO.medal_name); CUTE_MODULE.toast.success( `本房间勋章:${CUTE_DATA.ROOM_INFO.medal_name}` ); // $.toast({ // text: '本房间勋章:' + CUTE_DATA.ROOM_INFO.medal_name, // Text that is to be shown in the toast // icon: 'success', // Type of toast icon // showHideTransition: 'fade', // fade, slide or plain // allowToastClose: true, // Boolean value true or false // hideAfter: 3000, // false to make it sticky or number representing the miliseconds as time after which toast needs to be hidden // stack: 10, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time // position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values // textAlign: 'left', // Text alignment i.e. left, right or center // loader: false // Whether to show loader or not. True by default // }); } }); } catch (err) {} } }, // 获取guard列表 guard: page => { return CUTE_API.room.guard(page).then(response => { if (response.code === 0) { if (response.data.info.now == 1) { CUTE_DATA.ROOM_INFO.guard_list = []; let top3 = response.data.top3; for (let i = 0; i < top3.length; i++) { CUTE_DATA.ROOM_INFO.guard_list.push( top3[i].uid ); } } let list = response.data.list; for (let i = 0; i < list.length; i++) { CUTE_DATA.ROOM_INFO.guard_list.push(list[i].uid); } if (response.data.info.now < response.data.info.page) { CUTE_MODULE.room.guard(response.data.info.now + 1); } else { setTimeout(() => { if ( response.data.info.num == CUTE_DATA.ROOM_INFO.guard_list.length ) { CUTE_MODULE.toast.success( `本房间舰长数:${CUTE_DATA.ROOM_INFO.guard_list .length}` ); // $.toast({ // text: '本房间舰长数:' + CUTE_DATA.ROOM_INFO.guard_list.length, // Text that is to be shown in the toast // icon: 'success', // Type of toast icon // showHideTransition: 'fade', // fade, slide or plain // allowToastClose: true, // Boolean value true or false // hideAfter: 3000, // false to make it sticky or number representing the miliseconds as time after which toast needs to be hidden // stack: 10, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time // position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values // textAlign: 'left', // Text alignment i.e. left, right or center // loader: false // Whether to show loader or not. True by default // }); } else { CUTE_MODULE.toast.failed(`舰队数据获取有误,请刷新重试`); // $.toast({ // text: '舰队数据获取有误,请刷新重试', // Text that is to be shown in the toast // icon: 'error', // Type of toast icon // showHideTransition: 'fade', // fade, slide or plain // allowToastClose: true, // Boolean value true or false // hideAfter: false, // false to make it sticky or number representing the miliseconds as time after which toast needs to be hidden // stack: 10, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time // position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values // textAlign: 'left', // Text alignment i.e. left, right or center // loader: false // Whether to show loader or not. True by default // }); } }, 1e3); } } }); }, // 获取关注人数 follower: { now: () => { return CUTE_API.room.info().then(response => { if (response.code === 0) { // console.log(`请求成功`); let record = { ts: CUTE_CONFIG.FOLLOWER.record.ts, follower: CUTE_CONFIG.FOLLOWER.record.num }; let now = { ts: new Date().setHours(0, 0, 0, 0), follower: response.data.attention, live_status: response.data.live_status, online: response.data.online }; let change; let online; if (record.ts >= now.ts) { // 记录时间是今天 if (now.follower >= record.follower) { change = `(${now.follower - record.follower}↑)`; } else { change = `(${record.follower - now.follower}↓)`; } } if (now.live_status != 1) { online = `,未开播`; } else { online = `,气人值${response.data.online}`; } return CUTE_MODULE.danmaku.queue_add( `当前粉丝数${now.follower}${change || ''}${online}` ); } }); }, latest: () => { if (!CUTE_CONFIG.MODULE_SWITCH.follow) { return; } return CUTE_API.room.followers().then(response => { if (response.code === 0) { let list = response.data.list; let latest = CUTE_DATA.ROOM_INFO.follower.latest; let repeat = CUTE_DATA.ROOM_INFO.follower.repeat; let num; if (latest.ts >= list[0].mtime) { // console.log("没有新的关注"); return; } else { let follower_new = { uid: list[0].mid, name: list[0].uname }; if (latest.ts) { switch (repeat[follower_new.name]) { case 1: CUTE_MODULE.danmaku.queue_add( `${follower_new.name} 你为什么又点了一次关注|・ω・`)` ); repeat[follower_new.name]++; break; case 2: CUTE_MODULE.danmaku.queue_add( `${follower_new.name} 再玩一次你就没了|・ω・`)` ); repeat[follower_new.name]++; break; case 3: repeat[follower_new.name]++; CUTE_MODULE.block.add( follower_new.uid, 1, 'follow' ); break; case 4: console.log('重复关注过多,不搭理这个人'); break; default: for ( let i = 0; i < list.length; i++ ) { if (latest.ts < list[i].mtime) { // 未记录的用户加入重复关注监控列表 if ( !repeat[list[i].uname] ) { repeat[ list[i].uname ] = 1; } // 新关注的用户有2人时的处理 if (i == 1) { follower_new.name += ',' + list[i].uname; } } else { // 新关注的用户高于3人时,会在下一个循环进入这个条件,所以i取3,之后循环获取到的都会是老关注,所以break if (i >= 3) { num = i; } break; } } if (num >= 3) { CUTE_MODULE.danmaku.queue_add( `♥ ${follower_new.name} 等${num}个小伙伴点了关注哟~` ); } else { CUTE_MODULE.danmaku.queue_add( `♥ ${follower_new.name} 点了关注哟~` ); } break; } latest.ts = list[0].mtime; latest.name = list[0].uname; } else { latest.ts = list[0].mtime; latest.name = list[0].uname; } console.log( CUTE_MODULE.tsFormatter(latest.ts), latest.name ); } } }); }, record: param => { return CUTE_API.room.info().then(response => { if (response.code === 0) { CUTE_CONFIG.FOLLOWER = { record: { ts: new Date().getTime(), num: response.data.attention } }; CUTE_MODULE.config.update(); if (param == 'reply') { CUTE_MODULE.danmaku.queue_add( `当前粉丝数为${CUTE_CONFIG.FOLLOWER.record .num},已记录` ); } } }); } } }, // 弹幕发送及配置 danmaku: { list: [], to_be_sent: [], lastMsg: undefined, color: e => { let color = e.target.attributes.color.value, colorhex = '0x' + Number(color).toString(16); // console.log($(this)[0].outerHTML); return CUTE_API.user.send.config(colorhex).then( response => { if (response.code === 0) { $('#setColor').html( '<span style="color: #00BE00;">弹幕颜色已设置为 ' + e.target.outerHTML + '</span>' ); CUTE_MODULE.toast.success(`弹幕颜色设置成功`); // $.toast({ // heading: '弹幕颜色设置成功', // icon: 'success', // hideAfter: 1500, // stack: 10, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time // position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values // textAlign: 'left', // Text alignment i.e. left, right or center // loader: false // Whether to show loader or not. True by default // }); } else { CUTE_MODULE.toast.failed(`弹幕颜色设置失败`); // $.toast({ // heading: '弹幕颜色设置失败', // text: '原因:' + response.msg, // hideAfter: 1500, // stack: 10, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time // icon: 'error', // position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values // textAlign: 'left', // Text alignment i.e. left, right or center // loader: false // Whether to show loader or not. True by default // }); } }, err => { CUTE_MODULE.toast.failed(`网络错误:${err}`); } ); // .catch(err => { // CUTE_MODULE.toast.failed(`网络错误:${err}`); // // $.toast({ // // heading: '设置失败', // // text: '网络错误:' + err, // // hideAfter: 1500, // // stack: 10, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time // // icon: 'error', // // position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values // // textAlign: 'left', // Text alignment i.e. left, right or center // // loader: false // Whether to show loader or not. True by default // // }); // }); }, show: msg => { if (~CUTE_DATA.danmaku_filter.indexOf(msg.text)) { return; } try { let guard = '', admin = '', medal = '', user_level = `<div class="user-level-icon lv-${msg.user_level} dp-i-block p-relative v-middle"> UL ${msg.user_level} </div>`, user_name = `<span class="v-middle level-${msg.medal_level == 0 ? 'none' : msg.medal_level}" title="${msg.uid}"> <span class="level u-name"> ${msg.name} </span> </span>`; if (msg.guard) { guard = `<i class="guard-icon dp-i-block v-middle bg-center bg-no-repeat guard-level-${msg.guard}"></i>`; } if (msg.admin) { admin = `<div class="admin-icon dp-i-block p-relative v-middle" title="这是位大人物 (=・ω・=)"></div>`; } if (msg.medal_level > 0) { // console.log(msg.medal_level); medal = `<div class="v-middle fans-medal-item level-${msg.medal_level || 0}"> <span class="label"> ${msg.medal_name} </span> <span class="level"> ${msg.medal_level} </span> </div>`; } let ts = new Date().getTime(); let danmuSender = `<div class="v-middle"> ${guard} ${admin} ${medal} ${user_level} ${user_name} </div>`, danmuContent = `<div class="danmuContent"> <span style="color: #${msg.color.toString( 16 )}">${msg.text}</span> <button id="repeat${ts}">复读</button> <button id="ban${ts}">封禁</button> </div>`; $.toast({ text: danmuContent, // Text that is to be shown in the toast heading: danmuSender, // Optional heading to be shown on the toast hideAfter: false, // false to make it sticky or number representing the miliseconds as time after which toast needs to be hidden stack: 20, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values textAlign: 'left', // Text alignment i.e. left, right or center loader: false, // Whether to show loader or not. True by default afterShown: function() { $('#repeat' + ts).on('click', e => { return CUTE_MODULE.danmaku.queue_add(msg.text); }); $('#ban' + ts).on('click', e => { return CUTE_MODULE.block.add(msg.uid, 720); }); } // will be triggered after the toat has been shown }); let scrollHeight = $('.jq-toast-wrap:first').prop( 'scrollHeight' ); $('.jq-toast-wrap:first').scrollTop(scrollHeight); } catch (err) {} }, admin: msg => { let keyword = ['拉黑', '权限', '记录粉丝数', '存活测试']; for (let i = 0; i < keyword.length; i++) { if (msg.text.indexOf(keyword[i]) == 7) { switch (keyword[i]) { case '拉黑': CUTE_API.room.block_user .search(msg.text.split('=')[1]) .then(response => { if (response.code === 0) { let block_uid = response.data.items[0].uid; let block_uname = response.data.items[0].uname; if ( CUTE_CONFIG.BLACKLIST.indexOf( String(block_uid) ) == -1 ) { CUTE_CONFIG.BLACKLIST.push( block_uid ); CUTE_MODULE.config.update(); CUTE_MODULE.danmaku.queue_add( `用户 ${block_uname} 已被本机加入无视列表|・ω・`)` ); } else { CUTE_MODULE.danmaku.queue_add( `该用户已经凉了,无需重复添加|・ω・`)` ); } } else { console.log(response.msg); } }); break; case '记录粉丝数': CUTE_MODULE.room.follower.record('reply'); break; case '存活测试': CUTE_MODULE.danmaku.queue_add( `确认存活!本机正常工作中( ˘•ω•˘ )` ); break; default: CUTE_MODULE.danmaku.queue_add( `你好,没这个指令,告辞|・ω・`)` ); break; } return; } } return CUTE_MODULE.danmaku.queue_add(`你好,没这个指令,告辞|・ω・`)`); }, command: msg => { // console.log(`command`); let keyword = [ '全部功能', '礼物', '关注', '循环公告', '回复', '封禁', '高阶魔法', '复读', '休眠', '唤醒', '关机', '重连', '重启', '查询粉丝数' ]; for (let i = 0; i < keyword.length; i++) { if (msg.text.indexOf(keyword[i]) == 4) { // console.log(`指令:${keyword[i]}`); let param, param1, param2; try { param = msg.text.split('=')[1].split(','); param1 = param[0]; param2 = param[1]; } catch (err) {} switch (keyword[i]) { case '全部功能': switch (param1) { case '0': CUTE_CONFIG.MODULE_SWITCH.gift = 0; CUTE_CONFIG.MODULE_SWITCH.follow = 0; CUTE_CONFIG.MODULE_SWITCH.ad = 0; CUTE_CONFIG.MODULE_SWITCH.reply = 0; CUTE_MODULE.danmaku.queue_add( `全部功能 -> 关闭` ); break; case '1': CUTE_CONFIG.MODULE_SWITCH.gift = 1; CUTE_CONFIG.MODULE_SWITCH.follow = 1; CUTE_CONFIG.MODULE_SWITCH.ad = 1; CUTE_CONFIG.MODULE_SWITCH.reply = 1; CUTE_MODULE.danmaku.queue_add( `全部功能 -> 开启` ); break; } break; case '礼物': switch (param1) { case '0': CUTE_CONFIG.MODULE_SWITCH.gift = 0; CUTE_MODULE.danmaku.queue_add( `感谢礼物 -> 关闭` ); break; case '1': CUTE_CONFIG.MODULE_SWITCH.coin_type = 'gold'; CUTE_CONFIG.MODULE_SWITCH.gift = 1; CUTE_MODULE.danmaku.queue_add( `感谢金瓜子礼物 -> 开启` ); break; case '2': CUTE_CONFIG.MODULE_SWITCH.coin_type = undefined; CUTE_CONFIG.MODULE_SWITCH.gift = 2; CUTE_MODULE.danmaku.queue_add( `感谢所有礼物 -> 开启` ); break; } break; case '关注': switch (param1) { case '0': CUTE_CONFIG.MODULE_SWITCH.follow = 0; CUTE_MODULE.danmaku.queue_add( `感谢关注 -> 关闭` ); break; case '1': CUTE_MODULE.danmaku.queue_add( `感谢关注 -> 开启` ); CUTE_CONFIG.MODULE_SWITCH.follow = 1; break; } break; case '循环公告': switch (param1) { case '0': CUTE_CONFIG.MODULE_SWITCH.ad = 0; CUTE_MODULE.danmaku.queue_add( `循环公告 -> 关闭` ); break; case '1': CUTE_CONFIG.MODULE_SWITCH.ad = 1; CUTE_MODULE.danmaku.queue_add( `循环公告 -> 开启` ); break; } break; case '回复': switch (param1) { case '0': CUTE_CONFIG.MODULE_SWITCH.reply = 0; CUTE_MODULE.danmaku.queue_add( `关键词回复 -> 关闭` ); break; case '1': CUTE_CONFIG.MODULE_SWITCH.reply = 1; CUTE_MODULE.danmaku.queue_add( `关键词回复 -> 开启` ); break; } break; case '封禁': break; case '高阶魔法': var minute = 3, type = 'level', level = 1; for (let i = 0; i < param.length; i++) { if ( msg.text.split('=')[i].indexOf('分') != -1 ) { if (param[i].split('分')[0] == 0) { minute = 0; } else if ( param[i].split('分')[0] <= 3 ) { minute = 3; } else if ( param[i].split('分')[0] <= 10 ) { minute = 10; } else if ( param[i].split('分')[0] <= 30 ) { minute = 30; } else { minute = 0; } } if (param[i].indexOf('等级') != -1) { type = 'level'; if ( param[i].split('等级')[1] >= 1 && param[i].split('等级')[1] <= 60 ) { level = param[i].split('等级')[1]; } else { level = 1; } } else if (param[i].indexOf('勋章') != -1) { type = 'medal'; if ( param[i].split('勋章')[1] >= 1 && param[i].split('勋章')[1] <= 20 ) { level = param[i].split('勋章')[1]; } else { level = 1; } } else if (param[i].indexOf('全员') != -1) { type = 'member'; level = 1; } } if (msg.text.indexOf('解除') != -1) { minute = 3; type = 'off'; level = 1; } // 启动范围魔法 CUTE_MODULE.room .silent(minute, type, level) .then(response => { if (response.msg) { CUTE_MODULE.danmaku.queue_add( `高阶魔法启动失败:${response.msg}` ); } else { if (type == 'off') { CUTE_MODULE.danmaku.queue_add( `高阶魔法已解除(=・ω・=)` ); } else { CUTE_MODULE.danmaku.queue_add( `成功启动高阶范围魔法打击!${minute}分钟后解除` ); } } }); break; case '复读': switch (param1) { case '0': CUTE_CONFIG.MODULE_SWITCH.repeat = 0; CUTE_MODULE.danmaku.queue_add( `复读机 -> 关闭` ); break; case '1': CUTE_CONFIG.MODULE_SWITCH.repeat = 1; CUTE_MODULE.danmaku.queue_add( `限制型复读机 -> 开启` ); break; case '2': CUTE_CONFIG.MODULE_SWITCH.repeat = 2; CUTE_MODULE.danmaku.queue_add( `全员型复读机 -> 开启` ); break; } break; case '唤醒': CUTE_ROBOT.connect.common(); CUTE_MODULE.danmaku.queue_add( `你这个居居为什么要叫醒我( ˘•ω•˘ )` ); break; case '关机': CUTE_ROBOT.disconnect(); CUTE_MODULE.danmaku.queue_add( `啊我死了,下个ID见|・ω・`)` ); location.reload(); break; case '休眠': CUTE_ROBOT.connect.sleep_mode(); CUTE_MODULE.danmaku.queue_add( `啊我睡了,谁吵醒我谁是居|・ω・`)` ); break; case '重连': // $('#connect').click(); CUTE_MODULE.danmaku.queue_add( `知道了啦,本机将重新接入|・ω・`)` ); CUTE_ROBOT.reconnect(); break; case '重启': // $('#connect').click(); CUTE_MODULE.danmaku.queue_add( `知道了啦,本机将重新运行|・ω・`)` ); if (!CUTE_MODULE.getUrlParam('reconnect')) { location.href = `${window.location .href}?reconnect=1`; } else { window.location.reload(true); } break; case '查询粉丝数': CUTE_MODULE.room.follower.now().then(); break; default: CUTE_MODULE.danmaku.queue_add( `你好,没这个指令,告辞|・ω・`)` ); break; } CUTE_MODULE.config.update(); return; } } return CUTE_MODULE.danmaku.queue_add(`你好,没这个指令,告辞|・ω・`)`); }, cute: (msg, permission) => { let keyword = [ '添词', '删词', '制裁', '捞人', '弹幕颜色', '召唤', 'roll点', '抽个舰长', '送个辣条' ]; for (let i = 0; i < keyword.length; i++) { if (msg.text.indexOf(keyword[i]) == 4) { // console.log(`指令:${keyword[i]}`); let param, param1, param2; try { param = msg.text.split('=')[1].split(','); param1 = param[0]; param2 = param[1]; } catch (err) {} switch (keyword[i]) { case '添词': if ( permission >= CUTE_CONFIG.PERMISSION.normal ) { CUTE_MODULE.keyword.reply.add(msg); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.normal} |・ω・`)` ); } break; case '删词': if ( permission >= CUTE_CONFIG.PERMISSION.superfans ) { CUTE_MODULE.keyword.reply.delByDanmaku(msg); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.superfans} |・ω・`)` ); } break; case '制裁': var block_user = param1; var hour = param2 || 1; if ( block_user == '193351' || block_user.indexOf('萌萌兽') != -1 || block_user == '我自己' || block_user == '我' ) { if (msg.admin == 1) { return CUTE_MODULE.danmaku.queue_add( `小老弟,请收起你的骚操作,制裁不了的( ˘•ω•˘ )` ); } else { CUTE_MODULE.block.add( msg.uid, hour, 'reflect' ); } } else if (permission >= 170) { hour = param2 || 720; return CUTE_MODULE.block.search( block_user, hour, 'execute' ); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:170 |・ω・`)` ); } break; case '捞人': if (permission >= 170) { CUTE_MODULE.block.del(msg); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:170 |・ω・`)` ); } break; case '弹幕颜色': if (permission >= CUTE_CONFIG.PERMISSION.fans) { var colorhex; switch (param1) { case '红': colorhex = '0xff6868'; break; case '蓝': colorhex = '0x66ccff'; break; case '黄': colorhex = '0xffed4f'; break; case '绿': colorhex = '0x7eff00'; break; case '橙': colorhex = '0xff9800'; break; case '紫': colorhex = '0xe33fff'; break; case '白': colorhex = '0xffffff'; break; default: return; } CUTE_API.user.send .config(colorhex) .then(response => { if (response.code === 0) { CUTE_MODULE.danmaku.queue_add( `弹幕颜色设置成功!我${param1}了( ˘•ω•˘ )` ); } else { CUTE_MODULE.danmaku.queue_add( `弹幕颜色设置失败!我没${param1}(๑•́ ₃ •̀๑)` ); } }); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.fans} |・ω・`)` ); } break; case '召唤': if (permission >= CUTE_CONFIG.PERMISSION.host) { CUTE_MODULE.danmaku.queue_add( `召唤中……请等待响应( ˘•ω•˘ )` ); if ( window.Notification && Notification.permission !== 'denied' ) { Notification.requestPermission(function( status ) { let isClick; var notification = new Notification( '受到召唤', { body: CUTE_MODULE.tsFormatter( new Date().getTime() / 1000 ) + ' ' + CUTE_DATA.ROOM_INFO .uname + '的直播间发起了一个召唤' } ); notification.onclick = function() { isClick = 1; return CUTE_MODULE.danmaku.queue_add( `${msg.name}以为萌萌兽不在?太天真了!` ); // window.open( // "https://live.bilibili.com/" + CUTE_DATA.ROOM_INFO.short_id // ); }; setTimeout(() => { if (!isClick) { return CUTE_MODULE.danmaku.queue_add( `好的吧,萌萌兽真的不在,你召唤也没用` ); } }, 8e3); }); } } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.host} |・ω・`)` ); } break; case 'roll点': if (permission >= 1) { CUTE_MODULE.roll(msg); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:1 |・ω・`)` ); } break; case '抽个舰长': if ( permission >= CUTE_CONFIG.PERMISSION.guard ) { CUTE_MODULE.raffle(msg); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.guard} |・ω・`)` ); } break; case '送个辣条': if ( permission >= CUTE_CONFIG.PERMISSION.guard ) { CUTE_MODULE.gift.send_bag(msg); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.guard} |・ω・`)` ); } break; default: CUTE_MODULE.danmaku.queue_add( `你好,没这个指令,告辞|・ω・`)` ); break; } return; } } return CUTE_MODULE.danmaku.queue_add(`你好,没这个指令,告辞|・ω・`)`); // 切换勋章 if ( msg.text.indexOf('萌萌兽') != -1 && msg.text.indexOf('勋章') != -1 ) { return CUTE_MODULE.danmaku.queue_add(`勋章是什么?人家不知道呀|・ω・`)`); } }, query: (msg, permission) => { let keyword = ['指令', '权限', '粉丝数', '舰长群', '真爱群']; for (let i = 0; i < keyword.length; i++) { if (msg.text.indexOf(keyword[i]) == 4) { console.log(`查询:${keyword[i]}`); switch (keyword[i]) { case '指令': if (permission >= CUTE_CONFIG.PERMISSION.fans) { CUTE_MODULE.danmaku.queue_add( `由于字数限制,指令说明请到我的动态中查看哟|・ω・`)` ); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.fans} |・ω・`)` ); } break; case '权限': CUTE_MODULE.danmaku.queue_add( `@${msg.name} 当前权限:${permission}` ); break; case '粉丝数': if ( permission >= CUTE_CONFIG.PERMISSION.admin ) { if ( CUTE_DATA.ROOM_INFO.short_id != 8324350 ) { CUTE_MODULE.room.follower.now(); } else { return CUTE_MODULE.danmaku.queue_add( `本房间禁止使用该指令|・ω・`)` ); } } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.admin} |・ω・`)` ); } break; case '舰长群': if ( permission >= CUTE_CONFIG.PERMISSION.guard ) { let whisperCtx = { // 631: `欢迎来到631海豹大舰队!舰长群:870309615(可加稻叽解锁好友位哟\\n若已加入请无视~`, 189: `感谢大佬登上狐妖的小船船!舰长群:568744231,欢迎来玩♡\\n若已加入请无视~`, 223: `感谢大佬登上可可的小船船!舰长群:88479489,欢迎加入♡\\n若已加入请无视~`, 64566: `跪谢老板٩(๑^o^๑)۶对猫猫的船票支持,解锁欢乐的舰长群(823316645)快来一起玩耍吧٩(๑^o^๑)۶\\n若已加入请无视~` }; if ( whisperCtx[CUTE_DATA.ROOM_INFO.entry_id] ) { CUTE_MODULE.whisper( msg.uid, msg.username, `{"content":"[${CUTE_MODULE.tsFormatter( new Date() / 1000 )}] ${whisperCtx[ CUTE_DATA.ROOM_INFO.entry_id ]}"}`, 'guard' ); } else { console.log( `这个直播间没有设置舰长群,不能发送私信|・ω・`)` ); } } else { return CUTE_MODULE.danmaku.queue_add( `船都没上你查什么查|・ω・`)` ); } break; case '真爱群': let msgContent; switch (CUTE_DATA.ROOM_INFO.short_id) { case 189: if (permission >= 130) { msgContent = `{"content":"[${CUTE_MODULE.tsFormatter( new Date() / 1000 )} ] 感谢大佬一直以来对狐妖的支持!狐妖的真爱宝宝633202159,欢迎加入♡"}`; } else { return CUTE_MODULE.danmaku.queue_add( `不是真爱你查什么查|・ω・`)` ); } break; case 223: if (permission >= 50) { msgContent = `{"content":"[${CUTE_MODULE.tsFormatter( new Date() / 1000 )} ] 感谢大佬一直以来对可可的支持!可可的真爱群727774262,验证请填写:萌萌兽机器人,欢迎加入♡"}`; } else { return CUTE_MODULE.danmaku.queue_add( `不是真爱你查什么查|・ω・`)` ); } break; default: return CUTE_MODULE.danmaku.queue_add( `这个直播间没有设置真爱群|・ω・`)` ); } CUTE_MODULE.whisper( msg.uid, msg.name, msgContent, 'truelove' ); break; default: break; } return; } } return CUTE_MODULE.danmaku.queue_add(`你好,没这个指令,告辞|・ω・`)`); }, send: e => { let keyCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode; if (keyCode == 13) { // alert("响应键盘的enter事件"); // 获取时间戳 let msg = $('#danmu_send').val().trim(); if (msg) { return CUTE_API.user.send.danmaku(msg).then( response => { if (!response.msg) { CUTE_MODULE.toast.success(); $('#danmu_send').val(''); } else { CUTE_MODULE.toast.failed(response.msg); } }, err => { CUTE_MODULE.toast.failed(`网络错误:${err}`); } ); // .catch(err => { // CUTE_MODULE.toast.failed(`网络错误${err}`); // }); } else { CUTE_MODULE.toast.failed(`发送内容不能为空`); return; } } }, queue_add: msg => { let length = CUTE_MODULE.danmaku.to_be_sent.length; if (length === 0) { CUTE_MODULE.danmaku.to_be_sent.push(msg); CUTE_MODULE.danmaku.queue_send( CUTE_MODULE.danmaku.to_be_sent[0] ); CUTE_MODULE.danmaku.queue_status = 1; } else { if ( msg != CUTE_MODULE.danmaku.to_be_sent[length - 1] || msg == `你好,没这个指令,告辞|・ω・`)` ) { CUTE_MODULE.danmaku.to_be_sent.push(msg); if (CUTE_MODULE.danmaku.queue_status === 0) { CUTE_MODULE.danmaku.queue_send( CUTE_MODULE.danmaku.to_be_sent[1] ); CUTE_MODULE.danmaku.queue_status = 1; CUTE_MODULE.danmaku.to_be_sent.shift(); } } } }, queue_send: msg => { CUTE_API.user.send.danmaku(msg).then( response => { if (!response.msg) { CUTE_MODULE.toast.success(`回复成功`); } else { CUTE_MODULE.toast.failed(response.msg); } let length = CUTE_MODULE.danmaku.to_be_sent.length; setTimeout(() => { switch (length) { case 1: console.log(`弹幕队列空闲中~`); CUTE_MODULE.danmaku.queue_status = 0; break; default: CUTE_MODULE.danmaku.queue_send( CUTE_MODULE.danmaku.to_be_sent[1] ); CUTE_MODULE.danmaku.to_be_sent.shift(); console.log( `剩余弹幕队列:${CUTE_MODULE.danmaku .to_be_sent}` ); break; } }, 1111); }, err => { CUTE_MODULE.toast.failed(err); setTimeout(() => { switch (length) { case 1: console.log(`弹幕队列空闲中~`); CUTE_MODULE.danmaku.queue_status = 0; break; default: CUTE_MODULE.danmaku.queue_send( CUTE_MODULE.danmaku.to_be_sent[1] ); CUTE_MODULE.danmaku.to_be_sent.shift(); console.log( `剩余弹幕队列:${CUTE_MODULE.danmaku .to_be_sent}` ); break; } }, 1111); } ); }, queue_status: 0, todo: () => { if ( msg.text.indexOf('#萌回') === 0 && msg.text.indexOf('&') != -1 ) { // 添加 if ( CUTE_DATA.ROOM_INFO.medal_name || msg.guard != 0 || msg.admin == 1 || msg.uid == 193351 || msg.uid == 64131034 ) { let keyword = msg.text.slice(4, msg.text.indexOf('&')); let replyContent = msg.text.slice( msg.text.indexOf('&') + 1 ); $('#keyword').val(keyword); $('#reply').val(replyContent); setTimeout(function() { addReply(1); }, 100); } else { return CUTE_MODULE.danmaku.queue_add( `_(:з」∠)_权限不足,设置失败` ); } return; } if (msg.text.indexOf('#删回') === 0 && msg.text.length > 4) { // 删除自动回复 if ( msg.guard != 0 || msg.admin == 1 || msg.uid == 193351 || msg.uid == 64131034 ) { return delReplyByDanmu(msg); } else { return CUTE_MODULE.danmaku.queue_add( `_(:з」∠)_权限不足,删除失败` ); } } // console.log(msg.text, keyword_reply[0].keyword); if ( msg.text.indexOf('点歌') != -1 && (CUTE_DATA.ROOM_INFO.short_id == 631 || CUTE_DATA.ROOM_INFO.short_id == 64566) && msg.uid != 64131034 ) { if (msg.medal_name == CUTE_DATA.ROOM_INFO.medal_name) { if ( msg.text.split('=')[0] == '点歌' || msg.text.split('=')[0] == '#点歌' ) { return CUTE_MODULE.danmaku.queue_add( `滴~点歌格式正确!上车成功~` ); } else { return CUTE_MODULE.danmaku.queue_add( `你刚刚好像说了点歌?但是姿势好像不太对呢,要不再试试?` ); } } else { return CUTE_MODULE.danmaku.queue_add( `你是不是想点歌?只有戴上主播勋章才能点歌成功哟~` ); } } } }, // 私信发送 whisper: (receiver_id, receiver_name, content, mode) => { return CUTE_API.user.send .msg(receiver_id, content) .then(response => { if (response.code === 0) { switch (mode) { case 'help': CUTE_MODULE.danmaku.queue_add( `♥ 指令已发送给${receiver_name},请检查私信~` ); break; case 'truelove': CUTE_MODULE.danmaku.queue_add( `♥ 真爱群已发送给${receiver_name},请检查私信~` ); break; case 'guard': CUTE_MODULE.danmaku.queue_add( `♥ 舰长群已发送给${receiver_name},请检查私信~` ); break; default: CUTE_MODULE.danmaku.queue_add( `♥ 私信已发送给${receiver_name},请注意查收~` ); break; } } else { console.log(`私信发送失败:${response.msg}`); } }); }, // 获取/添加/删除 循环广告内容 ad: { // 未完成 get: () => { console.log(`读取循环公告`); let replyArr = CUTE_CONFIG.AD.replyArr; try { if (replyArr.length > 0) { $('#ad_arr').empty(); $('#intervalTime').val(CUTE_CONFIG.AD.replyTime); for (let i = 0; i < replyArr.length; i++) { $('#ad_arr').append( [i + 1] + '、<input style="width: 500px; margin-bottom: 5px;" type="text" index="' + [i] + '" value="' + replyArr[i] + '" maxlength="30"/> <button class="danmudel" index="' + [i] + '">删除</button><br />' ); } $('.danmudel').click(CUTE_MODULE.ad.del); } } catch (err) {} $('#ad_arr input').blur(e => { console.log(e); let index = e.target.attributes.index.value, val = e.target.value; console.log(`内容修改:${(index, val)}`); replyArr[index] = val; CUTE_MODULE.config.update(); }); CUTE_MODULE.ad.run(); }, add: () => { if (!CUTE_DATA.ROOM_INFO.room_id) { alert('请先连接直播间再操作|・ω・`)'); return false; } if ($('#ad_new_content').val()) { CUTE_CONFIG.AD.replyArr.push($('#ad_new_content').val()); CUTE_MODULE.config.update(); CUTE_MODULE.ad.get(); $('#ad_new_content').val(''); } else { alert('广告内容不能为空|・ω・`)'); } }, del: e => { let index = e.target.attributes.index.value; console.log(`删除:${index}`); CUTE_CONFIG.AD.replyArr.splice(index, 1); CUTE_MODULE.config.update(); CUTE_MODULE.ad.get(); }, send: () => { return CUTE_API.room.info().then(response => { if (response.code === 0) { CUTE_DATA.ROOM_INFO.live_status = response.data.live_status; if ( CUTE_DATA.ROOM_INFO.live_status == 1 && CUTE_CONFIG.MODULE_SWITCH.ad ) { $('#switch').html( '<span style="color: #00BE00; margin-left: 10px;">定时轰炸系统已启用,指挥中心工作中_(¦3」∠)_</span>' ); let AD = CUTE_CONFIG.AD; return CUTE_API.user.send .danmaku(AD.replyArr[AD.replySerial]) .then(response => { if (response.code === 0) { AD.replySerial < AD.replyArr.length - 1 ? AD.replySerial++ : (AD.replySerial = 0); CUTE_MODULE.config.update(); } }); } else { $('#switch').html( '<span style="color: #FF9800; margin-left: 10px;">定时轰炸系统被拦截,或指挥中心正在休眠_(¦3」∠)_</span>' ); } return; } }); }, run: () => { clearInterval(CUTE_DATA.INTERVAL.adItv); // 消除定时器的叠加 CUTE_DATA.INTERVAL.adItv = undefined; // 清空保存定时器的变量 console.log('发送间隔:' + CUTE_CONFIG.AD.replyTime); // CUTE_MODULE.ad.send(); CUTE_DATA.INTERVAL.adItv = setInterval( CUTE_MODULE.ad.send, CUTE_CONFIG.AD.replyTime * 1e3 ); }, end: () => { clearInterval(CUTE_DATA.INTERVAL.adItv); CUTE_DATA.INTERVAL.adItv = undefined; // 清空保存定时器的变量 CUTE_CONFIG.AD.replySerial = 0; $('#switch').html( '<span style="color: #EB3941; margin-left: 10px;">弹幕发射已关闭_(¦3」∠)_</span>' ); }, time: () => { CUTE_CONFIG.AD.replyTime = $('#intervalTime').val(); $('#setTime').html( '<span style="color: #00BE00;">发射间隔已设置为' + CUTE_CONFIG.AD.replyTime + '秒</span>' ); CUTE_MODULE.config.update(); if (CUTE_DATA.INTERVAL.adItv) { CUTE_MODULE.ad.run(); } return; }, interval: undefined }, keyword: { // 获取/添加/删除 关键词自动回复 reply: { // 未完成 get: () => { console.log(`读取关键词回复`); let replyArr = CUTE_CONFIG.KEYWORD.replyArr; // 更新配置结构,单回复转为多回复 // try { // for (let i = 0; i < replyArr.length; i++) { // if (typeof replyArr[i].reply == 'string') { // replyArr[i].reply = replyArr[i].reply.split('1qaz2wsx'); // } // } // localStorage.setItem( // 'auto_keyword_reply_' + room_id, // JSON.stringify(replyArr) // ); // } catch (e) {} if (replyArr) { $('#autoreply_arr').empty(); for (let i = 0; i < replyArr.length; i++) { let reply = ''; for (let j = 0; j < replyArr[i].reply.length; j++) { reply += replyArr[i].reply[j]; if (j != replyArr[i].reply.length - 1) { reply += '\n'; } } $('#autoreply_arr').append(` <div> <div style="display: inline-block;"> ${[i + 1]}、关键词: <input disabled style="display: inline-block; width: 200px; color: rgb(255, 104, 104); margin-bottom: 5px;" type="text" index="${[i]}" value="${replyArr[i] .keyword}" maxlength="20"/> </div> <div style="display: inline-block;"> 自动回复: <textarea disabled style="resize: none; vertical-align: middle; width: 500px; color: rgb(255, 104, 104); margin-bottom: 5px;" index="${[i]}">${reply}</textarea> <button class="replydel" index="${[i]}">删除</button> </div> </div> `); } $('textarea').autoHeightTextarea(); $('.replydel').click(CUTE_MODULE.keyword.reply.del); } }, add: msg => { if (!CUTE_DATA.ROOM_INFO.room_id) { alert('请先连接直播间再操作|・ω・`)'); return false; } let replyArr = CUTE_CONFIG.KEYWORD.replyArr; let repeat = 0; let keyword; let reply; if (msg) { keyword = msg.text.split('=')[1].split('&')[0]; reply = msg.text.split('=')[1].split('&')[1]; if (!keyword || !reply) { return CUTE_MODULE.danmaku.queue_add( '关键词和自动回复不能为空|・ω・`)' ); } } else { keyword = $('#keyword').val(); reply = $('#reply').val(); if (!keyword || !reply) { return alert('关键词和自动回复不能为空|・ω・`)'); } } try { // 查询关键词是否已经存在,不存在则新建对象 for (let i = 0; i < replyArr.length; i++) { if (replyArr[i].keyword == keyword) { replyArr[i].reply.push(reply); repeat = 1; if (msg) { CUTE_MODULE.danmaku.queue_add( `[${keyword}] 更新成功( ˘•ω•˘ )` ); } break; } } if (!repeat) { let obj = {}; obj.keyword = keyword; obj.reply = [reply]; replyArr.push(obj); if (msg) { CUTE_MODULE.danmaku.queue_add( `[${keyword}] 设置成功( ˘•ω•˘ )` ); } } // localStorage.setItem( // 'auto_keyword_reply_' + room_id, // JSON.stringify(replyArr) // ); CUTE_MODULE.config.update(); CUTE_MODULE.keyword.reply.get(); $('#keyword').val(''); $('#reply').val(''); } catch (err) {} }, del: e => { let index = e.target.attributes.index.value; let replyArr = CUTE_CONFIG.KEYWORD.replyArr; console.log(index); replyArr.splice(index, 1); CUTE_MODULE.config.update(); CUTE_MODULE.keyword.reply.get(); }, delByDanmaku: msg => { let replyArr = CUTE_CONFIG.KEYWORD.replyArr; if (replyArr) { let keyword = msg.text.split('=')[1]; for (let i = 0; i < replyArr.length; i++) { if (replyArr[i].keyword == keyword) { replyArr.splice(i, 1); CUTE_MODULE.config.update(); CUTE_MODULE.keyword.reply.get(); return CUTE_MODULE.danmaku.queue_add( `[${keyword}] 删除成功( ˘•ω•˘ )` ); } } return CUTE_MODULE.danmaku.queue_add( `[${keyword}] 未找到|・ω・`)` ); } } }, // 获取/添加/删除 关键词自动封禁 ban: { // 未完成 get: () => {}, add: msg => { if (!room_id) { alert('未连接直播间'); return false; } let keyword = msg.text.split('=')[1]; if (keyword) { let banArr = CUTE_CONFIG.KEYWORD.banArr; for (let i = 0; i < banArr.length; i++) { if (banArr[i] == keyword) { CUTE_MODULE.toast.failed(`不可以添加重复的关键词!`); // $.toast({ // heading: '添加失败', // text: '错误原因:不可以添加重复的关键词!', // hideAfter: 1500, // stack: 10, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time // icon: 'error', // position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values // textAlign: 'left', // Text alignment i.e. left, right or center // loader: false // Whether to show loader or not. True by default // }); return CUTE_MODULE.danmaku.queue_add( `${keyword} 已存在,不可以重复添加` ); } } banArr.push(keyword); CUTE_MODULE.config.update(); return CUTE_MODULE.danmaku.queue_add(`${keyword} 设置成功`); } }, del: () => {}, delByDanmaku: msg => { let keyword = msg.text.split('=')[1]; if (keyword) { let banArr = CUTE_CONFIG.KEYWORD.banArr; for (let i = 0; i < banArr.length; i++) { if (banArr[i] == keyword) { banArr.splice(i, 1); CUTE_MODULE.config.update(); return CUTE_MODULE.danmaku.queue_add( `${keyword} 删除成功` ); } } return CUTE_MODULE.danmaku.queue_add(`${keyword} 未找到`); } } } }, // 封禁 block: { // 可根据昵称查询用户uid search: (search, hour, mode) => { return CUTE_API.room.block_user .search(search) .then(response => { if (response.code === 0) { let block_uid = response.data.items[0].uid; switch (mode) { case 'execute': CUTE_MODULE.block.add( block_uid, hour, 'execute' ); break; default: break; } } else { console.log(response.msg); } }); }, add: (block_uid, hour, mode) => { return CUTE_API.room.block_user .add(block_uid, hour) .then(response => { if (response.code === 0) { console.log( `用户 ${response.data.uname} 被封禁至 ${response.data .block_end_time}` ); switch (mode) { case 'follow': CUTE_MODULE.danmaku.queue_add( `※ ${response.data.uname} 由于多次关注被制裁了` ); break; case 'keyword': CUTE_MODULE.danmaku.queue_add( `※ ${response.data.uname} 由于触发关键词被制裁了` ); break; case 'self': CUTE_MODULE.danmaku.queue_add( `※ ${response.data.uname} 由于想不开,进行了自裁` ); break; case 'execute': CUTE_MODULE.danmaku.queue_add( `※ ${response.data.uname} 被管理制裁了` ); break; case 'reflect': CUTE_MODULE.danmaku.queue_add( `※ ${response.data.uname} 由于作死,被反弹了制裁` ); break; default: break; } return; } else { console.log('触发了封禁,但是操作失败了'); CUTE_MODULE.danmaku.queue_add( `${response.message}|・ω・`)` ); } }); }, del: (msg, page = 1) => { return CUTE_API.room.block_user.check(page).then(response => { if (response.code === 0) { let block_user = msg.text.split('=')[1]; if (response.data.length > 0) { for (let i = 0; i < response.data.length; i++) { if ( block_user == response.data[i].uname || block_user == response.data[i].uid ) { block_user = response.data[i].uname; return CUTE_API.room.block_user .del(response.data[i].id) .then(response => { if (response.code === 0) { CUTE_MODULE.danmaku.queue_add( `${block_user} 被捞出了小黑屋|・ω・`)` ); } }); } } if (page < 5 && response.data.length == 10) { return CUTE_MODULE.room.block_user.del(page++); } else { return CUTE_MODULE.danmaku.queue_add( `该用户不在小黑屋中哦|・ω・`)` ); } } else { return CUTE_MODULE.danmaku.queue_add( `该用户不在小黑屋中哦|・ω・`)` ); } } else { console.log('发生了不可描述的错误: ' + response.msg); return CUTE_MODULE.danmaku.queue_add( `小黑屋查询请求失败了呢|・ω・`)` ); } }); } }, // 感谢、赠送礼物 gift: { // 感谢礼物列表 list: {}, // 添加新礼物进列表 add: msg => { // console.log(`有新礼物加入感谢列表`); let list = CUTE_MODULE.gift.list; if (list[msg.uname]) { if (list[msg.uname][msg.giftName]) { if (list[msg.uname][msg.giftName].time == -1) { // 同类礼物已存在,倒计时未启动 // console.log(`送礼闲置中,倒计时启动`); list[msg.uname][msg.giftName].time = 5; list[msg.uname][msg.giftName].giftNum = msg.num; CUTE_MODULE.gift.thank(msg); } else { // 同类礼物已存在,倒计时中 // console.log(`送礼连击中,倒计时重置`); list[msg.uname][msg.giftName].time = 5; list[msg.uname][msg.giftName].giftNum += msg.num; } } else { // 送礼用户已存在,但无同类礼物 // console.log(`送出新礼物,倒计时启动`); list[msg.uname][msg.giftName] = {}; list[msg.uname][msg.giftName].time = 5; list[msg.uname][msg.giftName].giftNum = msg.num; CUTE_MODULE.gift.thank(msg); } } else { // 送礼用户未记录 // console.log(`新送礼用户,倒计时启动`); list[msg.uname] = {}; list[msg.uname][msg.giftName] = {}; list[msg.uname][msg.giftName].time = 5; list[msg.uname][msg.giftName].giftNum = msg.num; CUTE_MODULE.gift.thank(msg); } }, // 执行感谢操作 thank: msg => { let list = CUTE_MODULE.gift.list; setTimeout(() => { if (list[msg.uname][msg.giftName].time > 0) { list[msg.uname][msg.giftName].time--; CUTE_MODULE.gift.thank(msg); // console.log(list[msg.uname][msg.giftName].time); } else { list[msg.uname][msg.giftName].time = -1; switch (CUTE_DATA.ROOM_INFO.entry_id) { case '631': CUTE_MODULE.danmaku.queue_add( `♥ ${msg.uname}献祭了${list[msg.uname][ msg.giftName ].giftNum}个${msg.giftName}给恶魔` ); break; case '189': CUTE_MODULE.danmaku.queue_add( `♥ ${msg.uname}用${list[msg.uname][ msg.giftName ].giftNum}个${msg.giftName}夸赞了狐妖` ); break; case '223': CUTE_MODULE.danmaku.queue_add( `♥ 收到${msg.uname}的${list[msg.uname][ msg.giftName ].giftNum}个${msg.giftName},可可爽得飞起` ); break; case '64566': CUTE_MODULE.danmaku.queue_add( `♥ ${msg.uname}用${list[msg.uname][ msg.giftName ].giftNum}个${msg.giftName}锤了猫幼的头` ); break; default: return CUTE_MODULE.danmaku.queue_add( `♥ ${msg.uname} 送出了${msg.giftName} × ${list[ msg.uname ][msg.giftName].giftNum}` ); } } }, 1e3); }, // 赠送礼物 send: msg => {}, // 赠送礼物(从包裹) send_bag: msg => { if ( !CUTE_DATA.send_gift_ts || new Date().getTime() > CUTE_DATA.send_gift_ts ) { return CUTE_API.user.gift.bag_list().then(response => { if (response.code === 0) { let bag_list = response.data.list; let bag_id; for (let i = 0; i < bag_list.length; i++) { if (bag_list[i].gift_name == '辣条') { bag_id = bag_list[i].bag_id; return CUTE_API.user.gift .send_bag(1, 1, bag_id) .then(response => { console.log(response); if (response.code === 0) { CUTE_DATA.send_gift_ts = new Date().getTime() + 6e5; return CUTE_MODULE.danmaku.queue_add( `${msg.name} 通过本机送出了1个辣条|・ω・`)` ); } else { return CUTE_MODULE.danmaku.queue_add( `${msg.name} 投喂辣条失败了呢|・ω・`)` ); } }); } } return CUTE_MODULE.danmaku.queue_add( `本机的包裹中没有辣条可以送了!(๑•́ ₃ •̀๑)` ); } }); } else { let cd = Math.round( (CUTE_DATA.send_gift_ts - new Date().getTime()) / 1000 ); return CUTE_MODULE.danmaku.queue_add( `功能冷却中!请在${cd}秒后使用|・ω・`)` ); } } }, // 转换时间戳 tsFormatter: ts => { var date = new Date(ts * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000 var Y = date.getFullYear() + '-'; var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'; var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '; var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'; var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':'; var s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds(); return Y + M + D + h + m + s; }, // 获取日期 getDate: () => { var date = new Date(); //时间戳为10位需*1000,时间戳为13位的话不需乘1000 var Y = date.getFullYear() + ''; var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + ''; var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ''; return Y + M + D; }, // 获取地址栏参数 getUrlParam: name => { var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)'); var r = window.location.search.substr(1).match(reg); if (r != null) return decodeURI(r[2]); return null; }, // roll点 roll: msg => { let roll_range = 100; let roll_num; if (msg.text.split('=')[1]) { if (msg.text.split('=')[1].length > 6) { return CUTE_MODULE.danmaku.queue_add( `对不起,你太长了,roll点失败|・ω・`)` ); } else if ( parseInt(msg.text.split('=')[1]) == msg.text.split('=')[1] ) { roll_range = parseInt(msg.text.split('=')[1]); roll_num = Math.floor(Math.random() * roll_range + 1); } } else { roll_num = Math.floor(Math.random() * roll_range + 1); } return CUTE_MODULE.danmaku .queue_add(`${msg.name} roll出了${roll_num}点`) .then(response => { if (response.msg) { CUTE_DATA.replyFailedText = msg.name + ' roll点失败,请重试'; CUTE_MODULE.danmaku.queue_add( CUTE_DATA.replyFailedText ); } }); }, // 抽奖 raffle: msg => { let total = CUTE_DATA.ROOM_INFO.guard_list.length; let lucky_num = Math.floor(Math.random() * total); let lucky_uid = CUTE_DATA.ROOM_INFO.guard_list[lucky_num]; return CUTE_API.user.search(lucky_uid).then(response => { if (response.code === 0) { let lucky_dog = response.data.name; CUTE_MODULE.danmaku.queue_add(`♥ ${lucky_dog} 成为了天选之人!`); } }); }, // 操作提示封装 toast: { success: msg => { try { $.toast({ heading: '操作成功', text: msg || '', icon: 'success', hideAfter: 1500, stack: 20, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values textAlign: 'left', // Text alignment i.e. left, right or center loader: false // Whether to show loader or not. True by default }); let scrollHeight = $('.jq-toast-wrap:first').prop( 'scrollHeight' ); $('.jq-toast-wrap:first').scrollTop(scrollHeight); } catch (error) { window.location.reload(true); } }, failed: msg => { $.toast({ heading: '操作失败', text: msg || '', hideAfter: 1500, stack: 20, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time icon: 'error', position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values textAlign: 'left', // Text alignment i.e. left, right or center loader: false // Whether to show loader or not. True by default }); let scrollHeight = $('.jq-toast-wrap:first').prop( 'scrollHeight' ); $('.jq-toast-wrap:first').scrollTop(scrollHeight); } }, // 礼物统计 giftRecorder: undefined }; let CUTE_CONFIG = { AD: { replyArr: [], // 自动广告列表 replySerial: 0, // 自动广告的发送位置 replyTime: 300 // 自动广告时间间隔 }, KEYWORD: { replyArr: [], replySerialArr: [], // 自动回复的发送位置 banArr: [] }, FOLLOWER: { record: { ts: undefined, // 上次记录时间 num: undefined // 上次记录关注数 } }, BLACKLIST: [], MODULE_SWITCH: { gift: 0, follow: 0, ad: 0, reply: 0, ban: 0, coin_type: 'gold' }, PERMISSION: { author: 9999, host: 5000, admin: 1000, guard: 200, superfans: 100, fans: 50, normal: 10 } }; // 弹幕管理器(全功能模式 let CUTE_DANMAKU_MGR = msg => { switch (msg.cmd) { // 特殊礼物刷屏 case 'SPECIAL_GIFT': try { if (msg.storm_action == 'start') { CUTE_DATA.danmaku_filter.push(msg.storm_content); CUTE_DATA.replyCD = 1; CUTE_CONFIG.MODULE_SWITCH.ban = 0; } else if (msg.storm_action == 'end') { CUTE_DATA.replyCD = 0; CUTE_CONFIG.MODULE_SWITCH.ban = 1; } } catch (e) { console.log('然而这并不是storm!'); } break; // 上船 case 'GUARD_BUY': try { if (msg.price == 50000) { return CUTE_MODULE.danmaku.queue_add( `[一週間${msg.gift_name}] ${msg.username} 关于舰长的记忆只有一周(误` ); } else if ( CUTE_DATA.ROOM_INFO.guard_list.indexOf(msg.uid) != -1 ) { return CUTE_MODULE.danmaku.queue_add( `[续费${msg.gift_name}] ${msg.username} 一直续船一直爽!` ); } else { CUTE_DATA.ROOM_INFO.guard_list.push(msg.uid); CUTE_MODULE.danmaku.queue_add( `[新${msg.gift_name}] ${msg.username} 上船了,我地位-1!` ); setTimeout(() => { let whisperCtx = { // 631: `欢迎来到631海豹大舰队!舰长群:870309615 \\n若已加入请无视~`, 189: `感谢大佬登上狐妖的小船船!舰长群:568744231,欢迎来玩♡\\n若已加入请无视~`, 223: `感谢大佬登上可可的小船船!舰长群:88479489,欢迎加入♡\\n若已加入请无视~`, 64566: `跪谢老板٩(๑^o^๑)۶对猫猫的船票支持,解锁欢乐的舰长群(823316645)快来一起玩耍吧٩(๑^o^๑)۶\\n若已加入请无视~` }; if (whisperCtx[CUTE_DATA.ROOM_INFO.entry_id]) { CUTE_MODULE.whisper( msg.uid, msg.username, `{"content":"[${CUTE_MODULE.tsFormatter( new Date() / 1000 )}] ${whisperCtx[ CUTE_DATA.ROOM_INFO.entry_id ]}"}`, 'guard' ); } else { console.log(`这个直播间没有设置舰长群,不能发送私信|・ω・`)`); } }, 5e3); } } catch (err) {} break; // 礼物 case 'SEND_GIFT': try { if ( CUTE_CONFIG.MODULE_SWITCH.gift == 2 || (CUTE_CONFIG.MODULE_SWITCH.gift == 1 && msg.coin_type == CUTE_CONFIG.MODULE_SWITCH.coin_type) ) { return CUTE_MODULE.gift.add(msg); } } catch (err) {} break; // 开播 case 'LIVE': try { if (typeof msg.roomid == 'number') { let startCtx = { 41682: `♥ 咕才是世界的常态……然而居然开播了|・ω・`)`, 70270: `♥ 啊,是我最喜欢的小狐妖开播了|・ω・`)`, 24589: `♥ 咕才是世界的常态……然而居然开播了|・ω・`)`, 64566: `♥ 第一次看直播,刚点进这个直播间就开播了|・ω・`)` }; if (startCtx[msg.roomid]) { CUTE_MODULE.danmaku.queue_add(startCtx[msg.roomid]); } CUTE_ROBOT.connect.common(); if ( window.Notification && Notification.permission !== 'denied' ) { Notification.requestPermission(function(status) { let notification = new Notification('真香警告', { body: CUTE_MODULE.tsFormatter( new Date().getTime() / 1000 ) + ' ' + CUTE_DATA.ROOM_INFO.uname + '出现了!我就是饿死也不会去看一眼!' }); notification.onclick = function() { window.open( 'https://live.bilibili.com/' + CUTE_DATA.ROOM_INFO.short_id ); }; }); } // $('#connect').click(); } } catch (err) {} break; // 下播 case 'PREPARING': try { CUTE_MODULE.danmaku.queue_add(`♥ 本次直播结束,感谢大家的陪伴,记得关注么么哒~!`); CUTE_MODULE.ad.end(); setTimeout(() => { CUTE_ROBOT.connect.sleep_mode(); }, 3e3); } catch (err) {} break; // 封禁提示 case 'ROOM_BLOCK_MSG': try { $.toast({ heading: '封禁提示', text: `${msg.block_uname}被制裁了`, hideAfter: false, stack: 20, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time icon: 'error', position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values textAlign: 'left', // Text alignment i.e. left, right or center loader: false // Whether to show loader or not. True by default }); let scrollHeight = $('.jq-toast-wrap:first').prop( 'scrollHeight' ); $('.jq-toast-wrap:first').scrollTop(scrollHeight); var couple_arr = [ { memberA: '133502', memberB: '1738519' } ]; let block_couple; for (let i = 0; i < couple_arr.length; i++) { if ( CUTE_DATA.blockIgnore == couple_arr[i].memberA || CUTE_DATA.blockIgnore == couple_arr[i].memberB ) { CUTE_DATA.blockIgnore = ''; console.log('cp已被封禁'); return; } if (msg.block_uid == couple_arr[i].memberA) { block_couple = couple_arr[i].memberB; } else if (msg.block_uid == couple_arr[i].memberB) { block_couple = couple_arr[i].memberA; } // console.log(msg.block_uid, couple_arr[i].memberA, couple_arr[i].memberB); if (block_couple) { console.log('couple: ' + block_couple); CUTE_DATA.blockIgnore = block_couple; CUTE_API.room.block_user .add(block_couple, 1) .then(response => { if (response.code == 0) { console.log('禁言成功'); CUTE_MODULE.danmaku.queue_add( `封禁用户存在CP,同步封禁CP用户|・ω・`)` ); } else { CUTE_MODULE.danmaku.queue_add( `封禁用户存在CP,CP用户已在小黑屋|・ω・`)` ); } CUTE_DATA.blockIgnore = ''; }); break; } } } catch (err) {} break; // 弹幕 case 'DANMU_MSG': case 'DANMU_MSG:4:0:2:2:2:0': try { CUTE_MODULE.danmaku.show(msg); // 黑名单返回 let blacklist = CUTE_CONFIG.BLACKLIST; if ( blacklist.length !== 0 && blacklist.indexOf(String(msg.uid)) != -1 ) { return; } let permission = 0; // 指令管理 if (msg.text.indexOf('*') == 0) { if (msg.uid == 64131034 || msg.uid == 193351) { permission += 9999; } if (msg.uid == CUTE_DATA.ROOM_INFO.ruid) { permission += 5000; } if (msg.admin) { permission += 1000; } if (msg.guard) { permission += 1 / msg.guard * 600; } if (msg.medal_name == CUTE_DATA.ROOM_INFO.medal_name) { permission += msg.medal_level * 10; } if (msg.user_level) { permission += Math.round(msg.user_level * 0.1); } // console.log(`用户权限:${permission}`); switch (msg.text.split(' ')[0].split('*')[1]) { case 'admin': if ( permission >= CUTE_CONFIG.PERMISSION.author ) { CUTE_MODULE.danmaku.admin(msg); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.author} |・ω・`)` ); } break; case '配置': if ( permission >= CUTE_CONFIG.PERMISSION.admin ) { CUTE_MODULE.danmaku.command(msg); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.admin} |・ω・`)` ); } break; case '功能': CUTE_MODULE.danmaku.cute(msg, permission); break; case '查询': CUTE_MODULE.danmaku.query(msg, permission); break; default: break; } } else { // 关键词自动回复 if ( CUTE_CONFIG.MODULE_SWITCH.reply && msg.uid != CUTE_DATA.USER_INFO.uid ) { let keyword = CUTE_CONFIG.KEYWORD; for (let i = 0; i < keyword.replyArr.length; i++) { if ( msg.text.indexOf( keyword.replyArr[i].keyword ) != -1 ) { let r = Math.floor( Math.random() * keyword.replyArr[i].reply.length ); if ( keyword.replySerialArr.toString() === [i].toString() ) { console.log(`自动回复内容相同,回避本次回复`); return; } if (!CUTE_DATA.replyCD) { keyword.replySerialArr = [i]; CUTE_MODULE.danmaku.queue_add( keyword.replyArr[i].reply[r] ); clearTimeout( CUTE_DATA.INTERVAL.replyItv ); CUTE_DATA.INTERVAL.replyItv = setTimeout( function() { keyword.replySerialArr = []; }, 5e3 ); CUTE_DATA.replyCD = 1; setTimeout(() => { CUTE_DATA.replyCD = 0; }, 3e3); console.log( `自动回复位置:${keyword.replySerialArr.toString()}` ); } else { console.log(`自动回复cd中`); } break; } } } } // } } catch (err) {} break; default: try { } catch (err) {} break; } }; // 弹幕管理器(休眠模式 let CUTE_SLEEP_MODE_MGR = msg => { switch (msg.cmd) { // 特殊礼物刷屏 case 'SPECIAL_GIFT': try { if (msg.storm) { if (msg.storm_action == 'start') { CUTE_DATA.danmaku_filter.push(msg.storm_content); } else if (msg.storm_action == 'end') { } } } catch (e) { console.log('然而这并不是storm!'); } break; // 封禁提示 case 'ROOM_BLOCK_MSG': try { $.toast({ heading: '封禁提示', text: `${msg.block_uname}被制裁了`, hideAfter: false, stack: 20, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time icon: 'error', position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values textAlign: 'left', // Text alignment i.e. left, right or center loader: false // Whether to show loader or not. True by default }); let scrollHeight = $('.jq-toast-wrap:first').prop( 'scrollHeight' ); $('.jq-toast-wrap:first').scrollTop(scrollHeight); } catch (error) {} break; case 'DANMU_MSG': case 'DANMU_MSG:4:0:2:2:2:0': try { CUTE_MODULE.danmaku.show(msg); // 黑名单返回 let blacklist = CUTE_CONFIG.BLACKLIST; if ( blacklist.length !== 0 && blacklist.indexOf(msg.uid) != -1 ) { return; } let permission = 0; // 指令管理 if (msg.text.indexOf('*') == 0) { if (msg.uid == 64131034 || msg.uid == 193351) { permission += 9999; } if (msg.uid == CUTE_DATA.ROOM_INFO.ruid) { permission += 5000; } if (msg.admin) { permission += 1000; } if (msg.guard) { permission += 1 / msg.guard * 600; } if (msg.medal_name == CUTE_DATA.ROOM_INFO.medal_name) { permission += msg.medal_level * 10; } if (msg.user_level) { permission += Math.round(msg.user_level * 0.1); } // console.log(`用户权限:${permission}`); switch (msg.text.split(' ')[0].split('*')[1]) { case 'admin': if ( permission >= CUTE_CONFIG.PERMISSION.author ) { CUTE_MODULE.danmaku.admin(msg); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.author} |・ω・`)` ); } break; case '配置': if ( permission >= CUTE_CONFIG.PERMISSION.admin ) { CUTE_MODULE.danmaku.command(msg); } else { return CUTE_MODULE.danmaku.queue_add( `拒绝执行!你的权限:${permission},需要:${CUTE_CONFIG .PERMISSION.admin} |・ω・`)` ); } break; case '功能': CUTE_MODULE.danmaku.cute(msg, permission); break; case '查询': CUTE_MODULE.danmaku.query(msg, permission); break; default: break; } } } catch (err) {} break; // 开播 case 'LIVE': try { if (typeof msg.roomid == 'number') { let startCtx = { 41682: `♥ 咕才是世界的常态……然而居然开播了|・ω・`)`, 70270: `♥ 啊,是我最喜欢的小狐妖开播了|・ω・`)`, 24589: `♥ 咕才是世界的常态……然而居然开播了|・ω・`)`, 64566: `♥ 第一次看直播,刚点进这个直播间就开播了|・ω・`)` }; if (startCtx[msg.roomid]) { CUTE_MODULE.danmaku.queue_add(startCtx[msg.roomid]); } CUTE_ROBOT.connect.common(); if ( window.Notification && Notification.permission !== 'denied' ) { Notification.requestPermission(function(status) { let notification = new Notification('真香警告', { body: CUTE_MODULE.tsFormatter( new Date().getTime() / 1000 ) + ' ' + CUTE_DATA.ROOM_INFO.uname + '出现了!我就是饿死也不会去看一眼!' }); notification.onclick = function() { window.open( 'https://live.bilibili.com/' + CUTE_DATA.ROOM_INFO.short_id ); }; }); } // $('#connect').click(); } } catch (err) {} break; // 上船 case 'GUARD_BUY': try { if (msg.price == 50000) { return CUTE_MODULE.danmaku.queue_add( `[一週間${msg.gift_name}] ${msg.username} 关于舰长的记忆只有一周(误` ); } else if ( CUTE_DATA.ROOM_INFO.guard_list.indexOf(msg.uid) != -1 ) { return CUTE_MODULE.danmaku.queue_add( `[续费${msg.gift_name}] ${msg.username} 一直续船一直爽!` ); } else { CUTE_DATA.ROOM_INFO.guard_list.push(msg.uid); CUTE_MODULE.danmaku.queue_add( `[新${msg.gift_name}] ${msg.username} 上船了,我地位-1!` ); setTimeout(() => { let whisperCtx = { // 631: `欢迎来到631海豹大舰队!舰长群:870309615 \\n若已加入请无视~`, 189: `感谢大佬登上狐妖的小船船!舰长群:568744231,欢迎来玩♡\\n若已加入请无视~`, 223: `感谢大佬登上可可的小船船!舰长群:88479489,欢迎加入♡\\n若已加入请无视~`, 64566: `跪谢老板٩(๑^o^๑)۶对猫猫的船票支持,解锁欢乐的舰长群(823316645)快来一起玩耍吧٩(๑^o^๑)۶\\n若已加入请无视~` }; if (whisperCtx[CUTE_DATA.ROOM_INFO.entry_id]) { CUTE_MODULE.whisper( msg.uid, msg.username, `{"content":"[${CUTE_MODULE.tsFormatter( new Date() / 1000 )}] ${whisperCtx[ CUTE_DATA.ROOM_INFO.entry_id ]}"}`, 'guard' ); } else { console.log(`这个直播间没有设置舰长群,不能发送私信|・ω・`)`); } }, 5e3); } } catch (err) {} break; default: break; } }; // 弹幕管理器(聊天模式 let CUTE_CHAT_MODE_MGR = msg => { console.log(msg.cmd); switch (msg.cmd) { // 特殊礼物刷屏 case 'SPECIAL_GIFT': try { if (msg.storm) { if (msg.storm_action == 'start') { CUTE_DATA.danmaku_filter.push(msg.storm_content); } else if (msg.storm_action == 'end') { } } } catch (e) { console.log('然而这并不是storm!'); } break; // 封禁提示 case 'ROOM_BLOCK_MSG': try { $.toast({ heading: '封禁提示', text: `${msg.block_uname}被制裁了`, hideAfter: false, stack: 20, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time icon: 'error', position: 'top-right', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values textAlign: 'left', // Text alignment i.e. left, right or center loader: false // Whether to show loader or not. True by default }); let scrollHeight = $('.jq-toast-wrap:first').prop( 'scrollHeight' ); $('.jq-toast-wrap:first').scrollTop(scrollHeight); } catch (error) {} break; case 'DANMU_MSG': case 'DANMU_MSG:4:0:2:2:2:0': try { CUTE_MODULE.danmaku.show(msg); } catch (error) {} break; default: console.log(msg.cmd); break; } }; CUTE_ROBOT.init(); window.onload = function() { // 延迟加载toast所需的js文件 // setTimeout(() => { // $('body').append( // `<script src="https://cdn.bootcss.com/jquery-toast-plugin/1.3.2/jquery.toast.min.js"></script>` // ); // }, 5e2); // 连接弹幕服务器并启用全部功能 $('#connect').on('click', e => { $('#connect').attr('disabled', true); // e.target.disabled.value = true; setTimeout(() => { $('#connect').attr('disabled', false); // e.target.disabled.value = false; }, 10e3); CUTE_ROBOT.connect.common(); }); // 休眠模式 $('#sleep_mode_connect').on('click', e => { // console.log(e); $('#sleep_mode_connect').attr('disabled', true); // e.target.disabled.value = true; setTimeout(() => { $('#sleep_mode_connect').attr('disabled', false); // e.target.disabled.value = false; }, 10e3); CUTE_ROBOT.connect.sleep_mode(); }); // 聊天模式 $('#chat_mode_connect').on('click', e => { // console.log(e); $('#chat_mode_connect').attr('disabled', true); // e.target.disabled.value = true; setTimeout(() => { $('#chat_mode_connect').attr('disabled', false); // e.target.disabled.value = false; }, 10e3); CUTE_ROBOT.connect.chat_mode(); }); // 断开弹幕服务器 $('#disconnect').on('click', () => { CUTE_ROBOT.disconnect(); }); // 循环广告 $('#intervalTime').blur(() => { CUTE_MODULE.ad.time(); }); $('#start').on('click', e => { CUTE_MODULE.ad.time(); CUTE_MODULE.ad.run(); }); $('#clear').on('click', CUTE_MODULE.ad.end); // 房间号输入 $('#room_entry').blur(() => { CUTE_DATA.ROOM_INFO.entry_id = $('#room_entry').val(); }); $('#room_entry').val(CUTE_DATA.ROOM_INFO.entry_id); // 打开直播间 $('#goToRoom').on('click', e => { window.open( 'https://live.bilibili.com/' + CUTE_DATA.ROOM_INFO.short_id ); }); // 更换弹幕颜色 $('.color').on('click', CUTE_MODULE.danmaku.color); // 弹幕发送 $('#danmu_send').keypress(CUTE_MODULE.danmaku.send); // 添加新的广告/关键词回复 $('#ad_new_submit').on('click', () => { CUTE_MODULE.ad.add(); }); $('#autoreply_add').on('click', () => { CUTE_MODULE.keyword.reply.add(); }); if (CUTE_MODULE.getUrlParam('reconnect')) { CUTE_ROBOT.reconnect(); } }; })();