// ==UserScript==
// @name B站直播自动抢辣条二代by十六夜
// @namespace http://tampermonkey.net/
// @version 6.3
// @description 我的我的 都是我的
// @author 逆回十六夜、SeaLoong
// @license MIT License
// @include /https?:\/\/live\.bilibili\.com\/\d+\??.*/
// @require https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js
// @require https://cdn.jsdelivr.net/gh/SeaLoong/Bilibili-LRHH/BilibiliAPI.js
// @require https://cdn.jsdelivr.net/gh/SeaLoong/Bilibili-LRHH/OCRAD.min.js
// ==/UserScript==
/*
[greasyfork源]
// @require https://greasyfork.org/scripts/38140-bilibiliapi/code/BilibiliAPI.js
// @require https://greasyfork.org/scripts/44866-ocrad/code/OCRAD.js(失效)
[github源]
// @require https://raw.githubusercontent.com/SeaLoong/Bilibili-LRHH/master/BilibiliAPI.js
// @require https://raw.githubusercontent.com/SeaLoong/Bilibili-LRHH/master/OCRAD.min.js
[gitee源]
// @require https://gitee.com/SeaLoong/Bilibili-LRHH/raw/master/BilibiliAPI.js
// @require https://gitee.com/SeaLoong/Bilibili-LRHH/raw/master/OCRAD.min.js
[腾讯云源]
// @require https://js-1258131272.file.myqcloud.com/BilibiliAPI.js
// @require https://js-1258131272.file.myqcloud.com/OCRAD.min.js
[jsDelivr源]
// @require https://cdn.jsdelivr.net/gh/SeaLoong/Bilibili-LRHH/BilibiliAPI.js
// @require https://cdn.jsdelivr.net/gh/SeaLoong/Bilibili-LRHH/OCRAD.min.js
[GitCDN源]
// @require https://gitcdn.xyz/repo/SeaLoong/Bilibili-LRHH/master/BilibiliAPI.js
// @require https://gitcdn.xyz/repo/SeaLoong/Bilibili-LRHH/master/OCRAD.min.js
*/
let logSwitch = false; //控制开关
let NAME = 'IZAYOI';
let BAPI;
let server_host;
if (!logSwitch) {
console.log = () => {
};//关闭控制台输出
}
let Info = {
roomId: undefined,
uid: undefined,
silver: undefined,
gold: undefined,
mobile_verify: undefined,
identification: undefined,
awardBlocked: undefined,
};
$(function () {//DOM完毕,等待弹幕加载完成
let loadInfo = (delay) => {
setTimeout(function () {
if (BilibiliLive === undefined || parseInt(BilibiliLive.UID) === 0 || isNaN(parseInt(BilibiliLive.UID))) {
loadInfo(1000);
console.log('无配置信息');
} else {
Info.roomId = BilibiliLive.ROOMID;
Info.uid = BilibiliLive.UID;
console.log(Info);
init();
}
}, delay);
};
loadInfo(1000);
addStyle();//加载style
});
Array.prototype.remove = function (val) {
let index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
function addStyle() {
$('head').append(`
<style>
.izayoi_input{
outline: none;
border: 1px solid #e9eaec;
background-color: #fff;
border-radius: 4px;
padding: 1px 0 0;
overflow: hidden;
font-size: 12px;
line-height: 19px;
width: 30px;
}
.izayoi_btn{
background-color: #23ade5;
color: #fff;
border-radius: 4px;
border: none;
padding: 5px;
cursor: pointer;
box-shadow: 0 0 2px #00000075;
}
.izayoi_fs{
border: 2px solid #d4d4d4;
}
</style>
`)
}
function init() {//API初始化
try {
BAPI = BilibiliAPI;
} catch (err) {
alert(`[${NAME}]BilibiliAPI初始化失败,请手动更改源`);
return;
}
BAPI.setCommonArgs(getCookie('bili_jct'), '');// 设置token
const get_room_info = BAPI.live_user.get_info_in_room(Info.roomId).then((response) => {
console.log('[直播间信息]', response);
Info.silver = response.data.wallet.silver;
Info.gold = response.data.wallet.gold;
Info.mobile_verify = response.data.info.mobile_verify;
Info.identification = response.data.info.identification;
});
const MY_API = {
CONFIG_DEFAULT: {
TIME_RELOAD: 60,
RANDOM_DELAY: true,
TIME_AREA_DISABLE: false,
TIME_AREA_START: 2,
TIME_AREA_END: 8,
RANDOM_SKIP: 0,
MAX_GIFT: 99999,
AUTO_TREASUREBOX: true,
AUTO_EXCHANGE: true,
AUTO_SIGNIN: true,
LINE_DELAY: 1,
TOP10_DELAY: 5,
GIFT_ROOM: 5050,
},
CONFIG: {},
GIFT_COUNT: {
COUNT: 0,
LOVE_COUNT: 0,
CLEAR_TS: 0,
EXCHANGE_TS: 0,
SIGN_TS: 0,
},
init: function () {
let p = $.Deferred();
try {
MY_API.loadConfig().then(function () {
MY_API.chatLog('脚本载入配置成功', 'success');
p.resolve()
});
} catch (e) {
console.log('API初始化出错', e);
MY_API.chatLog('脚本初始化出错', 'warning');
p.reject()
}
return p
},
loadConfig: function () {
let p = $.Deferred();
try {
let config = JSON.parse(localStorage.getItem(`${NAME}_CONFIG`));
$.extend(true, MY_API.CONFIG, MY_API.CONFIG_DEFAULT);
for (let item in MY_API.CONFIG) {
if (!MY_API.CONFIG.hasOwnProperty(item)) continue;
if (config[item] !== undefined && config[item] !== null) MY_API.CONFIG[item] = config[item];
}
MY_API.loadGiftCount();//载入礼物统计
p.resolve()
} catch (e) {
console.log('API载入配置失败,加载默认配置', e);
MY_API.setDefaults();
p.reject()
}
return p
},
saveConfig: function () {
try {
localStorage.setItem(`${NAME}_CONFIG`, JSON.stringify(MY_API.CONFIG));
MY_API.chatLog('配置已保存');
console.log(MY_API.CONFIG);
return true
} catch (e) {
console.log('API保存出错', e);
return false
}
},
setDefaults: function () {
MY_API.CONFIG = MY_API.CONFIG_DEFAULT;
MY_API.saveConfig();
MY_API.chatLog('配置已重置为默认3秒后刷新页面');
setTimeout(() => {
window.location.reload()
}, 3000);
},
loadGiftCount: function () {
try {
let config = JSON.parse(localStorage.getItem(`${NAME}_GIFT_COUNT`));
for (let item in MY_API.GIFT_COUNT) {
if (!MY_API.GIFT_COUNT.hasOwnProperty(item)) continue;
if (config[item] !== undefined && config[item] !== null) MY_API.GIFT_COUNT[item] = config[item];
}
console.log(MY_API.GIFT_COUNT);
} catch (e) {
console.log('读取统计失败', e);
}
},
saveGiftCount: function () {
try {
localStorage.setItem(`${NAME}_GIFT_COUNT`, JSON.stringify(MY_API.GIFT_COUNT));
console.log('统计保存成功', MY_API.GIFT_COUNT);
return true
} catch (e) {
console.log('统计保存出错', e);
return false
}
},
addGift: function (count) {
MY_API.GIFT_COUNT.COUNT += count;
$('#giftCount span:eq(0)').text(MY_API.GIFT_COUNT.COUNT);
MY_API.saveGiftCount();
},
addLove: function (count) {
MY_API.GIFT_COUNT.LOVE_COUNT += count;
$('#giftCount span:eq(1)').text(MY_API.GIFT_COUNT.LOVE_COUNT);
MY_API.saveGiftCount();
},
creatSetBox: function () {//创建设置框
//添加按钮
let btn = $('<button style="position: absolute; top: 128px; left: 0;z-index: 10;background-color: #23ade5;color: #fff;border-radius: 4px;border: none;padding: 5px;cursor: pointer;box-shadow: 1px 1px 2px #00000075;">' +
'隐藏当前抽奖信息<br>(抽奖会继续 不影响)</button>');
btn.click(function () {
$('.izayoiMsg').hide();
});
$('.chat-history-panel').append(btn);
let div = $('<div>');
div.css({
'width': '400px',
'height': '54px',
'position': 'absolute',
'top': '110px',
'right': '10px',
'background': '#F0F0F0',
'padding': '10px',
'z-index': '10',
'border-radius': '4px',
'overflow': 'hidden',
'box-shadow': '1px 1px 2px #00000075',
});
div.on('mouseover mouseout', '', function (e) {
if (e.type === 'mouseover') {
$(this).css('height', 'auto');
} else {
$(this).css('height', '54px');
}
});
div.append(`
<fieldset class="izayoi_fs">
<legend>今日统计</legend>
<div id="giftCount" style="font-size: large; text-shadow: 1px 1px #00000066; color: blueviolet;">
辣条·<span>${MY_API.GIFT_COUNT.COUNT}</span>
<button class="izayoi_btn" style="font-size: small" data-action="countReset">重置统计(会刷新页面)</button>
</div>
</fieldset>
<fieldset class="izayoi_fs">
<legend>瓜子及签到</legend>
<div data-toggle="AUTO_SIGNIN">
<label style="cursor: pointer; margin: 5px auto;">
<input style="vertical-align: text-top;" type="checkbox">自动签到
</label>
</div>
<div data-toggle="AUTO_EXCHANGE">
<label style="cursor: pointer; margin: 5px auto;">
<input style="vertical-align: text-top;" type="checkbox">自动银瓜子换硬币(一天一个)
</label>
</div>
<div data-toggle="AUTO_TREASUREBOX">
<label style="cursor: pointer; margin: 5px auto;">
<input style="vertical-align: text-top;" type="checkbox">自动领瓜子(°∀°)ノ
</label>
</div>
</fieldset>
<fieldset class="izayoi_fs">
<legend>低调设置(不要问我会不会降低小黑屋概率,我也不知道)</legend>
<div data-toggle="RANDOM_DELAY">
<label style="cursor: pointer; margin: 5px auto;">
<input style="vertical-align: text-top;" type="checkbox">抽奖附加随机延迟3~10s(加在倒计时时间里)
</label>
</div>
<div data-toggle="TIME_AREA_DISABLE">
<label style="cursor: pointer; margin: 5px auto;">
<input style="vertical-align: text-top;" type="checkbox">启用
<input class="start izayoi_input" style="width: 20px;" type="text">点至
<input class="end izayoi_input" style="width: 20px;" type="text">点不抽奖(24小时制)
<button data-action="save" class="izayoi_btn">保存</button>
</label>
</div>
<div data-toggle="RANDOM_SKIP">
<label style="cursor: pointer; margin: 5px auto;">
随机跳过礼物(整数1到100 设置为0则不跳过)<input class="per izayoi_input" style="width: 20px;" type="text">%
</label>
<button data-action="save" class="izayoi_btn">保存</button>
</div>
<div data-toggle="MAX_GIFT">
<label style="cursor: pointer; margin: 5px auto;">
当天最多抢辣条数量(整数)<input class="num izayoi_input" style="width: 40px;" type="text">
</label>
<button data-action="save" class="izayoi_btn">保存</button>
<div>↑此功能想法来自
<a href="https://space.bilibili.com/25296686" target="_blank">1183729</a>↑
</div>
</div>
<div data-toggle="TOP10_DELAY">
<label style="cursor: pointer; margin: 5px auto;">
检查小时榜时间间隔(单位分 整数)<input class="DELAY izayoi_input" style="width: 20px;" type="text">
</label>
<button data-action="save" class="izayoi_btn">保存</button>
</div>
<div data-toggle="LINE_DELAY">
<label style="cursor: pointer; margin: 5px auto;">
排队抽奖延迟(单位秒 精确到小数点一位 设置为0则不排队)<input class="DELAY izayoi_input" style="width: 20px;" type="text">
</label>
<button data-action="save" class="izayoi_btn">保存</button>
<div>↑此功能想法来自
<a href="https://space.bilibili.com/100645823" target="_blank">叔和牌湯湯</a>↑
</div>
</div>
<div data-toggle="GIFT_ROOM">
<label style="cursor: pointer; margin: 5px auto; color: blue">
自动赠送所有只剩1天礼物房间号<input class="ID izayoi_input" style="width: 50px;" type="text">
</label>
<button data-action="save" class="izayoi_btn">保存</button>
<br>↑(23:50后赠送 设置为0则不启用)↑
</div>
</fieldset>
<fieldset class="izayoi_fs">
<legend>其他设置</legend>
<div data-toggle="TIME_RELOAD">
本直播间重载时间(整数 刷新后生效 别设置成0):
<input class="delay-seconds izayoi_input" type="text" style="width: 30px;">分
<button data-action="save" class="izayoi_btn">保存</button>
</div>
<div><button data-action="reset" style="color: red;" class="izayoi_btn">重置所有为默认</button></div>
</fieldset>
<fieldset class="izayoi_fs">
<legend>说明</legend>
<span style="color: rgb(255,0,2);">排队抽奖可以防止同一时间抽取多个礼物,一个一个慢慢抽,数值设置太大可能会导致同一时间礼物数量
很多时抽不到后面的礼物</span><br>
<span style="color: rgb(79,178,255);">直播间重载目的是防止页面崩溃以及弹幕监听新的在线直播间</span><br>
<span style="color: rebeccapurple">
请求式会监听所有分区能抢所有分区会广播的礼物,不会广播的礼物也能从同一直播间或者小时榜上的直播间顺带抢一部分,如舰长、提督、PK</span><br>
<span style="color: #a8076c">礼物信息现在保存在浏览器缓存,出现重复领取的现象大大降低</span><br>
<span style="color: #e600ff">如果你发现突然多了10w银瓜子,那么恭喜你中奖了</span><br>
<span style="color: #770080;">如果使用请求式抢礼物,无需开启刷小时榜,开这个直播间就够了</span><br>
<span style="color: red;">如果你不知道如何设置重置为默认即可</span><br>
<span style="color: #488e1d;">如果脚本载入配置成功后没有提示连接弹幕服务器成功的话,尝试换浏览器更新浏览器及插件至最新</span><br>
<span style="color: #d58fff;">我语文不好如果没解释清楚,你他妈来打我呀</span><br>
</fieldset>
<fieldset class="izayoi_fs">
<legend>更新</legend>
<ul>
<li><span style="color: rgb(79,178,255);">7-2:添加自动赠送快过期辣条功能,排队功能优化,添加六个分区小时榜检查,能领到的舰长变多了</span></li>
<li><span style="color: rgb(79,178,255);">6-27:删除轮刷小时榜旧功能(总有人把这个打开然后跟我说脚本发神经了,反正没什么用就删了)、添加
排队抽奖、自定义检查小时榜间隔</span></li>
<li><span style="color: rgb(79,178,255);">6-8:添加自动领取瓜子、自动签到、自动换硬币,代码优化,时间段优化支持跨日</span></li>
<li><span style="color: rgb(79,178,255);">5-19:修复辣条统计(好像现在上船没有亲密度了),添加伪造直播间进入记录,优化辣条限制功能逻辑</span></li>
</ul>
</fieldset>
`);
$('.player-ctnr').append(div);
let checkList = [
'RANDOM_DELAY',
'AUTO_SIGNIN',
'AUTO_EXCHANGE',
'AUTO_TREASUREBOX',
'TIME_AREA_DISABLE',
];
for (let i of checkList) {//所有checkbox事件绑定
let input = div.find(`div[data-toggle="${i}"] input:checkbox`);
if (MY_API.CONFIG[i]) input.attr('checked', '');
input.change(function () {
MY_API.CONFIG[i] = $(this).prop('checked');
MY_API.saveConfig()
});
}
//对应配置状态
div.find('div[data-toggle="TIME_RELOAD"] .delay-seconds').val(MY_API.CONFIG.TIME_RELOAD.toString());
div.find('div[data-toggle="RANDOM_SKIP"] .per').val((parseInt(MY_API.CONFIG.RANDOM_SKIP)).toString());
div.find('div[data-toggle="MAX_GIFT"] .num').val((parseInt(MY_API.CONFIG.MAX_GIFT)).toString());
div.find('div[data-toggle="TIME_AREA_DISABLE"] .start').val(MY_API.CONFIG.TIME_AREA_START.toString());
div.find('div[data-toggle="TIME_AREA_DISABLE"] .end').val(MY_API.CONFIG.TIME_AREA_END.toString());
div.find('div[data-toggle="TOP10_DELAY"] .DELAY').val(MY_API.CONFIG.TOP10_DELAY.toString());
div.find('div[data-toggle="LINE_DELAY"] .DELAY').val(MY_API.CONFIG.LINE_DELAY.toString());
div.find('div[data-toggle="GIFT_ROOM"] .ID').val(MY_API.CONFIG.GIFT_ROOM.toString());
//事件绑定
div.find('div[data-toggle="GIFT_ROOM"] [data-action="save"]').click(function () {//GIFT_ROOM save按钮
let val = parseInt(div.find('div[data-toggle="GIFT_ROOM"] .ID').val());
if (MY_API.CONFIG.GIFT_ROOM === val) {
MY_API.chatLog('改都没改保存尼玛呢');
return
}
if (val === 0) {
MY_API.CONFIG.GIFT_ROOM = val;
MY_API.saveConfig()
} else {
BAPI.live_user.get_anchor_in_room(val).then(function (roomResult) {
if (roomResult.code === 0) {
MY_API.chatLog(`提示:该房间主播是${roomResult.data.info.uname}`);
MY_API.CONFIG.GIFT_ROOM = val;
MY_API.saveConfig()
} else {
MY_API.chatLog('检查出错,你确定是正确房间ID?');
}
});
}
});
div.find('div[data-toggle="TOP10_DELAY"] [data-action="save"]').click(function () {//TOP10_DELAY save按钮
let val = parseInt(div.find('div[data-toggle="TOP10_DELAY"] .DELAY').val());
if (MY_API.CONFIG.TOP10_DELAY === val) {
MY_API.chatLog('改都没改保存尼玛呢');
return
}
MY_API.CONFIG.TOP10_DELAY = val;
MY_API.saveConfig()
});
div.find('div[data-toggle="LINE_DELAY"] [data-action="save"]').click(function () {//LINE_DELAY save按钮
let val = parseFloat(div.find('div[data-toggle="LINE_DELAY"] .DELAY').val()).toFixed(1);
if (MY_API.CONFIG.LINE_DELAY === val) {
MY_API.chatLog('改都没改保存尼玛呢');
return
}
MY_API.CONFIG.LINE_DELAY = val;
MY_API.saveConfig()
});
div.find('div[data-toggle="RANDOM_SKIP"] [data-action="save"]').click(function () {//RANDOM_SKIP save按钮
let val = parseInt(div.find('div[data-toggle="RANDOM_SKIP"] .per').val());
if (MY_API.CONFIG.RANDOM_SKIP === val) {
MY_API.chatLog('改都没改保存尼玛呢');
return
}
MY_API.CONFIG.RANDOM_SKIP = val;
MY_API.saveConfig()
});
div.find('div[data-toggle="MAX_GIFT"] [data-action="save"]').click(function () {//MAX_GIFT save按钮
let val = parseInt(div.find('div[data-toggle="MAX_GIFT"] .num').val());
if (MY_API.CONFIG.MAX_GIFT === val) {
MY_API.chatLog('改都没改保存尼玛呢');
return
}
MY_API.CONFIG.MAX_GIFT = val;
MY_API.saveConfig()
});
div.find('button[data-action="reset"]').click(function () {//重置按钮
MY_API.setDefaults();
});
div.find('div[data-toggle="TIME_RELOAD"] [data-action="save"]').click(function () {//TIME_RELOAD save按钮
let val = parseInt(div.find('div[data-toggle="TIME_RELOAD"] .delay-seconds').val());
if (MY_API.CONFIG.TIME_RELOAD === val) {
MY_API.chatLog('改都没改保存尼玛呢');
return
}
if (val <= 0 || val > 10000) {
MY_API.chatLog('你咋不上天呢');
return
}
MY_API.CONFIG.TIME_RELOAD = val;
MY_API.saveConfig()
});
div.find('div[data-toggle="TIME_AREA_DISABLE"] [data-action="save"]').click(function () {//
MY_API.CONFIG.TIME_AREA_START = parseInt(div.find('div[data-toggle="TIME_AREA_DISABLE"] .start').val());
MY_API.CONFIG.TIME_AREA_END = parseInt(div.find('div[data-toggle="TIME_AREA_DISABLE"] .end').val());
MY_API.saveConfig()
});
div.find('#giftCount [data-action="countReset"]').click(function () {//
MY_API.GIFT_COUNT = {
COUNT: 0,
LOVE_COUNT: 0,
CLEAR_TS: 0,
};
MY_API.saveGiftCount();
MY_API.chatLog('已清空3秒后刷新页面');
setTimeout(() => {
window.location.reload()
}, 3000);
});
},
chatLog: function (text, type = 'info') {//自定义提示
let div = $("<div class='izayoiMsg'>");
let msg = $("<div>");
let ct = $('#chat-history-list');
let myDate = new Date();
msg.html(text);
div.text(myDate.toLocaleString());
div.append(msg);
div.css({
'text-align': 'center',
'border-radius': '4px',
'min-height': '30px',
'width': '256px',
'color': '#9585FF',
'line-height': '30px',
'padding': '0 10px',
'margin': '10px auto',
});
msg.css({
'word-wrap': 'break-word',
'width': '100%',
'line-height': '1em',
'margin-bottom': '10px',
});
switch (type) {
case 'warning':
div.css({
'border': '1px solid rgb(236, 221, 192)',
'color': 'rgb(218, 142, 36)',
'background': 'rgb(245, 235, 221) none repeat scroll 0% 0%',
});
break;
case 'success':
div.css({
'border': '1px solid rgba(22, 140, 0, 0.28)',
'color': 'rgb(69, 171, 69)',
'background': 'none 0% 0% repeat scroll rgba(16, 255, 0, 0.18)',
});
break;
case 'error':
div.css({
'border': '1px solid rgba(255, 0, 39, 0.28)',
'color': 'rgb(116,0,15)',
'background': 'none 0% 0% repeat scroll rgba(255, 0, 39, 0.18)',
});
break;
default:
div.css({
'border': '1px solid rgb(203, 195, 255)',
'background': 'rgb(233, 230, 255) none repeat scroll 0% 0%',
});
}
ct.find('#chat-items').append(div);//向聊天框加入信息
ct.scrollTop(ct.prop("scrollHeight"));//滚动到底部
},
blocked: false,
max_blocked: false,
listen: (roomId, uid, area = '本直播间') => {
BAPI.room.getConf(roomId).then((response) => {
server_host = response.data.host;
console.log('服务器地址', response);
let wst = new BAPI.DanmuWebSocket(uid, roomId, response.data.host_server_list, response.data.token);
wst.bind((newWst) => {
wst = newWst;
MY_API.chatLog(`${area}弹幕服务器连接断开,尝试重连`, 'warning');
}, () => {
MY_API.chatLog(`连接弹幕服务器成功<br>房间号: ${roomId} 分区: ${area}`
, 'success');
}, () => {
if (MY_API.blocked) {
wst.close();
MY_API.chatLog(`进了小黑屋主动与弹幕服务器断开连接-${area}`, 'warning')
}
if (MY_API.max_blocked) {
wst.close();
MY_API.chatLog(`辣条最大值主动与弹幕服务器断开连接-${area}`, 'warning')
}
}, (obj) => {
if (inTimeArea(MY_API.CONFIG.TIME_AREA_START, MY_API.CONFIG.TIME_AREA_END) && MY_API.CONFIG.TIME_AREA_DISABLE) return;//当前是否在两点到八点 如果在则返回
console.log('弹幕公告' + area, obj);
switch (obj.cmd) {
case 'GUARD_MSG':
if (obj.roomid === obj.real_roomid) {
MY_API.checkRoom(obj.roomid, area);
} else {
MY_API.checkRoom(obj.roomid, area);
MY_API.checkRoom(obj.real_roomid, area);
}
break;
case 'PK_BATTLE_SETTLE_USER':
if (!!obj.data.winner) {
MY_API.checkRoom(obj.data.winner.room_id, area);
} else {
MY_API.checkRoom(obj.data.my_info.room_id, area);
}
break;
case 'NOTICE_MSG':
if (obj.roomid === obj.real_roomid) {
MY_API.checkRoom(obj.roomid, area);
} else {
MY_API.checkRoom(obj.roomid, area);
MY_API.checkRoom(obj.real_roomid, area);
}
break;
default:
return;
}
});
}, () => {
MY_API.chatLog('获取弹幕服务器地址错误', 'warning')
});
},
RoomId_list: [],
err_roomId: [],
checkRoom: function (roomId, area = '本直播间') {
if (roomId === undefined) return;
if (MY_API.blocked || MY_API.max_blocked) {
return
}
if (MY_API.RoomId_list.indexOf(roomId) >= 0) {//防止重复检查直播间
return
} else {
MY_API.RoomId_list.push(roomId);
}
BAPI.room.room_entry_action(roomId);//直播间进入记录
$.get('https://api.live.bilibili.com/xlive/lottery-interface/v1/lottery/Check?roomid=' + roomId,
function (re) {
setTimeout(() => {
MY_API.RoomId_list.remove(roomId);//移除房间号
// console.log('防重复检查房间号列表', MY_API.RoomId_list);
}, 5e3);
console.log('检查房间返回信息', re);
let data = re.data;
if (re.code === 0) {
let list;
if (data.gift) {
list = data.gift;
for (let i in list) {
if (!list.hasOwnProperty(i)) continue;
MY_API.creat_join(roomId, list[i], 'gift', area)
}
}
if (data.guard) {
list = data.guard;
for (let i in list) {
if (!list.hasOwnProperty(i)) continue;
MY_API.creat_join(roomId, list[i], 'guard', area)
}
}
if (data.pk) {
list = data.pk;
for (let i in list) {
if (!list.hasOwnProperty(i)) continue;
MY_API.creat_join(roomId, list[i], 'pk', area)
}
}
} else {
if (MY_API.err_roomId.indexOf(roomId) > -1) {
console.log(`[检查此房间出错多次]${roomId}${re.message}`);
} else {
MY_API.err_roomId.push(roomId);
MY_API.checkRoom(roomId, area);
console.log(`[检查房间出错_重试一次]${roomId}${re.message}`);
}
}
});
},
Id_list_history: {
add: function (id, type) {
let id_list = [];
try {
let config = JSON.parse(localStorage.getItem(`${NAME}_${type}Id_list`));
id_list = [].concat(config.list);
id_list.push(id);
if (id_list.length > 200) {
id_list.splice(0, 50);//删除前50条数据
}
localStorage.setItem(`${NAME}_${type}Id_list`, JSON.stringify({list: id_list}));
console.log(`${NAME}_${type}Id_list_add`, id_list);
} catch (e) {
id_list.push(id);
localStorage.setItem(`${NAME}_${type}Id_list`, JSON.stringify({list: id_list}));
}
},
isIn: function (id, type) {
let id_list = [];
try {
let config = JSON.parse(localStorage.getItem(`${NAME}_${type}Id_list`));
if (config === null) {
id_list = [];
} else {
id_list = [].concat(config.list);
}
console.log(`${NAME}_${type}Id_list_read`, config);
return id_list.indexOf(id) > -1
} catch (e) {
localStorage.setItem(`${NAME}_${type}Id_list`, JSON.stringify({list: id_list}));
console.log('读取' + `${NAME}_${type}Id_list` + '缓存错误已重置');
return id_list.indexOf(id) > -1
}
}
},
raffleId_list: [],
guardId_list: [],
pkId_list: [],
creat_join: function (roomId, data, type, area = '本直播间') {
console.log('礼物信息', data);
if (MY_API.GIFT_COUNT.COUNT >= MY_API.CONFIG.MAX_GIFT) {//判断是否超过辣条限制
console.log('超过今日辣条限制,不参与抽奖');
MY_API.max_blocked = true;
return
}
switch (type) {//防止重复抽奖上船PK
case 'gift':
if (MY_API.Id_list_history.isIn(data.raffleId, 'raffle')) {
console.log('礼物重复');
return
} else {
MY_API.raffleId_list.push(data.raffleId);
MY_API.Id_list_history.add(data.raffleId, 'raffle');
}
break;
case 'guard':
if (MY_API.Id_list_history.isIn(data.id, 'guard')) {
console.log('舰长重复');
return
} else {
MY_API.guardId_list.push(data.id);
MY_API.Id_list_history.add(data.id, 'guard');
}
break;
case 'pk':
if (MY_API.Id_list_history.isIn(data.id, 'pk')) {
console.log('pk重复');
return
} else {
MY_API.pkId_list.push(data.id);
MY_API.Id_list_history.add(data.id, 'pk');
}
break;
}
let delay = data.time_wait || 0;
if (MY_API.CONFIG.RANDOM_DELAY) delay += 2 + Math.ceil(Math.random() * 8);//随机延迟
let div = $("<div class='izayoiMsg'>");
let msg = $("<div>");
let aa = $("<div>");
let ct = $('#chat-history-list');
let myDate = new Date();
msg.text(`[${area}]` + data.thank_text.split('<%')[1].split('%>')[0] + data.thank_text.split('%>')[1]);
div.text(myDate.toLocaleString());
div.append(msg);
aa.css('color', 'red');
msg.append(aa);
div.css({
'text-align': 'center',
'border-radius': '4px',
'min-height': '30px',
'width': '256px',
'color': '#9585FF',
'line-height': '30px',
'padding': '0 10px',
'margin': '10px auto',
});
msg.css({
'word-wrap': 'break-word',
'width': '100%',
'line-height': '1em',
'margin-bottom': '10px',
});
div.css({
'border': '1px solid rgb(203, 195, 255)',
'background': 'rgb(233, 230, 255) none repeat scroll 0% 0%',
});
ct.find('#chat-items').append(div);//向聊天框加入信息
ct.scrollTop(ct.prop("scrollHeight"));//滚动到底部
let run = () => {
aa.text(`等待抽奖倒计时${delay}秒`);
if (delay <= 0) {
if (probability(MY_API.CONFIG.RANDOM_SKIP)) {
aa.text(`跳过此礼物抽奖`);
} else {
switch (type) {
case 'gift':
MY_API.lineUpCall(aa, MY_API.gift_join, roomId, data.raffleId, data.type).then(function (msg, num) {
aa.css('color', 'green');
aa.text('获得' + msg);
if (num) {
if (msg.indexOf('辣条') > -1) {
MY_API.addGift(num);
} else if (msg.indexOf('亲密度') > -1) {
MY_API.addLove(num);
}
}
MY_API.raffleId_list.remove(data.raffleId);//移除礼物id列表
});
break;
case 'guard':
MY_API.lineUpCall(aa, MY_API.guard_join, roomId, data.id).then(function (msg, num) {
aa.css('color', 'green');
aa.text('获得' + msg);
if (num) {
if (msg.indexOf('辣条') > -1) {
MY_API.addGift(num);
} else if (msg.indexOf('亲密度') > -1) {
MY_API.addLove(num);
}
}
MY_API.guardId_list.remove(data.id);//移除礼物id列表
});
break;
case 'pk':
MY_API.lineUpCall(aa, MY_API.pk_join, roomId, data.id).then(function (msg, num) {
aa.css('color', 'green');
aa.text('获得' + msg);
if (num) {
if (msg.indexOf('辣条') > -1) {
MY_API.addGift(num);
} else if (msg.indexOf('亲密度') > -1) {
MY_API.addLove(num);
}
}
MY_API.pkId_list.remove(data.id);//移除礼物id列表
});
break;
}
}
clearInterval(timer)
}
delay--;
};
let timer = setInterval(run, 1000);
run();
},
gift_join: function (roomid, raffleId, type) {
let p = $.Deferred();
BAPI.Lottery.Gift.join(roomid, raffleId, type).then((response) => {
console.log('抽奖返回信息', response);
switch (response.code) {
case 0:
if (response.data.award_text) {
p.resolve(response.data.award_text, response.data.award_num);
} else {
p.resolve(response.data.award_name + 'X' + response.data.award_num.toString()
, response.data.award_num);
}
break;
default:
if (response.msg.indexOf('拒绝') > -1) {
MY_API.blocked = true;//停止抽奖
p.resolve('访问被拒绝,您的帐号可能已经被关小黑屋,已停止');
} else {
p.resolve(`[礼物抽奖](roomid=${roomid},id=${raffleId},type=${type})${response.msg}`);
}
}
});
return p
},
guard_join: function (roomid, Id) {
let p = $.Deferred();
BAPI.Lottery.Guard.join(roomid, Id).then((response) => {
console.log('上船抽奖返回信息', response);
switch (response.code) {
case 0:
if (response.data.award_text) {
p.resolve(response.data.award_text, response.data.award_num);
} else {
p.resolve(response.data.award_name + 'X' + response.data.award_num.toString()
, response.data.award_num);
}
break;
default:
if (response.msg.indexOf('拒绝') > -1) {
MY_API.blocked = true;//停止抽奖
p.resolve('访问被拒绝,您的帐号可能已经被关小黑屋,已停止');
} else {
p.resolve(`[上船](roomid=${roomid},id=${Id})${response.msg}`);
}
break;
}
});
return p
},
pk_join: function (roomid, Id) {
let p = $.Deferred();
BAPI.Lottery.Pk.join(roomid, Id).then((response) => {
console.log('PK抽奖返回信息', response);
switch (response.code) {
case 0:
if (response.data.award_text) {
p.resolve(response.data.award_text, response.data.award_num);
} else {
p.resolve(response.data.award_name + 'X' + response.data.award_num.toString()
, response.data.award_num);
}
break;
default:
if (response.msg.indexOf('拒绝') > -1) {
MY_API.blocked = true;//停止抽奖
p.resolve('访问被拒绝,您的帐号可能已经被关小黑屋,已停止');
} else {
p.resolve(`[PK](roomid=${roomid},id=${Id})${response.msg}`);
}
break;
}
});
return p
},
Exchange: {
run: () => {
try {
return MY_API.Exchange.silver2coin().then(() => {
}, () => delayCall(() => MY_API.Exchange.run()));
} catch (err) {
MY_API.chatLog('[银瓜子换硬币]运行时出现异常,已停止', 'error');
console.error(`[${NAME}]`, err);
return $.Deferred().reject();
}
},
silver2coin: () => {
return BAPI.Exchange.silver2coin().then((response) => {
console.log('Exchange.silver2coin: API.SilverCoinExchange.silver2coin', response);
if (response.code === 0) {
// 兑换成功
MY_API.chatLog(`[银瓜子换硬币]${response.msg}`, 'success');
} else if (response.code === 403) {
// 每天最多能兑换 1 个
// 银瓜子余额不足
MY_API.chatLog(`[银瓜子换硬币]${response.msg}`, 'info');
} else {
MY_API.chatLog(`[银瓜子换硬币]${response.msg}`, 'caution');
}
}, () => {
MY_API.chatLog('[银瓜子换硬币]兑换失败,请检查网络', 'error');
return delayCall(() => MY_API.Exchange.silver2coin());
});
}
},
lineList: [],
lineDelay: 0,
reSetDelay: function () {
this.lineDelay = this.CONFIG.LINE_DELAY;
let timer = setInterval(() => {
if (this.lineDelay > 0.15) {
this.lineDelay -= 0.1;
} else {
this.lineDelay = 0;
clearInterval(timer);
}
}, 100)
},
lineUpCall: function (div, fun, arg1, arg2, arg3, arg4, arg5, arg6) {
let p = $.Deferred();
let delayRunTimer;
let delayRun = () => {
if (this.lineDelay === 0) {
run();
} else {
delayRunTimer = setInterval(() => {
if (this.lineDelay === 0) {
run();
clearInterval(delayRunTimer);
} else {
div.css('color', '#b700ff');
div.text(`抽奖等待中...${this.lineDelay.toFixed(1)}S`);
}
}, 100)
}
};
let run = () => {
this.lineList.shift();//删除第一个
this.reSetDelay();//重置冷却
div.text(`进行抽奖...`);
let funRt = fun(arg1, arg2, arg3, arg4, arg5, arg6);
if (funRt && funRt.then) funRt.then((arg1, arg2, arg3, arg4, arg5, arg6) => p.resolve(arg1, arg2, arg3, arg4, arg5, arg6));
else p.resolve();
if (this.lineList.length !== 0) this.lineList[0]();
};
if (this.CONFIG.LINE_DELAY === 0) {//如果为延迟0则直接运行
run();
} else if (this.lineList.length === 0) {
this.lineList.push(delayRun);
delayRun();
} else {
this.lineList.push(delayRun);
div.css('color', '#00b5e5');
div.text(`排队中...`);
}
return p
},
sendBagGift: function () {
BAPI.gift.bag_list().then(function (bagResult) {
if (bagResult.data.list[0].corner_mark === '1天' && bagResult.data.list[0].gift_name === '辣条') {
BAPI.live_user.get_anchor_in_room(MY_API.CONFIG.GIFT_ROOM).then(function (roomResult) {
bagSend(roomResult.data.info.uid,
bagResult.data.list[0].gift_id,
bagResult.data.list[0].bag_id,
bagResult.data.list[0].gift_num)
});
}
});
let bagSend = (rUid, gift_id, bag_id, num) => {
let ts = Math.round(new Date() / 1000);//时间戳
BAPI.gift.bag_send(Info.uid, gift_id, rUid, num, bag_id, MY_API.CONFIG.GIFT_ROOM, ts).then(function (result) {
if (result.code === 0 && result.msg === 'success') {
MY_API.chatLog('[只剩1天辣条]' + result.data.send_tips, 'success');
} else {
MY_API.chatLog('[礼物]赠送失败', 'warning');
}
});
}
},
};
const runUntilSucceed = (callback, delay = 0, period = 100) => {
setTimeout(() => {
if (!callback()) runUntilSucceed(callback, period, period);
}, delay);
};
const ts_s = () => Math.round(ts_ms() / 1000);
const ts_ms = () => Date.now();
const delayCall = (callback, delay = 10e3) => {
const p = $.Deferred();
setTimeout(() => {
const t = callback();
if (t && t.then) t.then((arg1, arg2, arg3, arg4, arg5, arg6) => p.resolve(arg1, arg2, arg3, arg4, arg5, arg6));
else p.resolve();
}, delay);
return p;
};
const TreasureBox = {
timer: undefined,
time_end: undefined,
time_start: undefined,
promise: {
calc: undefined,
timer: undefined
},
DOM: {
image: undefined,
canvas: undefined,
div_tip: undefined,
div_timer: undefined,
tp: undefined,
},
init: () => {
if (!MY_API.CONFIG.AUTO_TREASUREBOX) return $.Deferred().resolve();
const p = $.Deferred();
runUntilSucceed(() => {
try {
let treasure_box = $('#gift-control-vm div.treasure-box.p-relative');
if (!treasure_box.length) return false;
treasure_box = treasure_box.first();
treasure_box.attr('id', 'old_treasure_box');
treasure_box.hide();
const div = $(`<div id="${NAME}_treasure_div" class="treasure-box p-relative" style="min-width: 46px;display: inline-block;float: left;padding: 0px 0 0 15px;"></div>`);
TreasureBox.DOM.div_tip = $(`<div id="${NAME}_treasure_div_tip" class="t-center b-box none-select">领取中</div>`);
TreasureBox.DOM.tp = $(`<img src="https://i0.hdslb.com/bfs/article/d40ff17d533047cbb9b2bed4feb927cb0e71901c.gif" height="60" width="60" >`);
TreasureBox.DOM.div_timer = $(`<div id="${NAME}_treasure_div_timer" class="t-center b-box none-select">0</div>`);
TreasureBox.DOM.image = $(`<img id="${NAME}_treasure_image" style="display:none">`);
TreasureBox.DOM.canvas = $(`<canvas id="${NAME}_treasure_canvas" style="display:none" height="40" width="120"></canvas>`);
const css_text = 'min-width: 40px;padding: 2px 3px;margin-top: 3px;font-size: 12px;color: #23ade6;background-color: rgba(0, 180, 255, .3);border-radius: 10px;';
TreasureBox.DOM.div_tip[0].style = css_text;
TreasureBox.DOM.div_timer[0].style = css_text;
div.append(TreasureBox.DOM.tp);
div.append(TreasureBox.DOM.div_tip);
div.append(TreasureBox.DOM.image);
div.append(TreasureBox.DOM.canvas);
TreasureBox.DOM.div_tip.after(TreasureBox.DOM.div_timer);
treasure_box.after(div);
if (!Info.mobile_verify) {
TreasureBox.setMsg('未绑定<br>手机');
MY_API.chatLog('[自动领取瓜子]未绑定手机,已停止');
p.resolve();
return true;
}
try {
if (OCRAD) ;
} catch (err) {
TreasureBox.setMsg('初始化<br>失败');
MY_API.chatLog('[自动领取瓜子]OCRAD初始化失败,请检查网络更换OCRAD源', 'error');
console.error(`[${NAME}]`, err);
p.resolve();
return true;
}
TreasureBox.timer = setInterval(() => {
let t = parseInt(TreasureBox.DOM.div_timer.text(), 10);
if (isNaN(t)) t = 0;
if (t > 0) TreasureBox.DOM.div_timer.text(`${t - 1}s`);
else TreasureBox.DOM.div_timer.hide();
}, 1e3);
TreasureBox.DOM.image[0].onload = () => {
// 实现功能类似 https://github.com/zacyu/bilibili-helper/blob/master/src/bilibili_live.js 中Live.treasure.init()的验证码处理部分
const ctx = TreasureBox.DOM.canvas[0].getContext('2d');
ctx.font = '40px agencyfbbold';
ctx.textBaseline = 'top';
ctx.clearRect(0, 0, TreasureBox.DOM.canvas[0].width, TreasureBox.DOM.canvas[0].height);
ctx.drawImage(TreasureBox.DOM.image[0], 0, 0);
const grayscaleMap = TreasureBox.captcha.OCR.getGrayscaleMap(ctx);
const filterMap = TreasureBox.captcha.OCR.orderFilter2In3x3(grayscaleMap);
ctx.clearRect(0, 0, 120, 40);
for (let i = 0; i < filterMap.length; ++i) {
const gray = filterMap[i];
ctx.fillStyle = `rgb(${gray}, ${gray}, ${gray})`;
ctx.fillRect(i % 120, Math.round(i / 120), 1, 1);
}
try {
const question = TreasureBox.captcha.correctQuestion(OCRAD(ctx.getImageData(0, 0, 120, 40)));
console.log('TreasureBox.DOM.image.load', 'question =', question);
const answer = TreasureBox.captcha.eval(question);
console.log('TreasureBox.DOM.image.load', 'answer =', answer);
if (answer !== undefined) {
// chatLog(`[自动领取瓜子]验证码识别结果: ${question} = ${answer}`, 'info');
console.info(`[${NAME}][自动领取瓜子]验证码识别结果: ${question} = ${answer}`);
TreasureBox.promise.calc.resolve(answer);
}
} catch (err) {
TreasureBox.promise.calc.reject();
}
};
p.resolve();
return true;
} catch (err) {
MY_API.chatLog('[自动领取瓜子]初始化时出现异常,已停止', 'error');
console.error(`[${NAME}]`, err);
p.reject();
return true;
}
});
return p;
},
run: () => {
try {
if (!MY_API.CONFIG.AUTO_TREASUREBOX || !TreasureBox.timer) return;
if (Info.awardBlocked) {
TreasureBox.setMsg('瓜子小黑屋');
MY_API.chatLog('[自动领取瓜子]可能被关瓜子小黑屋,停止领取瓜子');
return;
}
// if (CACHE.treasure_box_ts && !checkNewDay(CACHE.treasure_box_ts)) {
// TreasureBox.setMsg('今日<br>已领完');
// runTomorrow(TreasureBox.run);
// return;
// }
TreasureBox.getCurrentTask().then((response) => {
console.log('TreasureBox.run: TreasureBox.getCurrentTask().then', response);
if (response.code === 0) {
// 获取任务成功
TreasureBox.promise.timer = $.Deferred();
TreasureBox.promise.timer.then(() => {
TreasureBox.captcha.calc().then((captcha) => {
// 验证码识别完成
TreasureBox.getAward(captcha).then(() => TreasureBox.run(), () => TreasureBox.run());
}, () => TreasureBox.run());
});
TreasureBox.time_end = response.data.time_end;
TreasureBox.time_start = response.data.time_start;
let t = TreasureBox.time_end - ts_s() + 1;
if (t < 0) t = 0;
setTimeout(() => {
if (TreasureBox.promise.timer) TreasureBox.promise.timer.resolve();
}, t * 1e3);
TreasureBox.DOM.div_timer.text(`${t}s`);
TreasureBox.DOM.div_timer.show();
TreasureBox.DOM.div_tip.html(`嗑瓜子`);
} else if (response.code === -10017) {
// 今天所有的宝箱已经领完!
TreasureBox.setMsg('今日<br>已领完');
MY_API.chatLog(`[自动领取瓜子]${response.msg}`, 'info');
// CACHE.treasure_box_ts = ts_ms();
// Essential.Cache.save();
// runTomorrow(TreasureBox.run);
} else if (response.code === -500) {
// 请先登录!
MY_API.chatLog(`[自动领取瓜子]请先登录!`);
} else {
MY_API.chatLog(`[自动领取瓜子]${response.msg}`);
return TreasureBox.run();
}
});
} catch (err) {
TreasureBox.setMsg('运行<br>异常');
MY_API.chatLog('[自动领取瓜子]运行时出现异常,已停止', 'error');
console.error(`[${NAME}]`, err);
}
},
setMsg: (htmltext) => {
if (!MY_API.CONFIG.AUTO_TREASUREBOX) return;
if (TreasureBox.promise.timer) {
TreasureBox.promise.timer.reject();
TreasureBox.promise.timer = undefined;
}
if (TreasureBox.DOM.div_timer) TreasureBox.DOM.div_timer.hide();
if (TreasureBox.DOM.div_tip) TreasureBox.DOM.div_tip.html(htmltext);
},
getAward: (captcha, cnt = 0) => {
if (!MY_API.CONFIG.AUTO_TREASUREBOX) return $.Deferred().reject();
if (cnt > 3) return $.Deferred().resolve(); // 3次时间未到,重新运行任务
return BAPI.TreasureBox.getAward(TreasureBox.time_start, TreasureBox.time_end, captcha).then((response) => {
console.log('TreasureBox.getAward: getAward', response);
switch (response.code) {
case 0:
MY_API.chatLog(`[自动领取瓜子]领取了 ${response.data.awardSilver} 银瓜子`, 'success');
return $.Deferred().resolve();
case -903: // -903: 已经领取过这个宝箱
// MY_API.chatLog('[自动领取瓜子]已经领取过这个宝箱');
return $.Deferred().resolve();
case -902: // -902: 验证码错误
case -901: // -901: 验证码过期
return TreasureBox.captcha.calc().then((captcha) => {
return TreasureBox.getAward(captcha, cnt);
});
case -800: // -800:未绑定手机
TreasureBox.setMsg('未绑定<br>手机');
MY_API.chatLog('[自动领取瓜子]未绑定手机,已停止');
return $.Deferred().reject();
case -500: // -500:领取时间未到, 请稍后再试
const p = $.Deferred();
setTimeout(() => {
TreasureBox.captcha.calc().then((captcha) => {
TreasureBox.getAward(captcha, cnt + 1).then(() => p.resolve(), () => p.reject());
}, () => p.reject());
}, 3e3);
return p;
case 400: // 400: 访问被拒绝
if (response.msg.indexOf('拒绝') > -1) {
Info.awardBlocked = true;
// Essential.DataSync.down();
TreasureBox.setMsg('拒绝<br>访问');
MY_API.chatLog('[自动领取瓜子]访问被拒绝,可能已经被关瓜子小黑屋,已停止', 'error');
return $.Deferred().reject();
}
MY_API.chatLog(`[自动领取瓜子]${response.msg}`);
return $.Deferred().resolve();
default: // 其他错误
MY_API.chatLog(`[自动领取瓜子]${response.msg}`);
}
}, () => {
MY_API.chatLog('[自动领取瓜子]获取任务失败,请检查网络', 'error');
return delayCall(() => TreasureBox.getAward(captcha, cnt));
});
},
getCurrentTask: () => {
if (!MY_API.CONFIG.AUTO_TREASUREBOX) return $.Deferred().reject();
return BAPI.TreasureBox.getCurrentTask().then((response) => {
console.log('TreasureBox.getCurrentTask: API.TreasureBox.getCurrentTask', response);
return $.Deferred().resolve(response);
}, () => {
MY_API.chatLog('[自动领取瓜子]获取当前任务失败,请检查网络', 'error');
return delayCall(() => TreasureBox.getCurrentTask());
});
},
captcha: {
cnt: 0,
calc: () => {
if (!MY_API.CONFIG.AUTO_TREASUREBOX) {
TreasureBox.captcha.cnt = 0;
return $.Deferred().reject();
}
if (TreasureBox.captcha.cnt > 100) { // 允许验证码无法识别的次数
// 验证码识别失败
TreasureBox.setMsg('验证码<br>识别<br>失败');
MY_API.chatLog('[自动领取瓜子]验证码识别失败,已停止', 'error');
return $.Deferred().reject();
}
return BAPI.TreasureBox.getCaptcha(ts_ms()).then((response) => {
console.log('TreasureBox.captcha.calc: getCaptcha', response);
if (response.code === 0) {
TreasureBox.captcha.cnt++;
const p = $.Deferred();
TreasureBox.promise.calc = $.Deferred();
TreasureBox.promise.calc.then((captcha) => {
TreasureBox.captcha.cnt = 0;
p.resolve(captcha);
}, () => {
TreasureBox.captcha.calc().then((captcha) => {
p.resolve(captcha);
}, () => {
p.reject();
});
});
TreasureBox.DOM.image.attr('src', response.data.img);
return p;
} else {
MY_API.chatLog(`[自动领取瓜子]${response.msg}`);
return delayCall(() => TreasureBox.captcha.calc());
}
}, () => {
MY_API.chatLog('[自动领取瓜子]加载验证码失败,请检查网络', 'error');
return delayCall(() => TreasureBox.captcha.calc());
});
},
// 对B站验证码进行处理
// 代码来源:https://github.com/zacyu/bilibili-helper/blob/master/src/bilibili_live.js
// 删除了未使用的变量
OCR: {
getGrayscaleMap: (context, rate = 235, width = 120, height = 40) => {
function getGrayscale(x, y) {
const pixel = context.getImageData(x, y, 1, 1).data;
return pixel ? (77 * pixel[0] + 150 * pixel[1] + 29 * pixel[2] + 128) >> 8 : 0;
}
const map = [];
for (let y = 0; y < height; y++) { // line y
for (let x = 0; x < width; x++) { // column x
const gray = getGrayscale(x, y);
map.push(gray > rate ? gray : 0);
}
}
return map;
},
orderFilter2In3x3: (grayscaleMap, n = 9, width = 120) => {
const gray = (x, y) => (x + y * width >= 0) ? grayscaleMap[x + y * width] : 255;
const map = [];
const length = grayscaleMap.length;
const catchNumber = n - 1;
for (let i = 0; i < length; ++i) {
const [x, y] = [i % width, Math.floor(i / width)];
const matrix = new Array(9);
matrix[0] = gray(x - 1, y - 1);
matrix[1] = gray(x + 0, y - 1);
matrix[2] = gray(x + 1, y - 1);
matrix[3] = gray(x - 1, y + 0);
matrix[4] = gray(x + 0, y + 0);
matrix[5] = gray(x + 1, y + 0);
matrix[6] = gray(x - 1, y + 1);
matrix[7] = gray(x + 0, y + 1);
matrix[8] = gray(x + 1, y + 1);
matrix.sort((a, b) => a - b);
map.push(matrix[catchNumber]);
}
return map;
},
execMap: (connectMap, rate = 4) => {
const map = [];
const connectMapLength = connectMap.length;
for (let i = 0; i < connectMapLength; ++i) {
let blackPoint = 0;
// const [x, y] = [i % 120, Math.round(i / 120)];
const top = connectMap[i - 120];
const topLeft = connectMap[i - 120 - 1];
const topRight = connectMap[i - 120 + 1];
const left = connectMap[i - 1];
const right = connectMap[i + 1];
const bottom = connectMap[i + 120];
const bottomLeft = connectMap[i + 120 - 1];
const bottomRight = connectMap[i + 120 + 1];
if (top) blackPoint += 1;
if (topLeft) blackPoint += 1;
if (topRight) blackPoint += 1;
if (left) blackPoint += 1;
if (right) blackPoint += 1;
if (bottom) blackPoint += 1;
if (bottomLeft) blackPoint += 1;
if (bottomRight) blackPoint += 1;
if (blackPoint > rate) map.push(1);
else map.push(0);
}
return map;
}
},
eval: (fn) => {
let Fn = Function;
return new Fn(`return ${fn}`)();
},
// 修正OCRAD识别结果
// 代码来源:https://github.com/zacyu/bilibili-helper/blob/master/src/bilibili_live.js
// 修改部分:
// 1.将correctStr声明在correctQuestion函数内部,并修改相关引用
// 2.在correctStr中增加'>': 3
correctStr: {
'g': 9,
'z': 2,
'Z': 2,
'o': 0,
'l': 1,
'B': 8,
'O': 0,
'S': 6,
's': 6,
'i': 1,
'I': 1,
'.': '-',
'_': 4,
'b': 6,
'R': 8,
'|': 1,
'D': 0,
'>': 3
},
correctQuestion: (question) => {
let q = '';
question = question.trim();
for (let i in question) {
let a = TreasureBox.captcha.correctStr[question[i]];
q += (a !== undefined ? a : question[i]);
}
if (q[2] === '4') q[2] = '+';
return q;
}
}
}; // Constantly Run, Need Init
MY_API.init().then(function () {
if (MY_API.CONFIG.AUTO_TREASUREBOX) {
$.when(get_room_info).then(() => {//领瓜子初始化
TreasureBox.init().then(() => {
TreasureBox.run();
});
});
}
if (Info.uid === 0 || isNaN(Info.uid)) {
MY_API.chatLog('未登录,请先登录再使用脚本', 'warning');
return
}
console.log(MY_API.CONFIG);
StartPlunder(MY_API);
});
}
function StartPlunder(API) {
'use strict';
let LIVE_PLAYER_STATUS = window.localStorage["LIVE_PLAYER_STATUS"];
if (Info.roomId === 6498960) {
if (LIVE_PLAYER_STATUS.indexOf("flash") >= 0) {
window.localStorage["LIVE_PLAYER_STATUS"] = window.localStorage["LIVE_PLAYER_STATUS"].replace("flash", 'html5');
window.location.reload();
return
}
let LT_Timer = () => {//判断是否清空辣条数量
if (checkNewDay(API.GIFT_COUNT.CLEAR_TS)) {
API.GIFT_COUNT.COUNT = 0;
API.GIFT_COUNT.LOVE_COUNT = 0;
API.GIFT_COUNT.CLEAR_TS = dateNow();
API.saveGiftCount();
console.log('清空辣条数量')
} else {
console.log('无需清空辣条数量')
}
};
setInterval(LT_Timer, 60e3);
LT_Timer();
let BG = () => {//判断是否赠送只剩1天的礼物
if (API.CONFIG.GIFT_ROOM === 0) return;
let myDate = new Date();
let h = myDate.getHours();
let m = myDate.getMinutes();
console.log(h);
if (h === 23 && m > 50) {
API.sendBagGift();
}
};
setInterval(LT_Timer, 300e3);
BG();
let YB = () => {//判断是否换硬币
if (API.CONFIG.AUTO_EXCHANGE && checkNewDay(API.GIFT_COUNT.EXCHANGE_TS)) {
API.GIFT_COUNT.EXCHANGE_TS = dateNow();
API.saveGiftCount();
API.Exchange.run();
console.log('银瓜子换硬币')
} else {
console.log('无需银瓜子换硬币')
}
};
YB();
let SS = () => {//判断是否签到
if (API.CONFIG.AUTO_SIGNIN && checkNewDay(API.GIFT_COUNT.SIGN_TS)) {
API.GIFT_COUNT.SIGN_TS = dateNow();
API.saveGiftCount();
BAPI.sign.doSign().then(function (result) {
API.chatLog(result.message);
});
} else {
console.log('未开启签到功能')
}
};
SS();
if (Info.roomId.toString().indexOf('9896') === -1) API.blocked = true;
API.creatSetBox();//创建设置框
BAPI.room.getList().then((response) => {//获取各分区的房间号
console.log('直播间列表', response);
for (const obj of response.data) {
BAPI.room.getRoomList(obj.id, 0, 0, 1, 1).then((response) => {
console.log('直播间号列表', response);
for (let j = 0; j < response.data.length; ++j) {
API.listen(response.data[j].roomid, Info.uid, `${obj.name}区`);
}
});
}
});
let check_top_room = () => { //检查小时榜房间时钟
if (API.GIFT_COUNT.COUNT >= API.CONFIG.MAX_GIFT) {//判断是否超过辣条限制
console.log('超过今日辣条限制,不参与抽奖');
API.max_blocked = true;
}
if (API.blocked || API.max_blocked) {//如果被禁用则停止
if (API.blocked) {
API.chatLog('进入小黑屋检查小时榜已停止运行');
} else {
API.chatLog('辣条已达到最大值检查小时榜已停止运行');
}
clearInterval(check_timer);
return
}
if (inTimeArea(API.CONFIG.TIME_AREA_START, API.CONFIG.TIME_AREA_END) && API.CONFIG.TIME_AREA_DISABLE) {//判断时间段
API.chatLog('当前时间段不检查小时榜礼物', 'warning');
return
}
let idList = [
'总榜',
'娱乐',
'网游',
'手游',
'绘画',
'电台',
'单机',
];
let num = 0;
let timer = setInterval(function () {
if (num <= 6) {
checkRank(num, idList[num]);
num++;
} else {
clearInterval(timer);
}
}, 5000);
let checkRank = function (areaId = 0, areaText) {
$.get('https://api.live.bilibili.com/rankdb/v1/Rank2018/' +
'getTop?type=master_realtime_hour&type_id=areaid_realtime_hour' +
`&area_id=${areaId}`, function (data) {
let list = data.data.list;// [{id: ,link:}]
API.chatLog(`检查小时榜${areaText}区的礼物`, 'warning');
console.log(`[${areaText}区小时榜列表]`, list);
for (let i of list) {
API.checkRoom(i.roomid, `小时榜-${areaText}区`);
}
});
};
};
setTimeout(check_top_room, 6e3);
let check_timer = setInterval(check_top_room, API.CONFIG.TOP10_DELAY * 60e3);
let reset = (delay) => {
setTimeout(function () {//重置直播间
if (API.raffleId_list.length > 0 || API.guardId_list.length > 0 || API.pkId_list.length > 0) {
console.log('还有礼物没抽 延迟30s后刷新直播间');
reset(30000);
return
}
if (API.blocked || API.max_blocked) { //被阻止就不刷新直播间了
return
}
window.location.reload();
}, delay);
};
reset(API.CONFIG.TIME_RELOAD * 60000);
} else {
API.chatLog('脚本未在此直播间启用<br><a href="https://live.bilibili.com/6498960">点击前往</a>', 'warning');
}
}
function getUrlParam(name) {
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
let r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}
/**
* (2,10) 当前是否在两点到十点之间(10,2) 当前是否在十点到次日两点之间
* @param a 整数 起始时间
* @param b 整数 终止时间
* @returns {boolean}
*/
function inTimeArea(a, b) {
a %= 24;
b %= 24;
if (a < 0 || b < 0 || a === b) {
console.log('错误时间段');
return false
}
let myDate = new Date();
let h = myDate.getHours();
if (a < b) {
return h >= a && h < b
} else {
return h >= a || h < b
}
}
/**
* 概率
* @param val
* @returns {boolean}
*/
function probability(val) {
if (val <= 0) return false;
let rad = Math.ceil(Math.random() * 100);
return val >= rad
}
const dateNow = () => Date.now();
/**
* 检查是否为新一天
* @param ts
* @returns {boolean}
*/
const checkNewDay = (ts) => {
if (ts === 0) return true;
let t = new Date(ts);
let d = new Date();
let td = t.getDate();
let dd = d.getDate();
return (dd !== td);
};
/**
* 获取cookie
* @param name
* @returns {string|boolean}
*/
function getCookie(name) {
let arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"));
if (arr != null) return unescape(arr[2]);
return false;
}