[update] Version 1.0.0.*

This commit is contained in:
lkeme 2021-08-22 14:54:27 +08:00
parent 7210571ab8
commit 01c8422c98
79 changed files with 2158 additions and 988 deletions

2
.github/FUNDING.yml vendored
View File

@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
liberapay: # Replace with a single Liberapay username liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username otechie: # Replace with a single Otechie username
custom: ['https://i.loli.net/2019/07/13/5d2963e5cc1eb22973.png'] custom: [ 'https://i.loli.net/2019/07/13/5d2963e5cc1eb22973.png' ]

View File

@ -1,5 +1,7 @@
# Issue: BiliHepler 程序问题 # Issue: BiliHepler 程序问题
<!-- 上面是标题 下面才是正文 --> <!-- 上面是标题 下面才是正文 -->
### 版本、安装方式、系统 ### 版本、安装方式、系统
1. 你在使用什么版本的 BiliHelper 1. 你在使用什么版本的 BiliHelper
@ -10,22 +12,24 @@
3. 你所使用的操作系统 3. 你所使用的操作系统
--- ---
### 描述问题 ### 描述问题
<!-- 在下方简要描述问题 --> <!-- 在下方简要描述问题 -->
--- ---
### 复现问题的步骤 ### 复现问题的步骤
<!-- 在下方描述如何复现问题 --> <!-- 在下方描述如何复现问题 -->
--- ---
### BiliHelper 运行日志: ### BiliHelper 运行日志:
<!-- 如果条件允许请附日志 --> <!-- 如果条件允许请附日志 -->
```shell ```shell
@ -38,5 +42,6 @@
--- ---
### 截图 ### 截图
<!-- 如果条件允许请附图 --> <!-- 如果条件允许请附图 -->

View File

@ -1,5 +1,7 @@
# Issue: Bug Report # Issue: Bug Report
<!-- 上面是标题 下面才是正文 --> <!-- 上面是标题 下面才是正文 -->
### Version, approach of installation, operating system ### Version, approach of installation, operating system
1. What version of BiliHelper are you using? 1. What version of BiliHelper are you using?
@ -10,22 +12,24 @@
3. What is your operating system? 3. What is your operating system?
--- ---
### Description ### Description
<!-- Describe your problem below --> <!-- Describe your problem below -->
--- ---
### Steps to reproduce ### Steps to reproduce
<!-- Describe how to reproduce problem below --> <!-- Describe how to reproduce problem below -->
--- ---
### BiliHelper Logs ### BiliHelper Logs
<!-- Paste log if possible --> <!-- Paste log if possible -->
```shell ```shell
@ -38,5 +42,6 @@
--- ---
### Screenshot ### Screenshot
<!-- Paste screenshot if possible --> <!-- Paste screenshot if possible -->

View File

@ -8,6 +8,34 @@
[comment]: <> (</details>) [comment]: <> (</details>)
## v1.0.0.210822 alpha (2021-08-22)
### Added
- 支持自定义设备
- 全面支持PHP8.0
- 支持本地缓存
- 对使用体验进行了一轮优化并解决了一些bug~~
-
### Changed
- PHP版本提升值8.*, 不向下兼容
- 对使用体验进行了一轮优化并解决了一些bug~~
-
### Fixed
- 对使用体验进行了一轮优化并解决了一些bug~~
-
### Remarks
- 注意文档文件有些许改动
- 注意需要重新进行`composer update`操作
- 注意只支持PHP8.* 只支持PHP8.* 只支持PHP8.*
-
## v0.9.9.210807 alpha (2021-08-07) ## v0.9.9.210807 alpha (2021-08-07)
### Added ### Added

48
DOC.md
View File

@ -18,7 +18,7 @@
|Requirement | |Requirement |
|--------------------| |--------------------|
|PHP >=7.3 | |PHP >=8.0 |
|php_curl | |php_curl |
|php_sockets | |php_sockets |
|php_openssl | |php_openssl |
@ -36,7 +36,7 @@
+ 阿里云(全量镜像) + 阿里云(全量镜像)
```bash ```shell script
# 使用帮助 # 使用帮助
> https://developer.aliyun.com/composer > https://developer.aliyun.com/composer
# 使用命令 # 使用命令
@ -45,7 +45,7 @@
+ 恢复默认镜像|Composer.phar加速下载 + 恢复默认镜像|Composer.phar加速下载
```bash ```shell script
> composer config -g --unset repos.packagist > composer config -g --unset repos.packagist
> https://mirrors.cloud.tencent.com/composer/composer.phar > https://mirrors.cloud.tencent.com/composer/composer.phar
@ -56,7 +56,7 @@
<summary>其余镜像 展开查看</summary> <summary>其余镜像 展开查看</summary>
<pre><code> <pre><code>
+ cnpkg(全量镜像) + cnpkg(全量镜像)
```bash ```shell script
# 使用帮助 # 使用帮助
> https://php.cnpkg.org/ > https://php.cnpkg.org/
# 使用命令 # 使用命令
@ -65,16 +65,16 @@
+ 腾讯云(全量镜像) + 腾讯云(全量镜像)
```bash ```shell script
# 使用帮助 # 使用帮助
> https://mirrors.cloud.tencent.com/help/composer.html > https://mirrors.cloud.tencent.com/help/composer.html
# 使用命令 # 使用命令
> composer config -g repos.packagist composer https://mirrors.cloud.tencent.com/composer/ > composer config -g repos.packagist composer https://mirrors.cloud.tencent.com/composer/
``` ```
+ phpcomposer(全量镜像) + PhpComposer(全量镜像)
```bash ```shell script
# 使用帮助 # 使用帮助
> https://pkg.phpcomposer.com/ > https://pkg.phpcomposer.com/
# 使用命令 # 使用命令
@ -83,7 +83,7 @@
+ 华为云(全量镜像) + 华为云(全量镜像)
```bash ```shell script
# 使用帮助 # 使用帮助
> https://mirrors.huaweicloud.com/repository/php/ > https://mirrors.huaweicloud.com/repository/php/
# 使用命令 # 使用命令
@ -92,7 +92,7 @@
+ 交通大学(非全量镜像) + 交通大学(非全量镜像)
```bash ```shell script
# 使用帮助 # 使用帮助
> https://packagist.mirrors.sjtug.sjtu.edu.cn/ > https://packagist.mirrors.sjtug.sjtu.edu.cn/
# 使用命令 # 使用命令
@ -106,7 +106,7 @@
1. 下载(克隆)项目代码,初始化项目 1. 下载(克隆)项目代码,初始化项目
``` ```shell script
$ git clone https://github.com/lkeme/BiliHelper-personal.git $ git clone https://github.com/lkeme/BiliHelper-personal.git
$ cd BiliHelper-personal/conf $ cd BiliHelper-personal/conf
$ cp user.ini.example user.ini $ cp user.ini.example user.ini
@ -114,7 +114,7 @@ $ cp user.ini.example user.ini
2. 使用 [composer](https://getcomposer.org/download/) 工具进行安装 2. 使用 [composer](https://getcomposer.org/download/) 工具进行安装
``` ```shell script
$ composer install $ composer install
``` ```
@ -124,13 +124,14 @@ $ composer install
3. 按照说明修改配置文件 `user.ini` 3. 按照说明修改配置文件 `user.ini`
``` ```shell script
# 默认只需填写帐号密码,按需求开启其他功能即可 # 默认只需填写帐号密码,按需求开启其他功能即可
...
``` ```
4. 运行测试 4. 运行测试
``` ```shell script
$ php index.php $ php index.php
``` ```
@ -138,11 +139,26 @@ $ php index.php
5. 复制一份example配置文件修改账号密码即可 5. 复制一份example配置文件修改账号密码即可
``` ```shell script
$ php index.php example.ini $ php index.php example.ini
``` ```
6. 请保证配置文件存在,否则默认加载`user.ini`配置文件 6. 自定义设备方案
```shell script
$ cd conf
$ cp bili.yaml user_bili.yaml
$ cp device.yaml user_device.yaml
```
7. 命令模式
```shell script
# 获取所有命令
$ php index.php -?
```
8. 请保证配置文件存在,否则默认加载`user.ini`配置文件
<p align="center"><img width="680px" src="https://user-images.githubusercontent.com/19500576/118621472-f8455d80-b7f8-11eb-9fec-500148a566b4.png"></p> <p align="center"><img width="680px" src="https://user-images.githubusercontent.com/19500576/118621472-f8455d80-b7f8-11eb-9fec-500148a566b4.png"></p>
@ -173,7 +189,7 @@ $ docker run -itd --rm -v /path/to/your/confFileName.ini:/app/conf/user.ini lkem
- 使用github镜像加速 - 使用github镜像加速
```bash ```shell script
$ -e MIRRORS=0 # 使用 github.com $ -e MIRRORS=0 # 使用 github.com
$ -e MIRRORS=1 # 使用 ghproxy.com $ -e MIRRORS=1 # 使用 ghproxy.com
$ -e MIRRORS=2 # 使用 github.com.cnpmjs.org $ -e MIRRORS=2 # 使用 github.com.cnpmjs.org

View File

@ -16,7 +16,7 @@
<p align="center"> <p align="center">
<img src="https://img.shields.io/badge/Version-0.9.9.210807-orange.svg?longCache=true&style=for-the-badge"> <img src="https://img.shields.io/badge/Version-1.0.0.210822-orange.svg?longCache=true&style=for-the-badge">
<img src="https://img.shields.io/badge/PHP-7.3+-green.svg?longCache=true&style=for-the-badge"> <img src="https://img.shields.io/badge/PHP-7.3+-green.svg?longCache=true&style=for-the-badge">
<img src="https://img.shields.io/badge/Composer-latest-blueviolet.svg?longCache=true&style=for-the-badge"> <img src="https://img.shields.io/badge/Composer-latest-blueviolet.svg?longCache=true&style=for-the-badge">
<img src="https://img.shields.io/badge/License-mit-blue.svg?longCache=true&style=for-the-badge"> <img src="https://img.shields.io/badge/License-mit-blue.svg?longCache=true&style=for-the-badge">
@ -31,6 +31,7 @@
---- 免费的东西总是得不到人的珍惜。 ---- 免费的东西总是得不到人的珍惜。
---- 只有花大价钱去买到的东西,才会令人信任。 ---- 只有花大价钱去买到的东西,才会令人信任。
``` ```
## 🖥️星图 ## 🖥️星图
[![Stargazers over time](https://starchart.cc/lkeme/BiliHelper-personal.svg)](https://starchart.cc/lkeme/BiliHelper-personal) [![Stargazers over time](https://starchart.cc/lkeme/BiliHelper-personal.svg)](https://starchart.cc/lkeme/BiliHelper-personal)
@ -42,45 +43,46 @@
| plugin | status | version | cycle | description | | plugin | status | version | cycle | description |
|-----------------|--------|----------|--------|---------------------------------------------| |-----------------|--------|----------|--------|---------------------------------------------|
| CheckUpdate | true | 21.08.07 | 待整理 | 程序检查更新 | | CheckUpdate | true | 21.08.22 | 待整理 | 程序检查更新 |
| Login | true | 21.08.07 | 待整理 | 账号登录、刷新、维持 | | Login | true | 21.08.22 | 待整理 | 账号登录、刷新、维持 |
| Schedule | true | 21.08.07 | 待整理 | 控制插件运行周期 | | Schedule | true | 21.08.22 | 待整理 | 控制插件运行周期 |
| MainSite | true | 21.08.07 | 待整理 | 投币、观看、分享视频 (速升6级不是梦) | | MainSite | true | 21.08.22 | 待整理 | 投币、观看、分享视频 (速升6级不是梦) |
| DailyBag | true | 21.08.07 | 待整理 | 双端领取日常/周常礼包 | | DailyBag | true | 21.08.22 | 待整理 | 双端领取日常/周常礼包 |
| ManGa | true | 21.08.07 | 待整理 | 漫画签到、分享 | | ManGa | true | 21.08.22 | 待整理 | 漫画签到、分享 |
| ActivityLottery | true | 21.08.07 | 待整理 | 主站活动九宫格抽奖 | | ActivityLottery | true | 21.08.22 | 待整理 | 主站活动九宫格抽奖 |
| Competition | true | 21.08.07 | 待整理 | 游戏赛事竞猜 | | Competition | true | 21.08.22 | 待整理 | 游戏赛事竞猜 |
| DoubleHeart | true | 21.08.07 | 待整理 | 双端心跳 (姥爷直播经验) | | DoubleHeart | true | 21.08.22 | 待整理 | 双端心跳 (姥爷直播经验) |
| DailyTask | true | 21.08.07 | 待整理 | 直播每日任务(签到、观看) | | DailyTask | true | 21.08.22 | 待整理 | 直播每日任务(签到、观看) |
| Barrage | true | 21.08.07 | 待整理 | 保持活跃弹幕 | | Barrage | true | 21.08.22 | 待整理 | 保持活跃弹幕 |
| Silver2Coin | true | 21.08.07 | 待整理 | 银瓜子兑换硬币 | | Silver2Coin | true | 21.08.22 | 待整理 | 银瓜子兑换硬币 |
| Judge | true | 21.08.07 | 待整理 | 风纪委员投票 | | Judge | true | 21.08.22 | 待整理 | 风纪委员投票 |
| GiftSend | true | 21.08.07 | 待整理 | 礼物赠送、维持每日勋章亲密度 | | GiftSend | true | 21.08.22 | 待整理 | 礼物赠送、维持每日勋章亲密度 |
| GroupSignIn | true | 21.08.07 | 待整理 | 友爱社签到 | | GroupSignIn | true | 21.08.22 | 待整理 | 友爱社签到 |
| GiftHeart | true | 21.08.07 | 待整理 | 日常心跳每日礼包礼物 | | GiftHeart | true | 21.08.22 | 待整理 | 日常心跳每日礼包礼物 |
| SmallHeart | true | 21.08.07 | 待整理 | 直播挂机每日24个小心心 | | SmallHeart | true | 21.08.22 | 待整理 | 直播挂机每日24个小心心 |
| MaterialObject | true | 21.08.07 | 待整理 | 直播金色宝箱实物抽奖 | | MaterialObject | true | 21.08.22 | 待整理 | 直播金色宝箱实物抽奖 |
| AloneTcpClient | true | 21.08.07 | 待整理 | 作者的独立直播监控(可支持本项目哦) | | AloneTcpClient | true | 21.08.22 | 待整理 | 作者的独立直播监控(可支持本项目哦) |
| ZoneTcpClient | true | 21.08.07 | 待整理 | 官方的分区直播监控 | | ZoneTcpClient | true | 21.08.22 | 待整理 | 官方的分区直播监控 |
| StormRaffle | true | 21.08.07 | 待整理 | 直播节奏风暴抽奖、亿元 | | StormRaffle | true | 21.08.22 | 待整理 | 直播节奏风暴抽奖、亿元 |
| GiftRaffle | true | 21.08.07 | 待整理 | 直播礼物抽奖 | | GiftRaffle | true | 21.08.22 | 待整理 | 直播礼物抽奖 |
| PkRaffle | true | 21.08.07 | 待整理 | 直播大乱斗抽奖 | | PkRaffle | true | 21.08.22 | 待整理 | 直播大乱斗抽奖 |
| GuardRaffle | true | 21.08.07 | 待整理 | 直播大航海抽奖 | | GuardRaffle | true | 21.08.22 | 待整理 | 直播大航海抽奖 |
| AnchorRaffle | true | 21.08.07 | 待整理 | 直播天选时刻抽奖 | | AnchorRaffle | true | 21.08.22 | 待整理 | 直播天选时刻抽奖 |
| GiftRaffle | true | 21.08.07 | 待整理 | 直播礼物抽奖 | | GiftRaffle | true | 21.08.22 | 待整理 | 直播礼物抽奖 |
| AwardRecord | true | 21.08.07 | 待整理 | 最新的中奖纪录通知 | | AwardRecord | true | 21.08.22 | 待整理 | 最新的中奖纪录通知 |
| Forward | true | 21.08.07 | 待整理 | 主站动态抽奖转发 | | Forward | true | 21.08.22 | 待整理 | 主站动态抽奖转发 |
| CapsuleLottery | true | 21.08.07 | 待整理 | 直播扭蛋活动抽奖 | | CapsuleLottery | true | 21.08.22 | 待整理 | 直播扭蛋活动抽奖 |
| PolishTheMedal | true | 21.08.07 | 待整理 | 每日自动点亮灰色勋章 | | PolishTheMedal | true | 21.08.22 | 待整理 | 每日自动点亮灰色勋章 |
| CapsuleLottery | true | 21.08.07 | 待整理 | 直播扭蛋活动抽奖 | | CapsuleLottery | true | 21.08.22 | 待整理 | 直播扭蛋活动抽奖 |
| VipPrivilege | true | 21.08.07 | 待整理 | 每月领取年度大会员特权(B币券、会员购优惠券) | | VipPrivilege | true | 21.08.22 | 待整理 | 每月领取年度大会员特权(B币券、会员购优惠券) |
| BpConsumption | true | 21.08.07 | 待整理 | 每月消费使用年度大会员特权的B币券 | | BpConsumption | true | 21.08.22 | 待整理 | 每月消费使用年度大会员特权的B币券 |
| Statistics | true | 21.08.07 | 待整理 | 全局抽奖结果统计 | | Statistics | true | 21.08.22 | 待整理 | 全局抽奖结果统计 |
| Silver | false | 21.03.27 | 待整理 | 直播银瓜子自动开启宝箱 | | Silver | false | 21.03.27 | 待整理 | 直播银瓜子自动开启宝箱 |
## 交流反馈 ## 交流反馈
`没事不要加、潜水不要加、哑巴不要加。`
Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **请不要来问如何使用, 文档齐全, 仅用于BUG提交反馈** Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **请不要来问如何使用, 文档齐全, 仅用于BUG提交反馈**
## 相关文档 ## 相关文档

View File

@ -3,7 +3,7 @@
"description": "B 站自动领瓜子、直播助手、直播挂机脚本、主站助手 - PHP 版Personal", "description": "B 站自动领瓜子、直播助手、直播挂机脚本、主站助手 - PHP 版Personal",
"type": "project", "type": "project",
"require": { "require": {
"php": ">=7.3.0", "php": ">=8.0",
"ext-curl": "*", "ext-curl": "*",
"ext-openssl": "*", "ext-openssl": "*",
"ext-sockets": "*", "ext-sockets": "*",
@ -21,7 +21,9 @@
"hassankhan/config": "^2.2", "hassankhan/config": "^2.2",
"lkeme/inifile": "^3.4", "lkeme/inifile": "^3.4",
"adhocore/cli": "^0.9.0", "adhocore/cli": "^0.9.0",
"fire015/flintstone": "^2.3" "fire015/flintstone": "^2.3",
"symfony/yaml": "^5.3",
"consolidation/config": "^2.0"
}, },
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
@ -37,7 +39,8 @@
"BiliHelper\\Plugin\\": "src/plugin", "BiliHelper\\Plugin\\": "src/plugin",
"BiliHelper\\Util\\": "src/util", "BiliHelper\\Util\\": "src/util",
"BiliHelper\\Tool\\": "src/tool", "BiliHelper\\Tool\\": "src/tool",
"BiliHelper\\Script\\": "src/script" "BiliHelper\\Script\\": "src/script",
"BiliHelper\\Exceptions\\": "src/exception"
}, },
"files": [ "files": [
"src/core/Helpers.php" "src/core/Helpers.php"

756
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "28d262a352d5f6367f17a5e73ab48ade", "content-hash": "503a15c08236b91de15913134d6f88e3",
"packages": [ "packages": [
{ {
"name": "adhocore/cli", "name": "adhocore/cli",
@ -350,6 +350,72 @@
], ],
"time": "2020-11-27T13:16:18+00:00" "time": "2020-11-27T13:16:18+00:00"
}, },
{
"name": "consolidation/config",
"version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/consolidation/config.git",
"reference": "9a2c2a7b2aea1b3525984a4378743a8b74c14e1c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/consolidation/config/zipball/9a2c2a7b2aea1b3525984a4378743a8b74c14e1c",
"reference": "9a2c2a7b2aea1b3525984a4378743a8b74c14e1c",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"dflydev/dot-access-data": "^1.1.0",
"grasmash/expander": "^1",
"php": ">=7.1.3",
"psr/log": "^1.1",
"symfony/event-dispatcher": "^4||^5"
},
"require-dev": {
"phpunit/phpunit": ">=7.5.20",
"squizlabs/php_codesniffer": "^3",
"symfony/console": "^4||^5",
"symfony/yaml": "^4||^5",
"yoast/phpunit-polyfills": "^0.2.0"
},
"suggest": {
"symfony/event-dispatcher": "Required to inject configuration into Command options",
"symfony/yaml": "Required to use Consolidation\\Config\\Loader\\YamlConfigLoader"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"Consolidation\\Config\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Greg Anderson",
"email": "greg.1.anderson@greenknowe.org"
}
],
"description": "Provide configuration services for a commandline tool.",
"support": {
"issues": "https://github.com/consolidation/config/issues",
"source": "https://github.com/consolidation/config/tree/2.0.1"
},
"time": "2020-12-06T00:03:30+00:00"
},
{ {
"name": "container-interop/container-interop", "name": "container-interop/container-interop",
"version": "1.2.0", "version": "1.2.0",
@ -392,6 +458,75 @@
"abandoned": "psr/container", "abandoned": "psr/container",
"time": "2017-02-14T19:40:03+00:00" "time": "2017-02-14T19:40:03+00:00"
}, },
{
"name": "dflydev/dot-access-data",
"version": "v1.1.0",
"source": {
"type": "git",
"url": "https://github.com/dflydev/dflydev-dot-access-data.git",
"reference": "3fbd874921ab2c041e899d044585a2ab9795df8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/3fbd874921ab2c041e899d044585a2ab9795df8a",
"reference": "3fbd874921ab2c041e899d044585a2ab9795df8a",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=5.3.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-0": {
"Dflydev\\DotAccessData": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dragonfly Development Inc.",
"email": "info@dflydev.com",
"homepage": "http://dflydev.com"
},
{
"name": "Beau Simensen",
"email": "beau@dflydev.com",
"homepage": "http://beausimensen.com"
},
{
"name": "Carlos Frutos",
"email": "carlos@kiwing.it",
"homepage": "https://github.com/cfrutos"
}
],
"description": "Given a deep data structure, access data by dot notation.",
"homepage": "https://github.com/dflydev/dflydev-dot-access-data",
"keywords": [
"access",
"data",
"dot",
"notation"
],
"support": {
"issues": "https://github.com/dflydev/dflydev-dot-access-data/issues",
"source": "https://github.com/dflydev/dflydev-dot-access-data/tree/master"
},
"time": "2017-01-20T21:14:22+00:00"
},
{ {
"name": "fire015/flintstone", "name": "fire015/flintstone",
"version": "v2.3.0", "version": "v2.3.0",
@ -449,6 +584,63 @@
}, },
"time": "2021-01-20T10:36:23+00:00" "time": "2021-01-20T10:36:23+00:00"
}, },
{
"name": "grasmash/expander",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/grasmash/expander.git",
"reference": "95d6037344a4be1dd5f8e0b0b2571a28c397578f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/grasmash/expander/zipball/95d6037344a4be1dd5f8e0b0b2571a28c397578f",
"reference": "95d6037344a4be1dd5f8e0b0b2571a28c397578f",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"dflydev/dot-access-data": "^1.1.0",
"php": ">=5.4"
},
"require-dev": {
"greg-1-anderson/composer-test-scenarios": "^1",
"phpunit/phpunit": "^4|^5.5.4",
"satooshi/php-coveralls": "^1.0.2|dev-master",
"squizlabs/php_codesniffer": "^2.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Grasmash\\Expander\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Matthew Grasmick"
}
],
"description": "Expands internal property references in PHP arrays file.",
"support": {
"issues": "https://github.com/grasmash/expander/issues",
"source": "https://github.com/grasmash/expander/tree/master"
},
"time": "2017-12-21T22:14:55+00:00"
},
{ {
"name": "guzzlehttp/guzzle", "name": "guzzlehttp/guzzle",
"version": "6.5.5", "version": "6.5.5",
@ -1357,6 +1549,62 @@
}, },
"time": "2021-03-05T17:36:06+00:00" "time": "2021-03-05T17:36:06+00:00"
}, },
{
"name": "psr/event-dispatcher",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/event-dispatcher.git",
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\EventDispatcher\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Standard interfaces for event handling.",
"keywords": [
"events",
"psr",
"psr-14"
],
"support": {
"issues": "https://github.com/php-fig/event-dispatcher/issues",
"source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
},
"time": "2019-01-08T18:20:26+00:00"
},
{ {
"name": "psr/http-message", "name": "psr/http-message",
"version": "1.0.1", "version": "1.0.1",
@ -1583,6 +1831,340 @@
}, },
"time": "2021-01-19T12:14:40+00:00" "time": "2021-01-19T12:14:40+00:00"
}, },
{
"name": "symfony/deprecation-contracts",
"version": "v2.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627",
"reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.4-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0"
},
"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-03-23T23:28:01+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v5.3.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "f2fd2208157553874560f3645d4594303058c4bd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f2fd2208157553874560f3645d4594303058c4bd",
"reference": "f2fd2208157553874560f3645d4594303058c4bd",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1",
"symfony/event-dispatcher-contracts": "^2",
"symfony/polyfill-php80": "^1.16"
},
"conflict": {
"symfony/dependency-injection": "<4.4"
},
"provide": {
"psr/event-dispatcher-implementation": "1.0",
"symfony/event-dispatcher-implementation": "2.0"
},
"require-dev": {
"psr/log": "^1|^2|^3",
"symfony/config": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/error-handler": "^4.4|^5.0",
"symfony/expression-language": "^4.4|^5.0",
"symfony/http-foundation": "^4.4|^5.0",
"symfony/service-contracts": "^1.1|^2",
"symfony/stopwatch": "^4.4|^5.0"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\EventDispatcher\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v5.3.4"
},
"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-07-23T15:55:36+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
"version": "v2.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
"reference": "69fee1ad2332a7cbab3aca13591953da9cdb7a11"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/69fee1ad2332a7cbab3aca13591953da9cdb7a11",
"reference": "69fee1ad2332a7cbab3aca13591953da9cdb7a11",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.2.5",
"psr/event-dispatcher": "^1"
},
"suggest": {
"symfony/event-dispatcher-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.4-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
"Symfony\\Contracts\\EventDispatcher\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Generic abstractions related to dispatching event",
"homepage": "https://symfony.com",
"keywords": [
"abstractions",
"contracts",
"decoupling",
"interfaces",
"interoperability",
"standards"
],
"support": {
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.4.0"
},
"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-03-23T23:28:01+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.23.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
"reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
"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.23-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.23.0"
},
"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-02-19T12:13:01+00:00"
},
{ {
"name": "symfony/polyfill-intl-idn", "name": "symfony/polyfill-intl-idn",
"version": "v1.23.0", "version": "v1.23.0",
@ -1847,6 +2429,176 @@
} }
], ],
"time": "2021-05-27T09:17:38+00:00" "time": "2021-05-27T09:17:38+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.23.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be",
"reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.23.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-07-28T13:41:28+00:00"
},
{
"name": "symfony/yaml",
"version": "v5.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7",
"reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
"symfony/console": "<4.4"
},
"require-dev": {
"symfony/console": "^4.4|^5.0"
},
"suggest": {
"symfony/console": "For validating YAML files using the lint command"
},
"bin": [
"Resources/bin/yaml-lint"
],
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v5.3.6"
},
"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-07-29T06:20:01+00:00"
} }
], ],
"packages-dev": [], "packages-dev": [],
@ -1856,7 +2608,7 @@
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": ">=7.3.0", "php": ">=8.0",
"ext-curl": "*", "ext-curl": "*",
"ext-openssl": "*", "ext-openssl": "*",
"ext-sockets": "*", "ext-sockets": "*",

