[add] Script Mode

This commit is contained in:
Lkeme 2021-07-14 11:05:20 +08:00
parent 764dbf649c
commit 1ef8264f20
34 changed files with 1221 additions and 100 deletions

4
.gitignore vendored
View File

@ -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

View File

@ -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)

View File

@ -9,13 +9,14 @@
![](https://img.shields.io/github/stars/lkeme/BiliHelper-personal.svg?style=plastic&logo=appveyor "Star数量")
![](https://img.shields.io/github/forks/lkeme/BiliHelper-personal.svg?style=plastic&logo=stackshare "Fork数量")
![](https://img.shields.io/github/contributors/lkeme/BiliHelper-personal "贡献者")
![](https://img.shields.io/github/repo-size/lkeme/BiliHelper-personal?style=flat-square&label=files&color=cf8ef4&labelColor=373e4dl "文件大小")
[![Docker Pulls](https://img.shields.io/docker/pulls/lkeme/bilihelper-personal?style=flat-square)](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 @@
---- 免费的东西总是得不到人的珍惜。
---- 只有花大价钱去买到的东西,才会令人信任。
```
## 🖥️星图
[![Stargazers over time](https://starchart.cc/lkeme/BiliHelper-personal.svg)](https://starchart.cc/lkeme/BiliHelper-personal)
[![Stargazers over time](https://starchart.cc/lkeme/BiliHelper.svg)](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)

View File

@ -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
View File

@ -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": [],

View File

@ -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 =

View File

@ -640,7 +640,8 @@
"wav使用权",
"曲谱",
"抽个寂寞",
"儿子"
"儿子",
"送我"
],
"uid_list": [
28008897,

View File

@ -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"
}

View File

@ -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();

View File

@ -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
View 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;
}
}

View File

@ -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 = [

View File

@ -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
View 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));
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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');

View File

@ -12,7 +12,7 @@ namespace BiliHelper\Plugin;
class DataTreating
{
// TODO 独立分发 Push||Pull数据
// Todo 独立分发 Push||Pull数据
/**
* @use 抽奖分发
* @param array $data

View File

@ -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 {

View File

@ -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'] . '}中签到失败, 亲密度已达上限');

View File

@ -43,7 +43,7 @@ class Judge
}
/**
* @use 判案 TODO: 处理案例已满(MAX20例)
* @use 判案 Todo: 处理案例已满(MAX20例)
* @param $case_id
* @return bool
*/

View File

@ -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);

View File

@ -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));

View File

@ -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;
}

View File

@ -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 = [];

View File

@ -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',

View File

@ -23,7 +23,7 @@ class Statistics
private static $success_list = [];
private static $profit_list = [];
// TODO 统计开关 统计时间间隔 统计类型
// Todo 统计开关 统计时间间隔 统计类型
public static function run()
{
if (self::getLock() > time()) {

View File

@ -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
View 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
View 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
View 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
View 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
View 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');
}
}
}

View File

@ -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)) {