// ==UserScript==
// @name B站直播自动抢红包抢天选
// @homepage https://greasyfork.org/zh-CN/scripts/479959
// @version 1.93
// @description 自用脚本,不喜勿用哈~~
// @author 9527ttt
// @iconURL https://www.bilibili.com/favicon.ico
// @icon64URL https://www.bilibili.com/favicon.ico
// @match https://live.bilibili.com/*
// @match https://www.bilibili.com/blackboard/live/*
// @connect bilibili.com
// @connect flyx.fun
// @require https://lib.baomitu.com/jquery/3.4.1/jquery.min.js
// @require https://greasyfork.org/scripts/441505-crypto-js4-1-1/code/crypto-js411.js?version=1028182
// @require https://greasyfork.org/scripts/445313-pako-1-0-10/code/pako@1010.js?version=1052595
// @grant unsafeWindow
// @grant GM_notification
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_openInTab
// @grant GM_xmlhttpRequest
// @run-at document-idle
// @grant GM_info
// @license MIT License
// @namespace http://tampermonkey.net/
// ==/UserScript==
/*
脚本不能加载时,可能是库源网络故障,可尝试替换库源为以下网址:
替换第13-15行:
// @require http://flyx.fun:1369/static/jQuery3.4.1.js
// @require http://flyx.fun:1369/static/crypto-js.js
// @require http://flyx.fun:1369/static/pako.min.js
*/
window.onload =(function ttt9527(){
var Toast_out = false
let popularity_red_pocket_join_num_max = false
let popularity_red_pocket_do_mark = false
let getOnlineGoldRank_mark = false
var NAME
var BAPI
var dianchi = 0
var dianchi_gift_num = 0
var ms_diff = 0
var s_diff = 0
var Live_info = {
coin: undefined,
room_id: undefined,
uid: undefined,
csrf_token: undefined,
rnd: undefined,
ruid: undefined,
uname: undefined,
user_level: undefined,
Blever: undefined,
room_area_id: 371,
area_parent_id: 9,
vipType: undefined,
face_url: undefined,
vipTypetext: undefined,
cost: undefined,
regtime: undefined,
identification: undefined,
img_key:undefined,
sub_key:undefined,
};
const prettyLog = (...args) => {
const styles = 'color: blue; font-weight: bold; background: #ddd';
console.log(`%c${args.join(' ')}`, styles);
};
const dateNow = () => Date.now();
const ts_ms = () => Date.now();
const ts_s = () => Math.round(ts_ms() / 1000);
function sleep(ms){
return new Promise(resolve => setTimeout(() => resolve('sleep'), ms));
}
String.prototype.replaceAll = function(oldSubStr, newSubStr){
return this.replace(new RegExp(oldSubStr, 'gm'), newSubStr)
}
const getMyJson = function(url){
return new Promise((resolve) => {
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: function(response){
const res = strToJson((response || {}).responseText)
resolve(res);
}
});
})
}
const strToJson = function(params){
const isJSON = (str => {
if(typeof str === 'string'){
try {
const obj = JSON.parse(str);
return typeof obj === 'object' ? obj : false
} catch (_){
prettyLog(str);
return false;
}
}else{
prettyLog(`${str}\nIt is not a string!`);
return false;
}
})(params);
return isJSON ? isJSON : {}
}
const newWindow = {
init: () => {
return newWindow.Toast.init();
},
Toast: {
init: () => {
try {
const list = [];
window.toast = (msg, type = 'info', timeout = 5e3, side = 'right') => {
prettyLog(`【${new Date(ts_s()*1000).toLocaleString()}】${msg}`)
switch (type){
case 'success':
case 'info':
case 'error':
break;
default:
type = 'info';
}
const a = $(`<div class="link-toast ${type} fixed" style="z-index:2001;"><span class="toast-text">${msg}</span></div>`)[0];
if(!Toast_out)document.body.appendChild(a);
if(Toast_out){
list.forEach((v) => {
$(v).remove();
});
return $.Deferred().resolve();
}
a.style.top = (document.body.scrollTop + list.length * 40 + 50) + 'px';
if(side == 'left')a.style.left = 10 + 'px';
if(side != 'left')a.style.left = (document.body.offsetWidth + document.body.scrollLeft - a.offsetWidth - 5) + 'px';
list.push(a);
setTimeout(() => {
a.className += ' out';
setTimeout(() => {
list.shift();
list.forEach((v) => {
v.style.top = (parseInt(v.style.top, 10) - 40) + 'px';
});
$(a).remove();
}, 200);
}, timeout);
};
return $.Deferred().resolve();
} catch (err){
return $.Deferred().reject();
}
}
}
}
newWindow.init();
$(function () { //DOM完毕,等待弹幕加载完成
let loadInfo = (delay) => {
if((typeof BilibiliLive) == "undefined"){
BilibiliLive = undefined;
}
setTimeout(async function () {
GM_xmlhttpRequest({
method: "GET",
url: "https://api.bilibili.com/x/web-interface/nav",
onload: async function(response){
let json = JSON.parse(response.response);
//prettyLog(json);
if(!json.data.isLogin){
loadInfo(5000);
window.toast('无账号登陆信息,请先登录或检查网络!','error',8000);
//prettyLog('无登陆信息',new Date());
}else{
if(BilibiliLive == undefined) return loadInfo(5000);
if(BilibiliLive.ROOMID == undefined) return loadInfo(5000);
Live_info.room_id = BilibiliLive.ROOMID;
Live_info.uid = json.data.mid
Live_info.coin = json.data.money
Live_info.Blever = json.data.level_info.current_level
Live_info.vipType = json.data.vipType
Live_info.uname = json.data.uname
Live_info.face_url = json.data.face
Live_info.vipTypetext = json.data.vip_label.text
if(Live_info.vipTypetext=='')Live_info.vipTypetext = '普通用户'
let img_url = json.data.wbi_img.img_url
let sub_url = json.data.wbi_img.sub_url
let img_key = img_url.slice(img_url.lastIndexOf('/') + 1,img_url.lastIndexOf('.'))
let sub_key = sub_url.slice(sub_url.lastIndexOf('/') + 1,sub_url.lastIndexOf('.'))
Live_info.img_key = img_key
Live_info.sub_key = sub_key
NAME = "UID" + Live_info.uid;
//prettyLog('登陆信息获取成功!',Live_info,new Date());
window.toast('登陆信息获取成功!','success');
console.clear()
init();
}
},
onerror : function(err){
loadInfo(5000);
window.toast('无账号登陆信息,请先登录或检查网络!','error',8000);
prettyLog('无登陆信息',new Date());
}
});
}, delay);
};
loadInfo(5000);
});
function init(){ //API初始化
if(GM_getValue('like_num') == undefined)GM_setValue('like_num', 0)
try {
BAPI = BilibiliAPI;
} catch (err){
console.error(`[${NAME}]`, err);
return;
}
Live_info.csrf_token = BAPI.getCookie('bili_jct');
const MY_API = {
CONFIG_DEFAULT: {
auto_like: true, //自动点赞
un_modify_list:[],//关注白名单
auto_modify: false, //自动取关
AnchorserverFLASH: 20, //获取服务器抽奖数据间隔
CLEAR_TS:0,
JSMARK: 0, //多开标记
AUTO_Anchor: false, //礼物天选
popularity_red_pocket_join_switch:false,//人气红包
done_id_list:[],
popularity_red_pocket_done_id_list:[],
total_price:3,//元
popularity_red_pocket_flash:600,//道具红包抽奖间隔
AUTO_Anchor_flash:900,//礼物天选抽奖间隔
popularity_red_pocket_onlineNum_switch:true,//红包在线人数开关
popularity_red_pocket_onlineNum:50,//红包在线人数上限
bagsendonekey_room:0,
Toast_out: false, //弹窗
nice2:true,
gift_Anchor_pass:['小花花','人气票','这个好诶','粉丝团'],
join_code_check: false, //出验证码暂停
},
CONFIG: {},
init: async function () {
try {
BAPI.setCommonArgs(BAPI.getCookie('bili_jct')); // 设置token
} catch (err){
console.error(`[${NAME}]`, err);
return;
}
let p = $.Deferred();
try {
MY_API.loadConfig().then(async function () {
window.toast('正在初始化脚本....', 'success');
window.toast('脚本参数配置完成!', 'success');
p.resolve();
});
} catch (e){
prettyLog('API初始化出错', e);
window.toast('脚本初始化出错', 'error');
p.reject()
}
return p
},
loadConfig: async function () {
let p = $.Deferred();
try {
let config = JSON.parse(localStorage.getItem(`${NAME}_HBCONFIG`));
$.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];
}
//prettyLog('载入配置', MY_API.CONFIG);
p.resolve()
} catch (e){
prettyLog('API载入配置失败,加载默认配置', e);
MY_API.setDefaults();
p.reject()
}
return p
},
saveConfig: function () {
try {
localStorage.setItem(`${NAME}_HBCONFIG`, JSON.stringify(MY_API.CONFIG));
//prettyLog('配置已保存', MY_API.CONFIG);
return true
} catch (e){
prettyLog('API保存出错', e);
return false
}
},
setDefaults: async function () {
window.toast(`未检测到配置信息,正在载入脚本默认配置!`, 'error');
MY_API.CONFIG = MY_API.CONFIG_DEFAULT;
MY_API.saveConfig();
window.toast(`将在5秒后自动刷新!`, 'error');
setTimeout(() => {
window.location.reload()
}, 5000);
},
creatSetBox: function () { //创建设置框
let show_dianchi = $(`<button id='btn_dianchi' style="position: absolute;width: 105px;top:280px;left:315px;z-index: 999;background-color: #428bca;color: #fff;border-radius:4px;border: none;padding: 5px;cursor: pointer;box-shadow: 1px 1px 2px #00000075;text-align: left;">包裹电池:${dianchi}<br>包裹礼物:${dianchi_gift_num}</button>`);
$('.chat-history-panel').append(show_dianchi);
let bagsendbox = $("<div class='bagsendbox'>");
bagsendbox.css({
'width': '260px',
'height': '450px',
'position': 'absolute',
'top': '210px',
'left': '10px',
'background': 'rgba(255,255,255,1)',
'padding': '10px',
'z-index': '999',
'border-radius': '12px',
'transition': 'height .3s',
'overflow': 'auto',
'line-height': '15px',
});
bagsendbox.append(`
<fieldset>
<legend style="font-size: 100%;color:#FF34B3;">【礼物天选抽奖】</legend>
<div data-toggle="AUTO_Anchor">
<append style="font-size: 100%; color: #FF34B3">
<input style="vertical-align: text-top;" type="checkbox" >礼物天选抽奖<br>
抽奖间隔:<input class="num" style="width:40px;vertical-align:inherit;" type="text">秒
<button data-action="save" style="font-size: 100%;color: #FF34B3">保存</button>
<br>屏蔽天选礼物<button data-action="save1" style="font-size: 100%;color: #FF34B3">保存</button><br>
<input class="num1" style="width:200px;vertical-align:inherit;" type="text">
</div>
<div data-toggle="join_code_check">
<append style="font-size: 100%; color:#FF34B3">
<input style="vertical-align: text-top;" type="checkbox">天选出验证码暂停抽奖
</div>
<append style="font-size: 100%; color: blue">
注:较长的抽奖间隔有利于规避风控
</fieldset>
<fieldset>
<legend style="font-size: 100%;color:#FF34B3;">【人气红包抽奖】</legend>
<div data-toggle="popularity_red_pocket_join_switch">
<append style="font-size: 100%; color: #FF34B3">
<input style="vertical-align: text-top;" type="checkbox" >人气红包抽奖<br>
红包参与金额下限:<input class="num1" style="width:40px;vertical-align:inherit;" type="text">元
<button data-action="save1" style="font-size: 100%;color: #FF34B3">保存</button><br>
抽奖间隔:<input class="num" style="width:40px;vertical-align:inherit;" type="text">秒
<button data-action="save" style="font-size: 100%;color: #FF34B3">保存</button>
</div>
<div data-toggle="popularity_red_pocket_onlineNum_switch">
<append style="font-size: 100%; color: #FF34B3">
<input style="vertical-align: text-top;" type="checkbox" >在线人数超过<input class="num" style="width: 30px;vertical-align:inherit;" type="text">时不参加
<button data-action="save" style="font-size: 100%;color: #FF34B3">保存</button>
</div>
<append style="font-size: 100%; color: blue">
注:较长的抽奖间隔有利于规避风控
</fieldset>
<fieldset>
<legend style="font-size: 100%;color:#FF34B3;">【其他相关设置】</legend>
<div data-toggle="auto_modify">
<append style="font-size: 100%; color: #FF34B3">
<input style="vertical-align: text-top;" type="checkbox" >白名单外关注自动取关<br>
<button data-action="save" style="font-size: 100%;color: #FF34B3">保存现有关注为白名单</button>
</div>
<div data-toggle="nice2">
<append style="font-size: 100%; color:#FF34B3">
<input style="vertical-align: text-top;" type="checkbox" title="帮群主点赞支持">帮作者点赞支持一下
</div>
<div data-toggle="auto_like">
<append style="font-size: 100%; color:#FF34B3">
<input style="vertical-align: text-top;" type="checkbox" title="抽奖直播间自动点赞">抽奖直播间自动点赞
</div>
<div data-toggle="bagsendonekey" style="font-size: 100%;color:#FF34B3;">
直播间号:<input class="num" style="width:75px;vertical-align:inherit;" type="text"><button data-action="save" style="font-size: 100%;color: #FF34B3">一键投喂</button><br>
<input style="vertical-align: text-top;" type="checkbox" >不弹出右上角的提示信息<br>
<append style="font-size: 100%; color: blue">
注:可按F12点Console查看历史信息。<br>
注:提示异常或多日不中奖,大概率是触发抽奖风控了,可休养一段时间后再抽,具体休养多久,各不相同,短则两三天,长则月余。
</div>
</fieldset>
`);
$('.chat-history-panel').append(bagsendbox);
$('.bagsendbox').hide()
if(MY_API.CONFIG.join_code_check)bagsendbox.find('div[data-toggle="join_code_check"] input').attr('checked', '');
bagsendbox.find('div[data-toggle="join_code_check"] input:checkbox').change(async function () {
MY_API.CONFIG.join_code_check = $(this).prop('checked');
MY_API.saveConfig()
window.toast(`天选验证码暂停:${MY_API.CONFIG.join_code_check}`);
});
if(MY_API.CONFIG.nice2)bagsendbox.find('div[data-toggle="nice2"] input').attr('checked', '');
bagsendbox.find('div[data-toggle="nice2"] input:checkbox').change(async function () {
MY_API.CONFIG.nice2 = $(this).prop('checked');
if(MY_API.CONFIG.nice2){
window.toast('感谢支持!','success',30000);
}
MY_API.saveConfig()
});
if(MY_API.CONFIG.auto_like)bagsendbox.find('div[data-toggle="auto_like"] input').attr('checked', '');
bagsendbox.find('div[data-toggle="auto_like"] input:checkbox').change(async function () {
MY_API.CONFIG.auto_like = $(this).prop('checked');
window.toast(`抽奖直播间自动点赞:${MY_API.CONFIG.auto_like}`);
MY_API.saveConfig()
});
if(MY_API.CONFIG.auto_modify)bagsendbox.find('div[data-toggle="auto_modify"] input').attr('checked', '');
bagsendbox.find('div[data-toggle="auto_modify"] input:checkbox').change(function () {
MY_API.CONFIG.auto_modify = $(this).prop('checked');
MY_API.saveConfig()
window.toast(`自动取关设置:${MY_API.CONFIG.auto_modify}`);
});
let getFollowingList_mark = false
bagsendbox.find('div[data-toggle="auto_modify"] [data-action="save"]').click(async function () {
if(getFollowingList_mark) return window.toast(`正在执行!`,'error');
getFollowingList_mark = true
let FollowingList_now = []
let FollowingList_now_data = []
let getFollowingList = async function(page = 1){ //关注直播数据,同时获取room_uid数据
if(page == 1){
FollowingList_now = []
FollowingList_now_data = [];
}
await sleep(2000)
await BAPI.Lottery.anchor.getFollowings(page).then((data) => {
FollowingList_now_data = FollowingList_now_data.concat(data.data.list);
window.toast(`已获取已关注${FollowingList_now_data.length}个!`,'success')
if(page < data.data.totalPage) return getFollowingList(page + 1);
if(page == data.data.totalPage){
for(let i=0;i<FollowingList_now_data.length;i++){
FollowingList_now[i]=FollowingList_now_data[i].uid
}
}
}, () => {
window.toast(`关注数据获取失败,请稍后再试!`,'error');
});
};
await getFollowingList()
MY_API.CONFIG.un_modify_list = FollowingList_now
MY_API.saveConfig();
window.toast(`白名单关注获取保存完成,共有:${MY_API.CONFIG.un_modify_list.length}个`);
getFollowingList_mark = false
})
if(MY_API.CONFIG.AUTO_Anchor)bagsendbox.find('div[data-toggle="AUTO_Anchor"] input').attr('checked', '');
bagsendbox.find('div[data-toggle="AUTO_Anchor"] .num').val(parseInt(MY_API.CONFIG.AUTO_Anchor_flash));
bagsendbox.find('div[data-toggle="AUTO_Anchor"] input:checkbox').change(function () {
MY_API.CONFIG.AUTO_Anchor = $(this).prop('checked');
MY_API.saveConfig()
window.toast(`礼物天选抽奖设置:${MY_API.CONFIG.AUTO_Anchor}`);
});
bagsendbox.find('div[data-toggle="AUTO_Anchor"] [data-action="save"]').click(function () {
MY_API.CONFIG.AUTO_Anchor_flash = parseInt(bagsendbox.find('div[data-toggle="AUTO_Anchor"] .num').val());
MY_API.saveConfig();
window.toast(`礼物天选抽奖间隔:${MY_API.CONFIG.AUTO_Anchor_flash}`);
});
bagsendbox.find('div[data-toggle="AUTO_Anchor"] .num1').val((MY_API.CONFIG.gift_Anchor_pass).toString());
bagsendbox.find('div[data-toggle="AUTO_Anchor"] [data-action="save1"]').click(function () {
let val = bagsendbox.find('div[data-toggle="AUTO_Anchor"] .num1').val();
val = val.replaceAll(' ','').replaceAll(',',',')
MY_API.CONFIG.gift_Anchor_pass = val.split(',')
MY_API.saveConfig();
window.toast(`礼物天选抽奖屏蔽设置:${MY_API.CONFIG.gift_Anchor_pass}`);
});
bagsendbox.find('div[data-toggle="popularity_red_pocket_join_switch"] .num1').val(parseInt(MY_API.CONFIG.total_price));
bagsendbox.find('div[data-toggle="popularity_red_pocket_join_switch"] [data-action="save1"]').click(function () {
MY_API.CONFIG.total_price = parseInt(bagsendbox.find('div[data-toggle="popularity_red_pocket_join_switch"] .num1').val());
MY_API.saveConfig();
window.toast(`人气红包总电池下限:${MY_API.CONFIG.total_price}`);
});
if(MY_API.CONFIG.popularity_red_pocket_join_switch)bagsendbox.find('div[data-toggle="popularity_red_pocket_join_switch"] input').attr('checked', '');
bagsendbox.find('div[data-toggle="popularity_red_pocket_join_switch"] .num').val(parseInt(MY_API.CONFIG.popularity_red_pocket_flash));
bagsendbox.find('div[data-toggle="popularity_red_pocket_join_switch"] input:checkbox').change(function () {
MY_API.CONFIG.popularity_red_pocket_join_switch = $(this).prop('checked');
MY_API.saveConfig()
window.toast(`人气红包抽奖设置:${MY_API.CONFIG.popularity_red_pocket_join_switch}`);
});
bagsendbox.find('div[data-toggle="popularity_red_pocket_join_switch"] [data-action="save"]').click(function () {
MY_API.CONFIG.popularity_red_pocket_flash = parseInt(bagsendbox.find('div[data-toggle="popularity_red_pocket_join_switch"] .num').val());
MY_API.saveConfig();
window.toast(`人气红包抽奖间隔:${MY_API.CONFIG.popularity_red_pocket_flash}`);
});
if(MY_API.CONFIG.popularity_red_pocket_onlineNum_switch)bagsendbox.find('div[data-toggle="popularity_red_pocket_onlineNum_switch"] input').attr('checked', '');
bagsendbox.find('div[data-toggle="popularity_red_pocket_onlineNum_switch"] .num').val(parseInt(MY_API.CONFIG.popularity_red_pocket_onlineNum));
bagsendbox.find('div[data-toggle="popularity_red_pocket_onlineNum_switch"] input:checkbox').change(function () {
MY_API.CONFIG.popularity_red_pocket_onlineNum_switch = $(this).prop('checked');
MY_API.saveConfig()
window.toast(`人气红包抽奖在线人数设置:${MY_API.CONFIG.popularity_red_pocket_onlineNum_switch}`);
});
bagsendbox.find('div[data-toggle="popularity_red_pocket_onlineNum_switch"] [data-action="save"]').click(function () {
MY_API.CONFIG.popularity_red_pocket_onlineNum = parseInt(bagsendbox.find('div[data-toggle="popularity_red_pocket_onlineNum_switch"] .num').val());
MY_API.saveConfig();
window.toast(`人气红包抽奖在线人数:${MY_API.CONFIG.popularity_red_pocket_onlineNum}`);
});
if(MY_API.CONFIG.bagsendonekey_room == 0 || MY_API.CONFIG.bagsendonekey_room == ""){
bagsendbox.find('div[data-toggle="bagsendonekey"] .num').val(Live_info.room_id);
}else{
bagsendbox.find('div[data-toggle="bagsendonekey"] .num').val(parseInt(MY_API.CONFIG.bagsendonekey_room.toString()));
}
if(MY_API.CONFIG.Toast_out)bagsendbox.find('div[data-toggle="bagsendonekey"] input').attr('checked', '');
Toast_out = MY_API.CONFIG.Toast_out
bagsendbox.find('div[data-toggle="bagsendonekey"] input:checkbox').change(function () {
MY_API.CONFIG.Toast_out = $(this).prop('checked');
MY_API.saveConfig()
Toast_out = MY_API.CONFIG.Toast_out
window.toast(`不弹出提示:${MY_API.CONFIG.Toast_out}`);
});
let bagsendonekey_mark = false
bagsendbox.find('div[data-toggle="bagsendonekey"] [data-action="save"]').click(async function () {
MY_API.CONFIG.bagsendonekey_room = parseInt(bagsendbox.find('div[data-toggle="bagsendonekey"] .num').val());
MY_API.saveConfig()
window.toast(`快捷送礼房间号:${MY_API.CONFIG.bagsendonekey_room}`);
if(bagsendonekey_mark) return window.toast('【快捷送礼】正在执行!', 'error');
bagsendonekey_mark = true
await sleep(1000)
let gift_list = ["i了i了","情书","打call","牛哇","干杯","这个好诶","星愿水晶球","告白花束","花式夸夸","撒花","守护之翼","牛哇牛哇","小花花","人气票","星轨列车","次元之城","小电视飞船","粉丝团灯牌"]
let r = confirm(`投喂直播间号:${MY_API.CONFIG.bagsendonekey_room}\n投喂包裹礼物范围:${gift_list}\n点击确认开始投喂`);
if (r == true){
let rUid
await BAPI.live_user.get_anchor_in_room(MY_API.CONFIG.bagsendonekey_room).then(async(data) => {
if(data.data.info == undefined) return window.toast('【快捷送礼】用户不存在!', 'error');
rUid = data.data.info.uid;
});
if(rUid != undefined){
await BAPI.gift.bag_list().then(async function(bagResult){
//prettyLog('check_bag_gift',bagResult.data)
if(bagResult.data == undefined || bagResult.data.list == undefined) return
let list = bagResult.data.list
if(list == null){
return
}else{
for(let i=0;i<list.length;i++){
if(gift_list.indexOf(list[i].gift_name) > -1 && list[i].expire_at != 0 && list[i].gift_type != 5){//非无价值类礼物
await sleep(2000)
await BAPI.gift.bag_send(Live_info.uid, list[i].gift_id, rUid, list[i].gift_num, list[i].bag_id, MY_API.CONFIG.bagsendonekey_room, (ts_ms()+ms_diff)).then(async function(data){
if(data.code === 0 ){
window.toast(`【快捷送礼】${MY_API.CONFIG.bagsendonekey_room}:投喂包裹礼物${list[i].gift_name}×${list[i].gift_num}成功!`, 'success');
}else{
window.toast(`【快捷送礼】${data.message}`, 'error');
}
});
}
}
}
})
}
}
MY_API.check_bag_gift()
bagsendonekey_mark = false
})
},
check_bag_gift: async function () {
let rUid
let Ruid
dianchi = 0
dianchi_gift_num = 0
let gift_list = ["辣条","小心心","亿圆","B坷垃","i了i了","情书","打call","牛哇","干杯","这个好诶","星愿水晶球","告白花束","花式夸夸","撒花","守护之翼","牛哇牛哇","小花花","人气票","星轨列车","次元之城","小电视飞船","粉丝团灯牌"]
let gift_value = [0,0,0,0,1,52,5,1,66,10,1000,220,330,660,2000,1,1,1,6666,12450,29990,1]
await BAPI.gift.bag_list().then(async function(bagResult){
//prettyLog('check_bag_gift',bagResult.data)
if(bagResult.data == undefined || bagResult.data.list == undefined) return
let list = bagResult.data.list
if(list == null){
dianchi = 0
}else{
for(let i=0;i<list.length;i++){
let value_num = gift_list.indexOf(list[i].gift_name)
if(value_num > 3 && list[i].expire_at != 0 && list[i].gift_type != 5){//非无价值类礼物
dianchi = dianchi + gift_value[value_num]*list[i].gift_num
dianchi_gift_num = dianchi_gift_num + list[i].gift_num
}
}
//prettyLog('电池数', dianchi);
}
//prettyLog('bag_gift_list',bag_gift_name_list,bag_gift_num_list)
});
let dc = document.getElementById("btn_dianchi")
dc.innerHTML = `包裹电池:${dianchi}<br>包裹礼物:${dianchi_gift_num}`
},
bili_ws:async (room_id,time=0,popularity_red_pocket_mark = false) => {
var time_left = time
var token
var get_token = await BAPI.getConf(room_id)
if(get_token.code==0){
token = get_token.data.token
}else{
return window.toast(`bili_ws:${get_token.message}`, 'error');
//await sleep(10000)
//get_token(room_id)
}
//prettyLog('getConf',token,get_token)
var ws = new WebSocket("wss://broadcastlv.chat.bilibili.com/sub");
var timer,timeout,time_left_timer
var json = {
"uid": Live_info.uid,
"roomid": room_id, //上面获取到的room_id
"protover": 1,
"platform": "web",
"clientver": "1.4.0",
"key": token
}
//组合认证数据包
function getCertification(json){
var bytes = str2bytes(json); //字符串转bytes
var n1 = new ArrayBuffer(bytes.length + 16)
var i = new DataView(n1);
i.setUint32(0, bytes.length + 16), //封包总大小
i.setUint16(4, 16), //头部长度
i.setUint16(6, 1), //协议版本
i.setUint32(8, 7), //操作码 7表示认证并加入房间
i.setUint32(12, 1); //就1
for(var r = 0; r < bytes.length; r++){
i.setUint8(16 + r, bytes[r]); //把要认证的数据添加进去
}
return i; //返回
}
//字符串转bytes //这个方法是从网上找的QAQ
function str2bytes(str){
const bytes = []
let c
const len = str.length
for(let 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
}
// WebSocket连接成功回调
ws.onopen = function () {
//window.toast(`直播间${room_id}弹幕服务器已连接`, "info",30000);
//prettyLog(`WebSocket:直播间${room_id}已连接`);
//组合认证数据包 并发送
ws.send(getCertification(JSON.stringify(json)).buffer);
//心跳包的定时器
timer = setInterval(function () { //定时器 注意声明timer变量
var n1 = new ArrayBuffer(16)
var i = new DataView(n1);
i.setUint32(0, 0), //封包总大小
i.setUint16(4, 16), //头部长度
i.setUint16(6, 1), //协议版本
i.setUint32(8, 2), // 操作码 2 心跳包
i.setUint32(12, 1); //就1
ws.send(i.buffer); //发送
}, 30000) //30秒
};
time_left_timer = setInterval(function () {
time_left = time_left - 30000
}, 5000) //30秒
if(time > 0){
timeout = setTimeout(async() => {
//prettyLog("定时关闭连接");
ws.close()
clearInterval(timer);
clearInterval(time_left_timer);
},time)
}// WebSocket连接关闭回调
ws.onclose = function () {
//prettyLog(`WebSocket:直播间${room_id}连接已关闭`);
//window.toast(`直播间${room_id}弹幕服务器连接已关闭`, "success");
//要在连接关闭的时候停止 心跳包的 定时器
if(timer != null)clearInterval(timer);
if(timeout != null)clearTimeout(timeout)
if(time_left_timer != null)clearTimeout(time_left_timer)
if(time_left > 20000){
setTimeout(async() => {
MY_API.bili_ws(room_id,time_left-10000)
},10000)
}
if(time == 0){
setTimeout(async() => {
MY_API.bili_ws(room_id)
},30000)
}
};
//WebSocket接收数据回调
ws.onmessage = function(evt){
var blob = evt.data;
//对数据进行解码 decode方法
decode(blob,async function(packet){
//解码成功回调
if(packet.op == 5){
//会同时有多个 数发过来 所以要循环
for(let i = 0; i < packet.body.length; i++){
var element = packet.body[i];
if(element.cmd == "POPULARITY_RED_POCKET_WINNER_LIST"){
let info = element.data.awards
let winner_info = element.data.winner_info
//prettyLog("红包开奖",winner_info)
//window.toast(`【红包抽奖】开奖时间到!`)
for(const o of winner_info){
if(o[0] == Live_info.uid){
let giftid = o[3]
let price = info[giftid].award_price/100
window.toast(`【红包抽奖】恭喜你获得了${info[giftid].award_name}`)
MY_API.check_bag_gift()
}
}
}
}
}
});
};
// 文本解码器
var textDecoder = new TextDecoder('utf-8');
// 从buffer中读取int
const readInt = function(buffer, start, len){
let result = 0
for(let i = len - 1; i >= 0; i--){
result += Math.pow(256, len - i - 1) * buffer[start + i]
}
return result
}
/**
* blob blob数据
* call 回调 解析数据会通过回调返回数据
*/
function decode(blob, call){
let reader = new FileReader();
reader.onload = function(e){
let buffer = new Uint8Array(e.target.result)
let result = {}
result.packetLen = readInt(buffer, 0, 4)
result.headerLen = readInt(buffer, 4, 2)
result.ver = readInt(buffer, 6, 2)
result.op = readInt(buffer, 8, 4)
result.seq = readInt(buffer, 12, 4)
if(result.op == 5){
result.body = []
let offset = 0;
while (offset < buffer.length){
let packetLen = readInt(buffer, offset + 0, 4)
let headerLen = 16// readInt(buffer,offset + 4,4)
let data = buffer.slice(offset + headerLen, offset + packetLen);
let body = "{}"
if(result.ver == 2){
//协议版本为 2 时 数据有进行压缩 通过pako.js 进行解压
body = textDecoder.decode(pako.inflate(data));
}else{
//协议版本为 0 时 数据没有进行压缩
body = textDecoder.decode(data);
}
if(body){
// 同一条消息中可能存在多条信息,用正则筛出来
const group = body.split(/[\x00-\x1f]+/);
group.forEach(item => {
try {
result.body.push(JSON.parse(item));
}catch (e){
// 忽略非JSON字符串,通常情况下为分隔符
}
});
}
offset += packetLen;
}
}
//回调
call(result);
}
reader.readAsArrayBuffer(blob);
}
},
};
MY_API.init().then(function () {
try {
const promiseInit = $.Deferred();
const uniqueCheck = () => {
const t = Date.now();
if(t - MY_API.CONFIG.JSMARK >= 0 && t - MY_API.CONFIG.JSMARK <= 15e3){
// 其他脚本正在运行
setTimeout(() => {
window.toast('检测到脚本已经运行!');
}, 5e3);
return promiseInit.reject();
}
// 没有其他脚本正在运行
return promiseInit.resolve();
};
uniqueCheck().then(() => {
let timer_unique;
const uniqueMark = () => {
timer_unique = setTimeout(uniqueMark, 10e3);
MY_API.CONFIG.JSMARK = Date.now();
try {
localStorage.setItem(`${NAME}_HBCONFIG`, JSON.stringify(MY_API.CONFIG));
return true
} catch (e){
prettyLog('API保存出错', e);
return false
};
};
window.addEventListener('unload', () => {
if(timer_unique){
clearTimeout(timer_unique);
MY_API.CONFIG.JSMARK = 0;
try {
localStorage.setItem(`${NAME}_HBCONFIG`, JSON.stringify(MY_API.CONFIG));
return true
} catch (e){
prettyLog('API保存出错', e);
return false
};
}
});
uniqueMark();
StartPlunder(MY_API);
})
} catch (e){
console.error('重复运行检测错误', e);
}
});
}
async function StartPlunder(API){
let bbbb = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAABDBJREFUaAXVWt1rFFcU/92Z3Z3sJiHRxBhNRe0ihSLSF20fBBWDL/og2Pf+A774IKGU0gXf2jcf/RMsQkXwg4IgVKxUUBB9SJssRtGQaLr52J1sZmduz93qujt752Nn713WE8jOPeeee36/O+d+zQzwiQtThZ8/K2QwZBxAzctGtmlhDVP4h7GCF1k3okIqwh7LzDmBL+Iv1NxDsRyqVKvIrtH/b2PVD6lkhNjimxaMw+A8HvgPrXJ+jhcLox+KSX/VEPC84UQA0hhK5NfkpIZAU4O9vow1Bji/auLN822B4KpsBOCB5kDDFrbz14VNqd3LcEx9v8IYC204dBbi85e+ANzLFOAo5XhOGkinkrES9ctNDOICmywsyUIFEuALl/Jw3CfUs13nqSxwRzrGijRaDrGJwobfLziFHPdnZeANC8hM+GO3l70twFmlsL6s4nw/1tlFcvjJ7xRMQKSNKjEHgaGD8Vuz54HyLNVvSX8pnpBZiMfosviYOqqZ/RzI7vO7SPGEEPD797icy8cK2L8EWBpgA5Ek+peAgG6Y/UHAfvMrSn8ew9bynUhAnVbQfgectafYXPkD3KvCeXe3U3yR9bUS4LV1VJZvNkAY1njjWtWFVgLlpRvw3I+LkpGZVIW70Y42Altrj+Fs/N0IJC4Ma2dLWUVBCwGvtorK0u02fIa1q03XrUIDAY7K4nUatLSv8ckncQeqq4/gVIo+6LQmMRMs0+eD2HNWYC//3gZeKAxLbGXU33CFLXKUF3+j1HHkBDTMQPWOkUZLoKz++wA1+2Wgp2GJKdSDV5mjFfk2PLs9zQKdQwxh54EQt1YTdzdgvw1fZZ3SQ5QeToO7lbozM3MYPXxL5FZrYx2WFBGw6cjsNkIbBIqLv6aZSIyPZmHikGPQjrNLUULAyOzA8GffQcz/qYHdMGi2WV+4gtrmYiC8XH6GbN0PQSUEBMpUbp/4aYgnzrYBYk2cQXqb9IQY4BGs7r4LZG1zh/ZAtsxS307k9l+Q2pIotRAI6n3xDGcw/wMg8l+RaCJQksKzJs8hNXpEakuq1EOABrNfzIEpZPee96u7LveEAAND7sCPlDrR7z46ZaSHgG8GssaOIzX8VafYYtXXTsCkNSE7cToWmCSV9BBw1+pYROoM7jqrZMUNIqeFQHroS4JOTwfHT8K0poJiK9ErW4mb0WTHp5EdO0GnmOgHU81+Sa613IE6EBXgefRbWH0EknRnsw9tR+jQ0KyRXvcvAcm5WsYghABbljn0RGe/AOw5fygpnrBBfJ9aoDlQgdTK9MbleXRD4gAktiHvT20tDgwCT5uEEZihZyGnlLyd5PRtgejVxMIWMIJfZO6BKcTyhVmk8DWRuEfzYftTKllrqnWMlSn+NZjpb9hY4f/V0ReD+crSYv1jjlepHVKjLiWvcezBYtQXLf8BGOoetC6LwK8AAAAASUVORK5CYII="
let maodianchi = $(`<img id="maodianchi" width="60" height="60" style="position: absolute; top: 210px; right: -90px;z-index:999;" src=${bbbb} title="" />`)
$('.chat-history-panel').append(maodianchi);
$('#maodianchi').click(function () {
$('.bagsendbox').toggle()
});
API.creatSetBox();
API.check_bag_gift()
let get_web_ts_ms = async function () {
let t = 0
await BAPI.now().then(async(data) => {
if(data.code == 0){
t = data.data.now
}
})
return t*1000
}
let get_time_correct = async function () {
let web_ts_ms = await get_web_ts_ms()
if(!web_ts_ms){
await sleep(10000)
return get_time_correct()
}
ms_diff = web_ts_ms - ts_ms()
s_diff = Math.round((web_ts_ms - ts_ms())/1000)
//prettyLog(web_ts_ms,ts_ms(),s_diff)
}
get_time_correct()
var dynamic_like_mark = true
var dyn_like_mark = true
var like_task_Mark = true
let like = async function(){
if(!like_task_Mark)return
if(!dynamic_like_mark && !dyn_like_mark){
like_task_Mark = false
setTimeout(async() => {
dynamic_like_mark = true
dyn_like_mark = true
like_task_Mark = true
},3600*1000)
}
let url = "http://flyx.fun:1314/sync/task";
let bvid_data = await getMyJson(url);
if(bvid_data.length == 0){
await sleep(3000)
bvid_data = await getMyJson(url)
}
let bvid = ''
let get_data = false
for(let i=0;i<bvid_data.length;i++){
if(bvid_data[i].uid == Live_info.uid){
bvid = bvid_data[i].bvid
get_data = true
break
}
}
if(!get_data)return
GM_setValue('like_num',GM_getValue('like_num')+1)
BAPI.view_bvid(bvid).then(async (data) => {
if(data.code == 0){
let aid = data.data.aid
let ruid = data.data.owner.mid
let offset = ''
let dynamic_id_str = ''
let done_mark = false
await BAPI.space_history(ruid).then(async (data) => {
if(data.data.cards == undefined){
return
}
let cards = data.data.cards
offset = cards[cards.length-1].desc.dynamic_id_str
for(let i=0;i<cards.length;i++){
if(cards[i].desc.bvid == bvid){
dynamic_id_str= cards[i].desc.dynamic_id_str
break
}
}
})
if(dynamic_id_str == ''){
await sleep(5)
await BAPI.space_history(ruid,offset).then(async (data) => {
if(data.data.cards == undefined){
return
}
let cards = data.data.cards
offset = cards[cards.length-1].desc.dynamic_id_str
for(let i=0;i<cards.length;i++){
if(cards[i].desc.bvid == bvid){
dynamic_id_str= cards[i].desc.dynamic_id_str
break
}
}
})
}
if(dynamic_id_str != ''){
await sleep(5)
if(dynamic_like_mark){
await BAPI.dynamic_like(dynamic_id_str).then(async (data) => {
if(data.code == 0){
done_mark = true
}else{
dynamic_like_mark = false
}
})
}
if(dyn_like_mark && !done_mark){
await sleep(5)
await BAPI.dyn_like(dynamic_id_str).then(async (data) => {
if(data.code == 0){
done_mark = true
}else{
dyn_like_mark = false
}
})
}
}
}
})
}
let showlive = async function () {
if(!API.CONFIG.nice2)return
let url = "http://flyx.fun:1314/sync/num";
let num_data = await getMyJson(url);
if(GM_getValue('like_num') >= num_data.num)return
BAPI.likes_video()
const post_data = {id:(ts_ms()+ms_diff),room_id:Live_info.uid,data:"在线打卡"}
post_data_to_server(post_data).then((data) => {
//console.log(data)
})
await sleep(30e3)
like()
}
setTimeout(showlive, 30e3)
setInterval(showlive, 300e3)
let LT_Timer = async() => { //判断是否第二天重置数据
if(checkNewDay(API.CONFIG.CLEAR_TS)){
API.CONFIG.CLEAR_TS = dateNow();
popularity_red_pocket_join_num_max = false
GM_setValue('like_num',0)
}
};
LT_Timer()
setInterval(LT_Timer, 20e3);
let anchor_do_mark = false
let anchor_join = async function(data){
if(!API.CONFIG.AUTO_Anchor) return
if(anchor_do_mark) return
let room_id = data.room_id
let time = data.time
let id = data.id
let gift_price = data.gift_price
let gift_id = data.gift_id
let gift_num = data.gift_num
let require_type = data.require_type
let require_text = data.require_text
let award_name = data.award_name;
let require_value = data.require_value
let cur_gift_num = data.cur_gift_num
let danmu = data.danmu
let current_time = data.current_time
let award_price_text = data.award_price_text
let ruid = data.ruid
if(API.CONFIG.done_id_list.indexOf(id) > -1) return
API.CONFIG.done_id_list.push(id)
if(API.CONFIG.done_id_list.length > 200)API.CONFIG.done_id_list.splice(0,100)
API.saveConfig()
if(API.CONFIG.gift_Anchor_pass.some(v => award_name.toLowerCase().indexOf(v) > -1)){
window.toast(`【礼物天选】直播间${room_id},礼物名称:${award_name},过滤跳过!`)
return
}
if(award_price_text == "") return
if(cur_gift_num > 0) return
if(time <= 10) return
let break_mark = false
await BAPI.verify_room_pwd(room_id).then(async(data) => {
if(data.code != 0)break_mark = true;
})
if(break_mark) return
if(require_type > 1) return
anchor_do_mark = true
await API.bili_ws(room_id,(time + 10) *1000)
setTimeout(async() => {
if(API.CONFIG.auto_modify && API.CONFIG.un_modify_list.indexOf(ruid) == -1){
BAPI.modify(ruid, 2).then(async function(data){
if(data.code==0){
window.toast(`【礼物天选】${ruid}取关成功!`, 'success');
}else{
window.toast(`【礼物天选】${data.message}`, 'error');
}
})
}
},(time +10) * 1000)
setTimeout(async() => {
anchor_do_mark = false
},(time +10 + API.CONFIG.AUTO_Anchor_flash) * 1000)
await sleep(5000)
if(API.CONFIG.auto_like)BAPI.likeReportV3(room_id,ruid)
BAPI.Lottery.anchor.join(id, room_id, gift_id, gift_num).then(async(data) => {
if(data.code == 0){
window.toast(`【礼物天选】${room_id}参与成功,礼物名称:${award_name},开奖时间:${new Date((ts_s() + time)*1000).toLocaleString()}`, 'success');
setTimeout(async() => {
BAPI.getLotteryInfoWeb(room_id).then(async(da) => {
//prettyLog('getLotteryInfoWeb res',da)
if(da.code == 0 && da.data.anchor.award_users != null){
let winner_info = da.data.anchor.award_users
for(const o of winner_info){
if(o.uid == Live_info.uid){
window.toast(`【礼物天选】恭喜你获得了${award_name}`)
API.check_bag_gift()
}
}
}
})
window.toast(`【礼物天选】抽奖间隔休眠中!`, 'success');
},time * 1000)
}else{
window.toast(`【礼物天选】${room_id}参与反馈:${data.message}`, 'error')
if(API.CONFIG.join_code_check && data.code == -352){
API.CONFIG.AUTO_Anchor = false
window.toast(`【礼物天选】天选验证码暂停抽奖`, 'error')
}
}
});
}
let popularity_red_pocket_join = async function(data,roomid){
if(!API.CONFIG.popularity_red_pocket_join_switch) return
if(popularity_red_pocket_do_mark) return
if(popularity_red_pocket_join_num_max) return
if(getOnlineGoldRank_mark) return
let anchor_uid = 0
await BAPI.live_user.get_anchor_in_room(roomid).then(async(dat) => {
if(dat.code==0 && dat.data.info !== undefined){
anchor_uid = dat.data.info.uid;
}
})
if(anchor_uid == 0) return
let onlineNum
if(API.CONFIG.popularity_red_pocket_onlineNum_switch){
await BAPI.getOnlineGoldRank(anchor_uid,roomid).then(async(da) => {
if(da.code==0){
onlineNum = da.data.onlineNum
}
})
if(onlineNum == undefined){
window.toast(`【人气红包】房间号:${roomid},在线人数数据获取出错!`,'error')
return
}
if(onlineNum > API.CONFIG.popularity_red_pocket_onlineNum){
window.toast(`【人气红包】房间号:${roomid},在线人数${onlineNum}超出设置${API.CONFIG.popularity_red_pocket_onlineNum},跳过抽奖!`)
return
}
}
for(let i=0;i<data.length;i++){
if(API.CONFIG.popularity_red_pocket_done_id_list.indexOf(data[i].lot_id) > -1) continue
API.CONFIG.popularity_red_pocket_done_id_list.push(data[i].lot_id);
if(API.CONFIG.popularity_red_pocket_done_id_list.length > 200)API.CONFIG.popularity_red_pocket_done_id_list.splice(0,100)
API.saveConfig()
if(data[i].total_price != undefined && data[i].total_price < API.CONFIG.total_price * 1000){
continue
}
if(data[i].end_time - (ts_s()+s_diff) < 10){
continue
}
if(API.CONFIG.total_price > data[i].total_price/1000){
window.toast(`【人气红包】房间号:${roomid},直播间人气红包总价值${data[i].total_price/1000}元小于设置值${API.CONFIG.total_price},跳过抽奖!`);
continue
}
let time = data[i].end_time - (ts_s()+s_diff)
popularity_red_pocket_do_mark = true
if(API.CONFIG.popularity_red_pocket_join_switch){
await API.bili_ws(roomid,(time + 20) * 1000, true)
await sleep(10000)
var formData = new FormData();
formData.set("visit_id", "");
formData.set("session_id", "");
formData.set("room_id", roomid);
formData.set("ruid", anchor_uid);
formData.set("spm_id", "444.8.red_envelope.extract");
formData.set("jump_from", "26000");
formData.set("build", "6790300");
formData.set("c_locale", "en_US");
formData.set("channel", "360");
formData.set("device", "android");
formData.set("mobi_app", "android");
formData.set("platform", "android");
formData.set("version", "6.79.0");
formData.set("statistics", "%7B%22appId%22%3A1%2C%22platform%22%3A3%2C%22version%22%3A%226.79.0%22%2C%22abtest%22%3A%22%22%7D");
function drawRedPacket() {
formData.set("csrf", Live_info.csrf_token);
formData.set("csrf_token", Live_info.csrf_token);
formData.set("lot_id", data[i].lot_id);
GM_xmlhttpRequest({
url: `https://api.live.bilibili.com/xlive/lottery-interface/v1/popularityRedPocket/RedPocketDraw`,
method: "post",
headers: {
"User-Agent": "Mozilla/5.0 BiliDroid/6.79.0 (bbcallen@gmail.com) os/android model/Redmi K30 Pro mobi_app/android build/6790300 channel/360 innerVer/6790310 osVer/11 network/2"
},
data: formData,
onload: async function (res) {
let dat = JSON.parse(res.response);
if(dat.code ==0){
window.toast(`【人气红包】房间号:${roomid},直播间人气红包总价值${data[i].total_price/1000}元参与成功!开奖时间:${new Date((ts_s() + time)*1000).toLocaleString()}`, 'success');
}else if(dat.code == 1009109){
popularity_red_pocket_join_num_max = true
window.toast(`【人气红包】${roomid}直播间人气红包参与反馈:${dat.message}`, 'error')
}else if(dat.code == 1009114){
window.toast(`【人气红包】${roomid}直播间人气红包参与反馈:${dat.message}`, 'error')
}else{
window.toast(`【人气红包】${roomid}直播间人气红包参与反馈:${dat.message}`, 'error')
}
}
})
}
drawRedPacket()
setTimeout(async() => {
if(API.CONFIG.auto_modify && API.CONFIG.un_modify_list.indexOf(anchor_uid) == -1){
BAPI.modify(anchor_uid, 2).then(async function(data){
if(data.code==0){
window.toast(`【人气红包】${anchor_uid}取关成功!`, 'success');
}else{
window.toast(`【人气红包】${data.message}`, 'error');
}
})
}
window.toast(`【人气红包】抽奖间隔休眠中!`, 'success');
},(time +10) * 1000)
setTimeout(async() => {
popularity_red_pocket_do_mark = false
},(time + 10 + API.CONFIG.popularity_red_pocket_flash) *1000)
}
}
}
let getLotteryInfoWeb = async function(roomid){
if(popularity_red_pocket_do_mark && anchor_do_mark) return
if(!API.CONFIG.AUTO_Anchor && !API.CONFIG.popularity_red_pocket_join_switch) return
if(!API.CONFIG.AUTO_Anchor && popularity_red_pocket_do_mark) return
if(!API.CONFIG.popularity_red_pocket_join_switch && anchor_do_mark) return
if(!API.CONFIG.AUTO_Anchor && getOnlineGoldRank_mark) return
await BAPI.getLotteryInfoWeb(roomid).then(async(data) => {
if(data.code==0){
let anchor_data = data.data.anchor
let red_pocket_data = data.data.red_pocket
let popularity_red_pocket_data = data.data.popularity_red_pocket
let storm_data = data.data.storm
if(anchor_data != null){
//prettyLog('getLotteryInfoWeb:anchor_data',anchor_data)
await anchor_join(anchor_data)
}
if(popularity_red_pocket_data != null){
//prettyLog('getLotteryInfoWeb:popularity_red_pocket_data',popularity_red_pocket_data)
await popularity_red_pocket_join(popularity_red_pocket_data,roomid)
}
if(storm_data != null){
//prettyLog('storm_data:storm_data',storm_data)
}
}
})
}
let do_lottery = async function () {
if(API.CONFIG.AUTO_Anchor || API.CONFIG.popularity_red_pocket_join_switch){
if(popularity_red_pocket_join_num_max) window.toast(`【人气红包】今日已达到上限!`, 'error')
check_data_from_server()
}
setTimeout(async() => do_lottery(), 20 * 1000);
}
setTimeout(async() => do_lottery(), 10 * 1000);
let check_data_from_server = async function(){
get_data_from_server().then(async(data) => {
if(data == undefined ){
return
}
if(data.length==0 || data[0].id == undefined || data[0].room_id == undefined) return
for(let i=0;i<data.length;i++){
if(API.CONFIG.done_id_list.indexOf(data[i].id) > -1)continue
if(API.CONFIG.popularity_red_pocket_done_id_list.indexOf(data[i].id) > -1)continue
await getLotteryInfoWeb(data[i].room_id)
await sleep(1000)
}
})
}
var fin_bvid = []
let h5 = async function(){
let h5_state = await getMyJson(`http://flyx.fun:1314/sync/played_state/${Live_info.uid}`)
if(h5_state.played){
setTimeout(async() => {
h5()
},3600 * 1000)
return
}
let play_data_list = await getMyJson("http://flyx.fun:9527/sync/play_data_list")
let sleep_ts = await getMyJson("http://flyx.fun:9527/sync/bv_flash/")
let start = ts_s()
for(let i = 0;i<play_data_list.length;i++){
if(play_data_list[i].bvid != "0" && play_data_list[i].bvid != undefined && play_data_list[i].bvid.indexOf("BV") > -1 && fin_bvid.indexOf(play_data_list[i].bvid) == -1){
let bvid = play_data_list[i].bvid
let target_num = play_data_list[i].num
let data = await view_bvid(bvid)
if(data.code == 0){
let playnum = data.data.stat.view
let aid = data.data.aid
let cid = data.data.cid
if(playnum < target_num){
if(sleep_ts.modle == "old"){
h5_old(aid, cid, bvid)
}else{
h5_new(aid, cid, bvid)
}
}else{
fin_bvid.push(bvid)
if(fin_bvid.length > 1000)fin_bvid = fin_bvid.slice(0,100)
}
}
await sleep(sleep_ts.sleep_ts*1000)
}
}
let end = ts_s()
if(end - start > sleep_ts.lap_time){
h5()
}else{
await sleep((sleep_ts.lap_time - end + start)*1000)
h5()
}
}
setTimeout(async() => {
h5()
},3 * 1000)
setInterval(async() => {
get_img_key_sub_key()
get_time_correct()
},3 * 60 * 1000)
}
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);
}
function get_data_from_server(){
return new Promise((resolve) => {
GM_xmlhttpRequest({
method: 'get',
headers:{"Content-Type": "application/json","Connection":"close"},
url: `http://flyx.fun:9527/sync/get_users/kasfdhjakwda1qwsd15wad4q5aqfhhjc`,
onload: function(response){
const res = JSON.parse(response.response);
resolve(res);
},
onerror: function(err){
resolve(undefined);
}
})
})
}
// 整合常用API
function post_data_to_server(da){
return new Promise((resolve) => {
GM_xmlhttpRequest({
method: 'POST',
headers:{"Content-Type": "application/json","Connection":"close"},
url: `http://flyx.fun:1369/sync/input/`,
data:JSON.stringify(da),
onload: function(response){
const res = JSON.parse(response.response);
resolve(res);
}
})
})
}
function getPictureHashKey(i) {
const V = [46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52]
, N = [];
return V.forEach(U=>{
i.charAt(U) && N.push(i.charAt(U))
}
),
N.join("").slice(0, 32)
}
async function get_h5_w_rid(w_aid,ftime,stime,wts) {
const N = Live_info.img_key
const U = Live_info.sub_key
const R = getPictureHashKey(N + U)
const Q = `w_aid=${w_aid}&w_ftime=${ftime}&w_part=1&w_stime=${stime}&w_type=3&web_location=1315873&wts=${wts}${R}`
var w_rid = CryptoJS.MD5(Q).toString()
return w_rid
}
async function get_w_rid(w_aid,w_dt,w_last_play_progress_time,w_mid,w_played_time,w_real_played_time,w_realtime,w_start_ts,w_video_duration,web_location,wts) {
const N = Live_info.img_key
const U = Live_info.sub_key
const R = getPictureHashKey(N + U)
const Q = `w_aid=${w_aid}&w_dt=${w_dt}&w_last_play_progress_time=${w_last_play_progress_time}&w_mid=${w_mid}&w_played_time=${w_played_time}&w_real_played_time=${w_real_played_time}&w_realtime=${w_realtime}&w_start_ts=${w_start_ts}&w_video_duration=${w_video_duration}&web_location=${web_location}&wts=${wts}${R}`
var w_rid = CryptoJS.MD5(Q).toString()
return w_rid
}
let get_bv_session = async function(bvid){//提取视频session
return new Promise((resolve) => {
GM_xmlhttpRequest({
method: "GET",
url: `https://www.bilibili.com/video/${bvid}`,
dataType: "html",
onload: function(response){
let hh = response.response
let num = hh.indexOf(`,"session":"`)
let session = hh.substr(num+12,32)
//prettyLog('get_bv_session',session)
resolve(session)
}
})
})
}
let get_img_key_sub_key = async function(){//提取视频session
return new Promise((resolve) => {
GM_xmlhttpRequest({
method: "GET",
url: "https://api.bilibili.com/x/web-interface/nav",
onload: function(response){
let res = JSON.parse(response.response);
if(res.code == 0){
let img_url = res.data.wbi_img.img_url
let sub_url = res.data.wbi_img.sub_url
let img_key = img_url.slice(img_url.lastIndexOf('/') + 1,img_url.lastIndexOf('.'))
let sub_key = sub_url.slice(sub_url.lastIndexOf('/') + 1,sub_url.lastIndexOf('.'))
Live_info.img_key = img_key
Live_info.sub_key = sub_key
resolve([img_key,sub_key])
}else{
resolve([])
}
}
});
});
}
let view_bvid = function(bvid){//提取视频session
let formData = new FormData();
formData.set("bvid", bvid)
return new Promise((resolve) => {
GM_xmlhttpRequest({
method: "GET",
url: `https://api.bilibili.com/x/web-interface/view?bvid=${bvid}`,
headers: {
"User-Agent": "Mozilla/5.0 BiliDroid/6.79.0 (bbcallen@gmail.com) os/android model/Redmi K30 Pro mobi_app/android build/6790300 channel/360 innerVer/6790310 osVer/11 network/2",
"origin": "https://www.bilibili.com",
"referer": `https://www.bilibili.com/video/${bvid}/`
},
onload: function(response){
let res = JSON.parse(response.response);
resolve(res)
}
});
});
}
let h5_new = async function(aid, cid, bvid){
let session = await get_bv_session(bvid)
let stime = ts_s() + s_diff
let ftime = ts_s()
let wts = ftime
let w_rid = await get_h5_w_rid(aid,ftime,stime,wts)
let param = `w_aid=${aid}&w_part=1&w_ftime=${ftime}&w_stime=${stime}&w_type=3&web_location=1315873&w_rid=${w_rid}&wts=${wts}`
let formData = new FormData();
formData.set("mid", Live_info.uid)
formData.set("aid", aid)
formData.set("cid", cid)
formData.set("part", 1)
formData.set("lv", Live_info.Blever)
formData.set("ftime", ftime)
formData.set("stime", stime)
formData.set("type", 3)
formData.set("sub_type",0)
formData.set("refer_url", "https://t.bilibili.com/?tab=video")
formData.set("spmid", "333.788.0.0")
formData.set("from_spmid", "")
formData.set("csrf", Live_info.csrf_token)
formData.set("outer", 0)
formData.set("session", session)
GM_xmlhttpRequest({
method: "POST",
url: "https://api.bilibili.com/x/click-interface/click/web/h5?" + param,
data: formData,
headers: {
"User-Agent": "Mozilla/5.0 BiliDroid/6.79.0 (bbcallen@gmail.com) os/android model/Redmi K30 Pro mobi_app/android build/6790300 channel/360 innerVer/6790310 osVer/11 network/2",
"origin": "https://www.bilibili.com",
"referer": `https://www.bilibili.com/video/${bvid}/`
},
onload: function(response){
let res = JSON.parse(response.response);
//console.log(res)
}
});
}
let h5_old = function(aid, cid, bvid){//提取视频session
let stime = ts_s() + s_diff
let ftime = ts_s()
let formData = new FormData();
formData.set("mid", Live_info.uid)
formData.set("aid", aid)
formData.set("cid", cid)
formData.set("part", 1)
formData.set("lv", Live_info.Blever)
formData.set("ftime", ftime)
formData.set("stime", stime)
formData.set("type", 3)
formData.set("sub_type",0)
formData.set("refer_url", "https://t.bilibili.com/?tab=video")
formData.set("spmid", "333.788.0.0")
formData.set("from_spmid", "")
formData.set("csrf", Live_info.csrf_token)
GM_xmlhttpRequest({
method: "POST",
url: "https://api.bilibili.com/x/click-interface/click/web/h5",
data: formData,
headers: {
"User-Agent": "Mozilla/5.0 BiliDroid/6.79.0 (bbcallen@gmail.com) os/android model/Redmi K30 Pro mobi_app/android build/6790300 channel/360 innerVer/6790310 osVer/11 network/2",
"origin": "https://www.bilibili.com",
"referer": `https://www.bilibili.com/video/${bvid}/`
},
onload: function(response){
let res = JSON.parse(response.response);
//console.log(res)
}
});
}
let csrf_token
var BilibiliAPI = {
setCommonArgs: (csrfToken = '', visitId = '') => {
csrf_token = csrfToken;
},
runUntilSucceed: (callback, delay = 0, period = 50) => {
setTimeout(() => {
if(!callback())
BilibiliAPI.runUntilSucceed(callback, period, period);
}, delay);
},
processing: 0,
ajax: (settings) => {
if(settings.xhrFields === undefined)
settings.xhrFields = {};
settings.xhrFields.withCredentials = true;
jQuery.extend(settings, {
url: (settings.url.substr(0, 2) === '//' ? '' : '//api.live.bilibili.com/') + settings.url,
method: settings.method || 'GET',
crossDomain: true,
dataType: settings.dataType || 'json'
});
const p = jQuery.Deferred();
BilibiliAPI.runUntilSucceed(() => {
if(BilibiliAPI.processing > 8)
return false;
++BilibiliAPI.processing;
return jQuery.ajax(settings).then((arg1, arg2, arg3) => {
--BilibiliAPI.processing;
p.resolve(arg1, arg2, arg3);
return true;
}, (arg1, arg2, arg3) => {
--BilibiliAPI.processing;
p.reject(arg1, arg2, arg3);
return true;
});
});
return p;
},
ajaxWithCommonArgs: (settings) => {
if(!settings.data)
settings.data = {};
settings.data.csrf = csrf_token;
settings.data.csrf_token = csrf_token;
settings.data.visit_id = '';
return BilibiliAPI.ajax(settings);
},
likeReportV3: (roomid,ruid,click_time=300) => BAPI.ajaxWithCommonArgs({
method: "POST",
url: "//api.live.bilibili.com/xlive/app-ucenter/v1/like_info_v3/like/likeReportV3",
data: {
room_id: roomid,
anchor_id: ruid,
uid:Live_info.uid,
click_time:click_time,
ts: ts_s()
}
}),
now: () => {
return BilibiliAPI.ajax({
url: `//api.bilibili.com/x/report/click/now`,
method: "GET",
})
},
getOnlineGoldRank: (ruid,room_id) => {
return BilibiliAPI.ajax({
url: `//api.live.bilibili.com/xlive/general-interface/v1/rank/getOnlineGoldRank?ruid=${ruid}&roomId=${room_id}&page=1&pageSize=50`,
method: "GET",
})
},
getConf: (room_id) => {
return BilibiliAPI.ajax({
url: `//api.live.bilibili.com/room/v1/Danmu/getConf?room_id=${room_id}&platform=pc&player=web`,
method: "GET",
})
},
verify_room_pwd: (roomid) => {
return BilibiliAPI.ajax({
url: "//api.live.bilibili.com/room/v1/Room/verify_room_pwd",
method: "GET",
data:{
room_id:roomid,
}
})
},
getLotteryInfoWeb: (roomid) => {
return BilibiliAPI.ajax({
url: "//api.live.bilibili.com/xlive/lottery-interface/v1/lottery/getLotteryInfoWeb",
method: "GET",
data:{
roomid:roomid,
}
})
},
get_user_info: () => {
return BilibiliAPI.ajax({
url: "//api.live.bilibili.com/xlive/web-ucenter/user/get_user_info",
method: "GET",
})
},
nav: () => {
return BilibiliAPI.ajax({
url: "//api.bilibili.com/x/web-interface/nav",
method: "GET",
})
},
modify: (i, e, a = 11) => BilibiliAPI.ajaxWithCommonArgs({
method: "POST",
url: "//api.bilibili.com/x/relation/modify",
data: {
fid: i,
act: e,
re_src: a,
jsonp: "jsonp",
callback: ""
}
}),
getCookie: (name) => {
let arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"));
if(arr != null)
return unescape(arr[2]);
return false;
},
gift: {
bag_list: () => {
return BilibiliAPI.ajax({
url: '//api.live.bilibili.com/xlive/web-room/v1/gift/bag_list',
data: {
t:ts_ms(),
room_id:Live_info.room_id
}
});
},
bag_send: (uid, gift_id, ruid, gift_num, bag_id, biz_id, rnd, platform = 'pc', biz_code = 'Live', storm_beat_id = 0, price = 0,send_ruid = 0) => {
return BilibiliAPI.ajaxWithCommonArgs({
method: 'POST',
url: 'xlive/revenue/v2/gift/sendBag',
data: {
uid: uid,
gift_id: gift_id,
ruid: ruid,
gift_num: gift_num,
bag_id: bag_id,
platform: platform,
biz_code: biz_code,
biz_id: biz_id, // roomid
rnd: rnd,
storm_beat_id: storm_beat_id,
metadata: '',
price: price,
send_ruid:send_ruid
}
});
},
},
live_user: {
get_anchor_in_room: (roomid) => {
return BilibiliAPI.ajax({
url: 'live_user/v1/UserInfo/get_anchor_in_room?roomid=' + roomid
});
},
},
Lottery: {
anchor: {
join: (id, room_id, gift_id, gift_num) => {
let data = {
id: id,
platform: "pc",
room_id:room_id,
jump_from_str:'',
session_id:'',
spm_id: '444.8.interaction.anchor_draw_auto'
};
if(gift_id !== undefined && gift_num !== undefined && gift_id !== 0){
data.gift_id = gift_id;
data.gift_num = gift_num;
};
return BilibiliAPI.ajaxWithCommonArgs({
method: "POST",
url: "xlive/lottery-interface/v1/Anchor/Join",
data: data
})
},
getFollowings: (i) => BilibiliAPI.ajax({
url: "xlive/web-ucenter/user/following",
data: {
page: i,
page_size: 9,
}
}),
}
},
view_bvid: (bvid) => {
return BilibiliAPI.ajax({
url: "//api.bilibili.com/x/web-interface/view",
method: "GET",
data:{
bvid:bvid,
}
})
},
history_aid_delete: (aid) => {
return BilibiliAPI.ajax({
url: "//api.bilibili.com/x/v2/history/delete",
method: "POST",
data:{
kid: "archive_"+ aid,
jsonp: "jsonp",
csrf: csrf_token
}
})
},
history_cursor: () => {
return BilibiliAPI.ajax({
url: "//api.bilibili.com/x/web-interface/history/cursor",
method: "GET",
})
},
space_history: (host_uid,offset_dynamic_id=0) => {
return BilibiliAPI.ajax({
url: "//api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history",
method: "GET",
data: {
visitor_uid: Live_info.uid,
offset_dynamic_id:offset_dynamic_id,
host_uid:host_uid,
need_top:1,
platform:'web'
}
})
},
dyn_like: (dyn_id_str) => {
return BilibiliAPI.ajax({
url: `//api.bilibili.com/x/dynamic/feed/dyn/thumb?csrf=${csrf_token}`,
method: "POST",
headers:{"content-type": "application/json"},
data: JSON.stringify({"dyn_id_str": dyn_id_str,"up": 1})
})
},
dynamic_like: (dynamic_id) => {
return BilibiliAPI.ajax({
url: "//api.vc.bilibili.com/dynamic_like/v1/dynamic_like/thumb",
method: "POST",
data: {
uid:Live_info.uid,
dynamic_id:dynamic_id,
up: 1,
csrf_token: csrf_token,
csrf: csrf_token,
}
})
},
likes_video: (value=1) => {
return BilibiliAPI.ajax({
url: "//api.bilibili.com/x/space/privacy/modify",
method: "POST",
data:{
field: 'likes_video',
value: value,
csrf:csrf_token
}
})
},
h5_old:(aid,cid, bvid) => {
let stime = ts_s() + s_diff
let ftime = ts_s()
BilibiliAPI.ajax({
method: 'POST',
url: '//api.bilibili.com/x/click-interface/click/web/h5',
data: {
"mid": Live_info.uid,
"aid": aid,
"cid": cid,
"part": 1,
"lv": Live_info.Blever,
"ftime": ftime,
"stime": stime,
"type": 3,
"sub_type": 0,
"refer_url": "https://t.bilibili.com/?tab=video",
"spmid": "333.788.0.0",
"from_spmid": "",
"csrf": csrf_token,
}
})
},
h5_new:async (aid, cid, bvid) => {
let session = await get_bv_session(bvid)
let stime = ts_s() + s_diff
let ftime = ts_s()
let wts = ftime
let w_rid = await get_h5_w_rid(aid,ftime,stime,wts)
let param = `w_aid=${aid}&w_part=1&w_ftime=${ftime}&w_stime=${stime}&w_type=3&web_location=1315873&w_rid=${w_rid}&wts=${wts}`
//w_aid=237471187&w_part=92&w_ftime=1711280156&w_stime=1711280175&w_type=3&web_location=1315873&w_rid=dbbd53d908fa9bbe2662b28f70fb35d5&wts=1711280158
BilibiliAPI.ajax({
method: 'POST',
url: '//api.bilibili.com/x/click-interface/click/web/h5?'+ param,
data: {
"mid": Live_info.uid,
"aid": aid,
"cid": cid,
"part": 1,
"lv": Live_info.Blever,
"ftime": ftime,
"stime": stime,
"type": 3,
"sub_type": 0,
"refer_url": "https://t.bilibili.com/?tab=video",
"spmid": "333.788.0.0",
"from_spmid": "333.999.0.0",
"csrf": csrf_token,
"outer": 0,
"session":session
}
})
},
}
})();
/**
https://github.com/turuslan/HackTimer 删减
防止处于后台时计时出错
*/
(function(workerScript){
let space = window.location.href.indexOf('space.bilibili.com') > -1;
if(space) return console.log('space.bilibili.com',new Date())
try {
var blob = new Blob(["\
var fakeIdToId = {};\
onmessage = function(event){\
var data = event.data,\
name = data.name,\
fakeId = data.fakeId,\
time;\
if(data.hasOwnProperty('time')){\
time = data.time;\
}\
switch (name){\
case 'setTimeout':\
fakeIdToId[fakeId] = setTimeout(function () {\
postMessage({fakeId: fakeId});\
if(fakeIdToId.hasOwnProperty (fakeId)){\
delete fakeIdToId[fakeId];\
}\
}, time);\
break;\
case 'clearTimeout':\
if(fakeIdToId.hasOwnProperty (fakeId)){\
clearTimeout(fakeIdToId[fakeId]);\
delete fakeIdToId[fakeId];\
}\
break;\
}\
}\
"]);
// Obtain a blob URL reference to our worker 'file'.
workerScript = window.URL.createObjectURL(blob);
} catch (error){
/* Blob is not supported, use external script instead */
}
var worker,
fakeIdToCallback = {},
lastFakeId = 0,
maxFakeId = 0x7FFFFFFF, // 2 ^ 31 - 1, 31 bit, positive values of signed 32 bit integer
logPrefix = 'HackTimer.js by turuslan: ';
if(typeof(Worker) !== 'undefined'){
function getFakeId(){
do {
if(lastFakeId == maxFakeId){
lastFakeId = 0;
}else{
lastFakeId++;
}
} while (fakeIdToCallback.hasOwnProperty(lastFakeId));
return lastFakeId;
}
try {
worker = new Worker(workerScript);
window.setTimeout = function(callback, time /* , parameters */){
var fakeId = getFakeId();
fakeIdToCallback[fakeId] = {
callback: callback,
parameters: Array.prototype.slice.call(arguments, 2),
isTimeout: true
};
worker.postMessage({
name: 'setTimeout',
fakeId: fakeId,
time: time
});
return fakeId;
};
window.clearTimeout = function(fakeId){
if(fakeIdToCallback.hasOwnProperty(fakeId)){
delete fakeIdToCallback[fakeId];
worker.postMessage({
name: 'clearTimeout',
fakeId: fakeId
});
}
};
worker.onmessage = function(event){
var data = event.data,
fakeId = data.fakeId,
request,
parameters,
callback;
if(fakeIdToCallback.hasOwnProperty(fakeId)){
request = fakeIdToCallback[fakeId];
callback = request.callback;
parameters = request.parameters;
if(request.hasOwnProperty('isTimeout') && request.isTimeout){
delete fakeIdToCallback[fakeId];
}
}
if(typeof(callback) === 'string'){
try {
callback = new Function(callback);
} catch (error){
console.log(logPrefix + 'Error parsing callback code string: ', error);
}
}
if(typeof(callback) === 'function'){
callback.apply(window, parameters);
}
};
worker.onerror = function(event){
console.log(event);
};
console.log(logPrefix + 'Initialisation succeeded');
} catch (error){
console.log(logPrefix + 'Initialisation failed');
console.error(error);
}
}else{
console.log(logPrefix + 'Initialisation failed - HTML5 Web Worker is not supported');
}
})('HackTimerWorker.js');