diff --git a/.gitignore b/.gitignore index e2797e5..c78a40b 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ README1.md conf/user.conf /conf/user.conf /log/ +/src/backup/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 716a933..200b7d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,25 @@ # Release Notes # 本项目Log +## v0.3.0.200312 alpha (2020-03-12) + +### Added +- 引入风纪 (不稳定测试) +- 引入新库 (需要重新Composer) +- + +### Changed +- 重构部分公用方法 +- 重构CURL请求 +- + +### Fixed +- 修复登陆繁忙 +- 修复实物抽奖 +- 修复日志输出 +- 修复部分已知 +- + ## v0.2.0.200226 alpha (2020-02-26) ### Added diff --git a/DOC.md b/DOC.md index 956e081..5e600d0 100644 --- a/DOC.md +++ b/DOC.md @@ -2,7 +2,7 @@

- +

@@ -15,29 +15,29 @@ B 站直播实用脚本 |plugin |version |description | |--------------------|--------------------|--------------------| -|Login |20.02.24 |账号登录 | -|Sleep |20.02.24 |休眠控制 | -|MasterSite |20.02.24 |主站助手 | -|Daily |20.02.24 |每日礼包 | -|Heart |20.02.24 |双端心跳 | -|Task |20.02.24 |每日任务 | -|Silver |20.02.24 |银瓜子宝箱 | -|Barrage |20.02.24 |活跃弹幕 | -|Silver2Coin |20.02.24 |银瓜子换硬币 | -|GiftSend |20.02.24 |礼物赠送 | -|GroupSignIn |20.02.24 |友爱社签到 | -|ManGa |20.02.24 |漫画签到分享 | -|GiftHeart |20.02.24 |心跳礼物 | -|MaterialObject |20.02.24 |实物抽奖 | -|AloneTcpClient |20.02.24 |独立监控 | -|ZoneTcpClient |20.02.24 |分区监控 | -|StormRaffle |20.02.24 |节奏风暴 | -|GiftRaffle |20.02.24 |活动礼物 | -|PkRaffle |20.02.24 |大乱斗 | -|GuardRaffle |20.02.24 |舰长总督 | -|AnchorRaffle |20.02.24 |天选时刻 | -|AwardRecord |20.02.24 |获奖通知 | -|Statistics |20.02.24 |数据统计 | +|Login |20.03.12 |账号登录 | +|Sleep |20.03.12 |休眠控制 | +|MasterSite |20.03.12 |主站助手 | +|Daily |20.03.12 |每日礼包 | +|Heart |20.03.12 |双端心跳 | +|Task |20.03.12 |每日任务 | +|Silver |20.03.12 |银瓜子宝箱 | +|Barrage |20.03.12 |活跃弹幕 | +|Silver2Coin |20.03.12 |银瓜子换硬币 | +|GiftSend |20.03.12 |礼物赠送 | +|GroupSignIn |20.03.12 |友爱社签到 | +|ManGa |20.03.12 |漫画签到分享 | +|GiftHeart |20.03.12 |心跳礼物 | +|MaterialObject |20.03.12 |实物抽奖 | +|AloneTcpClient |20.03.12 |独立监控 | +|ZoneTcpClient |20.03.12 |分区监控 | +|StormRaffle |20.03.12 |节奏风暴 | +|GiftRaffle |20.03.12 |活动礼物 | +|PkRaffle |20.03.12 |大乱斗 | +|GuardRaffle |20.03.12 |舰长总督 | +|AnchorRaffle |20.03.12 |天选时刻 | +|AwardRecord |20.03.12 |获奖通知 | +|Statistics |20.03.12 |数据统计 | ## 打赏赞助 diff --git a/README.md b/README.md index 925c075..148cc03 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) ## 公告 -Currently for Personal Edition **0.2.0.200226 alpha** +Currently for Personal Edition **0.3.0.200312 alpha** ## 文档 diff --git a/composer.json b/composer.json index 322c238..bc6d5b2 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "clue/socket-raw": "^1.4.1", "vlucas/phpdotenv": "^4.1", "amphp/amp": "^2.4", - "ares333/php-curl": "^4.6" + "guzzlehttp/guzzle": "^6.5" }, "license": "MIT", "authors": [ @@ -30,7 +30,8 @@ "BiliHelper\\Core\\": "src/core", "BiliHelper\\Plugin\\": "src/plugin", "BiliHelper\\Util\\": "src/util", - "BiliHelper\\Tool\\": "src/tool" + "BiliHelper\\Tool\\": "src/tool", + "BiliHelper\\Backup\\": "src/backup" } } } diff --git a/composer.lock b/composer.lock index 9415252..ede6539 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "687175b9d9d6f818c02bd5174b036b19", + "content-hash": "8e56d20f6a534d503ecfa6c7f58bf88a", "packages": [ { "name": "amphp/amp", @@ -90,17 +90,17 @@ "time": "2020-02-10T18:10:57+00:00" }, { - "name": "ares333/php-curl", - "version": "v4.6.1", + "name": "amphp/byte-stream", + "version": "v1.7.2", "source": { "type": "git", - "url": "https://github.com/ares333/php-curl.git", - "reference": "580025300c3cbf7cafe825bd454018ffc62233cf" + "url": "https://github.com/amphp/byte-stream.git", + "reference": "1e52f1752b2e20e2a7e464476ef887a2388e3832" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ares333/php-curl/zipball/580025300c3cbf7cafe825bd454018ffc62233cf", - "reference": "580025300c3cbf7cafe825bd454018ffc62233cf", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/1e52f1752b2e20e2a7e464476ef887a2388e3832", + "reference": "1e52f1752b2e20e2a7e464476ef887a2388e3832", "shasum": "", "mirrors": [ { @@ -110,33 +110,705 @@ ] }, "require": { - "ext-curl": "*", - "php": ">=5.3.0" + "amphp/amp": "^2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "friendsofphp/php-cs-fixer": "^2.3", + "infection/infection": "^0.9.3", + "phpunit/phpunit": "^6" }, "type": "library", "autoload": { "psr-4": { - "Ares333\\Curl\\": "src" + "Amp\\ByteStream\\": "lib" + }, + "files": [ + "lib/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "http://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "time": "2020-01-29T18:22:23+00:00" + }, + { + "name": "amphp/cache", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/cache.git", + "reference": "14d9fa01a2518eda31b10a421660b41a55249736" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/cache/zipball/14d9fa01a2518eda31b10a421660b41a55249736", + "reference": "14d9fa01a2518eda31b10a421660b41a55249736", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "amphp/amp": "^2", + "amphp/sync": "^1.2", + "php": ">=7.1" + }, + "conflict": { + "amphp/file": "<0.2 || >=2" + }, + "require-dev": { + "amphp/file": "^1.0", + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "phpunit/phpunit": "^6 | ^7 | ^8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Cache\\": "lib" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "Apache-2.0" + "MIT" ], "authors": [ { - "name": "Ares", - "homepage": "http://phpdr.net" + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" } ], - "description": "The best php curl library.", - "keywords": [ - "PHP cURL", - "aysnc http", - "curl", - "curlmulti" + "description": "A promise-aware caching API for Amp.", + "homepage": "https://github.com/amphp/cache", + "time": "2019-11-29T18:47:04+00:00" + }, + { + "name": "amphp/dns", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/dns.git", + "reference": "9d7e57f37d21bfed8ff2e78db52b99d45ce0c215" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/dns/zipball/9d7e57f37d21bfed8ff2e78db52b99d45ce0c215", + "reference": "9d7e57f37d21bfed8ff2e78db52b99d45ce0c215", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "amphp/amp": "^2", + "amphp/byte-stream": "^1.1", + "amphp/cache": "^1.2", + "amphp/parser": "^1", + "amphp/windows-registry": "^0.3", + "daverandom/libdns": "^2.0.1", + "ext-filter": "*", + "ext-json": "*", + "php": ">=7.0" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "phpunit/phpunit": "^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Dns\\": "lib" + }, + "files": [ + "lib/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" ], - "time": "2018-12-13T03:47:27+00:00" + "authors": [ + { + "name": "Chris Wright", + "email": "addr@daverandom.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "Async DNS resolution for Amp.", + "homepage": "https://github.com/amphp/dns", + "keywords": [ + "amp", + "amphp", + "async", + "client", + "dns", + "resolve" + ], + "time": "2019-11-28T20:10:22+00:00" + }, + { + "name": "amphp/hpack", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/hpack.git", + "reference": "0dcd35f9a8d9fc04d5fb8af0aeb109d4474cfad8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/hpack/zipball/0dcd35f9a8d9fc04d5fb8af0aeb109d4474cfad8", + "reference": "0dcd35f9a8d9fc04d5fb8af0aeb109d4474cfad8", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "http2jp/hpack-test-case": "^1", + "phpunit/phpunit": "^6 | ^7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Http\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Bob Weinand" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "HTTP/2 HPack implementation.", + "homepage": "https://github.com/amphp/hpack", + "keywords": [ + "headers", + "hpack", + "http-2" + ], + "time": "2020-01-11T19:33:14+00:00" + }, + { + "name": "amphp/http", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/http.git", + "reference": "8a1a1d6a78e6f432618aea02c6351602cf735cef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/http/zipball/8a1a1d6a78e6f432618aea02c6351602cf735cef", + "reference": "8a1a1d6a78e6f432618aea02c6351602cf735cef", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "amphp/hpack": "^3", + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "phpunit/phpunit": "^7 || ^6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Amp\\Http\\": "src" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Basic HTTP primitives which can be shared by servers and clients.", + "time": "2020-01-14T17:41:56+00:00" + }, + { + "name": "amphp/http-client", + "version": "v4.2.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/http-client.git", + "reference": "7ab9ee09c29865133a54060267665c7ad7c6fb17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/http-client/zipball/7ab9ee09c29865133a54060267665c7ad7c6fb17", + "reference": "7ab9ee09c29865133a54060267665c7ad7c6fb17", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "amphp/amp": "^2.4", + "amphp/byte-stream": "^1.6", + "amphp/hpack": "^3", + "amphp/http": "^1.6", + "amphp/socket": "^1", + "amphp/sync": "^1.3", + "league/uri": "^6", + "php": ">=7.2", + "psr/http-message": "^1" + }, + "conflict": { + "amphp/file": "<0.2 || >=2" + }, + "require-dev": { + "amphp/file": "^1 || ^0.3 || ^0.2", + "amphp/http-server": "^2-rc4", + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1.1", + "ext-json": "*", + "phpunit/phpunit": "^7 || ^8" + }, + "suggest": { + "amphp/file": "Required for file request bodies and HTTP archive logging", + "ext-json": "Required for logging HTTP archives", + "ext-zlib": "Allows using compression for response bodies." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Amp\\Http\\Client\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@gmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "Asynchronous concurrent HTTP/2 and HTTP/1.1 client built on the Amp concurrency framework", + "homepage": "https://github.com/amphp/http-client", + "keywords": [ + "async", + "client", + "concurrent", + "http", + "non-blocking", + "rest" + ], + "time": "2020-03-07T18:12:27+00:00" + }, + { + "name": "amphp/parser", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/parser.git", + "reference": "f83e68f03d5b8e8e0365b8792985a7f341c57ae1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/parser/zipball/f83e68f03d5b8e8e0365b8792985a7f341c57ae1", + "reference": "f83e68f03d5b8e8e0365b8792985a7f341c57ae1", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.3", + "phpunit/phpunit": "^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Parser\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "A generator parser to make streaming parsers simple.", + "homepage": "https://github.com/amphp/parser", + "keywords": [ + "async", + "non-blocking", + "parser", + "stream" + ], + "time": "2017-06-06T05:29:10+00:00" + }, + { + "name": "amphp/process", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/process.git", + "reference": "355b1e561b01c16ab3d78fada1ad47ccc96df70e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/process/zipball/355b1e561b01c16ab3d78fada1ad47ccc96df70e", + "reference": "355b1e561b01c16ab3d78fada1ad47ccc96df70e", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "amphp/amp": "^2", + "amphp/byte-stream": "^1.4", + "php": ">=7" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "phpunit/phpunit": "^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Process\\": "lib" + }, + "files": [ + "lib/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "Asynchronous process manager.", + "homepage": "https://github.com/amphp/process", + "time": "2019-02-26T16:33:03+00:00" + }, + { + "name": "amphp/socket", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/socket.git", + "reference": "020b65271596f84f4b3127d2eab81ad2790f9fb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/socket/zipball/020b65271596f84f4b3127d2eab81ad2790f9fb6", + "reference": "020b65271596f84f4b3127d2eab81ad2790f9fb6", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "amphp/amp": "^2", + "amphp/byte-stream": "^1.6", + "amphp/dns": "^1 || ^0.9", + "ext-openssl": "*", + "kelunik/certificate": "^1.1", + "league/uri-parser": "^1.4", + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "phpunit/phpunit": "^6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Amp\\Socket\\": "src" + }, + "files": [ + "src/functions.php", + "src/Internal/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@gmail.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Async socket connection / server tools for Amp.", + "homepage": "https://github.com/amphp/socket", + "keywords": [ + "amp", + "async", + "encryption", + "non-blocking", + "sockets", + "tcp", + "tls" + ], + "time": "2020-02-27T21:29:37+00:00" + }, + { + "name": "amphp/sync", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/sync.git", + "reference": "512d62e83c8b8d5c848183005c70e70df2bcca55" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/sync/zipball/512d62e83c8b8d5c848183005c70e70df2bcca55", + "reference": "512d62e83c8b8d5c848183005c70e70df2bcca55", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "amphp/amp": "^2.2", + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1.1", + "phpunit/phpunit": "^8 || ^7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Sync\\": "src" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" + } + ], + "description": "Mutex, Semaphore, and other synchronization tools for Amp.", + "homepage": "https://github.com/amphp/sync", + "keywords": [ + "async", + "asynchronous", + "mutex", + "semaphore", + "synchronization" + ], + "time": "2019-11-08T18:42:56+00:00" + }, + { + "name": "amphp/windows-registry", + "version": "v0.3.2", + "source": { + "type": "git", + "url": "https://github.com/amphp/windows-registry.git", + "reference": "834af7a30ad7c006b0326ccd2686ddc6e6943366" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/windows-registry/zipball/834af7a30ad7c006b0326ccd2686ddc6e6943366", + "reference": "834af7a30ad7c006b0326ccd2686ddc6e6943366", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "amphp/amp": "^2", + "amphp/byte-stream": "^1.4", + "amphp/process": "^1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\WindowsRegistry\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Windows Registry Reader.", + "time": "2018-10-24T03:34:54+00:00" }, { "name": "bramus/ansi-php", @@ -293,6 +965,536 @@ ], "time": "2019-10-28T12:32:07+00:00" }, + { + "name": "daverandom/libdns", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/DaveRandom/LibDNS.git", + "reference": "e8b6d6593d18ac3a6a14666d8a68a4703b2e05f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DaveRandom/LibDNS/zipball/e8b6d6593d18ac3a6a14666d8a68a4703b2e05f9", + "reference": "e8b6d6593d18ac3a6a14666d8a68a4703b2e05f9", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-ctype": "*", + "php": ">=7.0" + }, + "suggest": { + "ext-intl": "Required for IDN support" + }, + "type": "library", + "autoload": { + "psr-4": { + "LibDNS\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "DNS protocol implementation written in pure PHP", + "keywords": [ + "dns" + ], + "time": "2019-12-03T09:12:46+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "43ece0e75098b7ecd8d13918293029e555a50f82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82", + "reference": "43ece0e75098b7ecd8d13918293029e555a50f82", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2019-12-23T11:57:10+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, + { + "name": "kelunik/certificate", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/kelunik/certificate.git", + "reference": "56542e62d51533d04d0a9713261fea546bff80f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kelunik/certificate/zipball/56542e62d51533d04d0a9713261fea546bff80f6", + "reference": "56542e62d51533d04d0a9713261fea546bff80f6", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-openssl": "*", + "php": ">=5.4" + }, + "require-dev": { + "fabpot/php-cs-fixer": "^1.9", + "phpunit/phpunit": "^4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Kelunik\\Certificate\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Access certificate details and transform between different formats.", + "keywords": [ + "DER", + "certificate", + "certificates", + "openssl", + "pem", + "x509" + ], + "time": "2019-05-29T19:02:31+00:00" + }, + { + "name": "league/uri", + "version": "6.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "7b29ca33b287b4277d5ce7c26bc1be5d4118b484" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/7b29ca33b287b4277d5ce7c26bc1be5d4118b484", + "reference": "7b29ca33b287b4277d5ce7c26bc1be5d4118b484", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "league/uri-interfaces": "^2.1", + "php": "^7.2", + "psr/http-message": "^1.0" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^7.0 | ^8.0" + }, + "suggest": { + "ext-fileinfo": "Needed to create Data URI from a filepath", + "ext-intl": "Needed to improve host validation", + "league/uri-components": "Needed to easily manipulate URI objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "http://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "uri-template", + "url", + "ws" + ], + "time": "2020-02-08T16:31:57+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "0068a469958895ceaf3afcb489c0258adfa1e406" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/0068a469958895ceaf3afcb489c0258adfa1e406", + "reference": "0068a469958895ceaf3afcb489c0258adfa1e406", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "php": "^7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^7.0|^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common interface for URI representation", + "homepage": "http://github.com/thephpleague/uri-interfaces", + "keywords": [ + "rfc3986", + "rfc3987", + "uri", + "url" + ], + "time": "2020-02-08T12:10:37+00:00" + }, + { + "name": "league/uri-parser", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-parser.git", + "reference": "671548427e4c932352d9b9279fdfa345bf63fa00" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-parser/zipball/671548427e4c932352d9b9279fdfa345bf63fa00", + "reference": "671548427e4c932352d9b9279fdfa345bf63fa00", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.0", + "phpstan/phpstan": "^0.9.2", + "phpstan/phpstan-phpunit": "^0.9.4", + "phpstan/phpstan-strict-rules": "^0.9.0", + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-intl": "Allow parsing RFC3987 compliant hosts", + "league/uri-schemes": "Allow validating and normalizing URI parsing results" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "src" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "userland URI parser RFC 3986 compliant", + "homepage": "https://github.com/thephpleague/uri-parser", + "keywords": [ + "parse_url", + "parser", + "rfc3986", + "rfc3987", + "uri", + "url" + ], + "time": "2018-11-22T07:55:51+00:00" + }, { "name": "monolog/monolog", "version": "1.25.3", @@ -438,6 +1640,62 @@ ], "time": "2019-12-15T19:35:24+00:00" }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, { "name": "psr/log", "version": "1.1.2", @@ -491,6 +1749,52 @@ ], "time": "2019-11-01T11:05:21+00:00" }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.14.0", @@ -557,16 +1861,16 @@ }, { "name": "vlucas/phpdotenv", - "version": "v4.1.0", + "version": "v4.1.1", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "0176075a1b7ee9cf86f70143ec79edf7072c975a" + "reference": "32bd5ca5a4170f88e27073353013d210a3354ae9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/0176075a1b7ee9cf86f70143ec79edf7072c975a", - "reference": "0176075a1b7ee9cf86f70143ec79edf7072c975a", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/32bd5ca5a4170f88e27073353013d210a3354ae9", + "reference": "32bd5ca5a4170f88e27073353013d210a3354ae9", "shasum": "", "mirrors": [ { @@ -577,13 +1881,17 @@ }, "require": { "php": "^5.5.9 || ^7.0", - "phpoption/phpoption": "^1.7.1", + "phpoption/phpoption": "^1.7.2", "symfony/polyfill-ctype": "^1.9" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.3", + "ext-filter": "*", "phpunit/phpunit": "^4.8.35 || ^5.0 || ^6.0 || ^7.0" }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, "type": "library", "extra": { "branch-alias": { @@ -617,7 +1925,7 @@ "env", "environment" ], - "time": "2019-12-14T13:59:29+00:00" + "time": "2020-03-01T23:56:01+00:00" } ], "packages-dev": [], diff --git a/conf/user.conf.example b/conf/user.conf.example index a843ae1..b616578 100644 --- a/conf/user.conf.example +++ b/conf/user.conf.example @@ -60,6 +60,9 @@ SLEEP_SECTION=2,3,4,5,6 # 漫画助手 USE_MANGA=false +# 风纪(测试) +USE_JUDGE=false + ####################### # 基础设置 # ####################### @@ -73,14 +76,6 @@ ALONE_SERVER_KEY=,*(?PVl]nIbo35sB USE_ZONE_SERVER=false ZONE_SERVER_ADDR=tcp://broadcastlv.chat.bilibili.com:2243/sub -# 切换HTTPS|为真则使用https协议 -USE_HTTPS=true - -# 是否使用代理(前提保证有效代理) -USE_PROXY=false -PROXY_IP=127.0.0.1 -PROXY_PORT=8888 - # SERVER酱|令牌KEY|过滤关键词|逗号分隔 USE_SC=false SC_KEY= @@ -102,6 +97,17 @@ ROOM_LIST=9522051 # 弹幕监控房间(为空则随机) SOCKET_ROOM_ID=9522051 +####################### +# 网络设置 # +####################### + +# 验证SSL证书|请求时验证SSL证书行为 +VERIFY_SSL=true + +# 是否使用代理|(http\https) +USE_PROXY=false +NETWORK_PROXY=http://127.0.0.1:8888 + ####################### # 程序设置 # ####################### diff --git a/src/core/App.php b/src/core/App.php index 2099109..0039c23 100644 --- a/src/core/App.php +++ b/src/core/App.php @@ -74,6 +74,7 @@ class App 'Silver', 'Barrage', 'Silver2Coin', + 'Judge', 'GiftSend', 'GroupSignIn', 'GiftHeart', diff --git a/src/core/Curl.php b/src/core/Curl.php index 6c49ecf..eab8eda 100644 --- a/src/core/Curl.php +++ b/src/core/Curl.php @@ -12,30 +12,257 @@ namespace BiliHelper\Core; class Curl { - public static $headers = array( - 'Accept' => '*/*', - 'Accept-Encoding' => 'gzip', - 'Accept-Language' => 'zh-cn', - 'Connection' => 'keep-alive', - 'Content-Type' => 'application/x-www-form-urlencoded', - 'User-Agent' => 'bili-universal/8470 CFNetwork/978.0.7 Darwin/18.5.0', -// 'Referer' => 'https://live.bilibili.com/', - ); - + private static $client; + private static $async_opt; private static $results = []; private static $result = []; /** - * @use 数组 - * @return array + * @use POST请求 + * @param $os + * @param $url + * @param array $params + * @param array $headers + * @param int $timeout + * @return mixed */ - private static function getResults() + public static function post($os, $url, $params = [], $headers = [], $timeout = 30) { - $results = self::$results; - self::$results = []; - return $results; + Log::debug("POST: {$url}"); + $headers = self::getHeaders($os, $headers); + $payload['form_params'] = count($params) ? $params : []; + $options = self::getClientOpt($payload, $headers); + $request = self::clientHandle($url, 'post', $options); + $body = $request->getBody(); + Log::debug($body); + return $body; } + /** + * @use GET请求 + * @param $os + * @param $url + * @param array $params + * @param array $headers + * @param int $timeout + * @return mixed + */ + public static function get($os, $url, $params = [], $headers = [], $timeout = 30) + { + Log::debug("GET: {$url}"); + $headers = self::getHeaders($os, $headers); + $payload['query'] = count($params) ? $params : []; + $options = self::getClientOpt($payload, $headers); + $request = self::clientHandle($url, 'get', $options); + $body = $request->getBody(); + Log::debug($body); + return $body; + } + + /** + * @use PUT请求 + * @param $os + * @param $url + * @param array $params + * @param array $headers + * @param int $timeout + * @return mixed + */ + public static function put($os, $url, $params = [], $headers = [], $timeout = 30) + { + Log::debug("PUT: {$url}"); + $headers = self::getHeaders($os, $headers); + $payload['json'] = count($params) ? $params : []; + $options = self::getClientOpt($payload, $headers); + $request = self::clientHandle($url, 'post', $options); + $body = $request->getBody(); + Log::debug($body); + return $body; + } + + /** + * @use 并发POST请求 + * @param $os + * @param $url + * @param array $tasks + * @param array $headers + * @param int $timeout + * @return array + */ + public static function async($os, $url, $tasks = [], $headers = [], $timeout = 30) + { + self::$async_opt = [ + 'tasks' => $tasks, + 'counter' => 1, + 'count' => count($tasks), + 'concurrency' => count($tasks) < 10 ? count($tasks) : 10 + ]; + Log::debug("ASYNC: {$url}"); + $headers = self::getHeaders($os, $headers); + $requests = function ($total) use ($url, $headers, $tasks) { + foreach ($tasks as $task) { + yield function () use ($url, $headers, $task) { + $payload['form_params'] = $task['payload']; + $options = self::getClientOpt($payload, $headers); + return self::clientHandle($url, 'postAsync', $options); + }; + } + }; + $pool = new \GuzzleHttp\Pool(self::$client, $requests(self::$async_opt['count']), [ + 'concurrency' => self::$async_opt['concurrency'], + 'fulfilled' => function ($response, $index) { + $res = $response->getBody(); + // Log::notice("启动多线程 {$index}"); + array_push(self::$results, [ + 'content' => $res, + 'source' => self::$async_opt['tasks'][$index]['source'] + ]); + self::countedAndCheckEnded(); + }, + 'rejected' => function ($reason, $index) { + Log::error("多线程第{$index}个请求失败, ERROR: {$reason}"); + self::countedAndCheckEnded(); + }, + ]); + // 开始发送请求 + $promise = $pool->promise(); + $promise->wait(); + return self::getResults(); + } + + /** + * @use 单次请求 + * @param $method + * @param $url + * @param array $payload + * @param array $headers + * @param int $timeout + * @return false|string|null + */ + public static function request($method, $url, $payload = [], $headers = [], $timeout = 10) + { + Log::debug("REQUEST: {$url}"); + $options = array( + 'http' => array( + 'method' => strtoupper($method), + 'header' => self::arr2str($headers), + 'content' => http_build_query($payload), + 'timeout' => $timeout, + ), + ); + $result = @file_get_contents($url, false, stream_context_create($options)); + Log::debug($result); + return $result ? $result : null; + } + + /** + * @use 计数搭配并发使用 + */ + private static function countedAndCheckEnded() + { + if (self::$async_opt['counter'] < self::$async_opt['count']) { + self::$async_opt['counter']++; + return; + } + # 请求结束! + self::$async_opt = []; + } + + /** + * @use 请求中心异常处理 + * @param string $url + * @param string $method + * @param array $options + * @return mixed + */ + private static function clientHandle(string $url, string $method, array $options) + { + $max_retry = range(0, 30); + foreach ($max_retry as $retry) { + try { + return call_user_func_array([self::$client, $method], [$url, $options]); + } catch (\GuzzleHttp\Exception\RequestException $e) { + Log::warning("CURl -> RETRY: {$retry} ERROR: {$e->getMessage()} ERRNO: {$e->getCode()}"); + // var_dump($e->getRequest()); + if ($e->hasResponse()) { + var_dump($e->getResponse()); + } + Log::warning("尝试重试第 {$retry} 次,等待网络恢复..."); + sleep(10); + } + } + exit('网络异常,超出最大尝试次数,退出程序~'); + } + + /** + * @use 获取请求配置 + * @param array $add_options + * @param array $headers + * @param float $timeout + * @return array + */ + private static function getClientOpt(array $add_options, array $headers = [], float $timeout = 30.0) + { + self::$client = new \GuzzleHttp\Client(); + $default_options = [ + 'headers' => $headers, + 'timeout' => $timeout, + 'http_errors' => false, + 'verify' => getenv('VERIFY_SSL') == 'false' ? false : true, + ]; + if (getenv('USE_PROXY') == 'true') { + $default_options['proxy'] = getenv('NETWORK_PROXY'); + } + return array_merge($default_options, $add_options); + } + + /** + * @use 获取Headers + * @param string $os + * @param array $headers + * @return array + */ + private static function getHeaders(string $os = 'app', array $headers = []): array + { + $app_headers = [ + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip', + 'Accept-Language' => 'zh-cn', + 'Connection' => 'keep-alive', + 'Content-Type' => 'application/x-www-form-urlencoded', + 'User-Agent' => 'Mozilla/5.0 BiliDroid/5.51.1 (bbcallen@gmail.com)', + // 'Referer' => 'https://live.bilibili.com/', + ]; + $pc_headers = [ + 'Accept' => "application/json, text/plain, */*", + 'Accept-Encoding' => 'gzip, deflate', + 'Accept-Language' => "zh-CN,zh;q=0.9", + 'Content-Type' => 'application/x-www-form-urlencoded', + 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/82.0.4056.0 Safari/537.36 Edg/82.0.431.0', + // 'Referer' => 'https://live.bilibili.com/', + ]; + $other_headers = [ + 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36', + ]; + $default_headers = isset(${$os . "_headers"}) ? ${$os . "_headers"} : $other_headers; + if (in_array($os, ['app', 'pc']) && getenv('COOKIE') != "") { + $default_headers['Cookie'] = getenv('COOKIE'); + } + // return self::formatHeaders(array_merge($default_headers, $headers)); + return array_merge($default_headers, $headers); + } + + /** + * @use 格式化Headers + * @param $headers + * @return array + */ + private static function formatHeaders(array $headers): array + { + return array_map(function ($k, $v) { + return $k . ': ' . $v; + }, array_keys($headers), $headers); + } /** * @use 字符串or其他 @@ -49,293 +276,14 @@ class Curl } /** - * @use 获取Headers - * @param $headers + * @use 数组 * @return array */ - private static function getHeaders($headers) + private static function getResults(): array { - return array_map(function ($k, $v) { - return $k . ': ' . $v; - }, array_keys($headers), $headers); - } - - - /** - * @use 初始化Curl - * @param int $tasks_num - * @param bool $bar - * @return \Ares333\Curl\Curl - */ - private static function getMultiClient(int $tasks_num = 1, bool $bar = false) - { - $toolkit = new \Ares333\Curl\Toolkit(); - $toolkit->setCurl(); - $curl = $toolkit->getCurl(); - $curl->maxThread = $tasks_num < 10 ? $tasks_num : 10; - if (!$bar) { - $curl->onInfo = null; - } - return $curl; - } - - - /** - * @use 填充CURL_OPT - * @param $url - * @param $payload - * @param $headers - * @param $timeout - * @return array - */ - private static function fillCurlOpts($url, $payload, $headers, $timeout): array - { - $default_opts = [ - CURLOPT_URL => self::http2https($url), - CURLOPT_HEADER => 0, - CURLOPT_ENCODING => 'gzip', - CURLOPT_IPRESOLVE => 1, - CURLINFO_HEADER_OUT => true, - CURLOPT_TIMEOUT => $timeout, - CURLOPT_USERAGENT => self::$headers['User-Agent'], - CURLOPT_HTTPHEADER => is_null($headers) ? self::getHeaders(self::$headers) : self::getHeaders($headers), - CURLOPT_COOKIE => getenv('COOKIE') != "" ? getenv('COOKIE') : "", - // CURLOPT_CONNECTTIMEOUT => 10, - // CURLOPT_AUTOREFERER => true, - // CURLOPT_RETURNTRANSFER => true, - // CURLOPT_FOLLOWLOCATION => true, - // CURLOPT_SSL_VERIFYHOST => false, - // CURLOPT_SSL_VERIFYPEER => false, - // CURLOPT_MAXREDIRS => 5 - ]; - if ($payload) { - $default_opts[CURLOPT_POST] = 1; - $payload = is_bool($payload) ? [] : (is_array($payload) ? http_build_query($payload) : $payload); - $default_opts[CURLOPT_POSTFIELDS] = $payload; - } - if (getenv('USE_PROXY') == 'true') { - $default_opts[CURLOPT_PROXY] = getenv('PROXY_IP'); - $default_opts[CURLOPT_PROXYPORT] = getenv('PROXY_PORT'); - } - return $default_opts; - } - - /** - * @use async - * @param $url - * @param array $tasks - * @param null $headers - * @param int $timeout - * @return array - */ - public static function asyncPost($url, $tasks = [], $headers = null, $timeout = 30) - { - $curl = self::getMultiClient(count($tasks)); - $curl_options = self::fillCurlOpts($url, true, $headers, $timeout); - $curl->onTask = function ($curl) use ($curl_options, &$tasks) { - $task = array_shift($tasks); - if (is_null($task)) { - return; - } - $payload = $task['payload']; - $curl_options[CURLOPT_POSTFIELDS] = is_array($payload) ? http_build_query($payload) : $payload; - $curl->add([ - 'opt' => $curl_options, - 'args' => $task['source'], - ], function ($response, $args) { - Log::debug($response['info']['url']); - array_push(self::$results, [ - 'content' => $response['body'], - 'source' => $args - ]); - Log::debug($response['body']); - }); - }; - $curl->start(); - return self::getResults(); - } - - /** - * @use post - * @param $url - * @param $payload - * @param null $headers - * @param int $timeout - * @return bool|string - * @throws \Exception - */ - public static function post($url, $payload = null, $headers = null, $timeout = 30) - { - $url = self::http2https($url); - Log::debug($url); - $header = is_null($headers) ? self::getHeaders(self::$headers) : self::getHeaders($headers); - - // 重试次数 - $ret_count = 300; - $waring = 280; - - while ($ret_count) { - // 网络断开判断 延时方便连接网络 - if ($ret_count < $waring) { - Log::warning("正常等待网络连接状态恢复正常..."); - sleep(random_int(5, 10)); - } - try { - $curl = curl_init(); - if (!is_null($payload)) { - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, is_array($payload) ? http_build_query($payload) : $payload); - } - curl_setopt($curl, CURLOPT_URL, $url); - curl_setopt($curl, CURLOPT_HTTPHEADER, $header); - curl_setopt($curl, CURLOPT_HEADER, 0); - curl_setopt($curl, CURLOPT_ENCODING, 'gzip'); - curl_setopt($curl, CURLOPT_IPRESOLVE, 1); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); - // 超时 重要 - curl_setopt($curl, CURLOPT_TIMEOUT, $timeout); - curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout); - if (($cookie = getenv('COOKIE')) != "") { - curl_setopt($curl, CURLOPT_COOKIE, $cookie); - } - if (getenv('USE_PROXY') == 'true') { - curl_setopt($curl, CURLOPT_PROXY, getenv('PROXY_IP')); - curl_setopt($curl, CURLOPT_PROXYPORT, getenv('PROXY_PORT')); - } - $raw = curl_exec($curl); - - if ($err_no = curl_errno($curl)) { - throw new \Exception(curl_error($curl)); - } - - if ($raw === false || strpos($raw, 'timeout') !== false) { - Log::warning('获取的资源无效!'); - $ret_count--; - continue; - } - - Log::debug($raw); - curl_close($curl); - return $raw; - - } catch (\Exception $e) { - Log::warning("Curl请求出错, {$e->getMessage()}!"); - $ret_count--; - continue; - } - } - exit('重试次数过多,请检查代码,退出!'); - } - - /** - * @use request - * @param $url - * @param null $payload - * @param null $headers - * @param null $cookie - * @param int $timeout - * @return bool|string - */ - public static function request($url, $payload = null, $headers = null, $cookie = null, $timeout = 30) - { - Log::debug($url); - $header = is_null($headers) ? self::getHeaders(self::$headers) : self::getHeaders($headers); - - // 重试次数 - $ret_count = 30; - while ($ret_count) { - try { - $curl = curl_init(); - if (!is_null($payload)) { - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, is_array($payload) ? http_build_query($payload) : $payload); - } - curl_setopt($curl, CURLOPT_URL, $url); - curl_setopt($curl, CURLOPT_HTTPHEADER, $header); - curl_setopt($curl, CURLOPT_HEADER, 0); - curl_setopt($curl, CURLOPT_ENCODING, 'gzip'); - curl_setopt($curl, CURLOPT_IPRESOLVE, 1); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); - // 超时 重要 - curl_setopt($curl, CURLOPT_TIMEOUT, $timeout); - curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout); - // 认证 - if (!is_null($cookie)) { - curl_setopt($curl, CURLOPT_COOKIE, $cookie); - } - if (getenv('USE_PROXY') == 'true') { - curl_setopt($curl, CURLOPT_PROXY, getenv('PROXY_IP')); - curl_setopt($curl, CURLOPT_PROXYPORT, getenv('PROXY_PORT')); - } - $raw = curl_exec($curl); - - if ($err_no = curl_errno($curl)) { - throw new \Exception(curl_error($curl)); - } - - if ($raw === false || strpos($raw, 'timeout') !== false) { - Log::warning('获取的资源无效!'); - $ret_count--; - continue; - } - - Log::debug($raw); - curl_close($curl); - return $raw; - - } catch (\Exception $e) { - Log::warning("Curl请求出错, {$e->getMessage()}!"); - $ret_count--; - continue; - } - } - exit('重试次数过多,请检查代码,退出!'); - } - - - /** - * @use get - * @param $url - * @param null $payload - * @param null $headers - * @return bool|string - * @throws \Exception - */ - public static function get($url, $payload = null, $headers = null) - { - if (!is_null($payload)) { - $url .= '?' . http_build_query($payload); - } - return self::post($url, null, $headers); - } - - - /** - * @use 单次请求 - * @param $method - * @param $url - * @param array $payload - * @param array $headers - * @param int $timeout - * @return false|string - */ - public static function singleRequest($method, $url, $payload = [], $headers = [], $timeout = 10) - { - $url = self::http2https($url); - Log::debug($url); - $options = array( - 'http' => array( - 'method' => strtoupper($method), - 'header' => self::arr2str($headers), - 'content' => http_build_query($payload), - 'timeout' => $timeout, - ), - ); - $result = @file_get_contents($url, false, stream_context_create($options)); - Log::debug($result); - return $result ? $result : null; + $results = self::$results; + self::$results = []; + return $results; } /** @@ -353,31 +301,24 @@ class Curl return $tmp; } - /** - * @use http(s)转换 - * @param string $url - * @return string + * @use GET请求 + * @param $os + * @param $url + * @param array $params + * @param array $headers + * @param int $timeout + * @return mixed */ - private static function http2https(string $url): string + public static function headers($os, $url, $params = [], $headers = [], $timeout = 30) { - switch (getenv('USE_HTTPS')) { - case 'false': - if (strpos($url, 'ttps://')) { - $url = str_replace('https://', 'http://', $url); - } - break; - case 'true': - if (strpos($url, 'ttp://')) { - $url = str_replace('http://', 'https://', $url); - } - break; - default: - Log::warning('当前协议设置不正确,请检查配置文件!'); - die(); - break; - } - - return $url; + Log::debug('HEADERS: ' . $url); + $headers = self::getHeaders($os, $headers); + $payload['query'] = count($params) ? $params : []; + $payload['allow_redirects'] = false; + $options = self::getClientOpt($payload, $headers); + $request = self::clientHandle($url, 'get', $options); + Log::debug("获取Headers"); + return $request->getHeaders(); } } diff --git a/src/core/Log.php b/src/core/Log.php index 9c3259b..2c6dd98 100644 --- a/src/core/Log.php +++ b/src/core/Log.php @@ -104,7 +104,7 @@ class Log $url = str_replace('{account}', self::prefix(), getenv('APP_CALLBACK')); $url = str_replace('{level}', $level, $url); $url = str_replace('{message}', urlencode($message), $url); - Curl::get($url); + Curl::get('other', $url); } } } \ No newline at end of file diff --git a/src/plugin/AloneTcpClient.php b/src/plugin/AloneTcpClient.php index ea3e990..3ee65ff 100644 --- a/src/plugin/AloneTcpClient.php +++ b/src/plugin/AloneTcpClient.php @@ -170,7 +170,7 @@ class AloneTcpClient Log::info("连接到 {$socket->getPeerName()} 推送服务器"); } catch (Exception $e) { Log::error("连接到推送服务器失败, {$e->getMessage()}"); - self::setLock( 60); + self::setLock(60); } } } @@ -219,7 +219,7 @@ class AloneTcpClient switch ($data_type) { case 'raffle': // 抽奖推送 - // Log::notice($body); + Log::debug("(receive={$body})"); DataTreating::distribute($raw_data['data']); break; case 'entered': diff --git a/src/plugin/AnchorRaffle.php b/src/plugin/AnchorRaffle.php index f90f286..571f2cc 100644 --- a/src/plugin/AnchorRaffle.php +++ b/src/plugin/AnchorRaffle.php @@ -122,14 +122,14 @@ class AnchorRaffle extends BaseRaffle 'visit_id' => '' ]; array_push($tasks, [ - 'payload' => Sign::api($payload), + 'payload' => Sign::common($payload), 'source' => [ 'room_id' => $raffle['room_id'], 'raffle_id' => $raffle['raffle_id'] ] ]); } - $results = Curl::asyncPost($url, $tasks); + $results = Curl::async('app', $url, $tasks); # print_r($results); return $results; } diff --git a/src/plugin/AwardRecord.php b/src/plugin/AwardRecord.php index 1187d78..d41d0fc 100644 --- a/src/plugin/AwardRecord.php +++ b/src/plugin/AwardRecord.php @@ -48,11 +48,11 @@ class AwardRecord */ private static function anchorAward() { + $url = 'https://api.live.bilibili.com/xlive/lottery-interface/v1/Anchor/AwardRecord'; $payload = [ 'page' => '1', ]; - $url = 'https://api.live.bilibili.com/xlive/lottery-interface/v1/Anchor/AwardRecord'; - $raw = Curl::get($url, Sign::api($payload)); + $raw = Curl::get('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); // 防止异常 if (!isset($de_raw['data']) || !isset($de_raw['data']['list'])) { @@ -84,12 +84,12 @@ class AwardRecord */ private static function raffleAward() { + $url = 'https://api.live.bilibili.com/lottery/v1/award/award_list'; $payload = [ 'page' => '1', 'month' => '', ]; - $url = 'https://api.live.bilibili.com/lottery/v1/award/award_list'; - $raw = Curl::get($url, Sign::api($payload)); + $raw = Curl::get('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); // 防止异常 @@ -122,14 +122,14 @@ class AwardRecord */ private static function giftAward() { + // Web V3 Notice + $url = 'https://api.live.bilibili.com/xlive/lottery-interface/v3/smalltv/Notice'; $payload = [ 'type' => 'type', 'raffleId' => 'raffle_id' ]; - // Web V3 Notice - $url = 'https://api.live.bilibili.com/xlive/lottery-interface/v3/smalltv/Notice'; // 请求 && 解码 - $raw = Curl::get($url, Sign::api($payload)); + $raw = Curl::get('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); } } \ No newline at end of file diff --git a/src/plugin/Barrage.php b/src/plugin/Barrage.php index 4b0993b..d502f6b 100644 --- a/src/plugin/Barrage.php +++ b/src/plugin/Barrage.php @@ -72,7 +72,7 @@ class Barrage shuffle($apis); try { foreach ($apis as $url) { - $data = Curl::singleRequest('get', $url); + $data = Curl::request('get', $url); if (is_null($data)) continue; foreach ($punctuations as $punctuation) { if (strpos($data, $punctuation)) { @@ -96,21 +96,19 @@ class Barrage private static function sendMsg($info) { $user_info = User::parseCookies(); - $raw = Curl::get('https://api.live.bilibili.com/room/v1/Room/room_init?id=' . $info['roomid']); - $de_raw = json_decode($raw, true); - + $url = 'https://api.live.bilibili.com/msg/send'; + $data = Live::getRoomInfo($info['roomid']); $payload = [ 'color' => '16777215', 'fontsize' => 25, 'mode' => 1, 'msg' => $info['content'], 'rnd' => 0, - 'roomid' => $de_raw['data']['room_id'], + 'roomid' => $data['data']['room_id'], 'csrf' => $user_info['token'], 'csrf_token' => $user_info['token'], ]; - - return Curl::post('https://api.live.bilibili.com/msg/send', Sign::api($payload)); + return Curl::post('app', $url, Sign::common($payload)); } /** diff --git a/src/plugin/BaseRaffle.php b/src/plugin/BaseRaffle.php index 05a7e4d..6856bf5 100644 --- a/src/plugin/BaseRaffle.php +++ b/src/plugin/BaseRaffle.php @@ -12,9 +12,7 @@ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; -use BiliHelper\Core\Curl; - -abstract class BaseRaffle +use BiliHelper\Core\Curl;abstract class BaseRaffle { const ACTIVE_TITLE = ''; const ACTIVE_SWITCH = ''; @@ -82,11 +80,11 @@ abstract class BaseRaffle */ protected static function check(int $room_id): array { + $url = 'https://api.live.bilibili.com/xlive/lottery-interface/v1/lottery/getLotteryInfo'; $payload = [ 'roomid' => $room_id ]; - $url = 'https://api.live.bilibili.com/xlive/lottery-interface/v1/lottery/getLotteryInfo'; - $raw = Curl::get($url, Sign::api($payload)); + $raw = Curl::get('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); if (!isset($de_raw['data']) || $de_raw['code']) { Log::error("获取抽奖数据错误,{$de_raw['message']}"); diff --git a/src/plugin/Daily.php b/src/plugin/Daily.php index 2b66dd9..6a149ba 100644 --- a/src/plugin/Daily.php +++ b/src/plugin/Daily.php @@ -24,7 +24,7 @@ class Daily return; } self::dailyBag(); - self::setLock( 8 * 60 * 60); + self::setLock(8 * 60 * 60); } /** @@ -32,8 +32,9 @@ class Daily */ private static function dailyBag() { + $url = 'https://api.live.bilibili.com/gift/v2/live/receive_daily_bag'; $payload = []; - $data = Curl::get('https://api.live.bilibili.com/gift/v2/live/receive_daily_bag', Sign::api($payload)); + $data = Curl::get('app', $url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { diff --git a/src/plugin/GiftHeart.php b/src/plugin/GiftHeart.php index ea293a0..d7b9c61 100644 --- a/src/plugin/GiftHeart.php +++ b/src/plugin/GiftHeart.php @@ -34,13 +34,15 @@ class GiftHeart /** * @use 礼物心跳 * @return bool + * @throws \Exception */ private static function giftHeart(): bool { + $url = 'https://api.live.bilibili.com/gift/v2/live/heart_gift_receive'; $payload = [ 'roomid' => getenv('ROOM_ID'), ]; - $raw = Curl::get('https://api.live.bilibili.com/gift/v2/live/heart_gift_receive', Sign::api($payload)); + $raw = Curl::get('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); if ($de_raw['code'] == -403) { @@ -48,7 +50,8 @@ class GiftHeart $payload = [ 'ruid' => 17561885, ]; - Curl::get('https://api.live.bilibili.com/eventRoom/index', Sign::api($payload)); + $url = 'https://api.live.bilibili.com/eventRoom/index'; + Curl::get('app', $url, Sign::common($payload)); return true; } diff --git a/src/plugin/GiftRaffle.php b/src/plugin/GiftRaffle.php index 3870282..6a702a8 100644 --- a/src/plugin/GiftRaffle.php +++ b/src/plugin/GiftRaffle.php @@ -88,14 +88,14 @@ class GiftRaffle extends BaseRaffle 'visit_id' => '' ]; array_push($tasks, [ - 'payload' => Sign::api($payload), + 'payload' => Sign::common($payload), 'source' => [ 'room_id' => $raffle['room_id'], 'raffle_id' => $raffle['raffle_id'] ] ]); } - $results = Curl::asyncPost($url, $tasks); + $results = Curl::async('app', $url, $tasks); # print_r($results); return $results; } diff --git a/src/plugin/GiftSend.php b/src/plugin/GiftSend.php index 2cc844d..4b0f642 100644 --- a/src/plugin/GiftSend.php +++ b/src/plugin/GiftSend.php @@ -10,8 +10,9 @@ namespace BiliHelper\Plugin; -use BiliHelper\Core\Curl; + use BiliHelper\Core\Log; +use BiliHelper\Core\Curl; use BiliHelper\Util\TimeLock; class GiftSend @@ -124,7 +125,8 @@ class GiftSend { $new_bag_list = []; $payload = []; - $data = Curl::get('https://api.live.bilibili.com/gift/v2/gift/bag_list', Sign::api($payload)); + $url = 'https://api.live.bilibili.com/gift/v2/gift/bag_list'; + $data = Curl::get('app', $url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { Log::warning('背包查看失败!', ['msg' => $data['message']]); @@ -170,9 +172,12 @@ class GiftSend protected static function getMedalList() { self::$medal_list = []; - Log::info('正在获取勋章列表...'); - $payload = []; - $data = Curl::get('https://api.live.bilibili.com/i/api/medal?page=1&pageSize=25', Sign::api($payload)); + $url = 'https://api.live.bilibili.com/i/api/medal'; + $payload = [ + 'page' => 1, + 'pageSize' => 25 + ]; + $data = Curl::get('app', $url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { Log::warning('获取勋章列表失败!', ['msg' => $data['message']]); @@ -198,8 +203,9 @@ class GiftSend */ protected static function getUserInfo() { + $url = 'https://api.live.bilibili.com/xlive/web-ucenter/user/get_user_info'; $payload = []; - $data = Curl::get('https://api.live.bilibili.com/xlive/web-ucenter/user/get_user_info', Sign::api($payload)); + $data = Curl::get('app', $url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { Log::warning('获取帐号信息失败!', ['msg' => $data['message']]); @@ -216,11 +222,8 @@ class GiftSend protected static function getRoomInfo() { Log::info('正在生成直播间信息...'); - $payload = [ - 'id' => empty(self::$tid) ? getenv('ROOM_ID') : self::$tid, - ]; - $data = Curl::get('https://api.live.bilibili.com/room/v1/Room/room_init', Sign::api($payload)); - $data = json_decode($data, true); + $room_id = empty(self::$tid) ? getenv('ROOM_ID') : self::$tid; + $data = Live::getRoomInfo($room_id); if (isset($data['code']) && $data['code']) { Log::warning('获取主播房间号失败!', ['msg' => $data['message']]); Log::warning('清空礼物功能禁用!'); @@ -260,6 +263,7 @@ class GiftSend */ protected static function sendGift(array $value, int $amt) { + $url = 'https://api.live.bilibili.com/gift/v2/live/bag_send'; $payload = [ 'coin_type' => 'silver', 'gift_id' => $value['gift_id'], @@ -271,7 +275,7 @@ class GiftSend 'data_behavior_id' => '', 'bag_id' => $value['bag_id'] ]; - $data = Curl::post('https://api.live.bilibili.com/gift/v2/live/bag_send', Sign::api($payload)); + $data = Curl::post('app', $url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { Log::warning('送礼失败!', ['msg' => $data['message']]); diff --git a/src/plugin/GroupSignIn.php b/src/plugin/GroupSignIn.php index 2c78dbd..74394ab 100644 --- a/src/plugin/GroupSignIn.php +++ b/src/plugin/GroupSignIn.php @@ -44,8 +44,9 @@ class GroupSignIn */ protected static function getGroupList(): array { + $url = 'https://api.vc.bilibili.com/link_group/v1/member/my_groups'; $payload = []; - $raw = Curl::get('https://api.vc.bilibili.com/link_group/v1/member/my_groups', Sign::api($payload)); + $raw = Curl::get('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); if (empty($de_raw['data']['list'])) { @@ -63,11 +64,12 @@ class GroupSignIn */ protected static function signInGroup(array $groupInfo): bool { + $url = 'https://api.vc.bilibili.com/link_setting/v1/link_setting/sign_in'; $payload = [ 'group_id' => $groupInfo['group_id'], 'owner_id' => $groupInfo['owner_uid'], ]; - $raw = Curl::get('https://api.vc.bilibili.com/link_setting/v1/link_setting/sign_in', Sign::api($payload)); + $raw = Curl::get('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); if ($de_raw['code'] != '0') { diff --git a/src/plugin/GuardRaffle.php b/src/plugin/GuardRaffle.php index e01b03c..35f63aa 100644 --- a/src/plugin/GuardRaffle.php +++ b/src/plugin/GuardRaffle.php @@ -103,14 +103,14 @@ class GuardRaffle extends BaseRaffle 'visit_id' => '' ]; array_push($tasks, [ - 'payload' => Sign::api($payload), + 'payload' => Sign::common($payload), 'source' => [ 'room_id' => $raffle['room_id'], 'raffle_id' => $raffle['raffle_id'] ] ]); } - $results = Curl::asyncPost($url, $tasks); + $results = Curl::async('app', $url, $tasks); # print_r($results); return $results; } diff --git a/src/plugin/Heart.php b/src/plugin/Heart.php index 0df8f74..f71deb1 100644 --- a/src/plugin/Heart.php +++ b/src/plugin/Heart.php @@ -34,10 +34,11 @@ class Heart protected static function webHeart() { User::webGetUserInfo(); + $url = 'https://api.live.bilibili.com/relation/v1/Feed/heartBeat'; $payload = [ 'room_id' => getenv('ROOM_ID'), ]; - $data = Curl::post('https://api.live.bilibili.com/relation/v1/Feed/heartBeat', Sign::api($payload)); + $data = Curl::post('app', $url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { @@ -53,10 +54,11 @@ class Heart protected static function appHeart() { User::appGetUserInfo(); + $url = 'https://api.live.bilibili.com/mobile/userOnlineHeart'; $payload = [ 'room_id' => getenv('ROOM_ID'), ]; - $data = Curl::post('https://api.live.bilibili.com/mobile/userOnlineHeart', Sign::api($payload)); + $data = Curl::post('app', $url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { diff --git a/src/plugin/Judge.php b/src/plugin/Judge.php new file mode 100644 index 0000000..0ca1468 --- /dev/null +++ b/src/plugin/Judge.php @@ -0,0 +1,300 @@ + time() || self::$retry_time > time() || getenv('USE_JUDGE') == 'false') { + return; + } + # https://www.bilibili.com/judgement/index + $case_id = self::$wait_case_id ? self::$wait_case_id : self::caseObtain(); + if (!self::judgeCase($case_id)) { + self::setLock(1 * 60 + 5); + return; + } + // self::judgementIndex(); + self::setLock(mt_rand(6, 10) * 60); + } + + /** + * @use 判案 + * @param $case_id + * @return bool + */ + private static function judgeCase($case_id) + { + if (is_null($case_id) || $case_id == 0) { + return true; + } + // Log::info("尝试判定案件 {$case_id}"); + $data = self::judgementVote($case_id); + $num_judged = $data['num_voted']; + $ok_pct = $data['ok_percent']; + $advice = self::judgeAdvice($num_judged, $ok_pct); + if ($num_judged >= 50) { + + self::$min_ok_pct = min(self::$min_ok_pct, $ok_pct); + self::$max_ok_pct = max(self::$max_ok_pct, $ok_pct); + // user.info('更新统计投票波动情况') + } + // Log::info("案件 {$case_id} 已经等待" . self::$wait_time . "s,统计波动区间为" . self::$min_ok_pct . "-" . self::$max_ok_pct); + if (is_null($advice)) { + if (self::$wait_time >= 1200) { + // 如果case判定中,波动很小,则表示趋势基本一致 + if ((self::$max_ok_pct - self::$min_ok_pct) >= 0 && (self::$max_ok_pct - self::$min_ok_pct) <= 0.1 && $num_judged > 200) { + $num_judged += 100; + $advice0 = self::judgeAdvice($num_judged, self::$max_ok_pct); + $advice1 = self::judgeAdvice($num_judged, self::$min_ok_pct); + $advice = ($advice0 == $advice1) ? $advice0 : null; + } + Log::info("判定结果 {$advice}"); + } else { + $sleep_wait_time = ($num_judged < 300) ? 200 : 60; + Log::info("案件 {$case_id} 暂无法判定,{$sleep_wait_time}S 后重新尝试"); + self::$wait_time += $sleep_wait_time; + self::$retry_time = $sleep_wait_time + time(); + self::$wait_case_id = $case_id; + return false; + } + } + // 如果还不行就放弃 + $decision = !is_null($advice) ? $advice : 3; + $dicision_info = ($decision == 3) ? '作废票' : '有效票'; + Log::info("案件 {$case_id} 的投票结果:{$dicision_info}({$decision})"); + self::juryVote($case_id, $decision); + self::initParams(); + return true; + } + + /** + * @use 投票建议 + * @param $num_judged + * @param $pct + * @return int|null + */ + private static function judgeAdvice($num_judged, $pct) + { + if ($num_judged >= 300) { + # 认为这里可能出现了较多分歧,抬一手 + if ($pct >= 0.4) { + return 2; + } elseif ($pct <= 0.25) { + return 4; + } else { + return null; + } + } elseif ($num_judged >= 150) { + if ($pct >= 0.9) { + return 2; + } elseif ($pct <= 0.1) { + return 4; + } else { + return null; + } + } elseif ($num_judged >= 50) { + if ($pct >= 0.97) { + return 2; + } elseif ($pct <= 0.03) { + return 4; + } else { + return null; + } + } + # 抬一手 + if ($num_judged >= 400) { + return 2; + } + return null; + } + + /** + * @use 投票 + * @param $case_id + * @param $decision + */ + private static function juryVote($case_id, $decision) + { + $user_info = User::parseCookies(); + $url = 'http://api.bilibili.com/x/credit/jury/vote'; + $payload = [ + "jsonp" => "jsonp", + "cid" => $case_id, + "vote" => $decision, + "content" => "", + "likes" => "", + "hates" => "", + "attr" => "1", + "csrf" => $user_info['token'], + ]; + $raw = Curl::post('pc', $url, $payload); + $de_raw = json_decode($raw, true); + if (isset($de_raw['code']) && $de_raw['code']) { + Log::warning("案件 {$case_id} 投票失败 {$raw}"); + } else { + Log::notice("案件 {$case_id} 投票成功 {$raw}"); + } + } + + + /** + * @use 案件获取 + * @return |null + */ + private static function caseObtain() + { + $user_info = User::parseCookies(); + $url = 'http://api.bilibili.com/x/credit/jury/caseObtain'; + $payload = [ + "jsonp" => "jsonp", + "csrf" => $user_info['token'] + ]; + $raw = Curl::post('pc', $url, $payload); + $de_raw = json_decode($raw, true); + if (isset($de_raw['code']) && $de_raw['code'] == 25005) { + // {"code":25005,"message":"请成为风纪委员后再试","ttl":1} + Log::warning($de_raw['message']); + self::setLock(24 * 60 * 60); + return null; + } + if (isset($de_raw['code']) && $de_raw['code']) { + Log::info("没有获取到案件~ {$raw}"); + return null; + } else { + $case_id = $de_raw['data']['id']; + Log::info("获取到案件 {$case_id} ~"); + return $case_id; + } + } + + /** + * @use 判断投票 + * @param $case_id + * @return array + */ + private static function judgementVote($case_id) + { + $url = 'https://api.bilibili.com/x/credit/jury/juryCase'; + $headers = [ + 'Referer' => "https://www.bilibili.com/judgement/vote/{$case_id}" + ]; + $payload = [ + 'callback' => "jQuery1720" . self::randInt() . "_" . time(), + 'cid' => $case_id, + '_' => time() + ]; + $raw = Curl::get('pc', $url, $payload, $headers); + $de_raw = json_decode($raw, true); + $data = $de_raw['data']; + # 3 放弃 + # 2 否 vote_rule + # 4 删除 vote_delete + # 1 封杀 vote_break + $vote_break = $data['voteBreak']; + $vote_delete = $data['voteDelete']; + $vote_rule = $data['voteRule']; + $num_voted = $vote_break + $vote_delete + $vote_rule; + $ok_percent = $num_voted ? ($vote_rule / $num_voted) : 0; + // 言论合理比例 {$ok_percent} + Log::info("案件 {$case_id} 目前已投票 {$num_voted}"); + return [ + 'num_voted' => $num_voted, + 'ok_percent' => $ok_percent + ]; + } + + + /** + * @use 获取案例数据|风纪检测 + * @return bool + */ + private static function judgementIndex() + { + $url = 'https://api.bilibili.com/x/credit/jury/caseList'; + $headers = [ + 'Referer' => "https://www.bilibili.com/judgement/index" + ]; + $payload = [ + 'callback' => "jQuery1720" . self::randInt() . "_" . time(), + 'pn' => 1, + 'ps' => 25, + '_' => time() + ]; + $raw = Curl::get('pc', $url, $payload, $headers); + $de_raw = json_decode($raw, true); + print_r($de_raw); + $data = $de_raw['data']; + if (!$data) { + Log::info('该用户非风纪委成员'); + return false; + } + $today = date("Y-m-d"); + $sum_cases = 0; + $valid_cases = 0; + $judging_cases = 0; + foreach ($data as $case) { + $ts = $case['voteTime'] / 1000; + $vote_day = date("Y-m-d", $ts); + if ($vote_day == $today) { + $sum_cases += 1; + $vote = $case['vote']; + if ($vote) { + $valid_cases += 1; + } else { + $judging_cases += 1; + } + } + } + Log::info("今日投票{$sum_cases}({$valid_cases}票有效(非弃权),{$judging_cases}票还在进行中)"); + return true; + } + + + /** + * @use 随机整数 + * @param int $max + * @return string + */ + private static function randInt(int $max = 17): string + { + $temp = []; + foreach (range(1, $max) as $index) { + array_push($temp, mt_rand(0, 9)); + } + return implode("", $temp); + } + + /** + * @use 初始化参数 + */ + private static function initParams() + { + self::$retry_time = 0; + self::$wait_case_id = 0; + self::$wait_time = 0; + self::$min_ok_pct = 1; + self::$max_ok_pct = 0; + } +} \ No newline at end of file diff --git a/src/plugin/Live.php b/src/plugin/Live.php index ab0af47..36f92a1 100644 --- a/src/plugin/Live.php +++ b/src/plugin/Live.php @@ -27,7 +27,8 @@ class Live { $areas = []; $url = "http://api.live.bilibili.com/room/v1/Area/getList"; - $raw = Curl::get($url); + $payload = []; + $raw = Curl::get('other', $url, $payload); $de_raw = json_decode($raw, true); // 防止异常 if (!isset($de_raw['data']) || $de_raw['code']) { @@ -50,8 +51,17 @@ class Live */ public static function areaToRid($area_id): array { - $url = "https://api.live.bilibili.com/room/v1/area/getRoomList?platform=web&parent_area_id={$area_id}&cate_id=0&area_id=0&sort_type=online&page=1&page_size=30"; - $raw = Curl::get($url); + $url = "https://api.live.bilibili.com/room/v1/area/getRoomList"; + $payload = [ + 'platform' => 'web', + 'parent_area_id' => $area_id, + 'cate_id' => 0, + 'area_id' => 0, + 'sort_type' => 'online', + 'page' => 1, + 'page_size' => 30 + ]; + $raw = Curl::get('other', $url, $payload); $de_raw = json_decode($raw, true); // 防止异常 if (!isset($de_raw['data']) || $de_raw['code']) { @@ -77,7 +87,14 @@ class Live */ public static function getUserRecommend() { - $raw = Curl::get('https://api.live.bilibili.com/room/v1/Area/getListByAreaID?areaId=0&sort=online&pageSize=30&page=1'); + $url = 'https://api.live.bilibili.com/room/v1/Area/getListByAreaID'; + $payload = [ + 'areaId' => 0, + 'sort' => 'online', + 'pageSize' => 30, + 'page' => 1 + ]; + $raw = Curl::get('other', $url, $payload); $de_raw = json_decode($raw, true); if ($de_raw['code'] != '0') { return 23058; @@ -94,23 +111,36 @@ class Live */ public static function getRealRoomID($room_id) { - $raw = Curl::get('https://api.live.bilibili.com/room/v1/Room/room_init?id=' . $room_id); - $de_raw = json_decode($raw, true); - if ($de_raw['code']) { - Log::warning($room_id . ' : ' . $de_raw['msg']); + $data = self::getRoomInfo($room_id); + if ($data['code']) { + Log::warning($room_id . ' : ' . $data['msg']); return false; } - if ($de_raw['data']['is_hidden']) { + if ($data['data']['is_hidden']) { return false; } - if ($de_raw['data']['is_locked']) { + if ($data['data']['is_locked']) { return false; } - if ($de_raw['data']['encrypted']) { + if ($data['data']['encrypted']) { return false; } - return $de_raw['data']['room_id']; + return $data['data']['room_id']; + } + /** + * @use 获取直播间信息 + * @param $room_id + * @return array + */ + public static function getRoomInfo($room_id): array + { + $url = 'https://api.live.bilibili.com/room/v1/Room/room_init'; + $payload = [ + 'id' => $room_id + ]; + $raw = Curl::get('other', $url, $payload); + return json_decode($raw, true);; } @@ -118,6 +148,7 @@ class Live * @use 钓鱼检测 * @param $room_id * @return bool + * @throws \Exception */ public static function fishingDetection($room_id): bool { @@ -136,11 +167,12 @@ class Live */ public static function goToRoom($room_id): bool { + $url = 'https://api.live.bilibili.com/room/v1/Room/room_entry_action'; $payload = [ 'room_id' => $room_id, ]; // Log::info('进入直播间[' . $room_id . ']抽奖!'); - Curl::post('https://api.live.bilibili.com/room/v1/Room/room_entry_action', Sign::api($payload)); + Curl::post('app', $url, Sign::common($payload)); return true; } diff --git a/src/plugin/Login.php b/src/plugin/Login.php index 8cee26e..5b8f2fb 100644 --- a/src/plugin/Login.php +++ b/src/plugin/Login.php @@ -11,8 +11,8 @@ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; use BiliHelper\Core\Curl; -use BiliHelper\Util\TimeLock; use BiliHelper\Core\Config; +use BiliHelper\Util\TimeLock; class Login @@ -71,11 +71,11 @@ class Login */ protected static function info() { - $access_token = getenv('ACCESS_TOKEN'); + $url = 'https://passport.bilibili.com/api/v2/oauth2/info'; $payload = [ - 'access_token' => $access_token, + 'access_token' => getenv('ACCESS_TOKEN'), ]; - $data = Curl::get('https://passport.bilibili.com/api/v2/oauth2/info', Sign::api($payload)); + $data = Curl::get('app', $url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { Log::error('检查令牌失败', ['msg' => $data['message']]); @@ -91,13 +91,12 @@ class Login */ public static function refresh() { - $access_token = getenv('ACCESS_TOKEN'); - $refresh_token = getenv('REFRESH_TOKEN'); + $url = 'https://passport.bilibili.com/api/oauth2/refreshToken'; $payload = [ - 'access_token' => $access_token, - 'refresh_token' => $refresh_token, + 'access_token' => getenv('ACCESS_TOKEN'), + 'refresh_token' => getenv('REFRESH_TOKEN'), ]; - $data = Curl::post('https://passport.bilibili.com/api/oauth2/refreshToken', Sign::api($payload)); + $data = Curl::post('app', $url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { Log::error('重新生成令牌失败', ['msg' => $data['message']]); @@ -106,13 +105,18 @@ class Login Log::info('令牌生成完毕!'); $access_token = $data['data']['access_token']; Config::put('ACCESS_TOKEN', $access_token); - Log::info(' > access token: ' . $access_token); + Log::info(" > access token: {$access_token}"); $refresh_token = $data['data']['refresh_token']; Config::put('REFRESH_TOKEN', $refresh_token); - Log::info(' > refresh token: ' . $refresh_token); + Log::info(" > refresh token: {$refresh_token}"); + if (!self::saveCookie()) { + self::clearAccount(); + die(); + }; return true; } + /** * @use 普通登陆 * @param string $captcha @@ -126,11 +130,12 @@ class Login Log::error('空白的帐号和口令!'); die(); } - + self::clearAccount(); // get PublicKey Log::info('正在载入安全模块...'); + $url = 'https://passport.snm0516.aisee.tv/api/oauth2/getKey'; $payload = []; - $data = Curl::post('https://passport.bilibili.com/api/oauth2/getKey', Sign::api($payload)); + $data = Curl::post('app', $url, Sign::login($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { Log::error('公钥获取失败', ['msg' => $data['message']]); @@ -144,14 +149,16 @@ class Login for ($i = 0; $i < 30; $i++) { // login Log::info('正在获取令牌...'); + $url = 'https://passport.snm0516.aisee.tv/api/tv/login'; $payload = [ - 'subid' => 1, - 'permission' => 'ALL', + 'channel' => 'master', + 'token' => '5598158bcd8511e2', + 'guid' => 'XYEBAA3E54D502E37BD606F0589A356902FCF', 'username' => $user, 'password' => base64_encode($crypt), 'captcha' => $captcha, ]; - $data = Curl::post('https://passport.bilibili.com/api/v2/oauth2/login', Sign::api($payload), $headers); + $data = Curl::post('app', $url, Sign::login($payload), $headers); $data = json_decode($data, true); if (isset($data['code']) && $data['code'] == -105) { $captcha_data = self::loginWithCaptcha(); @@ -160,7 +167,7 @@ class Login continue; } // https://passport.bilibili.com/mobile/verifytel_h5.html - if (!$data['code'] && $data['data']['status']) { + if ($data['code'] == -2100) { Log::error('登录失败', ['msg' => '登录异常, 账号启用了设备锁或异地登录需验证手机!']); die(); } @@ -170,15 +177,17 @@ class Login Log::error('登录失败', ['msg' => $data['message']]); die(); } - self::saveCookie($data); Log::info('令牌获取成功!'); $access_token = $data['data']['token_info']['access_token']; Config::put('ACCESS_TOKEN', $access_token); - Log::info(' > access token: ' . $access_token); + Log::info(" > access token: {$access_token}"); $refresh_token = $data['data']['token_info']['refresh_token']; Config::put('REFRESH_TOKEN', $refresh_token); - Log::info(' > refresh token: ' . $refresh_token); - + Log::info(" > refresh token: {$refresh_token}"); + if (!self::saveCookie()) { + self::clearAccount(); + die(); + }; return; } @@ -190,13 +199,16 @@ class Login protected static function loginWithCaptcha() { Log::info('登录需要验证, 启动验证码登录!'); + $url = 'https://passport.snm0516.aisee.tv/api/captcha'; + $payload = [ + 'token' => '5598158bcd8511e2' + ]; $headers = [ 'Accept' => 'application/json, text/plain, */*', - 'User-Agent' => 'bili-universal/8470 CFNetwork/978.0.7 Darwin/18.5.0', - 'Host' => 'passport.bilibili.com', + 'Host' => 'passport.snm0516.aisee.tv', 'Cookie' => 'sid=blhelper' ]; - $data = Curl::request('https://passport.bilibili.com/captcha', null, $headers); + $data = Curl::get('other', $url, $payload, $headers); $data = base64_encode($data); $captcha = self::ocrCaptcha($data); return [ @@ -213,35 +225,66 @@ class Login */ private static function ocrCaptcha($captcha_img) { + $url = 'http://47.102.120.84:19951/'; $payload = [ 'image' => (string)$captcha_img ]; $headers = [ 'Content-Type' => 'application/json', ]; - $data = Curl::request('http://47.102.120.84:19951/', json_encode($payload), $headers); + $data = Curl::put('other', $url, $payload, $headers); $de_raw = json_decode($data, true); Log::info("验证码识别结果 {$de_raw['message']}"); - return $de_raw['message']; } /** - * @use 保存cookie - * @param $data + * @use token转cookie + * @return string */ - private static function saveCookie($data) + private static function token2cookie(): string { - Log::info('COOKIE获取成功!'); - //临时保存cookie - $temp = ''; - $cookies = $data['data']['cookie_info']['cookies']; - foreach ($cookies as $cookie) { - $temp .= $cookie['name'] . '=' . $cookie['value'] . ';'; + $url = 'https://passport.bilibili.com/api/login/sso'; + $payload = [ + 'gourl' => 'https%3A%2F%2Faccount.bilibili.com%2Faccount%2Fhome' + ]; + $response = Curl::headers('app', $url, Sign::common($payload)); + $headers = $response['Set-Cookie']; + $cookies = []; + foreach ($headers as $header) { + preg_match_all('/^(.*);/iU', $header, $cookie); + array_push($cookies, $cookie[0][0]); + } + return implode("", array_reverse($cookies)); + } + + + /** + * @use 保存cookie + * @return bool + */ + private static function saveCookie(): bool + { + $cookies = self::token2cookie(); + if ($cookies == '') { + Log::error("COOKIE获取失败 {$cookies}"); + return false; + } + Log::info("COOKIE获取成功 !"); + Log::info(" > cookie: {$cookies}"); + Config::put('COOKIE', $cookies); + return true; + } + + /** + * @use 清除已有 + */ + private static function clearAccount() + { + $accounts = ['ACCESS_TOKEN', 'REFRESH_TOKEN', 'COOKIE']; + foreach ($accounts as $account) { + Config::put($account, ''); } - Config::put('COOKIE', $temp); - Log::info(' > auth cookie: ' . $temp); - return; } } \ No newline at end of file diff --git a/src/plugin/ManGa.php b/src/plugin/ManGa.php index 462e44d..c32d05f 100644 --- a/src/plugin/ManGa.php +++ b/src/plugin/ManGa.php @@ -34,11 +34,12 @@ class ManGa private static function sign(): bool { sleep(1); + $url = 'https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn'; $payload = [ 'access_key' => getenv('ACCESS_TOKEN'), 'ts' => time() ]; - $raw = Curl::post('https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn', Sign::api($payload)); + $raw = Curl::post('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); # {"code":0,"msg":"","data":{}} # {"code":"invalid_argument","msg":"clockin clockin is duplicate","meta":{"argument":"clockin"}} @@ -56,8 +57,7 @@ class ManGa sleep(1); $payload = []; $url = "https://manga.bilibili.com/twirp/activity.v1.Activity/ShareComic"; - - $raw = Curl::post($url, Sign::api($payload)); + $raw = Curl::post('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); # {"code":0,"msg":"","data":{"point":5}} # {"code":1,"msg":"","data":{"point":0}} diff --git a/src/plugin/MasterSite.php b/src/plugin/MasterSite.php index 9222cc1..b896e66 100644 --- a/src/plugin/MasterSite.php +++ b/src/plugin/MasterSite.php @@ -52,7 +52,7 @@ class MasterSite 'Referer' => "https://www.bilibili.com/video/av{$aid}", 'User-Agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36", ]; - $raw = Curl::post($url, Sign::api($payload), $headers); + $raw = Curl::post('app', $url, Sign::common($payload), $headers); $de_raw = json_decode($raw, true); if ($de_raw['code'] == 0) { Log::notice("主站任务: av{$aid}投币成功!"); @@ -72,7 +72,7 @@ class MasterSite { $url = "https://api.bilibili.com/x/member/web/coin/log"; $payload = []; - $raw = Curl::get($url, Sign::api($payload)); + $raw = Curl::get('pc', $url, $payload); $de_raw = json_decode($raw, true); $logs = $de_raw['data']['list']; @@ -150,10 +150,12 @@ class MasterSite private static function getRandomAid(): string { do { - $page = random_int(1, 1000); - $payload = []; - $url = "https://api.bilibili.com/x/web-interface/newlist?&pn={$page}&ps=1"; - $raw = Curl::get($url, Sign::api($payload)); + $url = "https://api.bilibili.com/x/web-interface/newlist"; + $payload = [ + 'pn' => random_int(1, 1000), + 'ps' => 1, + ]; + $raw = Curl::get('other', $url, $payload); $de_raw = json_decode($raw, true); // echo "getRandomAid " . count($de_raw['data']['archives']) . PHP_EOL; // $aid = array_rand($de_raw['data']['archives'])['aid']; @@ -172,11 +174,16 @@ class MasterSite private static function getDayRankingAids($num): array { // day: 日榜1 三榜3 周榜7 月榜30 - $payload = []; $aids = []; $rand_nums = []; - $url = "https://api.bilibili.com/x/web-interface/ranking?rid=0&day=1&type=1&arc_type=0"; - $raw = Curl::get($url, Sign::api($payload)); + $url = "https://api.bilibili.com/x/web-interface/ranking"; + $payload = [ + 'rid' => 0, + 'day' => 1, + 'type' => 1, + 'arc_type' => 0 + ]; + $raw = Curl::get('other', $url, $payload); $de_raw = json_decode($raw, true); for ($i = 0; $i < $num; $i++) { while (true) { @@ -218,7 +225,7 @@ class MasterSite 'Referer' => "https://www.bilibili.com/video/av{$av_info['aid']}", 'User-Agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36", ]; - $raw = Curl::post($url, Sign::api($payload), $headers); + $raw = Curl::post('pc', $url, $payload, $headers); $de_raw = json_decode($raw, true); if ($de_raw['code'] == 0) { Log::notice("主站任务: av{$av_info['aid']}分享成功!"); @@ -259,8 +266,7 @@ class MasterSite 'Referer' => "https://www.bilibili.com/video/av{$av_info['aid']}", 'User-Agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36", ]; - - $raw = Curl::post($url, Sign::api($payload), $headers); + $raw = Curl::post('pc', $url, $payload, $headers); $de_raw = json_decode($raw, true); if ($de_raw['code'] == 0) { @@ -278,7 +284,7 @@ class MasterSite "play_type" => "1", 'start_ts' => time() ]; - $raw = Curl::post($url, Sign::api($payload), $headers); + $raw = Curl::post('pc', $url, $payload, $headers); $de_raw = json_decode($raw, true); if ($de_raw['code'] == 0) { @@ -286,7 +292,7 @@ class MasterSite $payload['played_time'] = $av_info['duration'] - 1; $payload['play_type'] = 0; $payload['start_ts'] = time(); - $raw = Curl::post($url, Sign::api($payload), $headers); + $raw = Curl::post('pc', $url, $payload, $headers); $de_raw = json_decode($raw, true); if ($de_raw['code'] == 0) { Log::notice("主站任务: av{$av_info['aid']}观看成功!"); @@ -308,8 +314,11 @@ class MasterSite { while (true) { $aid = self::getRandomAid(); - $url = "https://api.bilibili.com/x/web-interface/view?aid={$aid}"; - $raw = Curl::get($url); + $url = "https://api.bilibili.com/x/web-interface/view"; + $payload = [ + 'aid' => $aid + ]; + $raw = Curl::get('other', $url, $payload); $de_raw = json_decode($raw, true); if ($de_raw['code'] != 0) { continue; diff --git a/src/plugin/MaterialObject.php b/src/plugin/MaterialObject.php index 9326d21..bee0142 100644 --- a/src/plugin/MaterialObject.php +++ b/src/plugin/MaterialObject.php @@ -66,10 +66,11 @@ class MaterialObject */ private static function boxStatus(int $aid, $reply = 'bool') { + $url = 'https://api.live.bilibili.com/lottery/v1/box/getStatus'; $payload = [ 'aid' => $aid, ]; - $raw = Curl::get('https://api.live.bilibili.com/lottery/v1/box/getStatus', Sign::api($payload)); + $raw = Curl::get('pc', $url, $payload); $de_raw = json_decode($raw, true); switch ($reply) { // 等于0是有抽奖返回false @@ -96,7 +97,7 @@ class MaterialObject private static function fetchLottery(): array { $lottery_list = []; - $max_probe = 5; + $max_probe = 10; $probes = range(self::$start_aid, self::$end_aid); foreach ($probes as $probe_aid) { // 最大试探 @@ -173,11 +174,12 @@ class MaterialObject $aid = $lottery['aid']; $num = $lottery['num']; Log::notice("实物抽奖 {$aid} 轮次 {$num} 可参与抽奖~"); + $url = 'https://api.live.bilibili.com/lottery/v1/Box/draw'; $payload = [ 'aid' => $aid, 'number' => $num, ]; - $raw = Curl::get('https://api.live.bilibili.com/lottery/v1/Box/draw', Sign::api($payload)); + $raw = Curl::get('pc', $url, $payload); $de_raw = json_decode($raw, true); if ($de_raw['code'] == 0) { Log::notice("实物抽奖 {$aid} 轮次 {$num} 参与抽奖成功~"); diff --git a/src/plugin/Notice.php b/src/plugin/Notice.php index e1a12cc..0085cf7 100644 --- a/src/plugin/Notice.php +++ b/src/plugin/Notice.php @@ -130,7 +130,7 @@ class Notice private static function scSend(array $info) { $url = "https://sc.ftqq.com/" . self::$sckey . ".send?text=" . urlencode($info['title']) . "&desp=" . urlencode($info['content']); - $data = Curl::singleRequest('get', $url); + $data = Curl::request('get', $url); if (is_null($data)) { Log::warning('Server酱推送信息失败,请检查!'); }; diff --git a/src/plugin/PkRaffle.php b/src/plugin/PkRaffle.php index 8fadf43..8eadaeb 100644 --- a/src/plugin/PkRaffle.php +++ b/src/plugin/PkRaffle.php @@ -86,14 +86,14 @@ class PkRaffle extends BaseRaffle "csrf" => $user_info['token'], ]; array_push($tasks, [ - 'payload' => Sign::api($payload), + 'payload' => Sign::common($payload), 'source' => [ 'room_id' => $raffle['room_id'], 'raffle_id' => $raffle['raffle_id'] ] ]); } - $results = Curl::asyncPost($url, $tasks); + $results = Curl::async('app', $url, $tasks); # print_r($results); return $results; } diff --git a/src/plugin/Sign.php b/src/plugin/Sign.php index d6f0a4f..1564b95 100644 --- a/src/plugin/Sign.php +++ b/src/plugin/Sign.php @@ -11,46 +11,78 @@ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; -use BiliHelper\Core\Curl; -use BiliHelper\Util\TimeLock; class Sign { + /** - * @use 计算sign + * @use 登录 * @param $payload * @return array */ - public static function api($payload) + public static function login($payload) { - # iOS 6680 - $appkey = '27eb53fc9058f8c3'; - $appsecret = 'c2ed53a74eeefe3cf99fbd01d8c9c375'; - # Android - // $appkey = '1d8b6e7d45233436'; - // $appsecret = '560c52ccd288fed045859ed18bffd973'; # 云视听 TV - // $appkey = '4409e2ce8ffd12b8'; - // $appsecret = '59b43e04ad6965f34319062b478f83dd'; + $appkey = '4409e2ce8ffd12b8'; + $appsecret = '59b43e04ad6965f34319062b478f83dd'; $default = [ 'access_key' => getenv('ACCESS_TOKEN'), 'actionKey' => 'appkey', 'appkey' => $appkey, - 'build' => '8230', - 'device' => 'phone', - 'mobi_app' => 'iphone', - 'platform' => 'ios', + 'build' => 101800, + 'device' => 'android', + 'mobi_app' => 'android_tv_yst', + 'platform' => 'android', 'ts' => time(), ]; - $payload = array_merge($payload, $default); + return self::encryption($payload, $appsecret); + } + + /** + * @use 通用 + * @param $payload + * @return array + */ + public static function common($payload) + { + # iOS 6680 +// $appkey = '27eb53fc9058f8c3'; +// $appsecret = 'c2ed53a74eeefe3cf99fbd01d8c9c375'; + # Android + $appkey = '1d8b6e7d45233436'; + $appsecret = '560c52ccd288fed045859ed18bffd973'; + + $default = [ + 'access_key' => getenv('ACCESS_TOKEN'), + 'actionKey' => 'appkey', + 'appkey' => $appkey, + 'build' => 5511400, + 'device' => 'android', + 'mobi_app' => 'android', + 'platform' => 'android', + 'ts' => time(), + ]; + $payload = array_merge($payload, $default); + return self::encryption($payload, $appsecret); + } + + + /** + * @use 加密 + * @param array $payload + * @param string $app_secret + * @return array + */ + private static function encryption(array $payload, string $app_secret): array + { if (isset($payload['sign'])) { unset($payload['sign']); } ksort($payload); $data = http_build_query($payload); - $payload['sign'] = md5($data . $appsecret); + $payload['sign'] = md5($data . $app_secret); return $payload; } } \ No newline at end of file diff --git a/src/plugin/Silver.php b/src/plugin/Silver.php index e29a906..dfb5070 100644 --- a/src/plugin/Silver.php +++ b/src/plugin/Silver.php @@ -37,13 +37,14 @@ class Silver */ private static function getSilverBox() { + $url = 'https://api.live.bilibili.com/lottery/v1/SilverBox/getCurrentTask'; $payload = []; - $data = Curl::get('https://api.live.bilibili.com/lottery/v1/SilverBox/getCurrentTask', Sign::api($payload)); + $data = Curl::get('app', $url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code'] == -10017) { Log::notice($data['message']); - self::setLock( 24 * 60 * 60); + self::setLock(24 * 60 * 60); return; } @@ -59,7 +60,7 @@ class Silver 'time_start' => $data['data']['time_start'], 'time_end' => $data['data']['time_end'], ]; - self::setLock( $data['data']['minute'] * 60 + 5); + self::setLock($data['data']['minute'] * 60 + 5); } @@ -68,15 +69,16 @@ class Silver */ private static function openSilverBox() { + $url = 'https://api.live.bilibili.com/mobile/freeSilverAward'; $payload = [ 'time_end' => self::$task['time_end'], 'time_start' => self::$task['time_start'] ]; - $data = Curl::get('https://api.live.bilibili.com/mobile/freeSilverAward', Sign::api($payload)); + $data = Curl::get('app',$url, Sign::common($payload)); $data = json_decode($data, true); if ($data['code'] == -800) { - self::setLock( 12 * 60 * 60); + self::setLock(12 * 60 * 60); Log::warning("领取宝箱失败,{$data['message']}!"); return; } @@ -84,19 +86,19 @@ class Silver if ($data['code'] == -903) { Log::warning("领取宝箱失败,{$data['message']}!"); self::$task = []; - self::setLock( 60); + self::setLock(60); return; } if (isset($data['code']) && $data['code']) { Log::warning("领取宝箱失败,{$data['message']}!"); - self::setLock( 60); + self::setLock(60); return; } Log::notice("领取宝箱成功,Silver: {$data['data']['silver']}(+{$data['data']['awardSilver']})"); self::$task = []; - self::setLock( 10); + self::setLock(10); } } diff --git a/src/plugin/Silver2Coin.php b/src/plugin/Silver2Coin.php index 6e04735..4a50dc4 100644 --- a/src/plugin/Silver2Coin.php +++ b/src/plugin/Silver2Coin.php @@ -38,8 +38,9 @@ class Silver2Coin protected static function appSilver2coin(): bool { sleep(1); + $url = 'https://api.live.bilibili.com/AppExchange/silver2coin'; $payload = []; - $raw = Curl::get('https://api.live.bilibili.com/AppExchange/silver2coin', Sign::api($payload)); + $raw = Curl::get('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); if (!$de_raw['code'] && $de_raw['msg'] == '兑换成功') { @@ -64,8 +65,8 @@ class Silver2Coin $payload = []; $url = "https://api.live.bilibili.com/exchange/silver2coin"; $url = "https://api.live.bilibili.com/pay/v1/Exchange/silver2coin"; - - $raw = Curl::get($url, Sign::api($payload)); + + $raw = Curl::get('pc', $url, $payload); $de_raw = json_decode($raw, true); if ($de_raw['code'] == -403) { return false; diff --git a/src/plugin/Sleep.php b/src/plugin/Sleep.php index 25783f6..e7bfe41 100644 --- a/src/plugin/Sleep.php +++ b/src/plugin/Sleep.php @@ -21,7 +21,7 @@ class Sleep // TODO 黑白名单|考虑添加到每个插件内部自动添加|优化RUN逻辑代码 private static $unlock_hour = 24; private static $unlock_time = 0; - private static $fillable = ['Login', 'Sleep', 'Daily', 'MasterSite', 'GiftSend', 'Task', 'Silver2Coin', 'GroupSignIn', 'AwardRecord', 'Statistics']; + private static $fillable = ['Login', 'Sleep', 'Daily', 'Judge', 'MasterSite', 'GiftSend', 'Task', 'Silver2Coin', 'GroupSignIn', 'AwardRecord', 'Statistics']; private static $guarded = ['Barrage', 'GiftHeart', 'Heart', 'Silver', 'MaterialObject', 'AloneTcpClient', 'ZoneTcpClient', 'StormRaffle', 'GuardRaffle', 'PkRaffle', 'GiftRaffle', 'AnchorRaffle']; private static $sleep_section = []; @@ -75,8 +75,9 @@ class Sleep */ private static function isRefuse(): bool { + $url = 'https://api.live.bilibili.com/mobile/freeSilverAward'; $payload = []; - $raw = Curl::get('https://api.live.bilibili.com/mobile/freeSilverAward', Sign::api($payload)); + $raw = Curl::get('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); if ($de_raw['msg'] == '访问被拒绝') { $unlock_time = strtotime(date("Y-m-d", strtotime("+1 day", time()))) - time(); diff --git a/src/plugin/Statistics.php b/src/plugin/Statistics.php index a6f5ee3..9094463 100644 --- a/src/plugin/Statistics.php +++ b/src/plugin/Statistics.php @@ -11,6 +11,7 @@ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; +use BiliHelper\Core\Curl; use BiliHelper\Util\TimeLock; diff --git a/src/plugin/StormRaffle.php b/src/plugin/StormRaffle.php index 3b0883b..9eb3a4f 100644 --- a/src/plugin/StormRaffle.php +++ b/src/plugin/StormRaffle.php @@ -108,7 +108,7 @@ class StormRaffle extends BaseRaffle "visit_id" => "" ]; for ($i = 1; $i < $num; $i++) { - $raw = Curl::post($url, Sign::api($payload)); + $raw = Curl::post('app', $url, Sign::common($payload)); $de_raw = json_decode($raw, true); if ($de_raw['code'] == 429 || $de_raw['code'] == -429) { Log::notice(self::formatInfo($raffle['raffle_id'], $num, '节奏风暴未实名或异常验证码')); diff --git a/src/plugin/Task.php b/src/plugin/Task.php index 72ed7a4..d4b4f83 100644 --- a/src/plugin/Task.php +++ b/src/plugin/Task.php @@ -41,8 +41,9 @@ class Task */ private static function check() { + $url = 'https://api.live.bilibili.com/i/api/taskInfo'; $payload = []; - $data = Curl::get('https://api.live.bilibili.com/i/api/taskInfo', Sign::api($payload)); + $data = Curl::get('app',$url, Sign::common($payload)); $data = json_decode($data, true); Log::info('正在检查每日任务...'); if (isset($data['code']) && $data['code']) { @@ -64,9 +65,9 @@ class Task Log::notice('该任务已完成'); return; } - + $url = 'https://api.live.bilibili.com/sign/doSign'; $payload = []; - $data = Curl::get('https://api.live.bilibili.com/sign/doSign', Sign::api($payload)); + $data = Curl::get('app',$url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { @@ -94,10 +95,11 @@ class Task Log::notice('任务未完成,请等待'); return; } + $url = 'https://api.live.bilibili.com/activity/v1/task/receive_award'; $payload = [ 'task_id' => 'double_watch_task', ]; - $data = Curl::post('https://api.live.bilibili.com/activity/v1/task/receive_award', Sign::api($payload)); + $data = Curl::post('app',$url, Sign::common($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { diff --git a/src/plugin/User.php b/src/plugin/User.php index 0eb8ab3..eb397eb 100644 --- a/src/plugin/User.php +++ b/src/plugin/User.php @@ -18,8 +18,6 @@ use BiliHelper\Core\Config; class User { - - /** * @use 实名检测 * @return bool @@ -27,8 +25,9 @@ class User */ public static function realNameCheck(): bool { + $url = 'https://account.bilibili.com/identify/index'; $payload = []; - $raw = Curl::get('https://account.bilibili.com/identify/index', Sign::api($payload)); + $raw = Curl::get('pc', $url, $payload); $de_raw = json_decode($raw, true); //检查有没有名字,没有则没实名 if (!$de_raw['data']['memberPerson']['realname']) { @@ -45,13 +44,9 @@ class User */ public static function isMaster(): bool { - $payload = [ - 'ts' => Live::getMillisecond(), - ]; - $raw = Curl::get('https://api.live.bilibili.com/User/getUserInfo', Sign::api($payload)); - $de_raw = json_decode($raw, true); - if ($de_raw['msg'] == 'ok') { - if ($de_raw['data']['vip'] || $de_raw['data']['svip']) { + $data = self::getUserInfo(); + if ($data['msg'] == 'ok') { + if ($data['data']['vip'] || $data['data']['svip']) { return true; } } @@ -60,29 +55,70 @@ class User /** - * @use 用户名写入 + * @use 写入用户名 * @return bool * @throws \Exception */ public static function userInfo(): bool { - $payload = [ - 'ts' => Live::getMillisecond(), - ]; - $raw = Curl::get('https://api.live.bilibili.com/User/getUserInfo', Sign::api($payload)); - $de_raw = json_decode($raw, true); - + $data = self::getUserInfo(); if (getenv('APP_UNAME') != "") { return true; } - if ($de_raw['msg'] == 'ok') { - Config::put('APP_UNAME', $de_raw['data']['uname']); + if ($data['msg'] == 'ok') { + Config::put('APP_UNAME', $data['data']['uname']); return true; } return false; } + /** + * @use UserInfo + * @return array + */ + public static function getUserInfo(): array + { + $url = 'https://api.live.bilibili.com/User/getUserInfo'; + $payload = [ + 'ts' => Live::getMillisecond(), + ]; + $raw = Curl::get('app', $url, Sign::common($payload)); + return json_decode($raw, true); + } + + /** + * @use Web User + * @param null $room_id + * @return mixed + * @throws \Exception + */ + public static function webGetUserInfo($room_id = null) + { + $url = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByUser'; + $payload = [ + 'room_id' => $room_id ?? getenv('ROOM_ID') + ]; + $raw = Curl::get('pc', $url, $payload); + return json_decode($raw, true);; + } + + + /** + * @use App User + * @param null $room_id + * @return mixed + */ + public static function appGetUserInfo($room_id = null) + { + $url = 'https://api.live.bilibili.com/xlive/app-room/v1/index/getInfoByUser'; + $payload = [ + 'room_id' => $room_id ?? getenv('ROOM_ID') + ]; + $raw = Curl::get('app', $url, Sign::common($payload)); + return json_decode($raw, true);; + } + /** * @use 转换信息 * @return array @@ -102,36 +138,4 @@ class User 'sid' => $sid, ]; } - - - /** - * @use Web User - * @param null $room_id - * @return mixed - * @throws \Exception - */ - public static function webGetUserInfo($room_id = null) - { - $url = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByUser'; - $payload = [ - 'room_id' => $room_id ?? getenv('ROOM_ID') - ]; - $raw = Curl::get($url, Sign::api($payload)); - return json_decode($raw, true);; - } - - /** - * @use App User - * @return mixed - * @throws \Exception - */ - public static function appGetUserInfo() - { - $url = 'https://api.live.bilibili.com/xlive/app-room/v1/index/getInfoByUser'; - $payload = [ - 'room_id' => $room_id ?? getenv('ROOM_ID') - ]; - $raw = Curl::get($url, Sign::api($payload)); - return json_decode($raw, true);; - } } \ No newline at end of file diff --git a/src/plugin/ZoneTcpClient.php b/src/plugin/ZoneTcpClient.php index affff54..9741ba3 100644 --- a/src/plugin/ZoneTcpClient.php +++ b/src/plugin/ZoneTcpClient.php @@ -11,6 +11,7 @@ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; +use BiliHelper\Core\Curl; use BiliHelper\Util\TimeLock; use Exception; diff --git a/src/tool/DumpMemory.php b/src/tool/DumpMemory.php index f806e92..39f5266 100644 --- a/src/tool/DumpMemory.php +++ b/src/tool/DumpMemory.php @@ -4,8 +4,7 @@ namespace BiliHelper\Tool; use BiliHelper\Core\Log; - -class DumpMemory +use BiliHelper\Core\Curl;class DumpMemory { public static function dd($title) {