diff --git a/.gitignore b/.gitignore
index c598a49..e72cf9c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
\ No newline at end of file
+/TODO
+/Todo
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 15080ab..aff8c0f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,33 @@
# 本项目Log
+[comment]: <> (更新历史latest
)
+
+[comment]: <> (
-
+
@@ -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)
diff --git a/composer.json b/composer.json
index 05d380a..cb19581 100644
--- a/composer.json
+++ b/composer.json
@@ -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"
diff --git a/composer.lock b/composer.lock
index 62ecc11..4ea622f 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,80 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "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": [],
diff --git a/conf/user.ini.example b/conf/user.ini.example
index eb1e4dd..f5efb82 100644
--- a/conf/user.ini.example
+++ b/conf/user.ini.example
@@ -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 =
diff --git a/data/filter_library.json b/data/filter_library.json
index 9c943ec..2279335 100644
--- a/data/filter_library.json
+++ b/data/filter_library.json
@@ -640,7 +640,8 @@
"wav使用权",
"曲谱",
"抽个寂寞",
- "儿子"
+ "儿子",
+ "送我"
],
"uid_list": [
28008897,
diff --git a/data/latest_version.json b/data/latest_version.json
index d964f18..ea47efc 100644
--- a/data/latest_version.json
+++ b/data/latest_version.json
@@ -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"
}
\ No newline at end of file
diff --git a/index.php b/index.php
index 30eb11b..dd2a4b3 100644
--- a/index.php
+++ b/index.php
@@ -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();
diff --git a/src/core/App.php b/src/core/App.php
index ecdce88..a235f9a 100644
--- a/src/core/App.php
+++ b/src/core/App.php
@@ -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();
+ }
+ }
}
diff --git a/src/core/Command.php b/src/core/Command.php
new file mode 100644
index 0000000..be5a97c
--- /dev/null
+++ b/src/core/Command.php
@@ -0,0 +1,52 @@
+argv = $argv;
+ }
+
+ /**
+ * @return \Garden\Cli\Args
+ */
+ public function run(): Args
+ {
+ $cli = new Cli();
+
+ $cli->description('BHP命令行工具.')
+ ->opt('script:s', '执行的Script模式.', false, 'bool');
+
+ try {
+ $args = $cli->parse($this->argv, true);
+ } catch (\Exception $e) {
+ die('解析命令行参数错误');
+ }
+ return $args;
+ }
+
+}
+
+
+
+
diff --git a/src/core/Curl.php b/src/core/Curl.php
index 2a7e19e..d5edcb0 100644
--- a/src/core/Curl.php
+++ b/src/core/Curl.php
@@ -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 = [
diff --git a/src/core/Helpers.php b/src/core/Helpers.php
index 886fc2b..74b12e2 100644
--- a/src/core/Helpers.php
+++ b/src/core/Helpers.php
@@ -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);
}
\ No newline at end of file
diff --git a/src/core/HttpClient.php b/src/core/HttpClient.php
new file mode 100644
index 0000000..ce6a0a6
--- /dev/null
+++ b/src/core/HttpClient.php
@@ -0,0 +1,159 @@
+ch = curl_init();
+ $this->url = $url;
+ curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false); //忽略 HTTPS 证书错误
+ $this->setUA("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36");
+ }
+
+ function __destruct()
+ {
+ //防止内存泄露
+ curl_close($this->ch);
+ }
+
+ /**
+ * @use 设置UA
+ * @param string $ua
+ * @return $this
+ */
+ public function setUA(string $ua): HttpClient
+ {
+ curl_setopt($this->ch, CURLOPT_USERAGENT, $ua); //设置 UA
+ return $this;
+ }
+
+ /**
+ * @use 添加Header
+ * @param string $header
+ * @return $this
+ */
+ public function addHeader(string $header): HttpClient
+ {
+ array_push($this->headers, $header);
+ return $this;
+ }
+
+ /**
+ * @use 添加Headers
+ * @param array $headers
+ * @return $this
+ */
+ public function addHeaders(array $headers): HttpClient
+ {
+ foreach ($headers as $key => $value) {
+ array_push($this->headers, "{$key}: {$value}");
+ }
+ return $this;
+ }
+
+ /**
+ * @use 设置Cookie
+ * @param string $cookie
+ * @return $this
+ */
+ public function setCookie(string $cookie): HttpClient
+ {
+ curl_setopt($this->ch, CURLOPT_COOKIE, $cookie);
+ return $this;
+ }
+
+ /**
+ * @use 设置 url 参数
+ */
+ public function buildQuery(array $query): HttpClient
+ {
+ $this->query = http_build_query($query);
+ return $this;
+ }
+
+ /**
+ * @use 自动将 json 文本解码
+ */
+ public function asJSON(): object
+ {
+ return json_decode($this->ret);
+ }
+
+ /**
+ * @use 获取返回结果
+ */
+ public function asString(): string
+ {
+ return $this->ret;
+ }
+
+ /**
+ * @use 构造POST表单
+ * @param array $form
+ * @return $this
+ */
+ public function buildPostForm(array $form): HttpClient
+ {
+ $this->form = http_build_query($form);
+
+ return $this;
+ }
+
+ /**
+ * @use 发送 Get 请求
+ */
+ public function get(): HttpClient
+ {
+ curl_setopt($this->ch, CURLOPT_URL, $this->url . "?" . $this->query);
+ curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中
+ curl_setopt($this->ch, CURLOPT_HEADER, $this->headers);
+ $this->ret = curl_exec($this->ch);
+ return $this;
+ }
+
+ /**
+ * @use 发送 POST 请求
+ * @param string|null $data 要 POST 的数据
+ * @return \HttpClient
+ */
+ public function post(string $data = null): HttpClient
+ {
+ curl_setopt($this->ch, CURLOPT_URL, $this->url . "?" . $this->query);
+ curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中
+ curl_setopt($this->ch, CURLOPT_POST, true); // 发送 POST 请求
+ curl_setopt($this->ch, CURLOPT_HEADER, $this->headers);
+ curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
+ $this->ret = curl_exec($this->ch);
+ return $this;
+ }
+
+
+ /**
+ * @use POST表单
+ * @param array $form
+ * @return $this
+ */
+ public function postForm(array $form): HttpClient
+ {
+ return $this->post(http_build_query($form));
+ }
+}
+
diff --git a/src/plugin/Barrage.php b/src/plugin/Barrage.php
index f4e3e11..fb777ec 100644
--- a/src/plugin/Barrage.php
+++ b/src/plugin/Barrage.php
@@ -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;
diff --git a/src/plugin/CapsuleLottery.php b/src/plugin/CapsuleLottery.php
index 1e83513..fe65cb4 100644
--- a/src/plugin/CapsuleLottery.php
+++ b/src/plugin/CapsuleLottery.php
@@ -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;
diff --git a/src/plugin/CheckUpdate.php b/src/plugin/CheckUpdate.php
index 3e684e8..53d40da 100644
--- a/src/plugin/CheckUpdate.php
+++ b/src/plugin/CheckUpdate.php
@@ -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');
diff --git a/src/plugin/DataTreating.php b/src/plugin/DataTreating.php
index 1faef3b..20732e1 100644
--- a/src/plugin/DataTreating.php
+++ b/src/plugin/DataTreating.php
@@ -12,7 +12,7 @@ namespace BiliHelper\Plugin;
class DataTreating
{
- // TODO 独立分发 Push||Pull数据
+ // Todo 独立分发 Push||Pull数据
/**
* @use 抽奖分发
* @param array $data
diff --git a/src/plugin/Dynamic.php b/src/plugin/Dynamic.php
index 114dea5..fefa5e5 100644
--- a/src/plugin/Dynamic.php
+++ b/src/plugin/Dynamic.php
@@ -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 {
diff --git a/src/plugin/GroupSignIn.php b/src/plugin/GroupSignIn.php
index 91f9408..65d809a 100644
--- a/src/plugin/GroupSignIn.php
+++ b/src/plugin/GroupSignIn.php
@@ -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'] . '}中签到失败, 亲密度已达上限');
diff --git a/src/plugin/Judge.php b/src/plugin/Judge.php
index babafda..f6c8a9e 100644
--- a/src/plugin/Judge.php
+++ b/src/plugin/Judge.php
@@ -43,7 +43,7 @@ class Judge
}
/**
- * @use 判案 TODO: 处理案例已满(MAX20例)
+ * @use 判案 Todo: 处理案例已满(MAX20例)
* @param $case_id
* @return bool
*/
diff --git a/src/plugin/Login.php b/src/plugin/Login.php
index 7f52d03..53c9b51 100644
--- a/src/plugin/Login.php
+++ b/src/plugin/Login.php
@@ -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);
diff --git a/src/plugin/ManGa.php b/src/plugin/ManGa.php
index da9f784..1592f30 100644
--- a/src/plugin/ManGa.php
+++ b/src/plugin/ManGa.php
@@ -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));
diff --git a/src/plugin/MaterialObject.php b/src/plugin/MaterialObject.php
index 2307fdc..ec6b753 100644
--- a/src/plugin/MaterialObject.php
+++ b/src/plugin/MaterialObject.php
@@ -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;
}
diff --git a/src/plugin/Schedule.php b/src/plugin/Schedule.php
index 3f154b4..3a2cbad 100644
--- a/src/plugin/Schedule.php
+++ b/src/plugin/Schedule.php
@@ -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 = [];
diff --git a/src/plugin/Sign.php b/src/plugin/Sign.php
index 45be081..5c92e79 100644
--- a/src/plugin/Sign.php
+++ b/src/plugin/Sign.php
@@ -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',
diff --git a/src/plugin/Statistics.php b/src/plugin/Statistics.php
index 52a8868..3701bfa 100644
--- a/src/plugin/Statistics.php
+++ b/src/plugin/Statistics.php
@@ -23,7 +23,7 @@ class Statistics
private static $success_list = [];
private static $profit_list = [];
- // TODO 统计开关 统计时间间隔 统计类型
+ // Todo 统计开关 统计时间间隔 统计类型
public static function run()
{
if (self::getLock() > time()) {
diff --git a/src/plugin/ZoneTcpClient.php b/src/plugin/ZoneTcpClient.php
index c9b167b..555c998 100644
--- a/src/plugin/ZoneTcpClient.php
+++ b/src/plugin/ZoneTcpClient.php
@@ -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);
diff --git a/src/script/BaseTask.php b/src/script/BaseTask.php
new file mode 100644
index 0000000..407c479
--- /dev/null
+++ b/src/script/BaseTask.php
@@ -0,0 +1,63 @@
+choice('Select', $options, $default, true);
+ static::interactor()->greenBold("You selected: {$options[$option]}", true);
+ // return $options[$option];
+ return $option;
+ }
+
+ /**
+ * @use 确认
+ * @param string $msg
+ * @param string $default
+ * @return bool
+ */
+ public static function confirm(string $msg, string $default = 'n'): bool
+ {
+ $confirm = static::interactor()->confirm($msg, $default); // Default: n (no)
+ if (!$confirm) die();
+// if ($confirm) { // is a boolean
+// static::interactor()->greenBold('是 :)', true); // Output green bold text
+// } else {
+// static::interactor()->redBold('否 :(', true); // Output red bold text
+// die();
+// }
+ return true;
+ }
+
+ /**
+ * @return \Ahc\Cli\IO\Interactor
+ */
+ public static function interactor(): Interactor
+ {
+ return static::$interactor ?? static::$interactor = new Interactor;
+ }
+}
\ No newline at end of file
diff --git a/src/script/DelDynamic.php b/src/script/DelDynamic.php
new file mode 100644
index 0000000..b12c5d7
--- /dev/null
+++ b/src/script/DelDynamic.php
@@ -0,0 +1,22 @@
+ $up_uname) {
+ $payload = [
+ 'fid' => $up_uid,
+ 'act' => 2,
+ 're_src' => 11,
+ 'csrf' => getCsrf(),
+ ];
+ $headers = [
+ 'origin' => 'https://space.bilibili.com',
+ 'referer' => 'https://space.bilibili.com/' . getUid() . '/fans/follow?tagid=' . $tag_id,
+ ];
+ $raw = Curl::post('pc', $url, $payload, $headers);
+ // {"code":0,"message":"0","ttl":1}
+ $data = json_decode($raw, true);
+ if ($data['code'] == 0) {
+ Log::notice("UP.{$up_uid} - {$up_uname} 取关成功");
+ } else {
+ Log::error("UP.{$up_uid} - {$up_uname} 取关失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
+ break;
+ }
+ sleep(random_int(5, 10));
+ }
+ }
+
+
+ /**
+ * @use 获取分组关注
+ * @param $tag_id
+ * @param int $max_pn
+ * @param int $max_ps
+ * @return array
+ * @throws \Exception
+ */
+ private static function relationTag($tag_id, int $max_pn = 30, int $max_ps = 20): array
+ {
+ $following = [];
+ $url = 'https://api.bilibili.com/x/relation/tag';
+ for ($pn = 1; $pn <= $max_pn; $pn++) {
+ $payload = [
+ 'mid' => getUid(),
+ 'tagid' => $tag_id,
+ 'pn' => $pn,
+ 'ps' => $max_ps,
+ ];
+ $headers = [
+ 'referer' => 'https://space.bilibili.com/' . getUid() . '/fans/follow',
+ ];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ $data = json_decode($raw, true);
+ if ($data['code'] == 0 && isset($data['data'])) {
+ // 循环添加到 following
+ foreach ($data['data'] as $up) {
+ $following[$up['mid']] = $up['uname'];
+ }
+ // 打印和延迟
+ Log::info("已获取分组 {$tag_id} 页码 {$pn}");
+ sleep(random_int(4, 8));
+ // 如果页面不等于 max_ps 跳出
+ if (count($data['data']) != $max_ps) {
+ break;
+ }
+ } else {
+ Log::error("获取分组关注失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
+ break;
+ }
+ }
+ $following_num = count($following);
+ Log::notice("已获取分组 {$tag_id} 有效关注数 {$following_num}");
+ return $following;
+ }
+
+
+ /**
+ * @use 获取分组
+ * @return mixed
+ */
+ private static function relationTags()
+ {
+ $url = 'https://api.bilibili.com/x/relation/tags';
+ $payload = [];
+ $headers = [
+ 'referer' => 'https://space.bilibili.com/',
+ ];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ $data = json_decode($raw, true);
+ if ($data['code'] == 0 && isset($data['data'])) {
+ $options = [];
+ foreach ($data['data'] as $tag) {
+ $options[$tag['tagid']] = "分组:{$tag['name']} - 关注数:{$tag['count']}";
+ }
+ $option = self::choice($options);
+ Log::notice("已获取分组 {$option} - {$options[$option]}");
+ return $option;
+ } else {
+ Log::error("获取关注分组失败 CODE -> {$data['code']} MSG -> {$data['message']} ");
+ die();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/script/User.php b/src/script/User.php
new file mode 100644
index 0000000..4036c42
--- /dev/null
+++ b/src/script/User.php
@@ -0,0 +1,57 @@
+ {$data['code']} MSG -> {$data['message']} ");
+ die();
+ }
+ return true;
+ }
+
+ /**
+ * @use 用户
+ * @return mixed
+ */
+ public static function userInfo()
+ {
+ $url = 'https://api.bilibili.com/x/web-interface/nav';
+ $payload = [];
+ $headers = [
+ 'origin' => 'https://space.bilibili.com',
+ 'referer' => 'https://space.bilibili.com/' . getUid(),
+ ];
+ $raw = Curl::get('pc', $url, $payload, $headers);
+ return json_decode($raw, true);
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/tool/UserAgent.php b/src/tool/UserAgent.php
new file mode 100644
index 0000000..30f011f
--- /dev/null
+++ b/src/tool/UserAgent.php
@@ -0,0 +1,401 @@
+ [
+ 'GT-I9:number2-5:00 Build/JDQ39',
+ 'Nokia 3:number1-3:[10|15] Build/IMM76D',
+ '[SAMSUNG |]SM-G3:number1-5:0[R5|I|V|A|T|S] Build/JLS36C',
+ 'Ascend G3:number0-3:0 Build/JLS36I',
+ '[SAMSUNG |]SM-G3:number3-6::number1-8::number0-9:[V|A|T|S|I|R5] Build/JLS36C',
+ 'HUAWEI G6-L:number10-11: Build/HuaweiG6-L:number10-11:',
+ '[SAMSUNG |]SM-[G|N]:number7-9:1:number0-8:[S|A|V|T] Build/[JLS36C|JSS15J]',
+ '[SAMSUNG |]SGH-N0:number6-9:5[T|V|A|S] Build/JSS15J',
+ 'Samsung Galaxy S[4|IV] Mega GT-I:number89-95:00 Build/JDQ39',
+ 'SAMSUNG SM-T:number24-28:5[s|a|t|v] Build/[JLS36C|JSS15J]',
+ 'HP :number63-73:5 Notebook PC Build/[JLS36C|JSS15J]',
+ 'HP Compaq 2:number1-3:10b Build/[JLS36C|JSS15J]',
+ 'HTC One 801[s|e] Build/[JLS36C|JSS15J]',
+ 'HTC One max Build/[JLS36C|JSS15J]',
+ 'HTC Xplorer A:number28-34:0[e|s] Build/GRJ90'
+ ],
+ '4.4' => [
+ 'XT10:number5-8:0 Build/SU6-7.3',
+ 'XT10:number12-52: Build/[KXB20.9|KXC21.5]',
+ 'Nokia :number30-34:10 Build/IMM76D',
+ 'E:number:20-23::number0-3::number0-4: Build/24.0.[A|B].1.34',
+ '[SAMSUNG |]SM-E500[F|L] Build/KTU84P',
+ 'LG Optimus G Build/KRT16M',
+ 'LG-E98:number7-9: Build/KOT49I',
+ 'Elephone P:number2-6:000 Build/KTU84P',
+ 'IQ450:number0-4: Quad Build/KOT49H',
+ 'LG-F:number2-5:00[K|S|L] Build/KOT49[I|H]',
+ 'LG-V:number3-7::number0-1:0 Build/KOT49I',
+ '[SAMSUNG |]SM-J:number1-2::number0-1:0[G|F] Build/KTU84P',
+ '[SAMSUNG |]SM-N80:number0-1:0 Build/[KVT49L|JZO54K]',
+ '[SAMSUNG |]SM-N900:number5-8: Build/KOT49H',
+ '[SAMSUNG-|]SGH-I337[|M] Build/[JSS15J|KOT49H]',
+ '[SAMSUNG |]SM-G900[W8|9D|FD|H|V|FG|A|T] Build/KOT49H',
+ '[SAMSUNG |]SM-T5:number30-35: Build/[KOT49H|KTU84P]',
+ '[Google |]Nexus :number5-7: Build/KOT49H',
+ 'LG-H2:number0-2:0 Build/KOT49[I|H]',
+ 'HTC One[_M8|_M9|0P6B|801e|809d|0P8B2|mini 2|S][ dual sim|] Build/[KOT49H|KTU84L]',
+ '[SAMSUNG |]GT-I9:number3-5:0:number0-6:[V|I|T|N] Build/KOT49H',
+ 'Lenovo P7:number7-8::number1-6: Build/[Lenovo|JRO03C]',
+ 'LG-D95:number1-8: Build/KOT49[I|H]',
+ 'LG-D:number1-8::number0-8:0 Build/KOT49[I|H]',
+ 'Nexus5 V:number6-7:.1 Build/KOT49H',
+ 'Nexus[_|] :number4-10: Build/[KOT49H|KTU84P]',
+ 'Nexus[_S_| S ][4G |]Build/GRJ22',
+ '[HM NOTE|NOTE-III|NOTE2 1LTE[TD|W|T]',
+ 'ALCATEL ONE[| ]TOUCH 70:number2-4::number0-9:[X|D|E|A] Build/KOT49H',
+ 'MOTOROLA [MOTOG|MSM8960|RAZR] Build/KVT49L'
+ ],
+ '5.0' => [
+ 'Nokia :number10-11:00 [wifi|4G|LTE] Build/GRK39F',
+ 'HTC 80:number1-2[s|w|e|t] Build/[LRX22G|JSS15J]',
+ 'Lenovo A7000-a Build/LRX21M;',
+ 'HTC Butterfly S [901|919][s|d|] Build/LRX22G',
+ 'HTC [M8|M9|M8 Pro Build/LRX22G',
+ 'LG-D3:number25-37: Build/LRX22G',
+ 'LG-D72:number0-9: Build/LRX22G',
+ '[SAMSUNG |]SM-G4:number0-9:0 Build/LRX22[G|C]',
+ '[|SAMSUNG ]SM-G9[00|25|20][FD|8|F|F-ORANGE|FG|FQ|H|I|L|M|S|T] Build/[LRX21T|KTU84F|KOT49H]',
+ '[SAMSUNG |]SM-A:number7-8:00[F|I|T|H|] Build/[LRX22G|LMY47X]',
+ '[SAMSUNG-|]SM-N91[0|5][A|V|F|G|FY] Build/LRX22C',
+ '[SAMSUNG |]SM-[T|P][350|550|555|355|805|800|710|810|815] Build/LRX22G',
+ 'LG-D7:number0-2::number0-9: Build/LRX22G',
+ '[LG|SM]-[D|G]:number8-9::number0-5::number0-9:[|P|K|T|I|F|T1] Build/[LRX22G|KOT49I|KVT49L|LMY47X]'
+ ],
+ '5.1' => [
+ 'Nexus :number5-9: Build/[LMY48B|LRX22C]',
+ '[|SAMSUNG ]SM-G9[28|25|20][X|FD|8|F|F-ORANGE|FG|FQ|H|I|L|M|S|T] Build/[LRX22G|LMY47X]',
+ '[|SAMSUNG ]SM-G9[35|350][X|FD|8|F|F-ORANGE|FG|FQ|H|I|L|M|S|T] Build/[MMB29M|LMY47X]',
+ '[MOTOROLA |][MOTO G|MOTO G XT1068|XT1021|MOTO E XT1021|MOTO XT1580|MOTO X FORCE XT1580|MOTO X PLAY XT1562|MOTO XT1562|MOTO XT1575|MOTO X PURE XT1575|MOTO XT1570 MOTO X STYLE] Build/[LXB22|LMY47Z|LPC23|LPK23|LPD23|LPH223]'
+ ],
+ '6.0' => [
+ '[SAMSUNG |]SM-[G|D][920|925|928|9350][V|F|I|L|M|S|8|I] Build/[MMB29K|MMB29V|MDB08I|MDB08L]',
+ 'Nexus :number5-7:[P|X|] Build/[MMB29K|MMB29V|MDB08I|MDB08L]',
+ 'HTC One[_| ][M9|M8|M8 Pro] Build/MRA58K',
+ 'HTC One[_M8|_M9|0P6B|801e|809d|0P8B2|mini 2|S][ dual sim|] Build/MRA58K'
+ ],
+ '7.0' => [
+ 'Pixel [XL|C] Build/[NRD90M|NME91E]',
+ 'Nexus :number5-9:[X|P|] Build/[NPD90G|NME91E]',
+ '[SAMSUNG |]GT-I:number91-98:00 Build/KTU84P',
+ 'Xperia [V |]Build/NDE63X',
+ 'LG-H:number90-93:0 Build/NRD90[C|M]'
+ ],
+ '7.1' => [
+ 'Pixel [XL|C] Build/[NRD90M|NME91E]',
+ 'Nexus :number5-9:[X|P|] Build/[NPD90G|NME91E]',
+ '[SAMSUNG |]GT-I:number91-98:00 Build/KTU84P',
+ 'Xperia [V |]Build/NDE63X',
+ 'LG-H:number90-93:0 Build/NRD90[C|M]'
+ ]
+ ];
+ public $locale = 'en-US';
+ /**
+ * List of "OS" strings used for android
+ * @var array $android_os
+ */
+ public $android_os = [
+ 'Linux; Android :androidVersion:; :androidDevice:',
+ //Todo: Add a $windowsDevices variable that does the same as androidDevice
+ //'Windows Phone 10.0; Android :androidVersion:; :windowsDevice:',
+ 'Linux; U; Android :androidVersion:; :androidDevice:',
+ 'Android; Android :androidVersion:; :androidDevice:'
+ ];
+ /**
+ * List of "OS" strings used for iOS
+ * @var array $mobile_ios
+ */
+ public $mobile_ios = [
+ 'iphone' => 'iPhone; CPU iPhone OS :number7-11:_:number0-9:_:number0-9:; like Mac OS X;',
+ 'ipad' => 'iPad; CPU iPad OS :number7-11:_:number0-9:_:number0-9: like Mac OS X;',
+ 'ipod' => 'iPod; CPU iPod OS :number7-11:_:number0-9:_:number0-9:; like Mac OS X;'
+ ];
+
+ /**
+ * Get a random operating system
+ * @param string|null $os
+ * @return string *
+ */
+ public function getOS(string $os = NULL)
+ {
+ $_os = [];
+ if ($os === NULL || in_array($os, ['chrome', 'firefox', 'explorer'])) {
+ $_os = $os === 'explorer' ? $this->windows_os : array_merge($this->windows_os, $this->linux_os, $this->mac_os);
+ } else {
+ $_os += $this->{$os . '_os'};
+ }
+ // randomly select on operating system
+ $selected_os = rtrim($_os[random_int(0, count($_os) - 1)], ';');
+
+ // check for spin syntax
+ if (strpos($selected_os, '[') !== FALSE) {
+ $selected_os = self::processSpinSyntax($selected_os);
+ }
+
+ // check for random number syntax
+ if (strpos($selected_os, ':number') !== FALSE) {
+ $selected_os = self::processRandomNumbers($selected_os);
+ }
+
+ if (random_int(1, 100) > 50) {
+ $selected_os .= '; ' . $this->locale;
+ }
+ return $selected_os;
+ }
+
+ /**
+ * Get Mobile OS
+ * @param string|null $os Can specifiy android, iphone, ipad, ipod, or null/blank for random
+ * @return string *
+ */
+ public function getMobileOS(string $os = NULL)
+ {
+ $os = strtolower($os);
+ $_os = [];
+ switch ($os) {
+ case'android':
+ $_os += $this->android_os;
+ break;
+ case 'iphone':
+ case 'ipad':
+ case 'ipod':
+ $_os[] = $this->mobile_ios[$os];
+ break;
+ default:
+ $_os = array_merge($this->android_os, array_values($this->mobile_ios));
+ }
+ // select random mobile os
+ $selected_os = rtrim($_os[random_int(0, count($_os) - 1)], ';');
+ if (strpos($selected_os, ':androidVersion:') !== FALSE) {
+ $selected_os = $this->processAndroidVersion($selected_os);
+ }
+ if (strpos($selected_os, ':androidDevice:') !== FALSE) {
+ $selected_os = $this->addAndroidDevice($selected_os);
+ }
+ if (strpos($selected_os, ':number') !== FALSE) {
+ $selected_os = self::processRandomNumbers($selected_os);
+ }
+ return $selected_os;
+ }
+
+ /**
+ * static::processRandomNumbers
+ * @param $selected_os
+ * @return null|string|string[] *
+ */
+ public static function processRandomNumbers($selected_os)
+ {
+ return preg_replace_callback('/:number(\d+)-(\d+):/i', function ($matches) {
+ return random_int($matches[1], $matches[2]);
+ }, $selected_os);
+ }
+
+ /**
+ * static::processSpinSyntax
+ * @param $selected_os
+ * @return null|string|string[] *
+ */
+ public static function processSpinSyntax($selected_os)
+ {
+ return preg_replace_callback('/\[([\w\-\s|;]*?)\]/i', function ($matches) {
+ $shuffle = explode('|', $matches[1]);
+ return $shuffle[array_rand($shuffle)];
+ }, $selected_os);
+ }
+
+ /**
+ * processAndroidVersion
+ * @param $selected_os
+ * @return null|string|string[] *
+ */
+ public function processAndroidVersion($selected_os)
+ {
+ $this->androidVersion = $version = $this->androidVersions[array_rand($this->androidVersions)];
+ return preg_replace_callback('/:androidVersion:/i', function ($matches) use ($version) {
+ return $version;
+ }, $selected_os);
+ }
+
+ /**
+ * addAndroidDevice
+ * @param $selected_os
+ * @return null|string|string[] *
+ */
+ public function addAndroidDevice($selected_os)
+ {
+ $devices = $this->androidDevices[substr($this->androidVersion, 0, 3)];
+ $device = $devices[array_rand($devices)];
+
+ $device = self::processSpinSyntax($device);
+ return preg_replace_callback('/:androidDevice:/i', function ($matches) use ($device) {
+ return $device;
+ }, $selected_os);
+ }
+
+ /**
+ * static::chromeVersion
+ * @param $version
+ * @return string *
+ */
+ public static function chromeVersion($version): string
+ {
+ return random_int($version['min'], $version['max']) . '.0.' . random_int(1000, 4000)
+ . '.' . random_int(100, 400);
+ }
+
+ /**
+ * static::firefoxVersion
+ * @param $version
+ * @return string *
+ */
+ public static function firefoxVersion($version): string
+ {
+ return random_int($version['min'], $version['max']) . '.' . random_int(0, 9);
+ }
+
+ /**
+ * static::windows
+ * @param $version
+ * @return string *
+ */
+ public static function windows($version): string
+ {
+ return random_int($version['min'], $version['max']) . '.' . random_int(0, 9);
+ }
+
+ /**
+ * generate
+ * @param null $userAgent
+ * @return string *
+ */
+ public function generate($userAgent = NULL, $locale = null): string
+ {
+
+ if (!is_null($locale))
+ $this->locale = $locale;
+
+ if ($userAgent === NULL) {
+ $r = random_int(0, 100);
+ if ($r >= 44) {
+ $userAgent = array_rand(['firefox' => 1, 'chrome' => 1, 'explorer' => 1]);
+ } else {
+ $userAgent = array_rand(['iphone' => 1, 'android' => 1, 'mobile' => 1]);
+ }
+ } elseif ($userAgent == 'windows' || $userAgent == 'mac' || $userAgent == 'linux') {
+ $agents = ['firefox' => 1, 'chrome' => 1];
+ if ($userAgent == 'windows') {
+ $agents['explorer'] = 1;
+ }
+ $userAgent = array_rand($agents);
+ }
+ $_SESSION['agent'] = $userAgent;
+ if ($userAgent == 'chrome') {
+ return 'Mozilla/5.0 (' . $this->getOS($userAgent) . ') AppleWebKit/' .
+ (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603))
+ . '.' . random_int(1, 50) . ' (KHTML, like Gecko) Chrome/' .
+ self::chromeVersion(['min' => 47, 'max' => 55]) . ' Safari/'
+ . (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603));
+ } elseif ($userAgent == 'firefox') {
+
+ return 'Mozilla/5.0 (' . $this->getOS($userAgent) . ') Gecko/'
+ . (random_int(1, 100) > 30 ? '20100101' : '20130401') . ' Firefox/'
+ . self::firefoxVersion(['min' => 45, 'max' => 74]);
+ } elseif ($userAgent == 'explorer') {
+
+ return 'Mozilla / 5.0 (compatible; MSIE ' . ($int = random_int(7, 11))
+ . '.0; ' . $this->getOS('windows') . ' Trident / '
+ . ($int == 7 || $int == 8 ? '4' : ($int == 9 ? '5' : ($int == 10 ? '6' : '7')))
+ . '.0)';
+ } elseif ($userAgent == 'mobile'
+ || $userAgent == 'android'
+ || $userAgent == 'iphone'
+ || $userAgent == 'ipad'
+ || $userAgent == 'ipod') {
+
+ return 'Mozilla/5.0 (' . $this->getMobileOS($userAgent) . ') AppleWebKit/'
+ . (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603))
+ . '.' . random_int(1, 50) . ' (KHTML, like Gecko) Chrome/'
+ . self::chromeVersion(['min' => 47, 'max' => 55]) . ' Mobile Safari/'
+ . (random_int(1, 100) > 50 ? random_int(533, 537) : random_int(600, 603))
+ . '.' . random_int(0, 9);
+ } else {
+ new Exception('Unable to determine user agent to generate');
+ }
+ }
+}
diff --git a/src/util/BaseRaffle.php b/src/util/BaseRaffle.php
index d12eb6e..1c80ddb 100644
--- a/src/util/BaseRaffle.php
+++ b/src/util/BaseRaffle.php
@@ -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)) {