mirror of
https://github.com/lkeme/BiliHelper-personal.git
synced 2025-12-19 09:30:10 +08:00
[add] Script Mode
This commit is contained in:
parent
764dbf649c
commit
1ef8264f20
4
.gitignore
vendored
4
.gitignore
vendored
@ -28,10 +28,12 @@ conf/user1.ini
|
||||
/conf/test1.ini
|
||||
/log/
|
||||
/src/backup/
|
||||
script.php
|
||||
|
||||
# ignore all files in lib/
|
||||
task/*
|
||||
# except for .gitkeep
|
||||
!.gitkeep
|
||||
# ignore TODO file in root directory,not subdir/TODO
|
||||
/TODO
|
||||
/TODO
|
||||
/Todo
|
||||
26
CHANGELOG.md
26
CHANGELOG.md
@ -2,7 +2,33 @@
|
||||
|
||||
# 本项目Log
|
||||
|
||||
[comment]: <> (<details>)
|
||||
|
||||
[comment]: <> ( <summary><strong>更新历史</strong><kbd>latest</kbd></summary>)
|
||||
|
||||
[comment]: <> (</details>)
|
||||
|
||||
## v0.9.7.210714 alpha (2021-07-14)
|
||||
|
||||
### Added
|
||||
|
||||
- 添加脚本模式 `php index.php -?`
|
||||
-
|
||||
|
||||
### Changed
|
||||
|
||||
- 省略
|
||||
-
|
||||
|
||||
### Fixed
|
||||
|
||||
- 省略
|
||||
-
|
||||
|
||||
### Remarks
|
||||
|
||||
- 注意配置文件有些许改动
|
||||
-
|
||||
|
||||
## v0.9.6.210625 alpha (2021-06-25)
|
||||
|
||||
|
||||
84
README.md
84
README.md
@ -9,13 +9,14 @@
|
||||

|
||||

|
||||

|
||||

|
||||
[](https://hub.docker.com/r/lkeme/bilihelper-personal)
|
||||
|
||||
</div>
|
||||
|
||||
<p align="center">
|
||||
|
||||
<img src="https://img.shields.io/badge/Version-0.9.6.210625-orange.svg?longCache=true&style=for-the-badge">
|
||||
<img src="https://img.shields.io/badge/Version-0.9.7.210714-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/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">
|
||||
@ -30,48 +31,53 @@
|
||||
---- 免费的东西总是得不到人的珍惜。
|
||||
---- 只有花大价钱去买到的东西,才会令人信任。
|
||||
```
|
||||
## 🖥️星图
|
||||
|
||||
[](https://starchart.cc/lkeme/BiliHelper-personal)
|
||||
[](https://starchart.cc/lkeme/BiliHelper)
|
||||
|
||||
## 功能组件
|
||||
|
||||
以下任务都是按设定周期自动执行,`true`为正常使用,`false`为暂停使用或抛弃。
|
||||
|
||||
| plugin | status | version | description |
|
||||
|-----------------|--------|----------|---------------------------------------------|
|
||||
| CheckUpdate | true | 21.06.25 | 程序检查更新 |
|
||||
| Login | true | 21.06.25 | 账号登录、刷新、维持 |
|
||||
| Schedule | true | 21.06.25 | 控制插件运行周期 |
|
||||
| MainSite | true | 21.06.25 | 投币、观看、分享视频 (速升6级不是梦) |
|
||||
| DailyBag | true | 21.06.25 | 双端领取日常/周常礼包 |
|
||||
| ManGa | true | 21.06.25 | 漫画签到、分享 |
|
||||
| ActivityLottery | true | 21.06.25 | 主站活动九宫格抽奖 |
|
||||
| Competition | true | 21.06.25 | 游戏赛事竞猜 |
|
||||
| DoubleHeart | true | 21.06.25 | 双端心跳 (姥爷直播经验) |
|
||||
| DailyTask | true | 21.06.25 | 直播每日任务(签到、观看) |
|
||||
| Barrage | true | 21.06.25 | 保持活跃弹幕 |
|
||||
| Silver2Coin | true | 21.06.25 | 银瓜子兑换硬币 |
|
||||
| Judge | true | 21.06.25 | 风纪委员投票 |
|
||||
| GiftSend | true | 21.06.25 | 礼物赠送、维持每日勋章亲密度 |
|
||||
| GroupSignIn | true | 21.06.25 | 友爱社签到 |
|
||||
| GiftHeart | true | 21.06.25 | 日常心跳每日礼包礼物 |
|
||||
| SmallHeart | true | 21.06.25 | 直播挂机,每日24个小心心 |
|
||||
| MaterialObject | true | 21.06.25 | 直播金色宝箱实物抽奖 |
|
||||
| AloneTcpClient | true | 21.06.25 | 作者的独立直播监控(可支持本项目哦) |
|
||||
| ZoneTcpClient | true | 21.06.25 | 官方的分区直播监控 |
|
||||
| StormRaffle | true | 21.06.25 | 直播节奏风暴抽奖、亿元 |
|
||||
| GiftRaffle | true | 21.06.25 | 直播礼物抽奖 |
|
||||
| PkRaffle | true | 21.06.25 | 直播大乱斗抽奖 |
|
||||
| GuardRaffle | true | 21.06.25 | 直播大航海抽奖 |
|
||||
| AnchorRaffle | true | 21.06.25 | 直播天选时刻抽奖 |
|
||||
| GiftRaffle | true | 21.06.25 | 直播礼物抽奖 |
|
||||
| AwardRecord | true | 21.06.25 | 最新的中奖纪录通知 |
|
||||
| Forward | true | 21.06.25 | 主站动态抽奖转发 |
|
||||
| CapsuleLottery | true | 21.06.25 | 直播扭蛋活动抽奖 |
|
||||
| PolishTheMedal | true | 21.06.25 | 每日自动点亮灰色勋章 |
|
||||
| CapsuleLottery | true | 21.06.25 | 直播扭蛋活动抽奖 |
|
||||
| VipPrivilege | true | 21.06.25 | 每月领取年度大会员特权(B币券、会员购优惠券) |
|
||||
| BpConsumption | true | 21.06.25 | 每月消费使用年度大会员特权的B币券 |
|
||||
| Statistics | true | 21.06.25 | 全局抽奖结果统计 |
|
||||
| Silver | false | 21.03.27 | 直播银瓜子自动开启宝箱 |
|
||||
| plugin | status | version | cycle | description |
|
||||
|-----------------|--------|----------|--------|---------------------------------------------|
|
||||
| CheckUpdate | true | 21.07.14 | 待整理 | 程序检查更新 |
|
||||
| Login | true | 21.07.14 | 待整理 | 账号登录、刷新、维持 |
|
||||
| Schedule | true | 21.07.14 | 待整理 | 控制插件运行周期 |
|
||||
| MainSite | true | 21.07.14 | 待整理 | 投币、观看、分享视频 (速升6级不是梦) |
|
||||
| DailyBag | true | 21.07.14 | 待整理 | 双端领取日常/周常礼包 |
|
||||
| ManGa | true | 21.07.14 | 待整理 | 漫画签到、分享 |
|
||||
| ActivityLottery | true | 21.07.14 | 待整理 | 主站活动九宫格抽奖 |
|
||||
| Competition | true | 21.07.14 | 待整理 | 游戏赛事竞猜 |
|
||||
| DoubleHeart | true | 21.07.14 | 待整理 | 双端心跳 (姥爷直播经验) |
|
||||
| DailyTask | true | 21.07.14 | 待整理 | 直播每日任务(签到、观看) |
|
||||
| Barrage | true | 21.07.14 | 待整理 | 保持活跃弹幕 |
|
||||
| Silver2Coin | true | 21.07.14 | 待整理 | 银瓜子兑换硬币 |
|
||||
| Judge | true | 21.07.14 | 待整理 | 风纪委员投票 |
|
||||
| GiftSend | true | 21.07.14 | 待整理 | 礼物赠送、维持每日勋章亲密度 |
|
||||
| GroupSignIn | true | 21.07.14 | 待整理 | 友爱社签到 |
|
||||
| GiftHeart | true | 21.07.14 | 待整理 | 日常心跳每日礼包礼物 |
|
||||
| SmallHeart | true | 21.07.14 | 待整理 | 直播挂机,每日24个小心心 |
|
||||
| MaterialObject | true | 21.07.14 | 待整理 | 直播金色宝箱实物抽奖 |
|
||||
| AloneTcpClient | true | 21.07.14 | 待整理 | 作者的独立直播监控(可支持本项目哦) |
|
||||
| ZoneTcpClient | true | 21.07.14 | 待整理 | 官方的分区直播监控 |
|
||||
| StormRaffle | true | 21.07.14 | 待整理 | 直播节奏风暴抽奖、亿元 |
|
||||
| GiftRaffle | true | 21.07.14 | 待整理 | 直播礼物抽奖 |
|
||||
| PkRaffle | true | 21.07.14 | 待整理 | 直播大乱斗抽奖 |
|
||||
| GuardRaffle | true | 21.07.14 | 待整理 | 直播大航海抽奖 |
|
||||
| AnchorRaffle | true | 21.07.14 | 待整理 | 直播天选时刻抽奖 |
|
||||
| GiftRaffle | true | 21.07.14 | 待整理 | 直播礼物抽奖 |
|
||||
| AwardRecord | true | 21.07.14 | 待整理 | 最新的中奖纪录通知 |
|
||||
| Forward | true | 21.07.14 | 待整理 | 主站动态抽奖转发 |
|
||||
| CapsuleLottery | true | 21.07.14 | 待整理 | 直播扭蛋活动抽奖 |
|
||||
| PolishTheMedal | true | 21.07.14 | 待整理 | 每日自动点亮灰色勋章 |
|
||||
| CapsuleLottery | true | 21.07.14 | 待整理 | 直播扭蛋活动抽奖 |
|
||||
| VipPrivilege | true | 21.07.14 | 待整理 | 每月领取年度大会员特权(B币券、会员购优惠券) |
|
||||
| BpConsumption | true | 21.07.14 | 待整理 | 每月消费使用年度大会员特权的B币券 |
|
||||
| Statistics | true | 21.07.14 | 待整理 | 全局抽奖结果统计 |
|
||||
| Silver | false | 21.03.27 | 待整理 | 直播银瓜子自动开启宝箱 |
|
||||
|
||||
|
||||
## 交流反馈
|
||||
|
||||
@ -81,6 +87,8 @@ Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **请不要来问如
|
||||
|
||||
有疑问一定要先看看文档或Issue里是否存在相同的问题,再考虑其他渠道咨询。
|
||||
|
||||
[comment]: <> (:cherry_blossom: :gift: :gift_heart: :confetti_ball:)
|
||||
|
||||
* [使用文档 / DOC.md](./DOC.md)
|
||||
* [更新日志 / CHANGELOG.md](./CHANGELOG.md)
|
||||
* [配置文档 / WIKI.md](https://github.com/lkeme/BiliHelper-personal/wiki/%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3)
|
||||
|
||||
@ -19,7 +19,9 @@
|
||||
"klkvsk/json-decode-stream": "^1.0",
|
||||
"sven/file-config": "^3.1",
|
||||
"hassankhan/config": "^2.2",
|
||||
"lkeme/inifile": "^3.4"
|
||||
"lkeme/inifile": "^3.4",
|
||||
"adhocore/cli": "^0.9.0",
|
||||
"vanilla/garden-cli": "^3.1"
|
||||
},
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
@ -35,7 +37,7 @@
|
||||
"BiliHelper\\Plugin\\": "src/plugin",
|
||||
"BiliHelper\\Util\\": "src/util",
|
||||
"BiliHelper\\Tool\\": "src/tool",
|
||||
"BiliHelper\\Backup\\": "src/backup"
|
||||
"BiliHelper\\Script\\": "src/script"
|
||||
},
|
||||
"files": [
|
||||
"src/core/Helpers.php"
|
||||
|
||||
163
composer.lock
generated
163
composer.lock
generated
@ -4,8 +4,80 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "224c6b1ce9f6f5220d3de9434a44da42",
|
||||
"content-hash": "0678ecd04eed6db66de4668ffffec283",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/cli",
|
||||
"version": "0.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/adhocore/php-cli.git",
|
||||
"reference": "319c7dd0092c0346d9ad03366cc13d3491b57e34"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/adhocore/php-cli/zipball/319c7dd0092c0346d9ad03366cc13d3491b57e34",
|
||||
"reference": "319c7dd0092c0346d9ad03366cc13d3491b57e34",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Ahc\\Cli\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jitendra Adhikari",
|
||||
"email": "jiten.adhikary@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Command line interface library for PHP",
|
||||
"keywords": [
|
||||
"PHP7",
|
||||
"argument-parser",
|
||||
"argv-parser",
|
||||
"cli",
|
||||
"cli-action",
|
||||
"cli-app",
|
||||
"cli-color",
|
||||
"cli-option",
|
||||
"cli-writer",
|
||||
"command",
|
||||
"console",
|
||||
"console-app",
|
||||
"php-cli",
|
||||
"stream-input",
|
||||
"stream-output"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/adhocore/php-cli/issues",
|
||||
"source": "https://github.com/adhocore/php-cli/tree/0.9.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://paypal.me/ji10",
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2021-01-06T00:25:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "amphp/amp",
|
||||
"version": "v2.5.2",
|
||||
@ -609,16 +681,16 @@
|
||||
},
|
||||
{
|
||||
"name": "klkvsk/json-decode-stream",
|
||||
"version": "v1.0.2",
|
||||
"version": "v1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/klkvsk/json-decode-stream.git",
|
||||
"reference": "76cbcd9eb9f1860293b82b4f071e76826bc90c82"
|
||||
"reference": "831b5310b42b51705a2d6ae5353bba7aaa302358"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/klkvsk/json-decode-stream/zipball/76cbcd9eb9f1860293b82b4f071e76826bc90c82",
|
||||
"reference": "76cbcd9eb9f1860293b82b4f071e76826bc90c82",
|
||||
"url": "https://api.github.com/repos/klkvsk/json-decode-stream/zipball/831b5310b42b51705a2d6ae5353bba7aaa302358",
|
||||
"reference": "831b5310b42b51705a2d6ae5353bba7aaa302358",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -663,9 +735,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/klkvsk/json-decode-stream/issues",
|
||||
"source": "https://github.com/klkvsk/json-decode-stream/tree/v1.0.2"
|
||||
"source": "https://github.com/klkvsk/json-decode-stream/tree/v1.0.3"
|
||||
},
|
||||
"time": "2021-03-23T14:26:50+00:00"
|
||||
"time": "2021-06-29T23:00:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-servicemanager",
|
||||
@ -762,16 +834,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-stdlib",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-stdlib.git",
|
||||
"reference": "d81c7ffe602ed0e6ecb18691019111c0f4bf1efe"
|
||||
"reference": "e89c2268c9cad25099f562f7f015c28c5dd383c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/d81c7ffe602ed0e6ecb18691019111c0f4bf1efe",
|
||||
"reference": "d81c7ffe602ed0e6ecb18691019111c0f4bf1efe",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/e89c2268c9cad25099f562f7f015c28c5dd383c9",
|
||||
"reference": "e89c2268c9cad25099f562f7f015c28c5dd383c9",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -788,9 +860,11 @@
|
||||
"zendframework/zend-stdlib": "^3.2.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"laminas/laminas-coding-standard": "~1.0.0",
|
||||
"laminas/laminas-coding-standard": "~2.3.0",
|
||||
"phpbench/phpbench": "^0.17.1",
|
||||
"phpunit/phpunit": "~9.3.7"
|
||||
"phpunit/phpunit": "~9.3.7",
|
||||
"psalm/plugin-phpunit": "^0.16.0",
|
||||
"vimeo/psalm": "^4.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -822,7 +896,7 @@
|
||||
"type": "community_bridge"
|
||||
}
|
||||
],
|
||||
"time": "2020-11-19T20:18:59+00:00"
|
||||
"time": "2021-06-28T21:37:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-text",
|
||||
@ -1715,6 +1789,67 @@
|
||||
}
|
||||
],
|
||||
"time": "2021-05-27T09:17:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vanilla/garden-cli",
|
||||
"version": "v3.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vanilla/garden-cli.git",
|
||||
"reference": "d9844c47f4f2812259ee1b583aa66e7b6b5d85c5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vanilla/garden-cli/zipball/d9844c47f4f2812259ee1b583aa66e7b6b5d85c5",
|
||||
"reference": "d9844c47f4f2812259ee1b583aa66e7b6b5d85c5",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": ">=7.2",
|
||||
"psr/log": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ergebnis/composer-normalize": "^2.8",
|
||||
"phpdocumentor/reflection-docblock": "^4.3",
|
||||
"phpunit/phpunit": "^8",
|
||||
"vanilla/garden-container": "^3.0",
|
||||
"vanilla/standards": "^1.3",
|
||||
"vimeo/psalm": "^3.16"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pdo": "Required for the DbUtils class.",
|
||||
"phpdocumentor/reflection-docblock": "Required for the CliApplication functionality.",
|
||||
"vanilla/garden-container": "Required for the CliApplication functionality."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Garden\\Cli\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Todd Burry",
|
||||
"email": "todd@vanillaforums.com"
|
||||
}
|
||||
],
|
||||
"description": "A full-featured, yet ridiculously simple commandline parser for your next php cli script. Stop fighting with getopt().",
|
||||
"support": {
|
||||
"issues": "https://github.com/vanilla/garden-cli/issues",
|
||||
"source": "https://github.com/vanilla/garden-cli/tree/v3.1.2"
|
||||
},
|
||||
"time": "2020-10-25T13:36:44+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
||||
@ -149,7 +149,7 @@ bp2gold = false
|
||||
enable = false
|
||||
clear_dynamic = false
|
||||
clear_group_follow = false
|
||||
min_fans_num = 4999
|
||||
min_fans_num = 15000
|
||||
auto_reply_text =
|
||||
filter_words =
|
||||
|
||||
|
||||
@ -640,7 +640,8 @@
|
||||
"wav使用权",
|
||||
"曲谱",
|
||||
"抽个寂寞",
|
||||
"儿子"
|
||||
"儿子",
|
||||
"送我"
|
||||
],
|
||||
"uid_list": [
|
||||
28008897,
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
"source": "https://github.com/lkeme/BiliHelper-personal",
|
||||
"raw_url": "https://cdn.jsdelivr.net/gh/lkeme/BiliHelper-personal@master/data/latest_version.json",
|
||||
"purge_url": "https://purge.jsdelivr.net/gh/lkeme/BiliHelper-personal@master/data/latest_version.json",
|
||||
"version": "0.9.6.210625",
|
||||
"version": "0.9.7.210714",
|
||||
"des": "程序有更新,请及时线上查看更新哦~",
|
||||
"time": "2021年6月25日11:40:35"
|
||||
"time": "2021年7月14日11:40:35"
|
||||
}
|
||||
@ -11,10 +11,7 @@
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
|
||||
$filename = $argv[1] ?? 'user.ini';
|
||||
|
||||
$app = new BiliHelper\Core\App(__DIR__);
|
||||
$app->load($filename)
|
||||
$app->load($argv)
|
||||
->inspect()
|
||||
->start();
|
||||
|
||||
@ -11,10 +11,14 @@
|
||||
namespace BiliHelper\Core;
|
||||
|
||||
use Amp\Loop;
|
||||
use Ahc\Cli\IO\Interactor;
|
||||
use function Amp\asyncCall;
|
||||
|
||||
class App
|
||||
{
|
||||
private $script_mode = false;
|
||||
private $loop_mode = true;
|
||||
|
||||
/**
|
||||
* App constructor.
|
||||
* @param string $app_path
|
||||
@ -39,39 +43,58 @@ class App
|
||||
|
||||
/**
|
||||
* @use 加载配置
|
||||
* @param string $load_file
|
||||
* @param $argv
|
||||
* @return $this
|
||||
*/
|
||||
public function load(string $load_file = 'user.ini'): App
|
||||
public function load($argv): App
|
||||
{
|
||||
Config::load($load_file);
|
||||
$args = (new Command($argv))->run();
|
||||
$filename = $args->getArg(0) ?? 'user.ini';
|
||||
$this->script_mode = $args->getOpt('script');
|
||||
|
||||
Config::load($filename);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 新任务
|
||||
* @param string $taskName
|
||||
* @param string $dir
|
||||
*/
|
||||
public function newTask(string $taskName)
|
||||
public function newTask(string $taskName, string $dir)
|
||||
{
|
||||
asyncCall(function () use ($taskName) {
|
||||
asyncCall(function () use ($taskName, $dir) {
|
||||
while (true) {
|
||||
try {
|
||||
call_user_func(array('BiliHelper\Plugin\\' . $taskName, 'run'), []);
|
||||
call_user_func(array("BiliHelper\\$dir\\" . $taskName, 'run'), []);
|
||||
} catch (\Throwable $e) {
|
||||
$error_msg = "MSG: {$e->getMessage()} CODE: {$e->getCode()} FILE: {$e->getFile()} LINE: {$e->getLine()}";
|
||||
Log::error($error_msg);
|
||||
// Notice::push('error', $error_msg);
|
||||
}
|
||||
yield call_user_func(array('BiliHelper\Plugin\\' . $taskName, 'Delayed'), []);
|
||||
yield call_user_func(array("BiliHelper\\$dir\\" . $taskName, 'Delayed'), []);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 核心运行
|
||||
* @use Script模式
|
||||
*/
|
||||
public function start()
|
||||
private function script_m()
|
||||
{
|
||||
$scripts = [
|
||||
'UnFollow' => '批量取消关注(暂测试)',
|
||||
'DelDynamic' => '批量清理动态(未完成)'
|
||||
];
|
||||
|
||||
$choice = \BiliHelper\Script\BaseTask::choice($scripts, 'UnFollow');
|
||||
$this->newTask($choice, 'Script');
|
||||
}
|
||||
|
||||
/**
|
||||
* @use Loop模式
|
||||
*/
|
||||
private function loop_m()
|
||||
{
|
||||
$plugins = [
|
||||
'CheckUpdate',
|
||||
@ -110,8 +133,24 @@ class App
|
||||
|
||||
];
|
||||
foreach ($plugins as $plugin) {
|
||||
$this->newTask($plugin);
|
||||
$this->newTask($plugin, 'Plugin');
|
||||
}
|
||||
Loop::run();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @use 核心运行
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
// Todo 模式名称需要优化
|
||||
if ($this->script_mode) {
|
||||
Log::info('执行Script模式');
|
||||
$this->script_m();
|
||||
} else {
|
||||
Log::info('执行Loop模式');
|
||||
$this->loop_m();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
52
src/core/Command.php
Normal file
52
src/core/Command.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Website: https://mudew.com/
|
||||
* Author: Lkeme
|
||||
* License: The MIT License
|
||||
* Email: Useri@live.cn
|
||||
* Updated: 2021 ~ 2022
|
||||
*/
|
||||
|
||||
namespace BiliHelper\Core;
|
||||
|
||||
use Garden\Cli\Cli;
|
||||
use Garden\Cli\Args;
|
||||
|
||||
class Command
|
||||
{
|
||||
|
||||
private $argv;
|
||||
|
||||
/**
|
||||
* Command constructor.
|
||||
* @param $argv
|
||||
*/
|
||||
public function __construct($argv)
|
||||
{
|
||||
$this->argv = $argv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Garden\Cli\Args
|
||||
*/
|
||||
public function run(): Args
|
||||
{
|
||||
$cli = new Cli();
|
||||
|
||||
$cli->description('BHP命令行工具.')
|
||||
->opt('script:s', '执行的Script模式.', false, 'bool');
|
||||
|
||||
try {
|
||||
$args = $cli->parse($this->argv, true);
|
||||
} catch (\Exception $e) {
|
||||
die('解析命令行参数错误');
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -243,7 +243,7 @@ class Curl
|
||||
'Connection' => 'keep-alive',
|
||||
// 'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
// 'User-Agent' => 'Mozilla/5.0 BiliDroid/5.51.1 (bbcallen@gmail.com)',
|
||||
'User-Agent' => 'Mozilla/5.0 BiliDroid/6.31.0 (bbcallen@gmail.com) os/android model/MuMu mobi_app/android build/6310200 channel/bili innerVer/6310200 osVer/7.1.2 network/2',
|
||||
'User-Agent' => 'Mozilla/5.0 BiliDroid/6.32.0 (bbcallen@gmail.com) os/android model/MuMu mobi_app/android build/6320200 channel/bili innerVer/6320200 osVer/7.1.2 network/2',
|
||||
// 'Referer' => 'https://live.bilibili.com/',
|
||||
];
|
||||
$pc_headers = [
|
||||
|
||||
@ -103,4 +103,15 @@ function getUid(): int
|
||||
function getCsrf(): string
|
||||
{
|
||||
return getConf('csrf', 'login.auth');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @use HttpClient
|
||||
* @param string $url
|
||||
* @return \HttpClient
|
||||
*/
|
||||
function newHttp(string $url): HttpClient
|
||||
{
|
||||
return new HttpClient($url);
|
||||
}
|
||||
159
src/core/HttpClient.php
Normal file
159
src/core/HttpClient.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Website: https://mudew.com/
|
||||
* Author: Lkeme
|
||||
* License: The MIT License
|
||||
* Email: Useri@live.cn
|
||||
* Updated: 2021 ~ 2022
|
||||
* Resource: https://github.com/XcantloadX
|
||||
*/
|
||||
|
||||
namespace BiliHelper\Core;
|
||||
|
||||
class HttpClient
|
||||
{
|
||||
private $ch;
|
||||
private $ret;
|
||||
private $form;
|
||||
private $headers;
|
||||
private $url;
|
||||
private $query;
|
||||
|
||||
public function __construct(string $url)
|
||||
{
|
||||
$this->ch = curl_init();
|
||||
$this->url = $url;
|
||||
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false); //忽略 HTTPS 证书错误
|
||||
$this->setUA("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36");
|
||||
}
|
||||
|
||||
function __destruct()
|
||||
{
|
||||
//防止内存泄露
|
||||
curl_close($this->ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 设置UA
|
||||
* @param string $ua
|
||||
* @return $this
|
||||
*/
|
||||
public function setUA(string $ua): HttpClient
|
||||
{
|
||||
curl_setopt($this->ch, CURLOPT_USERAGENT, $ua); //设置 UA
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 添加Header
|
||||
* @param string $header
|
||||
* @return $this
|
||||
*/
|
||||
public function addHeader(string $header): HttpClient
|
||||
{
|
||||
array_push($this->headers, $header);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 添加Headers
|
||||
* @param array $headers
|
||||
* @return $this
|
||||
*/
|
||||
public function addHeaders(array $headers): HttpClient
|
||||
{
|
||||
foreach ($headers as $key => $value) {
|
||||
array_push($this->headers, "{$key}: {$value}");
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 设置Cookie
|
||||
* @param string $cookie
|
||||
* @return $this
|
||||
*/
|
||||
public function setCookie(string $cookie): HttpClient
|
||||
{
|
||||
curl_setopt($this->ch, CURLOPT_COOKIE, $cookie);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 设置 url 参数
|
||||
*/
|
||||
public function buildQuery(array $query): HttpClient
|
||||
{
|
||||
$this->query = http_build_query($query);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 自动将 json 文本解码
|
||||
*/
|
||||
public function asJSON(): object
|
||||
{
|
||||
return json_decode($this->ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 获取返回结果
|
||||
*/
|
||||
public function asString(): string
|
||||
{
|
||||
return $this->ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 构造POST表单
|
||||
* @param array $form
|
||||
* @return $this
|
||||
*/
|
||||
public function buildPostForm(array $form): HttpClient
|
||||
{
|
||||
$this->form = http_build_query($form);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 发送 Get 请求
|
||||
*/
|
||||
public function get(): HttpClient
|
||||
{
|
||||
curl_setopt($this->ch, CURLOPT_URL, $this->url . "?" . $this->query);
|
||||
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中
|
||||
curl_setopt($this->ch, CURLOPT_HEADER, $this->headers);
|
||||
$this->ret = curl_exec($this->ch);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 发送 POST 请求
|
||||
* @param string|null $data 要 POST 的数据
|
||||
* @return \HttpClient
|
||||
*/
|
||||
public function post(string $data = null): HttpClient
|
||||
{
|
||||
curl_setopt($this->ch, CURLOPT_URL, $this->url . "?" . $this->query);
|
||||
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中
|
||||
curl_setopt($this->ch, CURLOPT_POST, true); // 发送 POST 请求
|
||||
curl_setopt($this->ch, CURLOPT_HEADER, $this->headers);
|
||||
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
|
||||
$this->ret = curl_exec($this->ch);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @use POST表单
|
||||
* @param array $form
|
||||
* @return $this
|
||||
*/
|
||||
public function postForm(array $form): HttpClient
|
||||
{
|
||||
return $this->post(http_build_query($form));
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ class Barrage
|
||||
$response = Live::sendBarragePC($room_id, $content);
|
||||
// {"code":0,"data":[],"message":"","msg":""}
|
||||
// {"code":0,"message":"你被禁言啦","msg":"你被禁言啦"}
|
||||
// TODO 长度限制
|
||||
// Todo 长度限制
|
||||
if (isset($response['code']) && $response['code'] == 0 && isset($response['data'])) {
|
||||
Log::notice("在直播间@{$room_id} 发送活跃弹幕成功 CODE -> {$response['code']}");
|
||||
return true;
|
||||
|
||||
@ -108,7 +108,7 @@ class CapsuleLottery
|
||||
Log::info("执行 {$task['act']->title} #{$task['operation']} 任务");
|
||||
// 执行任务
|
||||
switch ($task['operation']) {
|
||||
// TODO 观看 分享 签到任务
|
||||
// Todo 观看 分享 签到任务
|
||||
case 'watch':
|
||||
$interval = self::xliveHeartBeatTask($task['act']->room_id, 999, 999);
|
||||
self::$interval = $interval == 0 ? 60 : $interval;
|
||||
|
||||
@ -47,7 +47,7 @@ class CheckUpdate
|
||||
Log::info('项目已是最新版本');
|
||||
} else {
|
||||
Log::notice('项目有更新');
|
||||
// TODO 完善提示信息
|
||||
// Todo 完善提示信息
|
||||
$time = self::$latest_conf->get('time');
|
||||
$version = self::$latest_conf->get('version');
|
||||
$des = self::$latest_conf->get('des');
|
||||
|
||||
@ -12,7 +12,7 @@ namespace BiliHelper\Plugin;
|
||||
|
||||
class DataTreating
|
||||
{
|
||||
// TODO 独立分发 Push||Pull数据
|
||||
// Todo 独立分发 Push||Pull数据
|
||||
/**
|
||||
* @use 抽奖分发
|
||||
* @param array $data
|
||||
|
||||
@ -16,7 +16,7 @@ class Dynamic
|
||||
{
|
||||
use FilterWords;
|
||||
|
||||
// TODO 活动订阅
|
||||
// Todo 活动订阅
|
||||
// https://www.bilibili.com/blackboard/activity-WeqT10t1ep.html
|
||||
// https://api.vc.bilibili.com/topic_svr/v1/topic_svr/fetch_dynamics?topic_name=%E4%BA%92%E5%8A%A8%E6%8A%BD%E5%A5%96&sortby=2
|
||||
private static $tags = ['互动抽奖', '抽奖', '转发抽奖', '动态抽奖', '关注+转发'];
|
||||
@ -52,7 +52,7 @@ class Dynamic
|
||||
$description = $card['item']['description'];
|
||||
} elseif (array_key_exists("content", $card['item'])) {
|
||||
// 子动态
|
||||
// TODO 暂时跳过 需要合适的处理方法
|
||||
// Todo 暂时跳过 需要合适的处理方法
|
||||
// description = $card['item']['content'];
|
||||
continue;
|
||||
} else {
|
||||
|
||||
@ -71,7 +71,7 @@ class GroupSignIn
|
||||
$de_raw = json_decode($raw, true);
|
||||
|
||||
if ($de_raw['code'] != '0') {
|
||||
// TODO 任务失败原因
|
||||
// Todo 任务失败原因
|
||||
// {"code": 710001, "msg": "应援失败>_<", "message": "应援失败>_<", "ttl": "1", "data": {"add_num": 0, "status": 0}}
|
||||
if ($de_raw['code'] == '710001') {
|
||||
Log::warning('在应援团{' . $groupInfo['group_name'] . '}中签到失败, 亲密度已达上限');
|
||||
|
||||
@ -43,7 +43,7 @@ class Judge
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 判案 TODO: 处理案例已满(MAX20例)
|
||||
* @use 判案 Todo: 处理案例已满(MAX20例)
|
||||
* @param $case_id
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
@ -29,7 +29,7 @@ class Login
|
||||
return;
|
||||
}
|
||||
Log::info('启动登录程序');
|
||||
if (getConf('access_token', 'login.auth') == '') {
|
||||
if (getAccessToken() == '') {
|
||||
Log::info('准备载入登录令牌');
|
||||
self::login();
|
||||
}
|
||||
@ -117,7 +117,7 @@ class Login
|
||||
{
|
||||
$url = 'https://passport.bilibili.com/api/v2/oauth2/info';
|
||||
$payload = [
|
||||
'access_token' => getConf('access_token', 'login.auth'),
|
||||
'access_token' => getAccessToken(),
|
||||
];
|
||||
$data = Curl::get('app', $url, Sign::common($payload));
|
||||
// {"ts":1234,"code":0,"data":{"mid":1234,"access_token":"1234","expires_in":7759292}}
|
||||
@ -137,8 +137,8 @@ class Login
|
||||
{
|
||||
$url = 'https://passport.bilibili.com/api/v2/oauth2/refresh_token';
|
||||
$payload = [
|
||||
'access_token' => getConf('access_token', 'login.auth'),
|
||||
'refresh_token' => getConf('refresh_token', 'login.auth'),
|
||||
'access_token' => getAccessToken(),
|
||||
'refresh_token' => getRefreshToken(),
|
||||
];
|
||||
$raw = Curl::post('app', $url, Sign::common($payload));
|
||||
$de_raw = json_decode($raw, true);
|
||||
@ -313,7 +313,7 @@ class Login
|
||||
$payload = [
|
||||
'cid' => getConf('country_code', 'login.country') ,
|
||||
'tel' => $phone,
|
||||
'statistics' => '{"appId":1,"platform":3,"version":"6.31.0","abtest":""}',
|
||||
'statistics' => '{"appId":1,"platform":3,"version":"6.32.0","abtest":""}',
|
||||
];
|
||||
$raw = Curl::post('app', $url, Sign::login($payload));
|
||||
$de_raw = json_decode($raw, true);
|
||||
|
||||
@ -40,7 +40,7 @@ class ManGa
|
||||
sleep(1);
|
||||
$url = 'https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn';
|
||||
$payload = [
|
||||
'access_key' => getConf('access_token', 'login.auth'),
|
||||
'access_key' => getAccessToken(),
|
||||
'ts' => time()
|
||||
];
|
||||
$raw = Curl::post('app', $url, Sign::common($payload));
|
||||
|
||||
@ -194,7 +194,7 @@ class MaterialObject
|
||||
*/
|
||||
private static function calcAid($min, $max): bool
|
||||
{
|
||||
// TODO 优化计算AID算法
|
||||
// Todo 优化计算AID算法
|
||||
if (self::$end_aid != 0 && self::$start_aid != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ class Schedule
|
||||
{
|
||||
use TimeLock;
|
||||
|
||||
// TODO 黑白名单|考虑添加到每个插件内部自动添加|优化RUN逻辑代码
|
||||
// Todo 黑白名单|考虑添加到每个插件内部自动添加|优化RUN逻辑代码
|
||||
private static $unlock_hour = 24;
|
||||
private static $unlock_timers = [];
|
||||
private static $sleep_section = [];
|
||||
|
||||
@ -27,7 +27,7 @@ class Sign
|
||||
// $appsecret = '59b43e04ad6965f34319062b478f83dd';
|
||||
//
|
||||
// $default = [
|
||||
// 'access_key' => getConf('access_token', 'login.auth')
|
||||
// 'access_key' => getAccessToken()
|
||||
// 'actionKey' => 'appkey',
|
||||
// 'appkey' => $appkey,
|
||||
// 'build' => 101800,
|
||||
@ -52,10 +52,10 @@ class Sign
|
||||
$appsecret = '60698ba2f68e01ce44738920a0ffe768';
|
||||
|
||||
$default = [
|
||||
'access_key' => getConf('access_token', 'login.auth'),
|
||||
'access_key' => getAccessToken(),
|
||||
'actionKey' => 'appkey',
|
||||
'appkey' => $appkey,
|
||||
'build' => 6310200,
|
||||
'build' => 6320200,
|
||||
'channel' => 'bili',
|
||||
'device' => 'phone',
|
||||
'mobi_app' => 'android',
|
||||
@ -81,10 +81,10 @@ class Sign
|
||||
$appsecret = '560c52ccd288fed045859ed18bffd973';
|
||||
|
||||
$default = [
|
||||
'access_key' => getConf('access_token', 'login.auth'),
|
||||
'access_key' => getAccessToken(),
|
||||
'actionKey' => 'appkey',
|
||||
'appkey' => $appkey,
|
||||
'build' => 6310200,
|
||||
'build' => 6320200,
|
||||
'device' => 'phone',
|
||||
'mobi_app' => 'android',
|
||||
'platform' => 'android',
|
||||
|
||||
@ -23,7 +23,7 @@ class Statistics
|
||||
private static $success_list = [];
|
||||
private static $profit_list = [];
|
||||
|
||||
// TODO 统计开关 统计时间间隔 统计类型
|
||||
// Todo 统计开关 统计时间间隔 统计类型
|
||||
public static function run()
|
||||
{
|
||||
if (self::getLock() > time()) {
|
||||
|
||||
@ -499,7 +499,7 @@ class ZoneTcpClient
|
||||
break;
|
||||
Log::debug("Socket debug: select timeout" . PHP_EOL);
|
||||
}
|
||||
// TODO unable to read from socket[104]: Connection reset by peer
|
||||
// Todo unable to read from socket[104]: Connection reset by peer
|
||||
$ret = socket_recv($socket, $buffer, $length, 0);
|
||||
if ($ret < 1) {
|
||||
Log::warning("Socket error: [{$ret}] [{$length}]" . PHP_EOL);
|
||||
|
||||
63
src/script/BaseTask.php
Normal file
63
src/script/BaseTask.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Website: https://mudew.com/
|
||||
* Author: Lkeme
|
||||
* License: The MIT License
|
||||
* Updated: 2021 ~ 2022
|
||||
*/
|
||||
|
||||
namespace BiliHelper\Script;
|
||||
|
||||
use Ahc\Cli\IO\Interactor;
|
||||
|
||||
class BaseTask
|
||||
{
|
||||
public static $interactor = null;
|
||||
|
||||
public static function init()
|
||||
{
|
||||
User::login();
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 选择
|
||||
* @param array $options
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public static function choice(array $options, $default = null)
|
||||
{
|
||||
$option = static::interactor()->choice('Select', $options, $default, true);
|
||||
static::interactor()->greenBold("You selected: {$options[$option]}", true);
|
||||
// return $options[$option];
|
||||
return $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 确认
|
||||
* @param string $msg
|
||||
* @param string $default
|
||||
* @return bool
|
||||
*/
|
||||
public static function confirm(string $msg, string $default = 'n'): bool
|
||||
{
|
||||
$confirm = static::interactor()->confirm($msg, $default); // Default: n (no)
|
||||
if (!$confirm) die();
|
||||
// if ($confirm) { // is a boolean
|
||||
// static::interactor()->greenBold('是 :)', true); // Output green bold text
|
||||
// } else {
|
||||
// static::interactor()->redBold('否 :(', true); // Output red bold text
|
||||
// die();
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Ahc\Cli\IO\Interactor
|
||||
*/
|
||||
public static function interactor(): Interactor
|
||||
{
|
||||
return static::$interactor ?? static::$interactor = new Interactor;
|
||||
}
|
||||
}
|
||||
22
src/script/DelDynamic.php
Normal file
22
src/script/DelDynamic.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Website: https://mudew.com/
|
||||
* Author: Lkeme
|
||||
* License: The MIT License
|
||||
* Updated: 2021 ~ 2022
|
||||
*/
|
||||
|
||||
namespace BiliHelper\Script;
|
||||
|
||||
use BiliHelper\Core\Log;
|
||||
use BiliHelper\Core\Curl;
|
||||
|
||||
class DelDynamic extends BaseTask
|
||||
{
|
||||
public static $description = '批量删除动态,默认单次最大清理300个动态.';
|
||||
|
||||
public static function run(){
|
||||
Log::error('当前功能未完成');
|
||||
}
|
||||
}
|
||||
146
src/script/UnFollow.php
Normal file
146
src/script/UnFollow.php
Normal file
@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Website: https://mudew.com/
|
||||
* Author: Lkeme
|
||||
* License: The MIT License
|
||||
* Updated: 2021 ~ 2022
|
||||
*/
|
||||
|
||||
namespace BiliHelper\Script;
|
||||
|
||||
use BiliHelper\Core\Log;
|
||||
use BiliHelper\Core\Curl;
|
||||
|
||||
class UnFollow extends BaseTask
|
||||
{
|
||||
public static $description = '批量清理选定分组关注,默认单次最大清理300个关注.';
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
// 获取关注分组
|
||||
$tag_id = self::relationTags();
|
||||
// 获取分组关注
|
||||
$target_ups = self::relationTag($tag_id);
|
||||
// 取消关注状态
|
||||
self::relationModify($target_ups, $tag_id);
|
||||
// Todo 优化
|
||||
Log::notice('任务执行完毕~');
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 取消关注
|
||||
* @param $target_ups
|
||||
* @param $tag_id
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function relationModify($target_ups, $tag_id)
|
||||
{
|
||||
self::confirm('请确认以上输入信息,是否继续取关操作?');
|
||||
|
||||
$url = 'https://api.bilibili.com/x/relation/modify';
|
||||
|
||||
foreach ($target_ups as $up_uid => $up_uname) {
|
||||
$payload = [
|
||||
'fid' => $up_uid,
|
||||
'act' => 2,
|
||||
're_src' => 11,
|
||||
'csrf' => getCsrf(),
|
||||
];
|
||||
$headers = [
|
||||
'origin' => 'https://space.bilibili.com',
|
||||
'referer' => 'https://space.bilibili.com/' . getUid() . '/fans/follow?tagid=' . $tag_id,
|
||||
];
|
||||
$raw = Curl::post('pc', $url, $payload, $headers);
|
||||
// {"code":0,"message":"0","ttl":1}
|
||||
$data = json_decode($raw, true);
|
||||
if ($data['code'] == 0) {
|
||||
Log::notice("UP.{$up_uid} - {$up_uname} 取关成功");
|
||||
} else {
|
||||
Log::error("UP.{$up_uid} - {$up_uname} 取关失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
|
||||
break;
|
||||
}
|
||||
sleep(random_int(5, 10));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @use 获取分组关注
|
||||
* @param $tag_id
|
||||
* @param int $max_pn
|
||||
* @param int $max_ps
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function relationTag($tag_id, int $max_pn = 30, int $max_ps = 20): array
|
||||
{
|
||||
$following = [];
|
||||
$url = 'https://api.bilibili.com/x/relation/tag';
|
||||
for ($pn = 1; $pn <= $max_pn; $pn++) {
|
||||
$payload = [
|
||||
'mid' => getUid(),
|
||||
'tagid' => $tag_id,
|
||||
'pn' => $pn,
|
||||
'ps' => $max_ps,
|
||||
];
|
||||
$headers = [
|
||||
'referer' => 'https://space.bilibili.com/' . getUid() . '/fans/follow',
|
||||
];
|
||||
$raw = Curl::get('pc', $url, $payload, $headers);
|
||||
$data = json_decode($raw, true);
|
||||
if ($data['code'] == 0 && isset($data['data'])) {
|
||||
// 循环添加到 following
|
||||
foreach ($data['data'] as $up) {
|
||||
$following[$up['mid']] = $up['uname'];
|
||||
}
|
||||
// 打印和延迟
|
||||
Log::info("已获取分组 {$tag_id} 页码 {$pn}");
|
||||
sleep(random_int(4, 8));
|
||||
// 如果页面不等于 max_ps 跳出
|
||||
if (count($data['data']) != $max_ps) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
Log::error("获取分组关注失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
$following_num = count($following);
|
||||
Log::notice("已获取分组 {$tag_id} 有效关注数 {$following_num}");
|
||||
return $following;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @use 获取分组
|
||||
* @return mixed
|
||||
*/
|
||||
private static function relationTags()
|
||||
{
|
||||
$url = 'https://api.bilibili.com/x/relation/tags';
|
||||
$payload = [];
|
||||
$headers = [
|
||||
'referer' => 'https://space.bilibili.com/',
|
||||
];
|
||||
$raw = Curl::get('pc', $url, $payload, $headers);
|
||||
$data = json_decode($raw, true);
|
||||
if ($data['code'] == 0 && isset($data['data'])) {
|
||||
$options = [];
|
||||
foreach ($data['data'] as $tag) {
|
||||
$options[$tag['tagid']] = "分组:{$tag['name']} - 关注数:{$tag['count']}";
|
||||
}
|
||||
$option = self::choice($options);
|
||||
Log::notice("已获取分组 {$option} - {$options[$option]}");
|
||||
return $option;
|
||||
} else {
|
||||
Log::error("获取关注分组失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
57
src/script/User.php
Normal file
57
src/script/User.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Website: https://mudew.com/
|
||||
* Author: Lkeme
|
||||
* License: The MIT License
|
||||
* Updated: 2021 ~ 2022
|
||||
*/
|
||||
|
||||
namespace BiliHelper\Script;
|
||||
|
||||
use BiliHelper\Core\Log;
|
||||
use BiliHelper\Core\Curl;
|
||||
|
||||
class User
|
||||
{
|
||||
|
||||
/**
|
||||
* @use 登录
|
||||
* @return bool
|
||||
*/
|
||||
public static function login(): bool
|
||||
{
|
||||
if (getAccessToken() == '' || getCookie() == '' || getUid() == '' || getCsrf() == '') {
|
||||
Log::error('用户信息不全,请默认模式登录后使用。');
|
||||
die();
|
||||
}
|
||||
$data = User::userInfo();
|
||||
if ($data['code'] == 0 && $data['data']['isLogin']) {
|
||||
$nav = $data['data'];
|
||||
$level = $nav['level_info'];
|
||||
Log::notice("登录成功 Uname={$nav['uname']} Uid={$nav['mid']} Lv={$level['current_level']} ({$level['current_exp']}/{$level['current_min']})");
|
||||
} else {
|
||||
Log::error("登录失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
|
||||
die();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @use 用户
|
||||
* @return mixed
|
||||
*/
|
||||
public static function userInfo()
|
||||
{
|
||||
$url = 'https://api.bilibili.com/x/web-interface/nav';
|
||||
$payload = [];
|
||||
$headers = [
|
||||
'origin' => 'https://space.bilibili.com',
|
||||
'referer' => 'https://space.bilibili.com/' . getUid(),
|
||||
];
|
||||
$raw = Curl::get('pc', $url, $payload, $headers);
|
||||
return json_decode($raw, true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
401
src/tool/UserAgent.php
Normal file
401
src/tool/UserAgent.php
Normal file
@ -0,0 +1,401 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Website: https://mudew.com/
|
||||
* Author: Lkeme
|
||||
* License: The MIT License
|
||||
* Email: Useri@live.cn
|
||||
* Updated: 2021 ~ 2022
|
||||
* Source: https://github.com/Deemon47/user-agent-generator/
|
||||
*/
|
||||
|
||||
namespace BiliHelper\Tool;
|
||||
|
||||
|
||||
/** **********************************************************************************
|
||||
* 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
|
||||
* as well as browsers Firefox, Chrome, and Internet Explorer.
|
||||
*/
|
||||
class UserAgent
|
||||
{
|
||||
/**
|
||||
* Windows Operating System list with dynamic versioning
|
||||
* @var array $windows_os
|
||||
*/
|
||||
public $windows_os = [
|
||||
'[Windows; |Windows; U; |]Windows NT 6.:number0-3:;[ Win64; x64| WOW64| x64|]',
|
||||
'[Windows; |Windows; U; |]Windows NT 10.:number0-5:;[ Win64; x64| WOW64| x64|]'
|
||||
];
|
||||
/**
|
||||
* Linux Operating Systems [limited]
|
||||
* @var array $linux_os
|
||||
*/
|
||||
public $linux_os = [
|
||||
'[Linux; |][U; |]Linux x86_64',
|
||||
'[Linux; |][U; |]Linux i:number5-6::number4-8::number0-6: [x86_64|]'
|
||||
];
|
||||
/**
|
||||
* Mac Operating System (OS X) with dynamic versioning
|
||||
* @var array $mac_os
|
||||
*/
|
||||
public $mac_os = [
|
||||
'Macintosh; [U; |]Intel Mac OS X :number7-9:_:number0-9:_:number0-9:',
|
||||
'Macintosh; [U; |]Intel Mac OS X 10_:number0-12:_:number0-9:'
|
||||
];
|
||||
/**
|
||||
* Versions of Android to be used
|
||||
* @var array $androidVersions
|
||||
*/
|
||||
public $androidVersions = [
|
||||
'4.3.1',
|
||||
'4.4',
|
||||
'4.4.1',
|
||||
'4.4.4',
|
||||
'5.0',
|
||||
'5.0.1',
|
||||
'5.0.2',
|
||||
'5.1',
|
||||
'5.1.1',
|
||||
'6.0',
|
||||
'6.0.1',
|
||||
'7.0',
|
||||
'7.1',
|
||||
'7.1.1'
|
||||
];
|
||||
/**
|
||||
* Holds the version of android for the User Agent being generated
|
||||
* @property string $androidVersion
|
||||
*/
|
||||
public $androidVersion;
|
||||
/**
|
||||
* Android devices and for specific android versions
|
||||
* @var array $androidDevices
|
||||
*/
|
||||
public $androidDevices = [
|
||||
'4.3' => [
|
||||
'GT-I9:number2-5:00 Build/JDQ39',
|
||||
'Nokia 3:number1-3:[10|15] Build/IMM76D',
|
||||
'[SAMSUNG |]SM-G3:number1-5:0[R5|I|V|A|T|S] Build/JLS36C',
|
||||
'Ascend G3:number0-3:0 Build/JLS36I',
|
||||
'[SAMSUNG |]SM-G3:number3-6::number1-8::number0-9:[V|A|T|S|I|R5] Build/JLS36C',
|
||||
'HUAWEI G6-L:number10-11: Build/HuaweiG6-L:number10-11:',
|
||||
'[SAMSUNG |]SM-[G|N]:number7-9:1:number0-8:[S|A|V|T] Build/[JLS36C|JSS15J]',
|
||||
'[SAMSUNG |]SGH-N0:number6-9:5[T|V|A|S] Build/JSS15J',
|
||||
'Samsung Galaxy S[4|IV] Mega GT-I:number89-95:00 Build/JDQ39',
|
||||
'SAMSUNG SM-T:number24-28:5[s|a|t|v] Build/[JLS36C|JSS15J]',
|
||||
'HP :number63-73:5 Notebook PC Build/[JLS36C|JSS15J]',
|
||||
'HP Compaq 2:number1-3:10b Build/[JLS36C|JSS15J]',
|
||||
'HTC One 801[s|e] Build/[JLS36C|JSS15J]',
|
||||
'HTC One max Build/[JLS36C|JSS15J]',
|
||||
'HTC Xplorer A:number28-34:0[e|s] Build/GRJ90'
|
||||
],
|
||||
'4.4' => [
|
||||
'XT10:number5-8:0 Build/SU6-7.3',
|
||||
'XT10:number12-52: Build/[KXB20.9|KXC21.5]',
|
||||
'Nokia :number30-34:10 Build/IMM76D',
|
||||
'E:number:20-23::number0-3::number0-4: Build/24.0.[A|B].1.34',
|
||||
'[SAMSUNG |]SM-E500[F|L] Build/KTU84P',
|
||||
'LG Optimus G Build/KRT16M',
|
||||
'LG-E98:number7-9: Build/KOT49I',
|
||||
'Elephone P:number2-6:000 Build/KTU84P',
|
||||
'IQ450:number0-4: Quad Build/KOT49H',
|
||||
'LG-F:number2-5:00[K|S|L] Build/KOT49[I|H]',
|
||||
'LG-V:number3-7::number0-1:0 Build/KOT49I',
|
||||
'[SAMSUNG |]SM-J:number1-2::number0-1:0[G|F] Build/KTU84P',
|
||||
'[SAMSUNG |]SM-N80:number0-1:0 Build/[KVT49L|JZO54K]',
|
||||
'[SAMSUNG |]SM-N900:number5-8: Build/KOT49H',
|
||||
'[SAMSUNG-|]SGH-I337[|M] Build/[JSS15J|KOT49H]',
|
||||
'[SAMSUNG |]SM-G900[W8|9D|FD|H|V|FG|A|T] Build/KOT49H',
|
||||
'[SAMSUNG |]SM-T5:number30-35: Build/[KOT49H|KTU84P]',
|
||||
'[Google |]Nexus :number5-7: Build/KOT49H',
|
||||
'LG-H2:number0-2:0 Build/KOT49[I|H]',
|
||||
'HTC One[_M8|_M9|0P6B|801e|809d|0P8B2|mini 2|S][ dual sim|] Build/[KOT49H|KTU84L]',
|
||||
'[SAMSUNG |]GT-I9:number3-5:0:number0-6:[V|I|T|N] Build/KOT49H',
|
||||
'Lenovo P7:number7-8::number1-6: Build/[Lenovo|JRO03C]',
|
||||
'LG-D95:number1-8: Build/KOT49[I|H]',
|
||||
'LG-D:number1-8::number0-8:0 Build/KOT49[I|H]',
|
||||
'Nexus5 V:number6-7:.1 Build/KOT49H',
|
||||
'Nexus[_|] :number4-10: Build/[KOT49H|KTU84P]',
|
||||
'Nexus[_S_| S ][4G |]Build/GRJ22',
|
||||
'[HM NOTE|NOTE-III|NOTE2 1LTE[TD|W|T]',
|
||||
'ALCATEL ONE[| ]TOUCH 70:number2-4::number0-9:[X|D|E|A] Build/KOT49H',
|
||||
'MOTOROLA [MOTOG|MSM8960|RAZR] Build/KVT49L'
|
||||
],
|
||||
'5.0' => [
|
||||
'Nokia :number10-11:00 [wifi|4G|LTE] Build/GRK39F',
|
||||
'HTC 80:number1-2[s|w|e|t] Build/[LRX22G|JSS15J]',
|
||||
'Lenovo A7000-a Build/LRX21M;',
|
||||
'HTC Butterfly S [901|919][s|d|] Build/LRX22G',
|
||||
'HTC [M8|M9|M8 Pro Build/LRX22G',
|
||||
'LG-D3:number25-37: Build/LRX22G',
|
||||
'LG-D72:number0-9: Build/LRX22G',
|
||||
'[SAMSUNG |]SM-G4:number0-9:0 Build/LRX22[G|C]',
|
||||
'[|SAMSUNG ]SM-G9[00|25|20][FD|8|F|F-ORANGE|FG|FQ|H|I|L|M|S|T] Build/[LRX21T|KTU84F|KOT49H]',
|
||||
'[SAMSUNG |]SM-A:number7-8:00[F|I|T|H|] Build/[LRX22G|LMY47X]',
|
||||
'[SAMSUNG-|]SM-N91[0|5][A|V|F|G|FY] Build/LRX22C',
|
||||
'[SAMSUNG |]SM-[T|P][350|550|555|355|805|800|710|810|815] Build/LRX22G',
|
||||
'LG-D7:number0-2::number0-9: Build/LRX22G',
|
||||
'[LG|SM]-[D|G]:number8-9::number0-5::number0-9:[|P|K|T|I|F|T1] Build/[LRX22G|KOT49I|KVT49L|LMY47X]'
|
||||
],
|
||||
'5.1' => [
|
||||
'Nexus :number5-9: Build/[LMY48B|LRX22C]',
|
||||
'[|SAMSUNG ]SM-G9[28|25|20][X|FD|8|F|F-ORANGE|FG|FQ|H|I|L|M|S|T] Build/[LRX22G|LMY47X]',
|
||||
'[|SAMSUNG ]SM-G9[35|350][X|FD|8|F|F-ORANGE|FG|FQ|H|I|L|M|S|T] Build/[MMB29M|LMY47X]',
|
||||
'[MOTOROLA |][MOTO G|MOTO G XT1068|XT1021|MOTO E XT1021|MOTO XT1580|MOTO X FORCE XT1580|MOTO X PLAY XT1562|MOTO XT1562|MOTO XT1575|MOTO X PURE XT1575|MOTO XT1570 MOTO X STYLE] Build/[LXB22|LMY47Z|LPC23|LPK23|LPD23|LPH223]'
|
||||
],
|
||||
'6.0' => [
|
||||
'[SAMSUNG |]SM-[G|D][920|925|928|9350][V|F|I|L|M|S|8|I] Build/[MMB29K|MMB29V|MDB08I|MDB08L]',
|
||||
'Nexus :number5-7:[P|X|] Build/[MMB29K|MMB29V|MDB08I|MDB08L]',
|
||||
'HTC One[_| ][M9|M8|M8 Pro] Build/MRA58K',
|
||||
'HTC One[_M8|_M9|0P6B|801e|809d|0P8B2|mini 2|S][ dual sim|] Build/MRA58K'
|
||||
],
|
||||
'7.0' => [
|
||||
'Pixel [XL|C] Build/[NRD90M|NME91E]',
|
||||
'Nexus :number5-9:[X|P|] Build/[NPD90G|NME91E]',
|
||||
'[SAMSUNG |]GT-I:number91-98:00 Build/KTU84P',
|
||||
'Xperia [V |]Build/NDE63X',
|
||||
'LG-H:number90-93:0 Build/NRD90[C|M]'
|
||||
],
|
||||
'7.1' => [
|
||||
'Pixel [XL|C] Build/[NRD90M|NME91E]',
|
||||
'Nexus :number5-9:[X|P|] Build/[NPD90G|NME91E]',
|
||||
'[SAMSUNG |]GT-I:number91-98:00 Build/KTU84P',
|
||||
'Xperia [V |]Build/NDE63X',
|
||||
'LG-H:number90-93:0 Build/NRD90[C|M]'
|
||||
]
|
||||
];
|
||||
public $locale = 'en-US';
|
||||
/**
|
||||
* List of "OS" strings used for android
|
||||
* @var array $android_os
|
||||
*/
|
||||
public $android_os = [
|
||||
'Linux; Android :androidVersion:; :androidDevice:',
|
||||
//Todo: Add a $windowsDevices variable that does the same as androidDevice
|
||||
//'Windows Phone 10.0; Android :androidVersion:; :windowsDevice:',
|
||||
'Linux; U; Android :androidVersion:; :androidDevice:',
|
||||
'Android; Android :androidVersion:; :androidDevice:'
|
||||
];
|
||||
/**
|
||||
* List of "OS" strings used for iOS
|
||||
* @var array $mobile_ios
|
||||
*/
|
||||
public $mobile_ios = [
|
||||
'iphone' => 'iPhone; CPU iPhone OS :number7-11:_:number0-9:_:number0-9:; like Mac OS X;',
|
||||
'ipad' => 'iPad; CPU iPad OS :number7-11:_:number0-9:_:number0-9: like Mac OS X;',
|
||||
'ipod' => 'iPod; CPU iPod OS :number7-11:_:number0-9:_:number0-9:; like Mac OS X;'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get a random operating system
|
||||
* @param string|null $os
|
||||
* @return string *
|
||||
*/
|
||||
public function getOS(string $os = NULL)
|
||||
{
|
||||
$_os = [];
|
||||
if ($os === NULL || in_array($os, ['chrome', 'firefox', 'explorer'])) {
|
||||
$_os = $os === 'explorer' ? $this->windows_os : array_merge($this->windows_os, $this->linux_os, $this->mac_os);
|
||||
} else {
|
||||
$_os += $this->{$os . '_os'};
|
||||
}
|
||||
// randomly select on operating system
|
||||
$selected_os = rtrim($_os[random_int(0, count($_os) - 1)], ';');
|
||||
|
||||
// check for spin syntax
|
||||
if (strpos($selected_os, '[') !== FALSE) {
|
||||
$selected_os = self::processSpinSyntax($selected_os);
|
||||
}
|
||||
|
||||
// check for random number syntax
|
||||
if (strpos($selected_os, ':number') !== FALSE) {
|
||||
$selected_os = self::processRandomNumbers($selected_os);
|
||||
}
|
||||
|
||||
if (random_int(1, 100) > 50) {
|
||||
$selected_os .= '; ' . $this->locale;
|
||||
}
|
||||
return $selected_os;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Mobile OS
|
||||
* @param string|null $os Can specifiy android, iphone, ipad, ipod, or null/blank for random
|
||||
* @return string *
|
||||
*/
|
||||
public function getMobileOS(string $os = NULL)
|
||||
{
|
||||
$os = strtolower($os);
|
||||
$_os = [];
|
||||
switch ($os) {
|
||||
case'android':
|
||||
$_os += $this->android_os;
|
||||
break;
|
||||
case 'iphone':
|
||||
case 'ipad':
|
||||
case 'ipod':
|
||||
$_os[] = $this->mobile_ios[$os];
|
||||
break;
|
||||
default:
|
||||
$_os = array_merge($this->android_os, array_values($this->mobile_ios));
|
||||
}
|
||||
// select random mobile os
|
||||
$selected_os = rtrim($_os[random_int(0, count($_os) - 1)], ';');
|
||||
if (strpos($selected_os, ':androidVersion:') !== FALSE) {
|
||||
$selected_os = $this->processAndroidVersion($selected_os);
|
||||
}
|
||||
if (strpos($selected_os, ':androidDevice:') !== FALSE) {
|
||||
$selected_os = $this->addAndroidDevice($selected_os);
|
||||
}
|
||||
if (strpos($selected_os, ':number') !== FALSE) {
|
||||
$selected_os = self::processRandomNumbers($selected_os);
|
||||
}
|
||||
return $selected_os;
|
||||
}
|
||||
|
||||
/**
|
||||
* static::processRandomNumbers
|
||||
* @param $selected_os
|
||||
* @return null|string|string[] *
|
||||
*/
|
||||
public static function processRandomNumbers($selected_os)
|
||||
{
|
||||
return preg_replace_callback('/:number(\d+)-(\d+):/i', function ($matches) {
|
||||
return random_int($matches[1], $matches[2]);
|
||||
}, $selected_os);
|
||||
}
|
||||
|
||||
/**
|
||||
* static::processSpinSyntax
|
||||
* @param $selected_os
|
||||
* @return null|string|string[] *
|
||||
*/
|
||||
public static function processSpinSyntax($selected_os)
|
||||
{
|
||||
return preg_replace_callback('/\[([\w\-\s|;]*?)\]/i', function ($matches) {
|
||||
$shuffle = explode('|', $matches[1]);
|
||||
return $shuffle[array_rand($shuffle)];
|
||||
}, $selected_os);
|
||||
}
|
||||
|
||||
/**
|
||||
* processAndroidVersion
|
||||
* @param $selected_os
|
||||
* @return null|string|string[] *
|
||||
*/
|
||||
public function processAndroidVersion($selected_os)
|
||||
{
|
||||
$this->androidVersion = $version = $this->androidVersions[array_rand($this->androidVersions)];
|
||||
return preg_replace_callback('/:androidVersion:/i', function ($matches) use ($version) {
|
||||
return $version;
|
||||
}, $selected_os);
|
||||
}
|
||||
|
||||
/**
|
||||
* addAndroidDevice
|
||||
* @param $selected_os
|
||||
* @return null|string|string[] *
|
||||
*/
|
||||
public function addAndroidDevice($selected_os)
|
||||
{
|
||||
$devices = $this->androidDevices[substr($this->androidVersion, 0, 3)];
|
||||
$device = $devices[array_rand($devices)];
|
||||
|
||||
$device = self::processSpinSyntax($device);
|
||||
return preg_replace_callback('/:androidDevice:/i', function ($matches) use ($device) {
|
||||
return $device;
|
||||
}, $selected_os);
|
||||
}
|
||||
|
||||
/**
|
||||
* static::chromeVersion
|
||||
* @param $version
|
||||
* @return string *
|
||||
*/
|
||||
public static function chromeVersion($version): string
|
||||
{
|
||||
return random_int($version['min'], $version['max']) . '.0.' . random_int(1000, 4000)
|
||||
. '.' . random_int(100, 400);
|
||||
}
|
||||
|
||||
/**
|
||||
* static::firefoxVersion
|
||||
* @param $version
|
||||
* @return string *
|
||||
*/
|
||||
public static function firefoxVersion($version): string
|
||||
{
|
||||
return random_int($version['min'], $version['max']) . '.' . random_int(0, 9);
|
||||
}
|
||||
|
||||
/**
|
||||
* static::windows
|
||||
* @param $version
|
||||
* @return string *
|
||||
*/
|
||||
public static function windows($version): string
|
||||
{
|
||||
return random_int($version['min'], $version['max']) . '.' . random_int(0, 9);
|
||||
}
|
||||
|
||||
/**
|
||||
* generate
|
||||
* @param null $userAgent
|
||||
* @return string *
|
||||
*/
|
||||
public function generate($userAgent = NULL, $locale = null): string
|
||||
{
|
||||
|
||||
if (!is_null($locale))
|
||||
$this->locale = $locale;
|
||||
|
||||
if ($userAgent === NULL) {
|
||||
$r = random_int(0, 100);
|
||||
if ($r >= 44) {
|
||||
$userAgent = array_rand(['firefox' => 1, 'chrome' => 1, 'explorer' => 1]);
|
||||
} else {
|
||||
$userAgent = array_rand(['iphone' => 1, 'android' => 1, 'mobile' => 1]);
|
||||
}
|
||||
} elseif ($userAgent == 'windows' || $userAgent == 'mac' || $userAgent == 'linux') {
|
||||
$agents = ['firefox' => 1, 'chrome' => 1];
|
||||
if ($userAgent == 'windows') {
|
||||
$agents['explorer'] = 1;
|
||||
}
|
||||
$userAgent = array_rand($agents);
|
||||
}
|
||||
$_SESSION['agent'] = $userAgent;
|
||||
if ($userAgent == 'chrome') {
|
||||
return 'Mozilla/5.0 (' . $this->getOS($userAgent) . ') AppleWebKit/' .
|
||||
(random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603))
|
||||
. '.' . random_int(1, 50) . ' (KHTML, like Gecko) Chrome/' .
|
||||
self::chromeVersion(['min' => 47, 'max' => 55]) . ' Safari/'
|
||||
. (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603));
|
||||
} elseif ($userAgent == 'firefox') {
|
||||
|
||||
return 'Mozilla/5.0 (' . $this->getOS($userAgent) . ') Gecko/'
|
||||
. (random_int(1, 100) > 30 ? '20100101' : '20130401') . ' Firefox/'
|
||||
. self::firefoxVersion(['min' => 45, 'max' => 74]);
|
||||
} elseif ($userAgent == 'explorer') {
|
||||
|
||||
return 'Mozilla / 5.0 (compatible; MSIE ' . ($int = random_int(7, 11))
|
||||
. '.0; ' . $this->getOS('windows') . ' Trident / '
|
||||
. ($int == 7 || $int == 8 ? '4' : ($int == 9 ? '5' : ($int == 10 ? '6' : '7')))
|
||||
. '.0)';
|
||||
} elseif ($userAgent == 'mobile'
|
||||
|| $userAgent == 'android'
|
||||
|| $userAgent == 'iphone'
|
||||
|| $userAgent == 'ipad'
|
||||
|| $userAgent == 'ipod') {
|
||||
|
||||
return 'Mozilla/5.0 (' . $this->getMobileOS($userAgent) . ') AppleWebKit/'
|
||||
. (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603))
|
||||
. '.' . random_int(1, 50) . ' (KHTML, like Gecko) Chrome/'
|
||||
. self::chromeVersion(['min' => 47, 'max' => 55]) . ' Mobile Safari/'
|
||||
. (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603))
|
||||
. '.' . random_int(0, 9);
|
||||
} else {
|
||||
new Exception('Unable to determine user agent to generate');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,7 +97,7 @@ abstract class BaseRaffle
|
||||
$raw = Curl::get('app', $url, Sign::common($payload));
|
||||
$de_raw = json_decode($raw, true);
|
||||
if (!isset($de_raw['data']) || $de_raw['code']) {
|
||||
// TODO 请求被拦截 412
|
||||
// Todo 请求被拦截 412
|
||||
Log::error("获取抽奖数据错误,{$de_raw['message']}");
|
||||
return [];
|
||||
}
|
||||
@ -133,7 +133,7 @@ abstract class BaseRaffle
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
protected static function arrKeySort($arr, $key, $type = 'asc'): array
|
||||
protected static function arrKeySort($arr, $key, string $type = 'asc'): array
|
||||
{
|
||||
switch ($type) {
|
||||
case 'desc':
|
||||
@ -153,7 +153,7 @@ abstract class BaseRaffle
|
||||
* @param bool $filter
|
||||
* @return bool
|
||||
*/
|
||||
protected static function toRepeatLid($lid, $filter = true): bool
|
||||
protected static function toRepeatLid($lid, bool $filter = true): bool
|
||||
{
|
||||
$lid = (int)$lid;
|
||||
if (in_array($lid, static::$all_list)) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user