27
conf/bili.yaml Normal file
View File

@ -0,0 +1,27 @@
bili_version: 0.0.1
# Android
bili_a:
package: "tv.danmaku.bili"
version: "6.38.0"
build: "6380500"
channel: "bili"
device: "phone"
mobi_app: "android"
platform: "android"
s_locale: "zh-Hans_CN"
c_locale: "zh-Hans_CH"
app_key: "MWQ4YjZlN2Q0NTIzMzQzNg=="
secret_key: "NTYwYzUyY2NkMjg4ZmVkMDQ1ODU5ZWQxOGJmZmQ5NzM"
app_key_n: "YmNhN2U4NGMyZDk0N2FjNg=="
secret_key_n: "NjA2OThiYTJmNjhlMDFjZTQ0NzM4OTIwYTBmZmU3Njg="
# IOS
bili_i:
app_key: "MjdlYjUzZmM5MDU4ZjhjMw=="
secret_key: "YzJlZDUzYTc0ZWVlZmUzY2Y5OWZiZDAxZDhjOWMzNzU="
# Tv
bili_t:
app_key: "NDQwOWUyY2U4ZmZkMTJiOA=="
secret_key: "NTliNDNlMDRhZDY5NjVmMzQzMTkwNjJiNDc4ZjgzZGQ="

14
conf/device.yaml Normal file
View File

@ -0,0 +1,14 @@
device_version: 0.0.1
device:
os: "android"
os_ver: "7.1.2"
model: "MuMu"
network: "2" # 1 流量 2 WIFI
other_headers:
ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4450.0 Safari/537.36"
pc_headers:
ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.30 Safari/537.36 Edg/90.0.818.8"
app_headers:
ua: "Mozilla/5.0 BiliDroid/${bili_a.version} (bbcallen@gmail.com) os/${device.os} model/${device.model} mobi_app/${bili_a.mobi_app} build/${bili_a.build} channel/${bili_a.channel} innerVer/${bili_a.build} osVer/${device.os_ver} network/${device.network}"

View File

@ -1,11 +1,11 @@
{ {
"code": 0, "code": 0,
"project":"BiliHelper-personal", "project": "BiliHelper-personal",
"branch": "master", "branch": "master",
"source": "https://github.com/lkeme/BiliHelper-personal", "source": "https://github.com/lkeme/BiliHelper-personal",
"raw_url": "https://cdn.jsdelivr.net/gh/lkeme/BiliHelper-personal@master/data/latest_version.json", "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", "purge_url": "https://purge.jsdelivr.net/gh/lkeme/BiliHelper-personal@master/data/latest_version.json",
"version": "0.9.9.210807", "version": "1.0.0.210822",
"des": "程序有更新,请及时线上查看更新哦~", "des": "程序有更新,请及时线上查看更新哦~",
"time": "2021年8月7日11:40:35" "time": "2021年8月22日11:40:35"
} }

View File

@ -11,7 +11,6 @@
require 'vendor/autoload.php'; require 'vendor/autoload.php';
$app = new BiliHelper\Core\App(__DIR__); $app = new BiliHelper\Core\App(__DIR__);
$app->load($argv) $app->load($argv)
->inspect() ->inspect()

View File

