diff --git a/.github/Issue_Template_CN.md b/.github/ISSUE_TEMPLATE/Issue_Template_CN.md
similarity index 100%
rename from .github/Issue_Template_CN.md
rename to .github/ISSUE_TEMPLATE/Issue_Template_CN.md
diff --git a/.github/Issue_Template_EN.md b/.github/ISSUE_TEMPLATE/Issue_Template_EN.md
similarity index 100%
rename from .github/Issue_Template_EN.md
rename to .github/ISSUE_TEMPLATE/Issue_Template_EN.md
diff --git a/.github/workflows/build_image_bhp.yml b/.github/workflows/build_image_bhp.yml
new file mode 100644
index 0000000..1bf3977
--- /dev/null
+++ b/.github/workflows/build_image_bhp.yml
@@ -0,0 +1,22 @@
+name: "BiliHelper-personal Docker Image Buildx Stable Github"
+on:
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ name: Build BiliHelper-personal Docker Image Build Stable Github
+ steps:
+ - name: Checkout master
+ uses: actions/checkout@master
+ - name: Build and publish image
+ uses: ilteoood/docker_buildx@master
+ with:
+ publish: true
+ imageName: lkeme/bilihelper-personal
+ dockerFile: docker/Dockerfile
+ platform: linux/amd64,linux/arm64,linux/arm/v7
+ # platform: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v8
+ tag: latest
+ dockerUser: ${{ secrets.DOCKER_USERNAME }}
+ dockerPassword: ${{ secrets.DOCKER_PASSWORD }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index dc788fa..e72cf9c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,14 +17,23 @@ gen
/configs/
/tests/
config
-/conf/user*.conf
+/conf/user*.ini
*.log
Traits/
README1.md
-conf/user.conf
-conf/user1.conf
-/conf/user.conf
-/conf/test.conf
-/conf/test1.conf
+conf/user.ini
+conf/user1.ini
+/conf/user.ini
+/conf/test.ini
+/conf/test1.ini
/log/
-/src/backup/
\ No newline at end of file
+/src/backup/
+script.php
+
+# ignore all files in lib/
+task/*
+# except for .gitkeep
+!.gitkeep
+# ignore TODO file in root directory,not subdir/TODO
+/TODO
+/Todo
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 87482ad..4a6ad3a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,12 +1,198 @@
# Release Notes
+
# 本项目Log
+[comment]: <> ()
+
+[comment]: <> ( 更新历史latest
)
+
+[comment]: <> ( )
+
+## v0.9.7.210714 alpha (2021-07-14)
+
+### Added
+
+- 添加脚本模式 `php index.php -?`
+-
+
+### Changed
+
+- 省略
+-
+
+### Fixed
+
+- 省略
+-
+
+### Remarks
+
+- 注意配置文件有些许改动
+- 注意需要重新进行`composer update`操作
+-
+
+## v0.9.6.210625 alpha (2021-06-25)
+
+### Added
+
+-
+
+### Changed
+
+- 优化动态过滤
+- 优化过滤关键字
+- 优化短信登录流程
+-
+
+### Fixed
+
+- 修复动态转发
+-
+
+### Remarks
+
+- 注意配置文件有些许改动
+-
+
+## v0.9.5.210624 alpha (2021-06-24)
+
+### Added
+
+-
+
+### Changed
+
+- 更新动态转发
+- 更新基础环境参数
+-
+
+### Fixed
+
+-
+
+### Remarks
+
+- 注意配置文件有些许改动
+-
+
+## v0.9.4.210623 alpha (2021-06-23)
+
+### Added
+
+-
+
+### Changed
+
+- 更新部分仓库文件
+- 更新基础环境参数
+-
+
+### Fixed
+
+- 修复PC端银瓜子兑换硬币
+- 修复主站投币任务
+- 修复点亮勋章特殊情况
+-
+
+### Remarks
+
+-
+
+## v0.9.3.210616 alpha (2021-06-16)
+
+### Added
+
+- 任务排程
+-
+
+### Changed
+
+- 配置热更新
+-
+
+### Fixed
+
+- 修复弹幕
+- 修复独立监控
+-
+
+### Remarks
+
+-
+
+## v0.9.2.210602 alpha (2021-06-02)
+
+### Added
+
+-
+
+### Changed
+
+- 更新DcokerFile
+- 更新每日点亮勋章(100亲密度)
+-
+
+### Fixed
+
+-
+
+### Remarks
+
+-
+
+## v0.9.1.210518 alpha (2021-05-18)
+
+### Added
+
+-
+
+### Changed
+
+- 删除过期活动
+- 更新风纪委员
+- 更新银瓜子兑换硬币
+- 更新点亮勋章
+- 更新部分日志打印输出
+-
+
+### Fixed
+
+- 修复已知BUG
+-
+
+### Remarks
+
+-
+
+## v0.9.0.210517 alpha (2021-05-17)
+
+### Added
+
+- 重大更新
+-
+
+### Changed
+
+- 懒得写描述
+-
+
+### Fixed
+
+- 配置文件有变动
+-
+
+### Remarks
+
+- 请重新配置
+-
+
## v0.8.1.210423 alpha (2021-04-23)
### Added
-
### Changed
+
- 更新天选敏感词
- 更新活动列表
- 优化直播间心跳
@@ -21,12 +207,14 @@
## v0.8.0.210327 alpha (2021-03-27)
### Added
+
- 增加直播扭蛋抽奖活动(可自定义)
- 增加主站九宫格抽奖活动(可自定义)
- 增加多个推送消息通道
-
### Changed
+
- 更新过滤词独立
- 更新请求中心
- 更新日志打印
@@ -43,13 +231,15 @@
-
### Fixed
+
- 修复小心心心跳错误
- 修复部分推送错误
- 修复银瓜子换银币日志错误
-
### Remarks
-- 结构大更新,务必进行Composer等操作
+
+- 结构大更新,务必进行Composer等操作
-
## v0.6.7.201117 alpha (2020-11-17)
@@ -58,6 +248,7 @@
-
### Changed
+
- 调整WS读取数据大小
- 调整弹幕发送时间
- 更新天选之子日志打印
@@ -65,52 +256,61 @@
-
### Fixed
+
- 修复小心心心跳错误
--
+-
## v0.6.5.200808 alpha (2020-08-08)
### Added
+
- 添加小心心支持
- 添加活动抽奖
-
### Changed
+
- 去掉无效双端观看
- 过期小心心赠送
### Fixed
+
- 修复小心心心跳错误
-
## v0.6.0.200730 alpha (2020-07-30)
### Added
+
- 添加小心心支持
--
+-
### Changed
+
- 更新天选过滤关键词
-
### Fixed
+
- 修复节奏风暴逻辑错误
-
## v0.5.0.200625 alpha (2020-06-25)
### Added
+
- 添加破产机(赔到破产)
- 添加推送KEY到期通知
- 添加天选自动取关(测试)
- 添加收益统计
- 添加关注投币模式
--
+-
### Changed
+
- 更新部分信息输出
- 修改日志打印前缀
-- 更新活跃弹幕延迟
+- 更新活跃弹幕延迟
- 重构部分统计代码
- 更新视频投币逻辑
- 更新实物抽奖API
@@ -119,10 +319,11 @@
-
### Fixed
+
- 修复日志输出错误
- 修复每日送礼异常
- 修复赛事逻辑错误
-- 修复部分已知问题
+- 修复部分已知问题
-
## v0.4.0.200505 alpha (2020-05-05)
@@ -131,15 +332,17 @@
-
### Changed
+
- 关闭已结束的LPL赛事任务
-
### Fixed
+
- 修复日志回调空格解析异常
- 修复节奏风暴回显过滤错误
- 修复活动抽奖重复请求问题
- 修复主站任务获取AID异常
--
+-
## v0.4.0.200428 alpha (2020-04-28)
@@ -150,49 +353,58 @@
-
### Fixed
+
- 修复赠送礼物逻辑
-
## v0.4.0.200426 alpha (2020-04-26)
### Added
+
- 赛事助手 (签到、分享)
--
+-
### Changed
-
### Fixed
+
- 修复休眠机制
-
## v0.3.0.200425 alpha (2020-04-25)
### Added
+
- 添加调用函数
-
### Changed
+
- 取消一处请求头
-
### Fixed
+
- 修复休眠机制
-
## v0.3.0.200424 alpha (2020-04-24)
### Added
+
- 抽出独立小黑屋
- 提前引入BV2AV
-
### Changed
+
- 优化监控推送
- 优化登录参数
- 同步黑屋提醒
### Fixed
+
- 修复监控输出
-
@@ -205,6 +417,7 @@
-
### Fixed
+
- 修复节奏风暴回显
- 修复分区监控异常
- 修复获取勋章异常
@@ -216,10 +429,12 @@
-
### Changed
+
- 去除主监控
-
### Fixed
+
- 修复风暴回显过滤
- 修复一处舰长处理
- 修复中奖记录通知
@@ -236,6 +451,7 @@
-
### Fixed
+
- 修复备用监控无法获取
- 修复获取分区ID异常
-
@@ -243,6 +459,7 @@
## v0.3.0.200404 alpha (2020-04-04)
### Added
+
- 添加ISSUE模板
- 添加处理监控端命令
-
@@ -251,6 +468,7 @@
-
### Fixed
+
- 修复主监控内存溢出
- 修复活动礼物提醒
-
@@ -258,10 +476,12 @@
## v0.3.0.200318 alpha (2020-03-18)
### Added
+
- 添加日常任务定时执行(AM10:00)
--
+-
### Changed
+
- Sleep->Schedule
- 优化异常通知
- 优化异常重试数
@@ -270,6 +490,7 @@
-
### Fixed
+
- 修复日志回调
- 修复response为null
- 修复PC端心跳
@@ -279,13 +500,15 @@
## v0.3.0.200316 alpha (2020-03-16)
### Added
+
- 添加异常处理(通知)
--
+-
### Changed
-
### Fixed
+
- 修复活跃弹幕
- 修复风纪测试
- 修复部分已知
@@ -294,16 +517,19 @@
## v0.3.0.200312 alpha (2020-03-12)
### Added
+
- 引入风纪 (不稳定测试)
- 引入新库 (需要重新Composer)
--
+-
### Changed
+
- 重构部分公用方法
- 重构CURL请求
-
### Fixed
+
- 修复登录繁忙
- 修复实物抽奖
- 修复日志输出
@@ -319,18 +545,21 @@
-
### Fixed
+
- 修复节奏风暴
- 修复双端心跳
--
+-
## v0.2.0.200224 alpha (2020-02-24)
### Added
+
- 新增工具类
- 引入新库(需要重新Composer)
--
+-
### Changed
+
- 优化数据过滤条件
- 更新PC端心跳API
- 优化实物抽奖
@@ -338,9 +567,10 @@
-
### Fixed
+
- 修复内存异常
- 修复重复投币
--
+-
## v0.2.0.200214 alpha (2020-02-14)
@@ -348,10 +578,12 @@
-
### Changed
+
- 优化实物抽奖流程
- 优化延迟礼物抽奖
### Fixed
+
- 修正部分函数名称
- 尝试减少静态占用
-
@@ -359,20 +591,24 @@
## v0.2.0.200208 alpha (2020-02-08)
### Added
+
- 哔哩哔哩漫画助手(可选)
-
### Changed
+
- 补充部分过滤关键字
-
### Fixed
+
- 修复一处内存异常
-
## v0.1.0.200111 alpha (2020-01-11)
### Added
+
- 天选时刻奖品过滤
-
@@ -385,6 +621,7 @@
## v0.1.0.200128 alpha (2020-01-28)
### Added
+
- 增加推送消息过滤
-
@@ -392,12 +629,14 @@
-
### Fixed
+
- 修复抽奖推送错误
-
## v0.1.0.200111 alpha (2020-01-11)
### Added
+
- 天选时刻奖品过滤
-
@@ -410,40 +649,47 @@
## v0.1.0.200103 alpha (2020-01-03)
### Added
+
- 增加并发请求
-
### Changed
+
- 更新抽奖逻辑
- 更新部分API
- 减少重复请求
-
### Fixed
+
- 修复部分回显错误
-
## v0.1.0.200101 alpha (2020-01-01)
### Added
+
- 任务逻辑引入协程
### Changed
-
### Fixed
+
- 修复礼物赠送异常
-
## v0.1.0.191227 alpha (2019-12-27)
### Added
+
- 新增备用官方分区监控
- 新增按勋章亲密度赠送
- 新增天选时刻获奖推送
-
### Changed
+
- 优化部分架构
- 优化独立监控
- 优化监控逻辑
@@ -453,6 +699,7 @@
-
### Fixed
+
- 修复部分日志显示
- 修复数据统计异常
- 修复瓜子宝箱异常
@@ -462,7 +709,7 @@
- 修复部分已知BUG
- 修复获奖推送通知
- 修复休眠中心异常
-- 修复礼物赠送异常
+- 修复礼物赠送异常
-
## v0.0.5.191223 alpha (2019-12-23)
diff --git a/DOC.md b/DOC.md
index 85879fc..d6ed401 100644
--- a/DOC.md
+++ b/DOC.md
@@ -1,68 +1,24 @@
+

-
+[comment]: <> (
)
-
-
-
-
+
+[](https://github.com/lkeme/ )
+
+
+
+
-# BiliHelper
-
-B 站直播实用脚本
-
-## 功能组件
-
-|plugin |version |description |
-|--------------------|--------------------|--------------------|
-|Login |21.03.27 |账号登录 |
-|Schedule |21.03.27 |休眠控制 |
-|MainSite |21.03.27 |主站助手 |
-|Daily |21.03.27 |每日礼包 |
-|Heart |21.03.27 |双端心跳 |
-|DailyTask |21.03.27 |每日任务 |
-|Silver |21.03.27 |银瓜子宝箱 |
-|Barrage |21.03.27 |活跃弹幕 |
-|Silver2Coin |21.03.27 |银瓜子换硬币 |
-|GiftSend |21.03.27 |礼物赠送 |
-|Judge |21.03.27 |风纪 |
-|GroupSignIn |21.03.27 |友爱社签到 |
-|ManGa |21.03.27 |漫画签到分享 |
-|GameMatch |21.03.27 |赛事签到分享 |
-|GiftHeart |21.03.27 |心跳礼物 |
-|MaterialObject |21.03.27 |实物抽奖 |
-|AloneTcpClient |21.03.27 |独立监控 |
-|ZoneTcpClient |21.03.27 |分区监控 |
-|StormRaffle |21.03.27 |节奏风暴 |
-|GiftRaffle |21.03.27 |活动礼物 |
-|PkRaffle |21.03.27 |大乱斗 |
-|GuardRaffle |21.03.27 |舰长总督 |
-|AnchorRaffle |21.03.27 |天选时刻 |
-|AwardRecord |21.03.27 |获奖通知 |
-|Statistics |21.03.27 |数据统计 |
-|Competition |21.03.27 |赛事竞猜 |
-|SmallHeart |21.03.27 |小心心 |
-|ActivityLottery |21.03.27 |主站活动 |
-|CapsuleLottery |21.03.27 |直播扭蛋活动 |
-|Forward |21.03.27 |动态抽奖转发 |
-
-## 打赏赞助
-
-
-
-> 待添加
-
-## 未完成功能
-
-|待续 |
-|-----------|
-|多用户 |
+
## 环境依赖
+通常使用 `composer` 工具会自动检测以下依赖问题。
+
|Requirement |
|--------------------|
-|PHP >=7.0 |
+|PHP >=7.3 |
|php_curl |
|php_sockets |
|php_openssl |
@@ -70,83 +26,162 @@ B 站直播实用脚本
|php_zlib |
|php_mbstring |
-通常使用 `composer` 工具会自动检测上述依赖问题。
-
## Composer
-* 项目 `composer.lock` 基于阿里云Composer镜像生成
-+ 阿里云(推荐)
-```
+
++ [Composer 安装与使用](https://www.runoob.com/w3cnote/composer-install-and-usage.html)
+
++ [Composer 下载](https://getcomposer.org/download/)
+
++ 当前项目 `composer.lock` 基于阿里云 Composer镜像生成
+
++ 阿里云(全量镜像)
+
+```bash
# 使用帮助
-https://developer.aliyun.com/composer
+> https://developer.aliyun.com/composer
# 使用命令
> composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
```
-* 腾讯云(备用)
+
++ 恢复默认镜像|Composer.phar加速下载
+
+```bash
+> composer config -g --unset repos.packagist
+
+> https://mirrors.cloud.tencent.com/composer/composer.phar
+> https://mirrors.aliyun.com/composer/composer.phar
```
+
+
+其余镜像 展开查看
+
++ cnpkg(全量镜像)
+```bash
# 使用帮助
-https://mirrors.cloud.tencent.com/composer/
+> https://php.cnpkg.org/
# 使用命令
-composer config -g repos.packagist composer https://mirrors.cloud.tencent.com/composer/
+> composer config -g repos.packagist composer https://php.cnpkg.org
```
++ 腾讯云(全量镜像)
+```bash
+# 使用帮助
+> https://mirrors.cloud.tencent.com/help/composer.html
+# 使用命令
+> composer config -g repos.packagist composer https://mirrors.cloud.tencent.com/composer/
+```
+
++ phpcomposer(全量镜像)
+
+```bash
+# 使用帮助
+> https://pkg.phpcomposer.com/
+# 使用命令
+> composer config -g repo.packagist composer https://packagist.phpcomposer.com
+```
+
++ 华为云(全量镜像)
+
+```bash
+# 使用帮助
+> https://mirrors.huaweicloud.com/repository/php/
+# 使用命令
+> composer config -g repos.packagist composer https://mirrors.huaweicloud.com/repository/php/
+```
+
++ 交通大学(非全量镜像)
+
+```bash
+# 使用帮助
+> https://packagist.mirrors.sjtug.sjtu.edu.cn/
+# 使用命令
+> composer config -g repos.packagist composer https://packagist.mirrors.sjtug.sjtu.edu.cn
+```
+
+
+
## 使用指南
- 1. 下载(克隆)项目代码,初始化项目
+1. 下载(克隆)项目代码,初始化项目
+
```
$ git clone https://github.com/lkeme/BiliHelper-personal.git
$ cd BiliHelper-personal/conf
-$ cp user.conf.example user.conf
+$ cp user.ini.example user.ini
```
- 2. 使用 [composer](https://getcomposer.org/download/) 工具进行安装
+
+2. 使用 [composer](https://getcomposer.org/download/) 工具进行安装
+
```
$ composer install
```
- 3. 按照说明修改配置文件 `user.conf`
+
+[comment]: <> (composer dump-autoload (-o))
+
+[comment]: <> (composer dumpautoload (-o))
+
+3. 按照说明修改配置文件 `user.ini`
+
```
# 默认只需填写帐号密码,按需求开启其他功能即可
```
- 4. 运行测试
+
+4. 运行测试
+
```
$ php index.php
```
-> 以下是`多账户多开方案`,单个账户可以无视
- 5. 复制一份example配置文件,修改账号密码即可
- ```
- $ php index.php example.conf
- ```
- 6. 请保证配置文件存在,否则默认加载`user.conf`配置文件
-
+> 以下是`多账户多开方案`,单个账户可以无视
+
+5. 复制一份example配置文件,修改账号密码即可
+
+ ```
+ $ php index.php example.ini
+ ```
+
+6. 请保证配置文件存在,否则默认加载`user.ini`配置文件
+
+
+
+[comment]: <> (
)
## Docker使用指南
- 1. 安装好[Docker](https://yeasy.gitbooks.io/docker_practice/content/install/)
- 2. 直接命令行拉取镜像后运行
-
+1. 安装好[Docker](https://yeasy.gitbooks.io/docker_practice/content/install/)
+2. 直接命令行拉取镜像后运行
### 传入的参数方式有两种(二选一,如果同时传入则优先选择配置文件)
- 通过环境变量进行传入
```shell script
- docker run -itd --rm -e USER_NAME=你的B站登录账号 -e USER_PASSWORD=你的B站密码 zsnmwy/bilihelper-personal
+$ docker run -itd --rm -e USER_NAME=你的B站登录账号 -e USER_PASSWORD=你的B站密码 lkeme/bilihelper-personal
```
-- 通过配置文件进行传入
+- 通过配置文件进行传入(能保留登录状态,自定义配置)
-1. 下载[配置文件](https://raw.githubusercontent.com/lkeme/BiliHelper-personal/master/conf/user.conf.example)
+1. 下载[配置文件](https://raw.githubusercontent.com/lkeme/BiliHelper-personal/master/conf/user.ini.example)
2. 修改
3. 通过下面的命令进行挂载并运行
```shell script
-docker run -itd --rm -v /path/to/your/confFileName.conf:/app/conf/user.conf zsnmwy/bilihelper-personal
+$ docker run -itd --rm -v /path/to/your/confFileName.ini:/app/conf/user.ini lkeme/bilihelper-personal
```
-```
-相关参数
+- 使用github镜像加速
+```bash
+$ -e MIRRORS=0 # 使用 github.com
+$ -e MIRRORS=1 # 使用 ghproxy.com
+$ -e MIRRORS=2 # 使用 github.com.cnpmjs.org
+```
+
+- 相关参数
+
+```ps
-it 前台运行
-itd 后台运行
-v 本地文件:容器内部文件 ==> 挂载本地文件到容器中。本地文件路径随便变,容器内部文件路径不能变。
@@ -155,20 +190,29 @@ docker run -itd --rm -v /path/to/your/confFileName.conf:/app/conf/user.conf zsnm
- 注意: Docker镜像已经包含了所有所需的运行环境,无需在本地环境弄composer。每次启动容器时,都会与项目进行同步以确保版本最新。
## 升级指南
+
> 注意新版本的配置文件是否变动,则需要重新覆盖配置文件,并重新填写设置
- 1. 进入项目目录
+
+1. 进入项目目录
+
```
$ cd BiliHelper-personal
```
- 2. 拉取最新代码
+
+2. 拉取最新代码
+
```
$ git pull
```
- 3. 更新依赖库
+
+3. 更新依赖库
+
```
$ composer install
```
- 4. 如果使用 systemd 等,需要重启服务
+
+4. 如果使用 systemd 等,需要重启服务
+
```
$ systemctl restart bilibili
```
@@ -178,10 +222,11 @@ $ systemctl restart bilibili
如果你将 BiliHelper-personal 部署到线上服务器时,则需要配置一个进程监控器来监测 `php index.php` 命令,在它意外退出时自动重启。
通常可以使用以下的方式
- - systemd (推荐)
- - Supervisor
- - screen (自用)
- - nohup
+
+- systemd (推荐)
+- Supervisor
+- screen (自用)
+- nohup
## systemd 脚本
@@ -189,7 +234,7 @@ $ systemctl restart bilibili
# /usr/lib/systemd/system/bilibili.service
[Unit]
-Description=Bili Helper Manager
+Description=BiliHelper Manager
Documentation=https://github.com/lkeme/BiliHelper-personal
After=network.target
@@ -223,6 +268,7 @@ stdout_logfile=/tmp/bilibili.log
|TelegramBot|https://core.telegram.org/bots/api|
示范如下
+
```
# Server酱
# 自行替换
@@ -235,10 +281,9 @@ APP_CALLBACK="https://api.telegram.org/bot/sendMessage?chat_id=&
`{message}` 部分会自动替换成错误信息,接口采用 get 方式发送
-
## 直播间 ID 问题
-文件 `user.conf` 里
+文件 `user.ini` 里
`ROOM_ID` 配置,填写此项可以清空临过期礼物给指定直播间。
@@ -249,11 +294,13 @@ APP_CALLBACK="https://api.telegram.org/bot/sendMessage?chat_id=&
`SOCKET_ROOM_ID` 配置,监控使用,暂时没用到。
通常可以在直播间页面的 url 获取到它
+
```
http://live.bilibili.com/9522051
```
长位直播间ID获取
+
```
https://api.live.bilibili.com/room/v1/Room/room_init?id=3
```
@@ -261,24 +308,3 @@ https://api.live.bilibili.com/room/v1/Room/room_init?id=3
所有直播间号码小于 1000 的直播间为短号,部分4位直播间也为短号,
该脚本在每次启动会自动修正部分功能,特殊标注的请留意。
-
-## 相关
-
- > [BilibiliHelper](https://github.com/metowolf/BilibiliHelper)
-
- > [BiliHelper](https://github.com/lkeme/BiliHelper)
-
- > [Github](https://github.com/)
-
-
-## License 许可证
-
-BiliHelper is under the MIT license.
-
-本项目基于 MIT 协议发布,并增加了 SATA 协议。
-
-当你使用了使用 SATA 的开源软件或文档的时候,在遵守基础许可证的前提下,你必须马不停蹄地给你所使用的开源项目 “点赞” ,比如在 GitHub 上 star,然后你必须感谢这个帮助了你的开源项目的作者,作者信息可以在许可证头部的版权声明部分找到。
-
-本项目的所有代码文件、配置项,除另有说明外,均基于上述介绍的协议发布,具体请看分支下的 LICENSE。
-
-此处的文字仅用于说明,条款以 LICENSE 文件中的内容为准。
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 282022c..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,38 +0,0 @@
-FROM php:alpine
-
-MAINTAINER zsnmwy
-
-ENV USER_NAME='' \
- USER_PASSWORD='' \
- CONIFG_PATH='/app/conf/user.conf' \
- Green="\\033[32m" \
- Red="\\033[31m" \
- GreenBG="\\033[42;37m" \
- RedBG="\\033[41;37m" \
- Font="\\033[0m" \
- Green_font_prefix="\\033[32m" \
- Green_background_prefix="\\033[42;37m" \
- Font_color_suffix="\\033[0m" \
- Info="${Green}[信息]${Font}" \
- OK="${Green}[OK]${Font}" \
- Error="${Red}[错误]${Font}"
-
-WORKDIR /app
-
-#RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
-RUN docker-php-ext-install sockets
-
-RUN apk add --no-cache git && \
- git clone https://github.com/lkeme/BiliHelper-personal.git --depth=1 /app && \
- php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" && \
- php composer-setup.php && \
- php composer.phar install && \
- rm -r /var/cache/apk && \
- rm -r /usr/share/man
-
-ENTRYPOINT echo -e "\n ======== \n ${Info} ${GreenBG} 正使用 git pull 同步项目 ${Font} \n ======== \n" && \
- git pull && \
- echo -e "\n ======== \n ${Info} ${GreenBG} 安装/更新 项目运行依赖 ${Font} \n ======== \n" && \
- php composer.phar install && \
- echo -e "\n \n \n \n" && \
- if [[ -f ${CONIFG_PATH} ]]; then echo -e "\n ======== \n ${GreenBG} 正在使用外部配置文件 ${Font} \n ======== \n" && php index.php ; else echo -e "${OK} ${GreenBG} 正在使用传入的环境变量进行用户配置。\n 如果需要配置更多选择项,请通过挂载配置文件来传入。具体参考项目中的README。\n https://github.com/lkeme/BiliHelper-personal.git ${Font} \n ======== \n " && cp /app/conf/user.conf.example /app/conf/user.conf && sed -i ''"$(cat /app/conf/user.conf -n | grep "APP_USER=" | awk '{print $1}')"'c '"$(echo "APP_USER=${USER_NAME}")"'' ${CONIFG_PATH} && sed -i ''"$(cat /app/conf/user.conf -n | grep "APP_PASS=" | awk '{print $1}')"'c '"$(echo "APP_PASS=${USER_PASSWORD}")"'' ${CONIFG_PATH} && php index.php; fi
diff --git a/README.md b/README.md
index c26e1bc..078c81e 100644
--- a/README.md
+++ b/README.md
@@ -1,31 +1,138 @@
-# BiliHelper
-B 站直播实用脚本
+
-## 交流
+[comment]: <> (
)
-Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **仅用于BUG提交反馈**
+
-## 公告
+[](https://github.com/lkeme/ )
+
+
+
+
+
+[](https://hub.docker.com/r/lkeme/bilihelper-personal)
-> Personal Edition **0.8.1.210423 alpha**
+
+
+
+
+
+
+
+
+
+
+
+## 公告通知
+
+代码开源,本地化99.9%,项目不收集或使用任何敏感信息,兴趣所致,一切只为学习。
```notice
---- 免费的东西总是得不到人的珍惜。
---- 只有花大价钱去买到的东西,才会令人信任。
```
+## 🖥️星图
-## 文档
-> 有疑问一定要先看看文档或Issue里是否存在相同的问题,再考虑其他渠道咨询。
+[](https://starchart.cc/lkeme/BiliHelper-personal)
+[](https://starchart.cc/lkeme/BiliHelper)
+
+## 功能组件
+
+以下任务都是按设定周期自动执行,`true`为正常使用,`false`为暂停使用或抛弃。
+
+| plugin | status | version | cycle | description |
+|-----------------|--------|----------|--------|---------------------------------------------|
+| CheckUpdate | true | 21.07.14 | 待整理 | 程序检查更新 |
+| Login | true | 21.07.14 | 待整理 | 账号登录、刷新、维持 |
+| Schedule | true | 21.07.14 | 待整理 | 控制插件运行周期 |
+| MainSite | true | 21.07.14 | 待整理 | 投币、观看、分享视频 (速升6级不是梦) |
+| DailyBag | true | 21.07.14 | 待整理 | 双端领取日常/周常礼包 |
+| ManGa | true | 21.07.14 | 待整理 | 漫画签到、分享 |
+| ActivityLottery | true | 21.07.14 | 待整理 | 主站活动九宫格抽奖 |
+| Competition | true | 21.07.14 | 待整理 | 游戏赛事竞猜 |
+| DoubleHeart | true | 21.07.14 | 待整理 | 双端心跳 (姥爷直播经验) |
+| DailyTask | true | 21.07.14 | 待整理 | 直播每日任务(签到、观看) |
+| Barrage | true | 21.07.14 | 待整理 | 保持活跃弹幕 |
+| Silver2Coin | true | 21.07.14 | 待整理 | 银瓜子兑换硬币 |
+| Judge | true | 21.07.14 | 待整理 | 风纪委员投票 |
+| GiftSend | true | 21.07.14 | 待整理 | 礼物赠送、维持每日勋章亲密度 |
+| GroupSignIn | true | 21.07.14 | 待整理 | 友爱社签到 |
+| GiftHeart | true | 21.07.14 | 待整理 | 日常心跳每日礼包礼物 |
+| SmallHeart | true | 21.07.14 | 待整理 | 直播挂机,每日24个小心心 |
+| MaterialObject | true | 21.07.14 | 待整理 | 直播金色宝箱实物抽奖 |
+| AloneTcpClient | true | 21.07.14 | 待整理 | 作者的独立直播监控(可支持本项目哦) |
+| ZoneTcpClient | true | 21.07.14 | 待整理 | 官方的分区直播监控 |
+| StormRaffle | true | 21.07.14 | 待整理 | 直播节奏风暴抽奖、亿元 |
+| GiftRaffle | true | 21.07.14 | 待整理 | 直播礼物抽奖 |
+| PkRaffle | true | 21.07.14 | 待整理 | 直播大乱斗抽奖 |
+| GuardRaffle | true | 21.07.14 | 待整理 | 直播大航海抽奖 |
+| AnchorRaffle | true | 21.07.14 | 待整理 | 直播天选时刻抽奖 |
+| GiftRaffle | true | 21.07.14 | 待整理 | 直播礼物抽奖 |
+| AwardRecord | true | 21.07.14 | 待整理 | 最新的中奖纪录通知 |
+| Forward | true | 21.07.14 | 待整理 | 主站动态抽奖转发 |
+| CapsuleLottery | true | 21.07.14 | 待整理 | 直播扭蛋活动抽奖 |
+| PolishTheMedal | true | 21.07.14 | 待整理 | 每日自动点亮灰色勋章 |
+| CapsuleLottery | true | 21.07.14 | 待整理 | 直播扭蛋活动抽奖 |
+| VipPrivilege | true | 21.07.14 | 待整理 | 每月领取年度大会员特权(B币券、会员购优惠券) |
+| BpConsumption | true | 21.07.14 | 待整理 | 每月消费使用年度大会员特权的B币券 |
+| Statistics | true | 21.07.14 | 待整理 | 全局抽奖结果统计 |
+| Silver | false | 21.03.27 | 待整理 | 直播银瓜子自动开启宝箱 |
+
+
+## 交流反馈
+
+Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **请不要来问如何使用, 文档齐全, 仅用于BUG提交反馈**
+
+## 相关文档
+
+有疑问一定要先看看文档或Issue里是否存在相同的问题,再考虑其他渠道咨询。
+
+[comment]: <> (:cherry_blossom: :gift: :gift_heart: :confetti_ball:)
* [使用文档 / DOC.md](./DOC.md)
* [更新日志 / CHANGELOG.md](./CHANGELOG.md)
* [配置文档 / WIKI.md](https://github.com/lkeme/BiliHelper-personal/wiki/%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3)
* [常见问题 / WIKI.md](https://github.com/lkeme/BiliHelper-personal/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)
-## 打赏
+## 打赏支持
-
+如果觉得本项目好用,对你有所帮助,欢迎打赏支持本项目哦。
-## 效果
+
-
+[comment]: <> ()
+
+## 运行效果
+
+效果图不代表当前版本,请以当前最新版本运行结果为准。
+
+
+
+[comment]: <> ()
+
+## 项目相关
+
+* [BilibiliHelper](https://github.com/metowolf/BilibiliHelper)
+* [BiliHelper](https://github.com/lkeme/BiliHelper)
+* [Github](https://github.com/)
+
+## 致谢
+
+感谢 `JetBrains` 提供优秀的IDE。
+
+
+
+
+
+## License 许可证
+
+BiliHelper is under the MIT license.
+
+本项目基于 MIT 协议发布,并增加了 SATA 协议。
+
+当你使用了使用 SATA 的开源软件或文档的时候,在遵守基础许可证的前提下,你必须马不停蹄地给你所使用的开源项目 “点赞” ,比如在 GitHub 上
+star,然后你必须感谢这个帮助了你的开源项目的作者,作者信息可以在许可证头部的版权声明部分找到。
+
+本项目的所有代码文件、配置项,除另有说明外,均基于上述介绍的协议发布,具体请看分支下的 LICENSE。
+
+此处的文字仅用于说明,条款以 LICENSE 文件中的内容为准。
diff --git a/composer.json b/composer.json
index 1ad3703..cb19581 100644
--- a/composer.json
+++ b/composer.json
@@ -3,7 +3,7 @@
"description": "B 站自动领瓜子、直播助手、直播挂机脚本、主站助手 - PHP 版(Personal)",
"type": "project",
"require": {
- "php": ">=7.0.0",
+ "php": ">=7.3.0",
"ext-curl": "*",
"ext-openssl": "*",
"ext-sockets": "*",
@@ -13,12 +13,15 @@
"monolog/monolog": "^1.26.0",
"bramus/monolog-colored-line-formatter": "^2.0.3",
"clue/socket-raw": "^1.5.0",
- "vlucas/phpdotenv": "^4.2.0",
"amphp/amp": "^2.5.2",
"guzzlehttp/guzzle": "^6.5.5",
"mathieuviossat/arraytotexttable": "^1.0.8",
"klkvsk/json-decode-stream": "^1.0",
- "sven/file-config": "^3.1"
+ "sven/file-config": "^3.1",
+ "hassankhan/config": "^2.2",
+ "lkeme/inifile": "^3.4",
+ "adhocore/cli": "^0.9.0",
+ "vanilla/garden-cli": "^3.1"
},
"license": "MIT",
"authors": [
@@ -34,7 +37,10 @@
"BiliHelper\\Plugin\\": "src/plugin",
"BiliHelper\\Util\\": "src/util",
"BiliHelper\\Tool\\": "src/tool",
- "BiliHelper\\Backup\\": "src/backup"
- }
+ "BiliHelper\\Script\\": "src/script"
+ },
+ "files": [
+ "src/core/Helpers.php"
+ ]
}
}
diff --git a/composer.lock b/composer.lock
index 6f574d2..4ea622f 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,80 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "a9407272d4bb9ca1632a2aa728429bf0",
+ "content-hash": "0678ecd04eed6db66de4668ffffec283",
"packages": [
+ {
+ "name": "adhocore/cli",
+ "version": "0.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/adhocore/php-cli.git",
+ "reference": "319c7dd0092c0346d9ad03366cc13d3491b57e34"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/adhocore/php-cli/zipball/319c7dd0092c0346d9ad03366cc13d3491b57e34",
+ "reference": "319c7dd0092c0346d9ad03366cc13d3491b57e34",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Ahc\\Cli\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jitendra Adhikari",
+ "email": "jiten.adhikary@gmail.com"
+ }
+ ],
+ "description": "Command line interface library for PHP",
+ "keywords": [
+ "PHP7",
+ "argument-parser",
+ "argv-parser",
+ "cli",
+ "cli-action",
+ "cli-app",
+ "cli-color",
+ "cli-option",
+ "cli-writer",
+ "command",
+ "console",
+ "console-app",
+ "php-cli",
+ "stream-input",
+ "stream-output"
+ ],
+ "support": {
+ "issues": "https://github.com/adhocore/php-cli/issues",
+ "source": "https://github.com/adhocore/php-cli/tree/0.9.0"
+ },
+ "funding": [
+ {
+ "url": "https://paypal.me/ji10",
+ "type": "custom"
+ }
+ ],
+ "time": "2021-01-06T00:25:50+00:00"
+ },
{
"name": "amphp/amp",
"version": "v2.5.2",
@@ -460,16 +532,16 @@
},
{
"name": "guzzlehttp/psr7",
- "version": "1.8.1",
+ "version": "1.8.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
- "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1"
+ "reference": "dc960a912984efb74d0a90222870c72c87f10c91"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/35ea11d335fd638b5882ff1725228b3d35496ab1",
- "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91",
+ "reference": "dc960a912984efb74d0a90222870c72c87f10c91",
"shasum": "",
"mirrors": [
{
@@ -535,22 +607,90 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/1.8.1"
+ "source": "https://github.com/guzzle/psr7/tree/1.8.2"
},
- "time": "2021-03-21T16:25:00+00:00"
+ "time": "2021-04-26T09:17:50+00:00"
},
{
- "name": "klkvsk/json-decode-stream",
- "version": "v1.0.2",
+ "name": "hassankhan/config",
+ "version": "2.2.0",
"source": {
"type": "git",
- "url": "https://github.com/klkvsk/json-decode-stream.git",
- "reference": "76cbcd9eb9f1860293b82b4f071e76826bc90c82"
+ "url": "https://github.com/hassankhan/config.git",
+ "reference": "62b0fd17540136efa94ab6b39f04044c6dc5e4a7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/klkvsk/json-decode-stream/zipball/76cbcd9eb9f1860293b82b4f071e76826bc90c82",
- "reference": "76cbcd9eb9f1860293b82b4f071e76826bc90c82",
+ "url": "https://api.github.com/repos/hassankhan/config/zipball/62b0fd17540136efa94ab6b39f04044c6dc5e4a7",
+ "reference": "62b0fd17540136efa94ab6b39f04044c6dc5e4a7",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8.36 || ~5.7 || ~6.5 || ~7.5",
+ "scrutinizer/ocular": "~1.1",
+ "squizlabs/php_codesniffer": "~2.2",
+ "symfony/yaml": "~3.4"
+ },
+ "suggest": {
+ "symfony/yaml": "~3.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Noodlehaus\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Hassan Khan",
+ "homepage": "http://hassankhan.me/",
+ "role": "Developer"
+ }
+ ],
+ "description": "Lightweight configuration file loader that supports PHP, INI, XML, JSON, and YAML files",
+ "homepage": "http://hassankhan.me/config/",
+ "keywords": [
+ "config",
+ "configuration",
+ "ini",
+ "json",
+ "microphp",
+ "unframework",
+ "xml",
+ "yaml",
+ "yml"
+ ],
+ "support": {
+ "issues": "https://github.com/hassankhan/config/issues",
+ "source": "https://github.com/hassankhan/config/tree/2.2.0"
+ },
+ "time": "2020-12-07T16:04:15+00:00"
+ },
+ {
+ "name": "klkvsk/json-decode-stream",
+ "version": "v1.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/klkvsk/json-decode-stream.git",
+ "reference": "831b5310b42b51705a2d6ae5353bba7aaa302358"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/klkvsk/json-decode-stream/zipball/831b5310b42b51705a2d6ae5353bba7aaa302358",
+ "reference": "831b5310b42b51705a2d6ae5353bba7aaa302358",
"shasum": "",
"mirrors": [
{
@@ -595,9 +735,9 @@
],
"support": {
"issues": "https://github.com/klkvsk/json-decode-stream/issues",
- "source": "https://github.com/klkvsk/json-decode-stream/tree/v1.0.2"
+ "source": "https://github.com/klkvsk/json-decode-stream/tree/v1.0.3"
},
- "time": "2021-03-23T14:26:50+00:00"
+ "time": "2021-06-29T23:00:36+00:00"
},
{
"name": "laminas/laminas-servicemanager",
@@ -694,16 +834,16 @@
},
{
"name": "laminas/laminas-stdlib",
- "version": "3.3.1",
+ "version": "3.4.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-stdlib.git",
- "reference": "d81c7ffe602ed0e6ecb18691019111c0f4bf1efe"
+ "reference": "e89c2268c9cad25099f562f7f015c28c5dd383c9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/d81c7ffe602ed0e6ecb18691019111c0f4bf1efe",
- "reference": "d81c7ffe602ed0e6ecb18691019111c0f4bf1efe",
+ "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/e89c2268c9cad25099f562f7f015c28c5dd383c9",
+ "reference": "e89c2268c9cad25099f562f7f015c28c5dd383c9",
"shasum": "",
"mirrors": [
{
@@ -720,9 +860,11 @@
"zendframework/zend-stdlib": "^3.2.1"
},
"require-dev": {
- "laminas/laminas-coding-standard": "~1.0.0",
+ "laminas/laminas-coding-standard": "~2.3.0",
"phpbench/phpbench": "^0.17.1",
- "phpunit/phpunit": "~9.3.7"
+ "phpunit/phpunit": "~9.3.7",
+ "psalm/plugin-phpunit": "^0.16.0",
+ "vimeo/psalm": "^4.7"
},
"type": "library",
"autoload": {
@@ -754,7 +896,7 @@
"type": "community_bridge"
}
],
- "time": "2020-11-19T20:18:59+00:00"
+ "time": "2021-06-28T21:37:31+00:00"
},
{
"name": "laminas/laminas-text",
@@ -824,16 +966,16 @@
},
{
"name": "laminas/laminas-zendframework-bridge",
- "version": "1.2.0",
+ "version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-zendframework-bridge.git",
- "reference": "6cccbddfcfc742eb02158d6137ca5687d92cee32"
+ "reference": "13af2502d9bb6f7d33be2de4b51fb68c6cdb476e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6cccbddfcfc742eb02158d6137ca5687d92cee32",
- "reference": "6cccbddfcfc742eb02158d6137ca5687d92cee32",
+ "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/13af2502d9bb6f7d33be2de4b51fb68c6cdb476e",
+ "reference": "13af2502d9bb6f7d33be2de4b51fb68c6cdb476e",
"shasum": "",
"mirrors": [
{
@@ -888,7 +1030,71 @@
"type": "community_bridge"
}
],
- "time": "2021-02-25T21:54:58+00:00"
+ "time": "2021-06-24T12:49:22+00:00"
+ },
+ {
+ "name": "lkeme/inifile",
+ "version": "v3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/lkeme/inifile.git",
+ "reference": "bebdcced93b92ad929f6b05cb7cc305d72169a37"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/lkeme/inifile/zipball/bebdcced93b92ad929f6b05cb7cc305d72169a37",
+ "reference": "bebdcced93b92ad929f6b05cb7cc305d72169a37",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.8.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Jelix\\IniFile\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1"
+ ],
+ "authors": [
+ {
+ "name": "Laurent Jouanneau",
+ "email": "laurent@jelix.org"
+ },
+ {
+ "name": "Loic Mathaud"
+ },
+ {
+ "name": "Riccardo Mazzei",
+ "email": "riccardo.mazzei@gmail.com"
+ },
+ {
+ "name": "Lkeme",
+ "email": "Useri@live.cn"
+ }
+ ],
+ "description": "classes to read and modify ini files by preserving comments and empty lines",
+ "homepage": "https://github.com/lkeme/inifile",
+ "keywords": [
+ "files",
+ "ini"
+ ],
+ "support": {
+ "source": "https://github.com/lkeme/inifile/tree/v3.4.0"
+ },
+ "time": "2021-05-13T10:44:17+00:00"
},
{
"name": "mathieuviossat/arraytotexttable",
@@ -949,16 +1155,16 @@
},
{
"name": "monolog/monolog",
- "version": "1.26.0",
+ "version": "1.26.1",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
- "reference": "2209ddd84e7ef1256b7af205d0717fb62cfc9c33"
+ "reference": "c6b00f05152ae2c9b04a448f99c7590beb6042f5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/monolog/zipball/2209ddd84e7ef1256b7af205d0717fb62cfc9c33",
- "reference": "2209ddd84e7ef1256b7af205d0717fb62cfc9c33",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c6b00f05152ae2c9b04a448f99c7590beb6042f5",
+ "reference": "c6b00f05152ae2c9b04a448f99c7590beb6042f5",
"shasum": "",
"mirrors": [
{
@@ -1025,7 +1231,7 @@
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
- "source": "https://github.com/Seldaek/monolog/tree/1.26.0"
+ "source": "https://github.com/Seldaek/monolog/tree/1.26.1"
},
"funding": [
{
@@ -1037,82 +1243,7 @@
"type": "tidelift"
}
],
- "time": "2020-12-14T12:56:38+00:00"
- },
- {
- "name": "phpoption/phpoption",
- "version": "1.7.5",
- "source": {
- "type": "git",
- "url": "https://github.com/schmittjoh/php-option.git",
- "reference": "994ecccd8f3283ecf5ac33254543eb0ac946d525"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/994ecccd8f3283ecf5ac33254543eb0ac946d525",
- "reference": "994ecccd8f3283ecf5ac33254543eb0ac946d525",
- "shasum": "",
- "mirrors": [
- {
- "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
- "preferred": true
- }
- ]
- },
- "require": {
- "php": "^5.5.9 || ^7.0 || ^8.0"
- },
- "require-dev": {
- "bamarni/composer-bin-plugin": "^1.4.1",
- "phpunit/phpunit": "^4.8.35 || ^5.7.27 || ^6.5.6 || ^7.0 || ^8.0 || ^9.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.7-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "PhpOption\\": "src/PhpOption/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "Apache-2.0"
- ],
- "authors": [
- {
- "name": "Johannes M. Schmitt",
- "email": "schmittjoh@gmail.com"
- },
- {
- "name": "Graham Campbell",
- "email": "graham@alt-three.com"
- }
- ],
- "description": "Option Type for PHP",
- "keywords": [
- "language",
- "option",
- "php",
- "type"
- ],
- "support": {
- "issues": "https://github.com/schmittjoh/php-option/issues",
- "source": "https://github.com/schmittjoh/php-option/tree/1.7.5"
- },
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
- "type": "tidelift"
- }
- ],
- "time": "2020-07-20T17:29:33+00:00"
+ "time": "2021-05-28T08:32:12+00:00"
},
{
"name": "psr/container",
@@ -1229,16 +1360,16 @@
},
{
"name": "psr/log",
- "version": "1.1.3",
+ "version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
- "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
+ "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
- "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
+ "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
"shasum": "",
"mirrors": [
{
@@ -1268,7 +1399,7 @@
"authors": [
{
"name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
@@ -1279,9 +1410,9 @@
"psr-3"
],
"support": {
- "source": "https://github.com/php-fig/log/tree/1.1.3"
+ "source": "https://github.com/php-fig/log/tree/1.1.4"
},
- "time": "2020-03-23T09:12:05+00:00"
+ "time": "2021-05-03T11:20:27+00:00"
},
{
"name": "ralouphie/getallheaders",
@@ -1394,103 +1525,18 @@
},
"time": "2021-01-19T12:14:40+00:00"
},
- {
- "name": "symfony/polyfill-ctype",
- "version": "v1.22.1",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
- "reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
- "shasum": "",
- "mirrors": [
- {
- "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
- "preferred": true
- }
- ]
- },
- "require": {
- "php": ">=7.1"
- },
- "suggest": {
- "ext-ctype": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.22-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for ctype functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2021-01-07T16:49:33+00:00"
- },
{
"name": "symfony/polyfill-intl-idn",
- "version": "v1.22.1",
+ "version": "v1.23.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
- "reference": "2d63434d922daf7da8dd863e7907e67ee3031483"
+ "reference": "65bd267525e82759e7d8c4e8ceea44f398838e65"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/2d63434d922daf7da8dd863e7907e67ee3031483",
- "reference": "2d63434d922daf7da8dd863e7907e67ee3031483",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/65bd267525e82759e7d8c4e8ceea44f398838e65",
+ "reference": "65bd267525e82759e7d8c4e8ceea44f398838e65",
"shasum": "",
"mirrors": [
{
@@ -1510,7 +1556,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "1.22-dev"
+ "dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -1554,7 +1600,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.22.1"
+ "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.23.0"
},
"funding": [
{
@@ -1570,20 +1616,20 @@
"type": "tidelift"
}
],
- "time": "2021-01-22T09:19:47+00:00"
+ "time": "2021-05-27T09:27:20+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
- "version": "v1.22.1",
+ "version": "v1.23.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248"
+ "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248",
- "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
+ "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
"shasum": "",
"mirrors": [
{
@@ -1601,7 +1647,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "1.22-dev"
+ "dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -1644,7 +1690,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1"
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.23.0"
},
"funding": [
{
@@ -1660,20 +1706,20 @@
"type": "tidelift"
}
],
- "time": "2021-01-22T09:19:47+00:00"
+ "time": "2021-02-19T12:13:01+00:00"
},
{
"name": "symfony/polyfill-php72",
- "version": "v1.22.1",
+ "version": "v1.23.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
- "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9"
+ "reference": "9a142215a36a3888e30d0a9eeea9766764e96976"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9",
- "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976",
+ "reference": "9a142215a36a3888e30d0a9eeea9766764e96976",
"shasum": "",
"mirrors": [
{
@@ -1688,7 +1734,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "1.22-dev"
+ "dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -1726,7 +1772,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.1"
+ "source": "https://github.com/symfony/polyfill-php72/tree/v1.23.0"
},
"funding": [
{
@@ -1742,20 +1788,20 @@
"type": "tidelift"
}
],
- "time": "2021-01-07T16:49:33+00:00"
+ "time": "2021-05-27T09:17:38+00:00"
},
{
- "name": "vlucas/phpdotenv",
- "version": "v4.2.0",
+ "name": "vanilla/garden-cli",
+ "version": "v3.1.2",
"source": {
"type": "git",
- "url": "https://github.com/vlucas/phpdotenv.git",
- "reference": "da64796370fc4eb03cc277088f6fede9fde88482"
+ "url": "https://github.com/vanilla/garden-cli.git",
+ "reference": "d9844c47f4f2812259ee1b583aa66e7b6b5d85c5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/da64796370fc4eb03cc277088f6fede9fde88482",
- "reference": "da64796370fc4eb03cc277088f6fede9fde88482",
+ "url": "https://api.github.com/repos/vanilla/garden-cli/zipball/d9844c47f4f2812259ee1b583aa66e7b6b5d85c5",
+ "reference": "d9844c47f4f2812259ee1b583aa66e7b6b5d85c5",
"shasum": "",
"mirrors": [
{
@@ -1765,68 +1811,45 @@
]
},
"require": {
- "php": "^5.5.9 || ^7.0 || ^8.0",
- "phpoption/phpoption": "^1.7.3",
- "symfony/polyfill-ctype": "^1.17"
+ "ext-json": "*",
+ "php": ">=7.2",
+ "psr/log": "^1.0"
},
"require-dev": {
- "bamarni/composer-bin-plugin": "^1.4.1",
- "ext-filter": "*",
- "ext-pcre": "*",
- "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20"
+ "ergebnis/composer-normalize": "^2.8",
+ "phpdocumentor/reflection-docblock": "^4.3",
+ "phpunit/phpunit": "^8",
+ "vanilla/garden-container": "^3.0",
+ "vanilla/standards": "^1.3",
+ "vimeo/psalm": "^3.16"
},
"suggest": {
- "ext-filter": "Required to use the boolean validator.",
- "ext-pcre": "Required to use most of the library."
+ "ext-pdo": "Required for the DbUtils class.",
+ "phpdocumentor/reflection-docblock": "Required for the CliApplication functionality.",
+ "vanilla/garden-container": "Required for the CliApplication functionality."
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.1-dev"
- }
- },
"autoload": {
"psr-4": {
- "Dotenv\\": "src/"
+ "Garden\\Cli\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Graham Campbell",
- "email": "graham@alt-three.com",
- "homepage": "https://gjcampbell.co.uk/"
- },
- {
- "name": "Vance Lucas",
- "email": "vance@vancelucas.com",
- "homepage": "https://vancelucas.com/"
+ "name": "Todd Burry",
+ "email": "todd@vanillaforums.com"
}
],
- "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
- "keywords": [
- "dotenv",
- "env",
- "environment"
- ],
+ "description": "A full-featured, yet ridiculously simple commandline parser for your next php cli script. Stop fighting with getopt().",
"support": {
- "issues": "https://github.com/vlucas/phpdotenv/issues",
- "source": "https://github.com/vlucas/phpdotenv/tree/v4.2.0"
+ "issues": "https://github.com/vanilla/garden-cli/issues",
+ "source": "https://github.com/vanilla/garden-cli/tree/v3.1.2"
},
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
- "type": "tidelift"
- }
- ],
- "time": "2021-01-20T15:11:48+00:00"
+ "time": "2020-10-25T13:36:44+00:00"
}
],
"packages-dev": [],
@@ -1836,7 +1859,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": ">=7.0.0",
+ "php": ">=7.3.0",
"ext-curl": "*",
"ext-openssl": "*",
"ext-sockets": "*",
@@ -1845,5 +1868,5 @@
"ext-mbstring": "*"
},
"platform-dev": [],
- "plugin-api-version": "2.0.0"
+ "plugin-api-version": "2.1.0"
}
diff --git a/conf/ConfigGenerator.php b/conf/ConfigGenerator.php
index 381b5be..055500c 100644
--- a/conf/ConfigGenerator.php
+++ b/conf/ConfigGenerator.php
@@ -14,7 +14,7 @@ class ConfigGenerator
public $filename;
public $template;
private $options = ['APP_USER', 'APP_PASS'];
- private $default_filename = 'user.conf.example';
+ private $default_filename = 'user.ini.example';
/**
* ConfigGenerator constructor.
@@ -64,8 +64,8 @@ class ConfigGenerator
$value = $this->cliInput("请输入{$option}: ");
$this->template = $this->envReplace($option, $value, $this->template);
}
- file_put_contents(__DIR__ . "\\$this->filename.conf", $this->template);
- echo "生成配置文件 $this->filename.conf 成功~";
+ file_put_contents(__DIR__ . "\\$this->filename.ini", $this->template);
+ echo "生成配置文件 $this->filename.ini 成功~";
}
}
diff --git a/conf/user.conf.example b/conf/user.conf.example
deleted file mode 100644
index 710e46a..0000000
--- a/conf/user.conf.example
+++ /dev/null
@@ -1,196 +0,0 @@
-#######################
-# 账户设置 #
-#######################
-
-# 帐号|密码
-APP_USER=
-APP_PASS=
-
-# 登录模式|[1.账密模式 2.短信验证码模式 3.行为验证码模式(暂未开放)]
-LOGIN_MODE=1
-
-# 令牌(自动生成)
-ACCESS_TOKEN=
-REFRESH_TOKEN=
-COOKIE=
-
-#######################
-# 功能设置 #
-#######################
-
-# 主站每日任务(每日登录、观看、投币、分享)
-USE_MAIN_SITE=true
-
-# 直播大乱斗
-USE_PK=true
-
-# 直播箱子实物抽奖
-USE_LIVE_BOX=true
-
-# 每日24个小心心|依赖加密心跳服务器
-USE_HEARTBEAT=true
-
-# 直播扭蛋活动抽奖|依赖加密心跳服务器
-USE_CAPSULE=true
-
-# 主站九宫格抽奖活动助手
-USE_ACTIVITY=true
-
-# 银瓜子兑换硬币
-USE_SILVER2COIN=true
-
-# 风纪委员
-USE_JUDGE=false
-
-# 直播统一活动
-USE_ACTIVE=false
-
-# 直播舰长总督
-USE_GUARD=false
-
-# 漫画助手
-USE_MANGA=false
-
-# 赛事助手
-USE_MATCH=false
-
-# 节奏风暴|丢弃率(0-100)|尝试数(范围值)
-USE_STORM=false
-STORM_DROPRATE=0
-STORM_ATTEMPT=10,20
-
-# 破产机|每日竞猜次数|每次竞猜硬币(1-10)|下注(1.压大,2.压小,3.随机)
-USE_COMPETITION=false
-COMPET_MAX_NUM=20
-COMPET_MAX_COIN=10
-COMPET_STAKE=1
-
-# 天选时刻|抽取类型(0: 无限制; 1: 关注主播; 2: 粉丝勋章; 3大航海; 4用户等级;5主站等级)|自动取关(测试功能)|过滤关键词|逗号分隔
-USE_ANCHOR=false
-ANCHOR_UNFOLLOW=false
-ANCHOR_TYPE=0,1
-ANCHOR_FILTER_WORDS=
-
-# 活跃弹幕|弹幕房间(为空则随机)|弹幕内容(为空则随机)
-USE_DANMU=true
-DANMU_ROOMID=9522051
-DANMU_CONTENT=
-
-# 视频投币|random(随机热门)/fixed(关注列表)|投币稿件数(每日任务最大5)
-USE_ADD_COIN=false
-ADD_COIN_MODE=random
-ADD_COIN_NUM=5
-
-# 自动转发抽奖动态
-AUTO_DYNAMIC = false
-# 自动取关未中奖动态
-CLEAR_DYNAMIC = false
-# 强制清除抽奖组关注
-CLEAR_GROUP_FOLLOW = false
-# 更改自动回复语言
-AUTO_REPLY_TEXT = 从未中奖,从未放弃[doge]
-
-# 休眠时间|时间区间(0-23)|逗号分隔
-USE_SLEEP=true
-SLEEP_SECTION=2,3,4,5,6
-
-#######################
-# 通知设置 #
-#######################
-
-# 消息推送|消息推送过滤词|逗号分割|优先级从上到下
-USE_NOTIFY=false
-NOTIFY_FILTER_WORDS=
-## Dingtalk机器人|token|依赖USE_NOTIFY
-NOTIFY_DINGTALK_TOKEN=
-## Tele机器人|token|chatid|依赖USE_NOTIFY
-NOTIFY_TELE_BOTTOKEN=
-NOTIFY_TELE_CHATID=
-## Pushplus酱|token|依赖USE_NOTIFY
-NOTIFY_PUSHPLUS_TOKEN=
-## Sever酱(原版)|令牌Key|依赖USE_NOTIFY
-NOTIFY_SCKEY=
-## Server酱(Turbo版)|令牌Key|依赖USE_NOTIFY
-NOTIFY_SCTKEY=
-## GoCqhttp|url|token|qq|依赖USE_NOTIFY
-NOTIFY_CQ_URL=
-NOTIFY_CQ_TOKEN=
-NOTIFY_CQ_QQ=
-
-#######################
-# 基础设置 #
-#######################
-
-# 独立推送服务(主)|主备冲突
-USE_ALONE_SERVER=false
-ALONE_SERVER_ADDR=tcp://livecmt-1.mudew.com:10088
-ALONE_SERVER_KEY=
-
-# 分区推送服务(备)|主备冲突
-USE_ZONE_SERVER=true
-ZONE_SERVER_ADDR=tcp://broadcastlv.chat.bilibili.com:2243/sub
-
-# 加密心跳服务器(开源)|如失效自行搭建
-ENC_SERVER=http://heartbeat-1.mudew.com:3000/enc
-
-#######################
-# 房间设置 #
-#######################
-
-# 直播间ID,用于礼物赠送
-ROOM_ID=9522051
-
-# 勋章亲密度,测试功能,有短位使用短位反之长位,左侧优先,仅支持辣条和亿元
-# 当列表中所有ID都已达到每日上限,剩余礼物赠送ROOM_ID指定的直播间
-# 是否填满(按时间投喂正常礼物,否则过期礼物)|直播间ID列表|逗号分隔|
-FEED_FILL=false
-ROOM_LIST=9522051
-
-# 弹幕监控房间(为空则随机)
-SOCKET_ROOM_ID=9522051
-
-#######################
-# 网络设置 #
-#######################
-
-# 验证SSL证书|请求时验证SSL证书行为
-VERIFY_SSL=true
-
-# 是否使用代理|(http\https)
-USE_PROXY=false
-NETWORK_PROXY=http://127.0.0.1:8888
-
-#######################
-# 程序设置 #
-#######################
-
-# 写入日志
-APP_WRITE_LOG=false
-
-# 日志路径
-APP_LOG_PATH=log
-
-# 调试模式
-APP_DEBUG=false
-
-# 用户名,可自定义
-APP_UNAME=
-
-# 多账号区别输出
-APP_MULTIPLE=false
-
-# 账号别名,如果为空则默认使用登录账号作为标示
-APP_USER_IDENTITY=
-
-# 日志回调地址
-APP_CALLBACK="http://www.example.com/api.send?text={account}[{level}]: {message}"
-
-# 错误回调级别
-#
-# DEBUG 100
-# INFO 200
-# NOTICE 250
-# WARNING 300
-# ERROR 400
-#
-APP_CALLBACK_LEVEL=400
\ No newline at end of file
diff --git a/conf/user.ini.example b/conf/user.ini.example
new file mode 100644
index 0000000..f5efb82
--- /dev/null
+++ b/conf/user.ini.example
@@ -0,0 +1,290 @@
+#######################
+# 账户设置 #
+#######################
+
+[login.account]
+; 帐号|密码
+username = ""
+password = ""
+
+; 登录模式|[1.账密模式 2.短信验证码模式 3.行为验证码模式(暂未开放)]
+[login.mode]
+mode = 1
+
+; 国家代码|mode=2触发|例:大陆86 澳大利亚61
+[login.country]
+country_code = 86
+
+; 校验|mode=2触发|校验国内手机号|国外手机号关闭校验
+[login.check]
+phone = true
+
+; UID|CSRF|令牌|(当前区域自动生成)
+[login.auth]
+uid =
+csrf =
+cookie =
+access_token =
+refresh_token =
+
+#######################
+# 功能设置 #
+#######################
+
+; 主站每日任务(每日登录、观看、投币、分享)
+[main_site]
+enable = true
+; 每日观看
+watch = true
+; 每日分享
+share = true
+; 每日视频投币|random(随机热门)/fixed(关注列表)|投币稿件数(每日任务最大5)
+add_coin = true
+add_coin_mode = random
+add_coin_num = 5
+
+; 日常/周常礼物
+[daily_bag]
+enable = true
+
+; 双端心跳
+[double_heart]
+enable = true
+
+; 友爱社签到
+[love_club]
+enable = true
+
+; 领取心跳礼物
+[gift_heart]
+enable = true
+
+; 直播每日任务|每日签到|每日登录
+[daily_task]
+enable = true
+
+; 直播箱子实物抽奖
+[live_box]
+enable = true
+
+; 每日24个小心心|依赖加密心跳服务器
+[small_heart]
+enable = true
+
+; 直播扭蛋活动抽奖|依赖加密心跳服务器
+[live_capsule]
+enable = true
+
+; 点亮灰色勋章|100亲密度|每日或者只点亮灰色
+[polish_the_medal]
+enable = true
+everyday = false
+
+; 主站九宫格抽奖活动助手
+[main_activity]
+enable = true
+
+; 银瓜子兑换硬币
+[silver2coin]
+enable = true
+
+; 直播大乱斗
+[live_pk]
+enable = false
+
+; 直播舰长总督
+[live_guard]
+enable = false
+
+; 直播其他礼物
+[live_gift]
+enable = false
+
+; 直播节奏风暴|丢弃率(0-100)|尝试次数(范围值)
+[live_storm]
+enable = false
+drop_rate = 0
+attempt = "5,10"
+
+; 直播天选时刻|抽取类型(0: 无限制; 1: 关注主播; 2: 粉丝勋章; 3大航海; 4用户等级;5主站等级)|自动取关(测试功能)|过滤关键词|逗号分隔
+[live_anchor]
+enable = false
+limit_type = "0,1"
+auto_unfollow = true
+filter_words =
+
+; 获取最新的中奖纪录
+[award_record]
+enable = true
+
+; 活跃弹幕|弹幕房间(为空则随机)|弹幕内容(为空则随机)
+[barrage]
+enable = true
+room_id = 9522051
+content =
+
+; 漫画助手
+[manga]
+enable = false
+
+; 风纪委员投票|需要实名认证
+[judgement]
+enable = false
+
+; 大会员权益|年度大会员专享
+[vip_privilege]
+enable = false
+
+; B币券消费|年度大会员专享|每月默认充值数量5B币|消费方式优先级从上到下
+[bp_consumption]
+enable = false
+# 消费B币充电|充电的目标UID|可充值自己的UID
+bp2charge = false
+bp2charge_uid = 6580464
+# 消费B币充值金瓜子|5000金瓜子
+bp2gold = false
+
+; 自动转发抽奖动态|自动取关未中奖动态|强制清除抽奖组关注|过滤低于多少粉丝|自定义回复|过滤词|逗号分割
+[dynamic]
+enable = false
+clear_dynamic = false
+clear_group_follow = false
+min_fans_num = 15000
+auto_reply_text =
+filter_words =
+
+; 游戏赛事竞猜预测|破产机|每日竞猜次数|每次竞猜硬币(1-10)|下注(1.压大,2.压小,3.随机)
+[match_forecast]
+enable = false
+max_num = 20
+max_coin = 10
+bet = 1
+
+; 休眠时间|时间区间(0-23)|逗号分隔
+[sleep]
+enable = true
+section = "2,3,4,5,6"
+
+#######################
+# 通知设置 #
+#######################
+
+; 消息推送|消息推送过滤词|逗号分割|优先级从上到下
+[notify]
+enable = false
+filter_words =
+
+; Dingtalk机器人|token|依赖USE_NOTIFY
+[notify.dingtalk]
+token =
+
+; Tele机器人|token|chatid|依赖USE_NOTIFY
+[notify.telegram]
+bottoken =
+chatid =
+
+; Pushplus酱|token|依赖USE_NOTIFY
+[notify.pushplus]
+token =
+
+; Sever酱(原版)|令牌Key|依赖USE_NOTIFY
+[notify.sc]
+sckey =
+
+; Server酱(Turbo版)|令牌Key|依赖USE_NOTIFY
+[notify.sct]
+sctkey =
+
+; GoCqhttp|url|token|目标qq|依赖USE_NOTIFY
+[notify.gocqhttp]
+url = ""
+token =
+target_qq =
+
+; Debug|个人调试推送|url|token|
+[notify.debug]
+url = ""
+token =
+
+#######################
+# 基础设置 #
+#######################
+
+; 独立推送服务(主)|主备冲突
+[alone_monitor]
+enable = false
+server_addr = "tcp://livecmt-1.mudew.com:10088"
+server_key = ""
+
+; 分区推送服务(备)|主备冲突
+[zone_monitor]
+enable = true
+server_addr = "tcp://broadcastlv.chat.bilibili.com:2243/sub"
+
+; 加密心跳服务器(开源)|如失效自行搭建
+[heartbeat_enc]
+server = "http://heartbeat-1.mudew.com:3000/enc"
+
+#######################
+# 房间设置 #
+#######################
+
+; 直播间ID,全局房间,用于礼物赠送、心跳等等.
+[global_room]
+room_id = 9522051
+
+; 弹幕监控房间(为空则随机)
+[socket]
+room_id = 9522051
+
+; 勋章亲密度,测试功能,有短位使用短位反之长位,左侧优先,仅支持辣条和亿元
+; 当列表中所有ID都已达到每日上限,剩余礼物赠送ROOM_ID指定的直播间
+; 是否填满(按时间投喂正常礼物,否则过期礼物)|直播间ID列表|逗号分隔|
+[intimacy]
+feed_fill = false
+room_list = 9522051
+
+#######################
+# 网络设置 #
+#######################
+
+; 验证SSL证书|请求时验证SSL证书行为
+[network.ssl]
+verify_ssl = true
+
+; 是否使用代理|(http\https)
+[network.proxy]
+enable = false
+proxy = "http://127.0.0.1:8888"
+
+#######################
+# 程序设置 #
+#######################
+
+; 调试模式|采集完整日志
+[debug]
+enable = false
+
+; 记录日志|日志路径|日志回调地址
+[log]
+enable = false
+path = log
+callback = "http://www.example.com/api.send?text={account}[{level}]: {message}"
+# 错误回调级别
+#
+# DEBUG 100
+# INFO 200
+# NOTICE 250
+# WARNING 300
+# ERROR 400
+#
+callback_level = 400
+
+; app设置
+[print]
+; 用户名,可自定义
+uname =
+; 账号别名,如果为空则默认使用登录账号作为标示
+user_identity =
+; 多账号区别输出
+multiple = false
diff --git a/data/activity_infos.json b/data/activity_infos.json
index 90c1d60..9b50c37 100644
--- a/data/activity_infos.json
+++ b/data/activity_infos.json
@@ -31,62 +31,6 @@
"share": "true",
"draw_times": 1,
"expire_at": "2021-07-15 11:59:59"
- },
- {
- "url": "https://www.bilibili.com/blackboard/activity-nA2uYrmpfA.html",
- "title": "哥斯拉金刚你站谁",
- "description": "活动期间每天分享页面,新增一次机会。",
- "sid": "f851e27a-858e-11eb-8597-246e966235d8",
- "login": "true",
- "follow": "false",
- "share": "true",
- "draw_times": 2,
- "expire_at": "2021-05-23 11:59:59"
- },
- {
- "url": "https://www.bilibili.com/blackboard/activity-QEya2bouhQ.html",
- "title": "春日嗑糖大作战",
- "description": "活动期间每天分享页面,新增一次机会。",
- "sid": "20b0dfaf-8bcd-11eb-8597-246e966235d8",
- "login": "true",
- "follow": "false",
- "share": "true",
- "draw_times": 2,
- "expire_at": "2021-05-05 23:59:59"
- },
- {
- "url": "https://www.bilibili.com/blackboard/gaming_on_bilibili.html",
- "title": "上B站看电竞",
- "description": "活动期间每天分享页面,新增一次机会。",
- "sid": "0b87bd83-8565-11eb-8597-246e966235d8",
- "login": "true",
- "follow": "false",
- "share": "true",
- "draw_times": 1,
- "expire_at": "2021-05-30 23:59:59",
- "remarks": "时间不名,暂定一个月。"
- },
- {
- "url": "https://www.bilibili.com/blackboard/activity-aT7zphkwF1.html",
- "title": "初夏逛吃大会",
- "description": "活动期间每天分享页面,新增一次机会。",
- "sid": "01aff78a-9e1a-11eb-8597-246e966235d8",
- "login": "true",
- "follow": "false",
- "share": "true",
- "draw_times": 1,
- "expire_at": "2021-06-10 23:59:59"
- },
- {
- "url": "https://www.bilibili.com/blackboard/activity-oGiWFe0YTz.html",
- "title": "京东超市超有young",
- "description": "活动期间每天分享页面,新增一次机会。",
- "sid": "4eb728e2-a0d7-11eb-8597-246e966235d8",
- "login": "true",
- "follow": "false",
- "share": "true",
- "draw_times": 1,
- "expire_at": "2021-04-25 23:59:59"
}
]
}
\ No newline at end of file
diff --git a/data/capsule_infos.json b/data/capsule_infos.json
index 09fcb31..1554e38 100644
--- a/data/capsule_infos.json
+++ b/data/capsule_infos.json
@@ -5,9 +5,9 @@
"data": [
{
"_url": "注释: 活动地址",
- "url": "https://www.bilibili.com/blackboard/activity-c_fu2inm-.html",
+ "url": "https://www.bilibili.com/blackboard/activity-kiOl0D1nF8.html",
"_title": "注释: 活动标题",
- "title": "原神1.4版本「风花的邀约」激励计划",
+ "title": "原神1.6版本UP主激励计划",
"_description": "注释: 活动描述",
"description": "每日在原神分区任意直播间观看,20分钟1张、1小时2张、2小时3张,每日最高6张。",
"_room_id": "注释: 活动直播间,如果为0,则取分区随机一个",
@@ -17,25 +17,15 @@
"_parent_area_id": "注释: 主分区id",
"parent_area_id": 3,
"_coin_id": "注释: 抽奖id",
- "coin_id": 112,
+ "coin_id": 165,
+ "_pool_id": "注释: 抽奖id",
+ "pool_id": 179,
"_watch_time": "注释: 观看时长 单位秒",
"watch_time": 7320,
"_draw_times": "注释: 抽奖次数",
- "draw_times": 1,
+ "draw_times": 6,
"_expire_at": "注释: 活动有效时间",
- "expire_at": "2021-04-27 23:59:59"
- },
- {
- "url": "https://www.bilibili.com/blackboard/activity-MHRISE.html",
- "title": "《怪物猎人:崛起》直播挑战",
- "description": "每日在怪物猎人分区任意直播间观看,10分钟1张、30分钟3张、60分钟5张",
- "room_id": 0,
- "area_id": 412,
- "parent_area_id": 6,
- "coin_id": 121,
- "watch_time": 3720,
- "draw_times": 2,
- "expire_at": "2021-04-26 23:59:59"
+ "expire_at": "2021-07-20 23:59:59"
},
{
"url": "https://live.bilibili.com/11218604",
@@ -44,10 +34,11 @@
"room_id": 11218604,
"area_id": 0,
"parent_area_id": 2,
- "coin_id": 129,
+ "coin_id": 170,
+ "pool_id": 183,
"watch_time": 3720,
"draw_times": 3,
- "expire_at": "2021-05-31 23:59:59"
+ "expire_at": "2021-06-27 23:59:59"
},
{
"url": "https://live.bilibili.com/6",
@@ -63,7 +54,7 @@
},
{
"url": "https://live.bilibili.com/23",
- "title": "PEI亚洲邀请赛",
+ "title": "PEL和平精英职业联赛",
"description": "每日在PEL直播间观看,5分钟1张",
"room_id": 13242892,
"area_id": 0,
@@ -71,7 +62,7 @@
"coin_id": 109,
"watch_time": 3720,
"draw_times": 2,
- "expire_at": "2021-05-31 23:59:59"
+ "expire_at": "2021-06-13 23:59:59"
}
]
}
\ No newline at end of file
diff --git a/data/filter_library.json b/data/filter_library.json
new file mode 100644
index 0000000..2279335
--- /dev/null
+++ b/data/filter_library.json
@@ -0,0 +1,727 @@
+{
+ "MaterialObject": {
+ "sensitive": [
+ "测试",
+ "加密",
+ "test",
+ "TEST",
+ "钓",
+ "实验",
+ "炸鱼",
+ "调试",
+ "123",
+ "1111",
+ "测试",
+ "測試",
+ "Test",
+ "测一测",
+ "ce-shi",
+ "test",
+ "T-E-S-T",
+ "lala",
+ "我是抽奖标题",
+ "压测",
+ "測一測",
+ "t-e-s-t"
+ ]
+ },
+ "Anchor": {
+ "default": [
+ "拉黑",
+ "黑名单",
+ "脸皮厚",
+ "没有奖品",
+ "无奖",
+ "脸皮厚",
+ "ceshi",
+ "测试",
+ "测试",
+ "测试",
+ "脚本",
+ "抽奖号",
+ "星段位",
+ "星段位",
+ "圣晶石",
+ "圣晶石",
+ "水晶",
+ "水晶",
+ "万兴神剪手",
+ "万兴神剪手",
+ "自付邮费",
+ "自付邮费",
+ "test",
+ "Test",
+ "TEST",
+ "加密",
+ "QQ",
+ "测试",
+ "測試",
+ "VX",
+ "vx",
+ "ce",
+ "shi",
+ "这是一个",
+ "lalall",
+ "第一波",
+ "第二波",
+ "第三波",
+ "测试用",
+ "抽奖标题",
+ "策是",
+ "房间抽奖",
+ "CESHI",
+ "ceshi",
+ "奖品A",
+ "奖品B",
+ "奖品C",
+ "硬币",
+ "无奖品",
+ "白名单",
+ "我是抽奖",
+ "五毛二",
+ "一分",
+ "一毛",
+ "0.52",
+ "0.66",
+ "0.01",
+ "0.77",
+ "0.16",
+ "照片",
+ "穷",
+ "0.5",
+ "0.88",
+ "双排",
+ "1毛",
+ "1分",
+ "1角",
+ "P口罩",
+ "素颜",
+ "写真",
+ "图包",
+ "五毛",
+ "一角",
+ "冥币",
+ "自拍",
+ "日历",
+ "0.22",
+ "加速器",
+ "越南盾",
+ "毛",
+ "分",
+ "限",
+ "0.",
+ "角",
+ "〇点",
+ "①元",
+ "一起玩",
+ "不包邮",
+ "邮费",
+ "续期卡",
+ "儿时",
+ "闪宠",
+ "大师球",
+ "一元",
+ "两元",
+ "两块",
+ "赛车",
+ "代币",
+ "一块",
+ "一局",
+ "好友位",
+ "通话",
+ "首胜",
+ "代金券",
+ "辣条",
+ "补贴",
+ "抵用券",
+ "主播素颜照",
+ "武器箱棺材板",
+ "游戏道具",
+ "优惠券",
+ "日元",
+ "发音课",
+ "壹元",
+ "零点",
+ "舰长五折券",
+ "上车",
+ "没有钱",
+ "女装",
+ "肥宅快乐水",
+ "哥斯拉",
+ "公主连结",
+ "pokemmo",
+ "宝可>梦",
+ "明日方舟",
+ "雪碧",
+ "公主连接",
+ "专属头衔",
+ "FF14",
+ "韩元",
+ "空洞骑士",
+ "老婆饼",
+ "稀世时装",
+ "洛克衣服",
+ "帮过图",
+ "证件照",
+ "自抽号",
+ "晶耀之星",
+ "伊洛纳",
+ "〇.",
+ "②元",
+ "③元",
+ "0·",
+ "繁华美化",
+ "喵喵喵",
+ "闪伊布",
+ "①圆",
+ "o点",
+ "金达摩",
+ "嗷呜",
+ "游戏位",
+ "S-追光者",
+ "OWL",
+ "勾玉",
+ "跟yo宝游戏",
+ "三元",
+ "怡宝",
+ "蛋闪迷>你冰",
+ "哥伦比亚比索",
+ "油条",
+ "代金卷",
+ "小堂包",
+ "返现券",
+ "上舰",
+ "舰长",
+ "开舰",
+ "帅照",
+ "靓照",
+ "1元红包",
+ "红包3.3元",
+ "5.2元红包",
+ "2.33元红包",
+ "测试",
+ "钓鱼",
+ "炸鱼",
+ "黑屋",
+ "脚本",
+ "空气",
+ "大航海",
+ "上船",
+ "舰长",
+ "返现",
+ "抵用",
+ "代金",
+ "上车",
+ "上反船",
+ "照片",
+ "素颜",
+ "自拍",
+ "皂片",
+ "开舰",
+ "上舰",
+ "自画像",
+ "封面",
+ "取关",
+ "美照",
+ "随机照",
+ "女装照",
+ "日常照",
+ "好友",
+ "给主播",
+ "照骗",
+ "连麦",
+ "情书",
+ "一局",
+ "舰涨优惠卷",
+ "开黑",
+ "test",
+ "Test",
+ "金币",
+ "元宝",
+ "代打",
+ "上分",
+ "上段",
+ "台历",
+ "一毛",
+ "五毛",
+ "王者荣耀",
+ "玩游戏",
+ "encrypt",
+ "壁纸",
+ "相片",
+ "排位",
+ "语音",
+ "车位",
+ "网剧",
+ "一起玩",
+ "一次",
+ "专属头衔",
+ "手游",
+ "宠物",
+ "蒸汽",
+ "月饼",
+ "加速",
+ "挂件",
+ "渔夫",
+ "小黑屋",
+ "头像",
+ "许愿码",
+ "电池",
+ "赛车",
+ "保底",
+ "代币",
+ "越南盾",
+ "网点",
+ "机器",
+ "话梅",
+ "志愿",
+ "令牌",
+ "永久",
+ "第五人格",
+ "大蒜",
+ "唢呐",
+ "皇冠",
+ "徽章",
+ "铜牌",
+ "动物园",
+ "植物",
+ "钻石",
+ "宝石",
+ "尖叫",
+ "扭蛋机",
+ "点播",
+ "数字版月历",
+ "点歌一首",
+ "体验",
+ "点歌",
+ "三次取关",
+ "大航海",
+ "3块钱之前的巨款",
+ "礼金"
+ ]
+ },
+ "CapsuleLottery": {
+ "default": [
+ "谢谢参与",
+ "未中奖",
+ "辣条"
+ ]
+ },
+ "ActivityLottery": {
+ "default": [
+ "谢谢参与",
+ "未中奖",
+ "辣条"
+ ]
+ },
+ "Notice": {
+ "default": [
+ "谢谢参与",
+ "未中奖",
+ "辣条"
+ ]
+ },
+ "DynamicForward": {
+ "default": [
+ "一毛",
+ "结果",
+ "test",
+ "元宝",
+ "晒出",
+ "原石",
+ "代打",
+ "上分",
+ "测试",
+ "闹着玩",
+ "猫粮",
+ "钓鱼",
+ "加密",
+ "好友",
+ "视频下转发",
+ "签名照",
+ "全部答对",
+ "弹幕",
+ "评论下方投稿视频",
+ "炸鱼",
+ "黑屋",
+ "照片",
+ "素颜",
+ "自拍",
+ "皂片",
+ "自画像",
+ "封面",
+ "取关",
+ "随机照",
+ "宝石",
+ "真情实感",
+ "给主播",
+ "照骗",
+ "连麦",
+ "加群",
+ "钓鱼",
+ "脚本",
+ "代金券",
+ "体验卡",
+ "门票",
+ "渲染券",
+ "机器",
+ "给视频",
+ "投票",
+ "取关",
+ "视频转发",
+ "视频分享",
+ "于视频内",
+ "视频评论",
+ "分享视频",
+ "转发视频",
+ "评论视频",
+ "进入直播间",
+ "平时售价",
+ "体验名额",
+ "评论区点赞前",
+ "上直播",
+ "参与直播抽奖",
+ "堆jqr",
+ "AI转",
+ "AI来",
+ "bot来",
+ "堆bot",
+ "jqr来",
+ "有jqr",
+ "有bot",
+ "jqr",
+ "bot"
+ ]
+ },
+ "Common": {
+ "default": [
+ "禁言",
+ "测试",
+ "vcf",
+ "体验中奖",
+ "中奖的感觉",
+ "赶脚",
+ "感脚",
+ "感jio",
+ "黑名单",
+ "拉黑",
+ "脸皮厚",
+ "没有奖品",
+ "无奖",
+ "ceshi",
+ "脚本",
+ "抽奖号",
+ "不要脸",
+ "至尊vip会员7天",
+ "高级会员7天",
+ "万兴神剪手",
+ "加密",
+ "test",
+ "TEST",
+ "钓鱼",
+ "炸鱼",
+ "调试",
+ "编曲",
+ "作词",
+ "半价",
+ "打折",
+ "机器",
+ "禁言",
+ "vcf",
+ "体验中奖",
+ "中奖的感觉",
+ "录歌",
+ "混音",
+ "一毛",
+ "1角",
+ "0.5元",
+ "5毛",
+ "赶脚",
+ "感脚",
+ "曲风",
+ "专辑封面",
+ "一元红包",
+ "感jio",
+ "名片赞",
+ "黑名单",
+ "拉黑",
+ "脸皮厚",
+ "没有奖品",
+ "无奖",
+ "脚本",
+ "抽奖号",
+ "不要脸",
+ "至尊vip会员7天",
+ "高级会员7天",
+ "加密",
+ "test",
+ "TEST",
+ "钓鱼",
+ "炸鱼",
+ "调试",
+ "歌曲定制",
+ "学习视频",
+ "修图视频",
+ "免费编曲",
+ "后期制作",
+ "编曲搬家",
+ "内容自定",
+ "音乐人一个",
+ "私人唱歌",
+ "作业",
+ "八字",
+ "算命",
+ "万兴神剪手",
+ "学习修图",
+ "写一首歌",
+ "ceshi",
+ "管饱",
+ "dong tai ga",
+ "电话唱歌",
+ "感谢转发",
+ "非独家使用权",
+ "前排沙发",
+ "琴谱",
+ "有就送",
+ "什么也不给",
+ "什么都没有",
+ "租赁",
+ "伴奏",
+ "定制beat",
+ "定制logo",
+ "惊喜软件",
+ "加群",
+ "第一批粉丝",
+ "内部群",
+ "老粉",
+ "仅我关注",
+ "打字粉丝ID",
+ "手打粉丝ID",
+ "人声采集",
+ "采样包",
+ "约稿",
+ "remix",
+ "明信片",
+ "感受中奖",
+ "快落",
+ "中奖的快乐",
+ "单曲",
+ "主题创作",
+ "猎妈",
+ "签名照",
+ "数字专辑",
+ "除夕夜",
+ "专辑",
+ "励志的话",
+ "亲笔签名",
+ "扫码进群",
+ "粉丝群",
+ "签名写真",
+ "纹身",
+ "祝你",
+ "红包雨",
+ "电子书",
+ "好友位",
+ "豪车优惠",
+ "星段位",
+ "圣晶石",
+ "水晶",
+ "QQ",
+ "自付邮费",
+ "Test",
+ "测试用",
+ "VX",
+ "vx",
+ "ce",
+ "shi",
+ "这是一个",
+ "lalall",
+ "第一波",
+ "第二波",
+ "策是",
+ "照片",
+ "穷",
+ "0.5",
+ "一角",
+ "冥币",
+ "加速器",
+ "无奖品",
+ "白名单",
+ "五毛",
+ "第三波",
+ "五毛二",
+ "一分",
+ "0.52",
+ "0.66",
+ "0.01",
+ "0.77",
+ "0.16",
+ "0.88",
+ "双排",
+ "1毛",
+ "1分",
+ "P口罩",
+ "素颜",
+ "写真",
+ "图包",
+ "自拍",
+ "日历",
+ "0.22",
+ "CESHI",
+ "奖品A",
+ "抽奖标题",
+ "測試",
+ "越南盾",
+ "啥都没有",
+ "哈哈哈",
+ "作曲",
+ "一首",
+ "手绘",
+ "学霸",
+ "buff",
+ "头像",
+ "剩的",
+ "Ziyoda",
+ "Hilola",
+ "beden",
+ "新专",
+ "采样",
+ "音频",
+ "海报",
+ "粉丝ID",
+ "微博",
+ "互粉",
+ "真心话",
+ "回答",
+ "签名海报",
+ "不想要",
+ "抱抱",
+ "拥抱",
+ "WAV",
+ "邀请函",
+ "你猜猜",
+ "什么也没有",
+ "什么都",
+ "什么也",
+ "这不是抽奖",
+ "使用权",
+ "曲谱",
+ "啥也没有",
+ "木有",
+ "车载音乐",
+ "会员歌曲",
+ "一首歌",
+ "必唱",
+ "发文件",
+ "词作",
+ "购买资格",
+ "粉群",
+ "折扣",
+ "hoholive",
+ "surat",
+ "hisyat",
+ "免费观",
+ "免费演",
+ "免费门",
+ "谢谢参与",
+ "vx call u",
+ "新婚快乐",
+ "歌曲使用权",
+ "普通mp3使用权",
+ "破解版",
+ "土嗨",
+ "给你写",
+ "普通mp3",
+ "啥也不是",
+ "歌曲大礼包",
+ "歌手大礼包",
+ "无损wav",
+ "mp3使用权",
+ "wav使用权",
+ "曲谱",
+ "抽个寂寞",
+ "儿子",
+ "送我"
+ ],
+ "uid_list": [
+ 28008897,
+ 28272016,
+ 140389827,
+ 24598781,
+ 28008860,
+ 28008880,
+ 28008743,
+ 28008948,
+ 28009292,
+ 319696958,
+ 90138218,
+ 28272000,
+ 28272047,
+ 28271978,
+ 8831288,
+ 175979009,
+ 3177443,
+ 486780865,
+ 403048135,
+ 474325039,
+ 455274996,
+ 477519424,
+ 292671666,
+ 448873224,
+ 22498938,
+ 1770865,
+ 444796995,
+ 306112375,
+ 320193786,
+ 606637517,
+ 305276429,
+ 204487541,
+ 404761800,
+ 186914127,
+ 99439379,
+ 457697569,
+ 270886929,
+ 477519424,
+ 401575,
+ 201296348,
+ 206804212,
+ 333584926,
+ 34679178,
+ 699923691,
+ 392689522,
+ 178700744,
+ 272882445,
+ 350977368,
+ 487168411,
+ 22682842,
+ 444949061,
+ 523974463,
+ 192231907,
+ 503908324,
+ 383189098,
+ 252909207,
+ 336467750,
+ 264875137,
+ 90721742,
+ 452299642,
+ 677739290,
+ 441522918,
+ 8766623,
+ 698327474,
+ 5439672,
+ 483247863,
+ 237055308,
+ 95404163,
+ 202052696,
+ 1309889741,
+ 627942060,
+ 455030741,
+ 406353670,
+ 18036870,
+ 470220612,
+ 432013403,
+ 1346052604,
+ 501312931
+ ]
+ }
+}
diff --git a/data/filter_words.json b/data/filter_words.json
deleted file mode 100644
index b5eb8ec..0000000
--- a/data/filter_words.json
+++ /dev/null
@@ -1,324 +0,0 @@
-{
- "MaterialObject": {
- "sensitive": [
- "测试",
- "加密",
- "test",
- "TEST",
- "钓鱼",
- "炸鱼",
- "调试",
- "123",
- "1111",
- "测试",
- "測試",
- "Test",
- "测一测",
- "ce-shi",
- "test",
- "T-E-S-T",
- "lala",
- "我是抽奖标题",
- "压测",
- "測一測",
- "t-e-s-t"
- ]
- },
- "Anchor": {
- "default": [
- "拉黑",
- "黑名单",
- "脸皮厚",
- "没有奖品",
- "无奖",
- "脸皮厚",
- "ceshi",
- "测试",
- "测试",
- "测试",
- "脚本",
- "抽奖号",
- "星段位",
- "星段位",
- "圣晶石",
- "圣晶石",
- "水晶",
- "水晶",
- "万兴神剪手",
- "万兴神剪手",
- "自付邮费",
- "自付邮费",
- "test",
- "Test",
- "TEST",
- "加密",
- "QQ",
- "测试",
- "測試",
- "VX",
- "vx",
- "ce",
- "shi",
- "这是一个",
- "lalall",
- "第一波",
- "第二波",
- "第三波",
- "测试用",
- "抽奖标题",
- "策是",
- "房间抽奖",
- "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.",
- "角",
- "〇点",
- "①元",
- "一起玩",
- "不包邮",
- "邮费",
- "续期卡",
- "儿时",
- "闪宠",
- "大师球",
- "一元",
- "两元",
- "两块",
- "赛车",
- "代币",
- "一块",
- "一局",
- "好友位",
- "通话",
- "首胜",
- "代金券",
- "辣条",
- "补贴",
- "抵用券",
- "主播素颜照",
- "武器箱棺材板",
- "游戏道具",
- "优惠券",
- "日元",
- "发音课",
- "壹元",
- "零点",
- "舰长五折券",
- "上车",
- "没有钱",
- "女装",
- "肥宅快乐水",
- "哥斯拉",
- "公主连结",
- "pokemmo",
- "宝可>梦",
- "明日方舟",
- "雪碧",
- "公主连接",
- "专属头衔",
- "FF14",
- "韩元",
- "空洞骑士",
- "老婆饼",
- "稀世时装",
- "洛克衣服",
- "帮过图",
- "证件照",
- "自抽号",
- "晶耀之星",
- "伊洛纳",
- "〇.",
- "②元",
- "③元",
- "0·",
- "繁华美化",
- "喵喵喵",
- "闪伊布",
- "①圆",
- "o点",
- "金达摩",
- "嗷呜",
- "游戏位",
- "S-追光者",
- "OWL",
- "勾玉",
- "跟yo宝游戏",
- "三元",
- "怡宝",
- "蛋闪迷>你冰",
- "哥伦比亚比索",
- "油条",
- "代金卷",
- "小堂包",
- "返现券",
- "上舰",
- "舰长",
- "开舰",
- "帅照",
- "靓照",
- "1元红包",
- "红包3.3元",
- "5.2元红包",
- "2.33元红包",
- "测试",
- "钓鱼",
- "炸鱼",
- "黑屋",
- "脚本",
- "空气",
- "大航海",
- "上船",
- "舰长",
- "返现",
- "抵用",
- "代金",
- "上车",
- "上反船",
- "照片",
- "素颜",
- "自拍",
- "皂片",
- "开舰",
- "上舰",
- "自画像",
- "封面",
- "取关",
- "美照",
- "随机照",
- "女装照",
- "日常照",
- "好友",
- "给主播",
- "照骗",
- "连麦",
- "情书",
- "一局",
- "舰涨优惠卷",
- "开黑",
- "test",
- "Test",
- "金币",
- "元宝",
- "代打",
- "上分",
- "上段",
- "台历",
- "一毛",
- "五毛",
- "王者荣耀",
- "玩游戏",
- "encrypt",
- "壁纸",
- "相片",
- "排位",
- "语音",
- "车位",
- "网剧",
- "一起玩",
- "一次",
- "专属头衔",
- "手游",
- "宠物",
- "蒸汽",
- "月饼",
- "加速",
- "挂件",
- "渔夫",
- "小黑屋",
- "头像",
- "许愿码",
- "电池",
- "赛车",
- "保底",
- "代币",
- "越南盾",
- "网点",
- "机器",
- "话梅",
- "志愿",
- "令牌",
- "永久",
- "第五人格",
- "大蒜",
- "唢呐",
- "皇冠",
- "徽章",
- "铜牌",
- "动物园",
- "植物",
- "钻石",
- "宝石",
- "尖叫",
- "扭蛋机",
- "点播",
- "数字版月历",
- "点歌一首",
- "体验",
- "点歌",
- "三次取关",
- "大航海",
- "3块钱之前的巨款",
- "礼金"
- ]
- },
- "CapsuleLottery": {
- "default": [
- "谢谢参与",
- "未中奖",
- "辣条"
- ]
- },
- "ActivityLottery": {
- "default": [
- "谢谢参与",
- "未中奖",
- "辣条"
- ]
- },
- "Notice": {
- "default": [
- "谢谢参与",
- "未中奖",
- "辣条"
- ]
- }
-}
\ No newline at end of file
diff --git a/data/latest_version.json b/data/latest_version.json
new file mode 100644
index 0000000..ea47efc
--- /dev/null
+++ b/data/latest_version.json
@@ -0,0 +1,11 @@
+{
+ "code": 0,
+ "project":"BiliHelper-personal",
+ "branch": "master",
+ "source": "https://github.com/lkeme/BiliHelper-personal",
+ "raw_url": "https://cdn.jsdelivr.net/gh/lkeme/BiliHelper-personal@master/data/latest_version.json",
+ "purge_url": "https://purge.jsdelivr.net/gh/lkeme/BiliHelper-personal@master/data/latest_version.json",
+ "version": "0.9.7.210714",
+ "des": "程序有更新,请及时线上查看更新哦~",
+ "time": "2021年7月14日11:40:35"
+}
\ No newline at end of file
diff --git a/data/reply_words.json b/data/reply_words.json
new file mode 100644
index 0000000..1380ede
--- /dev/null
+++ b/data/reply_words.json
@@ -0,0 +1,175 @@
+{
+ "DynamicForward": {
+ "default": [
+ "从未中奖,从未放弃[doge]",
+ "来当分母= =",
+ "让我中一次吧QAQ",
+ "继续分母",
+ "转发动态",
+ "单纯想中次奖",
+ "我我我",
+ "不错",
+ "来了来了",
+ "爱了",
+ "(;¬_¬)",
+ "(~_~;)",
+ "= =!",
+ "╮(╯▽╰)╭",
+ "(シ_ _)シ",
+ ">_<",
+ "(๑• _ •๑)",
+ "(:3_ヽ)_",
+ "(⌒▽⌒)",
+ "(`・ω・´)",
+ "(◦˙▽˙◦)",
+ "(=・ω・=)",
+ "_Σ:з」∠)シ",
+ "o(∩_∩)o",
+ "(〜 ̄▽ ̄)〜",
+ "(๑• ▽ •๑)",
+ "哔哩哔哩干杯~",
+ "Bilibili 干杯~",
+ "bilibili 干杯~",
+ "[doge][doge][doge]",
+ "冲冲冲[打call][打call]",
+ "[doge]",
+ "万一可能呢",
+ "我的",
+ "[打call]",
+ "就看欧不欧啦",
+ "来了",
+ "中",
+ "好诶",
+ "好耶",
+ "拉低中奖率",
+ "重在拉低中奖率[doge]",
+ "分母",
+ "评论",
+ "成为一个分母,希望成为分子",
+ "[藏狐]我来",
+ "重在参与[OK]",
+ "就是我[给心心][打call]",
+ "抽起来!!!",
+ "我也要中奖",
+ "冲",
+ "[拥抱]",
+ "万一呢?",
+ "我来了",
+ "欧欧欧",
+ "冲冲冲",
+ "谢谢给我一个中奖的机会",
+ "奖励不重要,重要的是心[doge]",
+ "许愿",
+ "分母报道",
+ "大吉大利",
+ "欧气满满",
+ "不想再当分母",
+ "吸欧气",
+ "中!!!",
+ "",
+ "好运来",
+ "啊~",
+ "哈哈哈",
+ "抽奖奖(⌒▽⌒)",
+ "中奖绝缘体",
+ "绝缘体",
+ "求脱非入欧",
+ "好运",
+ "中奖绝缘体表示想中!",
+ "呜呜呜非洲人来了",
+ "选我吧",
+ "一定会中",
+ "好运bufff",
+ "滴滴滴",
+ "哇哇哇哇",
+ "万一呢",
+ "非酋日常",
+ "加油",
+ "抽中吧",
+ "我要",
+ "想欧一次!",
+ "拉低中奖率233",
+ "想要...",
+ "路过拉低中奖率",
+ "希望有个好运气",
+ "中奖",
+ "什么时候才会抽到我呢?",
+ "试试水,看看能不能中",
+ "过来水一手",
+ "这辈子都不可能中奖的",
+ "先拉低中奖率23333",
+ "先抽奖,抽不到再说",
+ "嘤嘤嘤",
+ "捞一把",
+ "我就想中一次",
+ "拉低拉低",
+ "试一试",
+ "搞一搞",
+ "中奖什么的不可能的( ̄▽ ̄)",
+ "听说我中奖了?",
+ "脱非转欧",
+ "emm",
+ "无聊.。。。。",
+ "[星星眼]",
+ "[妙啊]",
+ "[辣眼睛]",
+ "[吃瓜][吃瓜]",
+ "[滑稽]",
+ "[呲牙]",
+ "[打call][打call]",
+ "[哈欠][哈欠]",
+ "[吃瓜]不嫌事大",
+ "[口罩]",
+ "[思考]",
+ "[冷][冷][冷]",
+ "次次参加",
+ "从来没中过",
+ "让我中吧",
+ "来中个吧",
+ "送妹子多好",
+ "再送个小姐姐咋样",
+ "忍不住抽",
+ " (* ̄︶ ̄)",
+ "如影随形",
+ "参加够多就能中奖",
+ "参加够多就能当分子",
+ "[喜极而泣]",
+ "我是天选之子",
+ "中一次吧!",
+ "坚持不懈,迎难而上,开拓创新!",
+ "[OK][OK]",
+ "抽个奖和寂寞",
+ "中中",
+ "坚持不懈,迎难而上!",
+ "呵呵",
+ "我一般不抽奖,除非忍不住。",
+ "[OK]",
+ "[喜欢]",
+ "[偷笑]",
+ "[笑]",
+ "[吃瓜]",
+ "[奋斗]",
+ "在",
+ "冲吖~",
+ "[保佑][保佑]",
+ "从未中,从未停",
+ "[抠鼻][抠鼻]",
+ "来力",
+ "秋梨膏",
+ "从不缺席",
+ "分子",
+ "1",
+ "好",
+ "rush",
+ "来来来",
+ "ok",
+ "凑热闹",
+ "我要我要[打call]",
+ "我还能中!让我中!!!",
+ "大家都散了吧,已经抽完了,是我的",
+ "给我中一次吧!",
+ "我来抽个奖",
+ "[doge][doge][doge]"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 0000000..cc80e58
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,45 @@
+FROM php:alpine
+
+#MAINTAINER zsnmwy
+LABEL AUTHOR = "Lkeme "
+
+ENV USER_NAME='' \
+ USER_PASSWORD='' \
+ REPO_URL='https://github.com/' \
+ MIRRORS="0" \
+ CONIFG_PATH='/app/conf/user.ini' \
+ Green="\\033[32m" \
+ Red="\\033[31m" \
+ GreenBG="\\033[42;37m" \
+ RedBG="\\033[41;37m" \
+ Font="\\033[0m" \
+ Green_font_prefix="\\033[32m" \
+ Green_background_prefix="\\033[42;37m" \
+ Font_color_suffix="\\033[0m" \
+ Info="${Green}[信息]${Font}" \
+ OK="${Green}[OK]${Font}" \
+ Error="${Red}[错误]${Font}"
+
+WORKDIR /app
+
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
+#RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
+RUN docker-php-ext-install sockets
+
+#RUN if [ "${CN}" = true ]; then export REPO_URL="https://github.com.cnpmjs.org"; fi
+
+#RUN set -ex \
+# && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+# && echo "Asia/Shanghai" > /etc/timezone \
+
+RUN apk add --no-cache git && \
+ git clone ${REPO_URL}/lkeme/BiliHelper-personal.git --depth=1 /app && \
+ cp -f /app/docker/entrypoint.sh /usr/local/bin/entrypoint.sh && \
+ chmod 777 /usr/local/bin/entrypoint.sh && \
+ php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" && \
+ php composer-setup.php && \
+ php composer.phar install && \
+ rm -r /var/cache/apk && \
+ rm -r /usr/share/man
+
+ENTRYPOINT ["entrypoint.sh"]
\ No newline at end of file
diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh
new file mode 100644
index 0000000..e2af4dd
--- /dev/null
+++ b/docker/entrypoint.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+set -e
+
+# 源切换
+case ${MIRRORS} in
+"0")
+ echo -e "\n ======== \n ${Info} ${GreenBG} 切换源-github.com ${Font} \n ======== \n"
+ git remote set-url origin https://github.com/lkeme/BiliHelper-personal.git
+ ;;
+"1")
+ echo -e "\n ======== \n ${Info} ${GreenBG} 切换源-ghproxy.com ${Font} \n ======== \n"
+ git remote set-url origin https://ghproxy.com/https://github.com/lkeme/BiliHelper-personal.git
+ ;;
+"2")
+ echo -e "\n ======== \n ${Info} ${GreenBG} 切换源-github.com.cnpmjs.org ${Font} \n ======== \n"
+ git remote set-url origin https://github.com.cnpmjs.org/lkeme/BiliHelper-personal.git
+ ;;
+*)
+ echo -e "\n ======== \n ${Info} ${GreenBG} 切换源-github.com ${Font} \n ======== \n"
+ git remote set-url origin https://github.com/lkeme/BiliHelper-personal.git
+ ;;
+esac
+
+# 拉取更新
+echo -e "\n ======== \n ${Info} ${GreenBG} 正使用 git pull 同步项目 ${Font} \n ======== \n"
+git pull
+
+# 安装依赖
+echo -e "\n ======== \n ${Info} ${GreenBG} 安装/更新 项目运行依赖 ${Font} \n ======== \n"
+php composer.phar install
+echo -e "\n \n \n \n"
+
+# 判断类型
+if [[ -f ${CONIFG_PATH} ]]; then
+ echo -e "\n ======== \n ${GreenBG} 正在使用外部配置文件 ${Font} \n ======== \n"
+else
+ echo -e "${OK} ${GreenBG} 正在使用传入的环境变量进行用户配置。\n 如果需要配置更多选择项,请通过挂载配置文件来传入。具体参考项目中的README。\n https://github.com/lkeme/BiliHelper-personal.git ${Font} \n ======== \n "
+ cp /app/conf/user.ini.example /app/conf/user.ini
+ sed -i ''"$(cat /app/conf/user.ini -n | grep "username = \"\"" | awk '{print $1}')"'c '"$(echo "username = \"${USER_NAME}\"")"'' ${CONIFG_PATH}
+ sed -i ''"$(cat /app/conf/user.ini -n | grep "password = \"\"" | awk '{print $1}')"'c '"$(echo "password = \"${USER_PASSWORD}\"")"'' ${CONIFG_PATH}
+fi
+
+php index.php
diff --git a/index.php b/index.php
index c977764..dd2a4b3 100644
--- a/index.php
+++ b/index.php
@@ -11,9 +11,7 @@
require 'vendor/autoload.php';
-
-$filename = isset($argv[1]) ? $argv[1] : 'user.conf';
-
$app = new BiliHelper\Core\App(__DIR__);
-$app->load($filename);
-$app->start();
+$app->load($argv)
+ ->inspect()
+ ->start();
diff --git a/src/core/App.php b/src/core/App.php
index fccc7d2..749bf3e 100644
--- a/src/core/App.php
+++ b/src/core/App.php
@@ -12,11 +12,12 @@ namespace BiliHelper\Core;
use Amp\Loop;
use function Amp\asyncCall;
-use BiliHelper\Plugin\Notice;
-
class App
{
+ private $script_mode = false;
+ private $loop_mode = true;
+
/**
* App constructor.
* @param string $app_path
@@ -26,55 +27,84 @@ class App
define('APP_CONF_PATH', $app_path . "/conf/");
define('APP_DATA_PATH', $app_path . "/data/");
define('APP_LOG_PATH', $app_path . "/log/");
+ define('APP_TASK_PATH', $app_path . "/task/");
+ }
+
+ /**
+ * @use 检查环境
+ * @return $this
+ */
+ public function inspect(): App
+ {
(new Env())->inspect_configure()->inspect_extension();
+ return $this;
}
/**
* @use 加载配置
- * @param string $load_file
+ * @param $argv
* @return $this
*/
- public function load($load_file = 'user.conf')
+ public function load($argv): App
{
- Config::load($load_file);
+ $args = (new Command($argv))->run();
+ $filename = $args->getArg(0) ?? 'user.ini';
+ $this->script_mode = $args->getOpt('script');
+
+ Config::load($filename);
return $this;
}
/**
* @use 新任务
* @param string $taskName
+ * @param string $dir
*/
- public function newTask(string $taskName)
+ public function newTask(string $taskName, string $dir)
{
- asyncCall(function () use ($taskName) {
+ asyncCall(function () use ($taskName, $dir) {
while (true) {
try {
- call_user_func(array('BiliHelper\Plugin\\' . $taskName, 'run'), []);
+ call_user_func(array("BiliHelper\\$dir\\" . $taskName, 'run'), []);
} catch (\Throwable $e) {
$error_msg = "MSG: {$e->getMessage()} CODE: {$e->getCode()} FILE: {$e->getFile()} LINE: {$e->getLine()}";
Log::error($error_msg);
// Notice::push('error', $error_msg);
}
- yield call_user_func(array('BiliHelper\Plugin\\' . $taskName, 'Delayed'), []);
+ yield call_user_func(array("BiliHelper\\$dir\\" . $taskName, 'Delayed'), []);
}
});
}
/**
- * @use 核心运行
+ * @use Script模式
*/
- public function start()
+ private function script_m()
+ {
+ $scripts = [
+ 'UnFollow' => '批量取消关注(暂测试)',
+ 'DelDynamic' => '批量清理动态(未完成)'
+ ];
+
+ $choice = \BiliHelper\Script\BaseTask::choice($scripts, 'UnFollow');
+ $this->newTask($choice, 'Script');
+ }
+
+ /**
+ * @use Loop模式
+ */
+ private function loop_m()
{
$plugins = [
+ 'CheckUpdate',
'Login',
'Schedule',
'MainSite',
- 'Daily',
+ 'DailyBag',
'ManGa',
- 'GameMatch',
'ActivityLottery',
'Competition',
- 'Heart',
+ 'DoubleHeart',
'DailyTask',
'Barrage',
'Silver2Coin',
@@ -92,15 +122,34 @@ class App
'GuardRaffle',
'AnchorRaffle',
'AwardRecord',
- 'Statistics',
'Forward',
'CapsuleLottery',
- // 'Silver',
+ 'PolishTheMedal',
+ 'VipPrivilege',
+ 'BpConsumption',
+ // 'Silver', // Abandoned
+ 'Statistics',
];
foreach ($plugins as $plugin) {
- $this->newTask($plugin);
+ $this->newTask($plugin, 'Plugin');
}
Loop::run();
}
+
+
+ /**
+ * @use 核心运行
+ */
+ public function start()
+ {
+ // Todo 模式名称需要优化
+ if ($this->script_mode) {
+ Log::info('执行Script模式');
+ $this->script_m();
+ } else {
+ Log::info('执行Loop模式');
+ $this->loop_m();
+ }
+ }
}
diff --git a/src/core/Command.php b/src/core/Command.php
new file mode 100644
index 0000000..be5a97c
--- /dev/null
+++ b/src/core/Command.php
@@ -0,0 +1,52 @@
+argv = $argv;
+ }
+
+ /**
+ * @return \Garden\Cli\Args
+ */
+ public function run(): Args
+ {
+ $cli = new Cli();
+
+ $cli->description('BHP命令行工具.')
+ ->opt('script:s', '执行的Script模式.', false, 'bool');
+
+ try {
+ $args = $cli->parse($this->argv, true);
+ } catch (\Exception $e) {
+ die('解析命令行参数错误');
+ }
+ return $args;
+ }
+
+}
+
+
+
+
diff --git a/src/core/Config.php b/src/core/Config.php
index 1b8ce99..627034c 100644
--- a/src/core/Config.php
+++ b/src/core/Config.php
@@ -10,16 +10,17 @@
namespace BiliHelper\Core;
-use Dotenv\Dotenv;
-
+use Jelix\IniFile\IniModifier;
class Config
{
private static $app_config;
+ private static $load_file;
+ private static $last_time;
private static $config_path;
private static $instance;
- public static function getInstance()
+ private static function getInstance(): Config
{
if (is_null(self::$instance)) {
self::$instance = new static;
@@ -27,72 +28,78 @@ class Config
return self::$instance;
}
-
- public static function load($load_file)
- {
- return self::getInstance()::_load($load_file);
- }
-
- public static function put($key, $val = null)
- {
- return self::getInstance()::_put($key, $val);
- }
-
- public static function get($key = null)
- {
- return self::getInstance()::_get($key);
- }
-
/**
- * @use 加载配置文件
+ * @use 加载配置
* @param string $load_file
*/
- private static function _load($load_file)
+ public static function load(string $load_file)
{
$config_path = str_replace("\\", "/", APP_CONF_PATH . $load_file);
if (!is_file($config_path)) {
die("配置文件 {$load_file} 加载错误,请参照文档添加配置文件!");
}
- $app_config = Dotenv::createImmutable(dirname($config_path), $load_file);
- $app_config->load();
- self::$app_config = $app_config;
+ // 给静态参数赋值
+ self::$load_file = $load_file;
self::$config_path = $config_path;
+ // $config_path = dirname($config_path).DIRECTORY_SEPARATOR.$load_file;
+ self::$app_config = new IniModifier(self::$config_path);
+ self::$last_time = fileatime(self::$config_path);
}
- /**
- * @use 写入配置
- * @param $key
- * @param $val
- * @return bool
- */
- private static function _put($key, $val)
+ public static function _set($name, $value, $section = 0, $key = null)
{
- if (!is_null($val)) {
- if (!empty(self::$config_path)) {
- file_put_contents(self::$config_path, preg_replace(
- '/^' . $key . '=\S*/m',
- $key . '=' . $val,
- file_get_contents(self::$config_path)
- ));
- }
+ $_instance = self::getInstance();
+ $_instance::$app_config->setValue($name, $value, $section, $key);
+ $_instance::$app_config->save();
+ // 保存修改时间
+ $_instance::$last_time = fileatime($_instance::$config_path);
+ }
+
+ public static function _get($name, $section = 0, $key = null)
+ {
+ $_instance = self::getInstance();
+ // 判断是否被修改 重新加载文件
+ // echo $_instance::$last_time.PHP_EOL;
+ // echo fileatime($_instance::$config_path);
+ if (fileatime($_instance::$config_path) != $_instance::$last_time) {
+ $_instance::load($_instance::$load_file);
}
- putenv($key . '=' . $val);
- // self::$app_config->load();
- return true;
+ return $_instance::$app_config->getValue($name, $section, $key);
+ }
+
+ public static function _put()
+ {
+ $_instance = self::getInstance();
+
+ }
+
+ public static function _del()
+ {
+ $_instance = self::getInstance();
+
}
/**
- * @use 读出配置
- * @param string|null $key
- * @return mixed|null
+ * 不允许从外部调用以防止创建多个实例
+ * 要使用单例,必须通过 Singleton::getInstance() 方法获取实例
*/
- private static function _get($key)
+ private function __construct()
{
- if (self::$app_config->required($key)) {
- return getenv($key);
- }
- return null;
}
+ /**
+ * 防止实例被克隆(这会创建实例的副本)
+ */
+ private function __clone()
+ {
+ }
+
+ /**
+ * 防止反序列化(这将创建它的副本)
+ */
+ public function __wakeup()
+ {
+
+ }
}
\ No newline at end of file
diff --git a/src/core/Curl.php b/src/core/Curl.php
index cd47744..d5edcb0 100644
--- a/src/core/Curl.php
+++ b/src/core/Curl.php
@@ -92,7 +92,7 @@ class Curl
* @param int $timeout
* @return array
*/
- public static function async($os, $url, $tasks = [], $headers = [], $timeout = 30)
+ public static function async($os, $url, $tasks = [], $headers = [], $timeout = 30): array
{
self::$async_opt = [
'tasks' => $tasks,
@@ -155,7 +155,7 @@ class Curl
);
$result = $url ? @file_get_contents($url, false, stream_context_create($options)) : null;
Log::debug($result);
- return $result ? $result : null;
+ return $result ?: null;
}
/**
@@ -167,18 +167,16 @@ class Curl
self::$async_opt['counter']++;
return;
}
- # 请求结束!
+ // 请求结束
self::$async_opt = [];
}
-
/**
* @use 请求中心异常处理
* @param string $url
* @param string $method
* @param array $options
* @return mixed
- * @throws \Exception
*/
private static function clientHandle(string $url, string $method, array $options)
{
@@ -209,17 +207,17 @@ class Curl
* @param float $timeout
* @return array
*/
- private static function getClientOpt(array $add_options, array $headers = [], float $timeout = 30.0)
+ private static function getClientOpt(array $add_options, array $headers = [], float $timeout = 30.0): array
{
self::$client = new \GuzzleHttp\Client();
$default_options = [
'headers' => $headers,
'timeout' => $timeout,
'http_errors' => false,
- 'verify' => getenv('VERIFY_SSL') == 'false' ? false : true,
+ 'verify' => getConf('verify_ssl', 'network.ssl'),
];
- if (getenv('USE_PROXY') == 'true') {
- $default_options['proxy'] = getenv('NETWORK_PROXY');
+ if (getConf('enable', 'network.proxy')) {
+ $default_options['proxy'] = getConf('proxy', 'network.proxy');
}
return array_merge($default_options, $add_options);
}
@@ -245,7 +243,7 @@ class Curl
'Connection' => 'keep-alive',
// 'Content-Type' => 'application/x-www-form-urlencoded',
// 'User-Agent' => 'Mozilla/5.0 BiliDroid/5.51.1 (bbcallen@gmail.com)',
- 'User-Agent' => 'Mozilla/5.0 BiliDroid/6.20.5 (bbcallen@gmail.com) os/android model/MuMu mobi_app/android build/6205500 channel/bili innerVer/6205500 osVer/6.0.1 network/2',
+ 'User-Agent' => 'Mozilla/5.0 BiliDroid/6.32.0 (bbcallen@gmail.com) os/android model/MuMu mobi_app/android build/6320200 channel/bili innerVer/6320200 osVer/7.1.2 network/2',
// 'Referer' => 'https://live.bilibili.com/',
];
$pc_headers = [
@@ -259,37 +257,14 @@ class Curl
$other_headers = [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4450.0 Safari/537.36',
];
- $default_headers = isset(${$os . "_headers"}) ? ${$os . "_headers"} : $other_headers;
- if (in_array($os, ['app', 'pc']) && getenv('COOKIE') != "") {
- $default_headers['Cookie'] = getenv('COOKIE');
+ $default_headers = ${$os . "_headers"} ?? $other_headers;
+ if (in_array($os, ['app', 'pc']) && getCookie() != "") {
+ $default_headers['Cookie'] = getCookie();
}
// return self::formatHeaders(array_merge($default_headers, $headers));
return array_merge($default_headers, $headers);
}
- /**
- * @use 格式化Headers
- * @param $headers
- * @return array
- */
- private static function formatHeaders(array $headers): array
- {
- return array_map(function ($k, $v) {
- return $k . ': ' . $v;
- }, array_keys($headers), $headers);
- }
-
- /**
- * @use 字符串or其他
- * @return array
- */
- private static function getResult()
- {
- $result = self::$result;
- self::$result = [];
- return array_shift($result);
- }
-
/**
* @use 数组
* @return array
@@ -336,4 +311,27 @@ class Curl
Log::debug("获取Headers");
return $request->getHeaders();
}
+
+ /**
+ * @use 格式化Headers
+ * @param array $headers
+ * @return array
+ */
+ private static function formatHeaders(array $headers): array
+ {
+ return array_map(function ($k, $v) {
+ return $k . ': ' . $v;
+ }, array_keys($headers), $headers);
+ }
+
+ /**
+ * @use 字符串or其他
+ * @return array
+ */
+ private static function getResult(): array
+ {
+ $result = self::$result;
+ self::$result = [];
+ return array_shift($result);
+ }
}
diff --git a/src/core/Env.php b/src/core/Env.php
index 6015082..11b1fb5 100644
--- a/src/core/Env.php
+++ b/src/core/Env.php
@@ -10,10 +10,17 @@
namespace BiliHelper\Core;
+use Noodlehaus\Config;
+
class Env
{
- private $app_name = 'BiliHelper Personal';
- private $app_version = '0.8.1.*';
+ private $app_name;
+ private $app_version;
+ private $app_branch;
+ private $app_source;
+
+ private $repository = APP_DATA_PATH . 'latest_version.json';
+
/**
* Env constructor.
@@ -26,6 +33,8 @@ class Env
date_default_timezone_set('Asia/Shanghai');
ini_set('display_errors', 'on');
error_reporting(E_ALL);
+
+ $this->loadJsonData();
}
/**
@@ -38,7 +47,7 @@ class Env
if (!extension_loaded($extension)) {
Log::error("检查到项目依赖 {$extension} 扩展未加载。");
Log::error("请在 php.ini中启用 {$extension} 扩展后重试。");
- Log::error("程序常见问题请移步 https://github.com/lkeme/BiliHelper-personal 文档部分查看。");
+ Log::error("程序常见问题请移步 {$this->app_source} 文档部分查看。");
exit();
}
}
@@ -47,20 +56,32 @@ class Env
/**
* @use 检查环境
*/
- public function inspect_configure()
+ public function inspect_configure(): Env
{
- Log::info("欢迎使用 {$this->app_name} 当前版本 {$this->app_version}");
- Log::info("使用说明请移步 https://github.com/lkeme/BiliHelper-personal 查看。");
+ Log::info("欢迎使用 项目: {$this->app_name}@{$this->app_branch} 版本: {$this->app_version}");
+ Log::info("使用说明请移步 {$this->app_source} 查看");
if (PHP_SAPI != 'cli') {
die("Please run this script from command line .");
}
- if (version_compare(PHP_VERSION, '7.0.0', '<')) {
- die("Please upgrade PHP version > 7.0.0 .");
+ if (version_compare(PHP_VERSION, '7.3.0', '<')) {
+ die("Please upgrade PHP version > 7.3.0 .");
}
// if (version_compare(PHP_VERSION, '8.0.0', '>')) {
// die("Please upgrade PHP version < 8.0.0 .");
// }
return $this;
}
+
+ /**
+ * @use 加载本地JSON DATA
+ */
+ private function loadJsonData()
+ {
+ $conf = new Config($this->repository);
+ $this->app_name = $conf->get('project');
+ $this->app_version = $conf->get('version');
+ $this->app_branch = $conf->get('branch');
+ $this->app_source = $conf->get('source');
+ }
}
diff --git a/src/core/Helpers.php b/src/core/Helpers.php
new file mode 100644
index 0000000..74b12e2
--- /dev/null
+++ b/src/core/Helpers.php
@@ -0,0 +1,117 @@
+ch = curl_init();
+ $this->url = $url;
+ curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false); //忽略 HTTPS 证书错误
+ $this->setUA("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36");
+ }
+
+ function __destruct()
+ {
+ //防止内存泄露
+ curl_close($this->ch);
+ }
+
+ /**
+ * @use 设置UA
+ * @param string $ua
+ * @return $this
+ */
+ public function setUA(string $ua): HttpClient
+ {
+ curl_setopt($this->ch, CURLOPT_USERAGENT, $ua); //设置 UA
+ return $this;
+ }
+
+ /**
+ * @use 添加Header
+ * @param string $header
+ * @return $this
+ */
+ public function addHeader(string $header): HttpClient
+ {
+ array_push($this->headers, $header);
+ return $this;
+ }
+
+ /**
+ * @use 添加Headers
+ * @param array $headers
+ * @return $this
+ */
+ public function addHeaders(array $headers): HttpClient
+ {
+ foreach ($headers as $key => $value) {
+ array_push($this->headers, "{$key}: {$value}");
+ }
+ return $this;
+ }
+
+ /**
+ * @use 设置Cookie
+ * @param string $cookie
+ * @return $this
+ */
+ public function setCookie(string $cookie): HttpClient
+ {
+ curl_setopt($this->ch, CURLOPT_COOKIE, $cookie);
+ return $this;
+ }
+
+ /**
+ * @use 设置 url 参数
+ */
+ public function buildQuery(array $query): HttpClient
+ {
+ $this->query = http_build_query($query);
+ return $this;
+ }
+
+ /**
+ * @use 自动将 json 文本解码
+ */
+ public function asJSON(): object
+ {
+ return json_decode($this->ret);
+ }
+
+ /**
+ * @use 获取返回结果
+ */
+ public function asString(): string
+ {
+ return $this->ret;
+ }
+
+ /**
+ * @use 构造POST表单
+ * @param array $form
+ * @return $this
+ */
+ public function buildPostForm(array $form): HttpClient
+ {
+ $this->form = http_build_query($form);
+
+ return $this;
+ }
+
+ /**
+ * @use 发送 Get 请求
+ */
+ public function get(): HttpClient
+ {
+ curl_setopt($this->ch, CURLOPT_URL, $this->url . "?" . $this->query);
+ curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中
+ curl_setopt($this->ch, CURLOPT_HEADER, $this->headers);
+ $this->ret = curl_exec($this->ch);
+ return $this;
+ }
+
+ /**
+ * @use 发送 POST 请求
+ * @param string|null $data 要 POST 的数据
+ * @return \HttpClient
+ */
+ public function post(string $data = null): HttpClient
+ {
+ curl_setopt($this->ch, CURLOPT_URL, $this->url . "?" . $this->query);
+ curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中
+ curl_setopt($this->ch, CURLOPT_POST, true); // 发送 POST 请求
+ curl_setopt($this->ch, CURLOPT_HEADER, $this->headers);
+ curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
+ $this->ret = curl_exec($this->ch);
+ return $this;
+ }
+
+
+ /**
+ * @use POST表单
+ * @param array $form
+ * @return $this
+ */
+ public function postForm(array $form): HttpClient
+ {
+ return $this->post(http_build_query($form));
+ }
+}
+
diff --git a/src/core/Log.php b/src/core/Log.php
index 10d6a55..5a7c627 100644
--- a/src/core/Log.php
+++ b/src/core/Log.php
@@ -18,6 +18,9 @@ class Log
{
protected static $instance;
+ /**
+ * @use 实体
+ */
static public function getLogger()
{
if (!self::$instance) {
@@ -26,53 +29,79 @@ class Log
return self::$instance;
}
+ /**
+ * @use 单例
+ */
private static function configureInstance()
{
$logger = new Logger('BH');
- $handler = new StreamHandler('php://stdout', getenv('APP_DEBUG') == 'true' ? Logger::DEBUG : Logger::INFO);
+ $handler = new StreamHandler('php://stdout', getConf('enable', 'debug') ? Logger::DEBUG : Logger::INFO);
$handler->setFormatter(new ColoredLineFormatter());
$logger->pushHandler($handler);
self::$instance = $logger;
}
- private static function prefix()
+ /**
+ * @use 前缀
+ * @return string
+ */
+ private static function prefix(): string
{
- if (getenv('APP_MULTIPLE') == 'true') {
- return '[' . (empty($t = getenv('APP_USER_IDENTITY')) ? getenv('APP_USER') : $t) . ']';
+ if (getConf('multiple', 'print')) {
+ return '[' . getConf('user_identity', 'print') ?? getConf('username', 'login.account') . ']';
}
return '';
}
+ /**
+ * @use 写日志
+ * @param $type
+ * @param $message
+ */
private static function writeLog($type, $message)
{
- if (getenv('APP_WRITE_LOG') == 'true') {
- if ($type == 'DEBUG' && getenv("APP_DEBUG") != 'true') {
+ if (getConf('enable', 'log')) {
+ if ($type == 'DEBUG' && !getConf('enable', 'debug')) {
return;
}
- $path = './' . getenv("APP_LOG_PATH") . '/';
+ $path = './' . getConf('path', 'log') . '/';
if (!file_exists($path)) {
mkdir($path);
chmod($path, 0777);
}
- $filename = $path . getenv('APP_USER') . ".log";
+ $filename = $path . getConf('username', 'login.account') . ".log";
$date = date('[Y-m-d H:i:s] ');
$data = $date . ' Log.' . $type . ' ' . $message . PHP_EOL;
file_put_contents($filename, $data, FILE_APPEND);
}
}
+ /**
+ * @use 堆栈
+ * @return string
+ */
private static function backtrace(): string
{
$backtraces = debug_backtrace();
return "(" . pathinfo(basename($backtraces[1]['file']))['filename'] . ") => ";
}
+ /**
+ * @use 调试
+ * @param $message
+ * @param array $context
+ */
public static function debug($message, array $context = [])
{
self::writeLog('DEBUG', $message);
self::getLogger()->addDebug($message, $context);
}
+ /**
+ * @use 信息
+ * @param $message
+ * @param array $context
+ */
public static function info($message, array $context = [])
{
$message = self::prefix() . self::backtrace() . $message;
@@ -81,6 +110,11 @@ class Log
self::callback(Logger::INFO, 'INFO', $message);
}
+ /**
+ * @use 提醒
+ * @param $message
+ * @param array $context
+ */
public static function notice($message, array $context = [])
{
$message = self::prefix() . self::backtrace() . $message;
@@ -89,6 +123,11 @@ class Log
self::callback(Logger::NOTICE, 'NOTICE', $message);
}
+ /**
+ * @use 警告
+ * @param $message
+ * @param array $context
+ */
public static function warning($message, array $context = [])
{
$message = self::prefix() . self::backtrace() . $message;
@@ -97,6 +136,11 @@ class Log
self::callback(Logger::WARNING, 'WARNING', $message);
}
+ /**
+ * @use 错误
+ * @param $message
+ * @param array $context
+ */
public static function error($message, array $context = [])
{
$message = self::prefix() . self::backtrace() . $message;
@@ -105,11 +149,18 @@ class Log
self::callback(Logger::ERROR, 'ERROR', $message);
}
+ /**
+ * @use 回调
+ * @param $levelId
+ * @param $level
+ * @param $message
+ */
public static function callback($levelId, $level, $message)
{
- $callback_level = (('APP_CALLBACK_LEVEL') == '') ? (Logger::ERROR) : intval(getenv('APP_CALLBACK_LEVEL'));
+ // $callback_level = Logger::ERROR ?? getConf('callback_level', 'log');
+ $callback_level = getConf('callback_level', 'log') ?? Logger::ERROR;
if ($levelId >= $callback_level) {
- $url = str_replace('{account}', self::prefix(), getenv('APP_CALLBACK'));
+ $url = str_replace('{account}', self::prefix(), getConf('callback', 'log'));
$url = str_replace('{level}', $level, $url);
$url = str_replace('{message}', urlencode($message), $url);
Curl::request('get', str_replace(' ', '%20', $url));
diff --git a/src/core/Task.php b/src/core/Task.php
new file mode 100644
index 0000000..5f6a4b4
--- /dev/null
+++ b/src/core/Task.php
@@ -0,0 +1,104 @@
+ time() || getenv('USE_ACTIVITY') == 'false') {
+ if (self::getLock() > time() || !getEnable('main_activity')) {
return;
}
self::allotTasks();
@@ -35,7 +41,6 @@ class ActivityLottery
}
}
-
/**
* @use 分配任务
* @return bool
@@ -86,7 +91,7 @@ class ActivityLottery
* @use 执行任务
* @return bool
*/
- private static function workTask()
+ private static function workTask(): bool
{
if (self::$work_status['work_completed'] == date("Y/m/d")) {
return false;
@@ -110,7 +115,10 @@ class ActivityLottery
self::addTimes($task['act']->sid, $task['act']->url, 3);
break;
case 'draw':
- self::doLottery($task['act']->sid, $task['act']->url, 0);
+ // 有抽奖机会才抽奖
+ if (self::initTimes($task['act']->sid, $task['act']->url, false)) {
+ self::doLottery($task['act']->sid, $task['act']->url, 0);
+ }
break;
default:
Log::info("当前 {$task['act']->title} #{$task['operation']} 任务不存在哦");
@@ -119,14 +127,14 @@ class ActivityLottery
return true;
}
-
/**
* @use 获取抽奖机会
* @param string $sid
* @param string $referer
+ * @param bool $init
* @return bool
*/
- private static function initTimes(string $sid, string $referer): bool
+ private static function initTimes(string $sid, string $referer, bool $init = true): bool
{
$url = 'https://api.bilibili.com/x/activity/lottery/mytimes';
$headers = [
@@ -139,12 +147,25 @@ class ActivityLottery
$raw = Curl::get('pc', $url, $payload, $headers);
$de_raw = json_decode($raw, true);
// {"code":0,"message":"0","ttl":1,"data":{"times":2}}
+ // {"code":0,"message":"0","ttl":1,"data":{"times":3}}
+ if ($init) {
+ if ($de_raw['code'] == 0) {
+ Log::notice("剩余抽奖次数 {$de_raw['data']['times']}");
+ return true;
+ }
+ Log::warning("获取抽奖次数失败 {$raw}");
+ return false;
+ }
if ($de_raw['code'] == 0) {
- Log::info("获取抽奖机会成功 {$raw}");
+ Log::notice("剩余抽奖次数 {$de_raw['data']['times']}");
+ if ($de_raw['data']['times'] <= 0) {
+ return false;
+ }
return true;
}
- Log::warning("获取抽奖机会失败 {$raw}");
+ Log::warning("获取抽奖次数失败 {$raw}");
return false;
+
}
/**
@@ -161,17 +182,19 @@ class ActivityLottery
'origin' => 'https://www.bilibili.com',
'referer' => $referer
];
- $user_info = User::parseCookies();
// $action_type 4 关注 3 分享
$payload = [
'sid' => $sid,
'action_type' => $action_type,
- 'csrf' => $user_info['token']
+ 'csrf' => getCsrf()
];
$raw = Curl::post('pc', $url, $payload, $headers);
- $de_raw = json_decode($raw, true);
- Log::info("增加抽奖机会#{$action_type} {$raw}");
+ // {"code":75405,"message":"抽奖机会用尽啦","ttl":1}
+ // {"code":75003,"message":"活动已结束","ttl":1}
// {"code":0,"message":"0","ttl":1}
+ $de_raw = json_decode($raw, true);
+ Log::notice("增加抽奖机会#{$action_type} {$raw}");
+
if ($de_raw['code'] == 0) {
return true;
}
@@ -192,11 +215,10 @@ class ActivityLottery
'origin' => 'https://www.bilibili.com',
'referer' => $referer
];
- $user_info = User::parseCookies();
$payload = [
'sid' => $sid,
'type' => 1,
- 'csrf' => $user_info['token']
+ 'csrf' => getCsrf()
];
$raw = Curl::post('pc', $url, $payload, $headers);
$de_raw = json_decode($raw, true);
diff --git a/src/plugin/AloneTcpClient.php b/src/plugin/AloneTcpClient.php
index a4c6e3d..da3f3c7 100644
--- a/src/plugin/AloneTcpClient.php
+++ b/src/plugin/AloneTcpClient.php
@@ -32,7 +32,7 @@ class AloneTcpClient
*/
public static function run()
{
- if (self::getLock() > time() || getenv('USE_ALONE_SERVER') == 'false') {
+ if (self::getLock() > time() || !getEnable('alone_monitor')) {
return;
}
self::setPauseStatus();
@@ -41,36 +41,33 @@ class AloneTcpClient
self::receive();
}
-
/**
* @use 初始化
*/
private static function init()
{
- if (empty(getenv('ALONE_SERVER_ADDR')) || empty(getenv('ALONE_SERVER_KEY'))) {
+ if (empty(getConf('server_addr', 'alone_monitor')) || empty(getConf('server_key', 'alone_monitor'))) {
exit('推送服务器信息不完整, 请检查配置文件!');
}
if (!self::$server_addr || !self::$server_key) {
- self::$server_addr = getenv('ALONE_SERVER_ADDR');
- self::$server_key = getenv('ALONE_SERVER_KEY');
+ self::$server_addr = getConf('server_addr', 'alone_monitor');
+ self::$server_key = getConf('server_key', 'alone_monitor');
}
if (!self::$client) {
self::openConnect();
}
}
-
/**
* @use 数据封装
* @param $value
* @param $fmt
* @return string
*/
- private static function packMsg($value, $fmt = "N")
+ private static function packMsg($value, $fmt = "N"): string
{
$head = pack($fmt, strlen($value));
- $data = $head . $value;
- return $data;
+ return $head . $value;
}
/**
@@ -117,7 +114,7 @@ class AloneTcpClient
/**
* @use 读数据
* @param $length
- * @return array|bool|false
+ * @return array|bool
*/
private static function reader($length)
{
@@ -142,7 +139,7 @@ class AloneTcpClient
* @param $data
* @return bool
*/
- private static function writer($data)
+ private static function writer($data): bool
{
$status = false;
try {
@@ -157,7 +154,6 @@ class AloneTcpClient
return $status;
}
-
/**
* @use 打开连接
*/
@@ -202,7 +198,6 @@ class AloneTcpClient
self::$client = null;
}
-
/**
* @use 读取数据
*/
@@ -216,8 +211,8 @@ class AloneTcpClient
Log::debug("(len=$len_body)");
$body = self::reader($len_body);
$raw_data = json_decode($body, true);
- // 人气值(或者在线人数或者类似)以及心跳
- $data_type = $raw_data['type'];
+ // 数据可能出现不全 DECODE返回NULL 索引错误 交给default处理
+ $data_type = is_null($raw_data) ? "unknown" : $raw_data['type'];
switch ($data_type) {
case 'raffle':
// 抽奖推送
@@ -260,16 +255,16 @@ class AloneTcpClient
// 服务器发布命令
Log::error("服务器发布退出命令 {$raw_data['data']['msg']}");
exit();
- break;
default:
// 未知信息
var_dump($raw_data);
Log::info("出现未知信息 {$body}");
+ // 出现未知信息 处理重连 防止内存益处
+ self::reConnect();
break;
}
}
-
/**
* @use 写入log
* @param $message
@@ -281,7 +276,7 @@ class AloneTcpClient
mkdir($path);
chmod($path, 0777);
}
- $filename = $path . getenv('APP_USER') . ".log";
+ $filename = $path . getConf('username', 'login.account') . ".log";
$date = date('[Y-m-d H:i:s] ');
$data = "[{$date}]{$message}" . PHP_EOL;
file_put_contents($filename, $data, FILE_APPEND);
diff --git a/src/plugin/AnchorRaffle.php b/src/plugin/AnchorRaffle.php
index 5d44579..85ef140 100644
--- a/src/plugin/AnchorRaffle.php
+++ b/src/plugin/AnchorRaffle.php
@@ -12,13 +12,12 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log;
use BiliHelper\Core\Curl;
-use BiliHelper\Util\TimeLock;
use BiliHelper\Util\BaseRaffle;
class AnchorRaffle extends BaseRaffle
{
const ACTIVE_TITLE = '天选时刻';
- const ACTIVE_SWITCH = 'USE_ANCHOR';
+ const ACTIVE_SWITCH = 'live_anchor';
protected static $wait_list = [];
protected static $finish_list = [];
@@ -62,10 +61,10 @@ class AnchorRaffle extends BaseRaffle
$tags = User::fetchTags();
$tag_id = array_search(self::$group_name, $tags);
// 如果不存在则调用创建
- self::$group_id = $tag_id ? $tag_id : User::createRelationTag(self::$group_name);
+ self::$group_id = $tag_id ?: User::createRelationTag(self::$group_name);
}
// 获取需要关注的
- $data = Live::getRoomInfo($room_id);
+ $data = Live::getRoomInfoV1($room_id);
if ($data['code'] == 0 && isset($data['data'])) {
$need_follow_uid = $data['data']['uid'];
} else {
@@ -102,7 +101,6 @@ class AnchorRaffle extends BaseRaffle
self::$wait_un_follows = $new_list;
}
-
/**
* @use 获取默认关注
* @return array
@@ -120,7 +118,6 @@ class AnchorRaffle extends BaseRaffle
return self::$default_follows;
}
-
/**
* @use 过滤奖品
* @param string $prize_name
@@ -129,7 +126,7 @@ class AnchorRaffle extends BaseRaffle
protected static function filterPrizeWords(string $prize_name): bool
{
$default_words = self::$store->get("Anchor.default");
- $custom_words = empty(getenv('ANCHOR_FILTER_WORDS')) ? [] : explode(',', getenv('ANCHOR_FILTER_WORDS'));
+ $custom_words = empty($words = getConf('filter_words', 'live_anchor')) ? [] : explode(',', $words);
$total_words = array_merge($default_words, $custom_words);
foreach ($total_words as $word) {
if (strpos($prize_name, $word) !== false) {
@@ -160,7 +157,7 @@ class AnchorRaffle extends BaseRaffle
return false;
}
// 过滤抽奖范围
- self::$filter_type = empty(self::$filter_type) ? explode(',', getenv('ANCHOR_TYPE')) : self::$filter_type;
+ self::$filter_type = empty(self::$filter_type) ? explode(',', getConf('limit_type', 'live_anchor')) : self::$filter_type;
if (!in_array((string)$de_raw['require_type'], self::$filter_type)) {
return false;
}
@@ -173,7 +170,7 @@ class AnchorRaffle extends BaseRaffle
return false;
}
// 分组操作
- if (getenv('ANCHOR_UNFOLLOW') == 'true' && $de_raw['require_text'] == '关注主播') {
+ if (getConf('auto_unfollow', 'live_anchor') && $de_raw['require_text'] == '关注主播') {
self::addToGroup($room_id, $de_raw['id'], time() + $de_raw['time'] + 5);
}
// 推入列表
@@ -189,7 +186,6 @@ class AnchorRaffle extends BaseRaffle
return true;
}
-
/**
* @use 创建抽奖任务
* @param array $raffles
@@ -199,15 +195,13 @@ class AnchorRaffle extends BaseRaffle
{
$url = 'https://api.live.bilibili.com/xlive/lottery-interface/v1/Anchor/Join';
$tasks = [];
- $results = [];
- $user_info = User::parseCookies();
foreach ($raffles as $raffle) {
$payload = [
'id' => $raffle['raffle_id'],
'roomid' => $raffle['room_id'],
'platform' => 'pc',
- 'csrf_token' => $user_info['token'],
- 'csrf' => $user_info['token'],
+ 'csrf_token' => getCsrf(),
+ 'csrf' => getCsrf(),
'visit_id' => ''
];
array_push($tasks, [
@@ -219,15 +213,14 @@ class AnchorRaffle extends BaseRaffle
]
]);
}
- $results = Curl::async('app', $url, $tasks);
// print_r($results);
- return $results;
+ return Curl::async('app', $url, $tasks);
}
/**
* @use 解析抽奖信息
* @param array $results
- * @return mixed|void
+ * @return void
*/
protected static function parseLottery(array $results)
{
diff --git a/src/plugin/AwardRecord.php b/src/plugin/AwardRecord.php
index 3a30903..cd775eb 100644
--- a/src/plugin/AwardRecord.php
+++ b/src/plugin/AwardRecord.php
@@ -25,10 +25,9 @@ class AwardRecord
private static $gift_lock = 0;
private static $gift_list = [];
-
public static function run()
{
- if (self::getLock() > time()) {
+ if (self::getLock() > time() || !getEnable('award_record')) {
return;
}
if (self::$anchor_lock < time()) {
@@ -43,7 +42,6 @@ class AwardRecord
self::setLock(5 * 60);
}
-
/**
* @use 获取天选时刻中奖纪录
*/
@@ -83,7 +81,7 @@ class AwardRecord
}
if (in_array($wait_un_follow['anchor_id'], self::$anchor_list)) {
AnchorRaffle::delToGroup($wait_un_follow['uid'], $wait_un_follow['anchor_id'], false);
- }else{
+ } else {
AnchorRaffle::delToGroup($wait_un_follow['uid'], $wait_un_follow['anchor_id'], true);
}
}
@@ -91,7 +89,6 @@ class AwardRecord
self::$anchor_lock = time() + 6 * 60 * 60;
}
-
/**
* @use 获取实物抽奖中奖纪录
*/
@@ -129,7 +126,6 @@ class AwardRecord
self::$raffle_lock = time() + 6 * 60 * 60;
}
-
/**
* @use 获取活动礼物中奖纪录
*/
diff --git a/src/plugin/Barrage.php b/src/plugin/Barrage.php
index dd8d674..fb777ec 100644
--- a/src/plugin/Barrage.php
+++ b/src/plugin/Barrage.php
@@ -20,69 +20,41 @@ class Barrage
public static function run()
{
- if (self::getLock() > time() || getenv('USE_DANMU') == 'false') {
+ if (self::getLock() > time() || !getEnable('barrage')) {
return;
}
self::setPauseStatus();
- $room_id = empty(getenv('DANMU_ROOMID')) ? Live::getUserRecommend() : Live::getRealRoomID(getenv('DANMU_ROOMID'));
- $msg = empty(getenv('DANMU_CONTENT')) ? self::getMsgInfo() : getenv('DANMU_CONTENT');
-
- $info = [
- 'roomid' => $room_id,
- 'content' => $msg,
- ];
-
- if (self::privateSendMsg($info)) {
- self::setLock(mt_rand(40, 60) * 60);
+ if (self::sendMsg()) {
+ self::setLock(mt_rand(40, 80) * 60);
return;
}
-
- self::setLock(30);
+ self::setLock(15 * 60);
}
/**
- * @use 获取颜文字信息
+ * 获取一言api消息
+ * @param bool $sep
* @return string
*/
- private static function getEmojiMsg(): string
- {
- $emoji_list = [
- "(⌒▽⌒)", "( ̄▽ ̄)", "(=・ω・=)", "(`・ω・´)", "(〜 ̄△ ̄)〜", "(・∀・)",
- "(°∀°)ノ", "( ̄3 ̄)", "╮( ̄▽ ̄)╭", "_(:3」∠)_", "( ´_ゝ`)", "←_←", "→_→",
- "(<_<)", "(>_>)", "(;¬_¬)", '("▔□▔)/', "(゚Д゚≡゚д゚)!?", "Σ(゚д゚;)", "Σ(  ̄□ ̄||)",
- "(´;ω;`)", "(/TДT)/", "(^・ω・^ )", "(。・ω・。)", "(● ̄(エ) ̄●)", "ε=ε=(ノ≧∇≦)ノ",
- "(´・_・`)", "(-_-#)", "( ̄へ ̄)", "( ̄ε(# ̄) Σ", "ヽ(`Д´)ノ", "(#-_-)┯━┯",
- "(╯°口°)╯(┴—┴", "←◡←", "( ♥д♥)", "Σ>―(〃°ω°〃)♡→", "⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
- "(╬゚д゚)▄︻┻┳═一", "・*・:≡( ε:)", "(打卡)", "(签到)"
- ];
- shuffle($emoji_list);
- return $emoji_list[array_rand($emoji_list)];
- }
-
-
- /**
- * @use 获取一言api消息
- * @return string
- */
- private static function getMsgInfo():string
+ private static function getMsgInfo(bool $sep = true): string
{
/**
* 整理一部分API,收集于网络,侵权麻烦联系我删除.
* 如果设置项不能用可以选择,只保证代码发布时正常.
* 格式全部为TEXT,可以自己替换.
*/
- $punctuations = [',', ',', '。', '!', '.', ';', '——'];
+ $punctuations = $sep ? [',', ',', '。', '!', '.', ';', '——'] : [];
$apis = [
- 'https://api.ly522.com/yan.php?format=text',
'https://v1.hitokoto.cn/?encode=text',
+ 'https://api.ly522.com/Api/YiYan?format=text',
'https://api.jysafe.cn/yy/',
'https://api.imjad.cn/hitokoto/',
'https://www.ly522.com/hitokoto/',
'https://api.guoch.xyz/',
'https://api.gushi.ci/rensheng.txt',
'https://api.itswincer.com/hitokoto/v2/',
-// 'http://www.ooomg.cn/dutang/',
-// 'http://api.dsecret.com/yiyan/',
+ // 'http://www.ooomg.cn/dutang/',
+ // 'http://api.dsecret.com/yiyan/',
];
shuffle($apis);
try {
@@ -102,45 +74,24 @@ class Barrage
}
}
-
/**
- * @use 弹幕通用模块
- * @param $info
- * @return array
- */
- private static function sendMsg($info): array
- {
- $user_info = User::parseCookies();
- $url = 'https://api.live.bilibili.com/msg/send';
- $data = Live::getRoomInfo($info['roomid']);
- $payload = [
- 'color' => '16777215',
- 'fontsize' => 25,
- 'mode' => 1,
- 'msg' => $info['content'],
- 'rnd' => 0,
- 'roomid' => $data['data']['room_id'],
- 'csrf' => $user_info['token'],
- 'csrf_token' => $user_info['token'],
- ];
- $raw = Curl::post('app', $url, Sign::common($payload));
- return json_decode($raw, true) ?? ['code' => 404, 'msg' => '上层数据为空!'];
- }
-
- /**
- * @use 发送弹幕模块
- * @param $info
+ * @use 活跃弹幕
* @return bool
*/
- private static function privateSendMsg($info): bool
+ private static function sendMsg(): bool
{
- //TODO 短期功能 有需求就修改
- $response = self::sendMsg($info);
- if (isset($response['code']) && $response['code'] == 0) {
- Log::info('弹幕发送成功');
+ $room_id = empty($room_id = getConf('room_id', 'barrage')) ? Live::getUserRecommend() : Live::getRealRoomID($room_id);
+ $content = empty($msg = getConf('content', 'barrage')) ? self::getMsgInfo() : $msg;
+
+ $response = Live::sendBarragePC($room_id, $content);
+ // {"code":0,"data":[],"message":"","msg":""}
+ // {"code":0,"message":"你被禁言啦","msg":"你被禁言啦"}
+ // Todo 长度限制
+ if (isset($response['code']) && $response['code'] == 0 && isset($response['data'])) {
+ Log::notice("在直播间@{$room_id} 发送活跃弹幕成功 CODE -> {$response['code']}");
return true;
} else {
- Log::warning("弹幕发送失败, CODE -> {$response['code']} MSG -> {$response['msg']} ");
+ Log::warning("在直播间@{$room_id} 发送活跃弹幕失败 CODE -> {$response['code']} MSG -> {$response['message']} ");
return false;
}
}
diff --git a/src/plugin/BpConsumption.php b/src/plugin/BpConsumption.php
new file mode 100644
index 0000000..ca34fd3
--- /dev/null
+++ b/src/plugin/BpConsumption.php
@@ -0,0 +1,148 @@
+ time() || !getEnable('bp_consumption')) {
+ return;
+ }
+ // 定时14点 + 随机120分钟| 根据逻辑前置
+ self::setLock(self::timing(14) + mt_rand(1, 120) * 60);
+
+ // 如果为年度大会员
+ if (User::isYearVip()) {
+ // 获取B币余额
+ $bp_balance = self::getUserWallet();
+ // 最大支持5
+ if ($bp_balance != 5) return;
+ // 消费B币充电
+ if (getConf('bp2charge', 'bp_consumption')) {
+ // UID为空就切换成自己的
+ $uid = empty($uid = getConf('bp2charge_uid', 'bp_consumption')) ? getUid() : $uid;
+ self::BP2charge($uid, $bp_balance);
+ return;
+ }
+ // 消费B币充值金瓜子
+ if (getConf('bp2gold', 'bp_consumption')) {
+ self::BP2gold($bp_balance);
+ return;
+ }
+ }
+ }
+
+ /**
+ * @use 获取钱包B币券余额
+ * @return int
+ */
+ private static function getUserWallet(): int
+ {
+ $url = 'https://pay.bilibili.com/paywallet/wallet/getUserWallet';
+ $headers = [
+ 'Content-Type' => 'application/json;charset=utf-8',
+ 'origin' => 'https://pay.bilibili.com',
+ 'referer' => 'https://pay.bilibili.com/paywallet-fe/bb_balance.html'
+ ];
+ $ts = Common::getMillisecond();
+ $payload = [
+ 'panelType' => 3,
+ 'platformType' => 3,
+ 'timestamp' => $ts,
+ 'traceId' => $ts,
+ 'version' => "1.0",
+ ];
+ $raw = Curl::put('pc', $url, $payload, $headers);
+ // {"errno":0,"msg":"SUCCESS","showMsg":"","errtag":0,"data":{"mid":1234,"totalBp":5.00,"defaultBp":0.00,"iosBp":0.00,"couponBalance":5.00,"availableBp":5.00,"unavailableBp":0.00,"unavailableReason":"苹果设备上充值的B币不能在其他平台的设备上进行使用","tip":null}}
+ $de_raw = json_decode($raw, true);
+ if ($de_raw['errno'] == 0 && isset($de_raw['data']['couponBalance'])) {
+ Log::notice('获取钱包成功 B币券余额剩余' . $de_raw['data']['couponBalance']);
+ return intval($de_raw['data']['couponBalance']);
+ } else {
+ Log::warning("获取钱包失败 {$raw}");
+ return 0;
+ }
+ }
+
+ /**
+ * @use B币充电
+ * @param int $uid
+ * @param int $num
+ */
+ private static function BP2charge(int $uid, int $num = 5)
+ {
+ $url = 'https://api.bilibili.com/x/ugcpay/web/v2/trade/elec/pay/quick';
+ $payload = [
+ 'bp_num' => $num, // 数量
+ 'is_bp_remains_prior' => true, // 是否优先扣除B币余额
+ 'up_mid' => $uid, // 目标UID
+ 'otype' => 'up', // 来源 up:空间充电 archive:视频充电
+ 'oid' => $uid, // 目标UID or 稿件avid
+ 'csrf' => getCsrf()
+ ];
+ $raw = Curl::post('pc', $url, $payload);
+ // {"code":0,"message":"0","ttl":1,"data":{"mid":12324,"up_mid":1234,"order_no":"ABCD","bp_num":2,"exp":2,"status":4,"msg":""}}
+ $de_raw = json_decode($raw, true);
+ if ($de_raw['code'] == 0) {
+ // data.status 4 成功 -2:低于20电池下限 -4:B币不足
+ if ($de_raw['data']['status'] == 4) {
+ Log::notice("给{$uid}B币充电成功 NUM -> {$de_raw['data']['elec_num']} ORDER -> {$de_raw['data']['order_no']}");
+ } else {
+ Log::warning("给{$uid}B币充电失败 STATUS -> {$de_raw['data']['status']} MSG -> {$de_raw['data']['msg']}");
+ }
+ } else {
+ Log::warning("给{$uid}B币充电失败 CODE -> {$de_raw['code']} MSG -> {$de_raw['message']} ");
+ }
+ }
+
+ /**
+ * B币充值金瓜子
+ * @param int $num
+ */
+ private static function BP2gold(int $num)
+ {
+ $url = 'https://api.live.bilibili.com/xlive/revenue/v1/order/createOrder';
+ $headers = [
+ 'origin' => 'https://link.bilibili.com',
+ 'referer' => 'https://link.bilibili.com/p/center/index'
+ ];
+ $payload = [
+ 'platform' => 'pc',
+ 'pay_bp' => $num * 1000, // 瓜子数量
+ 'context_id' => 1, // 直播间
+ 'context_type' => 11,
+ 'goods_id' => 1, // 商品ID
+ 'goods_num' => $num, // B币数量
+ 'csrf_token' => getCsrf(),
+ 'csrf' => getCsrf(),
+ 'visit_id' => '',
+ ];
+ $raw = Curl::post('pc', $url, $payload, $headers);
+ // {"code":1300014,"message":"b币余额不足","ttl":1,"data":null}
+ // {"code":0,"message":"0","ttl":1,"data":{"status":2,"order_id":"1234171134577071132741234","gold":0,"bp":5000}}
+ $de_raw = json_decode($raw, true);
+ if ($de_raw['code'] == 0) {
+ Log::notice("B币充值金瓜子成功 NUM -> {$de_raw['data']['bp']} ORDER -> {$de_raw['data']['order_id']}");
+ } else {
+ Log::warning("B币充值金瓜子失败 CODE -> {$de_raw['code']} MSG -> {$de_raw['message']}");
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/plugin/CapsuleLottery.php b/src/plugin/CapsuleLottery.php
index fac5266..fe65cb4 100644
--- a/src/plugin/CapsuleLottery.php
+++ b/src/plugin/CapsuleLottery.php
@@ -13,6 +13,7 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log;
use BiliHelper\Core\Curl;
+use BiliHelper\Tool\Common;
use BiliHelper\Util\AllotTasks;
use BiliHelper\Util\TimeLock;
use BiliHelper\Util\XliveHeartBeat;
@@ -35,7 +36,7 @@ class CapsuleLottery
*/
public static function run()
{
- if (self::getLock() > time() || getenv('USE_CAPSULE') == 'false') {
+ if (self::getLock() > time() || !getEnable('live_capsule')) {
return;
}
self::allotTasks();
@@ -46,7 +47,6 @@ class CapsuleLottery
}
}
-
/**
* @use 分配任务
* @return bool
@@ -87,7 +87,6 @@ class CapsuleLottery
return true;
}
-
/**
* @use 执行任务
* @return bool
@@ -109,12 +108,16 @@ class CapsuleLottery
Log::info("执行 {$task['act']->title} #{$task['operation']} 任务");
// 执行任务
switch ($task['operation']) {
+ // Todo 观看 分享 签到任务
case 'watch':
- $interval = self::xliveHeartBeatTask($task['act']->room_id,999,999);
+ $interval = self::xliveHeartBeatTask($task['act']->room_id, 999, 999);
self::$interval = $interval == 0 ? 60 : $interval;
break;
case 'draw':
- self::doLottery($task['act']->coin_id, $task['act']->url, 0);
+ // 抽奖次数 > 0 开始抽奖
+ if (self::getLuckyNum($task['act']->coin_id, $task['act']->url)) {
+ self::doLottery($task['act']->coin_id, $task['act']->url, 0);
+ }
break;
default:
Log::info("当前 {$task['act']->title} #{$task['operation']} 任务不存在哦");
@@ -137,15 +140,14 @@ class CapsuleLottery
'origin' => 'https://live.bilibili.com',
'referer' => $referer
];
- $user_info = User::parseCookies();
$payload = [
'id' => $coin_id,
'count' => 1,
'type' => 1,
'platform' => 'web',
'_' => time() * 1000,
- 'csrf' => $user_info['token'],
- 'csrf_token' => $user_info['token'],
+ 'csrf' => getCsrf(),
+ 'csrf_token' => getCsrf(),
'visit_id' => ''
];
$raw = Curl::post('pc', $url, $payload, $headers);
@@ -161,4 +163,140 @@ class CapsuleLottery
}
+ /**
+ * @use 分享任务
+ * @param int $act_id
+ * @param string $referer
+ */
+ private static function taskShare(int $act_id, string $referer)
+ {
+ $url = 'https://api.live.bilibili.com/xlive/activity-interface/v1/task/UserShare';
+ $headers = [
+ 'origin' => 'https://live.bilibili.com',
+ 'referer' => 'https://live.bilibili.com/'
+ ];
+ $payload = [
+ 'act_id' => $act_id,
+ 'share_type' => 1,
+ 'csrf_token' => getCsrf(),
+ 'csrf' => getCsrf(),
+ 'visit_id' => '',
+ ];
+ $raw = Curl::post('pc', $url, $payload, $headers);
+ // {"code":0,"message":"0","ttl":1,"data":{"status":1}}
+ $de_raw = json_decode($raw, true);
+ }
+
+ /**
+ * @use 获取扭蛋池子信息
+ * @param int $pool_id
+ * @param string $referer
+ */
+ private static function getPoolDetail(int $pool_id, string $referer)
+ {
+ $url = 'https://api.live.bilibili.com/xlive/web-ucenter/v1/capsule/get_pool_detail';
+ $headers = [
+ 'origin' => 'https://live.bilibili.com',
+ 'referer' => $referer
+ ];
+ $payload = [
+ 'pool_id' => $pool_id,
+ '_' => Common::getMillisecond()
+ ];
+ $raw = Curl::get('pc', $url, $payload);
+ // {"code":0,"message":"0","ttl":1,"data":{"id":145,"coin":3,"coin_id":131,"title":"OWL2021","open_num_1":1,"open_num_2":10,"open_num_3":100,"status":0,"gift_list":[{"id":1237,"name":"谢谢参与","num":1,"web_url":"https://i0.hdslb.com/bfs/live/b0fccfb3bac2daae35d7e514a8f6d31530b9add2.png","mobile_url":"https://i0.hdslb.com/bfs/live/b0fccfb3bac2daae35d7e514a8f6d31530b9add2.png","usage":{"text":"谢谢参与","url":""},"type":32,"expire":"当天","gift_type":"7290bc172e5ab9e151eb141749adb9dd"},{"id":1238,"name":"杭州闪电队主场队服","num":1,"web_url":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","mobile_url":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","usage":{"text":"新款杭州闪电队队服","url":""},"type":100024,"expire":"当天","gift_type":"895ff9e63081033072a1bc5694d10095"},{"id":1239,"name":"上海龙之队主场队服","num":1,"web_url":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","mobile_url":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","usage":{"text":"新款上海龙之队队服","url":""},"type":100024,"expire":"当天","gift_type":"a314efd84276f0be571492823b1c0edb"},{"id":1240,"name":"广州冲锋队主场队服","num":1,"web_url":"https://i0.hdslb.com/bfs/live/cdc33523a1b018ee6af447f528c56848f5556eb8.png","mobile_url":"https://i0.hdslb.com/bfs/live/cdc33523a1b018ee6af447f528c56848f5556eb8.png","usage":{"text":"新款广州冲锋队队服","url":""},"type":100024,"expire":"当天","gift_type":"6d46360bc93b8b07b4c64efb9350579a"},{"id":1241,"name":"谢谢参与","num":1,"web_url":"https://i0.hdslb.com/bfs/live/b0fccfb3bac2daae35d7e514a8f6d31530b9add2.png","mobile_url":"https://i0.hdslb.com/bfs/live/b0fccfb3bac2daae35d7e514a8f6d31530b9add2.png","usage":{"text":"谢谢参与","url":""},"type":32,"expire":"当天","gift_type":"7290bc172e5ab9e151eb141749adb9dd"},{"id":1242,"name":"成都猎人队主场队服","num":1,"web_url":"https://i0.hdslb.com/bfs/live/625c55aa7a020040466cc7a842ea0c57ac4f484c.png","mobile_url":"https://i0.hdslb.com/bfs/live/625c55aa7a020040466cc7a842ea0c57ac4f484c.png","usage":{"text":"新款成都猎人队队服","url":""},"type":100024,"expire":"当天","gift_type":"51ecabc603848979410202a93391cd35"},{"id":1243,"name":"随机战队客场队服","num":1,"web_url":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","mobile_url":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","usage":{"text":"随机一件OWL战队客场队服","url":""},"type":100024,"expire":"当天","gift_type":"b2ec92156e57708caf923b1c18309fea"},{"id":1244,"name":"哔哩哔哩月度大会员","num":1,"web_url":"https://i0.hdslb.com/bfs/live/49b6d12eadc81acf68d5378b257df78ec38b4355.png","mobile_url":"https://i0.hdslb.com/bfs/live/49b6d12eadc81acf68d5378b257df78ec38b4355.png","usage":{"text":"bilibili月度大会员","url":""},"type":100024,"expire":"当天","gift_type":"78db25f308b8b8db86ba1a172c2deb35"}],"is_login":true,"list":[{"num":1,"gift":"哔哩哔哩月度大会员","date":"2021-05-10","name":"初夏的戏匣子","web_image":"https://i0.hdslb.com/bfs/live/49b6d12eadc81acf68d5378b257df78ec38b4355.png","mobile_image":"https://i0.hdslb.com/bfs/live/49b6d12eadc81acf68d5378b257df78ec38b4355.png","count":1},{"num":1,"gift":"杭州闪电队主场队服","date":"2021-05-10","name":"hentaiDIAO","web_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","mobile_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","count":1},{"num":1,"gift":"随机战队客场队服","date":"2021-05-10","name":"哗哗はな","web_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","mobile_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","count":10},{"num":1,"gift":"杭州闪电队主场队服","date":"2021-05-10","name":"Promissio小约定","web_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","mobile_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","count":1},{"num":1,"gift":"上海龙之队主场队服","date":"2021-05-10","name":"小新笔记","web_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","mobile_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","count":10},{"num":1,"gift":"广州冲锋队主场队服","date":"2021-05-10","name":"晚来天欲雪yyy","web_image":"https://i0.hdslb.com/bfs/live/cdc33523a1b018ee6af447f528c56848f5556eb8.png","mobile_image":"https://i0.hdslb.com/bfs/live/cdc33523a1b018ee6af447f528c56848f5556eb8.png","count":1},{"num":1,"gift":"成都猎人队主场队服","date":"2021-05-10","name":"Histo2y","web_image":"https://i0.hdslb.com/bfs/live/625c55aa7a020040466cc7a842ea0c57ac4f484c.png","mobile_image":"https://i0.hdslb.com/bfs/live/625c55aa7a020040466cc7a842ea0c57ac4f484c.png","count":1},{"num":1,"gift":"随机战队客场队服","date":"2021-05-10","name":"蜀黍我最怕亏钱啦","web_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","mobile_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","count":1},{"num":1,"gift":"上海龙之队主场队服","date":"2021-05-10","name":"国王大道修车师傅","web_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","mobile_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","count":10},{"num":1,"gift":"杭州闪电队主场队服","date":"2021-05-10","name":"丁马的早晨","web_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","mobile_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","count":10},{"num":1,"gift":"随机战队客场队服","date":"2021-05-10","name":"丁马的早晨","web_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","mobile_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","count":10},{"num":1,"gift":"上海龙之队主场队服","date":"2021-05-10","name":"-St-John","web_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","mobile_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","count":10},{"num":1,"gift":"哔哩哔哩月度大会员","date":"2021-05-03","name":"那个臭打游戏的","web_image":"https://i0.hdslb.com/bfs/live/49b6d12eadc81acf68d5378b257df78ec38b4355.png","mobile_image":"https://i0.hdslb.com/bfs/live/49b6d12eadc81acf68d5378b257df78ec38b4355.png","count":1},{"num":1,"gift":"成都猎人队主场队服","date":"2021-05-03","name":"金小伍","web_image":"https://i0.hdslb.com/bfs/live/625c55aa7a020040466cc7a842ea0c57ac4f484c.png","mobile_image":"https://i0.hdslb.com/bfs/live/625c55aa7a020040466cc7a842ea0c57ac4f484c.png","count":1},{"num":1,"gift":"广州冲锋队主场队服","date":"2021-05-03","name":"不灵梦Blame","web_image":"https://i0.hdslb.com/bfs/live/cdc33523a1b018ee6af447f528c56848f5556eb8.png","mobile_image":"https://i0.hdslb.com/bfs/live/cdc33523a1b018ee6af447f528c56848f5556eb8.png","count":1},{"num":1,"gift":"随机战队客场队服","date":"2021-05-03","name":"幻化叶之韵","web_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","mobile_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","count":10},{"num":1,"gift":"上海龙之队主场队服","date":"2021-05-03","name":"-莉娅菠萝-","web_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","mobile_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","count":10},{"num":1,"gift":"杭州闪电队主场队服","date":"2021-05-03","name":"康斯坦丁Constantine.","web_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","mobile_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","count":1},{"num":1,"gift":"随机战队客场队服","date":"2021-05-03","name":"夜魅三清","web_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","mobile_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","count":1},{"num":1,"gift":"上海龙之队主场队服","date":"2021-05-03","name":"夜魅三清","web_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","mobile_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","count":1},{"num":1,"gift":"随机战队客场队服","date":"2021-05-03","name":"蓝岚染","web_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","mobile_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","count":10},{"num":1,"gift":"杭州闪电队主场队服","date":"2021-05-03","name":"用了五级经验卡","web_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","mobile_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","count":1},{"num":1,"gift":"上海龙之队主场队服","date":"2021-05-03","name":"蜀黍我最怕亏钱啦","web_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","mobile_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","count":10},{"num":1,"gift":"杭州闪电队主场队服","date":"2021-05-03","name":"aii01992","web_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","mobile_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","count":10},{"num":1,"gift":"哔哩哔哩月度大会员","date":"2021-04-26","name":"妄想逃离现实的星轨君","web_image":"https://i0.hdslb.com/bfs/live/49b6d12eadc81acf68d5378b257df78ec38b4355.png","mobile_image":"https://i0.hdslb.com/bfs/live/49b6d12eadc81acf68d5378b257df78ec38b4355.png","count":1},{"num":1,"gift":"杭州闪电队主场队服","date":"2021-04-26","name":"乌鲁乌鲁崽","web_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","mobile_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","count":1},{"num":1,"gift":"上海龙之队主场队服","date":"2021-04-26","name":"思维回廊","web_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","mobile_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","count":1},{"num":1,"gift":"随机战队客场队服","date":"2021-04-26","name":"思维回廊","web_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","mobile_image":"https://i0.hdslb.com/bfs/live/2198f9659645d28a7fc20c15e93f050a30706016.png","count":1},{"num":1,"gift":"上海龙之队主场队服","date":"2021-04-26","name":"LilPank","web_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","mobile_image":"https://i0.hdslb.com/bfs/live/1e53fc5f1f13c1e2e30eaa7504bc0d939e77df42.png","count":10},{"num":1,"gift":"杭州闪电队主场队服","date":"2021-04-26","name":"一日学滴滴","web_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","mobile_image":"https://i0.hdslb.com/bfs/live/e7cc2043c85c43f8bdd338a693eef3fe3fc18757.png","count":10}]}}
+ $de_raw = json_decode($raw, true);
+ }
+
+ /**
+ * @use 获取扭蛋信息
+ * @param int $coin_id
+ * @param string $referer
+ * @return array
+ */
+ private static function getCapsuleInfo(int $coin_id, string $referer): array
+ {
+ $url = 'https://api.live.bilibili.com/xlive/web-ucenter/v1/capsule/get_capsule_info_v3';
+ $headers = [
+ 'origin' => 'https://live.bilibili.com',
+ 'referer' => $referer
+ ];
+ $payload = [
+ 'id' => $coin_id,
+ 'from' => 'web',
+ '-' => Common::getMillisecond()
+ ];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ // data -> status 0||2
+ // {"code":0,"message":"0","ttl":1,"data":{"coin":9,"rule":"2020年英雄联盟职业联赛春季赛抽奖奖池","gift_list":[{"name":"辣条","num":1,"web_url":"https://i0.hdslb.com/bfs/live/48605b0fe9eca5aba87f93da0fa0aa361c419835.png","mobile_url":"https://i0.hdslb.com/bfs/live/8e7a4dc8de374faee22fca7f9a3f801a1712a36b.png","usage":{"text":"辣条是一种直播虚拟礼物,可以在直播间送给自己喜爱的主播哦~","url":""},"type":1,"expire":"3天","gift_type":"325a347f91903c0353385e343dd358f0"},{"name":"3天头衔续期卡","num":1,"web_url":"https://i0.hdslb.com/bfs/live/48aecec2d7243b6f8bd17f20ff715db89f9adcec.png","mobile_url":"https://i0.hdslb.com/bfs/live/48aecec2d7243b6f8bd17f20ff715db89f9adcec.png","usage":{"text":"3天头衔续期卡*1","url":""},"type":21,"expire":"1周","gift_type":"4bda2f960342d86a426ebc067d3633ed"},{"name":"LPL2020助威","num":1,"web_url":"https://i0.hdslb.com/bfs/live/d9ee9558fcc438c99deb00ed1f6bd3707bac3452.png","mobile_url":"https://i0.hdslb.com/bfs/live/d9ee9558fcc438c99deb00ed1f6bd3707bac3452.png","usage":{"text":"2020LPL限定头衔","url":""},"type":2,"expire":"1周","gift_type":"b114c47920fce2aca5fca7a27cca5915"},{"name":"随机英雄联盟角色手办","num":1,"web_url":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_url":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","usage":{"text":"随机英雄联盟角色手办*1","url":""},"type":100024,"expire":"当天","gift_type":"6a4ae5853753d67d07cea2b1750795f4"},{"name":"2020LPL彩色弹幕","num":1,"web_url":"https://i0.hdslb.com/bfs/live/9a571f9d82c2a8cbbe869fd92796e70b19f9c2cc.png","mobile_url":"https://i0.hdslb.com/bfs/live/9a571f9d82c2a8cbbe869fd92796e70b19f9c2cc.png","usage":{"text":"LPL专属彩色弹幕","url":""},"type":20,"expire":"3天","gift_type":"14e40c6949800b5d840011e47e54d0c5"},{"name":"7天头衔续期卡","num":1,"web_url":"https://i0.hdslb.com/bfs/live/a2ffb62dc90d4896ddc3d1dcdbe83ac5d1dd7328.png","mobile_url":"https://i0.hdslb.com/bfs/live/a2ffb62dc90d4896ddc3d1dcdbe83ac5d1dd7328.png","usage":{"text":"7天头衔续期卡*1","url":""},"type":21,"expire":"1周","gift_type":"bbfc114b65126486a40c81daedd911e5"},{"name":"2020LPL春季赛助威券","num":1,"web_url":"https://i0.hdslb.com/bfs/live/be4cdecc4809caf8aa21817880a3283672b5a477.png","mobile_url":"https://i0.hdslb.com/bfs/live/be4cdecc4809caf8aa21817880a3283672b5a477.png","usage":{"text":"再来一次!(✪ω✪)","url":""},"type":22,"expire":"当天","gift_type":"96d2b8187ec6564fa40733153a41ac14"},{"name":"30天头衔续期卡","num":1,"web_url":"https://i0.hdslb.com/bfs/live/fc49e08115db6edd0276fba69ed8835a64714441.png","mobile_url":"https://i0.hdslb.com/bfs/live/fc49e08115db6edd0276fba69ed8835a64714441.png","usage":{"text":"30天头衔续期卡*1","url":""},"type":21,"expire":"1周","gift_type":"02810fd04244c47952bd4ed0b35617db"},{"name":"辣条","num":233,"web_url":"https://i0.hdslb.com/bfs/live/48605b0fe9eca5aba87f93da0fa0aa361c419835.png","mobile_url":"https://i0.hdslb.com/bfs/live/8e7a4dc8de374faee22fca7f9a3f801a1712a36b.png","usage":{"text":"辣条是一种直播虚拟礼物,可以在直播间送给自己喜爱的主播哦~","url":""},"type":1,"expire":"3天","gift_type":"a6d260760dfb1fe9f5375b3c8c7bd7ad"},{"name":"随机提伯斯熊毛绒公仔","num":1,"web_url":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_url":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","usage":{"text":"提伯斯熊毛绒公仔*1","url":""},"type":100024,"expire":"当天","gift_type":"2df71ff3306a4a2b4a627889cbd63c5b"}],"change_num":10000,"status":0,"is_login":true,"user_score":90000,"list":[{"num":1,"gift":"随机英雄联盟角色手办","date":"2020-04-23","name":"nXBo7p0svjm","web_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","count":1},{"num":1,"gift":"随机提伯斯熊毛绒公仔","date":"2020-04-20","name":"z98rwt","web_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","count":1},{"num":1,"gift":"随机英雄联盟角色手办","date":"2020-04-18","name":"wBQW6Z6jgbb","web_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","count":1},{"num":1,"gift":"随机提伯斯熊毛绒公仔","date":"2020-04-13","name":"dU9449p1zkz","web_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","count":1},{"num":1,"gift":"随机英雄联盟角色手办","date":"2020-04-10","name":"ckcs8151","web_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","count":1},{"num":1,"gift":"随机提伯斯熊毛绒公仔","date":"2020-04-06","name":"l1d9fgn1gl","web_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","count":1},{"num":1,"gift":"随机提伯斯熊毛绒公仔","date":"2020-03-31","name":"rlBF7ivbffe","web_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","count":1},{"num":1,"gift":"随机英雄联盟角色手办","date":"2020-03-29","name":"卟要悔","web_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","count":1},{"num":1,"gift":"随机提伯斯熊毛绒公仔","date":"2020-03-23","name":"就这样8丶","web_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","count":1},{"num":1,"gift":"随机英雄联盟角色手办","date":"2020-03-17","name":"bIud77Vsory","web_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","count":1}]}}
+ return json_decode($raw, true);
+ }
+
+ /**
+ * @获取剩余抽奖次数
+ * @param int $coin_id
+ * @param string $referer
+ * @return int
+ */
+ private static function getLuckyNum(int $coin_id, string $referer): int
+ {
+ $capsule_info = self::getCapsuleInfo($coin_id, $referer);
+ if ($capsule_info['code'] == 0) {
+ Log::info("获取剩余抽奖次数成功 {$capsule_info['data']['coin']}");
+ return $capsule_info['data']['coin'];
+ }
+ Log::warning("获取剩余抽奖次数失败 {$capsule_info}");
+ return 0;
+ }
+
+
+ /**
+ * @use 获取用户活动任务
+ * @param int $act_id
+ * @param string $referer
+ */
+ private static function userActTask(int $act_id, string $referer)
+ {
+ $url = 'https://api.live.bilibili.com/xlive/activity-interface/v1/activitytask/user_acttask/info';
+ $headers = [
+ 'origin' => 'https://live.bilibili.com',
+ 'referer' => $referer
+ ];
+ $payload = [
+ 'act_id' => $act_id,
+ ];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ // {"code":0,"message":"0","ttl":1,"data":{"act_info":{"id":30008,"title":"OWL2021","desc":"","start_time":0,"end_time":0,"sys_time":1621059078,"act_status":0},"task_list":[{"task_id":19,"task_name":"分享有礼","task_desc":"每日首次分享赛事直播间","task_cycle_type":0,"task_cycle_id":20210515,"progress":{"list":[{"progress_list":[{"task_id":19,"task_type":4,"task_level":1,"target_num":1,"current_num":0,"progress_status":0,"task_status":0,"real_num":0}],"reward_list":["OWL2021补给券"],"task_status":0,"draw_status":0,"task_title":"分享有礼","task_desc":"每日首次分享赛事直播间"}],"task_map":{"4":{"task_id":19,"task_type":4,"task_level":1,"target_num":1,"current_num":0,"progress_status":0,"task_status":0,"real_num":0}},"level":0,"is_finish":0}},{"task_id":18,"task_name":"关注有礼","task_desc":"每日首次关注任意3位推荐主播","task_cycle_type":0,"task_cycle_id":20210515,"progress":{"list":[{"progress_list":[{"task_id":18,"task_type":5,"task_level":1,"target_num":3,"current_num":0,"progress_status":0,"task_status":0,"real_num":0}],"reward_list":["OWL2021补给券"],"task_status":0,"draw_status":0,"task_title":"关注有礼","task_desc":"每日首次关注任意3位推荐主播"}],"task_map":{"5":{"task_id":18,"task_type":5,"task_level":1,"target_num":3,"current_num":0,"progress_status":0,"task_status":0,"real_num":0}},"level":0,"is_finish":0}}]}}
+ $de_raw = json_decode($raw, true);
+ }
+
+ /**
+ * @use 领取任务奖励
+ * @param int $act_id
+ * @param int $task_id
+ * @param int $level_id
+ * @param int $cycle_id
+ * @param string $referer
+ */
+ private static function getTaskAward(int $act_id, int $task_id, int $level_id, int $cycle_id, string $referer)
+ {
+ $url = 'https://api.live.bilibili.com/xlive/activity-interface/v1/activitytask/user_acttask/getaward';
+ $headers = [
+ 'origin' => 'https://live.bilibili.com',
+ 'referer' => $referer
+ ];
+ $payload = [
+ 'act_id' => $act_id,
+ 'task_id' => $task_id,
+ 'level_id' => 1,
+ 'cycle_id' => $cycle_id,
+ 'csrf' => getCsrf(),
+ 'csrf_token' => getCsrf(),
+ 'visit_id' => ''
+ ];
+ $raw = Curl::post('pc', $url, $payload, $headers);
+ // {"code":0,"message":"0","ttl":1,"data":{}}
+ $de_raw = json_decode($raw, true);
+
+ }
}
\ No newline at end of file
diff --git a/src/plugin/CheckUpdate.php b/src/plugin/CheckUpdate.php
new file mode 100644
index 0000000..53d40da
--- /dev/null
+++ b/src/plugin/CheckUpdate.php
@@ -0,0 +1,90 @@
+ time()) {
+ return;
+ }
+ self::check();
+ self::setLock(8 * 60 * 60);
+ }
+
+ /**
+ * @use 检查
+ */
+ private static function check()
+ {
+ Log::info('开始检查项目更新');
+ self::loadJsonData();
+ Log::info('拉取线上最新配置');
+ self::fetchLatest();
+ if (!self::compareVersion()) {
+ Log::info('项目已是最新版本');
+ } else {
+ Log::notice('项目有更新');
+ // Todo 完善提示信息
+ $time = self::$latest_conf->get('time');
+ $version = self::$latest_conf->get('version');
+ $des = self::$latest_conf->get('des');
+ $info = "最新版本-{$version}, {$des}";
+ Notice::push('update', $info);
+ }
+ }
+
+ /**
+ * @use 拉取最新
+ */
+ private static function fetchLatest()
+ {
+ $url = self::$current_conf->get('raw_url');
+ $payload = [];
+ $raw = Curl::get('other', $url, $payload);
+ self::$latest_conf = Config::load($raw, new Json, true);
+ }
+
+ /**
+ * @use 加载本地JSON DATA
+ */
+ private static function loadJsonData()
+ {
+ self::$current_conf = Config::load(self::$repository);
+ }
+
+ /**
+ * @use 比较版本号
+ * @return bool
+ */
+ private static function compareVersion(): bool
+ {
+ $current_version = self::$current_conf->get('version');
+ $latest_version = self::$latest_conf->get('version');
+ // true 有更新 false 无更新
+ return !($current_version == $latest_version);
+ }
+
+}
\ No newline at end of file
diff --git a/src/plugin/Competition.php b/src/plugin/Competition.php
index 8475ae0..3b5de39 100644
--- a/src/plugin/Competition.php
+++ b/src/plugin/Competition.php
@@ -23,22 +23,20 @@ class Competition
*/
public static function run()
{
- if (getenv('USE_COMPETITION') == 'false' || self::getLock() > time()) {
+ if (self::getLock() > time() || !getEnable('match_forecast')) {
return;
}
self::startStake();
-
- self::setLock(self::timing(1,30));
+ self::setLock(self::timing(1, 30));
}
-
/**
* @use 开始破产
*/
private static function startStake()
{
$questions = self::fetchQuestions();
- $max_guess = intval(getenv('COMPET_MAX_NUM'));
+ $max_guess = getConf('max_num', 'match_forecast');
foreach ($questions as $index => $question) {
if ($index >= $max_guess) {
break;
@@ -56,7 +54,6 @@ class Competition
{
Log::info($guess['title']);
Log::info($guess['estimate']);
- $user_info = User::parseCookies();
$url = 'https://api.bilibili.com/x/esports/guess/add';
$payload = [
'oid' => $guess['oid'],
@@ -64,7 +61,7 @@ class Competition
'detail_id' => $guess['detail_id'],
'count' => $guess['count'],
'is_fav' => 0,
- 'csrf' => $user_info['token']
+ 'csrf' => getCsrf()
];
$headers = [
'origin' => 'https://www.bilibili.com',
@@ -80,7 +77,6 @@ class Competition
}
}
-
/**
* @use 预计猜测结果
* @param array $question
@@ -92,13 +88,13 @@ class Competition
$guess['oid'] = $question['contest']['id'];
$guess['main_id'] = $question['questions'][0]['id'];
$details = $question['questions'][0]['details'];
- $guess['count'] = intval(in_array(getenv('COMPET_MAX_COIN'), range(1, 10)) ? getenv('COMPET_MAX_COIN') : 10);
+ $guess['count'] = ($count = getConf('max_coin', 'match_forecast') <= 10) ? $count : 10;
$guess['title'] = $question['questions'][0]['title'];
foreach ($details as $detail) {
$guess['title'] .= " 队伍: {$detail['option']} 赔率: {$detail['odds']}";
}
array_multisort(array_column($details, "odds"), SORT_ASC, $details);
- switch (intval(getenv('COMPET_STAKE'))) {
+ switch (getConf('bet', 'match_forecast')) {
case 1:
// 压大
$detail = array_pop($details);
diff --git a/src/plugin/Daily.php b/src/plugin/Daily.php
deleted file mode 100644
index 5a85b1c..0000000
--- a/src/plugin/Daily.php
+++ /dev/null
@@ -1,47 +0,0 @@
- time()) {
- return;
- }
- self::dailyBag();
- self::setLock(8 * 60 * 60);
- }
-
- /**
- * @use 领取每日包裹
- */
- private static function dailyBag()
- {
- $url = 'https://api.live.bilibili.com/gift/v2/live/receive_daily_bag';
- $payload = [];
- $data = Curl::get('app', $url, Sign::common($payload));
- $data = json_decode($data, true);
-
- if (isset($data['code']) && $data['code']) {
- Log::warning('每日礼包领取失败!', ['msg' => $data['message']]);
- } else {
- Log::notice('每日礼包领取成功');
- }
- }
-
-}
diff --git a/src/plugin/DailyBag.php b/src/plugin/DailyBag.php
new file mode 100644
index 0000000..9113d90
--- /dev/null
+++ b/src/plugin/DailyBag.php
@@ -0,0 +1,67 @@
+ time() || !getEnable('daily_bag')) {
+ return;
+ }
+ self::dailyBagPC();
+ self::dailyBagAPP();
+ self::setLock(12 * 60 * 60);
+ }
+
+ /**
+ * @use 领取每日包裹PC
+ */
+ private static function dailyBagPC()
+ {
+ sleep(1);
+ $url = 'https://api.live.bilibili.com/gift/v2/live/receive_daily_bag';
+ $payload = [];
+ $data = Curl::get('app', $url, Sign::common($payload));
+ $data = json_decode($data, true);
+
+ if (isset($data['code']) && $data['code']) {
+ Log::warning('[PC] 日常/周常礼包领取失败', ['msg' => $data['message']]);
+ } else {
+ Log::notice('[PC] 日常/周常礼包领取成功');
+ }
+ }
+
+ /**
+ * @use 领取每日包裹APP
+ */
+ private static function dailyBagAPP()
+ {
+ sleep(1);
+ $url = 'https://api.live.bilibili.com/AppBag/sendDaily';
+ $payload = [];
+ $data = Curl::get('app', $url, Sign::common($payload));
+ $data = json_decode($data, true);
+
+ if (isset($data['code']) && $data['code']) {
+ Log::warning('[APP] 日常/周常礼包领取失败', ['msg' => $data['message']]);
+ } else {
+ Log::notice('[APP] 日常/周常礼包领取成功');
+ }
+ }
+
+}
diff --git a/src/plugin/DailyTask.php b/src/plugin/DailyTask.php
index 3274374..368735b 100644
--- a/src/plugin/DailyTask.php
+++ b/src/plugin/DailyTask.php
@@ -20,7 +20,7 @@ class DailyTask
public static function run()
{
- if (self::getLock() > time()) {
+ if (self::getLock() > time() || !getEnable('daily_task')) {
return;
}
@@ -31,8 +31,7 @@ class DailyTask
if (isset($data['data']['sign_info'])) {
self::sign_info($data['data']['sign_info']);
}
-
- self::setLock(8 * 60 * 60);
+ self::setLock(mt_rand(8, 12) * 60 * 60);
}
/**
@@ -43,13 +42,12 @@ class DailyTask
{
$url = 'https://api.live.bilibili.com/i/api/taskInfo';
$payload = [];
- $data = Curl::get('app',$url, Sign::common($payload));
+ $data = Curl::get('app', $url, Sign::common($payload));
$data = json_decode($data, true);
Log::info('正在检查每日任务...');
if (isset($data['code']) && $data['code']) {
Log::warning('每日任务检查失败!', ['msg' => $data['message']]);
}
-
return $data;
}
@@ -65,16 +63,22 @@ class DailyTask
Log::notice('该任务已完成');
return;
}
+ $url = 'https://api.live.bilibili.com/xlive/web-ucenter/v1/sign/DoSign';
+ $headers = [
+ 'origin' => 'https://link.bilibili.com',
+ 'referer' => 'https://link.bilibili.com/p/center/index'
+ ];
$url = 'https://api.live.bilibili.com/sign/doSign';
$payload = [];
- $data = Curl::get('app',$url, Sign::common($payload));
+ $data = Curl::get('app', $url, Sign::common($payload));
$data = json_decode($data, true);
// {"code":1011040,"message":"今日已签到过,无法重复签到","ttl":1,"data":null}
+ // {"code":0,"message":"0","ttl":1,"data":{"text":"3000点用户经验,2根辣条","specialText":"再签到3天可以获得666银瓜子","allDays":31,"hadSignDays":2,"isBonusDay":0}}
// {"code":0,"message":"0","ttl":1,"data":{"text":"3000点用户经验,2根辣条,50根辣条","specialText":"","allDays":31,"hadSignDays":20,"isBonusDay":1}}
if (isset($data['code']) && $data['code']) {
Log::warning("签到失败: {$data['message']}");
} else {
- Log::info("签到成功: {$data['data']['text']}");
+ Log::notice("签到成功: {$data['data']['text']}");
// 推送签到信息
Notice::push('todaySign', $data['data']['text']);
}
@@ -100,7 +104,7 @@ class DailyTask
$payload = [
'task_id' => 'double_watch_task',
];
- $data = Curl::post('app',$url, Sign::common($payload));
+ $data = Curl::post('app', $url, Sign::common($payload));
$data = json_decode($data, true);
if (isset($data['code']) && $data['code']) {
diff --git a/src/plugin/DataTreating.php b/src/plugin/DataTreating.php
index 1faef3b..20732e1 100644
--- a/src/plugin/DataTreating.php
+++ b/src/plugin/DataTreating.php
@@ -12,7 +12,7 @@ namespace BiliHelper\Plugin;
class DataTreating
{
- // TODO 独立分发 Push||Pull数据
+ // Todo 独立分发 Push||Pull数据
/**
* @use 抽奖分发
* @param array $data
diff --git a/src/plugin/Heart.php b/src/plugin/DoubleHeart.php
similarity index 67%
rename from src/plugin/Heart.php
rename to src/plugin/DoubleHeart.php
index e8cec6f..5979ca6 100644
--- a/src/plugin/Heart.php
+++ b/src/plugin/DoubleHeart.php
@@ -14,13 +14,13 @@ use BiliHelper\Core\Log;
use BiliHelper\Core\Curl;
use BiliHelper\Util\TimeLock;
-class Heart
+class DoubleHeart
{
use TimeLock;
public static function run()
{
- if (self::getLock() > time()) {
+ if (self::getLock() > time() || !getEnable('double_heart')) {
return;
}
self::setPauseStatus();
@@ -36,23 +36,22 @@ class Heart
{
User::webGetUserInfo();
$url = 'https://api.live.bilibili.com/User/userOnlineHeart';
- $user_info = User::parseCookies();
$payload = [
- 'csrf' => $user_info['token'],
- 'csrf_token' => $user_info['token'],
- 'room_id' => getenv('ROOM_ID'),
+ 'csrf' => getCsrf(),
+ 'csrf_token' => getCsrf(),
+ 'room_id' => getConf('room_id', 'global_room'),
'_' => time() * 1000,
];
$headers = [
- 'Referer' => 'https://live.bilibili.com/' . getenv('ROOM_ID')
+ 'Referer' => 'https://live.bilibili.com/' . $payload['room_id'],
];
$data = Curl::post('app', $url, $payload, $headers);
$data = json_decode($data, true);
if (isset($data['code']) && $data['code']) {
- Log::warning('WEB端 发送心跳异常!', ['msg' => $data['message']]);
+ Log::warning('[PC] 发送在线心跳失败', ['msg' => $data['message']]);
} else {
- Log::info('WEB端 发送心跳正常!');
+ Log::notice('[PC] 发送在线心跳成功');
}
}
@@ -64,15 +63,15 @@ class Heart
User::appGetUserInfo();
$url = 'https://api.live.bilibili.com/mobile/userOnlineHeart';
$payload = [
- 'room_id' => getenv('ROOM_ID'),
+ 'room_id' => getConf('room_id', 'global_room'),
];
$data = Curl::post('app', $url, Sign::common($payload));
$data = json_decode($data, true);
if (isset($data['code']) && $data['code']) {
- Log::warning('APP端 发送心跳异常!', ['msg' => $data['message']]);
+ Log::warning('[APP] 发送在线心跳失败', ['msg' => $data['message']]);
} else {
- Log::info('APP端 发送心跳正常!');
+ Log::notice('[APP] 发送在线心跳成功');
}
}
}
diff --git a/src/plugin/Dynamic.php b/src/plugin/Dynamic.php
index c2ddd58..fefa5e5 100644
--- a/src/plugin/Dynamic.php
+++ b/src/plugin/Dynamic.php
@@ -8,11 +8,19 @@
namespace BiliHelper\Plugin;
-
use BiliHelper\Core\Curl;
+use BiliHelper\Core\Log;
+use BiliHelper\Util\FilterWords;
class Dynamic
{
+ use FilterWords;
+
+ // Todo 活动订阅
+ // https://www.bilibili.com/blackboard/activity-WeqT10t1ep.html
+ // https://api.vc.bilibili.com/topic_svr/v1/topic_svr/fetch_dynamics?topic_name=%E4%BA%92%E5%8A%A8%E6%8A%BD%E5%A5%96&sortby=2
+ private static $tags = ['互动抽奖', '抽奖', '转发抽奖', '动态抽奖', '关注+转发'];
+
// 228584 14027 434405 7019788 3230836
private static $topic_list = [
3230836 => '',
@@ -26,7 +34,7 @@ class Dynamic
/**
* 获取抽奖话题下的帖子
*/
- public static function getAwardTopic()
+ public static function getAwardTopic(): array
{
foreach (self::$topic_list as $t_id => $t_name) {
@@ -37,23 +45,42 @@ class Dynamic
// new
foreach ($data['data']['cards'] as $article) {
$article_id = $article['desc']['dynamic_id'];
+ // 获取 description
+ $card = json_decode($article['card'], true);
+ if (array_key_exists("description", $card['item'])) {
+ // 主动态
+ $description = $card['item']['description'];
+ } elseif (array_key_exists("content", $card['item'])) {
+ // 子动态
+ // Todo 暂时跳过 需要合适的处理方法
+ // description = $card['item']['content'];
+ continue;
+ } else {
+ // 链接到视频的动态 少数 跳过
+ // print_r($card);
+ continue;
+ }
$item = [
'uid' => $article['desc']['uid'],
'rid' => $article['desc']['rid'],
'did' => $article_id,
'tm' => $article['desc']['timestamp'],
+ 'desc' => $description
];
-
+ // 过滤为true 就跳过
+ if (self::filterLayer($item)) continue;
+ // 不要原始desc
+ unset($item['desc']);
self::$article_list[$article_id] = $item;
}
-// $has_more = 0;
+ // $has_more = 0;
// more ??
// https://api.vc.bilibili.com/topic_svr/v1/topic_svr/topic_history?topic_name=转发抽奖&offset_dynamic_id=454347930068783808
}
+ print_r(count(self::$article_list));
return self::$article_list;
}
-
/**
* 动态转发
* @param $rid
@@ -64,12 +91,11 @@ class Dynamic
* @param string $extension
* @return bool
*/
- public static function dynamicRepost($rid, $content = "", $type = 1, $repost_code = 3000, $from = "create.comment", $extension = '{"emoji_type":1}')
+ public static function dynamicRepost($rid, string $content = "", int $type = 1, int $repost_code = 3000, string $from = "create.comment", string $extension = '{"emoji_type":1}'): bool
{
- $user_info = User::parseCookies();
$url = "https://api.vc.bilibili.com/dynamic_repost/v1/dynamic_repost/reply";
$payload = [
- "uid" => $user_info['uid'],
+ "uid" => getUid(),
"rid" => $rid,
"type" => $type,
"content" => $content,
@@ -85,7 +111,6 @@ class Dynamic
return false;
}
-
/**
* 发表评论
* @param int $rid
@@ -94,16 +119,15 @@ class Dynamic
* @param int $plat
* @return bool
*/
- public static function dynamicReplyAdd($rid, $message = "", $type = 11, $plat = 1)
+ public static function dynamicReplyAdd(int $rid, string $message = "", int $type = 11, int $plat = 1): bool
{
- $user_info = User::parseCookies();
$url = "https://api.bilibili.com/x/v2/reply/add";
$payload = [
"oid" => $rid,
"plat" => $plat,
"type" => $type,
"message" => $message,
- "csrf" => $user_info['token'],
+ "csrf" => getCsrf(),
];
$raw = Curl::post('app', $url, $payload);
$de_raw = json_decode($raw, true);
@@ -113,19 +137,17 @@ class Dynamic
return false;
}
-
/**
* 删除指定动态
* @param $did
* @return bool
*/
- public static function removeDynamic($did)
+ public static function removeDynamic($did): bool
{
- $user_info = User::parseCookies();
$url = 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/rm_dynamic';
$payload = [
"dynamic_id" => $did,
- "csrf_token" => $user_info['token'],
+ "csrf_token" => getCsrf(),
];
$raw = Curl::post('app', $url, $payload);
$de_raw = json_decode($raw, true);
@@ -135,16 +157,14 @@ class Dynamic
return false;
}
-
/**
* 获取个人发布的动态
* @param int $uid
- * @return mixed
+ * @return array
*/
- public static function getMyDynamic($uid = 0)
+ public static function getMyDynamic(int $uid = 0): array
{
- $user_info = User::parseCookies();
- $uid = $uid == 0 ? $user_info['uid'] : $uid;
+ $uid = $uid == 0 ? getUid() : $uid;
$url = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history";
$offset = '';
$has_more = true;
@@ -185,7 +205,6 @@ class Dynamic
}
-
/**
* 获取抽奖动态信息
* @param $did
@@ -207,10 +226,9 @@ class Dynamic
* @param int $type_list
* @return array|mixed
*/
- public static function getDynamicTab($uid = 0, $type_list = 268435455)
+ public static function getDynamicTab(int $uid = 0, int $type_list = 268435455)
{
- $user_info = User::parseCookies();
- $uid = $uid == 0 ? $user_info['uid'] : $uid;
+ $uid = $uid == 0 ? getUid() : $uid;
$url = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new";
$offset = '';
$has_more = true;
@@ -233,6 +251,38 @@ class Dynamic
}
}
return $card_list;
+ }
+ /**
+ * @use 过滤层
+ * @param array $item
+ * @return bool
+ */
+ protected static function filterLayer(array $item): bool
+ {
+ self::loadJsonData();
+ // 过滤描述
+ $default_words = self::$store->get("DynamicForward.default");
+ $common_words = self::$store->get("Common.default");
+ $custom_words = empty($words = getConf('filter_words', 'dynamic')) ? [] : explode(',', $words);
+ $total_words = array_merge($default_words, $custom_words, $common_words);
+ foreach ($total_words as $word) {
+ if (strpos($item['desc'], $word) !== false) {
+ Log::warning("当前动态#{$item['did']}触发关键字过滤 {$word}");
+ return true;
+ }
+ }
+ // 过滤UID
+ $uid_list = self::$store->get("Common.uid_list");
+ if (array_key_exists((int)$item['uid'], $uid_list)) {
+ Log::warning("当前动态#{$item['did']}触发UP黑名单过滤 {$item['uid']}");
+ return true;
+ }
+ // 过滤粉丝数量
+ if (($num = Live::getMidFollower((int)$item['uid'])) < getConf('min_fans_num', 'dynamic')) {
+ Log::warning("当前动态#{$item['did']}触发UP粉丝数量过滤 {$num}");
+ return true;
+ }
+ return false;
}
}
\ No newline at end of file
diff --git a/src/plugin/Forward.php b/src/plugin/Forward.php
index 5e93fb0..14e3e41 100644
--- a/src/plugin/Forward.php
+++ b/src/plugin/Forward.php
@@ -12,18 +12,16 @@
* @Blog http://blog.jianxiaodai.com
* @author 菜如狗怎么了
* @date 2020-12
- */
-
-/**
+ *
* 2021-3-14 FEAT:增加自动回复语言更改
* @author:zymooll
*/
namespace BiliHelper\Plugin;
-
use BiliHelper\Core\Log;
use BiliHelper\Util\TimeLock;
+use Noodlehaus\Config;
class Forward
{
@@ -40,10 +38,10 @@ class Forward
private static $group_id = null;
- private static $msg = '从未中奖,从未放弃[doge]';
-
private static $draw_follow = [];
+ private static $repository = APP_DATA_PATH . 'reply_words.json';
+
public static function run()
{
@@ -60,38 +58,24 @@ class Forward
}
- public static function start()
+ public static function start(): bool
{
- //更改自动回复
- if (getenv('AUTO_REPLY_TEXT') != self::$msg) {
- self::changeReply();
- }
// 取关未中奖
- if (getenv('CLEAR_DYNAMIC') == 'true') {
+ if (getConf('clear_group_follow', 'dynamic')) {
self::clearDynamic();
}
// 自动转发关注评论
- if (getenv('AUTO_DYNAMIC') == 'true') {
+ if (getConf('enable', 'dynamic')) {
self::autoRepost();
}
// 强制清除抽奖关注组
- if (getenv('CLEAR_GROUP_FOLLOW') == 'true') {
+ if (getConf('clear_group_follow', 'dynamic')) {
self::clearAllDynamic();
self::clearFollowGroup();
}
return true;
}
- /**
- *更改自动回复
- */
- public static function changeReply()
- {
- self::$msg = getenv('AUTO_REPLY_TEXT');
- $msg = self::$msg;
- Log::info("已将自动回复改为\"{$msg}\"");
- }
-
/**
* 自动转发抽奖
*/
@@ -107,10 +91,10 @@ class Forward
}
// 评论
Log::info("[动态抽奖]-评论: {$did} {$article['rid']}");
- if (Dynamic::dynamicReplyAdd($article['rid'], self::$msg)) {
+ if (Dynamic::dynamicReplyAdd($article['rid'], self::getReplyMsg())) {
// 转发
Log::info("[动态抽奖]-转发: {$did}");
- if (Dynamic::dynamicRepost($did, self::$msg)) {
+ if (Dynamic::dynamicRepost($did, self::getReplyMsg())) {
// 关注
Log::info("[动态抽奖]-关注: {$did} {$article['uid']}");
self::addToGroup($article['uid']); //
@@ -121,7 +105,6 @@ class Forward
}
}
-
/**
* 清理无效的动态
*/
@@ -198,6 +181,9 @@ class Forward
}
}
+ /**
+ * @use 取关
+ */
private static function clearFollowGroup()
{
$tags = User::fetchTags();
@@ -214,20 +200,25 @@ class Forward
}
+ /**
+ * @use 清理动态
+ */
private static function clearAllDynamic()
{
$dynamicList = Dynamic::getMyDynamic();
+ $msg_list = self::getReplyMsgList();
foreach ($dynamicList as $dynamic) {
$did = $dynamic['desc']['dynamic_id'];
$card = json_decode($dynamic['card'], true);
- if (strpos($card['item']['content'], self::$msg) !== false) {
- Log::info("[删除所有动态] 删除动态 {$did}");
- Dynamic::removeDynamic($did);
+ foreach ($msg_list as $msg) {
+ if (strpos($card['item']['content'], $msg) !== false) {
+ Log::info("[删除所有动态] 删除动态 {$did}");
+ Dynamic::removeDynamic($did);
+ }
}
}
}
-
/**
* @use 添加分组
* @param int $need_follow_uid
@@ -241,7 +232,7 @@ class Forward
$tags = User::fetchTags();
$tag_id = array_search(self::$group_name, $tags);
// 如果不存在则调用创建
- self::$group_id = $tag_id ? $tag_id : User::createRelationTag(self::$group_name);
+ self::$group_id = $tag_id ?: User::createRelationTag(self::$group_name);
}
// 是否在关注里
$default_follows = self::getDefaultFollows();
@@ -256,7 +247,7 @@ class Forward
* @use 获取默认关注
* @return array
*/
- private static function getDefaultFollows()
+ private static function getDefaultFollows(): array
{
if (!empty(self::$default_follows)) {
return self::$default_follows;
@@ -268,4 +259,35 @@ class Forward
}
return self::$default_follows;
}
+
+ /**
+ * @use 获取回复 all
+ * @return array
+ */
+ private static function getReplyMsgList(): array
+ {
+ $data = Config::load(self::$repository);
+ $data = $data->get("DynamicForward.default");
+ array_push($data, getConf('auto_reply_text', 'dynamic'));
+ return $data;
+ }
+
+ /**
+ * @use 获取回复 1
+ * @return string
+ */
+ private static function getReplyMsg(): string
+ {
+ //更改自动回复
+ if (getConf('auto_reply_text', 'dynamic') != '') {
+ $msg = getConf('auto_reply_text', 'dynamic');
+ } else {
+ $data = self::getReplyMsgList();
+ shuffle($data);
+ $msg = array_pop($data);
+ }
+ Log::info("已将自动回复改为\"{$msg}\"");
+ return $msg;
+ }
+
}
diff --git a/src/plugin/GameMatch.php b/src/plugin/GameMatch.php
deleted file mode 100644
index be0c7df..0000000
--- a/src/plugin/GameMatch.php
+++ /dev/null
@@ -1,355 +0,0 @@
- [
-// 'type_id' => 25,
-// 'room_id' => 7734200,
-// 'short_room_id' => 6,
-// 'lottery_id' => 46,
-// 'status' => true
-// ],
-// 'OW' => [
-// 'type_id' => 26,
-// 'room_id' => 14073662,
-// 'short_room_id' => 76,
-// 'lottery_id' => 52,
-// 'status' => true
-// ],
-// 'KPL' => [
-// 'type_id' => 27,
-// 'room_id' => 21144080,
-// 'short_room_id' => 55,
-// 'lottery_id' => 55,
-// 'status' => true
-// ],
- ];
-
- public static function run()
- {
- if (self::getLock() > time() || getenv('USE_MATCH') == 'false') {
- return;
- }
- // TODO 赛事访问拒绝
- self::initTask();
- self::filterTask();
- self::workTask();
- self::setLock(3600);
- }
-
-
- /**
- * @use 初始化任务
- */
- private static function initTask()
- {
- // 检查有效性
- if (!self::$check_status) {
- foreach (self::$room_infos as $title => $room) {
- $status = self::getCapsuleStatus($room['lottery_id'], $room['short_room_id']);
- if (!$status) {
- self::$room_infos[$title]['status'] = false;
- }
- }
- self::$check_status = true;
- }
- }
-
-
- /**
- * @use 过滤任务
- */
- private static function filterTask()
- {
- // 签到任务
- foreach (self::$room_infos as $title => $room) {
- if (!$room['status']) {
- continue;
- }
- $status = self::getSignTask($room['type_id'], $room['room_id'], $room['short_room_id']);
- if ($status) {
- self::$room_infos[$title]['sign'] = true;
- } else {
- self::$room_infos[$title]['sign'] = false;
- }
- }
- // 分享任务
- foreach (self::$room_infos as $title => $room) {
- if (!$room['status']) {
- continue;
- }
- $status = self::getShareTask($room['type_id'], $room['room_id'], $room['short_room_id']);
- if ($status) {
- self::$room_infos[$title]['share'] = true;
- } else {
- self::$room_infos[$title]['share'] = false;
- }
- }
- }
-
-
- /**
- * @use 运行任务
- */
- private static function workTask()
- {
- foreach (self::$room_infos as $title => $room) {
- if (!$room['status']) {
- continue;
- }
- if (in_array('sign', $room) && $room['sign']) {
- self::matchSign($room['type_id'], $room['room_id'], $room['short_room_id']);
- }
- if (in_array('share', $room) && $room['share']) {
- self::matchShare($room['type_id'], $room['room_id'], $room['short_room_id']);
- }
- }
- }
-
-
- /**
- * @use 获取签到任务
- * @param int $type_id
- * @param int $room_id
- * @param int $short_room_id
- * @return bool
- */
- private static function getSignTask(int $type_id, int $room_id, int $short_room_id): bool
- {
- $url = 'https://api.live.bilibili.com/xlive/general-interface/v1/lpl-task/GetSignTask';
- $payload = [
- 'game_type' => $type_id,
- ];
- $headers = [
- 'origin' => 'https://live.bilibili.com',
- 'referer' => "https://live.bilibili.com/{$short_room_id}"
- ];
- $raw = Curl::get('pc', $url, $payload, $headers);
- $de_raw = json_decode($raw, true);
- // 成功 {"code":0,"message":"0","ttl":1,"data":{"id":601,"status":6,"day":30,"awards":[{"title":"彩色弹幕","cover":"https://i0.hdslb.com/bfs/live/9a571f9d82c2a8cbbe869fd92796e70b19f9c2cc.png"},{"title":"助威券","cover":"https://i0.hdslb.com/bfs/activity-plat/static/20200421/158d9f5e9553556421d8e1f652483400/ticket2.png"},{"title":"定制头衔","cover":"https://i0.hdslb.com/bfs/live/928598bde311f01364885ea14658476402eff99f.png"}]}}
- // 默认 {"code":0,"message":"0","ttl":1,"data":{"id":601,"status":3,"day":30,"awards":[{"title":"彩色弹幕","cover":"https://i0.hdslb.com/bfs/live/9a571f9d82c2a8cbbe869fd92796e70b19f9c2cc.png"},{"title":"助威券","cover":"https://i0.hdslb.com/bfs/activity-plat/static/20200421/158d9f5e9553556421d8e1f652483400/ticket2.png"},{"title":"定制头衔","cover":"https://i0.hdslb.com/bfs/live/928598bde311f01364885ea14658476402eff99f.png"}]}}
- if (isset($de_raw['data']['status']) && $de_raw['code'] == 0 && $de_raw['data']['status'] == 3) {
- return true;
- }
- return false;
- }
-
-
- /**
- * @use 获取弹幕任务
- * @param int $type_id
- * @param int $room_id
- * @param int $short_room_id
- * @return bool
- */
- private static function getDanmuTask(int $type_id, int $room_id, int $short_room_id): bool
- {
- $url = 'https://api.live.bilibili.com/xlive/general-interface/v1/lpl-task/GetDanmuTask';
- $payload = [
- 'game_type' => $type_id,
- '_' => Live::getMillisecond()
- ];
- $headers = [
- 'origin' => 'https://live.bilibili.com',
- 'referer' => "https://live.bilibili.com/{$short_room_id}"
- ];
- $raw = Curl::get('pc', $url, $payload, $headers);
- $de_raw = json_decode($raw, true);
- // 错误 {"code":1002002,"message":"参数错误","ttl":1,"data":{"id":0,"status":0,"awards":null,"progress":null}}
- // 默认 {"code":0,"message":"0","ttl":1,"data":{"id":620,"status":3,"awards":null,"progress":{"cur":0,"max":3}}}
- // 完成 {"code":0,"message":"0","ttl":1,"data":{"id":620,"status":6,"awards":null,"progress":{"cur":3,"max":3}}}
- if (isset($de_raw['data']['status']) && $de_raw['code'] == 0 && $de_raw['data']['status'] == 3) {
- return true;
- }
- return false;
- }
-
-
- /**
- * @use 获取分享任务
- * @param int $type_id
- * @param int $room_id
- * @param int $short_room_id
- * @return bool
- */
- private static function getShareTask(int $type_id, int $room_id, int $short_room_id): bool
- {
- $url = 'https://api.live.bilibili.com/xlive/general-interface/v1/lpl-task/GetShareTask';
- $payload = [
- 'game_type' => $type_id,
- 'room_id' => $short_room_id,
- '_' => Live::getMillisecond()
- ];
- $headers = [
- 'origin' => 'https://live.bilibili.com',
- 'referer' => "https://live.bilibili.com/{$short_room_id}"
- ];
- $raw = Curl::get('pc', $url, $payload, $headers);
- $de_raw = json_decode($raw, true);
- // 成功 {"code":0,"message":"0","ttl":1,"data":{"id":600,"status":6,"awards":null}}
- // 默认 {"code":0,"message":"0","ttl":1,"data":{"id":600,"status":3,"awards":null}}
- if (isset($de_raw['data']['status']) && $de_raw['code'] == 0 && $de_raw['data']['status'] == 3) {
- return true;
- }
- return false;
- }
-
-
- /**
- * @use 获取观看任务
- * @param int $type_id
- * @param int $room_id
- * @param int $short_room_id
- * @return bool
- */
- private static function getWatchTask(int $type_id, int $room_id, int $short_room_id): bool
- {
- $url = 'https://api.live.bilibili.com/xlive/general-interface/v1/lpl-task/GetWatchTask';
- $payload = [
- 'game_type' => $type_id,
- 'room_id' => $room_id,
- '_' => Live::getMillisecond()
- ];
- $headers = [
- 'origin' => 'https://live.bilibili.com',
- 'referer' => "https://live.bilibili.com/{$short_room_id}"
- ];
- $raw = Curl::get('pc', $url, $payload, $headers);
- $de_raw = json_decode($raw, true);
- // 错误 {"code":1002002,"message":"系统繁忙,请稍后再试","ttl":1,"data":{"id":0,"status":0,"progress":null,"awards":null}}
- // 默认 {"code":0,"message":"0","ttl":1,"data":{"id":606,"status":3,"progress":{"cur":0,"max":1800},"awards":null}}
- if (isset($de_raw['data']['status']) && $de_raw['code'] == 0 && $de_raw['data']['status'] == 3) {
- return true;
- }
- return false;
- }
-
-
- /**
- * @use 检查奖池状态
- * @param int $lottery_id
- * @param int $short_room_id
- * @return bool
- */
- private static function getCapsuleStatus(int $lottery_id, int $short_room_id): bool
- {
- $url = 'https://api.live.bilibili.com/xlive/web-ucenter/v1/capsule/get_capsule_info_v3';
- $payload = [
- 'id' => $lottery_id,
- 'from' => 'web',
- '-' => Live::getMillisecond()
- ];
- $headers = [
- 'origin' => 'https://live.bilibili.com',
- 'referer' => "https://live.bilibili.com/{$short_room_id}"
- ];
- $raw = Curl::get('pc', $url, $payload, $headers);
- $de_raw = json_decode($raw, true);
- // data -> status 0||2
- // {"code":0,"message":"0","ttl":1,"data":{"coin":9,"rule":"2020年英雄联盟职业联赛春季赛抽奖奖池","gift_list":[{"name":"辣条","num":1,"web_url":"https://i0.hdslb.com/bfs/live/48605b0fe9eca5aba87f93da0fa0aa361c419835.png","mobile_url":"https://i0.hdslb.com/bfs/live/8e7a4dc8de374faee22fca7f9a3f801a1712a36b.png","usage":{"text":"辣条是一种直播虚拟礼物,可以在直播间送给自己喜爱的主播哦~","url":""},"type":1,"expire":"3天","gift_type":"325a347f91903c0353385e343dd358f0"},{"name":"3天头衔续期卡","num":1,"web_url":"https://i0.hdslb.com/bfs/live/48aecec2d7243b6f8bd17f20ff715db89f9adcec.png","mobile_url":"https://i0.hdslb.com/bfs/live/48aecec2d7243b6f8bd17f20ff715db89f9adcec.png","usage":{"text":"3天头衔续期卡*1","url":""},"type":21,"expire":"1周","gift_type":"4bda2f960342d86a426ebc067d3633ed"},{"name":"LPL2020助威","num":1,"web_url":"https://i0.hdslb.com/bfs/live/d9ee9558fcc438c99deb00ed1f6bd3707bac3452.png","mobile_url":"https://i0.hdslb.com/bfs/live/d9ee9558fcc438c99deb00ed1f6bd3707bac3452.png","usage":{"text":"2020LPL限定头衔","url":""},"type":2,"expire":"1周","gift_type":"b114c47920fce2aca5fca7a27cca5915"},{"name":"随机英雄联盟角色手办","num":1,"web_url":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_url":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","usage":{"text":"随机英雄联盟角色手办*1","url":""},"type":100024,"expire":"当天","gift_type":"6a4ae5853753d67d07cea2b1750795f4"},{"name":"2020LPL彩色弹幕","num":1,"web_url":"https://i0.hdslb.com/bfs/live/9a571f9d82c2a8cbbe869fd92796e70b19f9c2cc.png","mobile_url":"https://i0.hdslb.com/bfs/live/9a571f9d82c2a8cbbe869fd92796e70b19f9c2cc.png","usage":{"text":"LPL专属彩色弹幕","url":""},"type":20,"expire":"3天","gift_type":"14e40c6949800b5d840011e47e54d0c5"},{"name":"7天头衔续期卡","num":1,"web_url":"https://i0.hdslb.com/bfs/live/a2ffb62dc90d4896ddc3d1dcdbe83ac5d1dd7328.png","mobile_url":"https://i0.hdslb.com/bfs/live/a2ffb62dc90d4896ddc3d1dcdbe83ac5d1dd7328.png","usage":{"text":"7天头衔续期卡*1","url":""},"type":21,"expire":"1周","gift_type":"bbfc114b65126486a40c81daedd911e5"},{"name":"2020LPL春季赛助威券","num":1,"web_url":"https://i0.hdslb.com/bfs/live/be4cdecc4809caf8aa21817880a3283672b5a477.png","mobile_url":"https://i0.hdslb.com/bfs/live/be4cdecc4809caf8aa21817880a3283672b5a477.png","usage":{"text":"再来一次!(✪ω✪)","url":""},"type":22,"expire":"当天","gift_type":"96d2b8187ec6564fa40733153a41ac14"},{"name":"30天头衔续期卡","num":1,"web_url":"https://i0.hdslb.com/bfs/live/fc49e08115db6edd0276fba69ed8835a64714441.png","mobile_url":"https://i0.hdslb.com/bfs/live/fc49e08115db6edd0276fba69ed8835a64714441.png","usage":{"text":"30天头衔续期卡*1","url":""},"type":21,"expire":"1周","gift_type":"02810fd04244c47952bd4ed0b35617db"},{"name":"辣条","num":233,"web_url":"https://i0.hdslb.com/bfs/live/48605b0fe9eca5aba87f93da0fa0aa361c419835.png","mobile_url":"https://i0.hdslb.com/bfs/live/8e7a4dc8de374faee22fca7f9a3f801a1712a36b.png","usage":{"text":"辣条是一种直播虚拟礼物,可以在直播间送给自己喜爱的主播哦~","url":""},"type":1,"expire":"3天","gift_type":"a6d260760dfb1fe9f5375b3c8c7bd7ad"},{"name":"随机提伯斯熊毛绒公仔","num":1,"web_url":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_url":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","usage":{"text":"提伯斯熊毛绒公仔*1","url":""},"type":100024,"expire":"当天","gift_type":"2df71ff3306a4a2b4a627889cbd63c5b"}],"change_num":10000,"status":0,"is_login":true,"user_score":90000,"list":[{"num":1,"gift":"随机英雄联盟角色手办","date":"2020-04-23","name":"nXBo7p0svjm","web_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","count":1},{"num":1,"gift":"随机提伯斯熊毛绒公仔","date":"2020-04-20","name":"z98rwt","web_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","count":1},{"num":1,"gift":"随机英雄联盟角色手办","date":"2020-04-18","name":"wBQW6Z6jgbb","web_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","count":1},{"num":1,"gift":"随机提伯斯熊毛绒公仔","date":"2020-04-13","name":"dU9449p1zkz","web_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","count":1},{"num":1,"gift":"随机英雄联盟角色手办","date":"2020-04-10","name":"ckcs8151","web_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","count":1},{"num":1,"gift":"随机提伯斯熊毛绒公仔","date":"2020-04-06","name":"l1d9fgn1gl","web_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","count":1},{"num":1,"gift":"随机提伯斯熊毛绒公仔","date":"2020-03-31","name":"rlBF7ivbffe","web_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","count":1},{"num":1,"gift":"随机英雄联盟角色手办","date":"2020-03-29","name":"卟要悔","web_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","count":1},{"num":1,"gift":"随机提伯斯熊毛绒公仔","date":"2020-03-23","name":"就这样8丶","web_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","mobile_image":"https://i0.hdslb.com/bfs/live/61414ab727c55cd1de8fb5c1c79a5a05dada3a55.png","count":1},{"num":1,"gift":"随机英雄联盟角色手办","date":"2020-03-17","name":"bIud77Vsory","web_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","mobile_image":"https://i0.hdslb.com/bfs/live/4a2f604ef7b3dad583c054d4ffdb30e37f37ad9c.png","count":1}]}}
- if (isset($de_raw['data']['status']) && $de_raw['code'] == 0 && $de_raw['data']['status'] == 0) {
- return true;
- }
- return false;
- }
-
-
- /**
- * @use 分享任务
- * @param int $type_id
- * @param int $room_id
- * @param int $short_room_id
- * @return bool
- */
- private static function matchShare(int $type_id, int $room_id, int $short_room_id): bool
- {
- $user_info = User::parseCookies();
- $url = 'https://api.live.bilibili.com/xlive/general-interface/v1/lpl-task/MatchShare';
- $payload = [
- 'game_type' => $type_id,
- 'csrf_token' => $user_info['token'],
- 'csrf' => $user_info['token'],
- 'visit_id' => ''
- ];
- $headers = [
- 'Content-Type' => 'application/x-www-form-urlencoded',
- 'Origin' => 'https://live.bilibili.com',
- 'Referer' => "https://live.bilibili.com/{$short_room_id}"
- ];
- // {"code":0,"message":"0","ttl":1,"data":{"status":1}}
- $raw = Curl::post('pc', $url, $payload, $headers);
- $de_raw = json_decode($raw, true);
- if ($de_raw['code'] == 0) {
- Log::notice("房间 {$short_room_id} 赛事 {$type_id} 分享成功~");
- return true;
- }
- Log::warning("房间 {$short_room_id} 赛事 {$type_id} 分享失败~");
- return false;
- }
-
-
- /**
- * @use 签到任务
- * @param int $type_id
- * @param int $room_id
- * @param int $short_room_id
- * @return bool
- */
- private static function matchSign(int $type_id, int $room_id, int $short_room_id): bool
- {
- $user_info = User::parseCookies();
- $url = 'https://api.live.bilibili.com/xlive/general-interface/v1/lpl-task/MatchSign';
- $payload = [
- 'room_id' => $room_id,
- 'game_type' => $type_id,
- 'csrf_token' => $user_info['token'],
- 'csrf' => $user_info['token'],
- 'visit_id' => ''
- ];
- $headers = [
- 'Content-Type' => 'application/x-www-form-urlencoded',
- 'Origin' => 'https://live.bilibili.com',
- 'Referer' => "https://live.bilibili.com/{$short_room_id}"
- ];
- // {"code":0,"message":"0","ttl":1,"data":{"status":1,"awards":[{"title":"彩色弹幕","cover":"https://i0.hdslb.com/bfs/live/9a571f9d82c2a8cbbe869fd92796e70b19f9c2cc.png","num":1}],"is_focus":1}}
- $raw = Curl::post('pc', $url, $payload, $headers);
- $de_raw = json_decode($raw, true);
- if ($de_raw['code'] == 0) {
- Log::notice("房间 {$short_room_id} 赛事 {$type_id} 签到成功~");
- return true;
- }
- Log::warning("房间 {$short_room_id} 赛事 {$type_id} 签到失败~");
- return false;
- }
-
- private static function matchDanmu()
- {
-
- }
-
- private static function matchWatch()
- {
-
- }
-
-
-}
\ No newline at end of file
diff --git a/src/plugin/GiftHeart.php b/src/plugin/GiftHeart.php
index d7ae5ce..4d32bad 100644
--- a/src/plugin/GiftHeart.php
+++ b/src/plugin/GiftHeart.php
@@ -20,7 +20,7 @@ class GiftHeart
public static function run()
{
- if (self::getLock() > time()) {
+ if (self::getLock() > time() || !getEnable('gift_heart')) {
return;
}
self::setPauseStatus();
@@ -31,7 +31,6 @@ class GiftHeart
self::setLock(5 * 60);
}
-
/**
* @use 礼物心跳
* @return bool
@@ -40,7 +39,7 @@ class GiftHeart
{
$url = 'https://api.live.bilibili.com/gift/v2/live/heart_gift_receive';
$payload = [
- 'roomid' => getenv('ROOM_ID'),
+ 'roomid' => getConf('room_id', 'global_room'),
];
$raw = Curl::get('app', $url, Sign::common($payload));
$de_raw = json_decode($raw, true);
diff --git a/src/plugin/GiftRaffle.php b/src/plugin/GiftRaffle.php
index 72fc944..e85f3dc 100644
--- a/src/plugin/GiftRaffle.php
+++ b/src/plugin/GiftRaffle.php
@@ -12,13 +12,12 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log;
use BiliHelper\Core\Curl;
-use BiliHelper\Util\TimeLock;
use BiliHelper\Util\BaseRaffle;
class GiftRaffle extends BaseRaffle
{
const ACTIVE_TITLE = '活动礼物';
- const ACTIVE_SWITCH = 'USE_ACTIVE';
+ const ACTIVE_SWITCH = 'live_gift';
protected static $wait_list = [];
protected static $finish_list = [];
@@ -62,7 +61,6 @@ class GiftRaffle extends BaseRaffle
return true;
}
-
/**
* @use 创建抽奖任务
* @param array $raffles
@@ -75,15 +73,13 @@ class GiftRaffle extends BaseRaffle
// $url = 'https://api.live.bilibili.com/gift/v4/smalltv/getAward';
$url = 'https://api.live.bilibili.com/xlive/lottery-interface/v5/smalltv/join';
$tasks = [];
- $results = [];
- $user_info = User::parseCookies();
foreach ($raffles as $raffle) {
$payload = [
'id' => $raffle['raffle_id'],
'roomid' => $raffle['room_id'],
'type' => $raffle['type'],
- 'csrf_token' => $user_info['token'],
- 'csrf' => $user_info['token'],
+ 'csrf_token' => getCsrf(),
+ 'csrf' => getCsrf(),
'visit_id' => ''
];
array_push($tasks, [
@@ -95,15 +91,14 @@ class GiftRaffle extends BaseRaffle
]
]);
}
- $results = Curl::async('app', $url, $tasks);
// print_r($results);
- return $results;
+ return Curl::async('app', $url, $tasks);
}
/**
* @use 解析抽奖信息
* @param array $results
- * @return mixed|void
+ * @return void
*/
protected static function parseLottery(array $results)
{
diff --git a/src/plugin/GiftSend.php b/src/plugin/GiftSend.php
index fd2f588..e4a9d71 100644
--- a/src/plugin/GiftSend.php
+++ b/src/plugin/GiftSend.php
@@ -10,7 +10,6 @@
namespace BiliHelper\Plugin;
-
use BiliHelper\Core\Log;
use BiliHelper\Core\Curl;
use BiliHelper\Util\TimeLock;
@@ -51,11 +50,10 @@ class GiftSend
}
}
-
/**
* @use 方案1
*/
- protected static function procOne()
+ protected static function procOne(): bool
{
if (!self::setTargetList()) {
return false;
@@ -63,7 +61,7 @@ class GiftSend
self::getMedalList();
foreach (self::$medal_list as $room_id => $total_intimacy) {
$bag_list = self::fetchBagList();
- if (getenv('FEED_FILL') == 'false') {
+ if (!getConf('feed_fill', 'intimacy')) {
$bag_list = self::checkExpireGift($bag_list);
}
if (count($bag_list)) {
@@ -116,13 +114,12 @@ class GiftSend
*/
protected static function setTargetList(): bool
{
- $temp = empty(getenv('ROOM_LIST')) ? null : getenv('ROOM_LIST');
+ $temp = empty($temp = getConf('room_list', 'intimacy')) ? null : $temp;
if (is_null($temp)) return false;
- self::$room_list = explode(',', getenv('ROOM_LIST'));
+ self::$room_list = explode(',', $temp);
return true;
}
-
/**
* @use 获取背包列表
* @return array
@@ -156,7 +153,6 @@ class GiftSend
return $new_bag_list;
}
-
/**
* @use 查找过期礼物
* @param array $bag_list
@@ -173,7 +169,6 @@ class GiftSend
return $expire_gift_list;
}
-
/**
* @use 获取勋章列表(过滤无勋章或已满)
*/
@@ -200,7 +195,6 @@ class GiftSend
}
}
-
/**
* @use 获取UID
*/
@@ -213,7 +207,7 @@ class GiftSend
if (isset($data['code']) && $data['code']) {
Log::warning('获取帐号信息失败!', ['msg' => $data['message']]);
Log::warning('清空礼物功能禁用!');
- self::$lock = time() + 100000000;
+ self::setLock(100000000);
return;
}
self::$uid = $data['data']['uid'];
@@ -225,12 +219,12 @@ class GiftSend
protected static function getRoomInfo()
{
Log::info('正在生成直播间信息...');
- $room_id = empty(self::$tid) ? getenv('ROOM_ID') : self::$tid;
- $data = Live::getRoomInfo($room_id);
+ $room_id = empty(self::$tid) ? getConf('room_id', 'global_room') : self::$tid;
+ $data = Live::getRoomInfoV1($room_id);
if (isset($data['code']) && $data['code']) {
Log::warning('获取主播房间号失败!', ['msg' => $data['message']]);
Log::warning('清空礼物功能禁用!');
- self::$lock = time() + 100000000;
+ self::setLock(100000000);
return;
}
Log::info('直播间信息生成完毕!');
@@ -239,7 +233,6 @@ class GiftSend
self::$short_id = $data['data']['short_id'] ? (string)$data['data']['short_id'] : self::$room_id;
}
-
/**
* @use 计算赠送数量
* @param array $gift
@@ -258,7 +251,6 @@ class GiftSend
return ($amt < 1) ? 1 : $amt;
}
-
/**
* @use 赠送礼物
* @param array $value
diff --git a/src/plugin/GroupSignIn.php b/src/plugin/GroupSignIn.php
index 92e3304..65d809a 100644
--- a/src/plugin/GroupSignIn.php
+++ b/src/plugin/GroupSignIn.php
@@ -20,7 +20,7 @@ class GroupSignIn
public static function run()
{
- if (self::getLock() > time()) {
+ if (self::getLock() > time() || !getEnable('love_club')) {
return;
}
@@ -34,10 +34,9 @@ class GroupSignIn
self::signInGroup($group);
}
- self::setLock(8 * 60 * 60);
+ self::setLock(mt_rand(8, 12) * 60 * 60);
}
-
/**
* @use 获取友爱社列表
* @return array
@@ -50,13 +49,12 @@ class GroupSignIn
$de_raw = json_decode($raw, true);
if (empty($de_raw['data']['list'])) {
- Log::notice('你没有需要签到的应援团!');
+ Log::warning('你没有需要签到的应援团!');
return [];
}
return $de_raw['data']['list'];
}
-
/**
* @use 签到
* @param array $groupInfo
@@ -73,14 +71,20 @@ class GroupSignIn
$de_raw = json_decode($raw, true);
if ($de_raw['code'] != '0') {
- Log::warning('在应援团{' . $groupInfo['group_name'] . '}中签到失败, 原因待查');
- // TODO 任务失败原因
+ // Todo 任务失败原因
+ // {"code": 710001, "msg": "应援失败>_<", "message": "应援失败>_<", "ttl": "1", "data": {"add_num": 0, "status": 0}}
+ if ($de_raw['code'] == '710001') {
+ Log::warning('在应援团{' . $groupInfo['group_name'] . '}中签到失败, 亲密度已达上限');
+ } else {
+ print_r($de_raw);
+ Log::warning('在应援团{' . $groupInfo['group_name'] . '}中签到失败, 原因待查');
+ }
return false;
}
if ($de_raw['data']['status'] == '0') {
- Log::info('在应援团{' . $groupInfo['group_name'] . '}中签到成功,增加{' . $de_raw['data']['add_num'] . '点}亲密度');
+ Log::notice('在应援团{' . $groupInfo['group_name'] . '}中签到成功,增加{' . $de_raw['data']['add_num'] . '点}亲密度');
} else {
- Log::notice('在应援团{' . $groupInfo['group_name'] . '}中不要重复签到');
+ Log::warning('在应援团{' . $groupInfo['group_name'] . '}中不要重复签到');
}
return true;
diff --git a/src/plugin/GuardRaffle.php b/src/plugin/GuardRaffle.php
index c9cc437..e8a2bc4 100644
--- a/src/plugin/GuardRaffle.php
+++ b/src/plugin/GuardRaffle.php
@@ -12,19 +12,17 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log;
use BiliHelper\Core\Curl;
-use BiliHelper\Util\TimeLock;
use BiliHelper\Util\BaseRaffle;
class GuardRaffle extends BaseRaffle
{
const ACTIVE_TITLE = '总督舰长';
- const ACTIVE_SWITCH = 'USE_GUARD';
+ const ACTIVE_SWITCH = 'live_guard';
protected static $wait_list = [];
protected static $finish_list = [];
protected static $all_list = [];
-
/**
* @use 解析数据
* @param int $room_id
@@ -80,7 +78,6 @@ class GuardRaffle extends BaseRaffle
return true;
}
-
/**
* @use 创建抽奖任务
* @param array $raffles
@@ -90,15 +87,13 @@ class GuardRaffle extends BaseRaffle
{
$url = 'https://api.live.bilibili.com/xlive/lottery-interface/v3/guard/join';
$tasks = [];
- $results = [];
- $user_info = User::parseCookies();
foreach ($raffles as $raffle) {
$payload = [
'id' => $raffle['raffle_id'],
'roomid' => $raffle['room_id'],
"type" => "guard",
- 'csrf_token' => $user_info['token'],
- 'csrf' => $user_info['token'],
+ 'csrf_token' => getCsrf(),
+ 'csrf' => getCsrf(),
'visit_id' => ''
];
array_push($tasks, [
@@ -110,15 +105,14 @@ class GuardRaffle extends BaseRaffle
]
]);
}
- $results = Curl::async('app', $url, $tasks);
// print_r($results);
- return $results;
+ return Curl::async('app', $url, $tasks);
}
/**
* @use 解析抽奖信息
* @param array $results
- * @return mixed|void
+ * @return void
*/
protected static function parseLottery(array $results)
{
diff --git a/src/plugin/Judge.php b/src/plugin/Judge.php
index 40cc2cc..f6c8a9e 100644
--- a/src/plugin/Judge.php
+++ b/src/plugin/Judge.php
@@ -26,25 +26,28 @@ class Judge
public static function run()
{
- if (self::getLock() > time() || self::$retry_time > time() || getenv('USE_JUDGE') == 'false') {
+ // https://www.bilibili.com/judgement/index
+ if (self::getLock() > time() || self::$retry_time > time() || !getEnable('judgement')) {
return;
}
- # https://www.bilibili.com/judgement/index
- $case_id = self::$wait_case_id ? self::$wait_case_id : self::caseObtain();
+ $case_id = self::$wait_case_id ?: self::caseObtain();
if (!self::judgeCase($case_id)) {
self::setLock(1 * 60 + 5);
return;
}
// self::judgementIndex();
- self::setLock(mt_rand(15, 30) * 60);
+ // 如果没有设置时间 就设置个默认时间 可能在一秒钟内处理完 所以 <=
+ if (self::getLock() <= time()) {
+ self::setLock(mt_rand(15, 30) * 60);
+ }
}
/**
- * @use 判案 TODO: 处理案例已满(MAX20例)
+ * @use 判案 Todo: 处理案例已满(MAX20例)
* @param $case_id
* @return bool
*/
- private static function judgeCase($case_id)
+ private static function judgeCase($case_id): bool
{
if (is_null($case_id) || $case_id == 0) {
return true;
@@ -95,7 +98,7 @@ class Judge
* @param $pct
* @return int|null
*/
- private static function judgeAdvice($num_judged, $pct)
+ private static function judgeAdvice($num_judged, $pct): ?int
{
if ($num_judged >= 300) {
# 认为这里可能出现了较多分歧,抬一手
@@ -137,8 +140,7 @@ class Judge
*/
private static function juryVote($case_id, $decision)
{
- $user_info = User::parseCookies();
- $url = 'http://api.bilibili.com/x/credit/jury/vote';
+ $url = 'https://api.bilibili.com/x/credit/jury/vote';
$payload = [
"jsonp" => "jsonp",
"cid" => $case_id,
@@ -147,9 +149,10 @@ class Judge
"likes" => "",
"hates" => "",
"attr" => "1",
- "csrf" => $user_info['token'],
+ "csrf" => getCsrf(),
];
$raw = Curl::post('pc', $url, $payload);
+ // {"code":25012,"message":"请勿重复投票","ttl":1}
$de_raw = json_decode($raw, true);
if (isset($de_raw['code']) && $de_raw['code']) {
Log::warning("案件 {$case_id} 投票失败 {$raw}");
@@ -158,32 +161,39 @@ class Judge
}
}
-
/**
* @use 案件获取
- * @return |null
+ * @return mixed|null
*/
private static function caseObtain()
{
- $user_info = User::parseCookies();
- $url = 'http://api.bilibili.com/x/credit/jury/caseObtain';
+ $url = 'https://api.bilibili.com/x/credit/jury/caseObtain';
$payload = [
"jsonp" => "jsonp",
- "csrf" => $user_info['token']
+ "csrf" => getCsrf()
];
$raw = Curl::post('pc', $url, $payload);
$de_raw = json_decode($raw, true);
// {"code":25008,"message":"真给力 , 移交众裁的举报案件已经被处理完了","ttl":1}
// {"code":25014,"message":"25014","ttl":1}
// {"code":25005,"message":"请成为风纪委员后再试","ttl":1}
- if (isset($de_raw['code']) && $de_raw['code'] == 25005) {
- Log::warning($de_raw['message']);
- self::setLock(self::timing(10));
- return null;
- }
if (isset($de_raw['code']) && $de_raw['code']) {
- Log::info("没有获取到案件~ {$raw}");
- return null;
+ switch ($de_raw['code']) {
+ case 25005:
+ Log::warning($de_raw['message']);
+ self::setLock(self::timing(10));
+ return null;
+ case 25008:
+ Log::info("暂时没有新的案件需要审理~ {$raw}");
+ return null;
+ case 25014:
+ Log::info("今日案件已审满,感谢您对社区的贡献!明天再来看看吧~");
+ self::setLock(self::timing(7, 0, 0, true));
+ return null;
+ default:
+ Log::info("获取案件失败~ {$raw}");
+ return null;
+ }
} else {
$case_id = $de_raw['data']['id'];
Log::info("获取到案件 {$case_id} ~");
@@ -196,7 +206,7 @@ class Judge
* @param $case_id
* @return array
*/
- private static function judgementVote($case_id)
+ private static function judgementVote($case_id): array
{
$url = 'https://api.bilibili.com/x/credit/jury/juryCase';
$headers = [
@@ -227,6 +237,31 @@ class Judge
];
}
+ /**
+ * @use 随机整数
+ * @param int $max
+ * @return string
+ */
+ private static function randInt(int $max = 17): string
+ {
+ $temp = [];
+ foreach (range(1, $max) as $_) {
+ array_push($temp, mt_rand(0, 9));
+ }
+ return implode("", $temp);
+ }
+
+ /**
+ * @use 初始化参数
+ */
+ private static function initParams()
+ {
+ self::$retry_time = 0;
+ self::$wait_case_id = 0;
+ self::$wait_time = 0;
+ self::$min_ok_pct = 1;
+ self::$max_ok_pct = 0;
+ }
/**
* @use 获取案例数据|风纪检测
@@ -273,31 +308,4 @@ class Judge
Log::info("今日投票{$sum_cases}({$valid_cases}票有效(非弃权),{$judging_cases}票还在进行中)");
return true;
}
-
-
- /**
- * @use 随机整数
- * @param int $max
- * @return string
- */
- private static function randInt(int $max = 17): string
- {
- $temp = [];
- foreach (range(1, $max) as $index) {
- array_push($temp, mt_rand(0, 9));
- }
- return implode("", $temp);
- }
-
- /**
- * @use 初始化参数
- */
- private static function initParams()
- {
- self::$retry_time = 0;
- self::$wait_case_id = 0;
- self::$wait_time = 0;
- self::$min_ok_pct = 1;
- self::$max_ok_pct = 0;
- }
}
\ No newline at end of file
diff --git a/src/plugin/Live.php b/src/plugin/Live.php
index 5f3300e..28d7978 100644
--- a/src/plugin/Live.php
+++ b/src/plugin/Live.php
@@ -41,7 +41,6 @@ class Live
return $areas;
}
-
/**
* @use AREA_ID转ROOM_ID
* @param $area_id
@@ -77,12 +76,11 @@ class Live
return $area_info;
}
-
/**
* @use 获取随机直播房间号
* @return int
*/
- public static function getUserRecommend()
+ public static function getUserRecommend(): int
{
$url = 'https://api.live.bilibili.com/room/v1/Area/getListByAreaID';
$payload = [
@@ -93,21 +91,21 @@ class Live
];
$raw = Curl::get('other', $url, $payload);
$de_raw = json_decode($raw, true);
+ print_r($de_raw);
if ($de_raw['code'] != '0') {
return 23058;
}
return $de_raw['data'][mt_rand(1, 29)]['roomid'];
}
-
/**
* @use 获取直播房间号
* @param $room_id
- * @return bool
+ * @return false|mixed
*/
public static function getRealRoomID($room_id)
{
- $data = self::getRoomInfo($room_id);
+ $data = self::getRoomInfoV1($room_id);
if (!isset($data['code']) || !isset($data['data'])) {
return false;
}
@@ -132,7 +130,7 @@ class Live
* @param $room_id
* @return array
*/
- public static function getRoomInfo($room_id): array
+ public static function getRoomInfoV1($room_id): array
{
$url = 'https://api.live.bilibili.com/room/v1/Room/room_init';
$payload = [
@@ -142,6 +140,21 @@ class Live
return json_decode($raw, true);
}
+ /**
+ * @use 获取直播间信息
+ * @param $room_id
+ * @return array
+ */
+ public static function getRoomInfoV2($room_id): array
+ {
+ $url = ' https://api.live.bilibili.com/room/v1/Room/get_info_by_id';
+ $payload = [
+ 'ids[]' => $room_id
+ ];
+ $raw = Curl::get('other', $url, $payload);
+ return json_decode($raw, true);
+ }
+
/**
* @use 获取弹幕配置
* @param $room_id
@@ -159,7 +172,6 @@ class Live
return json_decode($raw, true);
}
-
/**
* @use 获取配置信息
* @param $room_id
@@ -172,11 +184,11 @@ class Live
$server = $data['data']['host_server_list'][0];
$addr = "tcp://{$server['host']}:{$server['port']}/sub";
} else {
- $addr = getenv('ZONE_SERVER_ADDR');
+ $addr = getConf('server_addr', 'zone_monitor');
}
return [
'addr' => $addr,
- 'token' => isset($data['data']['token']) ? $data['data']['token'] : '',
+ 'token' => $data['data']['token'] ?? '',
];
}
@@ -208,7 +220,6 @@ class Live
return true;
}
-
/**
* @use 访问直播间
* @param $room_id
@@ -225,27 +236,18 @@ class Live
return true;
}
-
/**
- * @use 获取毫秒
- * @return float
- */
- public static function getMillisecond()
- {
- list($t1, $t2) = explode(' ', microtime());
- return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
- }
-
-
- /**
- * @use 发送弹幕
+ * @use 发送弹幕pc
* @param int $room_id
* @param string $content
* @return array
*/
- public static function sendBarrage(int $room_id, string $content): array
+ public static function sendBarragePC(int $room_id, string $content): array
{
- $user_info = User::parseCookies();
+ $room_id = self::getRealRoomID($room_id);
+ if (!$room_id) {
+ return ['code' => 404, 'message' => '直播间数据异常'];
+ }
$url = 'https://api.live.bilibili.com/msg/send';
$payload = [
'color' => '16777215',
@@ -255,17 +257,44 @@ class Live
'rnd' => 0,
'bubble' => 0,
'roomid' => $room_id,
- 'csrf' => $user_info['token'],
- 'csrf_token' => $user_info['token'],
+ 'csrf' => getCsrf(),
+ 'csrf_token' => getCsrf(),
];
$headers = [
'origin' => 'https://live.bilibili.com',
'referer' => "https://live.bilibili.com/{$room_id}"
];
$raw = Curl::post('pc', $url, $payload, $headers);
+ // {"code":0,"data":[],"message":"","msg":""}
return json_decode($raw, true) ?? ['code' => 404, 'msg' => '上层数据为空!'];
}
+ /**
+ * @use 发送弹幕app
+ * @param int $room_id
+ * @param string $content
+ * @return array
+ */
+ public static function sendBarrageAPP(int $room_id, string $content): array
+ {
+ $room_id = self::getRealRoomID($room_id);
+ if (!$room_id) {
+ return ['code' => 404, 'message' => '直播间数据异常'];
+ }
+ $url = 'https://api.live.bilibili.com/msg/send';
+ $payload = [
+ 'color' => '16777215',
+ 'fontsize' => 25,
+ 'mode' => 1,
+ 'msg' => $content,
+ 'rnd' => 0,
+ 'roomid' => $room_id,
+ 'csrf' => getCsrf(),
+ 'csrf_token' => getCsrf(),
+ ];
+ $raw = Curl::post('app', $url, Sign::common($payload));
+ return json_decode($raw, true) ?? ['code' => 404, 'msg' => '上层数据为空!'];
+ }
/**
* @use 获取勋章列表
@@ -276,6 +305,7 @@ class Live
{
$metal_list = [];
for ($i = 1; $i <= 10; $i++) {
+ // $url = 'https://api.live.bilibili.com/fans_medal/v5/live_fans_medal/iApiMedal';
$url = 'https://api.live.bilibili.com/i/api/medal';
$payload = [
'page' => $i,
@@ -347,9 +377,8 @@ class Live
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
+ 'uid' => getUid(), // 自己的UID
'gift_id' => $gift['gift_id'],
'ruid' => $guest['uid'], // UP的UID
'send_ruid' => 0,
@@ -362,8 +391,8 @@ class Live
'storm_beat_id' => 0,
'metadata' => '',
'price' => 0,
- 'csrf' => $user_info['token'],
- 'csrf_token' => $user_info['token']
+ 'csrf' => getCsrf(),
+ 'csrf_token' => getCsrf()
];
// {"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));
@@ -375,7 +404,6 @@ class Live
}
}
-
/**
* @use 获取分区直播间
* @param int $parent_area_id
@@ -383,7 +411,7 @@ class Live
* @param int $page
* @return array
*/
- public static function getAreaRoomList(int $parent_area_id, int $area_id, int $page=1): array
+ public static function getAreaRoomList(int $parent_area_id, int $area_id, int $page = 1): array
{
$url = 'https://api.live.bilibili.com/xlive/web-interface/v1/second/getList';
$payload = [
@@ -404,4 +432,60 @@ class Live
}
return $room_ids;
}
+
+ /**
+ * @use 获取用户卡片
+ * @param int $mid
+ * @return array
+ */
+ public static function getMidCard(int $mid): array
+ {
+ $url = 'https://api.bilibili.com/x/web-interface/card';
+ $payload = [
+ 'mid' => $mid,
+ ];
+ //{"code":0,"message":"0","ttl":1,"data":{"card":{"mid":"1","name":"bishi","approve":false,"sex":"男","rank":"10000","face":"http://i1.hdslb.com/bfs/face/34c5b30a990c7ce4a809626d8153fa7895ec7b63.gif","DisplayRank":"0","regtime":0,"spacesta":0,"birthday":"","place":"","description":"","article":0,"attentions":[],"fans":154167,"friend":5,"attention":5,"sign":"","level_info":{"current_level":4,"current_min":0,"current_exp":0,"next_exp":0},"pendant":{"pid":0,"name":"","image":"","expire":0,"image_enhance":"","image_enhance_frame":""},"nameplate":{"nid":0,"name":"","image":"","image_small":"","level":"","condition":""},"Official":{"role":0,"title":"","desc":"","type":-1},"official_verify":{"type":-1,"desc":""},"vip":{"type":2,"status":1,"due_date":1727625600000,"vip_pay_type":1,"theme_type":0,"label":{"path":"","text":"年度大会员","label_theme":"annual_vip","text_color":"#FFFFFF","bg_style":1,"bg_color":"#FB7299","border_color":""},"avatar_subscript":1,"nickname_color":"#FB7299","role":3,"avatar_subscript_url":"http://i0.hdslb.com/bfs/vip/icon_Certification_big_member_22_3x.png","vipType":2,"vipStatus":1}},"following":false,"archive_count":2,"article_count":0,"follower":154167}}
+ $raw = Curl::get('other', $url, $payload);
+ return json_decode($raw, true);
+ }
+
+ /**
+ * @use 获取用户状态
+ * @param int $mid
+ * @return array
+ */
+ public static function getMidStat(int $mid): array
+ {
+ $url = 'https://api.bilibili.com/x/relation/stat';
+ $payload = [
+ 'vmid' => $mid,
+ ];
+ // {"code":0,"message":"0","ttl":1,"data":{"mid":50329118,"following":62,"whisper":0,"black":0,"follower":7610241}}
+ $raw = Curl::get('other', $url, $payload);
+ return json_decode($raw, true);
+ }
+
+ /**
+ * @use 获取用户关注数
+ * @param int $mid
+ * @return int
+ */
+ public static function getMidFollower(int $mid): int
+ {
+ $follower = 0;
+ // root->data->follower
+ if (mt_rand(0, 10) > 5) {
+ $data = self::getMidStat($mid);
+ } else {
+ $data = self::getMidCard($mid);
+ }
+
+ if (isset($data['code']) && $data['code']) {
+ Log::warning("获取用户资料卡片失败: CODE -> {$data['code']} MSG -> {$data['message']} ");
+ } else {
+ // root->data->follower
+ $follower = $data['data']['follower'];
+ }
+ return $follower;
+ }
}
diff --git a/src/plugin/Login.php b/src/plugin/Login.php
index 0fd04ab..53c9b51 100644
--- a/src/plugin/Login.php
+++ b/src/plugin/Login.php
@@ -11,11 +11,9 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log;
use BiliHelper\Core\Curl;
-use BiliHelper\Core\Config;
use BiliHelper\Util\TimeLock;
use BiliHelper\Tool\Common;
-
class Login
{
use TimeLock;
@@ -31,14 +29,13 @@ class Login
return;
}
Log::info('启动登录程序');
- if (getenv('ACCESS_TOKEN') == "") {
+ if (getAccessToken() == '') {
Log::info('准备载入登录令牌');
self::login();
}
-
Log::info('检查登录令牌有效性');
if (!self::checkToken()) {
- Log::warning('登录令牌即将过期');
+ Log::warning('登录令牌失效或即将过期');
Log::info('申请更换登录令牌中');
if (!self::refreshToken()) {
Log::warning('无效的登录令牌,尝试重新申请');
@@ -48,14 +45,13 @@ class Login
self::setLock(3600);
}
-
/**
* @use 登录控制中心
*/
private static function login()
{
self::checkLogin();
- switch (intval(getenv('LOGIN_MODE'))) {
+ switch (getConf('mode', 'login.mode')) {
case 1:
// 账密模式
self::accountLogin();
@@ -69,7 +65,6 @@ class Login
// self::captchaLogin();
Log::error('此登录模式暂未开放');
die();
- break;
default:
Log::error('登录模式配置错误');
die();
@@ -81,23 +76,22 @@ class Login
*/
private static function checkLogin()
{
- $user = getenv('APP_USER');
- $pass = getenv('APP_PASS');
- if (empty($user) || empty($pass)) {
+ $username = getConf('username', 'login.account');
+ $password = getConf('password', 'login.account');
+ if (empty($username) || empty($password)) {
Log::error('空白的帐号和口令');
die();
}
self::clearAccount();
- self::$username = $user;
- self::$password = self::publicKeyEnc($pass);
+ self::$username = $username;
+ self::$password = self::publicKeyEnc($password);
}
-
/**
* @use 保持认证
* @return bool
*/
- private static function keepAuth()
+ private static function keepAuth(): bool
{
if (self::getLock() > time()) {
return true;
@@ -119,32 +113,32 @@ class Login
* @use 获取令牌信息
* @return bool
*/
- private static function checkToken()
+ private static function checkToken(): bool
{
$url = 'https://passport.bilibili.com/api/v2/oauth2/info';
$payload = [
- 'access_token' => getenv('ACCESS_TOKEN'),
+ 'access_token' => getAccessToken(),
];
$data = Curl::get('app', $url, Sign::common($payload));
+ // {"ts":1234,"code":0,"data":{"mid":1234,"access_token":"1234","expires_in":7759292}}
$data = json_decode($data, true);
if (isset($data['code']) && $data['code']) {
Log::error('检查令牌失败', ['msg' => $data['message']]);
return false;
}
- Log::info('令牌有效期: ' . date('Y-m-d H:i:s', $data['ts'] + $data['data']['expires_in']));
+ Log::notice('令牌有效期: ' . date('Y-m-d H:i:s', $data['ts'] + $data['data']['expires_in']));
return $data['data']['expires_in'] > 14400;
}
-
/**
* @use 刷新Token
*/
- private static function refreshToken()
+ private static function refreshToken(): bool
{
$url = 'https://passport.bilibili.com/api/v2/oauth2/refresh_token';
$payload = [
- 'access_token' => getenv('ACCESS_TOKEN'),
- 'refresh_token' => getenv('REFRESH_TOKEN'),
+ 'access_token' => getAccessToken(),
+ 'refresh_token' => getRefreshToken(),
];
$raw = Curl::post('app', $url, Sign::common($payload));
$de_raw = json_decode($raw, true);
@@ -153,45 +147,10 @@ class Login
Log::error('重新生成令牌失败', ['msg' => $de_raw['message']]);
return false;
}
- Log::info('重新令牌生成完毕');
- $access_token = $de_raw['data']['token_info']['access_token'];
- $refresh_token = $de_raw['data']['token_info']['refresh_token'];
- self::saveConfig('ACCESS_TOKEN', $access_token);
- self::saveConfig('REFRESH_TOKEN', $refresh_token);
- self::saveCookie($de_raw);
- Log::info('重置信息配置完毕');
+ self::refreshSuccess($de_raw);
return true;
}
- /**
- * @use 检查Cookie
- */
- private static function checkCookie()
- {
-
- }
-
-
- /**
- * @use 刷新Cookie
- */
- private static function refreshCookie()
- {
- $url = 'https://passport.bilibili.com/api/login/sso';
- $payload = [
- 'gourl' => 'https%3A%2F%2Faccount.bilibili.com%2Faccount%2Fhome'
- ];
- $response = Curl::headers('app', $url, Sign::common($payload));
- $headers = $response['Set-Cookie'];
- $cookies = [];
- foreach ($headers as $header) {
- preg_match_all('/^(.*);/iU', $header, $cookie);
- array_push($cookies, $cookie[0][0]);
- }
- return implode("", array_reverse($cookies));
- }
-
-
/**
* @use 公钥加密
* @param $plaintext
@@ -218,7 +177,6 @@ class Login
return base64_encode($crypt);
}
-
/**
* @use 获取验证码
* @return array|string[]
@@ -254,7 +212,7 @@ class Login
*/
private static function ocrCaptcha(array $captcha): array
{
- $url = 'http://captcha-v1.mudew.com:19951/';
+ $url = 'https://captcha-v1.mudew.com:19951/';
$payload = [
'type' => 'gt3',
'gt' => $captcha['gt'],
@@ -273,18 +231,6 @@ class Login
];
}
-
- /**
- * @use 验证码登录
- * @param string $mode
- */
- private static function captchaLogin(string $mode = '验证码模式')
- {
- $captcha_ori = self::getCaptcha();
- $captcha = self::ocrCaptcha($captcha_ori);
- self::accountLogin($captcha['validate'], $captcha['challenge'], $mode);
- }
-
/**
* @use 账密登录
* @param string $validate
@@ -293,8 +239,8 @@ class Login
*/
private static function accountLogin(string $validate = '', string $challenge = '', string $mode = '账密模式')
{
- Log::info("尝试{$mode}登录");
-// $url = 'https://passport.bilibili.com/api/v3/oauth2/login';
+ Log::info("尝试 {$mode} 登录");
+ // $url = 'https://passport.bilibili.com/api/v3/oauth2/login';
$url = 'https://passport.bilibili.com/x/passport-login/oauth2/login';
$payload = [
'seccode' => $validate ? "{$validate}|jordan" : '',
@@ -314,50 +260,7 @@ class Login
// {"ts":1593082432,"code":0,"data":{"status":0,"token_info":{"mid":123456,"access_token":"123123","refresh_token":"123123","expires_in":2592000},"cookie_info":{"cookies":[{"name":"bili_jct","value":"123123","http_only":0,"expires":1595674432},{"name":"DedeUserID","value":"123456","http_only":0,"expires":1595674432},{"name":"DedeUserID__ckMd5","value":"123123","http_only":0,"expires":1595674432},{"name":"sid","value":"bd6aagp7","http_only":0,"expires":1595674432},{"name":"SESSDATA","value":"6d74d850%123%2Cf0e36b61","http_only":1,"expires":1595674432}],"domains":[".bilibili.com",".biligame.com",".bigfunapp.cn"]},"sso":["https://passport.bilibili.com/api/v2/sso","https://passport.biligame.com/api/v2/sso","https://passport.bigfunapp.cn/api/v2/sso"]}}
// {"ts":1610254019,"code":0,"data":{"status":2,"url":"https://passport.bilibili.com/account/mobile/security/managephone/phone/verify?tmp_token=2bc5dd260df7158xx860565fxx0d5311&requestId=dffcfxx052fe11xxa9c8e2667739c15c&source=risk","message":"您的账号存在高危异常行为,为了您的账号安全,请验证手机号后登录帐号"}}
// https://passport.bilibili.com/mobile/verifytel_h5.html
- switch ($de_raw['code']) {
- case 0:
- // 二次判断
- switch ($de_raw['data']['status']) {
- case 0:
- // 正常登录
- Log::info("{$mode}登录成功");
- $access_token = $de_raw['data']['token_info']['access_token'];
- $refresh_token = $de_raw['data']['token_info']['refresh_token'];
- self::saveConfig('ACCESS_TOKEN', $access_token);
- self::saveConfig('REFRESH_TOKEN', $refresh_token);
- self::saveCookie($de_raw);
- Log::info('信息配置完毕');
- break;
- case 2:
- // 异常高危
- Log::error('登录失败', ['msg' => $de_raw['data']['message']]);
- die();
- default:
- Log::error('登录失败', ['msg' => '未知错误: ' . $de_raw['data']['message']]);
- die();
- break;
- }
- break;
- case -105:
- // 需要验证码
- Log::error('登录失败', ['msg' => '此次登录需要验证码或' . $de_raw['message']]);
- die();
- break;
- case -629:
- // 密码错误
- Log::error('登录失败', ['msg' => $de_raw['message']]);
- die();
- break;
- case -2100:
- // 验证手机号
- Log::error('登录失败', ['msg' => '账号启用了设备锁或异地登录需验证手机号']);
- die();
- break;
- default:
- Log::error('登录失败', ['msg' => '未知错误: ' . $de_raw['message']]);
- die();
- break;
- }
+ self::loginAfter($mode, $de_raw['code'], $de_raw);
}
/**
@@ -366,8 +269,10 @@ class Login
*/
private static function smsLogin(string $mode = '短信模式')
{
- Log::info("尝试{$mode}登录");
- self::checkPhone(self::$username);
+ Log::info("尝试 {$mode} 登录");
+ if (getConf('phone', 'login.check')) {
+ self::checkPhone(self::$username);
+ }
$captcha = self::sendSms(self::$username);
$url = 'https://passport.bilibili.com/x/passport-login/login/sms';
$payload = [
@@ -379,38 +284,7 @@ class Login
];
$raw = Curl::post('app', $url, Sign::login($payload));
$de_raw = json_decode($raw, true);
- switch ($de_raw['code']) {
- case 0:
- // 正常登录
- Log::info("{$mode}登录成功");
- $access_token = $de_raw['data']['token_info']['access_token'];
- $refresh_token = $de_raw['data']['token_info']['refresh_token'];
- self::saveConfig('ACCESS_TOKEN', $access_token);
- self::saveConfig('REFRESH_TOKEN', $refresh_token);
- self::saveCookie($de_raw);
- Log::info('信息配置完毕');
- break;
- case -105:
- // 需要验证码
- Log::error('登录失败', ['msg' => '此次登录需要验证码或' . $de_raw['message']]);
- die();
- break;
- case -629:
- // 密码错误
- Log::error('登录失败', ['msg' => $de_raw['message']]);
- die();
- break;
- case -2100:
- // 验证手机号
- Log::error('登录失败', ['msg' => '账号启用了设备锁或异地登录需验证手机号']);
- die();
- break;
- default:
- Log::error('登录失败', ['msg' => '未知错误: ' . $de_raw['message']]);
- die();
- break;
- }
-
+ self::loginAfter($mode, $de_raw['code'], $de_raw);
}
/**
@@ -437,9 +311,9 @@ class Login
{
$url = 'https://passport.bilibili.com//x/passport-login/sms/send';
$payload = [
- 'cid' => '86',
+ 'cid' => getConf('country_code', 'login.country') ,
'tel' => $phone,
- 'statistics' => '{"appId":1,"platform":3,"version":"6.3.0","abtest":""}',
+ 'statistics' => '{"appId":1,"platform":3,"version":"6.32.0","abtest":""}',
];
$raw = Curl::post('app', $url, Sign::login($payload));
$de_raw = json_decode($raw, true);
@@ -454,6 +328,108 @@ class Login
die();
}
+ /**
+ * @use 登录之后
+ * @param $mode
+ * @param $code
+ * @param $data
+ */
+ private static function loginAfter($mode, $code, $data)
+ {
+ switch ($code) {
+ case 0:
+ // data->data->status number
+ if (array_key_exists('status', $data['data'])) {
+ // 二次判断
+ switch ($data['data']['status']) {
+ case 0:
+ // 正常登录
+ self::loginSuccess($mode, $data);
+ break;
+ case 2:
+ // 异常高危
+ self::loginFail($mode, $data['data']['message']);
+ break;
+ default:
+ // 未知错误
+ self::loginFail($mode, '未知错误: ' . $data['data']['message']);
+ break;
+ }
+ } else {
+ // 正常登录
+ self::loginSuccess($mode, $data);
+ }
+ break;
+ case -105:
+ // 需要验证码
+ self::loginFail($mode, '此次登录需要验证码或' . $data['message']);
+ break;
+ case -629:
+ // 密码错误
+ self::loginFail($mode, $data['message']);
+ break;
+ case -2100:
+ // 验证手机号
+ self::loginFail($mode, '账号启用了设备锁或异地登录需验证手机号');
+ break;
+ default:
+ // 未知错误
+ self::loginFail($mode, '未知错误: ' . $data['message']);
+ break;
+ }
+
+ }
+
+ /**
+ * @use 登录成功
+ * @param $mode
+ * @param $data
+ */
+ private static function loginSuccess($mode, $data)
+ {
+ Log::info("{$mode} 登录成功");
+ self::successHandle($data);
+ Log::info('生成信息配置完毕');
+ }
+
+ /**
+ * @use 刷新成功
+ * @param $data
+ */
+ private static function refreshSuccess($data)
+ {
+ Log::info('重新令牌生成完毕');
+ self::successHandle($data);
+ Log::info('重置信息配置完毕');
+ }
+
+ /**
+ * @use 成功处理
+ * @param $data
+ */
+ private static function successHandle($data)
+ {
+ $access_token = $data['data']['token_info']['access_token'];
+ $refresh_token = $data['data']['token_info']['refresh_token'];
+ self::saveConfig('access_token', $access_token, 'login.auth');
+ self::saveConfig('refresh_token', $refresh_token, 'login.auth');
+ self::saveConfig('cookie', self::formatCookie($data), 'login.auth');
+ $user = User::parseCookies();
+ self::saveConfig('uid', $user['uid'], 'login.auth', false);
+ self::saveConfig('csrf', $user['csrf'], 'login.auth', false);
+ }
+
+ /**
+ * @use 登录失败
+ * @param $mode
+ * @param $data
+ */
+ private static function loginFail($mode, $data)
+ {
+ Log::error("{$mode} 登录失败", ['msg' => $data]);
+ die();
+ }
+
/**
* @use 检查手机号格式
* @param string $phone
@@ -470,26 +446,31 @@ class Login
* @use 保存配置
* @param string $key
* @param string $value
+ * @param string $section
+ * @param bool $print
* @param bool $hide
*/
- private static function saveConfig(string $key, string $value, $hide = true)
+ private static function saveConfig(string $key, string $value, string $section, $print = true, $hide = true)
{
- Config::put($key, $value);
- Log::info(" > {$key}: " . ($hide ? Common::replaceStar($value,4,4) : $value));
+ setConf($key, $value, $section);
+ if ($print) {
+ Log::info(" > {$key}: " . ($hide ? Common::replaceStar($value, 6, 6) : $value));
+ }
}
/**
- * @use 保存配置
+ * @use @use 格式化COOKIE
* @param array $data
+ * @return string
*/
- private static function saveCookie(array $data)
+ private static function formatCookie(array $data): string
{
$c = '';
$cookies = $data['data']['cookie_info']['cookies'];
foreach ($cookies as $cookie) {
$c .= $cookie['name'] . '=' . $cookie['value'] . ';';
}
- self::saveConfig('COOKIE', $c);
+ return $c;
}
/**
@@ -497,11 +478,42 @@ class Login
*/
private static function clearAccount()
{
- $variables = ['ACCESS_TOKEN', 'REFRESH_TOKEN', 'COOKIE'];
+ $variables = ['cookie', 'access_token', 'refresh_token'];
foreach ($variables as $variable) {
- Config::put($variable, '');
+ setConf($variable, '', 'login.auth');
}
}
+ /**
+ * @use 刷新COOKIE
+ * @return string
+ */
+ private static function refreshCookie(): string
+ {
+ $url = 'https://passport.bilibili.com/api/login/sso';
+ $payload = [
+ 'gourl' => 'https%3A%2F%2Faccount.bilibili.com%2Faccount%2Fhome'
+ ];
+ $response = Curl::headers('app', $url, Sign::common($payload));
+ $headers = $response['Set-Cookie'];
+ $cookies = [];
+ foreach ($headers as $header) {
+ preg_match_all('/^(.*);/iU', $header, $cookie);
+ array_push($cookies, $cookie[0][0]);
+ }
+ return implode("", array_reverse($cookies));
+ }
+
+ /**
+ * @use 验证码登录
+ * @param string $mode
+ */
+ private static function captchaLogin(string $mode = '验证码模式')
+ {
+ $captcha_ori = self::getCaptcha();
+ $captcha = self::ocrCaptcha($captcha_ori);
+ self::accountLogin($captcha['validate'], $captcha['challenge'], $mode);
+ }
+
}
\ No newline at end of file
diff --git a/src/plugin/MainSite.php b/src/plugin/MainSite.php
index 20e4e55..c684c05 100644
--- a/src/plugin/MainSite.php
+++ b/src/plugin/MainSite.php
@@ -20,7 +20,7 @@ class MainSite
public static function run()
{
- if (self::getLock() > time() || getenv('USE_MAIN_SITE') == 'false') {
+ if (self::getLock() > time() || !getEnable('main_site')) {
return;
}
if (self::watchAid() && self::shareAid() && self::coinAdd()) {
@@ -30,7 +30,6 @@ class MainSite
self::setLock(3600);
}
-
/**
* @use 投币
* @param $aid
@@ -38,13 +37,12 @@ class MainSite
*/
private static function reward($aid): bool
{
- $user_info = User::parseCookies();
$url = "https://api.bilibili.com/x/web-interface/coin/add";
$payload = [
"aid" => $aid,
"multiply" => "1",
"cross_domain" => "true",
- "csrf" => $user_info['token']
+ "csrf" => getCsrf()
];
$headers = [
'Host' => "api.bilibili.com",
@@ -52,18 +50,19 @@ class MainSite
'Referer' => "https://www.bilibili.com/video/av{$aid}",
'User-Agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",
];
+ // {"code":34005,"message":"超过投币上限啦~","ttl":1,"data":{"like":false}}
+ // {"code":0,"message":"0","ttl":1,"data":{"like":false}}
$raw = Curl::post('app', $url, Sign::common($payload), $headers);
$de_raw = json_decode($raw, true);
if ($de_raw['code'] == 0) {
- Log::notice("主站任务: av{$aid}投币成功!");
+ Log::notice("主站任务: av{$aid} 投币成功 {$de_raw['code']} MSG -> {$de_raw['message']}");
return true;
} else {
- Log::warning("主站任务: av{$aid}投币失败!");
+ Log::warning("主站任务: av{$aid} 投币失败 CODE -> {$de_raw['code']} MSG -> {$de_raw['message']}");
return false;
}
}
-
/**
* @use 投币日志
* @return int
@@ -75,7 +74,7 @@ class MainSite
$raw = Curl::get('pc', $url, $payload);
$de_raw = json_decode($raw, true);
- $logs = isset($de_raw['data']['list']) ? $de_raw['data']['list'] : [];
+ $logs = $de_raw['data']['list'] ?? [];
$coins = 0;
foreach ($logs as $log) {
$log_ux = strtotime($log['time']);
@@ -106,45 +105,36 @@ class MainSite
*/
protected static function coinAdd(): bool
{
- switch (getenv('USE_ADD_COIN')) {
- case 'false':
- break;
- case 'true':
- // 预计数量 失败默认0 避免损失
- $estimate_num = intval(getenv('ADD_COIN_NUM') ?? 0);
- // 库存数量
- $stock_num = self::getCoin();
- // 实际数量 处理硬币库存少于预计数量
- $actual_num = intval($estimate_num > $stock_num ? $stock_num : $estimate_num) - self::coinLog();
- Log::info("当前硬币库存 {$stock_num} 预计投币 {$estimate_num} 实际投币 {$actual_num}");
- // 上限
- if ($actual_num <= 0) {
- Log::info('今日投币上限已满!');
- break;
- }
- // 稿件列表
- if (gettype('ADD_COIN_MODE') =='random'){
- // 随机热门稿件榜单
- $aids = self::getDayRankingAids($actual_num);
- }else{
- // 固定获取关注UP稿件榜单, 不足会随机补全
- $aids = self::getFollowUpAids($actual_num);
- }
- Log::info("获取稿件列表: ". implode(" ",$aids));
- // 投币
- foreach ($aids as $aid) {
- self::reward($aid);
- }
- break;
- default:
- Log::warning('当前视频投币设置不正确, 请检查配置文件!');
- die();
- break;
+ if (!getConf('add_coin', 'main_site')) return true;
+
+ // 预计数量 失败默认0 避免损失
+ $estimate_num = getConf('add_coin_num', 'main_site') ?? 0;
+ // 库存数量
+ $stock_num = self::getCoin();
+ // 实际数量 处理硬币库存少于预计数量
+ $actual_num = intval($estimate_num > $stock_num ? $stock_num : $estimate_num) - self::coinLog();
+ Log::info("当前硬币库存 {$stock_num} 预计投币 {$estimate_num} 实际投币 {$actual_num}");
+ // 上限
+ if ($actual_num <= 0) {
+ Log::notice('今日投币上限已满');
+ return true;
+ }
+ // 稿件列表
+ if (getConf('add_coin_mode', 'main_site') == 'random') {
+ // 随机热门稿件榜单
+ $aids = self::getTopRCmdAids($actual_num);
+ } else {
+ // 固定获取关注UP稿件榜单, 不足会随机补全
+ $aids = self::getFollowUpAids($actual_num);
+ }
+ Log::info("获取稿件列表: " . implode(" ", $aids));
+ // 投币
+ foreach ($aids as $aid) {
+ self::reward($aid);
}
return true;
}
-
/**
* @use 获取随机AID
* @return string
@@ -161,12 +151,11 @@ class MainSite
$de_raw = json_decode($raw, true);
// echo "getRandomAid " . count($de_raw['data']['archives']) . PHP_EOL;
// $aid = array_rand($de_raw['data']['archives'])['aid'];
- } while (count($de_raw['data']['archives']) == 0);
+ } while (count((array)$de_raw['data']['archives']) == 0);
$aid = $de_raw['data']['archives'][0]['aid'];
return (string)$aid;
}
-
/**
* @use 获取关注UP稿件列表
* @param int $num
@@ -175,11 +164,9 @@ class MainSite
private static function getFollowUpAids(int $num): array
{
$aids = [];
- $rand_nums = [];
$url = 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new';
- $user_info = User::parseCookies();
$payload = [
- 'uid' => $user_info['uid'],
+ 'uid' => getUid(),
'type_list' => '8,512,4097,4098,4099,4100,4101'
];
$headers = [
@@ -196,12 +183,11 @@ class MainSite
}
// 此处补全缺失
if (count($aids) < $num) {
- $aids = array_merge($aids, self::getDayRankingAids($num - count($aids)));
+ $aids = array_merge($aids, self::getTopRCmdAids($num - count($aids)));
}
return $aids;
}
-
/**
* @use 获取榜单稿件列表
* @param int $num
@@ -238,6 +224,37 @@ class MainSite
return $aids;
}
+ /**
+ * @use 首页推荐
+ * @param int $num
+ * @param int $ps
+ * @return array
+ */
+ private static function getTopRCmdAids(int $num, int $ps = 30): array
+ {
+ // 动画1 国创168 音乐3 舞蹈129 游戏4 知识36 科技188 汽车223 生活160 美食211 动物圈127 鬼畜119 时尚155 资讯202 娱乐5 影视181
+ $rids = [1, 168, 3, 129, 4, 36, 188, 223, 160, 211, 127, 119, 155, 202, 5, 181];
+ $aids = [];
+ $url = 'https://api.bilibili.com/x/web-interface/dynamic/region';
+ $payload = [
+ 'ps' => $ps,
+ 'rid' => $rids[array_rand($rids)],
+ ];
+ $raw = Curl::get('other', $url, $payload);
+ $de_raw = json_decode($raw, true);
+ if ($de_raw['code'] == 0) {
+ if ($num == 1) {
+ $temps = [array_rand($de_raw['data']['archives'], $num)];
+ } else {
+ $temps = array_rand($de_raw['data']['archives'], $num);
+ }
+ foreach ($temps as $temp) {
+ array_push($aids, $de_raw['data']['archives'][$temp]['aid']);
+ }
+ return $aids;
+ }
+ return self::getDayRankingAids($num);
+ }
/**
* @use 分享视频
@@ -245,14 +262,15 @@ class MainSite
*/
private static function shareAid(): bool
{
+ if (!getConf('share', 'main_site')) return true;
+
# aid = 稿件av号
$url = "https://api.bilibili.com/x/web-interface/share/add";
$av_info = self::parseAid();
- $user_info = User::parseCookies();
$payload = [
'aid' => $av_info['aid'],
'jsonp' => "jsonp",
- 'csrf' => $user_info['token'],
+ 'csrf' => getCsrf(),
];
$headers = [
'Host' => "api.bilibili.com",
@@ -263,21 +281,22 @@ class MainSite
$raw = Curl::post('pc', $url, $payload, $headers);
$de_raw = json_decode($raw, true);
if ($de_raw['code'] == 0) {
- Log::notice("主站任务: av{$av_info['aid']}分享成功!");
+ Log::notice("主站任务: av{$av_info['aid']} 分享成功");
return true;
} else {
- Log::warning("主站任务: av{$av_info['aid']}分享失败!");
+ Log::warning("主站任务: av{$av_info['aid']} 分享失败");
return false;
}
}
-
/**
* @use 观看视频
* @return bool
*/
private static function watchAid(): bool
{
+ if (!getConf('watch', 'main_site')) return true;
+
$url = "https://api.bilibili.com/x/report/click/h5";
$av_info = self::parseAid();
$user_info = User::parseCookies();
@@ -289,8 +308,8 @@ class MainSite
'ftime' => time(),
'jsonp' => "jsonp",
'lv' => "",
- 'mid' => $user_info['uid'],
- 'csrf' => $user_info['token'],
+ 'mid' => getUid(),
+ 'csrf' => getCsrf(),
'stime' => time()
];
@@ -309,7 +328,7 @@ class MainSite
"aid" => $av_info['aid'],
"cid" => $av_info['cid'],
"mid" => $user_info['uid'],
- "csrf" => $user_info['token'],
+ "csrf" => getCsrf(),
"jsonp" => "jsonp",
"played_time" => "0",
"realtime" => $av_info['duration'],
@@ -329,16 +348,15 @@ class MainSite
$raw = Curl::post('pc', $url, $payload, $headers);
$de_raw = json_decode($raw, true);
if ($de_raw['code'] == 0) {
- Log::notice("主站任务: av{$av_info['aid']}观看成功!");
+ Log::notice("主站任务: av{$av_info['aid']} 观看成功");
return true;
}
}
}
- Log::warning("主站任务: av{$av_info['aid']}观看失败!");
+ Log::warning("主站任务: av{$av_info['aid']} 观看失败");
return false;
}
-
/**
* @use 解析AID到CID
* @return array
diff --git a/src/plugin/ManGa.php b/src/plugin/ManGa.php
index 0c5cfdb..1592f30 100644
--- a/src/plugin/ManGa.php
+++ b/src/plugin/ManGa.php
@@ -20,7 +20,7 @@ class ManGa
public static function run()
{
- if (self::getLock() > time() || getenv('USE_MANGA') == 'false') {
+ if (self::getLock() > time() || !getEnable('manga')) {
return;
}
if (self::sign() && self::share()) {
@@ -31,12 +31,16 @@ class ManGa
}
+ /**
+ * @use 漫画签到
+ * @return bool
+ */
private static function sign(): bool
{
sleep(1);
$url = 'https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn';
$payload = [
- 'access_key' => getenv('ACCESS_TOKEN'),
+ 'access_key' => getAccessToken(),
'ts' => time()
];
$raw = Curl::post('app', $url, Sign::common($payload));
@@ -44,14 +48,18 @@ class ManGa
# {"code":0,"msg":"","data":{}}
# {"code":"invalid_argument","msg":"clockin clockin is duplicate","meta":{"argument":"clockin"}}
if (!$de_raw['code']) {
- Log::notice('漫画签到: 成功~');
+ Log::notice('漫画签到: 成功');
} else {
- Log::warning('漫画签到: 失败或者重复操作~');
+ Log::warning('漫画签到: 失败或者重复操作');
}
return true;
}
+ /**
+ * @use 漫画分享
+ * @return bool
+ */
private static function share(): bool
{
sleep(1);
@@ -62,9 +70,9 @@ class ManGa
# {"code":0,"msg":"","data":{"point":5}}
# {"code":1,"msg":"","data":{"point":0}}
if (!$de_raw['code']) {
- Log::notice('漫画分享: 成功~');
+ Log::notice('漫画分享: 成功');
} else {
- Log::warning('漫画分享: 失败或者重复操作~');
+ Log::warning('漫画分享: 失败或者重复操作');
}
return true;
}
diff --git a/src/plugin/MaterialObject.php b/src/plugin/MaterialObject.php
index 0c49331..ec6b753 100644
--- a/src/plugin/MaterialObject.php
+++ b/src/plugin/MaterialObject.php
@@ -15,7 +15,6 @@ use BiliHelper\Core\Curl;
use BiliHelper\Util\TimeLock;
use BiliHelper\Util\FilterWords;
-
class MaterialObject
{
use TimeLock;
@@ -27,13 +26,10 @@ class MaterialObject
public static function run()
{
- if (getenv('USE_LIVE_BOX') == 'false') {
+ if (self::getLock() > time() || !getEnable('live_box')) {
return;
}
self::setPauseStatus();
- if (self::getLock() > time()) {
- return;
- }
self::calcAid(700, 900);
$lottery_list = self::fetchLottery();
self::drawLottery($lottery_list);
@@ -57,7 +53,6 @@ class MaterialObject
return false;
}
-
/**
* @use 抽奖盒子状态
* @param int $aid
@@ -92,7 +87,6 @@ class MaterialObject
}
}
-
/**
* @use 获取抽奖
* @return array
@@ -141,7 +135,6 @@ class MaterialObject
return $lottery_list;
}
-
/**
* @use 过滤轮次
* @param array $rounds
@@ -165,7 +158,6 @@ class MaterialObject
return 0;
}
-
/**
* @use 抽奖
* @param array $lottery_list
@@ -194,7 +186,6 @@ class MaterialObject
return true;
}
-
/**
* @use 计算Aid
* @param $min
@@ -203,7 +194,7 @@ class MaterialObject
*/
private static function calcAid($min, $max): bool
{
- // TODO 优化计算AID算法
+ // Todo 优化计算AID算法
if (self::$end_aid != 0 && self::$start_aid != 0) {
return false;
}
diff --git a/src/plugin/Notice.php b/src/plugin/Notice.php
index 30b9374..b6392a1 100644
--- a/src/plugin/Notice.php
+++ b/src/plugin/Notice.php
@@ -25,13 +25,13 @@ class Notice
*/
public static function push(string $type, string $result = '')
{
- if (getenv('USE_NOTIFY') == 'false') {
+ if (!getEnable('notify')) {
return;
}
if (self::filterResultWords($result)) {
return;
}
- $uname = User::userInfo() ? getenv('APP_UNAME') : getenv('APP_USER');
+ $uname = getConf('uname', 'print') ?? getConf('username', 'login.account');
self::sendInfoHandle($type, $uname, $result);
}
@@ -44,9 +44,10 @@ class Notice
{
self::loadJsonData();
$default_words = self::$store->get("Notice.default");;
- $custom_words = empty(getenv('NOTIFY_FILTER_WORDS')) ? [] : explode(',', getenv('NOTIFY_FILTER_WORDS'));
+ $custom_words = explode(',', getConf('filter_words', 'notify'));
$total_words = array_merge($default_words, $custom_words);
foreach ($total_words as $word) {
+ if (empty($word)) continue;
if (strpos($result, $word) !== false) {
return true;
}
@@ -54,7 +55,6 @@ class Notice
return false;
}
-
/**
* @use 处理信息
* @param string $type
@@ -156,27 +156,29 @@ class Notice
*/
private static function sendLog(array $info)
{
- if (getenv('NOTIFY_SCTKEY')) {
+ if (getConf('sctkey', 'notify.sct')) {
self::sctSend($info);
}
- if (getenv('NOTIFY_SCKEY')) {
+ if (getConf('sckey', 'notify.sc')) {
self::scSend($info);
}
- if (getenv('NOTIFY_TELE_BOTTOKEN') && getenv('NOTIFY_TELE_CHATID')) {
+ if (getConf('bottoken', 'notify.telegram') && getConf('chatid', 'notify.telegram')) {
self::teleSend($info);
}
- if (getenv('NOTIFY_DINGTALK_TOKEN')) {
+ if (getConf('token', 'notify.dingtalk')) {
self::dingTalkSend($info);
}
- if (getenv('NOTIFY_PUSHPLUS_TOKEN')) {
+ if (getConf('token', 'notify.pushplus')) {
self::pushPlusSend($info);
}
- if (getenv('NOTIFY_CQ_URL') && getenv('NOTIFY_CQ_TOKEN') && getenv('NOTIFY_CQ_QQ')) {
+ if (getConf('target_qq', 'notify.gocqhttp') && getConf('token', 'notify.gocqhttp') && getConf('url', 'notify.gocqhttp')) {
self::goCqhttp($info);
}
+ if (getConf('token', 'notify.debug') && getConf('url', 'notify.debug')) {
+ self::debug($info);
+ }
}
-
/**
* @use DingTalkbot推送
* @doc https://developers.dingtalk.com/document/app/document-upgrade-notice#/serverapi2/qf2nxq
@@ -185,7 +187,7 @@ class Notice
private static function dingTalkSend(array $info)
{
Log::info('使用DingTalk机器人推送消息');
- $url = 'https://oapi.dingtalk.com/robot/send?access_token=' . getenv('NOTIFY_DINGTALK_TOKEN');
+ $url = 'https://oapi.dingtalk.com/robot/send?access_token=' . getConf('token', 'notify.dingtalk');
$payload = [
'msgtype' => 'markdown',
'markdown' => [
@@ -199,13 +201,12 @@ class Notice
$raw = Curl::put('other', $url, $payload, $headers);
$de_raw = json_decode($raw, true);
if ($de_raw['errcode'] == 0) {
- Log::info("推送消息成功: {$de_raw['errmsg']}");
+ Log::notice("推送消息成功: {$de_raw['errmsg']}");
} else {
Log::warning("推送消息失败: {$raw}");
}
}
-
/**
* @use TeleBot推送
* @doc https://core.telegram.org/bots/api#sendmessage
@@ -214,22 +215,21 @@ class Notice
private static function teleSend(array $info)
{
Log::info('使用Tele机器人推送消息');
- $url = 'https://api.telegram.org/bot' . getenv('NOTIFY_TELE_BOTTOKEN');
+ $url = 'https://api.telegram.org/bot' . getConf('bottoken', 'notify.telegram') . '/sendMessage';
$payload = [
- 'method' => 'sendMessage',
- 'chat_id' => getenv('NOTIFY_TELE_CHATID'),
+ 'chat_id' => getConf('chatid', 'notify.telegram'),
'text' => $info['content']
];
+ // {"ok":true,"result":{"message_id":7,"from":{"id":,"is_bot":true,"first_name":"","username":""},"chat":{"id":,"first_name":"","username":"","type":"private"},"date":,"text":""}}
$raw = Curl::post('other', $url, $payload);
$de_raw = json_decode($raw, true);
- if (array_key_exists('message_id', $de_raw)) {
- Log::info("推送消息成功: {$de_raw['message_id']}");
+ if ($de_raw['ok'] && array_key_exists('message_id', $de_raw['result'])) {
+ Log::notice("推送消息成功: MSG_ID->{$de_raw['result']['message_id']}");
} else {
- Log::info("推送消息失败: {$raw}");
+ Log::warning("推送消息失败: {$raw}");
}
}
-
/**
* @use ServerChan推送
* @use https://sc.ftqq.com/
@@ -238,7 +238,7 @@ class Notice
private static function scSend(array $info)
{
Log::info('使用ServerChan推送消息');
- $url = 'https://sc.ftqq.com/' . getenv('NOTIFY_SCKEY') . '.send';
+ $url = 'https://sc.ftqq.com/' . getConf('sckey', 'notify.sc') . '.send';
$payload = [
'text' => $info['title'],
'desp' => $info['content'],
@@ -247,13 +247,12 @@ class Notice
$de_raw = json_decode($raw, true);
if ($de_raw['errno'] == 0) {
- Log::info("推送消息成功: {$de_raw['errmsg']}");
+ Log::notice("推送消息成功: {$de_raw['errmsg']}");
} else {
Log::warning("推送消息失败: {$raw}");
}
}
-
/**
* @use ServerChan(Turbo)推送
* @doc https://sct.ftqq.com/
@@ -262,7 +261,7 @@ class Notice
private static function sctSend(array $info)
{
Log::info('使用ServerChan(Turbo)推送消息');
- $url = 'https://sctapi.ftqq.com/' . getenv('NOTIFY_SCTKEY') . '.send';
+ $url = 'https://sctapi.ftqq.com/' . getConf('sctkey', 'notify.sct') . '.send';
$payload = [
'text' => $info['title'],
'desp' => $info['content'],
@@ -272,7 +271,7 @@ class Notice
// {'message': '[AUTH]用户不存在或者权限不足', 'code': 40001, 'info': '用户不存在或者权限不足', 'args': [None]}
// {'code': 0, 'message': '', 'data': {'pushid': 'xxxx', 'readkey': 'xxxxx', 'error': 'SUCCESS', 'errno': 0}}
if ($de_raw['code'] == 0) {
- Log::info("推送消息成功: {$de_raw['data']['pushid']}");
+ Log::notice("推送消息成功: {$de_raw['data']['pushid']}");
} else {
Log::warning("推送消息失败: {$raw}");
}
@@ -288,7 +287,7 @@ class Notice
Log::info('使用PushPlus酱推送消息');
$url = 'http://www.pushplus.plus/send';
$payload = [
- 'token' => getenv('NOTIFY_PUSHPLUS_TOKEN'),
+ 'token' => getConf('token', 'notify.pushplus'),
'title' => $info['title'],
'content' => $info['content']
];
@@ -299,13 +298,12 @@ class Notice
// {"code":200,"msg":"请求成功","data":"发送消息成功"}
$de_raw = json_decode($raw, true);
if ($de_raw['code'] == 200) {
- Log::info("推送消息成功: {$de_raw['data']}");
+ Log::notice("推送消息成功: {$de_raw['data']}");
} else {
Log::warning("推送消息失败: {$raw}");
}
}
-
/**
* @use GO-CQHTTP推送
* @doc https://docs.go-cqhttp.org/api/
@@ -314,20 +312,46 @@ class Notice
private static function goCqhttp(array $info)
{
Log::info('使用GoCqhttp推送消息');
- $url = getenv('NOTIFY_CQ_URL');
+ $url = getConf('url', 'notify.gocqhttp');
$payload = [
- 'access_token' => getenv('NOTIFY_CQ_TOKEN'),
- 'user_id' => getenv('NOTIFY_CQ_QQ'),
+ 'access_token' => getConf('token', 'notify.gocqhttp'),
+ 'user_id' => getConf('target_qq', 'notify.gocqhttp'),
'message' => $info['content']
];
$raw = Curl::get('other', $url, $payload);
// {"data":{"message_id":123456},"retcode":0,"status":"ok"}
$de_raw = json_decode($raw, true);
if ($de_raw['retcode'] == 0) {
- Log::info("推送消息成功: {$de_raw['status']}");
+ Log::notice("推送消息成功: {$de_raw['status']}");
} else {
Log::warning("推送消息失败: {$raw}");
}
}
+ /**
+ * @use 个人调试使用
+ * @doc
+ * @param array $info
+ */
+ private static function debug(array $info)
+ {
+ Log::info('使用Debug推送消息');
+ $url = getConf('url', 'notify.debug');
+ $payload = [
+ 'receiver' => getConf('token', 'notify.debug'),
+ 'title' => $info['title'],
+ 'body' => $info['content'],
+ 'url' => '',
+ ];
+ $raw = Curl::post('other', $url, $payload);
+ $de_raw = json_decode($raw, true);
+ // {"success": true, "msg": null, "data": {"errcode": 0, "errmsg": "ok", "msgid": 1231, "token": "456"}}
+ if ($de_raw['success'] == true) {
+ Log::notice("推送消息成功: {$de_raw['data']['msgid']}");
+ } else {
+ Log::warning("推送消息失败: {$raw}");
+ }
+
+ }
+
}
\ No newline at end of file
diff --git a/src/plugin/PkRaffle.php b/src/plugin/PkRaffle.php
index 3cce163..d523303 100644
--- a/src/plugin/PkRaffle.php
+++ b/src/plugin/PkRaffle.php
@@ -15,17 +15,15 @@ use BiliHelper\Core\Curl;
use BiliHelper\Util\TimeLock;
use BiliHelper\Util\BaseRaffle;
-
class PkRaffle extends BaseRaffle
{
- const ACTIVE_TITLE = '大乱斗';
- const ACTIVE_SWITCH = 'USE_PK';
+ const ACTIVE_TITLE = '主播乱斗';
+ const ACTIVE_SWITCH = 'live_pk';
protected static $wait_list = [];
protected static $finish_list = [];
protected static $all_list = [];
-
/**
* @use 解析数据
* @param int $room_id
@@ -65,7 +63,6 @@ class PkRaffle extends BaseRaffle
return true;
}
-
/**
* @use 创建抽奖任务
* @param array $raffles
@@ -75,14 +72,12 @@ class PkRaffle extends BaseRaffle
{
$url = 'https://api.live.bilibili.com/xlive/lottery-interface/v1/pk/join';
$tasks = [];
- $results = [];
- $user_info = User::parseCookies();
foreach ($raffles as $raffle) {
$payload = [
'id' => $raffle['raffle_id'],
'roomid' => $raffle['room_id'],
- 'csrf_token' => $user_info['token'],
- "csrf" => $user_info['token'],
+ 'csrf_token' => getCsrf(),
+ "csrf" => getCsrf(),
];
array_push($tasks, [
'payload' => Sign::common($payload),
@@ -93,15 +88,14 @@ class PkRaffle extends BaseRaffle
]
]);
}
- $results = Curl::async('app', $url, $tasks);
// print_r($results);
- return $results;
+ return Curl::async('app', $url, $tasks);
}
/**
* @use 解析抽奖信息
* @param array $results
- * @return mixed|void
+ * @return void
*/
protected static function parseLottery(array $results)
{
diff --git a/src/plugin/PolishTheMedal.php b/src/plugin/PolishTheMedal.php
new file mode 100644
index 0000000..2498c39
--- /dev/null
+++ b/src/plugin/PolishTheMedal.php
@@ -0,0 +1,117 @@
+ 11000 MSG -> ''
+ if (in_array($medal['roomid'], [21686237])) return;
+
+ Log::info("开始点亮直播间@{$medal['roomid']}的勋章");
+ // 擦亮
+ $response = Live::sendBarrageAPP($medal['roomid'], Generator::emoji());
+ if (isset($response['code']) && $response['code'] == 0) {
+ Log::notice("在直播间@{$medal['roomid']}发送点亮弹幕成功");
+ } else {
+ Log::warning("在直播间@{$medal['roomid']}发送点亮弹幕失败, CODE -> {$response['code']} MSG -> {$response['message']} ");
+ }
+ }
+
+
+ /**
+ * @use 获取灰色勋章列表(过滤无勋章或已满)
+ * @param bool $all
+ */
+ private static function fetchGreyMedalList(bool $all = false)
+ {
+ $data = Live::fetchMedalList();
+ foreach ($data as $vo) {
+ // 过滤主站勋章
+ if (!isset($vo['roomid'])) continue;
+ // 过滤自己勋章
+ if ($vo['target_id'] == getUid()) continue;
+ // 所有
+ self::$fans_medals[] = [
+ 'uid' => $vo['target_id'],
+ 'roomid' => $vo['roomid'],
+ ];
+ // 如果是每天擦亮 ,就不过滤|否则过滤掉,只点亮灰色
+ if ($all) {
+ self::$grey_fans_medals[] = [
+ 'uid' => $vo['target_id'],
+ 'roomid' => $vo['roomid'],
+ ];
+ } else {
+ // 灰色
+ 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'],
+ ];
+ }
+ }
+ }
+ // 乱序
+ shuffle(self::$grey_fans_medals);
+ }
+}
\ No newline at end of file
diff --git a/src/plugin/Schedule.php b/src/plugin/Schedule.php
index ce75d22..3a2cbad 100644
--- a/src/plugin/Schedule.php
+++ b/src/plugin/Schedule.php
@@ -13,17 +13,16 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log;
use BiliHelper\Util\TimeLock;
-
class Schedule
{
use TimeLock;
- // TODO 黑白名单|考虑添加到每个插件内部自动添加|优化RUN逻辑代码
+ // Todo 黑白名单|考虑添加到每个插件内部自动添加|优化RUN逻辑代码
private static $unlock_hour = 24;
private static $unlock_timers = [];
private static $sleep_section = [];
// 日常类
- private static $fillable = ['Login', 'Schedule', 'Daily', 'Judge', 'MainSite', 'GiftSend', 'DailyTask', 'Silver2Coin', 'ManGa', 'GameMatch', 'GroupSignIn', 'AwardRecord', 'Statistics'];
+ private static $fillable = ['Login', 'Schedule', 'DailyBag', 'Judge', 'MainSite', 'GiftSend', 'DailyTask', 'Silver2Coin', 'ManGa', 'GroupSignIn', 'AwardRecord', 'Statistics'];
// 任务类
private static $guarded_first = ['Barrage', 'GiftHeart', 'Silver', 'MaterialObject'];
// 监控类
@@ -31,9 +30,12 @@ class Schedule
// 抽奖类
private static $guarded_third = ['StormRaffle', 'GuardRaffle', 'PkRaffle', 'GiftRaffle', 'AnchorRaffle'];
// 特殊 老爷处理
- private static $guarded_fourth = ['Heart'];
+ private static $guarded_fourth = ['DoubleHeart'];
// 暂定不做处理,后期看情况再定
- private static $release = ['ActivityLottery', 'SmallHeart', 'Competition', 'SmallHeart', 'Forward', 'CapsuleLottery'];
+ private static $release = ['ActivityLottery', 'SmallHeart', 'Competition', 'SmallHeart', 'Forward', 'CapsuleLottery', 'PolishTheMedal'];
+ // 暂定不做处理 大会员类
+ private static $guarded_fifth = ['VipPrivilege', 'BpConsumption'];
+
public static function run()
{
@@ -48,10 +50,10 @@ class Schedule
/**
* @use 检查休眠
*/
- private static function isSleep()
+ private static function isSleep(): bool
{
- if (getenv('USE_SLEEP') != 'false' && self::$unlock_hour != date('H')) {
- self::$sleep_section = empty(self::$sleep_section) ? explode(',', getenv('SLEEP_SECTION')) : self::$sleep_section;
+ if (getEnable('sleep') && self::$unlock_hour != date('H')) {
+ self::$sleep_section = empty(self::$sleep_section) ? explode(',', getConf('section', 'sleep')) : self::$sleep_section;
if (!in_array(date('H'), self::$sleep_section)) {
return false;
};
@@ -64,7 +66,7 @@ class Schedule
/**
* @use 特殊暂停
*/
- private static function isSpecialPause()
+ private static function isSpecialPause(): bool
{
foreach (self::$guarded_second as $classname) {
$status = call_user_func(array(__NAMESPACE__ . '\\' . $classname, 'getPauseStatus'));
diff --git a/src/plugin/Sign.php b/src/plugin/Sign.php
index fca7219..5c92e79 100644
--- a/src/plugin/Sign.php
+++ b/src/plugin/Sign.php
@@ -27,7 +27,7 @@ class Sign
// $appsecret = '59b43e04ad6965f34319062b478f83dd';
//
// $default = [
-// 'access_key' => getenv('ACCESS_TOKEN'),
+// 'access_key' => getAccessToken()
// 'actionKey' => 'appkey',
// 'appkey' => $appkey,
// 'build' => 101800,
@@ -45,17 +45,17 @@ class Sign
* @param $payload
* @return array
*/
- public static function login($payload)
+ public static function login($payload): array
{
# Android 新
$appkey = 'bca7e84c2d947ac6';
$appsecret = '60698ba2f68e01ce44738920a0ffe768';
$default = [
- 'access_key' => getenv('ACCESS_TOKEN'),
+ 'access_key' => getAccessToken(),
'actionKey' => 'appkey',
'appkey' => $appkey,
- 'build' => 6205500,
+ 'build' => 6320200,
'channel' => 'bili',
'device' => 'phone',
'mobi_app' => 'android',
@@ -71,7 +71,7 @@ class Sign
* @param $payload
* @return array
*/
- public static function common($payload)
+ public static function common($payload): array
{
# iOS 6680
// $appkey = '27eb53fc9058f8c3';
@@ -81,11 +81,11 @@ class Sign
$appsecret = '560c52ccd288fed045859ed18bffd973';
$default = [
- 'access_key' => getenv('ACCESS_TOKEN'),
+ 'access_key' => getAccessToken(),
'actionKey' => 'appkey',
'appkey' => $appkey,
- 'build' => 6205500,
- 'device' => 'android',
+ 'build' => 6320200,
+ 'device' => 'phone',
'mobi_app' => 'android',
'platform' => 'android',
'ts' => time(),
diff --git a/src/plugin/Silver2Coin.php b/src/plugin/Silver2Coin.php
index 64a3a9c..89d587f 100644
--- a/src/plugin/Silver2Coin.php
+++ b/src/plugin/Silver2Coin.php
@@ -20,17 +20,17 @@ class Silver2Coin
public static function run()
{
- if (self::getLock() > time() || getenv('USE_SILVER2COIN') == 'false') {
+ if (self::getLock() > time() || !getEnable('silver2coin')) {
return;
}
if (self::appSilver2coin() && self::pcSilver2coin()) {
- self::setLock(self::timing(10));
+ // 定时10点 + 1-60分钟随机
+ self::setLock(self::timing(10, 0, 0, true));
return;
}
self::setLock(3600);
}
-
/**
* @use app兑换
* @return bool
@@ -40,20 +40,12 @@ class Silver2Coin
sleep(0.5);
$url = 'https://api.live.bilibili.com/AppExchange/silver2coin';
$payload = [];
- $raw = Curl::get('app', $url, Sign::common($payload));
+ $raw = Curl::post('app', $url, Sign::common($payload));
$de_raw = json_decode($raw, true);
- if (!$de_raw['code'] && $de_raw['msg'] == '兑换成功') {
- Log::info('[APP]银瓜子兑换硬币: ' . $de_raw['msg']);
- } elseif ($de_raw['code'] == 403) {
- Log::warning('[APP]银瓜子兑换硬币: ' . $de_raw['msg']);
- } else {
- Log::warning('[APP]银瓜子兑换硬币: ' . $de_raw['msg']);
- return false;
- }
- return true;
- }
+ return self::handle('APP', $de_raw);
+ }
/**
* @use pc兑换
@@ -62,16 +54,42 @@ class Silver2Coin
protected static function pcSilver2coin(): bool
{
sleep(0.5);
- $payload = [];
- $url = "https://api.live.bilibili.com/exchange/silver2coin";
- $url = "https://api.live.bilibili.com/pay/v1/Exchange/silver2coin";
-
- $raw = Curl::get('pc', $url, $payload);
+ $payload = [
+ 'csrf_token' => getCsrf(),
+ 'csrf' => getCsrf(),
+ 'visit_id' => ''
+ ];
+ // $url = "https://api.live.bilibili.com/exchange/silver2coin";
+ // $url = "https://api.live.bilibili.com/pay/v1/Exchange/silver2coin";
+ $url = "https://api.live.bilibili.com/xlive/revenue/v1/wallet/silver2coin";
+ $raw = Curl::post('pc', $url, $payload);
$de_raw = json_decode($raw, true);
- if ($de_raw['code'] == -403) {
- return false;
+
+ return self::handle('PC', $de_raw);
+ }
+
+ /**
+ * @use 处理结果
+ * @param string $type
+ * @param array $data
+ * @return bool
+ */
+ private static function handle(string $type, array $data): bool
+ {
+ // {"code":403,"msg":"每天最多能兑换 1 个","message":"每天最多能兑换 1 个","data":[]}
+ // {"code":403,"msg":"仅主站正式会员以上的用户可以兑换","message":"仅主站正式会员以上的用户可以兑换","data":[]}
+ // {"code":0,"msg":"兑换成功","message":"兑换成功","data":{"gold":"5074","silver":"36734","tid":"727ab65376a15a6b117cf560a20a21122334","coin":1}}
+ // {"code":0,"data":{"coin":1,"gold":1234,"silver":4321,"tid":"Silver2Coin21062316490299678123456"},"message":"兑换成功"}
+ switch ($data['code']) {
+ case 0:
+ Log::notice("[{$type}] 银瓜子兑换硬币: {$data['message']}");
+ return true;
+ case 403:
+ Log::warning("[{$type}] 银瓜子兑换硬币: {$data['message']}");
+ return true;
+ default:
+ Log::warning("[{$type}] 银瓜子兑换硬币: CODE -> {$data['code']} MSG -> {$data['message']} ");
+ return false;
}
- Log::info('[PC]银瓜子兑换硬币: ' . $de_raw['msg']);
- return true;
}
}
\ No newline at end of file
diff --git a/src/plugin/SmallHeart.php b/src/plugin/SmallHeart.php
index 328d5fa..fcdc911 100644
--- a/src/plugin/SmallHeart.php
+++ b/src/plugin/SmallHeart.php
@@ -10,7 +10,6 @@
namespace BiliHelper\Plugin;
-
use BiliHelper\Util\TimeLock;
use BiliHelper\Util\XliveHeartBeat;
@@ -19,9 +18,7 @@ class SmallHeart
use TimeLock;
use XliveHeartBeat;
-
private static $fans_medals = []; // 全部勋章
- private static $grey_fans_medals = []; // 灰色勋章
private static $metal_lock = 0; // 勋章时间锁
private static $interval = 60; // 每次跳动时间
private static $total_time = 0;
@@ -29,13 +26,12 @@ class SmallHeart
public static function run()
{
- if (getenv('USE_HEARTBEAT') == 'false') {
+ if (!getEnable('small_heart')) {
return;
}
-
if (self::$metal_lock < time()) {
- self::polishMetal();
- self::$metal_lock = time() + 8 * 60 * 60;
+ self::fetchMedalList();
+ self::$metal_lock = time() + 12 * 60 * 60;
}
if (self::getLock() < time()) {
self::heartBeat();
@@ -49,35 +45,6 @@ class SmallHeart
}
}
-
- /**
- * @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 心跳处理
*/
@@ -86,7 +53,7 @@ class SmallHeart
if (empty(self::$fans_medals)) {
return;
}
- if (is_null(self::$metal)){
+ if (is_null(self::$metal)) {
self::$metal = self::$fans_medals[array_rand(self::$fans_medals)];
}
$interval = self::xliveHeartBeatTask(self::$metal['roomid'], 999, 999);
@@ -96,31 +63,22 @@ class SmallHeart
self::$interval = $interval == 0 ? 60 : $interval;
}
-
/**
* @use 获取灰色勋章列表(过滤无勋章或已满)
*/
- private static function fetchGreyMedalList()
+ private static function fetchMedalList()
{
$data = Live::fetchMedalList();
- $user_info = User::parseCookies();
foreach ($data as $vo) {
// 过滤主站勋章
if (!isset($vo['roomid'])) continue;
// 过滤自己勋章
- if ($vo['target_id'] == $user_info['uid']) continue;
+ if ($vo['target_id'] == getUid()) 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'],
- ];
- }
}
}
diff --git a/src/plugin/Statistics.php b/src/plugin/Statistics.php
index 594014c..3701bfa 100644
--- a/src/plugin/Statistics.php
+++ b/src/plugin/Statistics.php
@@ -14,7 +14,6 @@ use BiliHelper\Core\Log;
use BiliHelper\Util\TimeLock;
use MathieuViossat\Util\ArrayToTextTable;
-
class Statistics
{
use TimeLock;
@@ -24,18 +23,16 @@ class Statistics
private static $success_list = [];
private static $profit_list = [];
- // TODO 统计开关 统计时间间隔 统计类型
+ // Todo 统计开关 统计时间间隔 统计类型
public static function run()
{
if (self::getLock() > time()) {
return;
}
self::outputResult();
-
self::setLock(20 * 60);
}
-
/**
* @use 添加推送
* @param string $key
@@ -49,7 +46,6 @@ class Statistics
return true;
}
-
/**
* @use 添加参与
* @param string $key
@@ -63,7 +59,6 @@ class Statistics
return true;
}
-
/**
* @use 添加成功
* @param string $key
@@ -77,7 +72,6 @@ class Statistics
return true;
}
-
/**
* @use 添加收益
* @param string $title
@@ -94,7 +88,6 @@ class Statistics
return true;
}
-
/**
* @use 转换时间
* @param int $the_time
@@ -142,7 +135,6 @@ class Statistics
return true;
}
-
/**
* @use 获取结果
* @param array $target
@@ -156,7 +148,6 @@ class Statistics
return is_null($second_key) ? $target[self::getTodayKey()][$key] : $target[self::getTodayKey()][$key][$second_key];
}
-
/**
* @use 获取所有结果
* @param array $target
@@ -164,7 +155,7 @@ class Statistics
* @param string $second_key
* @return int
*/
- private static function getResults(array &$target, string $key, $second_key = null)
+ private static function getResults(array &$target, string $key, $second_key = null): int
{
$results = 0;
is_null($second_key) ? self::initKeyValue($target, $key) : self::initKeyValue($target, $key, 0, $second_key);
@@ -177,7 +168,6 @@ class Statistics
return $results;
}
-
/**
* @use 变量增加
* @param array $target
@@ -186,13 +176,12 @@ class Statistics
* @param null $second_key
* @return bool
*/
- private static function valIncrease(array &$target, string $key, $num = 1, $second_key = null)
+ private static function valIncrease(array &$target, string $key, $num = 1, $second_key = null): bool
{
is_null($second_key) ? $target[self::getTodayKey()][$key] += $num : $target[self::getTodayKey()][$key][$second_key] += $num;
return true;
}
-
/**
* @use 变量替换
* @param array $target
@@ -201,7 +190,7 @@ class Statistics
* @param string $second_key
* @return bool
*/
- private static function valReplace(array &$target, string $key, $data = null, $second_key = '')
+ private static function valReplace(array &$target, string $key, $data = null, $second_key = ''): bool
{
is_null($second_key) ? $target[self::getTodayKey()][$key] = $data : $target[self::getTodayKey()][$key][$second_key] = $data;
return true;
@@ -242,10 +231,9 @@ class Statistics
return [self::unique_arr($tr_list_count), self::unique_arr($tr_list_profit)];
}
-
/**
* @use 二维数组去重
- * @param $result
+ * @param array $result
* @return array
*/
private static function unique_arr(array $result): array
diff --git a/src/plugin/StormRaffle.php b/src/plugin/StormRaffle.php
index ab239f1..2fa1a6b 100644
--- a/src/plugin/StormRaffle.php
+++ b/src/plugin/StormRaffle.php
@@ -12,13 +12,12 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log;
use BiliHelper\Core\Curl;
-use BiliHelper\Util\TimeLock;
use BiliHelper\Util\BaseRaffle;
class StormRaffle extends BaseRaffle
{
const ACTIVE_TITLE = '节奏风暴';
- const ACTIVE_SWITCH = 'USE_STORM';
+ const ACTIVE_SWITCH = 'live_storm';
protected static $wait_list = [];
protected static $finish_list = [];
@@ -27,7 +26,6 @@ class StormRaffle extends BaseRaffle
private static $drop_rate = null;
private static $attempt = null;
-
/**
* @use 解析数据
* @param int $room_id
@@ -49,7 +47,7 @@ class StormRaffle extends BaseRaffle
return false;
}
// 过滤抽奖范围
- self::$drop_rate = getenv('STORM_DROPRATE') !== "" ? (int)getenv('STORM_DROPRATE') : 0;
+ self::$drop_rate = (int)getConf('drop_rate', 'live_storm');
if (mt_rand(1, 100) <= (int)self::$drop_rate) {
return false;
}
@@ -69,7 +67,6 @@ class StormRaffle extends BaseRaffle
return true;
}
-
/**
* 格式化日志输出
* @param $id
@@ -79,10 +76,9 @@ class StormRaffle extends BaseRaffle
*/
private static function formatInfo($id, $num, $info): string
{
- return "风暴 {$id} 请求 {$num} 状态 {$info}";
+ return "节奏风暴 {$id} 请求 {$num} 状态 {$info}";
}
-
/**
* @use 创建抽奖任务
* @param array $raffles
@@ -91,9 +87,8 @@ class StormRaffle extends BaseRaffle
protected static function createLottery(array $raffles): array
{
$url = 'https://api.live.bilibili.com/lottery/v1/Storm/join';
- $user_info = User::parseCookies();
foreach ($raffles as $raffle) {
- self::$attempt = getenv('STORM_ATTEMPT') !== "" ? explode(',', getenv('STORM_ATTEMPT')) : [30, 50];
+ self::$attempt = empty($attempt = getConf('attempt', 'live_storm')) ? [5, 10] : explode(',', $attempt);
$num = mt_rand((int)self::$attempt[0], (int)self::$attempt[1]);
$payload = [
'id' => $raffle['raffle_id'],
@@ -101,8 +96,8 @@ class StormRaffle extends BaseRaffle
"color" => "16772431",
"captcha_token" => "",
"captcha_phrase" => "",
- "token" => $user_info['token'],
- "csrf_token" => $user_info['token'],
+ "token" => getCsrf(),
+ "csrf_token" => getCsrf(),
"visit_id" => ""
];
for ($i = 1; $i < $num; $i++) {
@@ -158,7 +153,7 @@ class StormRaffle extends BaseRaffle
/**
* @use 解析抽奖信息
* @param array $results
- * @return mixed|void
+ * @return void
*/
protected static function parseLottery(array $results)
{
diff --git a/src/plugin/User.php b/src/plugin/User.php
index 21031d0..7e19641 100644
--- a/src/plugin/User.php
+++ b/src/plugin/User.php
@@ -11,7 +11,8 @@
namespace BiliHelper\Plugin;
use BiliHelper\Core\Curl;
-use BiliHelper\Core\Config;
+use BiliHelper\Core\Log;
+use BiliHelper\Tool\Common;
class User
{
@@ -32,7 +33,6 @@ class User
return true;
}
-
/**
* @use 老爷检测
* @return bool
@@ -48,25 +48,6 @@ class User
return false;
}
-
- /**
- * @use 写入用户名
- * @return bool
- */
- public static function userInfo(): bool
- {
- $data = self::getUserInfo();
- if (getenv('APP_UNAME') != "") {
- return true;
- }
- if ($data['msg'] == 'ok') {
- Config::put('APP_UNAME', $data['data']['uname']);
- return true;
- }
- return false;
- }
-
-
/**
* @use UserInfo
* @return array
@@ -75,7 +56,7 @@ class User
{
$url = 'https://api.live.bilibili.com/User/getUserInfo';
$payload = [
- 'ts' => Live::getMillisecond(),
+ 'ts' => Common::getMillisecond(),
];
$raw = Curl::get('app', $url, Sign::common($payload));
return json_decode($raw, true);
@@ -91,7 +72,7 @@ class User
{
$url = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByUser';
$payload = [
- 'room_id' => $room_id ?? getenv('ROOM_ID')
+ 'room_id' => $room_id ?? getConf('room_id', 'global_room')
];
$raw = Curl::get('pc', $url, $payload);
return json_decode($raw, true);
@@ -107,10 +88,10 @@ class User
{
$url = 'https://api.live.bilibili.com/xlive/app-room/v1/index/getInfoByUser';
$payload = [
- 'room_id' => $room_id ?? getenv('ROOM_ID')
+ 'room_id' => $room_id ?? getConf('room_id', 'global_room')
];
$raw = Curl::get('app', $url, Sign::common($payload));
- return json_decode($raw, true);;
+ return json_decode($raw, true);
}
/**
@@ -119,17 +100,14 @@ class User
*/
public static function parseCookies(): array
{
- $cookies = getenv('COOKIE');
+ $cookies = getCookie();
preg_match('/bili_jct=(.{32})/', $cookies, $token);
- $token = isset($token[1]) ? $token[1] : '';
preg_match('/DedeUserID=(\d+)/', $cookies, $uid);
- $uid = isset($uid[1]) ? $uid[1] : '';
preg_match('/DedeUserID__ckMd5=(.{16})/', $cookies, $sid);
- $sid = isset($sid[1]) ? $sid[1] : '';
return [
- 'token' => $token,
- 'uid' => $uid,
- 'sid' => $sid,
+ 'csrf' => $token[1] ?? '',
+ 'uid' => $uid[1] ?? '',
+ 'sid' => $sid[1] ?? '',
];
}
@@ -139,8 +117,7 @@ class User
*/
public static function fetchAllFollowings(): array
{
- $user_info = User::parseCookies();
- $uid = $user_info['uid'];
+ $uid = getUid();
$followings = [];
for ($i = 1; $i < 100; $i++) {
$url = "https://api.bilibili.com/x/relation/followings";
@@ -168,7 +145,6 @@ class User
return $followings;
}
-
/**
* @use 获取分组关注列表
* @param int $tag_id
@@ -178,8 +154,7 @@ class User
*/
public static function fetchTagFollowings(int $tag_id = 0, int $page_num = 100, int $page_size = 50): array
{
- $user_info = User::parseCookies();
- $uid = $user_info['uid'];
+ $uid = getUid();
$followings = [];
for ($i = 1; $i < $page_num; $i++) {
$url = "https://api.bilibili.com/x/relation/tag";
@@ -208,7 +183,6 @@ class User
return $followings;
}
-
/**
* @use 设置用户关注
* @param int $follow_uid
@@ -217,15 +191,14 @@ class User
*/
public static function setUserFollow(int $follow_uid, $un_follow = false): bool
{
- $user_info = User::parseCookies();
$url = 'https://api.live.bilibili.com/relation/v1/Feed/SetUserFollow';
$payload = [
- 'uid' => $user_info['uid'],
+ 'uid' => getUid(),
'type' => $un_follow ? 0 : 1,
'follow' => $follow_uid,
're_src' => 18,
- 'csrf_token' => $user_info['token'],
- 'csrf' => $user_info['token'],
+ 'csrf_token' => getCsrf(),
+ 'csrf' => getCsrf(),
'visit_id' => ''
];
$headers = [
@@ -248,11 +221,10 @@ class User
*/
public static function createRelationTag(string $tag_name): int
{
- $user_info = User::parseCookies();
$url = 'https://api.bilibili.com/x/relation/tag/create?cross_domain=true';
$payload = [
'tag' => $tag_name,
- 'csrf' => $user_info['token'],
+ 'csrf' => getCsrf(),
];
$headers = [
'content-type' => 'application/x-www-form-urlencoded; charset=UTF-8',
@@ -276,12 +248,11 @@ class User
*/
public static function tagAddUsers(int $fid, int $tid): bool
{
- $user_info = User::parseCookies();
$url = 'https://api.bilibili.com/x/relation/tags/addUsers?cross_domain=true';
$payload = [
'fids' => $fid,
'tagids' => $tid,
- 'csrf' => $user_info['token'],
+ 'csrf' => getCsrf(),
];
$headers = [
'content-type' => 'application/x-www-form-urlencoded; charset=UTF-8',
@@ -303,12 +274,11 @@ class User
*/
public static function fetchTags(): array
{
- $user_info = User::parseCookies();
$tags = [];
$url = 'https://api.bilibili.com/x/relation/tags';
$payload = [];
$headers = [
- 'referer' => "https://space.bilibili.com/{$user_info['uid']}/fans/follow",
+ 'referer' => 'https://space.bilibili.com/' . getUid() . '/fans/follow',
];
$raw = Curl::get('pc', $url, $payload, $headers);
$de_raw = json_decode($raw, true);
@@ -320,4 +290,51 @@ class User
return $tags;
}
+ /**
+ * @use 是否为有效年度大会员
+ * @return bool
+ */
+ public static function isYearVip(): bool
+ {
+ $url = 'https://api.bilibili.com/x/vip/web/user/info';
+ $headers = [
+ 'origin' => 'https://account.bilibili.com',
+ 'referer' => 'https://account.bilibili.com/account/home'
+ ];
+ $payload = [];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ // {"code":0,"message":"0","ttl":1,"data":{"mid":1234,"vip_type":2,"vip_status":1,"vip_due_date":1667750400000,"vip_pay_type":0,"theme_type":0,"label":{"text":"年度大会员","label_theme":"annual_vip","text_color":"#FFFFFF","bg_style":1,"bg_color":"#FB7299","border_color":""},"avatar_subscript":1,"avatar_subscript_url":"http://i0.hdslb.com/bfs/vip/icon_Certification_big_member_22_3x.png","nickname_color":"#FB7299","is_new_user":false}}
+ $de_raw = json_decode($raw, true);
+ if ($de_raw['code'] == 0) {
+ if ($de_raw['data']['vip_type'] == 2 && $de_raw['data']['vip_due_date'] > Common::getMillisecond()) {
+ Log::debug("获取会员成功 有效年度大会员");
+ return true;
+ }
+ Log::debug("获取会员成功 不是年度大会员或已过期");
+ } else {
+ Log::debug("获取会员信息失败 {$raw}");
+ }
+ return false;
+ }
+
+ /**
+ * @use 我的钱包
+ */
+ public static function myWallet()
+ {
+ $url = 'https://api.live.bilibili.com/pay/v2/Pay/myWallet';
+ $headers = [
+ 'origin' => 'https://link.bilibili.com',
+ 'referer' => 'https://link.bilibili.com/p/center/index'
+ ];
+ $payload = [
+ 'need_bp' => 1,
+ 'need_metal' => 1,
+ 'platform' => 'pc',
+ ];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ // {"code":0,"msg":"succ","message":"succ","data":{"gold":5074,"silver":37434,"bp":"0","metal":1904}}
+ $de_raw = json_decode($raw, true);
+ }
+
}
\ No newline at end of file
diff --git a/src/plugin/VipPrivilege.php b/src/plugin/VipPrivilege.php
new file mode 100644
index 0000000..30809f5
--- /dev/null
+++ b/src/plugin/VipPrivilege.php
@@ -0,0 +1,96 @@
+ '未知奖励',
+ 1 => 'B币劵',
+ 2 => '会员购优惠券'
+ ];
+
+ public static function run()
+ {
+ if (self::getLock() > time() || !getEnable('vip_privilege')) {
+ return;
+ }
+ // 如果为年度大会员
+ if (User::isYearVip()) {
+ $privilege_list = self::myVipPrivilege();
+ foreach ($privilege_list as $privilege) {
+ // 是否领取状态
+ if ($privilege['state'] != 0) {
+ continue;
+ }
+ // 领取奖励
+ self::myVipPrivilegeReceive($privilege['type']);
+ }
+ }
+ // 定时11点 + 随机120分钟
+ self::setLock(self::timing(11) + mt_rand(1, 120) * 60);
+ }
+
+ /**
+ * @use 领取我的大会员权益
+ * @param int $type
+ */
+ private static function myVipPrivilegeReceive(int $type)
+ {
+ $url = 'https://api.bilibili.com/x/vip/privilege/receive';
+ $headers = [
+ 'origin' => 'https://account.bilibili.com',
+ 'referer' => 'https://account.bilibili.com/account/big/myPackage',
+ ];
+ $payload = [
+ 'type' => $type,
+ 'csrf' => getCsrf(),
+ ];
+ $raw = Curl::post('pc', $url, $payload, $headers);
+ // {"code":0,"message":"0","ttl":1}
+ $de_raw = json_decode($raw, true);
+ if ($de_raw['code'] == 0) {
+ Log::notice('大会员权益 ' . self::$privilege[$type] . ' 领取成功');
+ } else {
+ Log::warning('大会员权益 ' . self::$privilege[$type] . " 领取失败, {$raw}");
+ }
+ }
+
+ /**
+ * @use 获取我的大会员权益列表
+ * @return array
+ */
+ private static function myVipPrivilege(): array
+ {
+ $url = 'https://api.bilibili.com/x/vip/privilege/my';
+ $headers = [
+ 'origin' => 'https://account.bilibili.com',
+ 'referer' => 'https://account.bilibili.com/account/big/myPackage',
+ ];
+ $payload = [];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ // {"code":0,"message":"0","ttl":1,"data":{"list":[{"type":1,"state":0,"expire_time":1622476799},{"type":2,"state":0,"expire_time":1622476799}]}}
+ $de_raw = json_decode($raw, true);
+ if ($de_raw['code'] == 0 && isset($de_raw['data']['list'])) {
+ Log::info('获取大会员权益列表成功');
+ return $de_raw['data']['list'];
+ } else {
+ Log::warning("获取大会员权益列表失败 {$raw}");
+ return [];
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/plugin/ZoneTcpClient.php b/src/plugin/ZoneTcpClient.php
index 2d6bc8c..555c998 100644
--- a/src/plugin/ZoneTcpClient.php
+++ b/src/plugin/ZoneTcpClient.php
@@ -39,7 +39,7 @@ class ZoneTcpClient
*/
public static function run()
{
- if (self::getLock() > time() || getenv('USE_ZONE_SERVER') == 'false') {
+ if (self::getLock() > time() || !getEnable('zone_monitor')) {
return;
}
self::setPauseStatus();
@@ -50,13 +50,12 @@ class ZoneTcpClient
self::pushHandle();
}
-
/**
* @use 初始化
*/
private static function init()
{
- if (empty(getenv('ZONE_SERVER_ADDR'))) {
+ if (empty(getConf('server_addr', 'zone_monitor'))) {
exit('推送服务器信息不完整, 请检查配置文件!');
}
if (!self::$client) {
@@ -79,7 +78,6 @@ class ZoneTcpClient
}
}
-
/**
* @use 触发重连
* @param array $area_data
@@ -166,14 +164,13 @@ class ZoneTcpClient
return false;
}
-
/**
* @use 响应数据
* @param $msg
* @param $type
* @return bool
*/
- private static function onMessage($msg, $type)
+ private static function onMessage($msg, $type): bool
{
// 心跳后回复人气
if ($type == 3) {
@@ -359,9 +356,9 @@ class ZoneTcpClient
Log::info("监测到 @分区 {$data['area_id']} @房间 {$data['room_id']} @抽奖 {$data['raffle_title']}");
// print_r($data);
}
+ return true;
}
-
/**
* @推送到上游处理
*/
@@ -387,12 +384,11 @@ class ZoneTcpClient
{
}
-
/**
* @use 发送握手包
* @return bool
*/
- private static function sendHandShake()
+ private static function sendHandShake(): bool
{
return self::writer(self::genHandshakePkg(self::$room_id));
}
@@ -406,7 +402,6 @@ class ZoneTcpClient
return self::packMsg('', 0x0002);
}
-
/**
* @use 握手包
* @param $room_id
@@ -431,17 +426,16 @@ class ZoneTcpClient
* @param $option
* @return string
*/
- private static function packMsg($value, $option)
+ private static function packMsg($value, $option): string
{
$head = pack('NnnNN', 0x10 + strlen($value), 0x10, 0x01, $option, 0x0001);
return $head . $value;
}
-
/**
* @use 解包数据
* @param $value
- * @return int|mixed
+ * @return array|false
*/
private static function unPackMsg($value)
{
@@ -449,12 +443,10 @@ class ZoneTcpClient
Log::warning("unPackMsg: 包头异常 " . strlen($value));
return [];
};
- $head = unpack('Npacklen/nheadlen/nver/Nop/Nseq', $value);
// Log::info(json_encode($head, true));
- return $head;
+ return unpack('Npacklen/nheadlen/nver/Nop/Nseq', $value);
}
-
/**
* @use 心跳
*/
@@ -479,10 +471,10 @@ class ZoneTcpClient
/**
* @use 读数据
* @param $length
- * @param $is_header
- * @return array|bool|false
+ * @param bool $is_header
+ * @return array|bool
*/
- private static function reader($length, $is_header = false)
+ private static function reader($length, bool $is_header = false)
{
$data = false;
try {
@@ -507,7 +499,7 @@ class ZoneTcpClient
break;
Log::debug("Socket debug: select timeout" . PHP_EOL);
}
- // TODO unable to read from socket[104]: Connection reset by peer
+ // Todo unable to read from socket[104]: Connection reset by peer
$ret = socket_recv($socket, $buffer, $length, 0);
if ($ret < 1) {
Log::warning("Socket error: [{$ret}] [{$length}]" . PHP_EOL);
@@ -534,7 +526,7 @@ class ZoneTcpClient
* @param $data
* @return bool
*/
- private static function writer($data)
+ private static function writer($data): bool
{
$status = false;
try {
@@ -551,7 +543,6 @@ class ZoneTcpClient
return $status;
}
-
/**
* @use 读取数据
*/
@@ -570,8 +561,8 @@ class ZoneTcpClient
// 长度为0 ,空信息
continue;
}
- $length = isset($head['packlen']) ? $head['packlen'] : 16;
- $type = isset($head['op']) ? $head['op'] : 0x0000;
+ $length = $head['packlen'] ?? 16;
+ $type = $head['op'] ?? 0x0000;
$len_body = $length - 16;
Log::debug("(AreaId={$client_info['area_id']} -> RoomId={$client_info['room_id']} -> Len={$len_body})");
if (!$len_body)
@@ -590,7 +581,13 @@ class ZoneTcpClient
}
}
- private static function v2_split($bin, $total)
+ /**
+ * @use V2切割
+ * @param $bin
+ * @param $total
+ * @return array
+ */
+ private static function v2_split($bin, $total): array
{
$list = [];
$step = 0;
@@ -604,7 +601,7 @@ class ZoneTcpClient
if ($step == $total) break;
$bin = substr($data, $step, 16);
$head = self::unPackMsg($bin);
- $length = isset($head['packlen']) ? $head['packlen'] : 16;
+ $length = $head['packlen'] ?? 16;
$body = substr($data, $step + 16, $length - 16);
$step += $length;
array_push($list, $body);
@@ -612,12 +609,20 @@ class ZoneTcpClient
return $list;
}
+ /**
+ * @param $object
+ * @return string
+ */
private static function getClass($object): string
{
$class = \get_class($object);
return 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class) . '@anonymous' : $class;
}
+ /**
+ * @param $e
+ * @return string
+ */
private static function formatErr($e): string
{
return sprintf('Uncaught Exception %s: "%s" at %s line %s', self::getClass($e), $e->getMessage(), $e->getFile(), $e->getLine());
@@ -626,7 +631,7 @@ class ZoneTcpClient
/*
* @use replace delay by select
*/
- public static function Delayed()
+ public static function Delayed(): Delayed
{
$r = [];
$w = NULL;
diff --git a/src/script/BaseTask.php b/src/script/BaseTask.php
new file mode 100644
index 0000000..407c479
--- /dev/null
+++ b/src/script/BaseTask.php
@@ -0,0 +1,63 @@
+choice('Select', $options, $default, true);
+ static::interactor()->greenBold("You selected: {$options[$option]}", true);
+ // return $options[$option];
+ return $option;
+ }
+
+ /**
+ * @use 确认
+ * @param string $msg
+ * @param string $default
+ * @return bool
+ */
+ public static function confirm(string $msg, string $default = 'n'): bool
+ {
+ $confirm = static::interactor()->confirm($msg, $default); // Default: n (no)
+ if (!$confirm) die();
+// if ($confirm) { // is a boolean
+// static::interactor()->greenBold('是 :)', true); // Output green bold text
+// } else {
+// static::interactor()->redBold('否 :(', true); // Output red bold text
+// die();
+// }
+ return true;
+ }
+
+ /**
+ * @return \Ahc\Cli\IO\Interactor
+ */
+ public static function interactor(): Interactor
+ {
+ return static::$interactor ?? static::$interactor = new Interactor;
+ }
+}
\ No newline at end of file
diff --git a/src/script/DelDynamic.php b/src/script/DelDynamic.php
new file mode 100644
index 0000000..b12c5d7
--- /dev/null
+++ b/src/script/DelDynamic.php
@@ -0,0 +1,22 @@
+ $up_uname) {
+ $payload = [
+ 'fid' => $up_uid,
+ 'act' => 2,
+ 're_src' => 11,
+ 'csrf' => getCsrf(),
+ ];
+ $headers = [
+ 'origin' => 'https://space.bilibili.com',
+ 'referer' => 'https://space.bilibili.com/' . getUid() . '/fans/follow?tagid=' . $tag_id,
+ ];
+ $raw = Curl::post('pc', $url, $payload, $headers);
+ // {"code":0,"message":"0","ttl":1}
+ $data = json_decode($raw, true);
+ if ($data['code'] == 0) {
+ Log::notice("UP.{$up_uid} - {$up_uname} 取关成功");
+ } else {
+ Log::error("UP.{$up_uid} - {$up_uname} 取关失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
+ break;
+ }
+ sleep(random_int(5, 10));
+ }
+ }
+
+
+ /**
+ * @use 获取分组关注
+ * @param $tag_id
+ * @param int $max_pn
+ * @param int $max_ps
+ * @return array
+ * @throws \Exception
+ */
+ private static function relationTag($tag_id, int $max_pn = 30, int $max_ps = 20): array
+ {
+ $following = [];
+ $url = 'https://api.bilibili.com/x/relation/tag';
+ for ($pn = 1; $pn <= $max_pn; $pn++) {
+ $payload = [
+ 'mid' => getUid(),
+ 'tagid' => $tag_id,
+ 'pn' => $pn,
+ 'ps' => $max_ps,
+ ];
+ $headers = [
+ 'referer' => 'https://space.bilibili.com/' . getUid() . '/fans/follow',
+ ];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ $data = json_decode($raw, true);
+ if ($data['code'] == 0 && isset($data['data'])) {
+ // 循环添加到 following
+ foreach ($data['data'] as $up) {
+ $following[$up['mid']] = $up['uname'];
+ }
+ // 打印和延迟
+ Log::info("已获取分组 {$tag_id} 页码 {$pn}");
+ sleep(random_int(4, 8));
+ // 如果页面不等于 max_ps 跳出
+ if (count($data['data']) != $max_ps) {
+ break;
+ }
+ } else {
+ Log::error("获取分组关注失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
+ break;
+ }
+ }
+ $following_num = count($following);
+ Log::notice("已获取分组 {$tag_id} 有效关注数 {$following_num}");
+ return $following;
+ }
+
+
+ /**
+ * @use 获取分组
+ * @return mixed
+ */
+ private static function relationTags()
+ {
+ $url = 'https://api.bilibili.com/x/relation/tags';
+ $payload = [];
+ $headers = [
+ 'referer' => 'https://space.bilibili.com/',
+ ];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ $data = json_decode($raw, true);
+ if ($data['code'] == 0 && isset($data['data'])) {
+ $options = [];
+ foreach ($data['data'] as $tag) {
+ $options[$tag['tagid']] = "分组:{$tag['name']} - 关注数:{$tag['count']}";
+ }
+ $option = self::choice($options);
+ Log::notice("已获取分组 {$option} - {$options[$option]}");
+ return $option;
+ } else {
+ Log::error("获取关注分组失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
+ die();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/script/User.php b/src/script/User.php
new file mode 100644
index 0000000..4036c42
--- /dev/null
+++ b/src/script/User.php
@@ -0,0 +1,57 @@
+ {$data['code']} MSG -> {$data['message']} ");
+ die();
+ }
+ return true;
+ }
+
+ /**
+ * @use 用户
+ * @return mixed
+ */
+ public static function userInfo()
+ {
+ $url = 'https://api.bilibili.com/x/web-interface/nav';
+ $payload = [];
+ $headers = [
+ 'origin' => 'https://space.bilibili.com',
+ 'referer' => 'https://space.bilibili.com/' . getUid(),
+ ];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ return json_decode($raw, true);
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/tool/BvToAv.php b/src/tool/BvToAv.php
index 64f740d..953f367 100644
--- a/src/tool/BvToAv.php
+++ b/src/tool/BvToAv.php
@@ -20,11 +20,11 @@ class BvToAv
protected $add = 8728348608;
protected $s = [11, 10, 3, 8, 4, 6];
+
/**
- * BV 转 AV
- *
+ * @use BV 转 AV
* @param $bv
- * @return int
+ * @return int|string
*/
public function dec($bv)
{
@@ -36,14 +36,13 @@ class BvToAv
return ($r - $this->add) ^ $this->xor;
}
+
/**
- *
- * AV 转 BV
- *
+ * @use AV 转 BV
* @param $av
* @return string
*/
- public function enc($av)
+ public function enc($av): string
{
$tr = str_split($this->tr);
$bv = 'BV1 4 1 7 ';
diff --git a/src/tool/Common.php b/src/tool/Common.php
index 0738cd4..09c2b36 100644
--- a/src/tool/Common.php
+++ b/src/tool/Common.php
@@ -12,6 +12,33 @@ namespace BiliHelper\Tool;
class Common
{
+
+ /**
+ * @use 获取十三位时间戳
+ * @return int
+ */
+ public static function getMillisecond(): int
+ {
+ list($t1, $t2) = explode(' ', microtime());
+ // return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
+ return intval(sprintf('%u', (floatval($t1) + floatval($t2)) * 1000));
+ }
+
+ /**
+ * @use 获取当月第一天及最后一天
+ * $day[0] 第一天
+ * $day[1] 最后一天
+ * @return array
+ */
+ public static function getTheMonth(): array
+ {
+ $today = date("Y-m-d");
+ $first_day = date('Y-m-01', strtotime($today));
+ $last_day = date('Y-m-d', strtotime("$first_day +1 month -1 day"));
+ return array($first_day, $last_day);
+ }
+
+
/**
* @use 替换字符串
* @param $str
@@ -21,7 +48,7 @@ class Common
* @param string $charset
* @return string
*/
- public static function replaceStar($str, $start, $end = 0, $dot = "*", $charset = "UTF-8")
+ public static function replaceStar($str, $start, $end = 0, $dot = "*", $charset = "UTF-8"): string
{
$len = mb_strlen($str, $charset);
if ($start == 0 || $start > $len) {
@@ -39,9 +66,7 @@ class Common
$len = $len - mb_strlen($top, $charset);
$len = $len - mb_strlen($bottom, $charset);
$newStr = $top;
- for ($i = 0; $i < $len; $i++) {
- $newStr .= $dot;
- }
+ $newStr .= str_repeat($dot, $len);
$newStr .= $bottom;
return $newStr;
}
diff --git a/src/tool/DumpMemory.php b/src/tool/DumpMemory.php
index a5615d4..776721c 100644
--- a/src/tool/DumpMemory.php
+++ b/src/tool/DumpMemory.php
@@ -12,7 +12,6 @@
namespace BiliHelper\Tool;
use BiliHelper\Core\Log;
-use BiliHelper\Core\Curl;
class DumpMemory
{
diff --git a/src/tool/Faker.php b/src/tool/Faker.php
index d1e7c41..63d1775 100644
--- a/src/tool/Faker.php
+++ b/src/tool/Faker.php
@@ -22,7 +22,7 @@ class Faker
* @example 79907610
*
*/
- public static function numberBetween($int1 = 0, $int2 = 2147483647)
+ public static function numberBetween($int1 = 0, $int2 = 2147483647): int
{
$min = $int1 < $int2 ? $int1 : $int2;
$max = $int1 < $int2 ? $int2 : $int1;
@@ -36,7 +36,7 @@ class Faker
* @param int $except
* @return int
*/
- public static function randomDigitNot($except)
+ public static function randomDigitNot($except): int
{
$result = self::numberBetween(0, 8);
if ($result >= $except) {
@@ -53,7 +53,7 @@ class Faker
* @param string $string String that needs to bet parsed
* @return string
*/
- public static function asciify($string = '****')
+ public static function asciify($string = '****'): string
{
return preg_replace_callback('/\*/u', 'static::randomAscii', $string);
}
@@ -62,7 +62,7 @@ class Faker
/**
* @example 'fY4èHdZv68'
*/
- public function password($minLength = 6, $maxLength = 20)
+ public function password($minLength = 6, $maxLength = 20): string
{
$pattern = str_repeat('*', $this->numberBetween($minLength, $maxLength));
@@ -81,7 +81,7 @@ class Faker
/**
* @example '35cd:186d:3e23:2986:ef9f:5b41:42a4:e6f1'
*/
- public function ipv6()
+ public function ipv6(): string
{
$res = array();
for ($i = 0; $i < 8; $i++) {
@@ -108,7 +108,7 @@ class Faker
/**
* @example '32:F1:39:2F:D6:18'
*/
- public static function macAddress()
+ public static function macAddress(): string
{
for ($i = 0; $i < 6; $i++) {
$mac[] = sprintf('%02X', static::numberBetween(0, 0xff));
@@ -118,6 +118,11 @@ class Faker
return $mac;
}
+ /**
+ * @use 转Ascii
+ * @param $string
+ * @return array|string|string[]
+ */
protected static function toAscii($string)
{
static $arrayFrom, $arrayTo;
diff --git a/src/tool/File.php b/src/tool/File.php
index 30abcb8..9e24040 100644
--- a/src/tool/File.php
+++ b/src/tool/File.php
@@ -11,11 +11,9 @@
namespace BiliHelper\Tool;
-
class File
{
-
/**
* @use 创建文件
* @param string $filename
diff --git a/src/tool/Generator.php b/src/tool/Generator.php
index 3c5a65b..8d7414b 100644
--- a/src/tool/Generator.php
+++ b/src/tool/Generator.php
@@ -11,7 +11,6 @@
namespace BiliHelper\Tool;
-
class Generator
{
/**
@@ -53,7 +52,8 @@ class Generator
* @use 生成BUVID
* @return string
*/
- public static function buvid():string{
+ public static function buvid(): string
+ {
// XYD5B85DA7212341F51C612344A6B8C6C21234
$mac = Faker::macAddress();
$md5 = md5($mac);
@@ -61,4 +61,28 @@ class Generator
return strtoupper("XY{$md5_arr[2]}{$md5_arr[12]}{$md5_arr[22]}{$md5}");
}
+ /**
+ * @use 获取颜文字信息
+ * @return string
+ */
+ public static function emoji(): string
+ {
+ $emoji_list_all = [
+ "(⌒▽⌒)", "( ̄▽ ̄)", "(=・ω・=)", "(`・ω・´)", "(〜 ̄△ ̄)〜", "(・∀・)",
+ "(°∀°)ノ", "( ̄3 ̄)", "╮( ̄▽ ̄)╭", "_(:3」∠)_", "( ´_ゝ`)", "←_←", "→_→",
+ "(<_<)", "(>_>)", "(;¬_¬)", '("▔□▔)/', "(゚Д゚≡゚д゚)!?", "Σ(゚д゚;)", "Σ(  ̄□ ̄||)",
+ "(´;ω;`)", "(/TДT)/", "(^・ω・^ )", "(。・ω・。)", "(● ̄(エ) ̄●)", "ε=ε=(ノ≧∇≦)ノ",
+ "(´・_・`)", "(-_-#)", "( ̄へ ̄)", "( ̄ε(# ̄) Σ", "ヽ(`Д´)ノ", "(#-_-)┯━┯",
+ "(╯°口°)╯(┴—┴", "←◡←", "( ♥д♥)", "Σ>―(〃°ω°〃)♡→", "⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
+ "(╬゚д゚)▄︻┻┳═一", "・*・:≡( ε:)", "(打卡)", "(签到)"
+ ];
+ $emoji_list = [
+ "(⌒▽⌒)", "( ̄▽ ̄)", "(=・ω・=)", "(`・ω・´)", "(〜 ̄△ ̄)〜",
+ "╮( ̄▽ ̄)╭", "_(:3」∠)_", "( ´_ゝ`)", "(● ̄(エ) ̄●)", "(・∀・)",
+ "(´・_・`)", "( ̄へ ̄)", "(打卡)", "(签到)"
+ ];
+ shuffle($emoji_list);
+ return $emoji_list[array_rand($emoji_list)];
+ }
+
}
diff --git a/src/tool/UserAgent.php b/src/tool/UserAgent.php
new file mode 100644
index 0000000..30f011f
--- /dev/null
+++ b/src/tool/UserAgent.php
@@ -0,0 +1,401 @@
+ [
+ 'GT-I9:number2-5:00 Build/JDQ39',
+ 'Nokia 3:number1-3:[10|15] Build/IMM76D',
+ '[SAMSUNG |]SM-G3:number1-5:0[R5|I|V|A|T|S] Build/JLS36C',
+ 'Ascend G3:number0-3:0 Build/JLS36I',
+ '[SAMSUNG |]SM-G3:number3-6::number1-8::number0-9:[V|A|T|S|I|R5] Build/JLS36C',
+ 'HUAWEI G6-L:number10-11: Build/HuaweiG6-L:number10-11:',
+ '[SAMSUNG |]SM-[G|N]:number7-9:1:number0-8:[S|A|V|T] Build/[JLS36C|JSS15J]',
+ '[SAMSUNG |]SGH-N0:number6-9:5[T|V|A|S] Build/JSS15J',
+ 'Samsung Galaxy S[4|IV] Mega GT-I:number89-95:00 Build/JDQ39',
+ 'SAMSUNG SM-T:number24-28:5[s|a|t|v] Build/[JLS36C|JSS15J]',
+ 'HP :number63-73:5 Notebook PC Build/[JLS36C|JSS15J]',
+ 'HP Compaq 2:number1-3:10b Build/[JLS36C|JSS15J]',
+ 'HTC One 801[s|e] Build/[JLS36C|JSS15J]',
+ 'HTC One max Build/[JLS36C|JSS15J]',
+ 'HTC Xplorer A:number28-34:0[e|s] Build/GRJ90'
+ ],
+ '4.4' => [
+ 'XT10:number5-8:0 Build/SU6-7.3',
+ 'XT10:number12-52: Build/[KXB20.9|KXC21.5]',
+ 'Nokia :number30-34:10 Build/IMM76D',
+ 'E:number:20-23::number0-3::number0-4: Build/24.0.[A|B].1.34',
+ '[SAMSUNG |]SM-E500[F|L] Build/KTU84P',
+ 'LG Optimus G Build/KRT16M',
+ 'LG-E98:number7-9: Build/KOT49I',
+ 'Elephone P:number2-6:000 Build/KTU84P',
+ 'IQ450:number0-4: Quad Build/KOT49H',
+ 'LG-F:number2-5:00[K|S|L] Build/KOT49[I|H]',
+ 'LG-V:number3-7::number0-1:0 Build/KOT49I',
+ '[SAMSUNG |]SM-J:number1-2::number0-1:0[G|F] Build/KTU84P',
+ '[SAMSUNG |]SM-N80:number0-1:0 Build/[KVT49L|JZO54K]',
+ '[SAMSUNG |]SM-N900:number5-8: Build/KOT49H',
+ '[SAMSUNG-|]SGH-I337[|M] Build/[JSS15J|KOT49H]',
+ '[SAMSUNG |]SM-G900[W8|9D|FD|H|V|FG|A|T] Build/KOT49H',
+ '[SAMSUNG |]SM-T5:number30-35: Build/[KOT49H|KTU84P]',
+ '[Google |]Nexus :number5-7: Build/KOT49H',
+ 'LG-H2:number0-2:0 Build/KOT49[I|H]',
+ 'HTC One[_M8|_M9|0P6B|801e|809d|0P8B2|mini 2|S][ dual sim|] Build/[KOT49H|KTU84L]',
+ '[SAMSUNG |]GT-I9:number3-5:0:number0-6:[V|I|T|N] Build/KOT49H',
+ 'Lenovo P7:number7-8::number1-6: Build/[Lenovo|JRO03C]',
+ 'LG-D95:number1-8: Build/KOT49[I|H]',
+ 'LG-D:number1-8::number0-8:0 Build/KOT49[I|H]',
+ 'Nexus5 V:number6-7:.1 Build/KOT49H',
+ 'Nexus[_|] :number4-10: Build/[KOT49H|KTU84P]',
+ 'Nexus[_S_| S ][4G |]Build/GRJ22',
+ '[HM NOTE|NOTE-III|NOTE2 1LTE[TD|W|T]',
+ 'ALCATEL ONE[| ]TOUCH 70:number2-4::number0-9:[X|D|E|A] Build/KOT49H',
+ 'MOTOROLA [MOTOG|MSM8960|RAZR] Build/KVT49L'
+ ],
+ '5.0' => [
+ 'Nokia :number10-11:00 [wifi|4G|LTE] Build/GRK39F',
+ 'HTC 80:number1-2[s|w|e|t] Build/[LRX22G|JSS15J]',
+ 'Lenovo A7000-a Build/LRX21M;',
+ 'HTC Butterfly S [901|919][s|d|] Build/LRX22G',
+ 'HTC [M8|M9|M8 Pro Build/LRX22G',
+ 'LG-D3:number25-37: Build/LRX22G',
+ 'LG-D72:number0-9: Build/LRX22G',
+ '[SAMSUNG |]SM-G4:number0-9:0 Build/LRX22[G|C]',
+ '[|SAMSUNG ]SM-G9[00|25|20][FD|8|F|F-ORANGE|FG|FQ|H|I|L|M|S|T] Build/[LRX21T|KTU84F|KOT49H]',
+ '[SAMSUNG |]SM-A:number7-8:00[F|I|T|H|] Build/[LRX22G|LMY47X]',
+ '[SAMSUNG-|]SM-N91[0|5][A|V|F|G|FY] Build/LRX22C',
+ '[SAMSUNG |]SM-[T|P][350|550|555|355|805|800|710|810|815] Build/LRX22G',
+ 'LG-D7:number0-2::number0-9: Build/LRX22G',
+ '[LG|SM]-[D|G]:number8-9::number0-5::number0-9:[|P|K|T|I|F|T1] Build/[LRX22G|KOT49I|KVT49L|LMY47X]'
+ ],
+ '5.1' => [
+ 'Nexus :number5-9: Build/[LMY48B|LRX22C]',
+ '[|SAMSUNG ]SM-G9[28|25|20][X|FD|8|F|F-ORANGE|FG|FQ|H|I|L|M|S|T] Build/[LRX22G|LMY47X]',
+ '[|SAMSUNG ]SM-G9[35|350][X|FD|8|F|F-ORANGE|FG|FQ|H|I|L|M|S|T] Build/[MMB29M|LMY47X]',
+ '[MOTOROLA |][MOTO G|MOTO G XT1068|XT1021|MOTO E XT1021|MOTO XT1580|MOTO X FORCE XT1580|MOTO X PLAY XT1562|MOTO XT1562|MOTO XT1575|MOTO X PURE XT1575|MOTO XT1570 MOTO X STYLE] Build/[LXB22|LMY47Z|LPC23|LPK23|LPD23|LPH223]'
+ ],
+ '6.0' => [
+ '[SAMSUNG |]SM-[G|D][920|925|928|9350][V|F|I|L|M|S|8|I] Build/[MMB29K|MMB29V|MDB08I|MDB08L]',
+ 'Nexus :number5-7:[P|X|] Build/[MMB29K|MMB29V|MDB08I|MDB08L]',
+ 'HTC One[_| ][M9|M8|M8 Pro] Build/MRA58K',
+ 'HTC One[_M8|_M9|0P6B|801e|809d|0P8B2|mini 2|S][ dual sim|] Build/MRA58K'
+ ],
+ '7.0' => [
+ 'Pixel [XL|C] Build/[NRD90M|NME91E]',
+ 'Nexus :number5-9:[X|P|] Build/[NPD90G|NME91E]',
+ '[SAMSUNG |]GT-I:number91-98:00 Build/KTU84P',
+ 'Xperia [V |]Build/NDE63X',
+ 'LG-H:number90-93:0 Build/NRD90[C|M]'
+ ],
+ '7.1' => [
+ 'Pixel [XL|C] Build/[NRD90M|NME91E]',
+ 'Nexus :number5-9:[X|P|] Build/[NPD90G|NME91E]',
+ '[SAMSUNG |]GT-I:number91-98:00 Build/KTU84P',
+ 'Xperia [V |]Build/NDE63X',
+ 'LG-H:number90-93:0 Build/NRD90[C|M]'
+ ]
+ ];
+ public $locale = 'en-US';
+ /**
+ * List of "OS" strings used for android
+ * @var array $android_os
+ */
+ public $android_os = [
+ 'Linux; Android :androidVersion:; :androidDevice:',
+ //Todo: Add a $windowsDevices variable that does the same as androidDevice
+ //'Windows Phone 10.0; Android :androidVersion:; :windowsDevice:',
+ 'Linux; U; Android :androidVersion:; :androidDevice:',
+ 'Android; Android :androidVersion:; :androidDevice:'
+ ];
+ /**
+ * List of "OS" strings used for iOS
+ * @var array $mobile_ios
+ */
+ public $mobile_ios = [
+ 'iphone' => 'iPhone; CPU iPhone OS :number7-11:_:number0-9:_:number0-9:; like Mac OS X;',
+ 'ipad' => 'iPad; CPU iPad OS :number7-11:_:number0-9:_:number0-9: like Mac OS X;',
+ 'ipod' => 'iPod; CPU iPod OS :number7-11:_:number0-9:_:number0-9:; like Mac OS X;'
+ ];
+
+ /**
+ * Get a random operating system
+ * @param string|null $os
+ * @return string *
+ */
+ public function getOS(string $os = NULL)
+ {
+ $_os = [];
+ if ($os === NULL || in_array($os, ['chrome', 'firefox', 'explorer'])) {
+ $_os = $os === 'explorer' ? $this->windows_os : array_merge($this->windows_os, $this->linux_os, $this->mac_os);
+ } else {
+ $_os += $this->{$os . '_os'};
+ }
+ // randomly select on operating system
+ $selected_os = rtrim($_os[random_int(0, count($_os) - 1)], ';');
+
+ // check for spin syntax
+ if (strpos($selected_os, '[') !== FALSE) {
+ $selected_os = self::processSpinSyntax($selected_os);
+ }
+
+ // check for random number syntax
+ if (strpos($selected_os, ':number') !== FALSE) {
+ $selected_os = self::processRandomNumbers($selected_os);
+ }
+
+ if (random_int(1, 100) > 50) {
+ $selected_os .= '; ' . $this->locale;
+ }
+ return $selected_os;
+ }
+
+ /**
+ * Get Mobile OS
+ * @param string|null $os Can specifiy android, iphone, ipad, ipod, or null/blank for random
+ * @return string *
+ */
+ public function getMobileOS(string $os = NULL)
+ {
+ $os = strtolower($os);
+ $_os = [];
+ switch ($os) {
+ case'android':
+ $_os += $this->android_os;
+ break;
+ case 'iphone':
+ case 'ipad':
+ case 'ipod':
+ $_os[] = $this->mobile_ios[$os];
+ break;
+ default:
+ $_os = array_merge($this->android_os, array_values($this->mobile_ios));
+ }
+ // select random mobile os
+ $selected_os = rtrim($_os[random_int(0, count($_os) - 1)], ';');
+ if (strpos($selected_os, ':androidVersion:') !== FALSE) {
+ $selected_os = $this->processAndroidVersion($selected_os);
+ }
+ if (strpos($selected_os, ':androidDevice:') !== FALSE) {
+ $selected_os = $this->addAndroidDevice($selected_os);
+ }
+ if (strpos($selected_os, ':number') !== FALSE) {
+ $selected_os = self::processRandomNumbers($selected_os);
+ }
+ return $selected_os;
+ }
+
+ /**
+ * static::processRandomNumbers
+ * @param $selected_os
+ * @return null|string|string[] *
+ */
+ public static function processRandomNumbers($selected_os)
+ {
+ return preg_replace_callback('/:number(\d+)-(\d+):/i', function ($matches) {
+ return random_int($matches[1], $matches[2]);
+ }, $selected_os);
+ }
+
+ /**
+ * static::processSpinSyntax
+ * @param $selected_os
+ * @return null|string|string[] *
+ */
+ public static function processSpinSyntax($selected_os)
+ {
+ return preg_replace_callback('/\[([\w\-\s|;]*?)\]/i', function ($matches) {
+ $shuffle = explode('|', $matches[1]);
+ return $shuffle[array_rand($shuffle)];
+ }, $selected_os);
+ }
+
+ /**
+ * processAndroidVersion
+ * @param $selected_os
+ * @return null|string|string[] *
+ */
+ public function processAndroidVersion($selected_os)
+ {
+ $this->androidVersion = $version = $this->androidVersions[array_rand($this->androidVersions)];
+ return preg_replace_callback('/:androidVersion:/i', function ($matches) use ($version) {
+ return $version;
+ }, $selected_os);
+ }
+
+ /**
+ * addAndroidDevice
+ * @param $selected_os
+ * @return null|string|string[] *
+ */
+ public function addAndroidDevice($selected_os)
+ {
+ $devices = $this->androidDevices[substr($this->androidVersion, 0, 3)];
+ $device = $devices[array_rand($devices)];
+
+ $device = self::processSpinSyntax($device);
+ return preg_replace_callback('/:androidDevice:/i', function ($matches) use ($device) {
+ return $device;
+ }, $selected_os);
+ }
+
+ /**
+ * static::chromeVersion
+ * @param $version
+ * @return string *
+ */
+ public static function chromeVersion($version): string
+ {
+ return random_int($version['min'], $version['max']) . '.0.' . random_int(1000, 4000)
+ . '.' . random_int(100, 400);
+ }
+
+ /**
+ * static::firefoxVersion
+ * @param $version
+ * @return string *
+ */
+ public static function firefoxVersion($version): string
+ {
+ return random_int($version['min'], $version['max']) . '.' . random_int(0, 9);
+ }
+
+ /**
+ * static::windows
+ * @param $version
+ * @return string *
+ */
+ public static function windows($version): string
+ {
+ return random_int($version['min'], $version['max']) . '.' . random_int(0, 9);
+ }
+
+ /**
+ * generate
+ * @param null $userAgent
+ * @return string *
+ */
+ public function generate($userAgent = NULL, $locale = null): string
+ {
+
+ if (!is_null($locale))
+ $this->locale = $locale;
+
+ if ($userAgent === NULL) {
+ $r = random_int(0, 100);
+ if ($r >= 44) {
+ $userAgent = array_rand(['firefox' => 1, 'chrome' => 1, 'explorer' => 1]);
+ } else {
+ $userAgent = array_rand(['iphone' => 1, 'android' => 1, 'mobile' => 1]);
+ }
+ } elseif ($userAgent == 'windows' || $userAgent == 'mac' || $userAgent == 'linux') {
+ $agents = ['firefox' => 1, 'chrome' => 1];
+ if ($userAgent == 'windows') {
+ $agents['explorer'] = 1;
+ }
+ $userAgent = array_rand($agents);
+ }
+ $_SESSION['agent'] = $userAgent;
+ if ($userAgent == 'chrome') {
+ return 'Mozilla/5.0 (' . $this->getOS($userAgent) . ') AppleWebKit/' .
+ (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603))
+ . '.' . random_int(1, 50) . ' (KHTML, like Gecko) Chrome/' .
+ self::chromeVersion(['min' => 47, 'max' => 55]) . ' Safari/'
+ . (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603));
+ } elseif ($userAgent == 'firefox') {
+
+ return 'Mozilla/5.0 (' . $this->getOS($userAgent) . ') Gecko/'
+ . (random_int(1, 100) > 30 ? '20100101' : '20130401') . ' Firefox/'
+ . self::firefoxVersion(['min' => 45, 'max' => 74]);
+ } elseif ($userAgent == 'explorer') {
+
+ return 'Mozilla / 5.0 (compatible; MSIE ' . ($int = random_int(7, 11))
+ . '.0; ' . $this->getOS('windows') . ' Trident / '
+ . ($int == 7 || $int == 8 ? '4' : ($int == 9 ? '5' : ($int == 10 ? '6' : '7')))
+ . '.0)';
+ } elseif ($userAgent == 'mobile'
+ || $userAgent == 'android'
+ || $userAgent == 'iphone'
+ || $userAgent == 'ipad'
+ || $userAgent == 'ipod') {
+
+ return 'Mozilla/5.0 (' . $this->getMobileOS($userAgent) . ') AppleWebKit/'
+ . (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603))
+ . '.' . random_int(1, 50) . ' (KHTML, like Gecko) Chrome/'
+ . self::chromeVersion(['min' => 47, 'max' => 55]) . ' Mobile Safari/'
+ . (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603))
+ . '.' . random_int(0, 9);
+ } else {
+ new Exception('Unable to determine user agent to generate');
+ }
+ }
+}
diff --git a/src/util/AllotTasks.php b/src/util/AllotTasks.php
index 8602049..283d3f3 100644
--- a/src/util/AllotTasks.php
+++ b/src/util/AllotTasks.php
@@ -29,7 +29,7 @@ trait AllotTasks
* @use 加载json数据
* @return Parser
*/
- protected static function loadJsonData()
+ protected static function loadJsonData(): Parser
{
return Parser::fromFile(static::$repository);
}
diff --git a/src/util/BaseRaffle.php b/src/util/BaseRaffle.php
index 8b904f0..1c80ddb 100644
--- a/src/util/BaseRaffle.php
+++ b/src/util/BaseRaffle.php
@@ -21,6 +21,7 @@ abstract class BaseRaffle
{
use TimeLock;
use FilterWords;
+
const ACTIVE_TITLE = '';
const ACTIVE_SWITCH = '';
@@ -31,7 +32,7 @@ abstract class BaseRaffle
public static function run()
{
- if (getenv(static::ACTIVE_SWITCH) == 'false') {
+ if (!getEnable(static::ACTIVE_SWITCH)) {
return;
}
if (static::getLock() > time()) {
@@ -96,14 +97,13 @@ abstract class BaseRaffle
$raw = Curl::get('app', $url, Sign::common($payload));
$de_raw = json_decode($raw, true);
if (!isset($de_raw['data']) || $de_raw['code']) {
- // TODO 请求被拦截 412
+ // Todo 请求被拦截 412
Log::error("获取抽奖数据错误,{$de_raw['message']}");
return [];
}
return $de_raw;
}
-
/**
* @use 解析抽奖信息
* @param int $room_id
@@ -112,7 +112,6 @@ abstract class BaseRaffle
*/
abstract protected static function parseLotteryInfo(int $room_id, array $data): bool;
-
/**
* @use 创建抽奖
* @param array $raffles
@@ -120,7 +119,6 @@ abstract class BaseRaffle
*/
abstract protected static function createLottery(array $raffles): array;
-
/**
* @use 解析抽奖返回
* @param array $results
@@ -135,7 +133,7 @@ abstract class BaseRaffle
* @param string $type
* @return array
*/
- protected static function arrKeySort($arr, $key, $type = 'asc')
+ protected static function arrKeySort($arr, $key, string $type = 'asc'): array
{
switch ($type) {
case 'desc':
@@ -149,14 +147,13 @@ abstract class BaseRaffle
}
}
-
/**
* @use 去重检测
* @param $lid
* @param bool $filter
* @return bool
*/
- protected static function toRepeatLid($lid, $filter = true): bool
+ protected static function toRepeatLid($lid, bool $filter = true): bool
{
$lid = (int)$lid;
if (in_array($lid, static::$all_list)) {
@@ -179,7 +176,7 @@ abstract class BaseRaffle
public static function pushToQueue(array $data): bool
{
// 开关
- if (getenv(static::ACTIVE_SWITCH) == 'false') {
+ if (!getEnable(static::ACTIVE_SWITCH)) {
return false;
}
// 黑屋
diff --git a/src/util/FilterWords.php b/src/util/FilterWords.php
index 2bd744d..faac7b2 100644
--- a/src/util/FilterWords.php
+++ b/src/util/FilterWords.php
@@ -18,7 +18,7 @@ trait FilterWords
{
protected static $store;
protected static $store_status;
- protected static $repository = APP_DATA_PATH . 'filter_words.json';
+ protected static $repository = APP_DATA_PATH . 'filter_library.json';
/**
* @use 加载配置信息
diff --git a/src/util/TimeLock.php b/src/util/TimeLock.php
index 064b59c..eace2fe 100644
--- a/src/util/TimeLock.php
+++ b/src/util/TimeLock.php
@@ -11,6 +11,7 @@
namespace BiliHelper\Util;
use Amp\Delayed;
+use BiliHelper\Core\Task;
use BiliHelper\Plugin\Schedule;
trait TimeLock
@@ -25,7 +26,7 @@ trait TimeLock
public static function setLock(int $lock)
{
if (!static::getpauseStatus()) {
- static::$lock = time() + $lock;
+ Task::getInstance()::_setLock(static::getBaseClass(), time() + $lock);
}
}
@@ -35,33 +36,44 @@ trait TimeLock
*/
public static function getLock(): int
{
- return static::$lock;
+ return Task::getInstance()::_getLock(static::getBaseClass());
+ }
+
+ /**
+ * @use 获取基础CLASS NAME
+ * @return string
+ */
+ public static function getBaseClass(): string
+ {
+ return basename(str_replace('\\', '/', __CLASS__));
}
/**
* @use used in Amp loop Delayed
* @return delayed
*/
- public static function Delayed()
+ public static function Delayed(): Delayed
{
return new Delayed(1000);
}
/**
* @use 定时
- * @param int $hour
- * @param int $minute
- * @param int $seconds
+ * @param int $hour 时
+ * @param int $minute 分
+ * @param int $seconds 秒
+ * @param bool $random 随机一个小时内
* @return int
*/
- public static function timing(int $hour, int $minute = 0, int $seconds = 0): int
+ public static function timing(int $hour, int $minute = 0, int $seconds = 0, bool $random = false): int
{
$time = strtotime('today') + ($hour * 60 * 60) + ($minute * 60) + ($seconds);
if ($time > time()) {
- return strtotime('today') + ($hour * 60 * 60) + ($minute * 60) + ($seconds) - time();
+ $timing = strtotime('today') + ($hour * 60 * 60) + ($minute * 60) + ($seconds) - time();
} else {
- return strtotime('tomorrow') + ($hour * 60 * 60) + ($minute * 60) + ($seconds) - time();
+ $timing = strtotime('tomorrow') + ($hour * 60 * 60) + ($minute * 60) + ($seconds) - time();
}
+ return $random ? $timing + mt_rand(1, 60) * 60 : $timing;
}
@@ -102,14 +114,14 @@ trait TimeLock
*/
public static function cancelPause()
{
- static::$lock = false;
+ static::$pause_status = false;
}
/**
* @use 暂停状态
* @return bool
*/
- public static function getPauseStatus()
+ public static function getPauseStatus(): bool
{
return static::$pause_status;
}
diff --git a/src/util/XliveHeartBeat.php b/src/util/XliveHeartBeat.php
index 06e5075..a44a381 100644
--- a/src/util/XliveHeartBeat.php
+++ b/src/util/XliveHeartBeat.php
@@ -13,7 +13,6 @@ namespace BiliHelper\Util;
use BiliHelper\Core\Curl;
use BiliHelper\Core\Log;
use BiliHelper\Plugin\Live;
-use BiliHelper\Plugin\User;
use BiliHelper\Tool\Generator;
trait XliveHeartBeat
@@ -32,28 +31,14 @@ trait XliveHeartBeat
protected static $_default = 0; // 默认值
-
- /**
- * @use 重置变量
- * @param false $force
- */
- protected static function resetVar($force = false)
- {
- if ($force) {
- static::$_room_info = [];
- static::$_current_room_id = 0;
-
- static::$_retry = 3;
- static::$_count_num = 0;
- static::$_count_time = 0;
- }
- $data = [
- 'id' => static::$_data['id'],
- ];
- $data["id"][2] = 0;
- static::$_data = $data;
- }
-
+ // 请求配置
+ protected static $_user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36';
+ protected static $_headers = [
+ 'content-type' => 'application/x-www-form-urlencoded',
+ 'origin' => 'https://live.bilibili.com',
+ 'referer' => 'https://live.bilibili.com/',
+ 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36'
+ ];
/**
* @use 任务接口
@@ -73,7 +58,7 @@ trait XliveHeartBeat
static::resetVar(true);
static::$_current_room_id = $room_id;
}
- // 加载房间信息
+ // 获取房间信息
if (empty(static::$_room_info)) {
$r_data = Live::webGetRoomInfo($room_id);
if ($r_data['code'] != 0) {
@@ -92,53 +77,43 @@ trait XliveHeartBeat
$r_data = static::heartBeatIterator();
$index = static::$_data['id'][2];
if ($r_data['code'] != 0) {
+ Log::warning("心跳失败-$index {$r_data['message']}");
+ // 失败心跳
if (static::$_retry) {
- Log::warning("心跳失败-$index {$r_data['message']}");
- static::resetVar();
+ // 重试次数 > 1 , 不全部清除
+ static::resetVar(true);
static::$_retry -= 1;
- return static::$_default;
+ } else {
+ // 重试次数 < 1 , 全部清除
+ static::resetVar(true);
}
- }
- static::$_count_num += 1;
- static::$_count_time += $r_data['heartbeat_interval'];
+ return static::$_default;
+ } else {
+ // 成功心跳
+ static::$_count_num += 1;
+ static::$_count_time += $r_data['heartbeat_interval'];
- // 最大次数限制
- if ($max_num <= static::$_count_num) {
- // 成功在id为{room_id}的直播间发送完{ii}次心跳,退出直播心跳(达到最大心跳次数)
+ // 最大次数限制
+ if ($max_num <= static::$_count_num) {
+ // 成功在id为{room_id}的直播间发送完{ii}次心跳,退出直播心跳(达到最大心跳次数)
+ }
+ // 最大时间限制
+ if ($max_time <= static::$_count_time) {
+ //成功在id为{room_id}的直播间发送第{ii}次心跳
+ }
+ $minute = round(static::$_count_time / 60) - 1;
+ Log::notice("已在直播间 $room_id 连续观看了 $minute 分钟");
+ return $r_data['heartbeat_interval'];
}
- // 最大时间限制
- if ($max_time <= static::$_count_time) {
- //成功在id为{room_id}的直播间发送第{ii}次心跳
- }
- $minute = round(static::$_count_time / 60);
- Log::info("已在直播间 $room_id 连续观看了 $minute 分钟");
- return $r_data['heartbeat_interval'];
-
}
- /**
- * @use 检查依赖
- * @return bool
- */
- protected static function depend(): bool
- {
- if (getenv('ENC_SERVER') == '') {
- return false;
- }
- // 加载加密服务器
- if (is_null(static::$_enc_server)) {
- static::$_enc_server = getenv('ENC_SERVER');
- }
- return true;
- }
-
-
/**
* @use 心跳迭代
* @return array
*/
protected static function heartBeatIterator(): array
{
+// print_r(static::$_data);
$rdata = [];
# 第1次执行 eHeartBeat
if (static::$_data['id'][2] == 0) {
@@ -147,6 +122,13 @@ trait XliveHeartBeat
# 第1次之后执行 xHeartBeat
static::$_data['ts'] = time() * 1000;
static::$_data['s'] = static::encParamS(static::$_data, static::$_secret_rule);
+ if (!static::$_data['s']) {
+ return [
+ 'code' => 404,
+ 'message' => '心跳加密错误',
+ 'heartbeat_interval' => static::$_default
+ ];
+ }
$r_data = static::xHeartBeat(static::$_data['id']);
}
if ($r_data['code'] == 0) {
@@ -161,11 +143,10 @@ trait XliveHeartBeat
return [
'code' => $r_data['code'],
'message' => $r_data['message'],
- 'heartbeat_interval' => $rdata['heartbeat_interval']
+ 'heartbeat_interval' => array_key_exists('heartbeat_interval', $rdata) ? $rdata['heartbeat_interval'] : static::$_default
];
}
-
/**
* @use E心跳
* @param array $id
@@ -174,26 +155,20 @@ trait XliveHeartBeat
protected static function eHeartBeat(array $id): 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/' . $id[3],
- ];
- $user_info = User::parseCookies();
$payload = [
'id' => json_encode([$id[0], $id[1], $id[2], $id[3]], 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'],
+ 'ua' => static::$_user_agent,
+ 'csrf_token' => getCsrf(),
+ 'csrf' => getCsrf(),
'visit_id' => ''
];
- // print_r($payload);
+ // print_r($payload);
Log::debug(json_encode($payload, true));
- $raw = Curl::post('pc', $url, $payload, $headers);
+ $raw = Curl::post('pc', $url, $payload, static::$_headers);
// {'code':0,'message':'0','ttl':1,'data':{'timestamp':1595342828,'heartbeat_interval':300,'secret_key':'seacasdgyijfhofiuxoannn','secret_rule':[2,5,1,4],'patch_status':2}}
unset($payload['id']);
@@ -210,12 +185,6 @@ trait XliveHeartBeat
protected static function xHeartBeat(array $id): array
{
$url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/X';
- $user_info = User::parseCookies();
- $headers = [
- 'Content-Type' => 'application/x-www-form-urlencoded',
- 'Origin' => 'https://live.bilibili.com',
- 'Referer' => 'https://live.bilibili.com/' . $id[3],
- ];
$payload = [
's' => static::$_data['s'],
'id' => json_encode([$id[0], $id[1], $id[2], $id[3]], true),
@@ -225,13 +194,14 @@ trait XliveHeartBeat
'time' => static::$_data['time'],
'ts' => static::$_data['ts'],
'ua' => static::$_data['ua'],
- 'csrf_token' => $user_info['token'],
- 'csrf' => $user_info['token'],
+ 'csrf_token' => static::$_data['csrf_token'],
+ 'csrf' => static::$_data['csrf'],
'visit_id' => ''
];
// print_r($payload);
Log::debug(json_encode($payload, true));
- $raw = Curl::post('pc', $url, $payload, $headers);
+ $raw = Curl::post('pc', $url, $payload, static::$_headers);
+ # {"code":0,"message":"0","ttl":1,"data":{"heartbeat_interval":60,"timestamp":1619419450,"secret_rule":[2,5,1,4],"secret_key":"seacasdgyijfhofiuxoannn"}}
# {'code':0,'message':'0','ttl':1,'data':{'heartbeat_interval':300,'timestamp':1595346846,'secret_rule':[2,5,1,4],'secret_key':'seacasdgyijfhofiuxoannn'}}
return json_decode($raw, true);
}
@@ -248,17 +218,91 @@ trait XliveHeartBeat
'Content-Type' => 'application/json',
];
// 加密部分
- $payload = ['t' => $t, 'r' => $r];
+ $payload = [
+ 't' => static::formatT($t),
+ 'r' => static::formatR($r)
+ ];
+// print_r($payload);
$data = Curl::put('other', static::$_enc_server, $payload, $headers);
$de_raw = json_decode($data, true);
if ($de_raw['code'] == 0) {
- // Log::info("S加密成功 {$de_raw['s']}");
- return $de_raw['s'];
+ if (array_key_exists('s', $de_raw)) {
+ // Log::info("S加密成功 {$de_raw['s']}");
+ return $de_raw['s'];
+ }
+ Log::warning("参数S加密失败: 加密服务器暂时错误,请检查更换");
} else {
- Log::warning("S加密失败 {$de_raw['message']}");
- return false;
+ Log::warning("参数S加密失败: {$de_raw['message']}");
}
+ return false;
}
+ /**
+ * @use 格式T
+ * @param array $t
+ * @return array
+ */
+ protected static function formatT(array $t): array
+ {
+// print_r($t);
+ return [
+ 'id' => $t['id'],
+ 'device' => $t['device'],
+ 'ets' => $t['ets'],
+ 'benchmark' => $t['benchmark'],
+ 'time' => $t['time'],
+ 'ts' => $t['ts'],
+ 'ua' => $t['ua'],
+ ];
+ }
+
+ /**
+ * @use 格式R
+ * @param array $r
+ * @return array
+ */
+ protected static function formatR(array $r): array
+ {
+ return $r;
+ }
+
+ /**
+ * @use 重置变量
+ * @param false $force
+ */
+ protected static function resetVar(bool $force = false)
+ {
+ if ($force) {
+ static::$_room_info = [];
+ static::$_current_room_id = 0;
+
+ static::$_retry = 3;
+ static::$_count_num = 0;
+ static::$_count_time = 0;
+ }
+ static::$_data = null;
+ static::$_data = ['id' => []];
+ $data = [
+ 'id' => static::$_data['id'],
+ ];
+ $data["id"][2] = 0;
+ static::$_data = $data;
+ }
+
+ /**
+ * @use 检查依赖
+ * @return bool
+ */
+ protected static function depend(): bool
+ {
+ if (getConf('server', 'heartbeat_enc') == '') {
+ return false;
+ }
+ // 加载加密服务器
+ if (is_null(static::$_enc_server)) {
+ static::$_enc_server = getConf('server', 'heartbeat_enc');
+ }
+ return true;
+ }
}
\ No newline at end of file
diff --git a/task/.gitkeep b/task/.gitkeep
new file mode 100644
index 0000000..e69de29