mirror of
https://github.com/lkeme/BiliHelper-personal.git
synced 2025-12-19 09:30:10 +08:00
[update] Version 0.6.0
This commit is contained in:
parent
8a38ad85a8
commit
962b7d46a3
14
CHANGELOG.md
14
CHANGELOG.md
@ -1,6 +1,20 @@
|
||||
# Release Notes
|
||||
# 本项目Log
|
||||
|
||||
## v0.6.0.200730 alpha (2020-07-30)
|
||||
|
||||
### Added
|
||||
- 添加小心心支持
|
||||
-
|
||||
|
||||
### Changed
|
||||
- 更新天选过滤关键词
|
||||
-
|
||||
|
||||
### Fixed
|
||||
- 修复节奏风暴逻辑错误
|
||||
-
|
||||
|
||||
## v0.5.0.200625 alpha (2020-06-25)
|
||||
|
||||
### Added
|
||||
|
||||
55
DOC.md
55
DOC.md
@ -2,7 +2,7 @@
|
||||
<p align="center"><img width="300px" src="https://i.loli.net/2018/04/20/5ad97bd395912.jpeg"></p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/version-0.5.0.200625 alpha-green.svg?longCache=true&style=for-the-badge">
|
||||
<img src="https://img.shields.io/badge/version-0.6.0.200730 alpha-green.svg?longCache=true&style=for-the-badge">
|
||||
<img src="https://img.shields.io/badge/license-mit-blue.svg?longCache=true&style=for-the-badge">
|
||||
</p>
|
||||
|
||||
@ -15,32 +15,33 @@ B 站直播实用脚本
|
||||
|
||||
|plugin |version |description |
|
||||
|--------------------|--------------------|--------------------|
|
||||
|Login |20.06.24 |账号登录 |
|
||||
|Schedule |20.06.24 |休眠控制 |
|
||||
|MasterSite |20.06.24 |主站助手 |
|
||||
|Daily |20.06.24 |每日礼包 |
|
||||
|Heart |20.06.24 |双端心跳 |
|
||||
|Task |20.06.24 |每日任务 |
|
||||
|Silver |20.06.24 |银瓜子宝箱 |
|
||||
|Barrage |20.06.24 |活跃弹幕 |
|
||||
|Silver2Coin |20.06.24 |银瓜子换硬币 |
|
||||
|GiftSend |20.06.24 |礼物赠送 |
|
||||
|Judge |20.06.24 |风纪 |
|
||||
|GroupSignIn |20.06.24 |友爱社签到 |
|
||||
|ManGa |20.06.24 |漫画签到分享 |
|
||||
|Match |20.06.24 |赛事签到分享 |
|
||||
|GiftHeart |20.06.24 |心跳礼物 |
|
||||
|MaterialObject |20.06.24 |实物抽奖 |
|
||||
|AloneTcpClient |20.06.24 |独立监控 |
|
||||
|ZoneTcpClient |20.06.24 |分区监控 |
|
||||
|StormRaffle |20.06.24 |节奏风暴 |
|
||||
|GiftRaffle |20.06.24 |活动礼物 |
|
||||
|PkRaffle |20.06.24 |大乱斗 |
|
||||
|GuardRaffle |20.06.24 |舰长总督 |
|
||||
|AnchorRaffle |20.06.24 |天选时刻 |
|
||||
|AwardRecord |20.06.24 |获奖通知 |
|
||||
|Statistics |20.06.24 |数据统计 |
|
||||
|Competition |20.06.24 |赛事竞猜 |
|
||||
|Login |20.07.30 |账号登录 |
|
||||
|Schedule |20.07.30 |休眠控制 |
|
||||
|MasterSite |20.07.30 |主站助手 |
|
||||
|Daily |20.07.30 |每日礼包 |
|
||||
|Heart |20.07.30 |双端心跳 |
|
||||
|Task |20.07.30 |每日任务 |
|
||||
|Silver |20.07.30 |银瓜子宝箱 |
|
||||
|Barrage |20.07.30 |活跃弹幕 |
|
||||
|Silver2Coin |20.07.30 |银瓜子换硬币 |
|
||||
|GiftSend |20.07.30 |礼物赠送 |
|
||||
|Judge |20.07.30 |风纪 |
|
||||
|GroupSignIn |20.07.30 |友爱社签到 |
|
||||
|ManGa |20.07.30 |漫画签到分享 |
|
||||
|Match |20.07.30 |赛事签到分享 |
|
||||
|GiftHeart |20.07.30 |心跳礼物 |
|
||||
|MaterialObject |20.07.30 |实物抽奖 |
|
||||
|AloneTcpClient |20.07.30 |独立监控 |
|
||||
|ZoneTcpClient |20.07.30 |分区监控 |
|
||||
|StormRaffle |20.07.30 |节奏风暴 |
|
||||
|GiftRaffle |20.07.30 |活动礼物 |
|
||||
|PkRaffle |20.07.30 |大乱斗 |
|
||||
|GuardRaffle |20.07.30 |舰长总督 |
|
||||
|AnchorRaffle |20.07.30 |天选时刻 |
|
||||
|AwardRecord |20.07.30 |获奖通知 |
|
||||
|Statistics |20.07.30 |数据统计 |
|
||||
|Competition |20.07.30 |赛事竞猜 |
|
||||
|SmallHeart |20.07.30 |小心心 |
|
||||
|
||||
## 打赏赞助
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **仅用于BUG提交
|
||||
|
||||
## 公告
|
||||
|
||||
> Currently for Personal Edition **0.5.0.200625 alpha**
|
||||
> Currently for Personal Edition **0.6.0.200730 alpha**
|
||||
|
||||
```notice
|
||||
---- 免费的东西总是得不到人的珍惜。
|
||||
@ -28,4 +28,3 @@ Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **仅用于BUG提交
|
||||
## 效果
|
||||
|
||||

|
||||
|
||||
|
||||
@ -94,6 +94,10 @@ USE_SC=false
|
||||
SC_KEY=
|
||||
SC_FILTER_WORDS=
|
||||
|
||||
# 小心心|加密服务器(开源)|
|
||||
USE_HEARTBEAT=true
|
||||
ENC_SERVER=http://116.85.43.27:3000/enc
|
||||
|
||||
#######################
|
||||
# 房间设置 #
|
||||
#######################
|
||||
@ -154,4 +158,4 @@ APP_CALLBACK="http://www.example.com/api.send?text={account}[{level}]: {message}
|
||||
# WARNING 300
|
||||
# ERROR 400
|
||||
#
|
||||
APP_CALLBACK_LEVEL=400
|
||||
APP_CALLBACK_LEVEL=400
|
||||
@ -80,6 +80,7 @@ class App
|
||||
'GiftSend',
|
||||
'GroupSignIn',
|
||||
'GiftHeart',
|
||||
'SmallHeart',
|
||||
'MaterialObject',
|
||||
'AloneTcpClient',
|
||||
'ZoneTcpClient',
|
||||
|
||||
@ -13,7 +13,7 @@ namespace BiliHelper\Core;
|
||||
class Env
|
||||
{
|
||||
private $app_name = 'BiliHelper Personal';
|
||||
private $app_version = '0.5.0.*';
|
||||
private $app_version = '0.6.0.*';
|
||||
|
||||
/**
|
||||
* Env constructor.
|
||||
|
||||
@ -137,7 +137,14 @@ class AnchorRaffle extends BaseRaffle
|
||||
'房间抽奖', 'CESHI', 'ceshi', '奖品A', '奖品B', '奖品C', '硬币', '无奖品', '白名单', '我是抽奖',
|
||||
'0.1', '五毛二', '一分', '一毛', '0.52', '0.66', '0.01', '0.77', '0.16', '照片', '穷', '0.5',
|
||||
'0.88', '双排', '1毛', '1分', '1角', 'P口罩', '素颜', '写真', '图包', '五毛', '一角', '冥币',
|
||||
'自拍', '日历', '0.22', '加速器', '越南盾'
|
||||
'自拍', '日历', '0.22', '加速器', '越南盾','毛','分','限','0.','角','〇点','①元',
|
||||
'一起玩','不包邮','邮费','续期卡','儿时','闪宠','大师球','一元','两元','两块','赛车',
|
||||
'代币','一块','一局','好友位','通话','首胜','代金券','辣条','补贴','抵用券','主播素颜照',
|
||||
'武器箱棺材板','游戏道具','优惠券','日元','发音课','壹元','零点','舰长五折券','上车',
|
||||
'没有钱','女装','肥宅快乐水','哥斯拉','公主连结','pokemmo','宝可>梦','明日方舟','雪碧','公主连接',
|
||||
'专属头衔','FF14','韩元','空洞骑士','老婆饼','稀世时装','洛克衣服','帮过图','证件照','自抽号',
|
||||
'晶耀之星','伊洛纳','〇.','②元','③元','0·','繁华美化','喵喵喵','闪伊布','①圆','o点','金达摩','嗷呜',
|
||||
'游戏位','S-追光者','OWL','勾玉','跟yo宝游戏','三元','怡宝','蛋闪迷>你冰','哥伦比亚比索','油条'
|
||||
];
|
||||
$custom_words = empty(getenv('ANCHOR_FILTER_WORDS')) ? [] : explode(',', getenv('ANCHOR_FILTER_WORDS'));
|
||||
$total_words = array_merge($default_words, $custom_words);
|
||||
|
||||
@ -180,35 +180,22 @@ class GiftSend
|
||||
protected static function getMedalList()
|
||||
{
|
||||
self::$medal_list = [];
|
||||
$url = 'https://api.live.bilibili.com/i/api/medal';
|
||||
$payload = [
|
||||
'page' => 1,
|
||||
'pageSize' => 25
|
||||
];
|
||||
$data = Curl::get('app', $url, Sign::common($payload));
|
||||
$data = json_decode($data, true);
|
||||
if (isset($data['code']) && $data['code']) {
|
||||
Log::warning('获取勋章列表失败!', ['msg' => $data['message']]);
|
||||
return;
|
||||
$data = Live::fetchMedalList();
|
||||
$fans_medals = [];
|
||||
foreach ($data as $vo) {
|
||||
if (!isset($vo['roomid'])) continue;
|
||||
$fans_medals[(string)$vo['roomid']] = $vo;
|
||||
}
|
||||
Log::info('勋章列表获取成功!');
|
||||
if (isset($data['data']['fansMedalList'])) {
|
||||
$fans_medals = [];
|
||||
foreach ($data['data']['fansMedalList'] as $vo) {
|
||||
if (!isset($vo['roomid'])) continue;
|
||||
$fans_medals[(string)$vo['roomid']] = $vo;
|
||||
// 基于配置
|
||||
foreach (self::$room_list as $room_id) {
|
||||
// 配置是否存在获取
|
||||
if (!array_key_exists((string)$room_id, $fans_medals)) {
|
||||
continue;
|
||||
}
|
||||
// 基于配置
|
||||
foreach (self::$room_list as $room_id) {
|
||||
// 配置是否存在获取
|
||||
if (!array_key_exists((string)$room_id, $fans_medals)) {
|
||||
continue;
|
||||
}
|
||||
$vo = $fans_medals[(string)$room_id];
|
||||
// 是否还需要投喂
|
||||
if ($vo['day_limit'] - $vo['today_feed']) {
|
||||
self::$medal_list[(string)$vo['roomid']] = ($vo['day_limit'] - $vo['today_feed']);
|
||||
}
|
||||
$vo = $fans_medals[(string)$room_id];
|
||||
// 是否还需要投喂
|
||||
if ($vo['day_limit'] - $vo['today_feed']) {
|
||||
self::$medal_list[(string)$vo['roomid']] = ($vo['day_limit'] - $vo['today_feed']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ class Live
|
||||
*/
|
||||
public static function webGetRoomInfo($room_id): array
|
||||
{
|
||||
$url = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?=23058';
|
||||
$url = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom';
|
||||
$payload = [
|
||||
'room_id' => $room_id
|
||||
];
|
||||
@ -266,4 +266,112 @@ class Live
|
||||
return json_decode($raw, true) ?? ['code' => 404, 'msg' => '上层数据为空!'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 获取勋章列表
|
||||
* @param int $page_size
|
||||
* @return array
|
||||
*/
|
||||
public static function fetchMedalList(int $page_size = 100): array
|
||||
{
|
||||
$metal_list = [];
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
$url = 'https://api.live.bilibili.com/i/api/medal';
|
||||
$payload = [
|
||||
'page' => $i,
|
||||
'pageSize' => $page_size
|
||||
];
|
||||
$raw = Curl::get('app', $url, Sign::common($payload));
|
||||
$de_raw = json_decode($raw, true);
|
||||
if (isset($data['code']) && $data['code']) {
|
||||
Log::warning('获取勋章列表失败!', ['msg' => $data['message']]);
|
||||
return $metal_list;
|
||||
}
|
||||
if (empty($de_raw['data']['fansMedalList'])) {
|
||||
return $metal_list;
|
||||
}
|
||||
if (isset($de_raw['data']['fansMedalList'])) {
|
||||
foreach ($de_raw['data']['fansMedalList'] as $vo) {
|
||||
array_push($metal_list, $vo);
|
||||
}
|
||||
}
|
||||
if ($de_raw['data']['pageinfo']['totalpages'] == $de_raw['data']['pageinfo']['curPage']) {
|
||||
return $metal_list;
|
||||
}
|
||||
}
|
||||
Log::info('勋章列表获取成功!');
|
||||
return $metal_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 背包获取单项礼物
|
||||
* @param string $gift_name
|
||||
* @param int $gift_id
|
||||
* @return array
|
||||
*/
|
||||
public static function fetchBagListByGift(string $gift_name, int $gift_id): array
|
||||
{
|
||||
$new_bag_list = [];
|
||||
$payload = [];
|
||||
$url = 'https://api.live.bilibili.com/gift/v2/gift/bag_list';
|
||||
$data = Curl::get('app', $url, Sign::common($payload));
|
||||
$data = json_decode($data, true);
|
||||
if (isset($data['code']) && $data['code']) {
|
||||
Log::warning('背包查看失败!', ['msg' => $data['message']]);
|
||||
return $new_bag_list;
|
||||
}
|
||||
if (isset($data['data']['list'])) {
|
||||
$bag_list = $data['data']['list'];
|
||||
if (count($bag_list)) {
|
||||
// 按过期时间 升序
|
||||
// array_multisort(array_column($bag_list, "gift_id"), SORT_DESC, $bag_list);
|
||||
array_multisort(array_column($bag_list, "expire_at"), SORT_ASC, $bag_list);
|
||||
}
|
||||
foreach ($bag_list as $vo) {
|
||||
// 去除永久礼物
|
||||
if ($vo['corner_mark'] == '永久') continue;
|
||||
if ($vo['gift_id'] == $gift_id && $vo['gift_name'] == $gift_name){
|
||||
array_push($new_bag_list, $vo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $new_bag_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 赠送礼物
|
||||
* @param array $guest // 用户信息
|
||||
* @param array $gift // 礼物信息
|
||||
* @param int $num // 数量
|
||||
*/
|
||||
public static function sendGift(array $guest, array $gift, int $num)
|
||||
{
|
||||
$url = 'https://api.live.bilibili.com/gift/v2/live/bag_send';
|
||||
$user_info = User::parseCookies();
|
||||
$payload = [
|
||||
'uid' => $user_info['uid'], // 自己的UID
|
||||
'gift_id' => $gift['gift_id'],
|
||||
'ruid' => $guest['uid'], // UP的UID
|
||||
'send_ruid' => 0,
|
||||
'gift_num' => $num,
|
||||
'bag_id' => $gift['bag_id'],
|
||||
'platform' => 'pc',
|
||||
'biz_code' => 'live',
|
||||
'biz_id' => $guest['roomid'], // UP的直播间
|
||||
'rnd' => time(), // 时间戳
|
||||
'storm_beat_id' => 0,
|
||||
'metadata' => '',
|
||||
'price' => 0,
|
||||
'csrf' => $user_info['token'],
|
||||
'csrf_token' => $user_info['token']
|
||||
];
|
||||
// {"code":0,"msg":"success","message":"success","data":{"tid":"1595419985112400002","uid":4133274,"uname":"沙奈之朵","face":"https://i2.hdslb.com/bfs/face/eb101ef90ebc4e9bf79f65312a22ebac84946700.jpg","guard_level":0,"ruid":893213,"rcost":30834251,"gift_id":30607,"gift_type":5,"gift_name":"小心心","gift_num":1,"gift_action":"投喂","gift_price":5000,"coin_type":"silver","total_coin":5000,"pay_coin":5000,"metadata":"","fulltext":"","rnd":"1595419967","tag_image":"","effect_block":1,"extra":{"wallet":null,"gift_bag":{"bag_id":210196588,"gift_num":20},"top_list":[],"follow":null,"medal":null,"title":null,"pk":{"pk_gift_tips":"","crit_prob":0},"fulltext":"","event":{"event_score":0,"event_redbag_num":0},"capsule":null},"blow_switch":0,"send_tips":"赠送成功","gift_effect":{"super":0,"combo_timeout":0,"super_gift_num":0,"super_batch_gift_num":0,"batch_combo_id":"","broadcast_msg_list":[],"small_tv_list":[],"beat_storm":null,"smallTVCountFlag":true},"send_master":null,"crit_prob":0,"combo_stay_time":3,"combo_total_coin":0,"demarcation":2,"magnification":1,"combo_resources_id":1,"is_special_batch":0,"send_gift_countdown":6}}
|
||||
$data = Curl::post('app', $url, Sign::common($payload));
|
||||
$data = json_decode($data, true);
|
||||
if (isset($data['code']) && $data['code']) {
|
||||
Log::warning('送礼失败!', ['msg' => $data['message']]);
|
||||
} else {
|
||||
Log::notice("成功向 {$payload['biz_id']} 投喂了 {$num} 个{$gift['gift_name']}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,11 +296,11 @@ class Login
|
||||
'seccode' => $validate ? "{$validate}|jordan" : '',
|
||||
'validate' => $validate,
|
||||
'challenge' => $challenge,
|
||||
'subid' => 1,
|
||||
'permission' => 'ALL',
|
||||
'username' => self::$username,
|
||||
'password' => self::$password,
|
||||
'captcha' => '',
|
||||
'subid' => 1,
|
||||
'cookies' => ''
|
||||
];
|
||||
$raw = Curl::post('app', $url, Sign::login($payload));
|
||||
|
||||
301
src/plugin/SmallHeart.php
Normal file
301
src/plugin/SmallHeart.php
Normal file
@ -0,0 +1,301 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Website: https://mudew.com/
|
||||
* Author: Lkeme
|
||||
* License: The MIT License
|
||||
* Email: Useri@live.cn
|
||||
* Updated: 2020 ~ 2021
|
||||
*/
|
||||
|
||||
namespace BiliHelper\Plugin;
|
||||
|
||||
|
||||
use BiliHelper\Core\Log;
|
||||
use BiliHelper\Core\Curl;
|
||||
use BiliHelper\Util\TimeLock;
|
||||
use BiliHelper\Tool\Generator;
|
||||
|
||||
class SmallHeart
|
||||
{
|
||||
use TimeLock;
|
||||
|
||||
private static $enc_server = null; // 加密服务器 配置文件
|
||||
|
||||
private static $hb_payload = []; // 心跳请求数据
|
||||
private static $hb_headers = []; // 心跳请求头
|
||||
|
||||
private static $hb_count = 0; // 心跳次数 max 24
|
||||
private static $hb_room_info = []; // 心跳带勋章房间信息
|
||||
|
||||
private static $fans_medals = []; // 全部勋章
|
||||
private static $grey_fans_medals = []; // 灰色勋章
|
||||
|
||||
private static $metal_lock = 0; // 勋章时间锁
|
||||
|
||||
public static function run()
|
||||
{
|
||||
if (!self::init()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self::$metal_lock < time()) {
|
||||
self::polishMetal();
|
||||
self::$metal_lock = time() + 8 * 60 * 60;
|
||||
}
|
||||
if (self::getLock() < time()) {
|
||||
self::heartBeat();
|
||||
if (self::$hb_count >= 30) {
|
||||
self::resetVar();
|
||||
self::setLock(self::timing(2));
|
||||
} else {
|
||||
self::setLock(5 * 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 重置变量
|
||||
*/
|
||||
private static function resetVar()
|
||||
{
|
||||
self::$hb_payload = []; // 心跳请求数据
|
||||
self::$hb_headers = []; // 心跳请求头
|
||||
|
||||
self::$hb_count = 0; // 心跳次数 max 24
|
||||
self::$hb_room_info = []; // 心跳带勋章房间信息
|
||||
}
|
||||
|
||||
/**
|
||||
* @use init
|
||||
* @return bool
|
||||
*/
|
||||
private static function init(): bool
|
||||
{
|
||||
if (getenv('USE_HEARTBEAT') == 'false' || getenv('ENC_SERVER') == '') {
|
||||
return false;
|
||||
}
|
||||
if (is_null(self::$enc_server)) {
|
||||
self::$enc_server = getenv('ENC_SERVER');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @use 勋章处理
|
||||
*/
|
||||
private static function polishMetal()
|
||||
{
|
||||
// 灰色勋章
|
||||
self::fetchGreyMedalList();
|
||||
if (empty(self::$grey_fans_medals)) {
|
||||
return;
|
||||
}
|
||||
// 小心心
|
||||
$bag_list = Live::fetchBagListByGift('小心心', 30607);
|
||||
if (empty($bag_list)) {
|
||||
return;
|
||||
}
|
||||
// 擦亮勋章
|
||||
foreach ($bag_list as $gift) {
|
||||
for ($num = 1; $num <= $gift['gift_num']; $num++) {
|
||||
$grey_fans_medal = array_shift(self::$grey_fans_medals);
|
||||
// 为空
|
||||
if (is_null($grey_fans_medal)) break;
|
||||
// 擦亮
|
||||
Live::sendGift($grey_fans_medal, $gift, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @use 心跳处理
|
||||
*/
|
||||
private static function heartBeat()
|
||||
{
|
||||
if (empty(self::$fans_medals)) {
|
||||
return;
|
||||
}
|
||||
if (empty(self::$hb_room_info)) {
|
||||
$metal = self::$fans_medals[array_rand(self::$fans_medals)];
|
||||
$room_info = Live::webGetRoomInfo($metal['roomid']);
|
||||
}
|
||||
if (self::$hb_count == 0) {
|
||||
$e_data = self::eHeartBeat($room_info['data']['room_info']);
|
||||
if (!$e_data['status']) {
|
||||
// 错误级别
|
||||
return;
|
||||
}
|
||||
self::$hb_count += 1;
|
||||
self::$hb_payload = $e_data['payload'];
|
||||
self::$hb_headers = $e_data['headers'];
|
||||
return;
|
||||
}
|
||||
$x_data = self::xHeartBeat(self::$hb_count);
|
||||
if (!$x_data['status']) {
|
||||
// 错误级别
|
||||
return;
|
||||
}
|
||||
self::$hb_count += 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use E心跳
|
||||
* @param array $room_info
|
||||
* @param int $index
|
||||
* @return array|bool[]
|
||||
*/
|
||||
private static function eHeartBeat(array $room_info, $index = 0): array
|
||||
{
|
||||
$url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/E';
|
||||
$headers = [
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
'Origin' => 'https://live.bilibili.com',
|
||||
'Referer' => 'https://live.bilibili.com/' . $room_info['room_id'],
|
||||
];
|
||||
$user_info = User::parseCookies();
|
||||
$payload = [
|
||||
'id' => json_encode([$room_info['parent_area_id'], $room_info['area_id'], $index, $room_info['room_id']], true),
|
||||
'device' => json_encode([
|
||||
Generator::hash(), Generator::uuid4()
|
||||
], true),
|
||||
'ts' => time() * 1000,
|
||||
'is_patch' => 0,
|
||||
'heart_beat' => [],
|
||||
'ua' => 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0',
|
||||
'csrf_token' => $user_info['token'],
|
||||
'csrf' => $user_info['token'],
|
||||
'visit_id' => ''
|
||||
];
|
||||
$raw = Curl::post('pc', $url, $payload, $headers);
|
||||
$de_raw = json_decode($raw, true);
|
||||
// {"code":0,"message":"0","ttl":1,"data":{"timestamp":1595342828,"heartbeat_interval":300,"secret_key":"seacasdgyijfhofiuxoannn","secret_rule":[2,5,1,4],"patch_status":2}}
|
||||
if ($de_raw['code'] != 0) {
|
||||
Log::warning("小心心礼物E-{$index}心跳失败");
|
||||
return ['status' => false];
|
||||
}
|
||||
Log::info("小心心礼物E-{$index}心跳成功");
|
||||
// Log::info($raw);
|
||||
$payload['ets'] = $de_raw['data']['timestamp'];
|
||||
$payload['secret_key'] = $de_raw['data']['secret_key'];
|
||||
$payload['heartbeat_interval'] = $de_raw['data']['heartbeat_interval'];
|
||||
$payload['secret_rule'] = $de_raw['data']['secret_rule'];
|
||||
return [
|
||||
'status' => true,
|
||||
'payload' => $payload,
|
||||
'headers' => $headers,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @use X心跳
|
||||
* @param int $index
|
||||
* @return array|bool[]
|
||||
*/
|
||||
private static function xHeartBeat(int $index = 1): array
|
||||
{
|
||||
$s_data = self::encParamS($index);
|
||||
$s = $s_data['s'];
|
||||
$t = $s_data['payload'];
|
||||
|
||||
$url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/X';
|
||||
$user_info = User::parseCookies();
|
||||
$payload = [
|
||||
's' => $s,
|
||||
'id' => $t['id'],
|
||||
'device' => $t['device'],
|
||||
'ets' => $t['ets'],
|
||||
'benchmark' => $t['benchmark'],
|
||||
'time' => $t['time'],
|
||||
'ts' => $t['ts'],
|
||||
'ua' => $t['ua'],
|
||||
'csrf_token' => $user_info['token'],
|
||||
'csrf' => $user_info['token'],
|
||||
'visit_id' => ''
|
||||
];
|
||||
// print_r($payload);
|
||||
$raw = Curl::post('pc', $url, $payload, self::$hb_headers);
|
||||
$de_raw = json_decode($raw, true);
|
||||
# {"code":0,"message":"0","ttl":1,"data":{"heartbeat_interval":300,"timestamp":1595346846,"secret_rule":[2,5,1,4],"secret_key":"seacasdgyijfhofiuxoannn"}}
|
||||
if ($de_raw['code'] != 0) {
|
||||
Log::warning("小心心礼物X-{$index}心跳失败");
|
||||
return ['status' => false];
|
||||
}
|
||||
self::$hb_payload['ets'] = $de_raw['data']['timestamp'];
|
||||
self::$hb_payload['secret_key'] = $de_raw['data']['secret_key'];
|
||||
self::$hb_payload['heartbeat_interval'] = $de_raw['data']['heartbeat_interval'];
|
||||
Log::info("小心心礼物X-{$index}心跳成功");
|
||||
return ['status' => true];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @use 加密参数S
|
||||
* @param int $index
|
||||
* @return array
|
||||
*/
|
||||
private static function encParamS(int $index): array
|
||||
{
|
||||
// 转换index
|
||||
$temp = json_decode(self::$hb_payload['id'], true);
|
||||
$temp[2] += 1;
|
||||
self::$hb_payload['id'] = json_encode($temp, true);
|
||||
// 加密部分
|
||||
$payload = [
|
||||
't' => [
|
||||
'id' => self::$hb_payload['id'],
|
||||
'device' => self::$hb_payload['device'],
|
||||
'ets' => self::$hb_payload['ets'],
|
||||
'benchmark' => self::$hb_payload['secret_key'],
|
||||
'time' => self::$hb_payload['heartbeat_interval'],
|
||||
'ts' => time() * 1000,
|
||||
'ua' => self::$hb_payload['ua']
|
||||
],
|
||||
'r' => self::$hb_payload['secret_rule']
|
||||
];
|
||||
$headers = [
|
||||
'Content-Type' => 'application/json',
|
||||
];
|
||||
$data = Curl::put('other', self::$enc_server, $payload, $headers);
|
||||
$de_raw = json_decode($data, true);
|
||||
Log::info("S参数加密 {$de_raw['s']}");
|
||||
|
||||
return [
|
||||
's' => $de_raw['s'],
|
||||
'payload' => $payload['t']
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @use 获取灰色勋章列表(过滤无勋章或已满)
|
||||
*/
|
||||
private static function fetchGreyMedalList()
|
||||
{
|
||||
$data = Live::fetchMedalList();
|
||||
$user_info = User::parseCookies();
|
||||
foreach ($data as $vo) {
|
||||
// 过滤主站勋章
|
||||
if (!isset($vo['roomid'])) continue;
|
||||
// 过滤自己勋章
|
||||
if ($vo['target_id'] == $user_info['uid']) continue;
|
||||
// 所有
|
||||
self::$fans_medals[] = [
|
||||
'uid' => $vo['target_id'],
|
||||
'roomid' => $vo['roomid'],
|
||||
];
|
||||
// 灰色
|
||||
if ($vo['medal_color_start'] == 12632256 && $vo['medal_color_end'] == 12632256 && $vo['medal_color_border'] == 12632256) {
|
||||
self::$grey_fans_medals[] = [
|
||||
'uid' => $vo['target_id'],
|
||||
'roomid' => $vo['roomid'],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -24,7 +24,7 @@ class Statistics
|
||||
private static $success_list = [];
|
||||
private static $profit_list = [];
|
||||
|
||||
|
||||
// TODO 统计开关 统计时间间隔 统计类型
|
||||
public static function run()
|
||||
{
|
||||
if (self::getLock() > time()) {
|
||||
|
||||
@ -116,6 +116,7 @@ class StormRaffle extends BaseRaffle
|
||||
// {"code":-412,"message":"请求被拦截","ttl":1,"data":null}
|
||||
if ($de_raw['code'] == -412) {
|
||||
Log::notice(self::formatInfo($raffle['raffle_id'], $num, '触发哔哩哔哩安全风控策略(-412)'));
|
||||
break;
|
||||
}
|
||||
if ($de_raw['code'] == 429 || $de_raw['code'] == -429) {
|
||||
Log::notice(self::formatInfo($raffle['raffle_id'], $num, '节奏风暴未实名或异常验证码'));
|
||||
|
||||
52
src/tool/Generator.php
Normal file
52
src/tool/Generator.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Website: https://mudew.com/
|
||||
* Author: Lkeme
|
||||
* License: The MIT License
|
||||
* Email: Useri@live.cn
|
||||
* Updated: 2020 ~ 2021
|
||||
* Source: https://github.com/anhao/bv2av/
|
||||
*/
|
||||
|
||||
namespace BiliHelper\Tool;
|
||||
|
||||
|
||||
class Generator
|
||||
{
|
||||
/**
|
||||
* @use 生成uuid4
|
||||
* @return string
|
||||
*/
|
||||
public static function uuid4(): string
|
||||
{
|
||||
// 标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx(8-4-4-4-12)
|
||||
// var T = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(t) {
|
||||
// var e = 16 * Math.random() | 0;
|
||||
// return ("x" === t ? e : 3 & e | 8).toString(16)
|
||||
// });
|
||||
$chars = md5(uniqid(mt_rand(), true));
|
||||
$chars = substr_replace($chars, "4", 12, 1);
|
||||
$chars = substr_replace($chars, "a", 16, 1);
|
||||
$uuid = substr($chars, 0, 8) . '-'
|
||||
. substr($chars, 8, 4) . '-'
|
||||
. substr($chars, 12, 4) . '-'
|
||||
. substr($chars, 16, 4) . '-'
|
||||
. substr($chars, 20, 12);
|
||||
return $uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 生成hash
|
||||
* @return string
|
||||
*/
|
||||
public static function hash(): string
|
||||
{
|
||||
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
|
||||
$random = $chars[mt_rand(0, 73)] . $chars[mt_rand(0, 73)] . $chars[mt_rand(0, 73)] . $chars[mt_rand(0, 73)] . $chars[mt_rand(0, 73)];//Random 5 times
|
||||
$content = uniqid() . $random; // 类似 5443e09c27bf4aB4uT
|
||||
return md5($content); // sha1
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user