@ -10,12 +10,16 @@
namespace BiliHelper\Core; namespace BiliHelper\Core;
use BiliHelper\Plugin\Live;
use Throwable;
use Amp\Loop; use Amp\Loop;
use BiliHelper\Script\BaseTask;
use function Amp\asyncCall; use function Amp\asyncCall;
class App class App
{ {
private $mode = 0; private int $mode = 0;
/** /**
* App constructor. * App constructor.
@ -49,8 +53,14 @@ class App
{ {
$args = (new BCommand($argv))->run(); $args = (new BCommand($argv))->run();
$filename = $args->args()[0] ?? 'user.ini'; $filename = $args->args()[0] ?? 'user.ini';
// 加载配置
Config::getInstance()->load($filename);
// 加载设备
Device::getInstance()->load($filename);
// 引导参数
$this->selectMode($args); $this->selectMode($args);
Config::load($filename); $this->restoreMode($args);
return $this; return $this;
} }
@ -66,7 +76,7 @@ class App
while (true) { while (true) {
try { try {
call_user_func(array("BiliHelper\\$dir\\" . $taskName, 'run'), []); call_user_func(array("BiliHelper\\$dir\\" . $taskName, 'run'), []);
} catch (\Throwable $e) { } catch (Throwable $e) {
// TODO 多次错误删除tasks_***.json文件 // TODO 多次错误删除tasks_***.json文件
$error_msg = "MSG: {$e->getMessage()} CODE: {$e->getCode()} FILE: {$e->getFile()} LINE: {$e->getLine()}"; $error_msg = "MSG: {$e->getMessage()} CODE: {$e->getCode()} FILE: {$e->getFile()} LINE: {$e->getLine()}";
Log::error($error_msg); Log::error($error_msg);
@ -90,7 +100,7 @@ class App
'DelDynamic' => '批量清理动态(未完成)' 'DelDynamic' => '批量清理动态(未完成)'
]; ];
$choice = \BiliHelper\Script\BaseTask::choice($scripts, 'UnFollow'); $choice = BaseTask::choice($scripts, 'UnFollow');
$this->newTask($choice, 'Script'); $this->newTask($choice, 'Script');
} }
@ -154,6 +164,19 @@ class App
} }
} }
/**
* @use 复位模式
* @param object $args
*/
private function restoreMode(object $args)
{
// 复位 后期添加其他复位
if ($args->restore) {
Task::getInstance()->restore();
}
}
/** /**
* @use 核心运行 * @use 核心运行
*/ */

View File

@ -11,11 +11,12 @@
namespace BiliHelper\Core; namespace BiliHelper\Core;
use Ahc\Cli\Input\Command; use Ahc\Cli\Input\Command;
use Exception;
class BCommand class BCommand
{ {
private $argv; private array $argv;
/** /**
* Command constructor. * Command constructor.
@ -30,10 +31,12 @@ class BCommand
{ {
$cli = new Command('BHP-S', 'BHP命令行工具.'); $cli = new Command('BHP-S', 'BHP命令行工具.');
$cli->version('0.0.1-dev') $cli->version('0.0.1-dev')
->option('-s --script', '执行的Script模式.',null,false); ->option('-s --script', '执行的Script模式.', null, false)
->option('-r --restore', '任务排程复位(暂定).', null, false);
try { try {
$args = $cli->parse($this->argv); $args = $cli->parse($this->argv);
} catch (\Exception $e) { } catch (Exception $e) {
Log::error($e->getMessage());
die('解析命令行参数错误'); die('解析命令行参数错误');
} }
return $args; return $args;

102
src/core/Cache.php Normal file
View File

@ -0,0 +1,102 @@
<?php
/**
* Website: https://mudew.com/
* Author: Lkeme
* License: The MIT License
* Email: Useri@live.cn
* Updated: 2021 ~ 2022
* Source: https://github.com/fzaninotto/Faker/
*/
namespace BiliHelper\Core;
use BiliHelper\Util\Singleton;
use Flintstone\Flintstone;
use Flintstone\Formatter\JsonFormatter;
class Cache
{
use Singleton;
private array $caches;
private Flintstone $cache;
// 文档
// https://www.xeweb.net/flintstone/documentation/
/**
* @use 加载一个缓存
* @param string $classname
* @return \BiliHelper\Core\Cache
*/
private function load(string $classname): static
{
if (!isset($this->caches[$classname])) {
// 如果不存在缓存 初始化 "BHP_username_APP.dat"
$this->caches[$classname] = new Flintstone(
'BHP_' . getConf('username', 'login.account') . '_' . $classname, [
'dir' => APP_CACHE_PATH,
'gzip' => true,
'formatter' => new JsonFormatter()
]);
}
$this->cache = $this->caches[$classname];
return $this;
// self::$instance->set('bob', ['email' => 'bob@site.com', 'password' => '123456']);
}
/**
* @use 获取调用链类
* @return mixed
*/
private function backtraceClass(): mixed
{
// TODO 耦合度过高 需要解耦
$backtraces = debug_backtrace();
array_shift($backtraces);
return pathinfo(basename($backtraces[2]['file']))['filename'];
}
/**
* @use 获取调用类
* @param string $classname
* @return $this
*/
private function getClassObj(string $classname): static
{
if ($classname == '') {
$classname = $this->backtraceClass();
}
return $this->load($classname);
}
/**
* @use 获取值
* @param string $key
* @param string $extra_name
* @return mixed
*/
public function _get(string $key, string $extra_name = ''): mixed
{
// Get a key
// $user = $users->get('bob');
// echo 'Bob, your email is ' . $user['email'];
return $this->getClassObj($extra_name)->cache->get($key);
}
/**
* @use 写入值
* @param string $key
* @param $data
* @param string $extra_name
*/
public function _set(string $key, $data, string $extra_name = '')
{
// Set a key
// $users->set('bob', ['email' => 'bob@site.com', 'password' => '123456']);
$this->getClassObj($extra_name)->cache->set($key, $data);
}
}

View File

@ -10,96 +10,71 @@
namespace BiliHelper\Core; namespace BiliHelper\Core;
use BiliHelper\Util\Singleton;
use Jelix\IniFile\IniModifier; use Jelix\IniFile\IniModifier;
class Config class Config
{ {
private static $app_config; use Singleton;
private static $load_file;
private static $last_time; private string|array $load_file;
private static $config_path; private int|false $last_time;
private static $instance; private IniModifier $app_config;
private string $config_path;
private static function getInstance(): Config
{
if (is_null(self::$instance)) {
self::$instance = new static;
}
return self::$instance;
}
/** /**
* @use 加载配置 * @use 加载配置
* @param string $load_file * @param string $load_file
*/ */
public static function load(string $load_file) public function load(string $load_file)
{ {
$config_path = str_replace("\\", "/", APP_CONF_PATH . $load_file); $config_path = str_replace("\\", "/", APP_CONF_PATH . $load_file);
if (!is_file($config_path)) { if (!is_file($config_path)) {
die("配置文件 {$load_file} 加载错误,请参照文档添加配置文件!"); die("配置文件 $load_file 加载错误,请参照文档添加配置文件!");
} }
// 给静态参数赋值 $this->load_file = $load_file;
self::$load_file = $load_file; $this->config_path = $config_path;
self::$config_path = $config_path;
// $config_path = dirname($config_path).DIRECTORY_SEPARATOR.$load_file; // $config_path = dirname($config_path).DIRECTORY_SEPARATOR.$load_file;
self::$app_config = new IniModifier(self::$config_path); $this->app_config = new IniModifier($this->config_path);
self::$last_time = fileatime(self::$config_path); $this->last_time = fileatime($this->config_path);
} }
public static function _set($name, $value, $section = 0, $key = null) /**
* @use 写入值
* @param $name
* @param $value
* @param int|string $section
* @param null $key
* @throws \Jelix\IniFile\IniException
*/
public function _set($name, $value, int|string $section = 0, $key = null)
{ {
$_instance = self::getInstance(); $this->app_config->setValue($name, $value, $section, $key);
$_instance::$app_config->setValue($name, $value, $section, $key); $this->app_config->save();
$_instance::$app_config->save();
// 保存修改时间 // 保存修改时间
$_instance::$last_time = fileatime($_instance::$config_path); $this->last_time = fileatime($this->config_path);
} }
public static function _get($name, $section = 0, $key = null) /**
* @use 获取值
* @param $name
* @param int|string $section
* @param null $key
* @return mixed
*/
public function _get($name, int|string $section = 0, $key = null): mixed
{ {
$_instance = self::getInstance();
// 判断是否被修改 重新加载文件 // 判断是否被修改 重新加载文件
// echo $_instance::$last_time.PHP_EOL; // echo $this->last_time.PHP_EOL;
// echo fileatime($_instance::$config_path); // echo fileatime($this->config_path);
if (fileatime($_instance::$config_path) != $_instance::$last_time) { if (fileatime($this->config_path) != $this->last_time) {
$_instance::load($_instance::$load_file); $this->load($this->load_file);
} }
return $_instance::$app_config->getValue($name, $section, $key); return $this->app_config->getValue($name, $section, $key);
}
public static function _put()
{
$_instance = self::getInstance();
}
public static function _del()
{
$_instance = self::getInstance();
}
/**
* 不允许从外部调用以防止创建多个实例
* 要使用单例,必须通过 Singleton::getInstance() 方法获取实例
*/
private function __construct()
{
}
/**
* 防止实例被克隆(这会创建实例的副本)
*/
private function __clone()
{
}
/**
* 防止反序列化(这将创建它的副本)
*/
public function __wakeup()
{
} }
} }

View File

@ -10,15 +10,19 @@
namespace BiliHelper\Core; namespace BiliHelper\Core;
use Exception;
use GuzzleHttp\Pool;
use GuzzleHttp\Client;
use BiliHelper\Tool\Generator; use BiliHelper\Tool\Generator;
use GuzzleHttp\Exception\RequestException;
class Curl class Curl
{ {
private static $client; private static Client $client;
private static $async_opt; private static array $async_opt;
private static $results = []; private static array $results = [];
private static $result = []; private static array $result = [];
private static $buvid = ''; private static string $buvid = '';
/** /**
* @use POST请求 * @use POST请求
@ -26,15 +30,15 @@ class Curl
* @param $url * @param $url
* @param array $params * @param array $params
* @param array $headers * @param array $headers
* @param int $timeout * @param float $timeout
* @return mixed * @return mixed
*/ */
public static function post($os, $url, $params = [], $headers = [], $timeout = 30) public static function post($os, $url, array $params = [], array $headers = [], float $timeout = 30.0): mixed
{ {
Log::debug("POST: {$url}"); Log::debug("POST: $url");
$headers = self::getHeaders($os, $headers); $headers = self::getHeaders($os, $headers);
$payload['form_params'] = count($params) ? $params : []; $payload['form_params'] = count($params) ? $params : [];
$options = self::getClientOpt($payload, $headers); $options = self::getClientOpt($payload, $headers, $timeout);
$request = self::clientHandle($url, 'post', $options); $request = self::clientHandle($url, 'post', $options);
$body = $request->getBody(); $body = $request->getBody();
Log::debug($body); Log::debug($body);
@ -47,15 +51,15 @@ class Curl
* @param $url * @param $url
* @param array $params * @param array $params
* @param array $headers * @param array $headers
* @param int $timeout * @param float $timeout
* @return mixed * @return mixed
*/ */
public static function get($os, $url, $params = [], $headers = [], $timeout = 30) public static function get($os, $url, array $params = [], array $headers = [], float $timeout = 30.0): mixed
{ {
Log::debug("GET: {$url}"); Log::debug("GET: $url");
$headers = self::getHeaders($os, $headers); $headers = self::getHeaders($os, $headers);
$payload['query'] = count($params) ? $params : []; $payload['query'] = count($params) ? $params : [];
$options = self::getClientOpt($payload, $headers); $options = self::getClientOpt($payload, $headers, $timeout);
$request = self::clientHandle($url, 'get', $options); $request = self::clientHandle($url, 'get', $options);
$body = $request->getBody(); $body = $request->getBody();
Log::debug($body); Log::debug($body);
@ -68,15 +72,15 @@ class Curl
* @param $url * @param $url
* @param array $params * @param array $params
* @param array $headers * @param array $headers
* @param int $timeout * @param float $timeout
* @return mixed * @return mixed
*/ */
public static function put($os, $url, $params = [], $headers = [], $timeout = 30) public static function put($os, $url, array $params = [], array $headers = [], float $timeout = 30.0): mixed
{ {
Log::debug("PUT: {$url}"); Log::debug("PUT: $url");
$headers = self::getHeaders($os, $headers); $headers = self::getHeaders($os, $headers);
$payload['json'] = count($params) ? $params : []; $payload['json'] = count($params) ? $params : [];
$options = self::getClientOpt($payload, $headers); $options = self::getClientOpt($payload, $headers, $timeout);
$request = self::clientHandle($url, 'post', $options); $request = self::clientHandle($url, 'post', $options);
$body = $request->getBody(); $body = $request->getBody();
Log::debug($body); Log::debug($body);
@ -89,10 +93,10 @@ class Curl
* @param $url * @param $url
* @param array $tasks * @param array $tasks
* @param array $headers * @param array $headers
* @param int $timeout * @param float $timeout
* @return array * @return array
*/ */
public static function async($os, $url, $tasks = [], $headers = [], $timeout = 30): array public static function async($os, $url, array $tasks = [], array $headers = [], float $timeout = 30.0): array
{ {
self::$async_opt = [ self::$async_opt = [
'tasks' => $tasks, 'tasks' => $tasks,
@ -100,18 +104,18 @@ class Curl
'count' => count($tasks), 'count' => count($tasks),
'concurrency' => count($tasks) < 10 ? count($tasks) : 10 'concurrency' => count($tasks) < 10 ? count($tasks) : 10
]; ];
Log::debug("ASYNC: {$url}"); Log::debug("ASYNC: $url");
$headers = self::getHeaders($os, $headers); $headers = self::getHeaders($os, $headers);
$requests = function ($total) use ($url, $headers, $tasks) { $requests = function ($total) use ($url, $headers, $tasks, $timeout) {
foreach ($tasks as $task) { foreach ($tasks as $task) {
yield function () use ($url, $headers, $task) { yield function () use ($url, $headers, $task, $timeout) {
$payload['form_params'] = $task['payload']; $payload['form_params'] = $task['payload'];
$options = self::getClientOpt($payload, $headers); $options = self::getClientOpt($payload, $headers, $timeout);
return self::clientHandle($url, 'postAsync', $options); return self::clientHandle($url, 'postAsync', $options);
}; };
} }
}; };
$pool = new \GuzzleHttp\Pool(self::$client, $requests(self::$async_opt['count']), [ $pool = new Pool(self::$client, $requests(self::$async_opt['count']), [
'concurrency' => self::$async_opt['concurrency'], 'concurrency' => self::$async_opt['concurrency'],
'fulfilled' => function ($response, $index) { 'fulfilled' => function ($response, $index) {
$res = $response->getBody(); $res = $response->getBody();
@ -123,7 +127,7 @@ class Curl
self::countedAndCheckEnded(); self::countedAndCheckEnded();
}, },
'rejected' => function ($reason, $index) { 'rejected' => function ($reason, $index) {
Log::error("多线程第{$index}个请求失败, ERROR: {$reason}"); Log::error("多线程第 $index 个请求失败, ERROR: $reason");
self::countedAndCheckEnded(); self::countedAndCheckEnded();
}, },
]); ]);
@ -142,9 +146,9 @@ class Curl
* @param int $timeout * @param int $timeout
* @return false|string|null * @return false|string|null
*/ */
public static function request($method, $url, $payload = [], $headers = [], $timeout = 10) public static function request($method, $url, array $payload = [], array $headers = [], int $timeout = 10): bool|string|null
{ {
Log::debug("REQUEST: {$url}"); Log::debug("REQUEST: $url");
$options = array( $options = array(
'http' => array( 'http' => array(
'method' => strtoupper($method), 'method' => strtoupper($method),
@ -178,23 +182,23 @@ class Curl
* @param array $options * @param array $options
* @return mixed * @return mixed
*/ */
private static function clientHandle(string $url, string $method, array $options) private static function clientHandle(string $url, string $method, array $options): mixed
{ {
$max_retry = range(1, 40); $max_retry = range(1, 40);
foreach ($max_retry as $retry) { foreach ($max_retry as $retry) {
try { try {
$response = call_user_func_array([self::$client, $method], [$url, $options]); $response = call_user_func_array([self::$client, $method], [$url, $options]);
if (is_null($response) or empty($response)) throw new \Exception("Value IsEmpty"); if (is_null($response) or empty($response)) throw new Exception("Value IsEmpty");
return $response; return $response;
} catch (\GuzzleHttp\Exception\RequestException $e) { } catch (RequestException $e) {
// var_dump($e->getRequest()); // var_dump($e->getRequest());
if ($e->hasResponse()) var_dump($e->getResponse()); if ($e->hasResponse()) var_dump($e->getResponse());
} catch (\Exception $e) { } catch (Exception $e) {
// $e->getHandlerContext() // $e->getHandlerContext()
// var_dump($e); // var_dump($e);
} }
Log::warning("Target -> URL: {$url} METHOD: {$method}"); Log::warning("Target -> URL: $url METHOD: $method");
Log::warning("CURl -> RETRY: {$retry} ERROR: {$e->getMessage()} ERRNO: {$e->getCode()} STATUS: Waiting for recovery!"); Log::warning("CURl -> RETRY: $retry ERROR: {$e->getMessage()} ERRNO: {$e->getCode()} STATUS: Waiting for recovery!");
sleep(15); sleep(15);
} }
exit('网络异常,超出最大尝试次数,退出程序~'); exit('网络异常,超出最大尝试次数,退出程序~');
@ -209,7 +213,7 @@ class Curl
*/ */
private static function getClientOpt(array $add_options, array $headers = [], float $timeout = 30.0): array private static function getClientOpt(array $add_options, array $headers = [], float $timeout = 30.0): array
{ {
self::$client = new \GuzzleHttp\Client(); self::$client = new Client();
$default_options = [ $default_options = [
'headers' => $headers, 'headers' => $headers,
'timeout' => $timeout, 'timeout' => $timeout,
@ -231,8 +235,16 @@ class Curl
private static function getHeaders(string $os = 'app', array $headers = []): array private static function getHeaders(string $os = 'app', array $headers = []): array
{ {
if (!self::$buvid) { if (!self::$buvid) {
// 缓存开始 如果存在就赋值 否则默认值
if ($temp = getCache('buvid')) {
self::$buvid = $temp;
} else {
self::$buvid = Generator::buvid(); self::$buvid = Generator::buvid();
} }
// 缓存结束 需要的数据的放进缓存
setCache('buvid', self::$buvid);
}
$app_headers = [ $app_headers = [
'env' => 'prod', 'env' => 'prod',
'APP-KEY' => 'android', 'APP-KEY' => 'android',
@ -241,21 +253,21 @@ class Curl
'Accept-Encoding' => 'gzip', 'Accept-Encoding' => 'gzip',
'Accept-Language' => 'zh-cn', 'Accept-Language' => 'zh-cn',
'Connection' => 'keep-alive', 'Connection' => 'keep-alive',
'User-Agent' => getDevice('device.app_headers.ua'),
// 'Content-Type' => 'application/x-www-form-urlencoded', // '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/5.51.1 (bbcallen@gmail.com)',
'User-Agent' => 'Mozilla/5.0 BiliDroid/6.36.0 (bbcallen@gmail.com) os/android model/MuMu mobi_app/android build/6360400 channel/bili innerVer/6360400 osVer/7.1.2 network/2',
// 'Referer' => 'https://live.bilibili.com/', // 'Referer' => 'https://live.bilibili.com/',
]; ];
$pc_headers = [ $pc_headers = [
'Accept' => "application/json, text/plain, */*", 'Accept' => "application/json, text/plain, */*",
'Accept-Encoding' => 'gzip, deflate', 'Accept-Encoding' => 'gzip, deflate',
'Accept-Language' => "zh-CN,zh;q=0.9", 'Accept-Language' => "zh-CN,zh;q=0.9",
'User-Agent' => getDevice('device.pc_headers.ua'),
// 'Content-Type' => 'application/x-www-form-urlencoded', // 'Content-Type' => 'application/x-www-form-urlencoded',
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.30 Safari/537.36 Edg/90.0.818.8',
// 'Referer' => 'https://live.bilibili.com/', // 'Referer' => 'https://live.bilibili.com/',
]; ];
$other_headers = [ $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', 'User-Agent' => getDevice('device.other_headers.ua')
]; ];
$default_headers = ${$os . "_headers"} ?? $other_headers; $default_headers = ${$os . "_headers"} ?? $other_headers;
if (in_array($os, ['app', 'pc']) && getCookie() != "") { if (in_array($os, ['app', 'pc']) && getCookie() != "") {
@ -279,14 +291,13 @@ class Curl
/** /**
* @use 关联数组转字符串 * @use 关联数组转字符串
* @param array $array * @param array $array
* @param string $separator
* @return string * @return string
*/ */
private static function arr2str(array $array, string $separator = "\r\n"): string private static function arr2str(array $array): string
{ {
$tmp = ''; $tmp = '';
foreach ($array as $key => $value) { foreach ($array as $key => $value) {
$tmp .= "{$key}:{$value}{$separator}"; $tmp .= "$key:$value\r\n";
} }
return $tmp; return $tmp;
} }
@ -297,16 +308,16 @@ class Curl
* @param $url * @param $url
* @param array $params * @param array $params
* @param array $headers * @param array $headers
* @param int $timeout * @param float $timeout
* @return mixed * @return mixed
*/ */
public static function headers($os, $url, $params = [], $headers = [], $timeout = 30) public static function headers($os, $url, array $params = [], array $headers = [], float $timeout = 30.0): mixed
{ {
Log::debug('HEADERS: ' . $url); Log::debug('HEADERS: ' . $url);
$headers = self::getHeaders($os, $headers); $headers = self::getHeaders($os, $headers);
$payload['query'] = count($params) ? $params : []; $payload['query'] = count($params) ? $params : [];
$payload['allow_redirects'] = false; $payload['allow_redirects'] = false;
$options = self::getClientOpt($payload, $headers); $options = self::getClientOpt($payload, $headers, $timeout);
$request = self::clientHandle($url, 'get', $options); $request = self::clientHandle($url, 'get', $options);
Log::debug("获取Headers"); Log::debug("获取Headers");
return $request->getHeaders(); return $request->getHeaders();

67
src/core/Device.php Normal file
View File

@ -0,0 +1,67 @@
<?php
/**
* Website: https://mudew.com/
* Author: Lkeme
* License: The MIT License
* Email: Useri@live.cn
* Updated: 2021 ~ 2022
*/
namespace BiliHelper\Core;
use BiliHelper\Util\Singleton;
use Consolidation\Config\Config;
use Consolidation\Config\Loader\YamlConfigLoader;
use Consolidation\Config\Loader\ConfigProcessor;
class Device
{
use Singleton;
private Config $device;
private string $bili_file = 'bili.yaml';
private string $device_file = 'device.yaml';
/**
* 加载配置
*/
public function load(string $load_file)
{
// 提前处理 后缀
$custom_file = str_replace(strrchr($load_file, "."), "", $load_file) . '_';
// 自定义客户端
if (is_file(APP_CONF_PATH . $custom_file . $this->bili_file)) {
$this->bili_file = APP_CONF_PATH . $custom_file . $this->bili_file;
Log::info('使用自定义Bili.yaml');
}
// 自定义设备
if (is_file(APP_CONF_PATH . $custom_file . $this->device_file)) {
$this->device_file = APP_CONF_PATH . $custom_file . $this->device_file;
Log::info('使用自定义Device.yaml');
}
// 加载数据
$this->device = new Config();
$loader = new YamlConfigLoader();
$processor = new ConfigProcessor();
$files = [$this->bili_file, $this->device_file];
// 循环加载
foreach ($files as $file) {
$processor->extend($loader->load(APP_CONF_PATH . $file));
}
$this->device->import($processor->export());
}
/**
* @use 获取值
* @param $key
* @param null $defaultFallback
* @return mixed
*/
public function _get($key, $defaultFallback = null): mixed
{
return $this->device->get($key, $defaultFallback);
}
}

View File

@ -14,12 +14,12 @@ use Noodlehaus\Config;
class Env class Env
{ {
private $app_name; private string $app_name;
private $app_version; private string $app_version;
private $app_branch; private string $app_branch;
private $app_source; private string $app_source;
private $repository = APP_DATA_PATH . 'latest_version.json'; private string $repository = APP_DATA_PATH . 'latest_version.json';
/** /**
@ -45,9 +45,9 @@ class Env
$default_extensions = ['curl', 'openssl', 'sockets', 'json', 'zlib', 'mbstring']; $default_extensions = ['curl', 'openssl', 'sockets', 'json', 'zlib', 'mbstring'];
foreach ($default_extensions as $extension) { foreach ($default_extensions as $extension) {
if (!extension_loaded($extension)) { if (!extension_loaded($extension)) {
Log::error("检查到项目依赖 {$extension} 扩展未加载。"); Log::error("检查到项目依赖 $extension 扩展未加载。");
Log::error("请在 php.ini中启用 {$extension} 扩展后重试。"); Log::error("请在 php.ini中启用 $extension 扩展后重试。");
Log::error("程序常见问题请移步 {$this->app_source} 文档部分查看。"); Log::error("程序常见问题请移步 $this->app_source 文档部分查看。");
exit(); exit();
} }
} }
@ -58,18 +58,18 @@ class Env
*/ */
public function inspect_configure(): Env public function inspect_configure(): Env
{ {
Log::info("欢迎使用 项目: {$this->app_name}@{$this->app_branch} 版本: {$this->app_version}"); Log::info("欢迎使用 项目: $this->app_name@$this->app_branch 版本: $this->app_version");
Log::info("使用说明请移步 {$this->app_source} 查看"); Log::info("使用说明请移步 $this->app_source 查看");
if (PHP_SAPI != 'cli') { if (PHP_SAPI != 'cli') {
die("Please run this script from command line ."); die("Please run this script from command line .");
} }
if (version_compare(PHP_VERSION, '7.3.0', '<')) { // if (version_compare(PHP_VERSION, '7.4.0', '<')) {
die("Please upgrade PHP version > 7.3.0 ."); // die("Please upgrade PHP version > 7.4.0 .");
}
// if (version_compare(PHP_VERSION, '8.0.0', '>')) {
// die("Please upgrade PHP version < 8.0.0 .");
// } // }
if (version_compare(PHP_VERSION, '8.0.0', '<')) {
die("Please upgrade PHP version < 8.0.0 .");
}
return $this; return $this;
} }

View File

@ -8,46 +8,33 @@
* Updated: 2021 ~ 2022 * Updated: 2021 ~ 2022
*/ */
use BiliHelper\Core\Cache;
use BiliHelper\Core\Config; use BiliHelper\Core\Config;
use BiliHelper\Core\Device;
/** /**
* @use 读取 * @use 配置读取
* @param $name * @param $name
* @param int $section * @param int|string $section
* @param null $key * @param null $key
* @return mixed * @return mixed
*/ */
function getConf($name, $section = 0, $key = null) function getConf($name, int|string $section = 0, $key = null): mixed
{ {
return Config::_get($name, $section, $key); return Config::getInstance()->_get($name, $section, $key);
} }
/** /**
* @use 写入 * @use 配置写入
* @param $name * @param $name
* @param $value * @param $value
* @param int $section * @param int|string $section
* @param null $key * @param null $key
* @throws \Jelix\IniFile\IniException
*/ */
function setConf($name, $value, $section = 0, $key = null) function setConf($name, $value, int|string $section = 0, $key = null)
{ {
Config::_set($name, $value, $section, $key); Config::getInstance()->_set($name, $value, $section, $key);
}
/**
* @use 更新
*/
function putConf()
{
}
/**
* @use 删除
*/
function delConf()
{
} }
/** /**
@ -105,13 +92,35 @@ function getCsrf(): string
return getConf('csrf', 'login.auth'); return getConf('csrf', 'login.auth');
} }
/**
* @use 获取设备信息
* @param $key
* @param null $defaultFallback
* @return mixed
*/
function getDevice($key, $defaultFallback = null): mixed
{
return Device::getInstance()->_get($key, $defaultFallback);
}
/** /**
* @use HttpClient * @use 缓存读取
* @param string $url * @param string $key
* @return \HttpClient * @param string $extra_name
* @return mixed
*/ */
function newHttp(string $url): HttpClient function getCache(string $key, string $extra_name = ''): mixed
{ {
return new HttpClient($url); return Cache::getInstance()->_get($key, $extra_name);
}
/**
* @use 缓存写入
* @param string $key
* @param $data
* @param string $extra_name
*/
function setCache(string $key, $data, string $extra_name = '')
{
Cache::getInstance()->_set($key, $data, $extra_name);
} }

View File

@ -13,147 +13,157 @@ namespace BiliHelper\Core;
class HttpClient class HttpClient
{ {
private $ch; // private $ch;
private $ret; // private $ret;
private $form; // private $form;
private $headers; // private $headers;
private $url; // private $url;
private $query; // private $query;
//
public function __construct(string $url) // public function __construct(string $url)
{ // {
$this->ch = curl_init(); // $this->ch = curl_init();
$this->url = $url; // $this->url = $url;
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false); //忽略 HTTPS 证书错误 // 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"); // $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() // function __destruct()
{ // {
//防止内存泄露 // //防止内存泄露
curl_close($this->ch); // curl_close($this->ch);
} // }
//
/** // /**
* @use 设置UA // * @use 设置UA
* @param string $ua // * @param string $ua
* @return $this // * @return $this
*/ // */
public function setUA(string $ua): HttpClient // public function setUA(string $ua): HttpClient
{ // {
curl_setopt($this->ch, CURLOPT_USERAGENT, $ua); //设置 UA // curl_setopt($this->ch, CURLOPT_USERAGENT, $ua); //设置 UA
return $this; // return $this;
} // }
//
/** // /**
* @use 添加Header // * @use 添加Header
* @param string $header // * @param string $header
* @return $this // * @return $this
*/ // */
public function addHeader(string $header): HttpClient // public function addHeader(string $header): HttpClient
{ // {
array_push($this->headers, $header); // array_push($this->headers, $header);
return $this; // return $this;
} // }
//
/** // /**
* @use 添加Headers // * @use 添加Headers
* @param array $headers // * @param array $headers
* @return $this // * @return $this
*/ // */
public function addHeaders(array $headers): HttpClient // public function addHeaders(array $headers): HttpClient
{ // {
foreach ($headers as $key => $value) { // foreach ($headers as $key => $value) {
array_push($this->headers, "{$key}: {$value}"); // array_push($this->headers, "{$key}: {$value}");
} // }
return $this; // return $this;
} // }
//
/** // /**
* @use 设置Cookie // * @use 设置Cookie
* @param string $cookie // * @param string $cookie
* @return $this // * @return $this
*/ // */
public function setCookie(string $cookie): HttpClient // public function setCookie(string $cookie): HttpClient
{ // {
curl_setopt($this->ch, CURLOPT_COOKIE, $cookie); // curl_setopt($this->ch, CURLOPT_COOKIE, $cookie);
return $this; // return $this;
} // }
//
/** // /**
* @use 设置 url 参数 // * @use 设置 url 参数
*/ // */
public function buildQuery(array $query): HttpClient // public function buildQuery(array $query): HttpClient
{ // {
$this->query = http_build_query($query); // $this->query = http_build_query($query);
return $this; // return $this;
} // }
//
/** // /**
* @use 自动将 json 文本解码 // * @use 自动将 json 文本解码
*/ // */
public function asJSON(): object // public function asJSON(): object
{ // {
return json_decode($this->ret); // return json_decode($this->ret);
} // }
//
/** // /**
* @use 获取返回结果 // * @use 获取返回结果
*/ // */
public function asString(): string // public function asString(): string
{ // {
return $this->ret; // return $this->ret;
} // }
//
/** // /**
* @use 构造POST表单 // * @use 构造POST表单
* @param array $form // * @param array $form
* @return $this // * @return $this
*/ // */
public function buildPostForm(array $form): HttpClient // public function buildPostForm(array $form): HttpClient
{ // {
$this->form = http_build_query($form); // $this->form = http_build_query($form);
//
return $this; // return $this;
} // }
//
/** // /**
* @use 发送 Get 请求 // * @use 发送 Get 请求
*/ // */
public function get(): HttpClient // public function get(): HttpClient
{ // {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "?" . $this->query); // curl_setopt($this->ch, CURLOPT_URL, $this->url . "?" . $this->query);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中 // curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中
curl_setopt($this->ch, CURLOPT_HEADER, $this->headers); // curl_setopt($this->ch, CURLOPT_HEADER, $this->headers);
$this->ret = curl_exec($this->ch); // $this->ret = curl_exec($this->ch);
return $this; // return $this;
} // }
//
/** // /**
* @use 发送 POST 请求 // * @use 发送 POST 请求
* @param string|null $data POST 的数据 // * @param string|null $data 要 POST 的数据
* @return \HttpClient // * @return \HttpClient
*/ // */
public function post(string $data = null): HttpClient // public function post(string $data = null): HttpClient
{ // {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "?" . $this->query); // curl_setopt($this->ch, CURLOPT_URL, $this->url . "?" . $this->query);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中 // curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中
curl_setopt($this->ch, CURLOPT_POST, true); // 发送 POST 请求 // curl_setopt($this->ch, CURLOPT_POST, true); // 发送 POST 请求
curl_setopt($this->ch, CURLOPT_HEADER, $this->headers); // curl_setopt($this->ch, CURLOPT_HEADER, $this->headers);
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data); // curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
$this->ret = curl_exec($this->ch); // $this->ret = curl_exec($this->ch);
return $this; // return $this;
} // }
//
//
/** // /**
* @use POST表单 // * @use POST表单
* @param array $form // * @param array $form
* @return $this // * @return $this
*/ // */
public function postForm(array $form): HttpClient // public function postForm(array $form): HttpClient
{ // {
return $this->post(http_build_query($form)); // return $this->post(http_build_query($form));
} // }
} }
///**
// * @use HttpClient
// * @param string $url
// * @return \BiliHelper\Core\HttpClient
// */
//function newHttp(string $url): HttpClient
//{
// return new HttpClient($url);
//}

View File

@ -49,7 +49,7 @@ class Log
{ {
if (getConf('multiple', 'print')) { if (getConf('multiple', 'print')) {
// return '[' . (getConf('user_identity', 'print') ?? getConf('username', 'login.account')) . ']'; // return '[' . (getConf('user_identity', 'print') ?? getConf('username', 'login.account')) . ']';
return sprintf("[%s]",getConf('user_identity', 'print') ?? getConf('username', 'login.account')); return sprintf("[%s]", getConf('user_identity', 'print') ?? getConf('username', 'login.account'));
} }
return ''; return '';
} }

View File

@ -10,37 +10,26 @@
namespace BiliHelper\Core; namespace BiliHelper\Core;
use BiliHelper\Tool\File;
use BiliHelper\Util\Singleton;
class Task class Task
{ {
private static $init = true; use Singleton;
private static $repository = null;
private static $instance;
/** private string $repository = '';
* @use 单例
* @return \BiliHelper\Core\Task
*/
public static function getInstance(): Task
{
if (is_null(self::$instance)) {
self::$instance = new static;
}
return self::$instance;
}
/** /**
* @use 初始化 * @use 初始化
*/ */
private static function init() protected function init()
{ {
if (self::$init) {
// 赋值仓库地址 // 赋值仓库地址
if (is_null(self::$repository)) { if ($this->repository == '') {
self::$repository = APP_TASK_PATH . 'tasks_' . getConf('username', 'login.account') . '.json'; $this->repository = APP_TASK_PATH . 'tasks_' . getConf('username', 'login.account') . '.json';
}
// 仓库不存在自动创建 // 仓库不存在自动创建
if (!file_exists(self::$repository)) { if (!file_exists($this->repository)) {
$fh = fopen(self::$repository, "w"); $fh = fopen($this->repository, "w");
fwrite($fh, "{}"); fwrite($fh, "{}");
fclose($fh); fclose($fh);
Log::info('任务排程文件不存在,初始化所有任务。'); Log::info('任务排程文件不存在,初始化所有任务。');
@ -48,18 +37,15 @@ class Task
Log::info('任务排程文件存在,继续执行所有任务。'); Log::info('任务排程文件存在,继续执行所有任务。');
} }
} }
// 限制初始化
self::$init = false;
} }
/** /**
* @use * @use
* @return array * @return array
*/ */
private static function read(): array private function read(): array
{ {
self::init(); $data = file_get_contents($this->repository);
$data = file_get_contents(self::$repository);
return json_decode($data, true); return json_decode($data, true);
} }
@ -68,10 +54,9 @@ class Task
* @param array $data * @param array $data
* @return bool * @return bool
*/ */
private static function write(array $data): bool private function write(array $data): bool
{ {
self::init(); return file_put_contents($this->repository, json_encode($data));
return file_put_contents(self::$repository, json_encode($data));
} }
/** /**
@ -80,11 +65,11 @@ class Task
* @param int $lock * @param int $lock
* @return bool * @return bool
*/ */
public static function _setLock(string $class, int $lock): bool public function _setLock(string $class, int $lock): bool
{ {
$data = self::read(); $data = $this->read();
$data[$class] = $lock; $data[$class] = $lock;
return self::write($data); return $this->write($data);
} }
/** /**
@ -92,13 +77,24 @@ class Task
* @param string $class * @param string $class
* @return int * @return int
*/ */
public static function _getLock(string $class): int public function _getLock(string $class): int
{ {
$data = self::read(); $data = $this->read();
if (array_key_exists($class, $data)) { if (array_key_exists($class, $data)) {
return $data[$class]; return $data[$class];
} }
return 0; return 0;
} }
/**
* @use 复位
*/
public function restore()
{
Log::info('复位任务排程文件。');
File::del($this->repository);
$this->repository = '';
$this->init();
}
} }

View File

@ -0,0 +1,19 @@
<?php
/**
* Website: https://mudew.com/
* Author: Lkeme
* License: The MIT License
* Email: Useri@live.cn
* Updated: 2021 ~ 2022
*/
declare(strict_types=1);
namespace BiliHelper\Exceptions;
use Exception;
class SingletonException extends Exception
{
}

View File

@ -0,0 +1,19 @@
<?php
/**
* Website: https://mudew.com/
* Author: Lkeme
* License: The MIT License
* Email: Useri@live.cn
* Updated: 2021 ~ 2022
*/
declare(strict_types=1);
namespace BiliHelper\Exceptions;
use Exception;
class TaskException extends Exception
{
}

View File

@ -20,7 +20,7 @@ class ActivityLottery
use TimeLock; use TimeLock;
use AllotTasks; use AllotTasks;
private static $repository = APP_DATA_PATH . 'activity_infos.json'; private static string $repository = APP_DATA_PATH . 'activity_infos.json';
/** /**
* @throws \JsonDecodeStream\Exception\TokenizerException * @throws \JsonDecodeStream\Exception\TokenizerException
@ -78,7 +78,7 @@ class ActivityLottery
} }
// draw_times // draw_times
$arr = range(1, $act->draw_times); $arr = range(1, $act->draw_times);
foreach ($arr as $_) { foreach ($arr as $ignored) {
self::pushTask('draw', $act); self::pushTask('draw', $act);
} }
} }
@ -153,7 +153,7 @@ class ActivityLottery
Log::notice("剩余抽奖次数 {$de_raw['data']['times']}"); Log::notice("剩余抽奖次数 {$de_raw['data']['times']}");
return true; return true;
} }
Log::warning("获取抽奖次数失败 {$raw}"); Log::warning("获取抽奖次数失败 $raw");
return false; return false;
} }
if ($de_raw['code'] == 0) { if ($de_raw['code'] == 0) {
@ -163,7 +163,7 @@ class ActivityLottery
} }
return true; return true;
} }
Log::warning("获取抽奖次数失败 {$raw}"); Log::warning("获取抽奖次数失败 $raw");
return false; return false;
} }
@ -193,7 +193,7 @@ class ActivityLottery
// {"code":75003,"message":"活动已结束","ttl":1} // {"code":75003,"message":"活动已结束","ttl":1}
// {"code":0,"message":"0","ttl":1} // {"code":0,"message":"0","ttl":1}
$de_raw = json_decode($raw, true); $de_raw = json_decode($raw, true);
Log::notice("增加抽奖机会#{$action_type} {$raw}"); Log::notice("增加抽奖机会#$action_type $raw");
if ($de_raw['code'] == 0) { if ($de_raw['code'] == 0) {
return true; return true;
@ -222,11 +222,11 @@ class ActivityLottery
]; ];
$raw = Curl::post('pc', $url, $payload, $headers); $raw = Curl::post('pc', $url, $payload, $headers);
$de_raw = json_decode($raw, true); $de_raw = json_decode($raw, true);
Log::notice("开始抽奖#{$num} {$raw}"); Log::notice("开始抽奖#$num $raw");
// {"code":0,"message":"0","ttl":1,"data":[{"id":0,"mid":4133274,"num":1,"gift_id":1152,"gift_name":"硬币x6","gift_type":0,"img_url":"https://i0.hdslb.com/bfs/activity-plat/static/b6e956937ee4aefd1e19c01283145fc0/JQ9Y9-KCm_w96_h102.png","type":5,"ctime":1596255796,"cid":0}]} // {"code":0,"message":"0","ttl":1,"data":[{"id":0,"mid":4133274,"num":1,"gift_id":1152,"gift_name":"硬币x6","gift_type":0,"img_url":"https://i0.hdslb.com/bfs/activity-plat/static/b6e956937ee4aefd1e19c01283145fc0/JQ9Y9-KCm_w96_h102.png","type":5,"ctime":1596255796,"cid":0}]}
// {"code":0,"message":"0","ttl":1,"data":[{"id":0,"mid":4133274,"ip":0,"num":1,"gift_id":0,"gift_name":"未中奖0","gift_type":0,"img_url":"","type":1,"ctime":1616825625,"cid":0,"extra":{}}]} // {"code":0,"message":"0","ttl":1,"data":[{"id":0,"mid":4133274,"ip":0,"num":1,"gift_id":0,"gift_name":"未中奖0","gift_type":0,"img_url":"","type":1,"ctime":1616825625,"cid":0,"extra":{}}]}
if ($de_raw['code'] == 0) { if ($de_raw['code'] == 0) {
$result = "活动->{$referer} 获得->{$de_raw['data'][0]['gift_name']}"; $result = "活动->$referer 获得->{$de_raw['data'][0]['gift_name']}";
Notice::push('activity_lottery', $result); Notice::push('activity_lottery', $result);
return true; return true;
} }

View File

@ -20,12 +20,12 @@ class AloneTcpClient
{ {
use TimeLock; use TimeLock;
private static $heart_lock = 0; private static int $heart_lock = 0;
private static $client = null; private static $client = null;
private static $server_addr = null; private static $server_addr = null;
private static $server_key = null; private static $server_key = null;
private static $socket_timeout = 0; private static int $socket_timeout = 0;
private static $max_errors_num = 0; // 最大连续错误5次 private static int $max_errors_num = 0; // 最大连续错误5次
/** /**
* @use 入口 * @use 入口
@ -74,10 +74,10 @@ class AloneTcpClient
* @use 数据解包 * @use 数据解包
* @param $value * @param $value
* @param string $fmt * @param string $fmt
* @return array|false * @return mixed
* @throws \Exception * @throws \Exception
*/ */
private static function unPackMsg($value, string $fmt = "N") private static function unPackMsg($value, string $fmt = "N"):mixed
{ {
return unpack($fmt, $value)[1]; return unpack($fmt, $value)[1];
} }
@ -114,9 +114,9 @@ class AloneTcpClient
/** /**
* @use 读数据 * @use 读数据
* @param $length * @param $length
* @return array|bool * @return mixed
*/ */
private static function reader($length) private static function reader($length): mixed
{ {
$data = false; $data = false;
try { try {
@ -216,7 +216,7 @@ class AloneTcpClient
switch ($data_type) { switch ($data_type) {
case 'raffle': case 'raffle':
// 抽奖推送 // 抽奖推送
Log::debug("(receive={$body})"); Log::debug("(receive=$body)");
DataTreating::distribute($raw_data['data']); DataTreating::distribute($raw_data['data']);
break; break;
case 'entered': case 'entered':
@ -229,7 +229,7 @@ class AloneTcpClient
Log::error("推送服务器异常 {$raw_data['data']['msg']}, 程序错误5次后将挂起, 请手动关闭!"); Log::error("推送服务器异常 {$raw_data['data']['msg']}, 程序错误5次后将挂起, 请手动关闭!");
if (self::$max_errors_num == 5) { if (self::$max_errors_num == 5) {
// KEY到期推送提醒 // KEY到期推送提醒
Notice::push('key_expired', ''); Notice::push('key_expired');
// 程序挂起 防止systemd无限重启导致触发过多推送提醒 // 程序挂起 防止systemd无限重启导致触发过多推送提醒
sleep(86400); sleep(86400);
exit(); exit();
@ -258,7 +258,7 @@ class AloneTcpClient
default: default:
// 未知信息 // 未知信息
var_dump($raw_data); var_dump($raw_data);
Log::info("出现未知信息 {$body}"); Log::info("出现未知信息 $body");
// 出现未知信息 处理重连 防止内存益处 // 出现未知信息 处理重连 防止内存益处
self::reConnect(); self::reConnect();
break; break;
@ -278,8 +278,7 @@ class AloneTcpClient
} }
$filename = $path . getConf('username', 'login.account') . ".log"; $filename = $path . getConf('username', 'login.account') . ".log";
$date = date('[Y-m-d H:i:s] '); $date = date('[Y-m-d H:i:s] ');
$data = "[{$date}]{$message}" . PHP_EOL; $data = "[$date]$message" . PHP_EOL;
file_put_contents($filename, $data, FILE_APPEND); file_put_contents($filename, $data, FILE_APPEND);
return;
} }
} }

View File

@ -19,18 +19,18 @@ class AnchorRaffle extends BaseRaffle
const ACTIVE_TITLE = '天选之子'; const ACTIVE_TITLE = '天选之子';
const ACTIVE_SWITCH = 'live_anchor'; const ACTIVE_SWITCH = 'live_anchor';
protected static $wait_list = []; protected static array $wait_list = [];
protected static $finish_list = []; protected static array $finish_list = [];
protected static $all_list = []; protected static array $all_list = [];
// 过滤类型 // 过滤类型
private static $filter_type = []; private static array $filter_type = [];
// 默认关注 特殊关注 等待关注 // 默认关注 特殊关注 等待关注
private static $default_follows = []; private static array $default_follows = [];
private static $special_follows = []; private static array $special_follows = [];
public static $wait_un_follows = []; public static array $wait_un_follows = [];
// 特殊分组 分组ID // 特殊分组 分组ID
private static $group_name = "玄不改非"; // 氪不改命 private static string $group_name = "玄不改非"; // 氪不改命
private static $group_id = null; private static int|null $group_id = null;
/** /**
@ -64,9 +64,9 @@ class AnchorRaffle extends BaseRaffle
self::$group_id = $tag_id ?: User::createRelationTag(self::$group_name); self::$group_id = $tag_id ?: User::createRelationTag(self::$group_name);
} }
// 获取需要关注的 // 获取需要关注的
$data = Live::getRoomInfoV1($room_id); $data = Live::getRealRoomID($room_id, true);
if ($data['code'] == 0 && isset($data['data'])) { if ($data['uid']) {
$need_follow_uid = $data['data']['uid']; $need_follow_uid = $data['uid'];
} else { } else {
return; return;
} }
@ -129,7 +129,7 @@ class AnchorRaffle extends BaseRaffle
$custom_words = empty($words = getConf('filter_words', 'live_anchor')) ? [] : explode(',', $words); $custom_words = empty($words = getConf('filter_words', 'live_anchor')) ? [] : explode(',', $words);
$total_words = array_merge($default_words, $custom_words); $total_words = array_merge($default_words, $custom_words);
foreach ($total_words as $word) { foreach ($total_words as $word) {
if (strpos($prize_name, $word) !== false) { if (str_contains($prize_name, $word)) {
return true; return true;
} }
} }
@ -221,9 +221,9 @@ class AnchorRaffle extends BaseRaffle
/** /**
* @use 解析抽奖信息 * @use 解析抽奖信息
* @param array $results * @param array $results
* @return void * @return mixed
*/ */
protected static function parseLottery(array $results) protected static function parseLottery(array $results): mixed
{ {
foreach ($results as $result) { foreach ($results as $result) {
$data = $result['source']; $data = $result['source'];
@ -240,5 +240,6 @@ class AnchorRaffle extends BaseRaffle
Log::notice("房间 {$data['room_id']} 编号 {$data['raffle_id']} " . self::ACTIVE_TITLE . "-(" . $data['raffle_name'] . "): {$de_raw['message']}"); Log::notice("房间 {$data['room_id']} 编号 {$data['raffle_id']} " . self::ACTIVE_TITLE . "-(" . $data['raffle_name'] . "): {$de_raw['message']}");
} }
} }
return '';
} }
} }

View File

@ -18,12 +18,12 @@ class AwardRecord
{ {
use TimeLock; use TimeLock;
private static $raffle_lock = 0; private static int $raffle_lock = 0;
private static $raffle_list = []; private static array $raffle_list = [];
private static $anchor_lock = 0; private static int $anchor_lock = 0;
private static $anchor_list = []; private static array $anchor_list = [];
private static $gift_lock = 0; private static int $gift_lock = 0;
private static $gift_list = []; private static array $gift_list = [];
public static function run() public static function run()
{ {
@ -69,7 +69,7 @@ class AwardRecord
// 范围 // 范围
if ($day <= 2) { if ($day <= 2) {
$info = $anchor['award_name'] . 'x' . $anchor['award_num']; $info = $anchor['award_name'] . 'x' . $anchor['award_num'];
Log::notice("天选时刻于" . $anchor['end_time'] . "获奖: {$info} ,请留意查看..."); Log::notice("天选时刻于" . $anchor['end_time'] . "获奖: $info ,请留意查看...");
Notice::push('anchor', $info); Notice::push('anchor', $info);
} }
array_push(self::$anchor_list, $anchor['id']); array_push(self::$anchor_list, $anchor['id']);
@ -82,7 +82,7 @@ class AwardRecord
if (in_array($wait_un_follow['anchor_id'], self::$anchor_list)) { if (in_array($wait_un_follow['anchor_id'], self::$anchor_list)) {
AnchorRaffle::delToGroup($wait_un_follow['uid'], $wait_un_follow['anchor_id'], false); 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); AnchorRaffle::delToGroup($wait_un_follow['uid'], $wait_un_follow['anchor_id']);
} }
} }
@ -118,7 +118,7 @@ class AwardRecord
// 范围 // 范围
if ($day <= 2 && empty($raffle['update_time'])) { if ($day <= 2 && empty($raffle['update_time'])) {
$info = $raffle['gift_name'] . 'x' . $raffle['gift_num']; $info = $raffle['gift_name'] . 'x' . $raffle['gift_num'];
Log::notice("实物奖励于" . $raffle['create_time'] . "获奖: {$info} ,请留意查看..."); Log::notice("实物奖励于" . $raffle['create_time'] . "获奖: $info ,请留意查看...");
Notice::push('raffle', $info); Notice::push('raffle', $info);
} }
array_push(self::$raffle_list, $raffle['id']); array_push(self::$raffle_list, $raffle['id']);

View File

@ -13,6 +13,7 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log; use BiliHelper\Core\Log;
use BiliHelper\Core\Curl; use BiliHelper\Core\Curl;
use BiliHelper\Util\TimeLock; use BiliHelper\Util\TimeLock;
use Exception;
class Barrage class Barrage
{ {
@ -69,11 +70,12 @@ class Barrage
} }
return $data; return $data;
} }
} catch (\Exception $e) { } catch (Exception $e) {
return $e->getMessage(); return $e->getMessage();
} }
} }
/** /**
* @use 活跃弹幕 * @use 活跃弹幕
* @return bool * @return bool
@ -88,10 +90,10 @@ class Barrage
// {"code":0,"message":"你被禁言啦","msg":"你被禁言啦"} // {"code":0,"message":"你被禁言啦","msg":"你被禁言啦"}
// Todo 长度限制 // Todo 长度限制
if (isset($response['code']) && $response['code'] == 0 && isset($response['data'])) { if (isset($response['code']) && $response['code'] == 0 && isset($response['data'])) {
Log::notice("在直播间@{$room_id} 发送活跃弹幕成功 CODE -> {$response['code']}"); Log::notice("在直播间@$room_id 发送活跃弹幕成功 CODE -> {$response['code']}");
return true; return true;
} else { } else {
Log::warning("在直播间@{$room_id} 发送活跃弹幕失败 CODE -> {$response['code']} MSG -> {$response['message']} "); Log::warning("在直播间@$room_id 发送活跃弹幕失败 CODE -> {$response['code']} MSG -> {$response['message']} ");
return false; return false;
} }
} }

View File

@ -44,7 +44,6 @@ class BpConsumption
// 消费B币充值金瓜子 // 消费B币充值金瓜子
if (getConf('bp2gold', 'bp_consumption')) { if (getConf('bp2gold', 'bp_consumption')) {
self::BP2gold($bp_balance); self::BP2gold($bp_balance);
return;
} }
} }
} }
@ -76,7 +75,7 @@ class BpConsumption
Log::notice('获取钱包成功 B币券余额剩余' . $de_raw['data']['couponBalance']); Log::notice('获取钱包成功 B币券余额剩余' . $de_raw['data']['couponBalance']);
return intval($de_raw['data']['couponBalance']); return intval($de_raw['data']['couponBalance']);
} else { } else {
Log::warning("获取钱包失败 {$raw}"); Log::warning("获取钱包失败 $raw");
return 0; return 0;
} }
} }

View File

@ -24,8 +24,8 @@ class CapsuleLottery
use AllotTasks; use AllotTasks;
use XliveHeartBeat; use XliveHeartBeat;
private static $repository = APP_DATA_PATH . 'capsule_infos.json'; private static string $repository = APP_DATA_PATH . 'capsule_infos.json';
private static $interval = 60; private static int $interval = 60;
/** /**
@ -78,7 +78,7 @@ class CapsuleLottery
self::pushTask('watch', $act, true); self::pushTask('watch', $act, true);
// 抽奖次数 // 抽奖次数
$arr = range(1, $act->draw_times); $arr = range(1, $act->draw_times);
foreach ($arr as $_) { foreach ($arr as $ignored) {
self::pushTask('draw', $act); self::pushTask('draw', $act);
} }
} }
@ -155,10 +155,10 @@ class CapsuleLottery
]; ];
$raw = Curl::post('pc', $url, $payload, $headers); $raw = Curl::post('pc', $url, $payload, $headers);
$de_raw = json_decode($raw, true); $de_raw = json_decode($raw, true);
Log::notice("开始抽奖#{$num} {$raw}"); Log::notice("开始抽奖#$num $raw");
// {"code":0,"message":"0","ttl":1,"data":{"status":false,"isEntity":false,"info":{"coin":1},"awards":[{"name":"谢谢参与","num":1,"text":"谢谢参与 X 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","gift_value":""}],"text":["谢谢参与 X 1"],"isExCode":false}} // {"code":0,"message":"0","ttl":1,"data":{"status":false,"isEntity":false,"info":{"coin":1},"awards":[{"name":"谢谢参与","num":1,"text":"谢谢参与 X 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","gift_value":""}],"text":["谢谢参与 X 1"],"isExCode":false}}
if ($de_raw['code'] == 0) { if ($de_raw['code'] == 0) {
$result = "活动->{$referer} 获得->{$de_raw['data']['text'][0]}"; $result = "活动->$referer 获得->{$de_raw['data']['text'][0]}";
Notice::push('capsule_lottery', $result); Notice::push('capsule_lottery', $result);
return true; return true;
} }
@ -248,7 +248,7 @@ class CapsuleLottery
Log::info("获取剩余抽奖次数成功 {$capsule_info['data']['coin']}"); Log::info("获取剩余抽奖次数成功 {$capsule_info['data']['coin']}");
return $capsule_info['data']['coin']; return $capsule_info['data']['coin'];
} }
Log::warning("获取剩余抽奖次数失败 {$capsule_info}"); Log::warning("获取剩余抽奖次数失败 $capsule_info");
return 0; return 0;
} }

View File

@ -20,9 +20,9 @@ class CheckUpdate
{ {
use TimeLock; use TimeLock;
private static $current_conf; private static object $current_conf;
private static $latest_conf; private static object $latest_conf;
private static $repository = APP_DATA_PATH . 'latest_version.json'; private static string $repository = APP_DATA_PATH . 'latest_version.json';
public static function run() public static function run()
@ -51,7 +51,7 @@ class CheckUpdate
$time = self::$latest_conf->get('time'); $time = self::$latest_conf->get('time');
$version = self::$latest_conf->get('version'); $version = self::$latest_conf->get('version');
$des = self::$latest_conf->get('des'); $des = self::$latest_conf->get('des');
$info = "最新版本-{$version}, {$des}"; $info = "最新版本-$version, $des";
Notice::push('update', $info); Notice::push('update', $info);
} }
} }

View File

@ -73,7 +73,7 @@ class Competition
if ($de_raw['code'] == 0) { if ($de_raw['code'] == 0) {
Log::notice("破产成功: {$de_raw['message']}"); Log::notice("破产成功: {$de_raw['message']}");
} else { } else {
Log::warning("破产失败: {$raw}"); Log::warning("破产失败: $raw");
} }
} }
@ -115,7 +115,7 @@ class Competition
} }
$guess['detail_id'] = $detail['detail_id']; $guess['detail_id'] = $detail['detail_id'];
$profit = ceil($guess['count'] * $detail['odds']); $profit = ceil($guess['count'] * $detail['odds']);
$guess['estimate'] = "竞猜队伍: {$detail['option']} 预计下注: {$guess['count']} 预计赚取: {$profit} 预计亏损: {$guess['count']} (硬币)"; $guess['estimate'] = "竞猜队伍: {$detail['option']} 预计下注: {$guess['count']} 预计赚取: $profit 预计亏损: {$guess['count']} (硬币)";
return $guess; return $guess;
} }

View File

@ -36,9 +36,9 @@ class DailyTask
/** /**
* @use 检查每日任务 * @use 检查每日任务
* @return bool|mixed|string * @return mixed
*/ */
private static function check() private static function check(): mixed
{ {
$url = 'https://api.live.bilibili.com/i/api/taskInfo'; $url = 'https://api.live.bilibili.com/i/api/taskInfo';
$payload = []; $payload = [];

View File

@ -10,6 +10,8 @@
namespace BiliHelper\Plugin; namespace BiliHelper\Plugin;
use Exception;
class DataTreating class DataTreating
{ {
// Todo 独立分发 Push||Pull数据 // Todo 独立分发 Push||Pull数据
@ -23,7 +25,7 @@ class DataTreating
// room_id raffle_id raffle_title raffle_type // room_id raffle_id raffle_title raffle_type
try { try {
$info = ['rid' => $data['room_id'], 'lid' => $data['raffle_id']]; $info = ['rid' => $data['room_id'], 'lid' => $data['raffle_id']];
} catch (\Exception $e) { } catch (Exception $e) {
return; return;
} }
switch ($data['raffle_type']) { switch ($data['raffle_type']) {

View File

@ -21,7 +21,7 @@ class Dynamic
// 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 // 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
// https://t.bilibili.com/topic/name/%E5%8A%A8%E6%80%81%E6%8A%BD%E5%A5%96/feed // https://t.bilibili.com/topic/name/%E5%8A%A8%E6%80%81%E6%8A%BD%E5%A5%96/feed
private static $topic_list = [ private static array $topic_list = [
'互动抽奖' => '3230836', '互动抽奖' => '3230836',
'转发抽奖' => '434405', '转发抽奖' => '434405',
'动态抽奖' => '7146512', '动态抽奖' => '7146512',
@ -37,7 +37,7 @@ class Dynamic
]; ];
private static $article_list = []; private static array $article_list = [];
/** /**
* 获取抽奖话题下的帖子 * 获取抽奖话题下的帖子
@ -45,7 +45,7 @@ class Dynamic
public static function getAwardTopic(): array public static function getAwardTopic(): array
{ {
foreach (self::$topic_list as $t_name => $t_id) { foreach (self::$topic_list as $t_name => $t_id) {
Log::info("获取关键字 {$t_name}-{$t_id}"); Log::info("获取关键字 $t_name - $t_id");
$url = 'https://api.vc.bilibili.com/topic_svr/v1/topic_svr/topic_new?topic_id=' . $t_id; $url = 'https://api.vc.bilibili.com/topic_svr/v1/topic_svr/topic_new?topic_id=' . $t_id;
$data = Curl::request('get', $url); $data = Curl::request('get', $url);
$data = json_decode($data, true); $data = json_decode($data, true);
@ -93,7 +93,7 @@ class Dynamic
// https://api.vc.bilibili.com/topic_svr/v1/topic_svr/topic_history?topic_name=转发抽奖&offset_dynamic_id=454347930068783808 // https://api.vc.bilibili.com/topic_svr/v1/topic_svr/topic_history?topic_name=转发抽奖&offset_dynamic_id=454347930068783808
} }
$num = count(self::$article_list); $num = count(self::$article_list);
Log::info("获取到 {$num} 条有效动态"); Log::info("获取到 $num 条有效动态");
return self::$article_list; return self::$article_list;
} }
@ -210,7 +210,7 @@ class Dynamic
* @param $did * @param $did
* @return mixed * @return mixed
*/ */
public static function getDynamicDetail($did) public static function getDynamicDetail($did): mixed
{ {
$url = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail"; $url = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail";
$payload = [ $payload = [
@ -226,7 +226,7 @@ class Dynamic
* @param $did * @param $did
* @return mixed * @return mixed
*/ */
public static function getLotteryNotice($did) public static function getLotteryNotice($did): mixed
{ {
$url = 'https://api.vc.bilibili.com/lottery_svr/v1/lottery_svr/lottery_notice'; $url = 'https://api.vc.bilibili.com/lottery_svr/v1/lottery_svr/lottery_notice';
$payload = [ $payload = [
@ -240,9 +240,9 @@ class Dynamic
* 获取个人动态TAB列表 * 获取个人动态TAB列表
* @param int $uid * @param int $uid
* @param int $type_list * @param int $type_list
* @return array|mixed * @return mixed
*/ */
public static function getDynamicTab(int $uid = 0, int $type_list = 268435455) public static function getDynamicTab(int $uid = 0, int $type_list = 268435455): mixed
{ {
$uid = $uid == 0 ? getUid() : $uid; $uid = $uid == 0 ? getUid() : $uid;
$url = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new"; $url = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new";
@ -283,8 +283,8 @@ class Dynamic
$custom_words = empty($words = getConf('filter_words', 'dynamic')) ? [] : explode(',', $words); $custom_words = empty($words = getConf('filter_words', 'dynamic')) ? [] : explode(',', $words);
$total_words = array_merge($default_words, $custom_words, $common_words); $total_words = array_merge($default_words, $custom_words, $common_words);
foreach ($total_words as $word) { foreach ($total_words as $word) {
if (strpos($item['desc'], $word) !== false) { if (str_contains($item['desc'], $word)) {
Log::warning("当前动态#{$item['did']}触发关键字过滤 {$word}"); Log::warning("当前动态#{$item['did']}触发关键字过滤 $word");
return true; return true;
} }
} }
@ -296,7 +296,7 @@ class Dynamic
} }
// 过滤粉丝数量 // 过滤粉丝数量
if (($num = Live::getMidFollower((int)$item['uid'])) < getConf('min_fans_num', 'dynamic')) { if (($num = Live::getMidFollower((int)$item['uid'])) < getConf('min_fans_num', 'dynamic')) {
Log::warning("当前动态#{$item['did']}触发UP粉丝数量过滤 {$num}"); Log::warning("当前动态#{$item['did']}触发UP粉丝数量过滤 $num");
return true; return true;
} }
return false; return false;

View File

@ -27,20 +27,20 @@ class Forward
{ {
use TimeLock; use TimeLock;
public static $default_follows = []; public static array $default_follows = [];
public static $un_follows = []; public static array $un_follows = [];
public static $del_dynamic = []; public static array $del_dynamic = [];
public static $already = []; public static array $already = [];
private static $group_name = "氪可改命"; private static string $group_name = "氪可改命";
private static $group_id = null; private static int|null $group_id = null;
private static $draw_follow = []; private static array $draw_follow = [];
private static $repository = APP_DATA_PATH . 'reply_words.json'; private static string $repository = APP_DATA_PATH . 'reply_words.json';
public static function run() public static function run()
@ -86,17 +86,17 @@ class Forward
if (isset(self::$already[$did])) { if (isset(self::$already[$did])) {
//重复 //重复
Log::info("[动态抽奖]-已转发 跳过: {$did} {$article['uid']}"); Log::info("[动态抽奖]-已转发 跳过: $did {$article['uid']}");
continue; continue;
} }
// 评论 // 评论
Log::info("[动态抽奖]-评论: {$did} {$article['rid']}"); Log::info("[动态抽奖]-评论: $did {$article['rid']}");
if (Dynamic::dynamicReplyAdd($article['rid'], self::getReplyMsg())) { if (Dynamic::dynamicReplyAdd($article['rid'], self::getReplyMsg())) {
// 转发 // 转发
Log::info("[动态抽奖]-转发: {$did}"); Log::info("[动态抽奖]-转发: $did");
if (Dynamic::dynamicRepost($did, self::getReplyMsg())) { if (Dynamic::dynamicRepost($did, self::getReplyMsg())) {
// 关注 // 关注
Log::info("[动态抽奖]-关注: {$did} {$article['uid']}"); Log::info("[动态抽奖]-关注: $did {$article['uid']}");
self::addToGroup($article['uid']); // self::addToGroup($article['uid']); //
self::$already[$did] = 1; self::$already[$did] = 1;
} }
@ -122,20 +122,20 @@ class Forward
if (isset($card["item"]["miss"]) && $card["item"]["miss"] == 1) { if (isset($card["item"]["miss"]) && $card["item"]["miss"] == 1) {
$flag = true; $flag = true;
$msg = "[动态抽奖]-删除动态 源动态已删除 {$did}"; $msg = "[动态抽奖]-删除动态 源动态已删除 $did";
} }
if (isset($card["origin_extension"]['lott'])) { if (isset($card["origin_extension"]['lott'])) {
$lott = json_decode($card["origin_extension"]["lott"], true); $lott = json_decode($card["origin_extension"]["lott"], true);
if (isset($lott["lottery_time"]) && $lott["lottery_time"] <= time()) { if (isset($lott["lottery_time"]) && $lott["lottery_time"] <= time()) {
$flag = true; $flag = true;
$msg = "[动态抽奖]-删除动态 抽奖已过期 {$did}"; $msg = "[动态抽奖]-删除动态 抽奖已过期 $did";
} }
} }
if (isset($card["item"]["orig_dy_id"])) { if (isset($card["item"]["orig_dy_id"])) {
$ret = Dynamic::getLotteryNotice($card["item"]["orig_dy_id"]); $ret = Dynamic::getLotteryNotice($card["item"]["orig_dy_id"]);
if (isset($ret['data']['lottery_time']) && $ret['data']['lottery_time'] <= time()) { if (isset($ret['data']['lottery_time']) && $ret['data']['lottery_time'] <= time()) {
$flag = true; $flag = true;
$msg = "[动态抽奖]-删除动态 抽奖已过期 {$did}"; $msg = "[动态抽奖]-删除动态 抽奖已过期 $did";
} }
} }
@ -175,7 +175,7 @@ class Forward
foreach (self::$un_follows as $uid) { foreach (self::$un_follows as $uid) {
// 非转发抽奖动态关注的up 不取关 // 非转发抽奖动态关注的up 不取关
if (isset(self::$draw_follow[$uid])) { if (isset(self::$draw_follow[$uid])) {
Log::info("[动态抽奖]-未中奖-取关 {$uid}"); Log::info("[动态抽奖]-未中奖-取关 $uid");
User::setUserFollow($uid, true); User::setUserFollow($uid, true);
} }
} }
@ -193,7 +193,7 @@ class Forward
} }
$r = User::fetchTagFollowings($gid); $r = User::fetchTagFollowings($gid);
foreach ($r as $uid) { foreach ($r as $uid) {
Log::info("[清除抽奖组关注] : {$uid}"); Log::info("[清除抽奖组关注] : $uid");
User::setUserFollow($uid, true); User::setUserFollow($uid, true);
} }
} }
@ -215,8 +215,8 @@ class Forward
if (!isset($card['item']['content']) || !$msg) { if (!isset($card['item']['content']) || !$msg) {
continue; continue;
} }
if (strpos($card['item']['content'], $msg) !== false) { if (str_contains($card['item']['content'], $msg)) {
Log::info("[删除所有动态] 删除动态 {$did}"); Log::info("[删除所有动态] 删除动态 $did");
Dynamic::removeDynamic($did); Dynamic::removeDynamic($did);
} }
} }
@ -290,7 +290,7 @@ class Forward
shuffle($data); shuffle($data);
$msg = array_pop($data); $msg = array_pop($data);
} }
Log::info("已将自动回复改为\"{$msg}\""); Log::info("已将自动回复改为\"$msg\"");
return $msg; return $msg;
} }

View File

@ -76,6 +76,7 @@ class GiftHeart
} }
return false; return false;
} }
return false;
} }
} }

View File

@ -19,9 +19,9 @@ class GiftRaffle extends BaseRaffle
const ACTIVE_TITLE = '活动礼物'; const ACTIVE_TITLE = '活动礼物';
const ACTIVE_SWITCH = 'live_gift'; const ACTIVE_SWITCH = 'live_gift';
protected static $wait_list = []; protected static array $wait_list = [];
protected static $finish_list = []; protected static array $finish_list = [];
protected static $all_list = []; protected static array $all_list = [];
/** /**
* @use 解析数据 * @use 解析数据
@ -98,9 +98,9 @@ class GiftRaffle extends BaseRaffle
/** /**
* @use 解析抽奖信息 * @use 解析抽奖信息
* @param array $results * @param array $results
* @return void * @return mixed
*/ */
protected static function parseLottery(array $results) protected static function parseLottery(array $results):mixed
{ {
foreach ($results as $result) { foreach ($results as $result) {
$data = $result['source']; $data = $result['source'];
@ -123,5 +123,6 @@ class GiftRaffle extends BaseRaffle
Log::notice("房间 {$data['room_id']} 编号 {$data['raffle_id']} {$data['raffle_name']}: " . isset($de_raw['msg']) ? $de_raw['msg'] : $de_raw); Log::notice("房间 {$data['room_id']} 编号 {$data['raffle_id']} {$data['raffle_name']}: " . isset($de_raw['msg']) ? $de_raw['msg'] : $de_raw);
} }
} }
return '';
} }
} }

View File

@ -18,13 +18,13 @@ class GiftSend
{ {
use TimeLock; use TimeLock;
protected static $uid = 0; protected static int $uid = 0;
protected static $tid = 0; protected static int $tid = 0;
protected static $r_uid = 0; protected static int $r_uid = 0;
protected static $room_id = 0; protected static int $room_id = 0;
protected static $short_id = 0; protected static int $short_id = 0;
protected static $room_list = []; protected static array $room_list = [];
protected static $medal_list = []; protected static array $medal_list = [];
public static function run() public static function run()
@ -77,12 +77,12 @@ class GiftSend
if (!in_array($gift['gift_id'], [1, 6])) { if (!in_array($gift['gift_id'], [1, 6])) {
continue; continue;
} }
Log::notice("直播间 {$room_id} 需赠送亲密度 {$total_intimacy} 剩余亲密度 " . ($total_intimacy - $current_intimacy)); Log::notice("直播间 $room_id 需赠送亲密度 $total_intimacy 剩余亲密度 " . ($total_intimacy - $current_intimacy));
$amt = self::calcAmt($gift, $total_intimacy - $current_intimacy); $amt = self::calcAmt($gift, $total_intimacy - $current_intimacy);
self::sendGift($gift, $amt); self::sendGift($gift, $amt);
$current_intimacy += ($gift['gift_id'] == 6) ? ($amt * 10) : $amt; $current_intimacy += ($gift['gift_id'] == 6) ? ($amt * 10) : $amt;
if (!($current_intimacy - $total_intimacy)) { if (!($current_intimacy - $total_intimacy)) {
Log::notice("直播间 {$room_id} 亲密度 {$total_intimacy} 送满啦~送满啦~"); Log::notice("直播间 $room_id 亲密度 $total_intimacy 送满啦~送满啦~");
break; break;
} }
} }
@ -275,7 +275,7 @@ class GiftSend
if (isset($data['code']) && $data['code']) { if (isset($data['code']) && $data['code']) {
Log::warning('送礼失败!', ['msg' => $data['message']]); Log::warning('送礼失败!', ['msg' => $data['message']]);
} else { } else {
Log::notice("成功向 {$payload['biz_id']} 投喂了 {$amt}{$value['gift_name']}"); Log::notice("成功向 {$payload['biz_id']} 投喂了 $amt{$value['gift_name']}");
} }
} }
} }

View File

@ -19,9 +19,9 @@ class GuardRaffle extends BaseRaffle
const ACTIVE_TITLE = '总督舰长'; const ACTIVE_TITLE = '总督舰长';
const ACTIVE_SWITCH = 'live_guard'; const ACTIVE_SWITCH = 'live_guard';
protected static $wait_list = []; protected static array $wait_list = [];
protected static $finish_list = []; protected static array $finish_list = [];
protected static $all_list = []; protected static array $all_list = [];
/** /**
* @use 解析数据 * @use 解析数据
@ -112,9 +112,9 @@ class GuardRaffle extends BaseRaffle
/** /**
* @use 解析抽奖信息 * @use 解析抽奖信息
* @param array $results * @param array $results
* @return void * @return mixed
*/ */
protected static function parseLottery(array $results) protected static function parseLottery(array $results):mixed
{ {
foreach ($results as $result) { foreach ($results as $result) {
$data = $result['source']; $data = $result['source'];
@ -132,6 +132,7 @@ class GuardRaffle extends BaseRaffle
Log::notice("房间 {$data['room_id']} 编号 {$data['raffle_id']} {$data['raffle_name']}: " . isset($de_raw['msg']) ? $de_raw['msg'] : $de_raw); Log::notice("房间 {$data['room_id']} 编号 {$data['raffle_id']} {$data['raffle_name']}: " . isset($de_raw['msg']) ? $de_raw['msg'] : $de_raw);
} }
} }
return '';
} }
} }

View File

@ -13,16 +13,17 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log; use BiliHelper\Core\Log;
use BiliHelper\Core\Curl; use BiliHelper\Core\Curl;
use BiliHelper\Util\TimeLock; use BiliHelper\Util\TimeLock;
use JetBrains\PhpStorm\ArrayShape;
class Judge class Judge
{ {
use TimeLock; use TimeLock;
private static $retry_time = 0; private static int $retry_time = 0;
private static $wait_case_id = 0; private static int $wait_case_id = 0;
private static $wait_time = 0; private static int $wait_time = 0;
private static $min_ok_pct = 1; private static int $min_ok_pct = 1;
private static $max_ok_pct = 0; private static int $max_ok_pct = 0;
public static function run() public static function run()
{ {
@ -63,7 +64,7 @@ class Judge
self::$max_ok_pct = max(self::$max_ok_pct, $ok_pct); self::$max_ok_pct = max(self::$max_ok_pct, $ok_pct);
// user.info('更新统计投票波动情况') // user.info('更新统计投票波动情况')
} }
// Log::info("案件 {$case_id} 已经等待" . self::$wait_time . "s统计波动区间为" . self::$min_ok_pct . "-" . self::$max_ok_pct); // Log::info("案件 $case_id 已经等待" . self::$wait_time . "s统计波动区间为" . self::$min_ok_pct . "-" . self::$max_ok_pct);
if (is_null($advice)) { if (is_null($advice)) {
if (self::$wait_time >= 1200) { if (self::$wait_time >= 1200) {
// 如果case判定中波动很小则表示趋势基本一致 // 如果case判定中波动很小则表示趋势基本一致
@ -73,10 +74,10 @@ class Judge
$advice1 = self::judgeAdvice($num_judged, self::$min_ok_pct); $advice1 = self::judgeAdvice($num_judged, self::$min_ok_pct);
$advice = ($advice0 == $advice1) ? $advice0 : null; $advice = ($advice0 == $advice1) ? $advice0 : null;
} }
Log::info("判定结果 {$advice}"); Log::info("判定结果 $advice");
} else { } else {
$sleep_wait_time = ($num_judged < 300) ? 200 : 60; $sleep_wait_time = ($num_judged < 300) ? 200 : 60;
Log::info("案件 {$case_id} 暂无法判定,{$sleep_wait_time}S 后重新尝试"); Log::info("案件 $case_id 暂无法判定,{$sleep_wait_time}S 后重新尝试");
self::$wait_time += $sleep_wait_time; self::$wait_time += $sleep_wait_time;
self::$retry_time = $sleep_wait_time + time(); self::$retry_time = $sleep_wait_time + time();
self::$wait_case_id = $case_id; self::$wait_case_id = $case_id;
@ -86,7 +87,7 @@ class Judge
// 如果还不行就放弃 // 如果还不行就放弃
$decision = !is_null($advice) ? $advice : 3; $decision = !is_null($advice) ? $advice : 3;
$dicision_info = ($decision == 3) ? '作废票' : '有效票'; $dicision_info = ($decision == 3) ? '作废票' : '有效票';
Log::info("案件 {$case_id} 的投票结果:{$dicision_info}({$decision})"); Log::info("案件 $case_id 的投票结果:$dicision_info($decision)");
self::juryVote($case_id, $decision); self::juryVote($case_id, $decision);
self::initParams(); self::initParams();
return true; return true;
@ -155,17 +156,17 @@ class Judge
// {"code":25012,"message":"请勿重复投票","ttl":1} // {"code":25012,"message":"请勿重复投票","ttl":1}
$de_raw = json_decode($raw, true); $de_raw = json_decode($raw, true);
if (isset($de_raw['code']) && $de_raw['code']) { if (isset($de_raw['code']) && $de_raw['code']) {
Log::warning("案件 {$case_id} 投票失败 {$raw}"); Log::warning("案件 $case_id 投票失败 $raw");
} else { } else {
Log::notice("案件 {$case_id} 投票成功 {$raw}"); Log::notice("案件 $case_id 投票成功 $raw");
} }
} }
/** /**
* @use 案件获取 * @use 案件获取
* @return mixed|null * @return mixed
*/ */
private static function caseObtain() private static function caseObtain(): mixed
{ {
$url = 'https://api.bilibili.com/x/credit/jury/caseObtain'; $url = 'https://api.bilibili.com/x/credit/jury/caseObtain';
$payload = [ $payload = [
@ -184,19 +185,19 @@ class Judge
self::setLock(self::timing(10)); self::setLock(self::timing(10));
return null; return null;
case 25008: case 25008:
Log::info("暂时没有新的案件需要审理~ {$raw}"); Log::info("暂时没有新的案件需要审理~ $raw");
return null; return null;
case 25014: case 25014:
Log::info("今日案件已审满,感谢您对社区的贡献!明天再来看看吧~"); Log::info("今日案件已审满,感谢您对社区的贡献!明天再来看看吧~");
self::setLock(self::timing(7, 0, 0, true)); self::setLock(self::timing(7, 0, 0, true));
return null; return null;
default: default:
Log::info("获取案件失败~ {$raw}"); Log::info("获取案件失败~ $raw");
return null; return null;
} }
} else { } else {
$case_id = $de_raw['data']['id']; $case_id = $de_raw['data']['id'];
Log::info("获取到案件 {$case_id} ~"); Log::info("获取到案件 $case_id ~");
return $case_id; return $case_id;
} }
} }
@ -206,11 +207,12 @@ class Judge
* @param $case_id * @param $case_id
* @return array * @return array
*/ */
#[ArrayShape(['num_voted' => "mixed", 'ok_percent' => "float|int"])]
private static function judgementVote($case_id): array private static function judgementVote($case_id): array
{ {
$url = 'https://api.bilibili.com/x/credit/jury/juryCase'; $url = 'https://api.bilibili.com/x/credit/jury/juryCase';
$headers = [ $headers = [
'Referer' => "https://www.bilibili.com/judgement/vote/{$case_id}" 'Referer' => "https://www.bilibili.com/judgement/vote/$case_id"
]; ];
$payload = [ $payload = [
'callback' => "jQuery1720" . self::randInt() . "_" . time(), 'callback' => "jQuery1720" . self::randInt() . "_" . time(),
@ -230,7 +232,7 @@ class Judge
$num_voted = $vote_break + $vote_delete + $vote_rule; $num_voted = $vote_break + $vote_delete + $vote_rule;
$ok_percent = $num_voted ? ($vote_rule / $num_voted) : 0; $ok_percent = $num_voted ? ($vote_rule / $num_voted) : 0;
// 言论合理比例 {$ok_percent} // 言论合理比例 {$ok_percent}
Log::info("案件 {$case_id} 目前已投票 {$num_voted}"); Log::info("案件 $case_id 目前已投票 $num_voted");
return [ return [
'num_voted' => $num_voted, 'num_voted' => $num_voted,
'ok_percent' => $ok_percent 'ok_percent' => $ok_percent
@ -245,7 +247,7 @@ class Judge
private static function randInt(int $max = 17): string private static function randInt(int $max = 17): string
{ {
$temp = []; $temp = [];
foreach (range(1, $max) as $_) { foreach (range(1, $max) as $ignored) {
array_push($temp, mt_rand(0, 9)); array_push($temp, mt_rand(0, 9));
} }
return implode("", $temp); return implode("", $temp);
@ -267,7 +269,7 @@ class Judge
* @use 获取案例数据|风纪检测 * @use 获取案例数据|风纪检测
* @return bool * @return bool
*/ */
private static function judgementIndex() private static function judgementIndex(): bool
{ {
$url = 'https://api.bilibili.com/x/credit/jury/caseList'; $url = 'https://api.bilibili.com/x/credit/jury/caseList';
$headers = [ $headers = [

View File

@ -13,6 +13,7 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log; use BiliHelper\Core\Log;
use BiliHelper\Core\Curl; use BiliHelper\Core\Curl;
use BiliHelper\Util\TimeLock; use BiliHelper\Util\TimeLock;
use JetBrains\PhpStorm\ArrayShape;
class Live class Live
{ {
@ -25,7 +26,7 @@ class Live
public static function fetchLiveAreas(): array public static function fetchLiveAreas(): array
{ {
$areas = []; $areas = [];
$url = "http://api.live.bilibili.com/room/v1/Area/getList"; $url = "https://api.live.bilibili.com/room/v1/Area/getList";
$payload = []; $payload = [];
$raw = Curl::get('other', $url, $payload); $raw = Curl::get('other', $url, $payload);
$de_raw = json_decode($raw, true); $de_raw = json_decode($raw, true);
@ -46,6 +47,7 @@ class Live
* @param $area_id * @param $area_id
* @return array * @return array
*/ */
#[ArrayShape(['area_id' => "", 'room_id' => "int|mixed"])]
public static function areaToRid($area_id): array public static function areaToRid($area_id): array
{ {
$url = "https://api.live.bilibili.com/room/v1/area/getRoomList"; $url = "https://api.live.bilibili.com/room/v1/area/getRoomList";
@ -101,28 +103,56 @@ class Live
/** /**
* @use 获取直播房间号 * @use 获取直播房间号
* @param $room_id * @param $room_id
* @return false|mixed * @param bool $uid
* @return mixed
*/ */
public static function getRealRoomID($room_id) public static function getRealRoomID($room_id, bool $uid = false): mixed
{ {
$room_infos = [];
// 缓存开始 如果存在就赋值 否则默认值
if ($temp = getCache('room_infos')) {
$room_infos = $temp;
}
// 取缓存
if (isset($room_infos[strval($room_id)])) {
$data = $room_infos[strval($room_id)];
} else {
// 默认数据
$_data = ['uid' => false, 'room_id' => false];
// TODO 优化
$data = self::getRoomInfoV1($room_id); $data = self::getRoomInfoV1($room_id);
if (!isset($data['code']) || !isset($data['data'])) { if (!isset($data['code']) || !isset($data['data'])) {
return false; // 访问错误
} $data = $_data;
if ($data['code']) { } elseif ($data['code']) {
// 访问错误
$data = $_data;
Log::warning($room_id . ' : ' . $data['msg']); Log::warning($room_id . ' : ' . $data['msg']);
return false; } elseif ($data['data']['is_hidden']) {
// 隐藏
$data = $_data;
} elseif ($data['data']['is_locked']) {
// 锁定
$data = $_data;
} elseif ($data['data']['encrypted']) {
// 加密
$data = $_data;
} else {
// 有效
$data = [
'uid' => $data['data']['uid'],
'room_id' => $data['data']['room_id'],
];
} }
if ($data['data']['is_hidden']) { // 推入缓存前
return false; $room_infos[strval($room_id)] = $data;
} }
if ($data['data']['is_locked']) { // 缓存结束 需要的数据的放进缓存
return false; setCache('room_infos', $room_infos);
} // 如果需要UID
if ($data['data']['encrypted']) { if ($uid) return $data;
return false; // 否
} return $data['room_id'];
return $data['data']['room_id'];
} }
/** /**
@ -177,6 +207,7 @@ class Live
* @param $room_id * @param $room_id
* @return array * @return array
*/ */
#[ArrayShape(['addr' => "mixed|string", 'token' => "mixed|string"])]
public static function getDanMuInfo($room_id): array public static function getDanMuInfo($room_id): array
{ {
$data = self::getDanMuConf($room_id); $data = self::getDanMuConf($room_id);
@ -262,7 +293,7 @@ class Live
]; ];
$headers = [ $headers = [
'origin' => 'https://live.bilibili.com', 'origin' => 'https://live.bilibili.com',
'referer' => "https://live.bilibili.com/{$room_id}" 'referer' => "https://live.bilibili.com/$room_id"
]; ];
$raw = Curl::post('pc', $url, $payload, $headers); $raw = Curl::post('pc', $url, $payload, $headers);
// {"code":0,"data":[],"message":"","msg":""} // {"code":0,"data":[],"message":"","msg":""}
@ -400,7 +431,7 @@ class Live
if (isset($data['code']) && $data['code']) { if (isset($data['code']) && $data['code']) {
Log::warning('送礼失败!', ['msg' => $data['message']]); Log::warning('送礼失败!', ['msg' => $data['message']]);
} else { } else {
Log::notice("成功向 {$payload['biz_id']} 投喂了 {$num}{$gift['gift_name']}"); Log::notice("成功向 {$payload['biz_id']} 投喂了 $num{$gift['gift_name']}");
} }
} }

View File

@ -13,15 +13,20 @@ use BiliHelper\Core\Log;
use BiliHelper\Core\Curl; use BiliHelper\Core\Curl;
use BiliHelper\Util\TimeLock; use BiliHelper\Util\TimeLock;
use BiliHelper\Tool\Common; use BiliHelper\Tool\Common;
use JetBrains\PhpStorm\ArrayShape;
use JetBrains\PhpStorm\NoReturn;
class Login class Login
{ {
use TimeLock; use TimeLock;
// 账密 // 账密
private static $username; private static string $username;
private static $password; private static string $password;
/**
* @throws \Jelix\IniFile\IniException
*/
public static function run() public static function run()
{ {
if (self::getLock()) { if (self::getLock()) {
@ -47,6 +52,7 @@ class Login
/** /**
* @use 登录控制中心 * @use 登录控制中心
* @throws \Jelix\IniFile\IniException
*/ */
private static function login() private static function login()
{ {
@ -73,6 +79,7 @@ class Login
/** /**
* @use 检查登录 * @use 检查登录
* @throws \Jelix\IniFile\IniException
*/ */
private static function checkLogin() private static function checkLogin()
{ {
@ -90,6 +97,7 @@ class Login
/** /**
* @use 保持认证 * @use 保持认证
* @return bool * @return bool
* @throws \Jelix\IniFile\IniException
*/ */
private static function keepAuth(): bool private static function keepAuth(): bool
{ {
@ -132,6 +140,7 @@ class Login
/** /**
* @use 刷新Token * @use 刷新Token
* @throws \Jelix\IniFile\IniException
*/ */
private static function refreshToken(): bool private static function refreshToken(): bool
{ {
@ -179,7 +188,7 @@ class Login
/** /**
* @use 获取验证码 * @use 获取验证码
* @return array|string[] * @return array
*/ */
private static function getCaptcha(): array private static function getCaptcha(): array
{ {
@ -210,6 +219,7 @@ class Login
* @param array $captcha * @param array $captcha
* @return array * @return array
*/ */
#[ArrayShape(['validate' => "mixed", 'challenge' => "mixed"])]
private static function ocrCaptcha(array $captcha): array private static function ocrCaptcha(array $captcha): array
{ {
$url = 'https://captcha-v1.mudew.com:19951/'; $url = 'https://captcha-v1.mudew.com:19951/';
@ -236,14 +246,15 @@ class Login
* @param string $validate * @param string $validate
* @param string $challenge * @param string $challenge
* @param string $mode * @param string $mode
* @throws \Jelix\IniFile\IniException
*/ */
private static function accountLogin(string $validate = '', string $challenge = '', string $mode = '账密模式') private static function accountLogin(string $validate = '', string $challenge = '', string $mode = '账密模式')
{ {
Log::info("尝试 {$mode} 登录"); Log::info("尝试 $mode 登录");
// $url = 'https://passport.bilibili.com/api/v3/oauth2/login'; // $url = 'https://passport.bilibili.com/api/v3/oauth2/login';
$url = 'https://passport.bilibili.com/x/passport-login/oauth2/login'; $url = 'https://passport.bilibili.com/x/passport-login/oauth2/login';
$payload = [ $payload = [
'seccode' => $validate ? "{$validate}|jordan" : '', 'seccode' => $validate ? "$validate|jordan" : '',
'validate' => $validate, 'validate' => $validate,
'challenge' => $challenge, 'challenge' => $challenge,
'permission' => 'ALL', 'permission' => 'ALL',
@ -266,10 +277,11 @@ class Login
/** /**
* @use 短信登录 * @use 短信登录
* @param string $mode * @param string $mode
* @throws \Jelix\IniFile\IniException
*/ */
private static function smsLogin(string $mode = '短信模式') private static function smsLogin(string $mode = '短信模式')
{ {
Log::info("尝试 {$mode} 登录"); Log::info("尝试 $mode 登录");
if (getConf('phone', 'login.check')) { if (getConf('phone', 'login.check')) {
self::checkPhone(self::$username); self::checkPhone(self::$username);
} }
@ -293,7 +305,7 @@ class Login
* @param int $max_char * @param int $max_char
* @return string * @return string
*/ */
private static function cliInput(string $msg, $max_char = 100): string private static function cliInput(string $msg, int $max_char = 100): string
{ {
$stdin = fopen('php://stdin', 'r'); $stdin = fopen('php://stdin', 'r');
echo '# ' . $msg; echo '# ' . $msg;
@ -307,11 +319,12 @@ class Login
* @param string $phone * @param string $phone
* @return array * @return array
*/ */
#[ArrayShape(['cid' => "mixed", 'tel' => "string", 'statistics' => "string", 'captcha_key' => "mixed"])]
private static function sendSms(string $phone): array private static function sendSms(string $phone): array
{ {
$url = 'https://passport.bilibili.com//x/passport-login/sms/send'; $url = 'https://passport.bilibili.com//x/passport-login/sms/send';
$payload = [ $payload = [
'cid' => getConf('country_code', 'login.country') , 'cid' => getConf('country_code', 'login.country'),
'tel' => $phone, 'tel' => $phone,
'statistics' => '{"appId":1,"platform":3,"version":"6.32.0","abtest":""}', 'statistics' => '{"appId":1,"platform":3,"version":"6.32.0","abtest":""}',
]; ];
@ -324,7 +337,7 @@ class Login
$payload['captcha_key'] = $de_raw['data']['captcha_key']; $payload['captcha_key'] = $de_raw['data']['captcha_key'];
return $payload; return $payload;
} }
Log::error("短信验证码发送失败 {$raw}"); Log::error("短信验证码发送失败 $raw");
die(); die();
} }
@ -333,6 +346,7 @@ class Login
* @param $mode * @param $mode
* @param $code * @param $code
* @param $data * @param $data
* @throws \Jelix\IniFile\IniException
*/ */
private static function loginAfter($mode, $code, $data) private static function loginAfter($mode, $code, $data)
{ {
@ -349,11 +363,9 @@ class Login
case 2: case 2:
// 异常高危 // 异常高危
self::loginFail($mode, $data['data']['message']); self::loginFail($mode, $data['data']['message']);
break;
default: default:
// 未知错误 // 未知错误
self::loginFail($mode, '未知错误: ' . $data['data']['message']); self::loginFail($mode, '未知错误: ' . $data['data']['message']);
break;
} }
} else { } else {
// 正常登录 // 正常登录
@ -363,19 +375,15 @@ class Login
case -105: case -105:
// 需要验证码 // 需要验证码
self::loginFail($mode, '此次登录需要验证码或' . $data['message']); self::loginFail($mode, '此次登录需要验证码或' . $data['message']);
break;
case -629: case -629:
// 密码错误 // 密码错误
self::loginFail($mode, $data['message']); self::loginFail($mode, $data['message']);
break;
case -2100: case -2100:
// 验证手机号 // 验证手机号
self::loginFail($mode, '账号启用了设备锁或异地登录需验证手机号'); self::loginFail($mode, '账号启用了设备锁或异地登录需验证手机号');
break;
default: default:
// 未知错误 // 未知错误
self::loginFail($mode, '未知错误: ' . $data['message']); self::loginFail($mode, '未知错误: ' . $data['message']);
break;
} }
} }
@ -384,10 +392,11 @@ class Login
* @use 登录成功 * @use 登录成功
* @param $mode * @param $mode
* @param $data * @param $data
* @throws \Jelix\IniFile\IniException
*/ */
private static function loginSuccess($mode, $data) private static function loginSuccess($mode, $data)
{ {
Log::info("{$mode} 登录成功"); Log::info("$mode 登录成功");
self::successHandle($data); self::successHandle($data);
Log::info('生成信息配置完毕'); Log::info('生成信息配置完毕');
} }
@ -395,6 +404,7 @@ class Login
/** /**
* @use 刷新成功 * @use 刷新成功
* @param $data * @param $data
* @throws \Jelix\IniFile\IniException
*/ */
private static function refreshSuccess($data) private static function refreshSuccess($data)
{ {
@ -406,6 +416,7 @@ class Login
/** /**
* @use 成功处理 * @use 成功处理
* @param $data * @param $data
* @throws \Jelix\IniFile\IniException
*/ */
private static function successHandle($data) private static function successHandle($data)
{ {
@ -424,9 +435,10 @@ class Login
* @param $mode * @param $mode
* @param $data * @param $data
*/ */
#[NoReturn]
private static function loginFail($mode, $data) private static function loginFail($mode, $data)
{ {
Log::error("{$mode} 登录失败", ['msg' => $data]); Log::error("$mode 登录失败", ['msg' => $data]);
die(); die();
} }
@ -436,7 +448,8 @@ class Login
*/ */
private static function checkPhone(string $phone) private static function checkPhone(string $phone)
{ {
if (!preg_match("/^1[3456789]{1}\d{9}$/", $phone)) { // /^1[3456789]{1}\d{9}$/
if (!preg_match("/^1[3456789]\d{9}$/", $phone)) {
Log::error("当前用户名不是有效手机号格式"); Log::error("当前用户名不是有效手机号格式");
die(); die();
} }
@ -449,12 +462,13 @@ class Login
* @param string $section * @param string $section
* @param bool $print * @param bool $print
* @param bool $hide * @param bool $hide
* @throws \Jelix\IniFile\IniException
*/ */
private static function saveConfig(string $key, string $value, string $section, $print = true, $hide = true) private static function saveConfig(string $key, string $value, string $section, bool $print = true, bool $hide = true)
{ {
setConf($key, $value, $section); setConf($key, $value, $section);
if ($print) { if ($print) {
Log::info(" > {$key}: " . ($hide ? Common::replaceStar($value, 6, 6) : $value)); Log::info(" > $key: " . ($hide ? Common::replaceStar($value, 6, 6) : $value));
} }
} }
@ -475,6 +489,7 @@ class Login
/** /**
* @use 清除已有 * @use 清除已有
* @throws \Jelix\IniFile\IniException
*/ */
private static function clearAccount() private static function clearAccount()
{ {
@ -507,6 +522,7 @@ class Login
/** /**
* @use 验证码登录 * @use 验证码登录
* @param string $mode * @param string $mode
* @throws \Jelix\IniFile\IniException
*/ */
private static function captchaLogin(string $mode = '验证码模式') private static function captchaLogin(string $mode = '验证码模式')
{ {

View File

@ -13,6 +13,7 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Log; use BiliHelper\Core\Log;
use BiliHelper\Core\Curl; use BiliHelper\Core\Curl;
use BiliHelper\Util\TimeLock; use BiliHelper\Util\TimeLock;
use JetBrains\PhpStorm\ArrayShape;
class MainSite class MainSite
{ {
@ -47,7 +48,7 @@ class MainSite
$headers = [ $headers = [
'Host' => "api.bilibili.com", 'Host' => "api.bilibili.com",
'Origin' => "https://www.bilibili.com", 'Origin' => "https://www.bilibili.com",
'Referer' => "https://www.bilibili.com/video/av{$aid}", '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", '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":34005,"message":"超过投币上限啦~","ttl":1,"data":{"like":false}}
@ -55,10 +56,10 @@ class MainSite
$raw = Curl::post('app', $url, Sign::common($payload), $headers); $raw = Curl::post('app', $url, Sign::common($payload), $headers);
$de_raw = json_decode($raw, true); $de_raw = json_decode($raw, true);
if ($de_raw['code'] == 0) { if ($de_raw['code'] == 0) {
Log::notice("主站任务: av{$aid} 投币成功 {$de_raw['code']} MSG -> {$de_raw['message']}"); Log::notice("主站任务: av$aid 投币成功 {$de_raw['code']} MSG -> {$de_raw['message']}");
return true; return true;
} else { } else {
Log::warning("主站任务: av{$aid} 投币失败 CODE -> {$de_raw['code']} MSG -> {$de_raw['message']}"); Log::warning("主站任务: av$aid 投币失败 CODE -> {$de_raw['code']} MSG -> {$de_raw['message']}");
return false; return false;
} }
} }
@ -83,7 +84,7 @@ class MainSite
if ($log_date != $now_date) { if ($log_date != $now_date) {
break; break;
} }
if (strpos($log['reason'], "打赏") !== false) { if (str_contains($log['reason'], "打赏")) {
switch ($log['delta']) { switch ($log['delta']) {
case -1: case -1:
$coins += 1; $coins += 1;
@ -113,7 +114,7 @@ class MainSite
$stock_num = self::getCoin(); $stock_num = self::getCoin();
// 实际数量 处理硬币库存少于预计数量 // 实际数量 处理硬币库存少于预计数量
$actual_num = intval($estimate_num > $stock_num ? $stock_num : $estimate_num) - self::coinLog(); $actual_num = intval($estimate_num > $stock_num ? $stock_num : $estimate_num) - self::coinLog();
Log::info("当前硬币库存 {$stock_num} 预计投币 {$estimate_num} 实际投币 {$actual_num}"); Log::info("当前硬币库存 $stock_num 预计投币 $estimate_num 实际投币 $actual_num");
// 上限 // 上限
if ($actual_num <= 0) { if ($actual_num <= 0) {
Log::notice('今日投币上限已满'); Log::notice('今日投币上限已满');
@ -361,6 +362,7 @@ class MainSite
* @use 解析AID到CID * @use 解析AID到CID
* @return array * @return array
*/ */
#[ArrayShape(['aid' => "string", 'cid' => "mixed", 'duration' => "mixed"])]
private static function parseAid(): array private static function parseAid(): array
{ {
while (true) { while (true) {

View File

@ -20,9 +20,9 @@ class MaterialObject
use TimeLock; use TimeLock;
use FilterWords; use FilterWords;
private static $invalid_aids = []; private static array $invalid_aids = [];
private static $start_aid = 0; private static int $start_aid = 0;
private static $end_aid = 0; private static int $end_aid = 0;
public static function run() public static function run()
{ {
@ -46,7 +46,7 @@ class MaterialObject
self::loadJsonData(); self::loadJsonData();
$sensitive_words = self::$store->get("MaterialObject.sensitive"); $sensitive_words = self::$store->get("MaterialObject.sensitive");
foreach ($sensitive_words as $word) { foreach ($sensitive_words as $word) {
if (strpos($title, $word) !== false) { if (str_contains($title, $word)) {
return true; return true;
} }
} }
@ -57,9 +57,9 @@ class MaterialObject
* @use 抽奖盒子状态 * @use 抽奖盒子状态
* @param int $aid * @param int $aid
* @param string $reply * @param string $reply
* @return array|bool|mixed * @return mixed
*/ */
private static function boxStatus(int $aid, $reply = 'bool') private static function boxStatus(int $aid, string $reply = 'bool'): mixed
{ {
// $url = 'https://api.live.bilibili.com/lottery/v1/box/getStatus'; // $url = 'https://api.live.bilibili.com/lottery/v1/box/getStatus';
$url = 'https://api.live.bilibili.com/xlive/lottery-interface/v2/Box/getStatus'; $url = 'https://api.live.bilibili.com/xlive/lottery-interface/v2/Box/getStatus';
@ -93,6 +93,11 @@ class MaterialObject
*/ */
private static function fetchLottery(): array private static function fetchLottery(): array
{ {
// 缓存开始 如果存在就赋值 否则默认值
if ($temp = getCache('invalid_aids')) {
self::$invalid_aids = $temp;
}
$lottery_list = []; $lottery_list = [];
$max_probe = 10; $max_probe = 10;
$probes = range(self::$start_aid, self::$end_aid); $probes = range(self::$start_aid, self::$end_aid);
@ -132,6 +137,9 @@ class MaterialObject
'num' => $round_num, 'num' => $round_num,
]); ]);
} }
// 缓存结束 需要的数据的放进缓存
setCache('invalid_aids', self::$invalid_aids);
return $lottery_list; return $lottery_list;
} }
@ -168,7 +176,7 @@ class MaterialObject
foreach ($lottery_list as $lottery) { foreach ($lottery_list as $lottery) {
$aid = $lottery['aid']; $aid = $lottery['aid'];
$num = $lottery['num']; $num = $lottery['num'];
Log::notice("实物抽奖 {$aid} 轮次 {$num} 可参与抽奖~"); Log::notice("实物抽奖 $aid 轮次 $num 可参与抽奖~");
// $url = 'https://api.live.bilibili.com/lottery/v1/Box/draw'; // $url = 'https://api.live.bilibili.com/lottery/v1/Box/draw';
$url = 'https://api.live.bilibili.com/xlive/lottery-interface/v2/Box/draw'; $url = 'https://api.live.bilibili.com/xlive/lottery-interface/v2/Box/draw';
$payload = [ $payload = [
@ -178,9 +186,9 @@ class MaterialObject
$raw = Curl::get('pc', $url, $payload); $raw = Curl::get('pc', $url, $payload);
$de_raw = json_decode($raw, true); $de_raw = json_decode($raw, true);
if ($de_raw['code'] == 0) { if ($de_raw['code'] == 0) {
Log::notice("实物抽奖 {$aid} 轮次 {$num} 参与抽奖成功~"); Log::notice("实物抽奖 $aid 轮次 $num 参与抽奖成功~");
} else { } else {
Log::notice("实物抽奖 {$aid} 轮次 {$num} {$de_raw['msg']}~"); Log::notice("实物抽奖 $aid 轮次 $num {$de_raw['msg']}~");
} }
} }
return true; return true;

View File

@ -43,12 +43,12 @@ class Notice
private static function filterResultWords(string $result): bool private static function filterResultWords(string $result): bool
{ {
self::loadJsonData(); self::loadJsonData();
$default_words = self::$store->get("Notice.default");; $default_words = self::$store->get("Notice.default");
$custom_words = explode(',', getConf('filter_words', 'notify')); $custom_words = explode(',', getConf('filter_words', 'notify'));
$total_words = array_merge($default_words, $custom_words); $total_words = array_merge($default_words, $custom_words);
foreach ($total_words as $word) { foreach ($total_words as $word) {
if (empty($word)) continue; if (empty($word)) continue;
if (strpos($result, $word) !== false) { if (str_contains($result, $word)) {
return true; return true;
} }
} }
@ -65,86 +65,60 @@ class Notice
private static function sendInfoHandle(string $type, string $uname, string $result): bool private static function sendInfoHandle(string $type, string $uname, string $result): bool
{ {
$now_time = date('Y-m-d H:i:s'); $now_time = date('Y-m-d H:i:s');
switch ($type) { $info = match ($type) {
case 'update': 'update' => [
$info = [
'title' => '程序更新通知', 'title' => '程序更新通知',
'content' => "[{$now_time}] 用户: {$uname} 程序更新通知: {$result}" 'content' => "[$now_time] 用户: $uname 程序更新通知: $result"
]; ],
break; 'anchor' => [
case 'anchor':
$info = [
'title' => '天选时刻获奖记录', 'title' => '天选时刻获奖记录',
'content' => "[{$now_time}] 用户: {$uname} 在天选时刻中获得: {$result}" 'content' => "[$now_time] 用户: $uname 在天选时刻中获得: $result"
]; ],
break; 'raffle' => [
case 'raffle':
$info = [
'title' => '实物奖励获奖纪录', 'title' => '实物奖励获奖纪录',
'content' => "[{$now_time}] 用户: {$uname} 在实物奖励中获得: {$result}" 'content' => "[$now_time] 用户: $uname 在实物奖励中获得: $result"
]; ],
break; 'gift' => [
case 'gift':
$info = [
'title' => '活动礼物获奖纪录', 'title' => '活动礼物获奖纪录',
'content' => "[{$now_time}] 用户: {$uname} 在活动礼物中获得: {$result}" 'content' => "[$now_time] 用户: $uname 在活动礼物中获得: $result"
]; ],
break; 'storm' => [
case 'storm':
$info = [
'title' => '节奏风暴获奖纪录', 'title' => '节奏风暴获奖纪录',
'content' => "[{$now_time}] 用户: {$uname} 在节奏风暴中获得: {$result}" 'content' => "[$now_time] 用户: $uname 在节奏风暴中获得: $result"
]; ],
break; 'cookieRefresh' => [
case 'cookieRefresh':
$info = [
'title' => 'Cookie刷新', 'title' => 'Cookie刷新',
'content' => "[{$now_time}] 用户: {$uname} 刷新Cookie: {$result}" 'content' => "[$now_time] 用户: $uname 刷新Cookie: $result"
]; ],
break; 'todaySign' => [
case 'todaySign':
$info = [
'title' => '每日签到', 'title' => '每日签到',
'content' => "[{$now_time}] 用户: {$uname} 签到: {$result}" 'content' => "[$now_time] 用户: $uname 签到: $result"
]; ],
break; 'banned' => [
case 'banned':
$info = [
'title' => '任务小黑屋', 'title' => '任务小黑屋',
'content' => "[{$now_time}] 用户: {$uname} 小黑屋: {$result}" 'content' => "[$now_time] 用户: $uname 小黑屋: $result"
]; ],
break; 'error' => [
case 'error':
$info = [
'title' => '程序运行错误', 'title' => '程序运行错误',
'content' => "[{$now_time}] 用户: {$uname} 错误详情: {$result}" 'content' => "[$now_time] 用户: $uname 错误详情: $result"
]; ],
break; 'key_expired' => [
case 'key_expired':
$info = [
'title' => '监控KEY异常', 'title' => '监控KEY异常',
'content' => "[{$now_time}] 用户: {$uname} 监控KEY到期或者错误请及时查错或续期后重试哦~" 'content' => "[$now_time] 用户: $uname 监控KEY到期或者错误请及时查错或续期后重试哦~"
]; ],
break; 'capsule_lottery' => [
case 'capsule_lottery':
$info = [
'title' => '直播扭蛋抽奖活动', 'title' => '直播扭蛋抽奖活动',
'content' => "[{$now_time}] 用户: {$uname} 详情: {$result}" 'content' => "[$now_time] 用户: $uname 详情: $result"
]; ],
break; 'activity_lottery' => [
case 'activity_lottery':
$info = [
'title' => '主站九宫格抽奖活动', 'title' => '主站九宫格抽奖活动',
'content' => "[{$now_time}] 用户: {$uname} 详情: {$result}" 'content' => "[$now_time] 用户: $uname 详情: $result"
]; ],
break; default => [
default:
$info = [
'title' => '推送消息异常记录', 'title' => '推送消息异常记录',
'content' => "[{$now_time}] 用户: {$uname} 推送消息key错误: {$type}->{$result}" 'content' => "[$now_time] 用户: $uname 推送消息key错误: $type->$result"
]; ],
break; };
}
self::sendLog($info); self::sendLog($info);
return true; return true;
@ -203,7 +177,7 @@ class Notice
if ($de_raw['errcode'] == 0) { if ($de_raw['errcode'] == 0) {
Log::notice("推送消息成功: {$de_raw['errmsg']}"); Log::notice("推送消息成功: {$de_raw['errmsg']}");
} else { } else {
Log::warning("推送消息失败: {$raw}"); Log::warning("推送消息失败: $raw");
} }
} }
@ -226,7 +200,7 @@ class Notice
if ($de_raw['ok'] && array_key_exists('message_id', $de_raw['result'])) { if ($de_raw['ok'] && array_key_exists('message_id', $de_raw['result'])) {
Log::notice("推送消息成功: MSG_ID->{$de_raw['result']['message_id']}"); Log::notice("推送消息成功: MSG_ID->{$de_raw['result']['message_id']}");
} else { } else {
Log::warning("推送消息失败: {$raw}"); Log::warning("推送消息失败: $raw");
} }
} }
@ -249,7 +223,7 @@ class Notice
if ($de_raw['errno'] == 0) { if ($de_raw['errno'] == 0) {
Log::notice("推送消息成功: {$de_raw['errmsg']}"); Log::notice("推送消息成功: {$de_raw['errmsg']}");
} else { } else {
Log::warning("推送消息失败: {$raw}"); Log::warning("推送消息失败: $raw");
} }
} }
@ -273,7 +247,7 @@ class Notice
if ($de_raw['code'] == 0) { if ($de_raw['code'] == 0) {
Log::notice("推送消息成功: {$de_raw['data']['pushid']}"); Log::notice("推送消息成功: {$de_raw['data']['pushid']}");
} else { } else {
Log::warning("推送消息失败: {$raw}"); Log::warning("推送消息失败: $raw");
} }
} }
@ -285,7 +259,7 @@ class Notice
private static function pushPlusSend(array $info) private static function pushPlusSend(array $info)
{ {
Log::info('使用PushPlus酱推送消息'); Log::info('使用PushPlus酱推送消息');
$url = 'http://www.pushplus.plus/send'; $url = 'https://www.pushplus.plus/send';
$payload = [ $payload = [
'token' => getConf('token', 'notify.pushplus'), 'token' => getConf('token', 'notify.pushplus'),
'title' => $info['title'], 'title' => $info['title'],
@ -300,7 +274,7 @@ class Notice
if ($de_raw['code'] == 200) { if ($de_raw['code'] == 200) {
Log::notice("推送消息成功: {$de_raw['data']}"); Log::notice("推送消息成功: {$de_raw['data']}");
} else { } else {
Log::warning("推送消息失败: {$raw}"); Log::warning("推送消息失败: $raw");
} }
} }
@ -324,7 +298,7 @@ class Notice
if ($de_raw['retcode'] == 0) { if ($de_raw['retcode'] == 0) {
Log::notice("推送消息成功: {$de_raw['status']}"); Log::notice("推送消息成功: {$de_raw['status']}");
} else { } else {
Log::warning("推送消息失败: {$raw}"); Log::warning("推送消息失败: $raw");
} }
} }
@ -349,7 +323,7 @@ class Notice
if ($de_raw['success'] == true) { if ($de_raw['success'] == true) {
Log::notice("推送消息成功: {$de_raw['data']['msgid']}"); Log::notice("推送消息成功: {$de_raw['data']['msgid']}");
} else { } else {
Log::warning("推送消息失败: {$raw}"); Log::warning("推送消息失败: $raw");
} }
} }

View File

@ -20,9 +20,9 @@ class PkRaffle extends BaseRaffle
const ACTIVE_TITLE = '主播乱斗'; const ACTIVE_TITLE = '主播乱斗';
const ACTIVE_SWITCH = 'live_pk'; const ACTIVE_SWITCH = 'live_pk';
protected static $wait_list = []; protected static array $wait_list = [];
protected static $finish_list = []; protected static array $finish_list = [];
protected static $all_list = []; protected static array $all_list = [];
/** /**
* @use 解析数据 * @use 解析数据
@ -95,9 +95,9 @@ class PkRaffle extends BaseRaffle
/** /**
* @use 解析抽奖信息 * @use 解析抽奖信息
* @param array $results * @param array $results
* @return void * @return mixed
*/ */
protected static function parseLottery(array $results) protected static function parseLottery(array $results):mixed
{ {
foreach ($results as $result) { foreach ($results as $result) {
$data = $result['source']; $data = $result['source'];
@ -122,5 +122,6 @@ class PkRaffle extends BaseRaffle
Log::notice("房间 {$data['room_id']} 编号 {$data['raffle_id']} {$data['raffle_name']}: {$de_raw['message']}"); Log::notice("房间 {$data['room_id']} 编号 {$data['raffle_id']} {$data['raffle_name']}: {$de_raw['message']}");
} }
} }
return '';
} }
} }

View File

@ -18,9 +18,9 @@ class PolishTheMedal
{ {
use TimeLock; use TimeLock;
private static $metal_lock = 0; // 勋章时间锁 private static int $metal_lock = 0; // 勋章时间锁
private static $fans_medals = []; // 全部勋章 private static array $fans_medals = []; // 全部勋章
private static $grey_fans_medals = []; // 灰色勋章 private static array $grey_fans_medals = []; // 灰色勋章
/** /**
*/ */
@ -65,7 +65,7 @@ class PolishTheMedal
// 为空 // 为空
if (is_null($medal)) return; if (is_null($medal)) return;
// 特殊房间处理|央视未开播|CODE -> 11000 MSG -> '' // 特殊房间处理|央视未开播|CODE -> 11000 MSG -> ''
if (in_array($medal['roomid'], [21686237])) return; if (in_array($medal['roomid'], [21686237, 0])) return;
Log::info("开始点亮直播间@{$medal['roomid']}的勋章"); Log::info("开始点亮直播间@{$medal['roomid']}的勋章");
// 擦亮 // 擦亮

View File

@ -18,23 +18,23 @@ class Schedule
use TimeLock; use TimeLock;
// Todo 黑白名单|考虑添加到每个插件内部自动添加|优化RUN逻辑代码 // Todo 黑白名单|考虑添加到每个插件内部自动添加|优化RUN逻辑代码
private static $unlock_hour = 24; private static int $unlock_hour = 24;
private static $unlock_timers = []; private static array $unlock_timers = [];
private static $sleep_section = []; private static array $sleep_section = [];
// 日常类 // 日常类
private static $fillable = ['Login', 'Schedule', 'DailyBag', 'Judge', 'MainSite', 'GiftSend', 'DailyTask', 'Silver2Coin', 'ManGa', 'GroupSignIn', 'AwardRecord', 'Statistics']; private static array $fillable = ['Login', 'Schedule', 'DailyBag', 'Judge', 'MainSite', 'GiftSend', 'DailyTask', 'Silver2Coin', 'ManGa', 'GroupSignIn', 'AwardRecord', 'Statistics'];
// 任务类 // 任务类
private static $guarded_first = ['Barrage', 'GiftHeart', 'Silver', 'MaterialObject']; private static array $guarded_first = ['Barrage', 'GiftHeart', 'Silver', 'MaterialObject'];
// 监控类 // 监控类
private static $guarded_second = ['AloneTcpClient', 'ZoneTcpClient',]; private static array $guarded_second = ['AloneTcpClient', 'ZoneTcpClient',];
// 抽奖类 // 抽奖类
private static $guarded_third = ['StormRaffle', 'GuardRaffle', 'PkRaffle', 'GiftRaffle', 'AnchorRaffle']; private static array $guarded_third = ['StormRaffle', 'GuardRaffle', 'PkRaffle', 'GiftRaffle', 'AnchorRaffle'];
// 特殊 老爷处理 // 特殊 老爷处理
private static $guarded_fourth = ['DoubleHeart']; private static array $guarded_fourth = ['DoubleHeart'];
// 暂定不做处理,后期看情况再定 // 暂定不做处理,后期看情况再定
private static $release = ['ActivityLottery', 'SmallHeart', 'Competition', 'SmallHeart', 'Forward', 'CapsuleLottery', 'PolishTheMedal']; private static array $release = ['ActivityLottery', 'SmallHeart', 'Competition', 'SmallHeart', 'Forward', 'CapsuleLottery', 'PolishTheMedal'];
// 暂定不做处理 大会员类 // 暂定不做处理 大会员类
private static $guarded_fifth = ['VipPrivilege', 'BpConsumption']; private static array $guarded_fifth = ['VipPrivilege', 'BpConsumption'];
public static function run() public static function run()
@ -56,9 +56,9 @@ class Schedule
self::$sleep_section = empty(self::$sleep_section) ? explode(',', getConf('section', 'sleep')) : self::$sleep_section; self::$sleep_section = empty(self::$sleep_section) ? explode(',', getConf('section', 'sleep')) : self::$sleep_section;
if (!in_array(date('H'), self::$sleep_section)) { if (!in_array(date('H'), self::$sleep_section)) {
return false; return false;
}; }
self::handleBan('sleep'); self::handleBan('sleep');
}; }
return true; return true;
} }
@ -90,13 +90,13 @@ class Schedule
* @param $action * @param $action
* @param string $classname * @param string $classname
*/ */
private static function handleBan($action, $classname = '') private static function handleBan($action, string $classname = '')
{ {
switch ($action) { switch ($action) {
// 休眠 // 休眠
case 'sleep': case 'sleep':
foreach (self::$fillable as $classname) { foreach (self::$fillable as $classname) {
Log::info("插件 {$classname} 白名单,保持当前状态继续"); Log::info("插件 $classname 白名单,保持当前状态继续");
} }
$unlock_time = 60 * 60; $unlock_time = 60 * 60;
self::$unlock_hour = date('H'); self::$unlock_hour = date('H');
@ -112,10 +112,10 @@ class Schedule
// 访问拒绝 统一时间 第二天0点 // 访问拒绝 统一时间 第二天0点
$unlock_time = strtotime(date("Y-m-d", strtotime("+1 day", time()))) - time(); $unlock_time = strtotime(date("Y-m-d", strtotime("+1 day", time()))) - time();
self::stopProc([$classname], $unlock_time); self::stopProc([$classname], $unlock_time);
Log::warning("{$classname} 任务拒绝访问,暂停任务,自动开启!"); Log::warning("$classname 任务拒绝访问,暂停任务,自动开启!");
// 推送被ban信息 // 推送被ban信息
$time = floor($unlock_time / 60 / 60); $time = floor($unlock_time / 60 / 60);
Notice::push('banned', "任务 {$classname} 暂停,{$time} 小时后自动恢复!"); Notice::push('banned', "任务 $classname 暂停,$time 小时后自动恢复!");
break; break;
// 特殊类 // 特殊类
case 'special': case 'special':
@ -139,7 +139,7 @@ class Schedule
private static function stopProc(array $classname_list, int $unlock_time, bool $force = false) private static function stopProc(array $classname_list, int $unlock_time, bool $force = false)
{ {
foreach ($classname_list as $classname) { foreach ($classname_list as $classname) {
Log::info("插件 {$classname} 黑名单,锁定状态将于" . date("Y-m-d H:i", time() + $unlock_time) . "解除"); Log::info("插件 $classname 黑名单,锁定状态将于" . date("Y-m-d H:i", time() + $unlock_time) . "解除");
// 强制 无视小黑屋设定 // 强制 无视小黑屋设定
if ($force) { if ($force) {
call_user_func(array(__NAMESPACE__ . '\\' . $classname, 'setPauseStatus'), false); call_user_func(array(__NAMESPACE__ . '\\' . $classname, 'setPauseStatus'), false);

View File

@ -10,36 +10,8 @@
namespace BiliHelper\Plugin; namespace BiliHelper\Plugin;
use BiliHelper\Core\Log;
class Sign class Sign
{ {
// /**
// * @use 登录
// * @param $payload
// * @return array
// */
// public static function login($payload)
// {
// # 云视听 TV
// $appkey = '4409e2ce8ffd12b8';
// $appsecret = '59b43e04ad6965f34319062b478f83dd';
//
// $default = [
// 'access_key' => getAccessToken()
// 'actionKey' => 'appkey',
// 'appkey' => $appkey,
// 'build' => 101800,
// 'device' => 'android',
// 'mobi_app' => 'android_tv_yst',
// 'platform' => 'android',
// 'ts' => time(),
// ];
// $payload = array_merge($payload, $default);
// return self::encryption($payload, $appsecret);
// }
/** /**
* @use 登录 * @use 登录
* @param $payload * @param $payload
@ -48,22 +20,22 @@ class Sign
public static function login($payload): array public static function login($payload): array
{ {
# Android 新 # Android 新
$appkey = 'bca7e84c2d947ac6'; $app_key = base64_decode(getDevice('bili_a.app_key_n'));
$appsecret = '60698ba2f68e01ce44738920a0ffe768'; $app_secret = base64_decode(getDevice('bili_a.secret_key_n'));
$default = [ $default = [
'access_key' => getAccessToken(), 'access_key' => getAccessToken(),
'actionKey' => 'appkey', 'actionKey' => 'appkey',
'appkey' => $appkey, 'appkey' => $app_key,
'build' => 6360400, 'build' => getDevice('bili_a.build'),
'channel' => 'bili', 'channel' => getDevice('bili_a.channel'),
'device' => 'phone', 'device' => getDevice('bili_a.device'),
'mobi_app' => 'android', 'mobi_app' => getDevice('bili_a.mobi_app'),
'platform' => 'android', 'platform' => getDevice('bili_a.platform'),
'ts' => time(), 'ts' => time(),
]; ];
$payload = array_merge($payload, $default); $payload = array_merge($payload, $default);
return self::encryption($payload, $appsecret); return self::encryption($payload, $app_secret);
} }
/** /**
@ -73,25 +45,22 @@ class Sign
*/ */
public static function common($payload): array public static function common($payload): array
{ {
# iOS 6680
// $appkey = '27eb53fc9058f8c3';
// $appsecret = 'c2ed53a74eeefe3cf99fbd01d8c9c375';
# Android 旧 # Android 旧
$appkey = '1d8b6e7d45233436'; $app_key = base64_decode(getDevice('bili_a.app_key'));
$appsecret = '560c52ccd288fed045859ed18bffd973'; $app_secret = base64_decode(getDevice('bili_a.secret_key'));
$default = [ $default = [
'access_key' => getAccessToken(), 'access_key' => getAccessToken(),
'actionKey' => 'appkey', 'actionKey' => 'appkey',
'appkey' => $appkey, 'appkey' => $app_key,
'build' => 6360400, 'build' => getDevice('bili_a.build'),
'device' => 'phone', 'device' => getDevice('bili_a.device'),
'mobi_app' => 'android', 'mobi_app' => getDevice('bili_a.mobi_app'),
'platform' => 'android', 'platform' => getDevice('bili_a.platform'),
'ts' => time(), 'ts' => time(),
]; ];
$payload = array_merge($payload, $default); $payload = array_merge($payload, $default);
return self::encryption($payload, $appsecret); return self::encryption($payload, $app_secret);
} }

View File

@ -18,7 +18,7 @@ class Silver
{ {
use TimeLock; use TimeLock;
protected static $task = []; protected static array $task = [];
public static function run() public static function run()
{ {

View File

@ -82,13 +82,13 @@ class Silver2Coin
// {"code":0,"data":{"coin":1,"gold":1234,"silver":4321,"tid":"Silver2Coin21062316490299678123456"},"message":"兑换成功"} // {"code":0,"data":{"coin":1,"gold":1234,"silver":4321,"tid":"Silver2Coin21062316490299678123456"},"message":"兑换成功"}
switch ($data['code']) { switch ($data['code']) {
case 0: case 0:
Log::notice("[{$type}] 银瓜子兑换硬币: {$data['message']}"); Log::notice("[$type] 银瓜子兑换硬币: {$data['message']}");
return true; return true;
case 403: case 403:
Log::warning("[{$type}] 银瓜子兑换硬币: {$data['message']}"); Log::warning("[$type] 银瓜子兑换硬币: {$data['message']}");
return true; return true;
default: default:
Log::warning("[{$type}] 银瓜子兑换硬币: CODE -> {$data['code']} MSG -> {$data['message']} "); Log::warning("[$type] 银瓜子兑换硬币: CODE -> {$data['code']} MSG -> {$data['message']} ");
return false; return false;
} }
} }

View File

@ -18,11 +18,11 @@ class SmallHeart
use TimeLock; use TimeLock;
use XliveHeartBeat; use XliveHeartBeat;
private static $fans_medals = []; // 全部勋章 private static array $fans_medals = []; // 全部勋章
private static $metal_lock = 0; // 勋章时间锁 private static int $metal_lock = 0; // 勋章时间锁
private static $interval = 60; // 每次跳动时间 private static int $interval = 60; // 每次跳动时间
private static $total_time = 0; private static int $total_time = 0;
private static $metal = null; private static array|null $metal = null;
public static function run() public static function run()
{ {

View File

@ -18,10 +18,10 @@ class Statistics
{ {
use TimeLock; use TimeLock;
private static $push_list = []; private static array $push_list = [];
private static $join_list = []; private static array $join_list = [];
private static $success_list = []; private static array $success_list = [];
private static $profit_list = []; private static array $profit_list = [];
// Todo 统计开关 统计时间间隔 统计类型 // Todo 统计开关 统计时间间隔 统计类型
public static function run() public static function run()
@ -111,6 +111,7 @@ class Statistics
return $c . $v . '前'; return $c . $v . '前';
} }
} }
return '';
} }
/** /**
@ -121,7 +122,7 @@ class Statistics
* @param null $second_key * @param null $second_key
* @return bool * @return bool
*/ */
private static function initKeyValue(array &$target, string $key, $value = 0, $second_key = null): bool private static function initKeyValue(array &$target, string $key, int $value = 0, $second_key = null): bool
{ {
if (!array_key_exists(self::getTodayKey(), $target)) { if (!array_key_exists(self::getTodayKey(), $target)) {
$target[self::getTodayKey()] = []; $target[self::getTodayKey()] = [];
@ -142,7 +143,7 @@ class Statistics
* @param null $second_key * @param null $second_key
* @return mixed * @return mixed
*/ */
private static function getResult(array &$target, string $key, $second_key = null) private static function getResult(array &$target, string $key, $second_key = null): mixed
{ {
is_null($second_key) ? self::initKeyValue($target, $key) : self::initKeyValue($target, $key, 0, $second_key); is_null($second_key) ? self::initKeyValue($target, $key) : self::initKeyValue($target, $key, 0, $second_key);
return is_null($second_key) ? $target[self::getTodayKey()][$key] : $target[self::getTodayKey()][$key][$second_key]; return is_null($second_key) ? $target[self::getTodayKey()][$key] : $target[self::getTodayKey()][$key][$second_key];
@ -152,10 +153,10 @@ class Statistics
* @use 获取所有结果 * @use 获取所有结果
* @param array $target * @param array $target
* @param string $key * @param string $key
* @param string $second_key * @param string|null $second_key
* @return int * @return int
*/ */
private static function getResults(array &$target, string $key, $second_key = null): int private static function getResults(array &$target, string $key, string $second_key = null): int
{ {
$results = 0; $results = 0;
is_null($second_key) ? self::initKeyValue($target, $key) : self::initKeyValue($target, $key, 0, $second_key); is_null($second_key) ? self::initKeyValue($target, $key) : self::initKeyValue($target, $key, 0, $second_key);
@ -176,7 +177,7 @@ class Statistics
* @param null $second_key * @param null $second_key
* @return bool * @return bool
*/ */
private static function valIncrease(array &$target, string $key, $num = 1, $second_key = null): bool private static function valIncrease(array &$target, string $key, int $num = 1, $second_key = null): bool
{ {
is_null($second_key) ? $target[self::getTodayKey()][$key] += $num : $target[self::getTodayKey()][$key][$second_key] += $num; is_null($second_key) ? $target[self::getTodayKey()][$key] += $num : $target[self::getTodayKey()][$key][$second_key] += $num;
return true; return true;
@ -190,7 +191,7 @@ class Statistics
* @param string $second_key * @param string $second_key
* @return bool * @return bool
*/ */
private static function valReplace(array &$target, string $key, $data = null, $second_key = ''): bool private static function valReplace(array &$target, string $key, $data = null, string $second_key = ''): bool
{ {
is_null($second_key) ? $target[self::getTodayKey()][$key] = $data : $target[self::getTodayKey()][$key][$second_key] = $data; is_null($second_key) ? $target[self::getTodayKey()][$key] = $data : $target[self::getTodayKey()][$key][$second_key] = $data;
return true; return true;

View File

@ -19,12 +19,12 @@ class StormRaffle extends BaseRaffle
const ACTIVE_TITLE = '节奏风暴'; const ACTIVE_TITLE = '节奏风暴';
const ACTIVE_SWITCH = 'live_storm'; const ACTIVE_SWITCH = 'live_storm';
protected static $wait_list = []; protected static array $wait_list = [];
protected static $finish_list = []; protected static array $finish_list = [];
protected static $all_list = []; protected static array $all_list = [];
private static $drop_rate = null; private static string|null $drop_rate = null;
private static $attempt = null; private static array|null $attempt = null;
/** /**
* @use 解析数据 * @use 解析数据
@ -76,7 +76,7 @@ class StormRaffle extends BaseRaffle
*/ */
private static function formatInfo($id, $num, $info): string private static function formatInfo($id, $num, $info): string
{ {
return "节奏风暴 {$id} 请求 {$num} 状态 {$info}"; return "节奏风暴 $id 请求 $num 状态 $info";
} }
/** /**
@ -102,7 +102,7 @@ class StormRaffle extends BaseRaffle
]; ];
for ($i = 1; $i < $num; $i++) { for ($i = 1; $i < $num; $i++) {
$raw = Curl::post('app', $url, Sign::common($payload)); $raw = Curl::post('app', $url, Sign::common($payload));
if (strpos((string)$raw, 'html') !== false) { if (str_contains((string)$raw, 'html')) {
Log::notice(self::formatInfo($raffle['raffle_id'], $num, '触发哔哩哔哩安全风控策略(412)')); Log::notice(self::formatInfo($raffle['raffle_id'], $num, '触发哔哩哔哩安全风控策略(412)'));
break; break;
} }
@ -144,7 +144,6 @@ class StormRaffle extends BaseRaffle
continue; continue;
} }
Log::notice(self::formatInfo($raffle['raffle_id'], $num, $de_raw['msg'])); Log::notice(self::formatInfo($raffle['raffle_id'], $num, $de_raw['msg']));
continue;
} }
} }
return []; return [];
@ -153,14 +152,15 @@ class StormRaffle extends BaseRaffle
/** /**
* @use 解析抽奖信息 * @use 解析抽奖信息
* @param array $results * @param array $results
* @return void * @return mixed
*/ */
protected static function parseLottery(array $results) protected static function parseLottery(array $results):mixed
{ {
foreach ($results as $result) { foreach ($results as $result) {
$data = $result['source']; $data = $result['source'];
$content = $result['content']; $content = $result['content'];
echo ''; echo '';
} }
return '';
} }
} }

View File

@ -13,6 +13,7 @@ namespace BiliHelper\Plugin;
use BiliHelper\Core\Curl; use BiliHelper\Core\Curl;
use BiliHelper\Core\Log; use BiliHelper\Core\Log;
use BiliHelper\Tool\Common; use BiliHelper\Tool\Common;
use JetBrains\PhpStorm\ArrayShape;
class User class User
{ {
@ -68,7 +69,7 @@ class User
* @param null $room_id * @param null $room_id
* @return mixed * @return mixed
*/ */
public static function webGetUserInfo($room_id = null) public static function webGetUserInfo($room_id = null): mixed
{ {
$url = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByUser'; $url = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByUser';
$payload = [ $payload = [
@ -84,7 +85,7 @@ class User
* @param null $room_id * @param null $room_id
* @return mixed * @return mixed
*/ */
public static function appGetUserInfo($room_id = null) public static function appGetUserInfo($room_id = null): mixed
{ {
$url = 'https://api.live.bilibili.com/xlive/app-room/v1/index/getInfoByUser'; $url = 'https://api.live.bilibili.com/xlive/app-room/v1/index/getInfoByUser';
$payload = [ $payload = [
@ -98,6 +99,7 @@ class User
* @use 转换信息 * @use 转换信息
* @return array * @return array
*/ */
#[ArrayShape(['csrf' => "mixed|string", 'uid' => "mixed|string", 'sid' => "mixed|string"])]
public static function parseCookies(): array public static function parseCookies(): array
{ {
$cookies = getCookie(); $cookies = getCookie();
@ -127,7 +129,7 @@ class User
'ps' => 50, 'ps' => 50,
]; ];
$headers = [ $headers = [
'referer' => "https://space.bilibili.com/{$uid}/fans/follow?tagid=-1", 'referer' => "https://space.bilibili.com/$uid/fans/follow?tagid=-1",
]; ];
$raw = Curl::get('pc', $url, $payload, $headers); $raw = Curl::get('pc', $url, $payload, $headers);
$de_raw = json_decode($raw, true); $de_raw = json_decode($raw, true);
@ -165,7 +167,7 @@ class User
'ps' => $page_size, 'ps' => $page_size,
]; ];
$headers = [ $headers = [
'referer' => "https://space.bilibili.com/{$uid}/fans/follow?tagid={$tag_id}", 'referer' => "https://space.bilibili.com/$uid/fans/follow?tagid=$tag_id",
]; ];
$raw = Curl::get('pc', $url, $payload, $headers); $raw = Curl::get('pc', $url, $payload, $headers);
$de_raw = json_decode($raw, true); $de_raw = json_decode($raw, true);
@ -189,7 +191,7 @@ class User
* @param bool $un_follow * @param bool $un_follow
* @return bool * @return bool
*/ */
public static function setUserFollow(int $follow_uid, $un_follow = false): bool public static function setUserFollow(int $follow_uid, bool $un_follow): bool
{ {
$url = 'https://api.live.bilibili.com/relation/v1/Feed/SetUserFollow'; $url = 'https://api.live.bilibili.com/relation/v1/Feed/SetUserFollow';
$payload = [ $payload = [
@ -312,7 +314,7 @@ class User
} }
Log::debug("获取会员成功 不是年度大会员或已过期"); Log::debug("获取会员成功 不是年度大会员或已过期");
} else { } else {
Log::debug("获取会员信息失败 {$raw}"); Log::debug("获取会员信息失败 $raw");
} }
return false; return false;
} }

View File

@ -18,7 +18,7 @@ class VipPrivilege
{ {
use TimeLock; use TimeLock;
private static $privilege = [ private static array $privilege = [
0 => '未知奖励', 0 => '未知奖励',
1 => 'B币劵', 1 => 'B币劵',
2 => '会员购优惠券' 2 => '会员购优惠券'
@ -66,7 +66,7 @@ class VipPrivilege
if ($de_raw['code'] == 0) { if ($de_raw['code'] == 0) {
Log::notice('大会员权益 ' . self::$privilege[$type] . ' 领取成功'); Log::notice('大会员权益 ' . self::$privilege[$type] . ' 领取成功');
} else { } else {
Log::warning('大会员权益 ' . self::$privilege[$type] . " 领取失败, {$raw}"); Log::warning('大会员权益 ' . self::$privilege[$type] . " 领取失败, $raw");
} }
} }
@ -89,7 +89,7 @@ class VipPrivilege
Log::info('获取大会员权益列表成功'); Log::info('获取大会员权益列表成功');
return $de_raw['data']['list']; return $de_raw['data']['list'];
} else { } else {
Log::warning("获取大会员权益列表失败 {$raw}"); Log::warning("获取大会员权益列表失败 $raw");
return []; return [];
} }
} }

View File

@ -15,23 +15,25 @@ use BiliHelper\Util\TimeLock;
use Amp\Delayed; use Amp\Delayed;
use Exception; use Exception;
use JetBrains\PhpStorm\Pure;
use Socket\Raw\Factory; use Socket\Raw\Factory;
use function get_class;
class ZoneTcpClient class ZoneTcpClient
{ {
use TimeLock; use TimeLock;
private static $raffle_id = 0; private static int $raffle_id = 0;
private static $raffle_list = []; private static array $raffle_list = [];
private static $server = []; private static array $server = [];
private static $server_key = null; private static string|null $server_key = null;
private static $area_id; private static int|string $area_id;
private static $room_id; private static int|string $room_id;
private static $client; private static $client;
private static $client_maps = []; private static array $client_maps = [];
private static $trigger_restart = []; private static array $trigger_restart = [];
private static $socket_timeout = 0; private static int $socket_timeout = 0;
/** /**
@ -70,7 +72,7 @@ class ZoneTcpClient
{ {
$areas = Live::fetchLiveAreas(); $areas = Live::fetchLiveAreas();
foreach ($areas as $area_id) { foreach ($areas as $area_id) {
self::$client_maps["server{$area_id}"] = ["area_id" => null, "room_id" => null, "client" => null, "heart_beat" => 0, "status" => false]; self::$client_maps["server$area_id"] = ["area_id" => null, "room_id" => null, "client" => null, "heart_beat" => 0, "status" => false];
self::triggerReConnect([ self::triggerReConnect([
'area_id' => $area_id, 'area_id' => $area_id,
'wait_time' => time() 'wait_time' => time()
@ -85,7 +87,7 @@ class ZoneTcpClient
*/ */
private static function triggerReConnect(array $area_data, string $reason) private static function triggerReConnect(array $area_data, string $reason)
{ {
Log::debug("Reconnect Reason: {$area_data['area_id']} -> {$reason}"); Log::debug("Reconnect Reason: {$area_data['area_id']} -> $reason");
self::$client_maps["server" . $area_data['area_id']]['status'] = false; self::$client_maps["server" . $area_data['area_id']]['status'] = false;
array_push(self::$trigger_restart, $area_data); array_push(self::$trigger_restart, $area_data);
} }
@ -152,7 +154,7 @@ class ZoneTcpClient
* @param bool $assoc 是否返回对象or关联数组默认返回关联数组 * @param bool $assoc 是否返回对象or关联数组默认返回关联数组
* @return array|bool|object 成功返回转换后的对象或数组,失败返回 false * @return array|bool|object 成功返回转换后的对象或数组,失败返回 false
*/ */
private static function analyJson($data = '', $assoc = true) private static function analyJson(string $data = '', bool $assoc = true): object|bool|array
{ {
if (is_array($data)) { if (is_array($data)) {
return $data; return $data;
@ -178,14 +180,14 @@ class ZoneTcpClient
// Log::info("当前直播间现有 {$num} 人聚众搞基!"); // Log::info("当前直播间现有 {$num} 人聚众搞基!");
return false; return false;
} }
$de_raw = self::analyJson($msg, true); $de_raw = self::analyJson($msg);
// 进入房间返回 // 进入房间返回
if (isset($de_raw['code']) && !$de_raw['code']) { if (isset($de_raw['code']) && !$de_raw['code']) {
return false; return false;
} }
// 部分cmd抽风 // 部分cmd抽风
if (!$de_raw || !isset($de_raw['cmd'])) { if (!$de_raw || !isset($de_raw['cmd'])) {
Log::warning("解析错误: {$msg}"); Log::warning("解析错误: $msg");
return false; return false;
} }
$data = []; $data = [];
@ -301,7 +303,7 @@ class ZoneTcpClient
]; ];
// echo self::$room_id . '--' . $real_room_id . PHP_EOL; // echo self::$room_id . '--' . $real_room_id . PHP_EOL;
} }
if ($msg_type == 6 && strpos($msg_common, '节奏风暴') !== false) { if ($msg_type == 6 && str_contains($msg_common, '节奏风暴')) {
$data = [ $data = [
'room_id' => $real_room_id, 'room_id' => $real_room_id,
'raffle_id' => self::$raffle_id++, 'raffle_id' => self::$raffle_id++,
@ -397,6 +399,7 @@ class ZoneTcpClient
* @use 心跳包 * @use 心跳包
* @return string * @return string
*/ */
#[Pure]
private static function genHeartBeatPkg(): string private static function genHeartBeatPkg(): string
{ {
return self::packMsg('', 0x0002); return self::packMsg('', 0x0002);
@ -437,12 +440,12 @@ class ZoneTcpClient
* @param $value * @param $value
* @return array|false * @return array|false
*/ */
private static function unPackMsg($value) private static function unPackMsg($value): bool|array
{ {
if (strlen($value) < 4) { if (strlen($value) < 4) {
Log::warning("unPackMsg: 包头异常 " . strlen($value)); Log::warning("unPackMsg: 包头异常 " . strlen($value));
return []; return [];
}; }
// Log::info(json_encode($head, true)); // Log::info(json_encode($head, true));
return unpack('Npacklen/nheadlen/nver/Nop/Nseq', $value); return unpack('Npacklen/nheadlen/nver/Nop/Nseq', $value);
} }
@ -472,9 +475,9 @@ class ZoneTcpClient
* @use 读数据 * @use 读数据
* @param $length * @param $length
* @param bool $is_header * @param bool $is_header
* @return array|bool * @return bool|array|string
*/ */
private static function reader($length, bool $is_header = false) private static function reader($length, bool $is_header = false): bool|array|string
{ {
$data = false; $data = false;
try { try {
@ -483,8 +486,8 @@ class ZoneTcpClient
$socket = self::$client->getResource(); $socket = self::$client->getResource();
while ($length) { while ($length) {
if ($length < 1 || $length > 65535) { if ($length < 1 || $length > 65535) {
Log::warning("Socket error: [{$ret}] [{$length}]" . PHP_EOL); Log::warning("Socket error: [$ret] [$length]" . PHP_EOL);
throw new Exception("Socket error: [{$ret}] [{$length}]"); throw new Exception("Socket error: [$ret] [$length]");
} }
$cnt = 0; $cnt = 0;
$w = NULL; $w = NULL;
@ -502,8 +505,8 @@ class ZoneTcpClient
// 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); $ret = socket_recv($socket, $buffer, $length, 0);
if ($ret < 1) { if ($ret < 1) {
Log::warning("Socket error: [{$ret}] [{$length}]" . PHP_EOL); Log::warning("Socket error: [$ret] [$length]" . PHP_EOL);
throw new Exception("Socket error: [{$ret}] [{$length}]"); throw new Exception("Socket error: [$ret] [$length]");
} }
$data .= $buffer; $data .= $buffer;
unset($buffer); unset($buffer);
@ -564,7 +567,7 @@ class ZoneTcpClient
$length = $head['packlen'] ?? 16; $length = $head['packlen'] ?? 16;
$type = $head['op'] ?? 0x0000; $type = $head['op'] ?? 0x0000;
$len_body = $length - 16; $len_body = $length - 16;
Log::debug("(AreaId={$client_info['area_id']} -> RoomId={$client_info['room_id']} -> Len={$len_body})"); Log::debug("(AreaId={$client_info['area_id']} -> RoomId={$client_info['room_id']} -> Len=$len_body)");
if (!$len_body) if (!$len_body)
continue; continue;
$body = self::reader($len_body); $body = self::reader($len_body);
@ -595,9 +598,9 @@ class ZoneTcpClient
$total = strlen($data); $total = strlen($data);
while (true) { while (true) {
if ($step > 165535) { if ($step > 165535) {
Log::warning("v2_split: 数据step异常 {$step}"); Log::warning("v2_split: 数据step异常 $step");
break; break;
}; }
if ($step == $total) break; if ($step == $total) break;
$bin = substr($data, $step, 16); $bin = substr($data, $step, 16);
$head = self::unPackMsg($bin); $head = self::unPackMsg($bin);
@ -615,8 +618,8 @@ class ZoneTcpClient
*/ */
private static function getClass($object): string private static function getClass($object): string
{ {
$class = \get_class($object); $class = get_class($object);
return 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class) . '@anonymous' : $class; return 'c' === $class[0] && str_starts_with($class, "class@anonymous\0") ? get_parent_class($class) . '@anonymous' : $class;
} }
/** /**

View File

@ -26,10 +26,10 @@ class BaseTask
* @param null $default * @param null $default
* @return mixed * @return mixed
*/ */
public static function choice(array $options, $default = null) public static function choice(array $options, $default = null): mixed
{ {
$option = static::interactor()->choice('Select', $options, $default, true); $option = static::interactor()->choice('Select', $options, $default, true);
static::interactor()->greenBold("You selected: {$options[$option]}", true); static::interactor()->greenBold("You selected: $options[$option]", true);
// return $options[$option]; // return $options[$option];
return $option; return $option;
} }

View File

@ -10,13 +10,13 @@
namespace BiliHelper\Script; namespace BiliHelper\Script;
use BiliHelper\Core\Log; use BiliHelper\Core\Log;
use BiliHelper\Core\Curl;
class DelDynamic extends BaseTask class DelDynamic extends BaseTask
{ {
public static $description = '批量删除动态默认单次最大清理300个动态.'; public static string $description = '批量删除动态默认单次最大清理300个动态.';
public static function run(){ public static function run()
{
Log::error('当前功能未完成'); Log::error('当前功能未完成');
} }
} }

View File

@ -14,7 +14,7 @@ use BiliHelper\Core\Curl;
class UnFollow extends BaseTask class UnFollow extends BaseTask
{ {
public static $description = '批量清理选定分组关注默认单次最大清理600个关注.'; public static string $description = '批量清理选定分组关注默认单次最大清理600个关注.';
/** /**
* @throws \Exception * @throws \Exception
@ -59,9 +59,9 @@ class UnFollow extends BaseTask
// {"code":0,"message":"0","ttl":1} // {"code":0,"message":"0","ttl":1}
$data = json_decode($raw, true); $data = json_decode($raw, true);
if ($data['code'] == 0) { if ($data['code'] == 0) {
Log::notice("UP.{$up_uid} - {$up_uname} 取关成功"); Log::notice("UP.$up_uid - $up_uname 取关成功");
} else { } else {
Log::error("UP.{$up_uid} - {$up_uname} 取关失败 CODE -> {$data['code']} MSG -> {$data['message']} "); Log::error("UP.$up_uid - $up_uname 取关失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
break; break;
} }
sleep(random_int(5, 10)); sleep(random_int(5, 10));
@ -99,7 +99,7 @@ class UnFollow extends BaseTask
$following[$up['mid']] = $up['uname']; $following[$up['mid']] = $up['uname'];
} }
// 打印和延迟 // 打印和延迟
Log::info("已获取分组 {$tag_id} 页码 {$pn}"); Log::info("已获取分组 $tag_id 页码 $pn");
sleep(random_int(4, 8)); sleep(random_int(4, 8));
// 如果页面不等于 max_ps 跳出 // 如果页面不等于 max_ps 跳出
if (count($data['data']) != $max_ps) { if (count($data['data']) != $max_ps) {
@ -111,7 +111,7 @@ class UnFollow extends BaseTask
} }
} }
$following_num = count($following); $following_num = count($following);
Log::notice("已获取分组 {$tag_id} 有效关注数 {$following_num}"); Log::notice("已获取分组 $tag_id 有效关注数 $following_num");
return $following; return $following;
} }
@ -120,7 +120,7 @@ class UnFollow extends BaseTask
* @use 获取分组 * @use 获取分组
* @return mixed * @return mixed
*/ */
private static function relationTags() private static function relationTags(): mixed
{ {
$url = 'https://api.bilibili.com/x/relation/tags'; $url = 'https://api.bilibili.com/x/relation/tags';
$payload = []; $payload = [];
@ -135,7 +135,7 @@ class UnFollow extends BaseTask
$options[$tag['tagid']] = "分组:{$tag['name']} - 关注数:{$tag['count']}"; $options[$tag['tagid']] = "分组:{$tag['name']} - 关注数:{$tag['count']}";
} }
$option = self::choice($options); $option = self::choice($options);
Log::notice("已获取分组 {$option} - {$options[$option]}"); Log::notice("已获取分组 $option - $options[$option]");
return $option; return $option;
} else { } else {
Log::error("获取关注分组失败 CODE -> {$data['code']} MSG -> {$data['message']} "); Log::error("获取关注分组失败 CODE -> {$data['code']} MSG -> {$data['message']} ");

View File

@ -41,7 +41,7 @@ class User
* @use 用户 * @use 用户
* @return mixed * @return mixed
*/ */
public static function userInfo() public static function userInfo(): mixed
{ {
$url = 'https://api.bilibili.com/x/web-interface/nav'; $url = 'https://api.bilibili.com/x/web-interface/nav';
$payload = []; $payload = [];

View File

@ -11,14 +11,12 @@
namespace BiliHelper\Tool; namespace BiliHelper\Tool;
use BiliHelper\Core\Log;
class BvToAv class BvToAv
{ {
protected $tr = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"; protected string $tr = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
protected $xor = 177451812; protected int $xor = 177451812;
protected $add = 8728348608; protected int $add = 8728348608;
protected $s = [11, 10, 3, 8, 4, 6]; protected array $s = [11, 10, 3, 8, 4, 6];
/** /**
@ -26,7 +24,7 @@ class BvToAv
* @param $bv * @param $bv
* @return int|string * @return int|string
*/ */
public function dec($bv) public function dec($bv): int|string
{ {
$r = 0; $r = 0;
$tr = array_flip(str_split($this->tr)); $tr = array_flip(str_split($this->tr));

View File

@ -1,60 +0,0 @@
<?php
/**
* Website: https://mudew.com/
* Author: Lkeme
* License: The MIT License
* Email: Useri@live.cn
* Updated: 2021 ~ 2022
* Source: https://github.com/fzaninotto/Faker/
*/
namespace BiliHelper\Tool;
use Flintstone\Flintstone;
use Flintstone\Formatter\JsonFormatter;
class Cache
{
private static $instance;
private static function getInstance()
{
if (is_null(self::$instance)) {
self::configureInstance();
}
return self::$instance;
}
private static function configureInstance()
{
self::$instance = new Flintstone(
'BHP', [
'dir' => APP_CACHE_PATH,
// 'gzip' => true,
'formatter' => new JsonFormatter()
]);
// self::$instance->set('bob', ['email' => 'bob@site.com', 'password' => '123456']);
}
public static function get()
{
// Get a key
// $user = $users->get('bob');
// echo 'Bob, your email is ' . $user['email'];
$args = func_get_args();
return self::getInstance()->get(...$args);
}
public static function set()
{
// Set a key
// $users->set('bob', ['email' => 'bob@site.com', 'password' => '123456']);
$args = func_get_args();
self::getInstance()->set(...$args);
}
}

View File

@ -48,7 +48,7 @@ class Common
* @param string $charset * @param string $charset
* @return string * @return string
*/ */
public static function replaceStar($str, $start, $end = 0, $dot = "*", $charset = "UTF-8"): string public static function replaceStar($str, $start, int $end = 0, string $dot = "*", string $charset = "UTF-8"): string
{ {
$len = mb_strlen($str, $charset); $len = mb_strlen($str, $charset);
if ($start == 0 || $start > $len) { if ($start == 0 || $start > $len) {

View File

@ -20,6 +20,6 @@ class DumpMemory
$unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb'); $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb');
$size = memory_get_usage(true); $size = memory_get_usage(true);
$memory = @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i]; $memory = @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i];
Log::warning("{$title} # 内存 # {$memory}"); Log::warning("$title # 内存 # $memory");
} }
} }

View File

@ -22,7 +22,7 @@ class Faker
* @example 79907610 * @example 79907610
* *
*/ */
public static function numberBetween($int1 = 0, $int2 = 2147483647): int public static function numberBetween(int $int1 = 0, int $int2 = 2147483647): int
{ {
$min = $int1 < $int2 ? $int1 : $int2; $min = $int1 < $int2 ? $int1 : $int2;
$max = $int1 < $int2 ? $int2 : $int1; $max = $int1 < $int2 ? $int2 : $int1;
@ -36,7 +36,7 @@ class Faker
* @param int $except * @param int $except
* @return int * @return int
*/ */
public static function randomDigitNot($except): int public static function randomDigitNot(int $except): int
{ {
$result = self::numberBetween(0, 8); $result = self::numberBetween(0, 8);
if ($result >= $except) { if ($result >= $except) {
@ -53,7 +53,7 @@ class Faker
* @param string $string String that needs to bet parsed * @param string $string String that needs to bet parsed
* @return string * @return string
*/ */
public static function asciify($string = '****'): string public static function asciify(string $string = '****'): string
{ {
return preg_replace_callback('/\*/u', 'static::randomAscii', $string); return preg_replace_callback('/\*/u', 'static::randomAscii', $string);
} }
@ -73,7 +73,7 @@ class Faker
/** /**
* @example '237.149.115.38' * @example '237.149.115.38'
*/ */
public function ipv4() public function ipv4(): bool|string
{ {
return long2ip(mt_rand(0, 1) == 0 ? mt_rand(-2147483648, -2) : mt_rand(16777216, 2147483647)); return long2ip(mt_rand(0, 1) == 0 ? mt_rand(-2147483648, -2) : mt_rand(16777216, 2147483647));
} }
@ -94,7 +94,7 @@ class Faker
/** /**
* @example '10.1.1.17' * @example '10.1.1.17'
*/ */
public static function localIpv4() public static function localIpv4(): bool|string
{ {
if (static::numberBetween(0, 1) === 0) { if (static::numberBetween(0, 1) === 0) {
// 10.x.x.x range // 10.x.x.x range
@ -113,17 +113,15 @@ class Faker
for ($i = 0; $i < 6; $i++) { for ($i = 0; $i < 6; $i++) {
$mac[] = sprintf('%02X', static::numberBetween(0, 0xff)); $mac[] = sprintf('%02X', static::numberBetween(0, 0xff));
} }
$mac = implode(':', $mac); return implode(':', $mac);
return $mac;
} }
/** /**
* @use 转Ascii * @use 转Ascii
* @param $string * @param $string
* @return array|string|string[] * @return array|string
*/ */
protected static function toAscii($string) protected static function toAscii($string): array|string
{ {
static $arrayFrom, $arrayTo; static $arrayFrom, $arrayTo;

View File

@ -11,6 +11,8 @@
namespace BiliHelper\Tool; namespace BiliHelper\Tool;
use JetBrains\PhpStorm\Pure;
class File class File
{ {
@ -131,9 +133,10 @@ class File
/** /**
* @use 获取文件详细信息 * @use 获取文件详细信息
* @param string $filename * @param string $filename
* @return array|false * @return array|bool
*/ */
public static function getInfo(string $filename): bool #[Pure]
public static function getInfo(string $filename): array|bool
{ {
// 如果不是文件 或者 不可读返回false // 如果不是文件 或者 不可读返回false
if (!is_file($filename) || !is_readable($filename)) { if (!is_file($filename) || !is_readable($filename)) {
@ -143,7 +146,7 @@ class File
return [ return [
"文件名称" => basename($filename), "文件名称" => basename($filename),
"文件类型" => filetype($filename), "文件类型" => filetype($filename),
"文件大小" => trans_byte(filesize($filename)), "文件大小" => static::transByte(filesize($filename)),
"创建时间" => date('Y-m-d H:i:s', filectime($filename)), "创建时间" => date('Y-m-d H:i:s', filectime($filename)),
"修改时间" => date('Y-m-d H:i:s', filemtime($filename)), "修改时间" => date('Y-m-d H:i:s', filemtime($filename)),
"上一次访问时间" => date('Y-m-d H:i:s', fileatime($filename)), "上一次访问时间" => date('Y-m-d H:i:s', fileatime($filename)),
@ -157,7 +160,7 @@ class File
* @param int $precision 小数点保留位数 * @param int $precision 小数点保留位数
* @return string 转换后的单位 * @return string 转换后的单位
*/ */
public static function transByte(int $byte, $precision = 2): string public static function transByte(int $byte, int $precision = 2): string
{ {
$kb = 1024; $kb = 1024;
$mb = 1024 * $kb; $mb = 1024 * $kb;
@ -180,6 +183,7 @@ class File
if ($byte < $tb) { if ($byte < $tb) {
return round($byte / $tb, $precision) . ' GB'; return round($byte / $tb, $precision) . ' GB';
} }
return '';
} }
@ -188,7 +192,7 @@ class File
* @param string $filename * @param string $filename
* @return false|string * @return false|string
*/ */
public static function readString(string $filename) public static function readString(string $filename): bool|string
{ {
if (is_file($filename) && is_readable($filename)) { if (is_file($filename) && is_readable($filename)) {
return file_get_contents($filename); return file_get_contents($filename);
@ -203,7 +207,7 @@ class File
* @param bool $skip_empty_lines * @param bool $skip_empty_lines
* @return array|false * @return array|false
*/ */
public static function readArray(string $filename, bool $skip_empty_lines = false) public static function readArray(string $filename, bool $skip_empty_lines = false): bool|array
{ {
if (is_file($filename) && is_readable($filename)) { if (is_file($filename) && is_readable($filename)) {
if ($skip_empty_lines) { if ($skip_empty_lines) {
@ -214,6 +218,7 @@ class File
return file($filename); return file($filename);
} }
} }
return false;
} }
@ -224,8 +229,9 @@ class File
* @param boolean $clear_content 是否清空原始内容再写入 * @param boolean $clear_content 是否清空原始内容再写入
* @return bool true|false * @return bool true|false
*/ */
public static function write(string $filename, $data, bool $clear_content = false) public static function write(string $filename, mixed $data, bool $clear_content = false): bool
{ {
$srcData = '';
$dirname = dirname($filename); $dirname = dirname($filename);
// 检测目标路径是否存在 // 检测目标路径是否存在
if (!file_exists($dirname)) { if (!file_exists($dirname)) {

View File

@ -27,12 +27,11 @@ class Generator
$chars = md5(uniqid(mt_rand(), true)); $chars = md5(uniqid(mt_rand(), true));
$chars = substr_replace($chars, "4", 12, 1); $chars = substr_replace($chars, "4", 12, 1);
$chars = substr_replace($chars, "a", 16, 1); $chars = substr_replace($chars, "a", 16, 1);
$uuid = substr($chars, 0, 8) . '-' return substr($chars, 0, 8) . '-'
. substr($chars, 8, 4) . '-' . substr($chars, 8, 4) . '-'
. substr($chars, 12, 4) . '-' . substr($chars, 12, 4) . '-'
. substr($chars, 16, 4) . '-' . substr($chars, 16, 4) . '-'
. substr($chars, 20, 12); . substr($chars, 20, 12);
return $uuid;
} }
/** /**
@ -54,11 +53,15 @@ class Generator
*/ */
public static function buvid(): string public static function buvid(): string
{ {
// XW UUID
// XX AndroidID
// XY MAC
// XZ IMEI
// XYD5B85DA7212341F51C612344A6B8C6C21234 // XYD5B85DA7212341F51C612344A6B8C6C21234
$mac = Faker::macAddress(); $mac = Faker::macAddress();
$md5 = md5($mac); $md5 = md5($mac);
$md5_arr = str_split($md5); $md5_arr = str_split($md5);
return strtoupper("XY{$md5_arr[2]}{$md5_arr[12]}{$md5_arr[22]}{$md5}"); return strtoupper("XY$md5_arr[2]$md5_arr[12]$md5_arr[22]$md5");
} }
/** /**

View File

@ -12,6 +12,8 @@
namespace BiliHelper\Tool; namespace BiliHelper\Tool;
use Exception;
/** ********************************************************************************** /** **********************************************************************************
* Generate hundreds of thousands of unique mobile & desktop User Agents that are 100% authentic. * Generate hundreds of thousands of unique mobile & desktop User Agents that are 100% authentic.
* Supports Hundreds of Android devices, 32 & 64 bit versions of Windows XP-10.5, Linux 540-686, and Mac 7-10.12 * Supports Hundreds of Android devices, 32 & 64 bit versions of Windows XP-10.5, Linux 540-686, and Mac 7-10.12
@ -23,7 +25,7 @@ class UserAgent
* Windows Operating System list with dynamic versioning * Windows Operating System list with dynamic versioning
* @var array $windows_os * @var array $windows_os
*/ */
public $windows_os = [ public array $windows_os = [
'[Windows; |Windows; U; |]Windows NT 6.:number0-3:;[ Win64; x64| WOW64| x64|]', '[Windows; |Windows; U; |]Windows NT 6.:number0-3:;[ Win64; x64| WOW64| x64|]',
'[Windows; |Windows; U; |]Windows NT 10.:number0-5:;[ Win64; x64| WOW64| x64|]' '[Windows; |Windows; U; |]Windows NT 10.:number0-5:;[ Win64; x64| WOW64| x64|]'
]; ];
@ -31,7 +33,7 @@ class UserAgent
* Linux Operating Systems [limited] * Linux Operating Systems [limited]
* @var array $linux_os * @var array $linux_os
*/ */
public $linux_os = [ public array $linux_os = [
'[Linux; |][U; |]Linux x86_64', '[Linux; |][U; |]Linux x86_64',
'[Linux; |][U; |]Linux i:number5-6::number4-8::number0-6: [x86_64|]' '[Linux; |][U; |]Linux i:number5-6::number4-8::number0-6: [x86_64|]'
]; ];
@ -39,7 +41,7 @@ class UserAgent
* Mac Operating System (OS X) with dynamic versioning * Mac Operating System (OS X) with dynamic versioning
* @var array $mac_os * @var array $mac_os
*/ */
public $mac_os = [ public array $mac_os = [
'Macintosh; [U; |]Intel Mac OS X :number7-9:_:number0-9:_:number0-9:', 'Macintosh; [U; |]Intel Mac OS X :number7-9:_:number0-9:_:number0-9:',
'Macintosh; [U; |]Intel Mac OS X 10_:number0-12:_:number0-9:' 'Macintosh; [U; |]Intel Mac OS X 10_:number0-12:_:number0-9:'
]; ];
@ -47,7 +49,7 @@ class UserAgent
* Versions of Android to be used * Versions of Android to be used
* @var array $androidVersions * @var array $androidVersions
*/ */
public $androidVersions = [ public array $androidVersions = [
'4.3.1', '4.3.1',
'4.4', '4.4',
'4.4.1', '4.4.1',
@ -67,12 +69,12 @@ class UserAgent
* Holds the version of android for the User Agent being generated * Holds the version of android for the User Agent being generated
* @property string $androidVersion * @property string $androidVersion
*/ */
public $androidVersion; public string $androidVersion;
/** /**
* Android devices and for specific android versions * Android devices and for specific android versions
* @var array $androidDevices * @var array $androidDevices
*/ */
public $androidDevices = [ public array $androidDevices = [
'4.3' => [ '4.3' => [
'GT-I9:number2-5:00 Build/JDQ39', 'GT-I9:number2-5:00 Build/JDQ39',
'Nokia 3:number1-3:[10|15] Build/IMM76D', 'Nokia 3:number1-3:[10|15] Build/IMM76D',
@ -165,12 +167,12 @@ class UserAgent
'LG-H:number90-93:0 Build/NRD90[C|M]' 'LG-H:number90-93:0 Build/NRD90[C|M]'
] ]
]; ];
public $locale = 'en-US'; public string $locale = 'en-US';
/** /**
* List of "OS" strings used for android * List of "OS" strings used for android
* @var array $android_os * @var array $android_os
*/ */
public $android_os = [ public array $android_os = [
'Linux; Android :androidVersion:; :androidDevice:', 'Linux; Android :androidVersion:; :androidDevice:',
//Todo: Add a $windowsDevices variable that does the same as androidDevice //Todo: Add a $windowsDevices variable that does the same as androidDevice
//'Windows Phone 10.0; Android :androidVersion:; :windowsDevice:', //'Windows Phone 10.0; Android :androidVersion:; :windowsDevice:',
@ -181,7 +183,7 @@ class UserAgent
* List of "OS" strings used for iOS * List of "OS" strings used for iOS
* @var array $mobile_ios * @var array $mobile_ios
*/ */
public $mobile_ios = [ public array $mobile_ios = [
'iphone' => 'iPhone; CPU iPhone OS :number7-11:_:number0-9:_:number0-9:; like Mac OS X;', '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;', '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;' 'ipod' => 'iPod; CPU iPod OS :number7-11:_:number0-9:_:number0-9:; like Mac OS X;'
@ -190,9 +192,10 @@ class UserAgent
/** /**
* Get a random operating system * Get a random operating system
* @param string|null $os * @param string|null $os
* @return string * * @return array|string|null *
* @throws \Exception
*/ */
public function getOS(string $os = NULL) public function getOS(string $os = NULL): array|string|null
{ {
$_os = []; $_os = [];
if ($os === NULL || in_array($os, ['chrome', 'firefox', 'explorer'])) { if ($os === NULL || in_array($os, ['chrome', 'firefox', 'explorer'])) {
@ -204,12 +207,12 @@ class UserAgent
$selected_os = rtrim($_os[random_int(0, count($_os) - 1)], ';'); $selected_os = rtrim($_os[random_int(0, count($_os) - 1)], ';');
// check for spin syntax // check for spin syntax
if (strpos($selected_os, '[') !== FALSE) { if (str_contains($selected_os, '[')) {
$selected_os = self::processSpinSyntax($selected_os); $selected_os = self::processSpinSyntax($selected_os);
} }
// check for random number syntax // check for random number syntax
if (strpos($selected_os, ':number') !== FALSE) { if (str_contains($selected_os, ':number')) {
$selected_os = self::processRandomNumbers($selected_os); $selected_os = self::processRandomNumbers($selected_os);
} }
@ -222,9 +225,10 @@ class UserAgent
/** /**
* Get Mobile OS * Get Mobile OS
* @param string|null $os Can specifiy android, iphone, ipad, ipod, or null/blank for random * @param string|null $os Can specifiy android, iphone, ipad, ipod, or null/blank for random
* @return string * * @return array|string|null *
* @throws \Exception
*/ */
public function getMobileOS(string $os = NULL) public function getMobileOS(string $os = NULL): array|string|null
{ {
$os = strtolower($os); $os = strtolower($os);
$_os = []; $_os = [];
@ -242,13 +246,13 @@ class UserAgent
} }
// select random mobile os // select random mobile os
$selected_os = rtrim($_os[random_int(0, count($_os) - 1)], ';'); $selected_os = rtrim($_os[random_int(0, count($_os) - 1)], ';');
if (strpos($selected_os, ':androidVersion:') !== FALSE) { if (str_contains($selected_os, ':androidVersion:')) {
$selected_os = $this->processAndroidVersion($selected_os); $selected_os = $this->processAndroidVersion($selected_os);
} }
if (strpos($selected_os, ':androidDevice:') !== FALSE) { if (str_contains($selected_os, ':androidDevice:')) {
$selected_os = $this->addAndroidDevice($selected_os); $selected_os = $this->addAndroidDevice($selected_os);
} }
if (strpos($selected_os, ':number') !== FALSE) { if (str_contains($selected_os, ':number')) {
$selected_os = self::processRandomNumbers($selected_os); $selected_os = self::processRandomNumbers($selected_os);
} }
return $selected_os; return $selected_os;
@ -258,8 +262,9 @@ class UserAgent
* static::processRandomNumbers * static::processRandomNumbers
* @param $selected_os * @param $selected_os
* @return null|string|string[] * * @return null|string|string[] *
* @throws \Exception
*/ */
public static function processRandomNumbers($selected_os) public static function processRandomNumbers($selected_os): array|string|null
{ {
return preg_replace_callback('/:number(\d+)-(\d+):/i', function ($matches) { return preg_replace_callback('/:number(\d+)-(\d+):/i', function ($matches) {
return random_int($matches[1], $matches[2]); return random_int($matches[1], $matches[2]);
@ -271,7 +276,7 @@ class UserAgent
* @param $selected_os * @param $selected_os
* @return null|string|string[] * * @return null|string|string[] *
*/ */
public static function processSpinSyntax($selected_os) public static function processSpinSyntax($selected_os): array|string|null
{ {
return preg_replace_callback('/\[([\w\-\s|;]*?)\]/i', function ($matches) { return preg_replace_callback('/\[([\w\-\s|;]*?)\]/i', function ($matches) {
$shuffle = explode('|', $matches[1]); $shuffle = explode('|', $matches[1]);
@ -284,7 +289,7 @@ class UserAgent
* @param $selected_os * @param $selected_os
* @return null|string|string[] * * @return null|string|string[] *
*/ */
public function processAndroidVersion($selected_os) public function processAndroidVersion($selected_os): array|string|null
{ {
$this->androidVersion = $version = $this->androidVersions[array_rand($this->androidVersions)]; $this->androidVersion = $version = $this->androidVersions[array_rand($this->androidVersions)];
return preg_replace_callback('/:androidVersion:/i', function ($matches) use ($version) { return preg_replace_callback('/:androidVersion:/i', function ($matches) use ($version) {
@ -297,7 +302,7 @@ class UserAgent
* @param $selected_os * @param $selected_os
* @return null|string|string[] * * @return null|string|string[] *
*/ */
public function addAndroidDevice($selected_os) public function addAndroidDevice($selected_os): array|string|null
{ {
$devices = $this->androidDevices[substr($this->androidVersion, 0, 3)]; $devices = $this->androidDevices[substr($this->androidVersion, 0, 3)];
$device = $devices[array_rand($devices)]; $device = $devices[array_rand($devices)];
@ -312,6 +317,7 @@ class UserAgent
* static::chromeVersion * static::chromeVersion
* @param $version * @param $version
* @return string * * @return string *
* @throws \Exception
*/ */
public static function chromeVersion($version): string public static function chromeVersion($version): string
{ {
@ -323,6 +329,7 @@ class UserAgent
* static::firefoxVersion * static::firefoxVersion
* @param $version * @param $version
* @return string * * @return string *
* @throws \Exception
*/ */
public static function firefoxVersion($version): string public static function firefoxVersion($version): string
{ {
@ -333,6 +340,7 @@ class UserAgent
* static::windows * static::windows
* @param $version * @param $version
* @return string * * @return string *
* @throws \Exception
*/ */
public static function windows($version): string public static function windows($version): string
{ {
@ -343,6 +351,7 @@ class UserAgent
* generate * generate
* @param null $userAgent * @param null $userAgent
* @return string * * @return string *
* @throws \Exception
*/ */
public function generate($userAgent = NULL, $locale = null): string public function generate($userAgent = NULL, $locale = null): string
{ {
@ -395,7 +404,7 @@ class UserAgent
. (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603)) . (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603))
. '.' . random_int(0, 9); . '.' . random_int(0, 9);
} else { } else {
new Exception('Unable to determine user agent to generate'); throw new Exception('Unable to determine user agent to generate');
} }
} }
} }

View File

@ -11,14 +11,15 @@
namespace BiliHelper\Util; namespace BiliHelper\Util;
use JsonDecodeStream\Parser; use JsonDecodeStream\Parser;
use stdClass;
trait AllotTasks trait AllotTasks
{ {
// protected static $repository = ''; // protected static $repository = '';
protected static $tasks = []; protected static array $tasks = [];
protected static $work_status = [ protected static array $work_status = [
'work_updated' => null, 'work_updated' => null,
'estimated_time' => null, 'estimated_time' => null,
'work_completed' => null, 'work_completed' => null,
@ -40,7 +41,7 @@ trait AllotTasks
* @param bool $time * @param bool $time
* @return bool * @return bool
*/ */
protected static function pushTask(string $operation, \stdClass $act, bool $time = false): bool protected static function pushTask(string $operation, stdClass $act, bool $time = false): bool
{ {
$task = [ $task = [
'operation' => $operation, 'operation' => $operation,
@ -53,9 +54,9 @@ trait AllotTasks
/** /**
* @use 拉取任务 * @use 拉取任务
* @return false|mixed * @return mixed
*/ */
protected static function pullTask() protected static function pullTask(): mixed
{ {
// 任务列表为空 // 任务列表为空
if (empty(static::$tasks)) { if (empty(static::$tasks)) {

View File

@ -25,10 +25,10 @@ abstract class BaseRaffle
const ACTIVE_TITLE = ''; const ACTIVE_TITLE = '';
const ACTIVE_SWITCH = ''; const ACTIVE_SWITCH = '';
protected static $wait_list; protected static array $wait_list;
protected static $finish_list; protected static array $finish_list;
protected static $all_list; protected static array $all_list;
protected static $banned_rids = []; protected static array $banned_rids = [];
public static function run() public static function run()
{ {
@ -129,7 +129,7 @@ abstract class BaseRaffle
* @param array $results * @param array $results
* @return mixed * @return mixed
*/ */
abstract protected static function parseLottery(array $results); abstract protected static function parseLottery(array $results): mixed;
/** /**
* @use 二维数组按key排序 * @use 二维数组按key排序
@ -209,7 +209,7 @@ abstract class BaseRaffle
} }
$wait_num = count(static::$wait_list); $wait_num = count(static::$wait_list);
if ($wait_num > 10 && ($wait_num % 2)) { if ($wait_num > 10 && ($wait_num % 2)) {
Log::info("当前队列中共有 {$wait_num}" . static::ACTIVE_TITLE . "待抽奖"); Log::info("当前队列中共有 $wait_num" . static::ACTIVE_TITLE . "待抽奖");
} }
return true; return true;
} }

View File

@ -16,9 +16,9 @@ use Sven\FileConfig\Drivers\Json;
trait FilterWords trait FilterWords
{ {
protected static $store; protected static Store $store;
protected static $store_status; protected static $store_status;
protected static $repository = APP_DATA_PATH . 'filter_library.json'; protected static string $repository = APP_DATA_PATH . 'filter_library.json';
/** /**
* @use 加载配置信息 * @use 加载配置信息

112
src/util/Singleton.php Normal file
View File

@ -0,0 +1,112 @@
<?php
/**
* Website: https://mudew.com/
* Author: Lkeme
* License: The MIT License
* Email: Useri@live.cn
* Updated: 2021 ~ 2022
*/
declare(strict_types=1);
namespace BiliHelper\Util;
use BiliHelper\Exceptions\SingletonException;
/**
* Singleton Trait
*
* @author Alexander Smyslov <smyslov@selby.su>
* @package Smysloff\Traits
*/
trait Singleton
{
/**
* Singleton instance
*/
private static $instance = null;
/**
* Creates an instance of Singleton
* and always returns same instance
*
* @return Singleton
*/
public static function getInstance(): self
{
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Initializes the singleton
*/
protected function init(): void
{
}
/**
* Singleton constructor.
* Singleton constructor needs to be private
* 不允许从外部调用以防止创建多个实例
* 要使用单例,必须通过 Singleton::getInstance() 方法获取实例
*/
final public function __construct()
{
$this->init();
}
/**
* Singleton can't be cloned
* 防止实例被克隆(这会创建实例的副本)
*/
final public function __clone()
{
throw new SingletonException("Singleton can't be cloned");
}
/**
* Singleton can't be serialized
*/
final public function __sleep()
{
throw new SingletonException("Singleton can't be serialized");
}
/**
* Singleton can't be deserialized
* 防止反序列化(这将创建它的副本)
*/
final public function __wakeup()
{
throw new SingletonException("Singleton can't be deserialized");
}
/**
* 其他方法自动调用
* @param $method
* @param $args
* @return mixed
*/
public function __call($method, $args)
{
return call_user_func_array([static::$instance, $method], $args);
}
/**
* 静态调用
* @param $method
* @param $args
* @return mixed
*/
public static function __callStatic($method, $args)
{
return call_user_func_array([static::$instance, $method], $args);
}
}

View File

@ -13,11 +13,12 @@ namespace BiliHelper\Util;
use Amp\Delayed; use Amp\Delayed;
use BiliHelper\Core\Task; use BiliHelper\Core\Task;
use BiliHelper\Plugin\Schedule; use BiliHelper\Plugin\Schedule;
use ReflectionClass;
trait TimeLock trait TimeLock
{ {
public static $lock = 0; public static int $lock = 0;
public static $pause_status = false; public static bool $pause_status = false;
/** /**
* @use 设置时间 * @use 设置时间
@ -26,7 +27,7 @@ trait TimeLock
public static function setLock(int $lock) public static function setLock(int $lock)
{ {
if (!static::getpauseStatus()) { if (!static::getpauseStatus()) {
Task::getInstance()::_setLock(static::getBaseClass(), time() + $lock); Task::getInstance()->_setLock(static::getBaseClass(), time() + $lock);
} }
} }
@ -36,7 +37,7 @@ trait TimeLock
*/ */
public static function getLock(): int public static function getLock(): int
{ {
return Task::getInstance()::_getLock(static::getBaseClass()); return Task::getInstance()->_getLock(static::getBaseClass());
} }
/** /**
@ -106,7 +107,7 @@ trait TimeLock
// substr(strrchr($class, "\\"), 1); // substr(strrchr($class, "\\"), 1);
// substr($class, strrpos($class, '\\') + 1); // substr($class, strrpos($class, '\\') + 1);
// array_pop(explode('\\', $class)); // array_pop(explode('\\', $class));
Schedule::triggerRefused((new \ReflectionClass(static::class))->getShortName()); Schedule::triggerRefused((new ReflectionClass(static::class))->getShortName());
} }
/** /**

View File

@ -14,26 +14,27 @@ use BiliHelper\Core\Curl;
use BiliHelper\Core\Log; use BiliHelper\Core\Log;
use BiliHelper\Plugin\Live; use BiliHelper\Plugin\Live;
use BiliHelper\Tool\Generator; use BiliHelper\Tool\Generator;
use JetBrains\PhpStorm\ArrayShape;
trait XliveHeartBeat trait XliveHeartBeat
{ {
protected static $_data = ['id' => []]; // data [ets, benchmark, time, secret_rule, id] data->id [parent_area_id, area_id, 0, room_id] protected static array|null $_data = ['id' => []]; // data [ets, benchmark, time, secret_rule, id] data->id [parent_area_id, area_id, 0, room_id]
protected static $_secret_rule = []; // secret_rule [2, 3, 1, 5] protected static array $_secret_rule = []; // secret_rule [2, 3, 1, 5]
protected static $_room_info = []; // 心跳房间信息 protected static array $_room_info = []; // 心跳房间信息
protected static $_retry = 3; // 重试次数 protected static int $_retry = 3; // 重试次数
protected static $_count_num = 0; // 计数 protected static int $_count_num = 0; // 计数
protected static $_count_time = 0; // 计时间 protected static int $_count_time = 0; // 计时间
protected static $_current_room_id = 0; // 当前运行的ROOM_ID protected static int $_current_room_id = 0; // 当前运行的ROOM_ID
protected static $_enc_server = null; // 加密服务器 依赖配置文件 protected static string|null $_enc_server = null; // 加密服务器 依赖配置文件
protected static $_default = 0; // 默认值 protected static int $_default = 0; // 默认值
// 请求配置 // 请求配置
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 string $_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 = [ protected static array $_headers = [
'content-type' => 'application/x-www-form-urlencoded', 'content-type' => 'application/x-www-form-urlencoded',
'origin' => 'https://live.bilibili.com', 'origin' => 'https://live.bilibili.com',
'referer' => 'https://live.bilibili.com/', 'referer' => 'https://live.bilibili.com/',
@ -45,9 +46,9 @@ trait XliveHeartBeat
* @param int $room_id * @param int $room_id
* @param int $max_time * @param int $max_time
* @param int $max_num * @param int $max_num
* @return int|mixed * @return mixed
*/ */
protected static function xliveHeartBeatTask(int $room_id, int $max_time, int $max_num) protected static function xliveHeartBeatTask(int $room_id, int $max_time, int $max_num): mixed
{ {
// 加载依赖 // 加载依赖
if (!static::depend()) { if (!static::depend()) {
@ -150,7 +151,7 @@ trait XliveHeartBeat
/** /**
* @use E心跳 * @use E心跳
* @param array $id * @param array $id
* @return array|false[] * @return array
*/ */
protected static function eHeartBeat(array $id): array protected static function eHeartBeat(array $id): array
{ {
@ -180,7 +181,7 @@ trait XliveHeartBeat
/** /**
* @use X心跳 * @use X心跳
* @param array $id * @param array $id
* @return array|bool[] * @return array
*/ */
protected static function xHeartBeat(array $id): array protected static function xHeartBeat(array $id): array
{ {
@ -212,7 +213,7 @@ trait XliveHeartBeat
* @param array $r * @param array $r
* @return string|false * @return string|false
*/ */
protected static function encParamS(array $t, array $r) protected static function encParamS(array $t, array $r): bool|string
{ {
$headers = [ $headers = [
'Content-Type' => 'application/json', 'Content-Type' => 'application/json',
@ -242,6 +243,7 @@ trait XliveHeartBeat
* @param array $t * @param array $t
* @return array * @return array
*/ */
#[ArrayShape(['id' => "mixed", 'device' => "mixed", 'ets' => "mixed", 'benchmark' => "mixed", 'time' => "mixed", 'ts' => "mixed", 'ua' => "mixed"])]
protected static function formatT(array $t): array protected static function formatT(array $t): array
{ {
// print_r($t); // print_r($t);

View File

@ -11,10 +11,10 @@
class ConfigGenerator class ConfigGenerator
{ {
public $filename; public string $filename;
public $template; public string $template;
private $options = ['APP_USER', 'APP_PASS']; private array $options = ['APP_USER', 'APP_PASS'];
private $default_filename = 'user.ini.example'; private string $default_filename = 'user.ini.example';
/** /**
* ConfigGenerator constructor. * ConfigGenerator constructor.
@ -30,7 +30,7 @@ class ConfigGenerator
* @param string $content * @param string $content
* @return string|string[]|null * @return string|string[]|null
*/ */
private function envReplace(string $key, string $value, string $content) private function envReplace(string $key, string $value, string $content): array|string|null
{ {
return preg_replace( return preg_replace(
'/^' . $key . '=.*' . '/m', '/^' . $key . '=.*' . '/m',
@ -44,7 +44,7 @@ class ConfigGenerator
* @param int $max_char * @param int $max_char
* @return string * @return string
*/ */
private function cliInput(string $msg, $max_char = 100): string private function cliInput(string $msg, int $max_char = 100): string
{ {
$stdin = fopen('php://stdin', 'r'); $stdin = fopen('php://stdin', 'r');
echo '# ' . $msg; echo '# ' . $msg;
@ -61,7 +61,7 @@ class ConfigGenerator
$this->filename = $this->cliInput('请输入配置文件名: '); $this->filename = $this->cliInput('请输入配置文件名: ');
$this->template = file_get_contents($this->default_filename); $this->template = file_get_contents($this->default_filename);
foreach ($this->options as $index => $option) { foreach ($this->options as $index => $option) {
$value = $this->cliInput("请输入{$option}: "); $value = $this->cliInput("请输入$option: ");
$this->template = $this->envReplace($option, $value, $this->template); $this->template = $this->envReplace($option, $value, $this->template);
} }
file_put_contents(__DIR__ . "\\$this->filename.ini", $this->template); file_put_contents(__DIR__ . "\\$this->filename.ini", $this->template);