diff --git a/.gitignore b/.gitignore index da64cdc..dc788fa 100644 --- a/.gitignore +++ b/.gitignore @@ -25,5 +25,6 @@ conf/user.conf conf/user1.conf /conf/user.conf /conf/test.conf +/conf/test1.conf /log/ /src/backup/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 5665802..87482ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,57 @@ # Release Notes # 本项目Log +## v0.8.1.210423 alpha (2021-04-23) + +### Added +- + +### Changed +- 更新天选敏感词 +- 更新活动列表 +- 优化直播间心跳 +- + +### Fixed +- + +### Remarks +- + +## v0.8.0.210327 alpha (2021-03-27) + +### Added +- 增加直播扭蛋抽奖活动(可自定义) +- 增加主站九宫格抽奖活动(可自定义) +- 增加多个推送消息通道 +- + +### Changed +- 更新过滤词独立 +- 更新请求中心 +- 更新日志打印 +- 更新基础库 +- 更新环境读取流程 +- 更新部分配置 +- 更新登录请求 +- 更新实物抽奖&天选抽奖 +- 支持PHP8.0+ +- 更新弹幕抽奖 +- 更新每日任务 +- 更新部分任务架构 +- 引入必要新包 +- + +### Fixed +- 修复小心心心跳错误 +- 修复部分推送错误 +- 修复银瓜子换银币日志错误 +- + +### Remarks +- 结构大更新,务必进行Composer等操作 +- + ## v0.6.7.201117 alpha (2020-11-17) ### Added diff --git a/DOC.md b/DOC.md index cc397dd..85879fc 100644 --- a/DOC.md +++ b/DOC.md @@ -2,7 +2,7 @@

- +

@@ -15,34 +15,36 @@ B 站直播实用脚本 |plugin |version |description | |--------------------|--------------------|--------------------| -|Login |20.08.08 |账号登录 | -|Schedule |20.08.08 |休眠控制 | -|MasterSite |20.08.08 |主站助手 | -|Daily |20.08.08 |每日礼包 | -|Heart |20.08.08 |双端心跳 | -|Task |20.08.08 |每日任务 | -|Silver |20.08.08 |银瓜子宝箱 | -|Barrage |20.08.08 |活跃弹幕 | -|Silver2Coin |20.08.08 |银瓜子换硬币 | -|GiftSend |20.08.08 |礼物赠送 | -|Judge |20.08.08 |风纪 | -|GroupSignIn |20.08.08 |友爱社签到 | -|ManGa |20.08.08 |漫画签到分享 | -|Match |20.08.08 |赛事签到分享 | -|GiftHeart |20.08.08 |心跳礼物 | -|MaterialObject |20.08.08 |实物抽奖 | -|AloneTcpClient |20.08.08 |独立监控 | -|ZoneTcpClient |20.08.08 |分区监控 | -|StormRaffle |20.08.08 |节奏风暴 | -|GiftRaffle |20.08.08 |活动礼物 | -|PkRaffle |20.08.08 |大乱斗 | -|GuardRaffle |20.08.08 |舰长总督 | -|AnchorRaffle |20.08.08 |天选时刻 | -|AwardRecord |20.08.08 |获奖通知 | -|Statistics |20.08.08 |数据统计 | -|Competition |20.08.08 |赛事竞猜 | -|SmallHeart |20.08.08 |小心心 | -|ActivityLottery |20.08.08 |主站活动 | +|Login |21.03.27 |账号登录 | +|Schedule |21.03.27 |休眠控制 | +|MainSite |21.03.27 |主站助手 | +|Daily |21.03.27 |每日礼包 | +|Heart |21.03.27 |双端心跳 | +|DailyTask |21.03.27 |每日任务 | +|Silver |21.03.27 |银瓜子宝箱 | +|Barrage |21.03.27 |活跃弹幕 | +|Silver2Coin |21.03.27 |银瓜子换硬币 | +|GiftSend |21.03.27 |礼物赠送 | +|Judge |21.03.27 |风纪 | +|GroupSignIn |21.03.27 |友爱社签到 | +|ManGa |21.03.27 |漫画签到分享 | +|GameMatch |21.03.27 |赛事签到分享 | +|GiftHeart |21.03.27 |心跳礼物 | +|MaterialObject |21.03.27 |实物抽奖 | +|AloneTcpClient |21.03.27 |独立监控 | +|ZoneTcpClient |21.03.27 |分区监控 | +|StormRaffle |21.03.27 |节奏风暴 | +|GiftRaffle |21.03.27 |活动礼物 | +|PkRaffle |21.03.27 |大乱斗 | +|GuardRaffle |21.03.27 |舰长总督 | +|AnchorRaffle |21.03.27 |天选时刻 | +|AwardRecord |21.03.27 |获奖通知 | +|Statistics |21.03.27 |数据统计 | +|Competition |21.03.27 |赛事竞猜 | +|SmallHeart |21.03.27 |小心心 | +|ActivityLottery |21.03.27 |主站活动 | +|CapsuleLottery |21.03.27 |直播扭蛋活动 | +|Forward |21.03.27 |动态抽奖转发 | ## 打赏赞助 diff --git a/LICENSE b/LICENSE index 610b7f2..dd68ab2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 lkeme +Copyright (c) 2021 Lkeme Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index e3fd0c0..c26e1bc 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **仅用于BUG提交 ## 公告 -> Currently for Personal Edition **0.6.7.201117 alpha** +> Personal Edition **0.8.1.210423 alpha** ```notice ---- 免费的东西总是得不到人的珍惜。 @@ -15,6 +15,7 @@ Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **仅用于BUG提交 ``` ## 文档 +> 有疑问一定要先看看文档或Issue里是否存在相同的问题,再考虑其他渠道咨询。 * [使用文档 / DOC.md](./DOC.md) * [更新日志 / CHANGELOG.md](./CHANGELOG.md) diff --git a/composer.json b/composer.json index df5f982..1ad3703 100644 --- a/composer.json +++ b/composer.json @@ -10,13 +10,15 @@ "ext-json": "*", "ext-zlib": "*", "ext-mbstring": "*", - "monolog/monolog": "^1.23", - "bramus/monolog-colored-line-formatter": "^2.0", - "clue/socket-raw": "^1.4.1", - "vlucas/phpdotenv": "^4.1", - "amphp/amp": "^2.4", - "guzzlehttp/guzzle": "^6.5", - "mathieuviossat/arraytotexttable": "^1.0" + "monolog/monolog": "^1.26.0", + "bramus/monolog-colored-line-formatter": "^2.0.3", + "clue/socket-raw": "^1.5.0", + "vlucas/phpdotenv": "^4.2.0", + "amphp/amp": "^2.5.2", + "guzzlehttp/guzzle": "^6.5.5", + "mathieuviossat/arraytotexttable": "^1.0.8", + "klkvsk/json-decode-stream": "^1.0", + "sven/file-config": "^3.1" }, "license": "MIT", "authors": [ diff --git a/composer.lock b/composer.lock index 116dc01..6f574d2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "773a1bbd829be3a7bb684f926002ac37", + "content-hash": "a9407272d4bb9ca1632a2aa728429bf0", "packages": [ { "name": "amphp/amp", - "version": "v2.5.1", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", - "reference": "ecdc3c476b3ccff02f8e5d5bcc04f7ccfd18751c" + "reference": "efca2b32a7580087adb8aabbff6be1dc1bb924a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/ecdc3c476b3ccff02f8e5d5bcc04f7ccfd18751c", - "reference": "ecdc3c476b3ccff02f8e5d5bcc04f7ccfd18751c", + "url": "https://api.github.com/repos/amphp/amp/zipball/efca2b32a7580087adb8aabbff6be1dc1bb924a9", + "reference": "efca2b32a7580087adb8aabbff6be1dc1bb924a9", "shasum": "", "mirrors": [ { @@ -91,7 +91,7 @@ "support": { "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.5.1" + "source": "https://github.com/amphp/amp/tree/v2.5.2" }, "funding": [ { @@ -99,7 +99,7 @@ "type": "github" } ], - "time": "2020-11-03T16:23:45+00:00" + "time": "2021-01-10T17:06:37+00:00" }, { "name": "bramus/ansi-php", @@ -205,16 +205,16 @@ }, { "name": "clue/socket-raw", - "version": "v1.4.1", + "version": "v1.5.0", "source": { "type": "git", "url": "https://github.com/clue/php-socket-raw.git", - "reference": "00ab102d061f6cdb895e79dd4d69140c7bda31cc" + "reference": "089ffa05fa75bdc4e919aac44bbc435b3ef640ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/clue/php-socket-raw/zipball/00ab102d061f6cdb895e79dd4d69140c7bda31cc", - "reference": "00ab102d061f6cdb895e79dd4d69140c7bda31cc", + "url": "https://api.github.com/repos/clue/php-socket-raw/zipball/089ffa05fa75bdc4e919aac44bbc435b3ef640ef", + "reference": "089ffa05fa75bdc4e919aac44bbc435b3ef640ef", "shasum": "", "mirrors": [ { @@ -228,7 +228,7 @@ "php": ">=5.3" }, "require-dev": { - "phpunit/phpunit": "^7.0 || ^6.0 || ^5.2 || ^4.8.35" + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" }, "type": "library", "autoload": { @@ -246,7 +246,7 @@ "email": "christian@clue.engineering" } ], - "description": "Simple and lightweight OOP wrapper for PHP's low-level sockets extension (ext-sockets)", + "description": "Simple and lightweight OOP wrapper for PHP's low-level sockets extension (ext-sockets).", "homepage": "https://github.com/clue/php-socket-raw", "keywords": [ "Socket", @@ -264,9 +264,19 @@ ], "support": { "issues": "https://github.com/clue/php-socket-raw/issues", - "source": "https://github.com/clue/php-socket-raw/tree/v1.4.1" + "source": "https://github.com/clue/php-socket-raw/tree/v1.5.0" }, - "time": "2019-10-28T12:32:07+00:00" + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2020-11-27T13:16:18+00:00" }, { "name": "container-interop/container-interop", @@ -389,16 +399,16 @@ }, { "name": "guzzlehttp/promises", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "60d379c243457e073cff02bc323a2a86cb355631" + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/60d379c243457e073cff02bc323a2a86cb355631", - "reference": "60d379c243457e073cff02bc323a2a86cb355631", + "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", "shasum": "", "mirrors": [ { @@ -444,22 +454,22 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.4.0" + "source": "https://github.com/guzzle/promises/tree/1.4.1" }, - "time": "2020-09-30T07:37:28+00:00" + "time": "2021-03-07T09:25:29+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.7.0", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" + "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", - "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/35ea11d335fd638b5882ff1725228b3d35496ab1", + "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1", "shasum": "", "mirrors": [ { @@ -525,22 +535,82 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/1.7.0" + "source": "https://github.com/guzzle/psr7/tree/1.8.1" }, - "time": "2020-09-30T07:37:11+00:00" + "time": "2021-03-21T16:25:00+00:00" }, { - "name": "laminas/laminas-servicemanager", - "version": "3.4.1", + "name": "klkvsk/json-decode-stream", + "version": "v1.0.2", "source": { "type": "git", - "url": "https://github.com/laminas/laminas-servicemanager.git", - "reference": "0d4c8628a71fae9f7bd0b1b74b76382e5e9a04b1" + "url": "https://github.com/klkvsk/json-decode-stream.git", + "reference": "76cbcd9eb9f1860293b82b4f071e76826bc90c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/0d4c8628a71fae9f7bd0b1b74b76382e5e9a04b1", - "reference": "0d4c8628a71fae9f7bd0b1b74b76382e5e9a04b1", + "url": "https://api.github.com/repos/klkvsk/json-decode-stream/zipball/76cbcd9eb9f1860293b82b4f071e76826bc90c82", + "reference": "76cbcd9eb9f1860293b82b4f071e76826bc90c82", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "php": ">=7.1" + }, + "require-dev": { + "nyholm/psr7": "^1.3", + "phpunit/phpunit": "*", + "psr/http-message": "^1.0", + "vimeo/psalm": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "JsonDecodeStream\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mikhail Kulakovskiy", + "email": "m@klkvsk.ru" + } + ], + "description": "JSON streaming reader", + "homepage": "https://github.com/klkvsk/json-decode-stream", + "keywords": [ + "decode", + "json", + "parse", + "stream" + ], + "support": { + "issues": "https://github.com/klkvsk/json-decode-stream/issues", + "source": "https://github.com/klkvsk/json-decode-stream/tree/v1.0.2" + }, + "time": "2021-03-23T14:26:50+00:00" + }, + { + "name": "laminas/laminas-servicemanager", + "version": "3.6.4", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-servicemanager.git", + "reference": "b1445e1a7077c21b0fad0974a1b7a11b9dbe0828" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/b1445e1a7077c21b0fad0974a1b7a11b9dbe0828", + "reference": "b1445e1a7077c21b0fad0974a1b7a11b9dbe0828", "shasum": "", "mirrors": [ { @@ -553,9 +623,13 @@ "container-interop/container-interop": "^1.2", "laminas/laminas-stdlib": "^3.2.1", "laminas/laminas-zendframework-bridge": "^1.0", - "php": "^5.6 || ^7.0", + "php": "^7.3 || ~8.0.0", "psr/container": "^1.0" }, + "conflict": { + "laminas/laminas-code": "<3.3.1", + "zendframework/zend-code": "<3.3.1" + }, "provide": { "container-interop/container-interop-implementation": "^1.2", "psr/container-implementation": "^1.0" @@ -564,27 +638,24 @@ "zendframework/zend-servicemanager": "^3.4.0" }, "require-dev": { + "composer/package-versions-deprecated": "^1.0", "laminas/laminas-coding-standard": "~1.0.0", - "mikey179/vfsstream": "^1.6.5", - "ocramius/proxy-manager": "^1.0 || ^2.0", - "phpbench/phpbench": "^0.13.0", - "phpunit/phpunit": "^5.7.25 || ^6.4.4" + "laminas/laminas-container-config-test": "^0.3", + "laminas/laminas-dependency-plugin": "^2.1", + "mikey179/vfsstream": "^1.6.8", + "ocramius/proxy-manager": "^2.2.3", + "phpbench/phpbench": "^1.0.0-alpha3", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.4" }, "suggest": { - "laminas/laminas-stdlib": "laminas-stdlib ^2.5 if you wish to use the MergeReplaceKey or MergeRemoveKey features in Config instances", - "ocramius/proxy-manager": "ProxyManager 1.* to handle lazy initialization of services" + "ocramius/proxy-manager": "ProxyManager ^2.1.1 to handle lazy initialization of services" }, "bin": [ "bin/generate-deps-for-config-factory", "bin/generate-factory-for-class" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.3-dev", - "dev-develop": "4.0-dev" - } - }, "autoload": { "psr-4": { "Laminas\\ServiceManager\\": "src/" @@ -619,20 +690,20 @@ "type": "community_bridge" } ], - "time": "2020-05-11T14:43:22+00:00" + "time": "2021-02-03T08:44:41+00:00" }, { "name": "laminas/laminas-stdlib", - "version": "3.3.0", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "b9d84eaa39fde733356ea948cdef36c631f202b6" + "reference": "d81c7ffe602ed0e6ecb18691019111c0f4bf1efe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/b9d84eaa39fde733356ea948cdef36c631f202b6", - "reference": "b9d84eaa39fde733356ea948cdef36c631f202b6", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/d81c7ffe602ed0e6ecb18691019111c0f4bf1efe", + "reference": "d81c7ffe602ed0e6ecb18691019111c0f4bf1efe", "shasum": "", "mirrors": [ { @@ -651,15 +722,9 @@ "require-dev": { "laminas/laminas-coding-standard": "~1.0.0", "phpbench/phpbench": "^0.17.1", - "phpunit/phpunit": "^9.3.7" + "phpunit/phpunit": "~9.3.7" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.3.x-dev", - "dev-develop": "3.4.x-dev" - } - }, "autoload": { "psr-4": { "Laminas\\Stdlib\\": "src/" @@ -689,20 +754,20 @@ "type": "community_bridge" } ], - "time": "2020-08-25T09:08:16+00:00" + "time": "2020-11-19T20:18:59+00:00" }, { "name": "laminas/laminas-text", - "version": "2.8.0", + "version": "2.8.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-text.git", - "reference": "76fccc8f79a6fb61689e96ab300566c0065deaaa" + "reference": "d696fa1fb3880b9b8f02c08be58685013b421608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-text/zipball/76fccc8f79a6fb61689e96ab300566c0065deaaa", - "reference": "76fccc8f79a6fb61689e96ab300566c0065deaaa", + "url": "https://api.github.com/repos/laminas/laminas-text/zipball/d696fa1fb3880b9b8f02c08be58685013b421608", + "reference": "d696fa1fb3880b9b8f02c08be58685013b421608", "shasum": "", "mirrors": [ { @@ -755,20 +820,20 @@ "type": "community_bridge" } ], - "time": "2020-10-31T13:21:17+00:00" + "time": "2021-02-17T21:24:58+00:00" }, { "name": "laminas/laminas-zendframework-bridge", - "version": "1.1.1", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-zendframework-bridge.git", - "reference": "6ede70583e101030bcace4dcddd648f760ddf642" + "reference": "6cccbddfcfc742eb02158d6137ca5687d92cee32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6ede70583e101030bcace4dcddd648f760ddf642", - "reference": "6ede70583e101030bcace4dcddd648f760ddf642", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6cccbddfcfc742eb02158d6137ca5687d92cee32", + "reference": "6cccbddfcfc742eb02158d6137ca5687d92cee32", "shasum": "", "mirrors": [ { @@ -778,11 +843,13 @@ ] }, "require": { - "php": "^5.6 || ^7.0 || ^8.0" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3", - "squizlabs/php_codesniffer": "^3.5" + "psalm/plugin-phpunit": "^0.15.1", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.6" }, "type": "library", "extra": { @@ -821,7 +888,7 @@ "type": "community_bridge" } ], - "time": "2020-09-14T14:23:00+00:00" + "time": "2021-02-25T21:54:58+00:00" }, { "name": "mathieuviossat/arraytotexttable", @@ -882,16 +949,16 @@ }, { "name": "monolog/monolog", - "version": "1.25.5", + "version": "1.26.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "1817faadd1846cd08be9a49e905dc68823bc38c0" + "reference": "2209ddd84e7ef1256b7af205d0717fb62cfc9c33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1817faadd1846cd08be9a49e905dc68823bc38c0", - "reference": "1817faadd1846cd08be9a49e905dc68823bc38c0", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/2209ddd84e7ef1256b7af205d0717fb62cfc9c33", + "reference": "2209ddd84e7ef1256b7af205d0717fb62cfc9c33", "shasum": "", "mirrors": [ { @@ -913,7 +980,7 @@ "graylog2/gelf-php": "~1.0", "php-amqplib/php-amqplib": "~2.4", "php-console/php-console": "^3.1.3", - "php-parallel-lint/php-parallel-lint": "^1.0", + "phpstan/phpstan": "^0.12.59", "phpunit/phpunit": "~4.5", "ruflin/elastica": ">=0.90 <3.0", "sentry/sentry": "^0.13", @@ -933,11 +1000,6 @@ "sentry/sentry": "Allow sending log messages to a Sentry server" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, "autoload": { "psr-4": { "Monolog\\": "src/Monolog" @@ -963,7 +1025,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/1.25.5" + "source": "https://github.com/Seldaek/monolog/tree/1.26.0" }, "funding": [ { @@ -975,7 +1037,7 @@ "type": "tidelift" } ], - "time": "2020-07-23T08:35:51+00:00" + "time": "2020-12-14T12:56:38+00:00" }, { "name": "phpoption/phpoption", @@ -1054,16 +1116,16 @@ }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "", "mirrors": [ { @@ -1073,14 +1135,9 @@ ] }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -1093,7 +1150,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -1107,9 +1164,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/master" + "source": "https://github.com/php-fig/container/tree/1.1.1" }, - "time": "2017-02-14T16:28:37+00:00" + "time": "2021-03-05T17:36:06+00:00" }, { "name": "psr/http-message", @@ -1277,17 +1334,78 @@ "time": "2019-03-08T08:55:37+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.20.0", + "name": "sven/file-config", + "version": "v3.1.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" + "url": "https://github.com/svenluijten/file-config.git", + "reference": "6151381cf8b4d18beecf6605f2db64226abe58d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "url": "https://api.github.com/repos/svenluijten/file-config/zipball/6151381cf8b4d18beecf6605f2db64226abe58d0", + "reference": "6151381cf8b4d18beecf6605f2db64226abe58d0", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "league/flysystem": "^2.0", + "phpunit/phpunit": "^7.5 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sven\\FileConfig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sven Luijten", + "email": "contact@svenluijten.com", + "homepage": "https://svenluijten.com" + } + ], + "description": "Store and read configuration values using files on disk", + "keywords": [ + "config", + "configuration", + "env", + "file", + "flat", + "flatfile", + "json" + ], + "support": { + "issues": "https://github.com/svenluijten/file-config/issues", + "source": "https://github.com/svenluijten/file-config/tree/v3.1.0" + }, + "time": "2021-01-19T12:14:40+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.22.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "", "mirrors": [ { @@ -1305,7 +1423,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1343,7 +1461,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" }, "funding": [ { @@ -1359,20 +1477,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.20.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117" + "reference": "2d63434d922daf7da8dd863e7907e67ee3031483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3b75acd829741c768bc8b1f84eb33265e7cc5117", - "reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/2d63434d922daf7da8dd863e7907e67ee3031483", + "reference": "2d63434d922daf7da8dd863e7907e67ee3031483", "shasum": "", "mirrors": [ { @@ -1392,7 +1510,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1436,7 +1554,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.22.1" }, "funding": [ { @@ -1452,20 +1570,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.20.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "727d1096295d807c309fb01a851577302394c897" + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897", - "reference": "727d1096295d807c309fb01a851577302394c897", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", "shasum": "", "mirrors": [ { @@ -1483,7 +1601,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1526,7 +1644,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1" }, "funding": [ { @@ -1542,20 +1660,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.20.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930" + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cede45fcdfabdd6043b3592e83678e42ec69e930", - "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", "shasum": "", "mirrors": [ { @@ -1570,7 +1688,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1608,7 +1726,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.1" }, "funding": [ { @@ -1624,20 +1742,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "vlucas/phpdotenv", - "version": "v4.1.8", + "version": "v4.2.0", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "572af79d913627a9d70374d27a6f5d689a35de32" + "reference": "da64796370fc4eb03cc277088f6fede9fde88482" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/572af79d913627a9d70374d27a6f5d689a35de32", - "reference": "572af79d913627a9d70374d27a6f5d689a35de32", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/da64796370fc4eb03cc277088f6fede9fde88482", + "reference": "da64796370fc4eb03cc277088f6fede9fde88482", "shasum": "", "mirrors": [ { @@ -1655,7 +1773,7 @@ "bamarni/composer-bin-plugin": "^1.4.1", "ext-filter": "*", "ext-pcre": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7.27 || ^6.5.6 || ^7.0" + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20" }, "suggest": { "ext-filter": "Required to use the boolean validator.", @@ -1696,7 +1814,7 @@ ], "support": { "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/4.1" + "source": "https://github.com/vlucas/phpdotenv/tree/v4.2.0" }, "funding": [ { @@ -1708,7 +1826,7 @@ "type": "tidelift" } ], - "time": "2020-07-14T19:22:52+00:00" + "time": "2021-01-20T15:11:48+00:00" } ], "packages-dev": [], diff --git a/conf/ConfigGenerator.php b/conf/ConfigGenerator.php index d6400fd..381b5be 100644 --- a/conf/ConfigGenerator.php +++ b/conf/ConfigGenerator.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 * Source: https://github.com/NeverBehave/BilibiliHelper */ diff --git a/conf/user.conf.example b/conf/user.conf.example index 18b0697..710e46a 100644 --- a/conf/user.conf.example +++ b/conf/user.conf.example @@ -18,35 +18,59 @@ COOKIE= # 功能设置 # ####################### -# 主站助手 -USE_MASTER_SITE=true +# 主站每日任务(每日登录、观看、投币、分享) +USE_MAIN_SITE=true -# 统一活动 -USE_ACTIVE=true - -# 舰长总督 -USE_GUARD=true - -# 大乱斗 +# 直播大乱斗 USE_PK=true +# 直播箱子实物抽奖 +USE_LIVE_BOX=true + +# 每日24个小心心|依赖加密心跳服务器 +USE_HEARTBEAT=true + +# 直播扭蛋活动抽奖|依赖加密心跳服务器 +USE_CAPSULE=true + +# 主站九宫格抽奖活动助手 +USE_ACTIVITY=true + +# 银瓜子兑换硬币 +USE_SILVER2COIN=true + +# 风纪委员 +USE_JUDGE=false + +# 直播统一活动 +USE_ACTIVE=false + +# 直播舰长总督 +USE_GUARD=false + +# 漫画助手 +USE_MANGA=false + +# 赛事助手 +USE_MATCH=false + +# 节奏风暴|丢弃率(0-100)|尝试数(范围值) +USE_STORM=false +STORM_DROPRATE=0 +STORM_ATTEMPT=10,20 + +# 破产机|每日竞猜次数|每次竞猜硬币(1-10)|下注(1.压大,2.压小,3.随机) +USE_COMPETITION=false +COMPET_MAX_NUM=20 +COMPET_MAX_COIN=10 +COMPET_STAKE=1 + # 天选时刻|抽取类型(0: 无限制; 1: 关注主播; 2: 粉丝勋章; 3大航海; 4用户等级;5主站等级)|自动取关(测试功能)|过滤关键词|逗号分隔 USE_ANCHOR=false ANCHOR_UNFOLLOW=false ANCHOR_TYPE=0,1 ANCHOR_FILTER_WORDS= -# 实物抽奖 -USE_MO=true - -# 银瓜子兑换硬币 -USE_SILVER2COIN=true - -# 节奏风暴|丢弃率(0-100)|尝试数(范围值) -USE_STORM=true -STORM_DROPRATE=0 -STORM_ATTEMPT=30,50 - # 活跃弹幕|弹幕房间(为空则随机)|弹幕内容(为空则随机) USE_DANMU=true DANMU_ROOMID=9522051 @@ -57,34 +81,41 @@ USE_ADD_COIN=false ADD_COIN_MODE=random ADD_COIN_NUM=5 -# 休眠时间|时间区间(0-23)|逗号分隔 -USE_SLEEP=true -SLEEP_SECTION=2,3,4,5,6 - -# 漫画助手 -USE_MANGA=false - -# 赛事助手 -USE_MATCH=false - -# 活动助手 -USE_ACTIVITY=false - -# 破产机|每日竞猜次数|每次竞猜硬币(1-10)|下注(1.压大,2.压小,3.随机) -USE_COMPETITION=false -COMPET_MAX_NUM=20 -COMPET_MAX_COIN=10 -COMPET_STAKE=1 - -# 风纪委员 -USE_JUDGE=false - # 自动转发抽奖动态 AUTO_DYNAMIC = false # 自动取关未中奖动态 CLEAR_DYNAMIC = false # 强制清除抽奖组关注 CLEAR_GROUP_FOLLOW = false +# 更改自动回复语言 +AUTO_REPLY_TEXT = 从未中奖,从未放弃[doge] + +# 休眠时间|时间区间(0-23)|逗号分隔 +USE_SLEEP=true +SLEEP_SECTION=2,3,4,5,6 + +####################### +# 通知设置 # +####################### + +# 消息推送|消息推送过滤词|逗号分割|优先级从上到下 +USE_NOTIFY=false +NOTIFY_FILTER_WORDS= +## Dingtalk机器人|token|依赖USE_NOTIFY +NOTIFY_DINGTALK_TOKEN= +## Tele机器人|token|chatid|依赖USE_NOTIFY +NOTIFY_TELE_BOTTOKEN= +NOTIFY_TELE_CHATID= +## Pushplus酱|token|依赖USE_NOTIFY +NOTIFY_PUSHPLUS_TOKEN= +## Sever酱(原版)|令牌Key|依赖USE_NOTIFY +NOTIFY_SCKEY= +## Server酱(Turbo版)|令牌Key|依赖USE_NOTIFY +NOTIFY_SCTKEY= +## GoCqhttp|url|token|qq|依赖USE_NOTIFY +NOTIFY_CQ_URL= +NOTIFY_CQ_TOKEN= +NOTIFY_CQ_QQ= ####################### # 基础设置 # @@ -99,14 +130,8 @@ ALONE_SERVER_KEY= USE_ZONE_SERVER=true ZONE_SERVER_ADDR=tcp://broadcastlv.chat.bilibili.com:2243/sub -# SERVER酱|令牌KEY|过滤关键词|逗号分隔 -USE_SC=false -SC_KEY= -SC_FILTER_WORDS= - -# 小心心|加密服务器(开源)| -USE_HEARTBEAT=true -ENC_SERVER=http://116.85.43.27:3000/enc +# 加密心跳服务器(开源)|如失效自行搭建 +ENC_SERVER=http://heartbeat-1.mudew.com:3000/enc ####################### # 房间设置 # @@ -140,10 +165,10 @@ NETWORK_PROXY=http://127.0.0.1:8888 ####################### # 写入日志 -APP_WRITELOG=false +APP_WRITE_LOG=false # 日志路径 -APP_WRITELOGPATH=log +APP_LOG_PATH=log # 调试模式 APP_DEBUG=false diff --git a/data/activity_infos.json b/data/activity_infos.json new file mode 100644 index 0000000..90c1d60 --- /dev/null +++ b/data/activity_infos.json @@ -0,0 +1,92 @@ +{ + "remarks": "有需要可以自己添加,或者提pr", + "data": [ + { + "_url": "注释: 活动地址", + "url": "https://www.bilibili.com/blackboard/activity-S9PC.html", + "_title": "注释: 活动标题", + "title": "vivo S9系列照亮我的美", + "_description": "注释: 活动描述", + "description": "vivo S9系列照亮我的美", + "_sid": "注释: 活动SID", + "sid": "f3ae9322-817d-11eb-8597-246e966235d8", + "_login": "注释: 登录+1次机会", + "login": "true", + "_follow": "注释: 关注+1次机会", + "follow": "false", + "_share": "注释: 分享+1次机会", + "share": "true", + "_draw_times": "抽奖次数", + "draw_times": 2, + "_expire_at": "注释: 到期时间", + "expire_at": "2021-03-30 23:59:59" + }, + { + "url": "https://www.bilibili.com/blackboard/BDF2021.html", + "title": "哔哩哔哩舞蹈嘉年华2021", + "description": "BDF2021等你来玩!活动期间每天分享页面,新增一次机会。", + "sid": "12a6d7e9-7813-11eb-8597-246e966235d8", + "login": "true", + "follow": "false", + "share": "true", + "draw_times": 1, + "expire_at": "2021-07-15 11:59:59" + }, + { + "url": "https://www.bilibili.com/blackboard/activity-nA2uYrmpfA.html", + "title": "哥斯拉金刚你站谁", + "description": "活动期间每天分享页面,新增一次机会。", + "sid": "f851e27a-858e-11eb-8597-246e966235d8", + "login": "true", + "follow": "false", + "share": "true", + "draw_times": 2, + "expire_at": "2021-05-23 11:59:59" + }, + { + "url": "https://www.bilibili.com/blackboard/activity-QEya2bouhQ.html", + "title": "春日嗑糖大作战", + "description": "活动期间每天分享页面,新增一次机会。", + "sid": "20b0dfaf-8bcd-11eb-8597-246e966235d8", + "login": "true", + "follow": "false", + "share": "true", + "draw_times": 2, + "expire_at": "2021-05-05 23:59:59" + }, + { + "url": "https://www.bilibili.com/blackboard/gaming_on_bilibili.html", + "title": "上B站看电竞", + "description": "活动期间每天分享页面,新增一次机会。", + "sid": "0b87bd83-8565-11eb-8597-246e966235d8", + "login": "true", + "follow": "false", + "share": "true", + "draw_times": 1, + "expire_at": "2021-05-30 23:59:59", + "remarks": "时间不名,暂定一个月。" + }, + { + "url": "https://www.bilibili.com/blackboard/activity-aT7zphkwF1.html", + "title": "初夏逛吃大会", + "description": "活动期间每天分享页面,新增一次机会。", + "sid": "01aff78a-9e1a-11eb-8597-246e966235d8", + "login": "true", + "follow": "false", + "share": "true", + "draw_times": 1, + "expire_at": "2021-06-10 23:59:59" + }, + { + "url": "https://www.bilibili.com/blackboard/activity-oGiWFe0YTz.html", + "title": "京东超市超有young", + "description": "活动期间每天分享页面,新增一次机会。", + "sid": "4eb728e2-a0d7-11eb-8597-246e966235d8", + "login": "true", + "follow": "false", + "share": "true", + "draw_times": 1, + "expire_at": "2021-04-25 23:59:59" + } + ] +} \ No newline at end of file diff --git a/data/capsule_infos.json b/data/capsule_infos.json new file mode 100644 index 0000000..09fcb31 --- /dev/null +++ b/data/capsule_infos.json @@ -0,0 +1,77 @@ +{ + "pool": "https://api.live.bilibili.com/xlive/web-ucenter/v1/capsule/get_pool_detail?pool_id=131&_=1616829671726", + "v3": "https://api.live.bilibili.com/xlive/web-ucenter/v1/capsule/get_capsule_info_v3?id=79&from=web&_=1608110093802", + "remarks": "有需要可以自己添加,或者提pr", + "data": [ + { + "_url": "注释: 活动地址", + "url": "https://www.bilibili.com/blackboard/activity-c_fu2inm-.html", + "_title": "注释: 活动标题", + "title": "原神1.4版本「风花的邀约」激励计划", + "_description": "注释: 活动描述", + "description": "每日在原神分区任意直播间观看,20分钟1张、1小时2张、2小时3张,每日最高6张。", + "_room_id": "注释: 活动直播间,如果为0,则取分区随机一个", + "room_id": 0, + "_area_id": "注释: 子分区id", + "area_id": 321, + "_parent_area_id": "注释: 主分区id", + "parent_area_id": 3, + "_coin_id": "注释: 抽奖id", + "coin_id": 112, + "_watch_time": "注释: 观看时长 单位秒", + "watch_time": 7320, + "_draw_times": "注释: 抽奖次数", + "draw_times": 1, + "_expire_at": "注释: 活动有效时间", + "expire_at": "2021-04-27 23:59:59" + }, + { + "url": "https://www.bilibili.com/blackboard/activity-MHRISE.html", + "title": "《怪物猎人:崛起》直播挑战", + "description": "每日在怪物猎人分区任意直播间观看,10分钟1张、30分钟3张、60分钟5张", + "room_id": 0, + "area_id": 412, + "parent_area_id": 6, + "coin_id": 121, + "watch_time": 3720, + "draw_times": 2, + "expire_at": "2021-04-26 23:59:59" + }, + { + "url": "https://live.bilibili.com/11218604", + "title": "2021PCL春季赛观赛任务", + "description": "每日在PGI直播间观看,10、15、30", + "room_id": 11218604, + "area_id": 0, + "parent_area_id": 2, + "coin_id": 129, + "watch_time": 3720, + "draw_times": 3, + "expire_at": "2021-05-31 23:59:59" + }, + { + "url": "https://live.bilibili.com/6", + "title": "2021LPL春季赛", + "description": "每日在LOL直播间观看,5分钟1张,15分钟1张", + "room_id": 7734200, + "area_id": 86, + "parent_area_id": 2, + "coin_id": 76, + "watch_time": 3720, + "draw_times": 3, + "expire_at": "2021-05-31 23:59:59" + }, + { + "url": "https://live.bilibili.com/23", + "title": "PEI亚洲邀请赛", + "description": "每日在PEL直播间观看,5分钟1张", + "room_id": 13242892, + "area_id": 0, + "parent_area_id": 2, + "coin_id": 109, + "watch_time": 3720, + "draw_times": 2, + "expire_at": "2021-05-31 23:59:59" + } + ] +} \ No newline at end of file diff --git a/data/filter_words.json b/data/filter_words.json new file mode 100644 index 0000000..b5eb8ec --- /dev/null +++ b/data/filter_words.json @@ -0,0 +1,324 @@ +{ + "MaterialObject": { + "sensitive": [ + "测试", + "加密", + "test", + "TEST", + "钓鱼", + "炸鱼", + "调试", + "123", + "1111", + "测试", + "測試", + "Test", + "测一测", + "ce-shi", + "test", + "T-E-S-T", + "lala", + "我是抽奖标题", + "压测", + "測一測", + "t-e-s-t" + ] + }, + "Anchor": { + "default": [ + "拉黑", + "黑名单", + "脸皮厚", + "没有奖品", + "无奖", + "脸皮厚", + "ceshi", + "测试", + "测试", + "测试", + "脚本", + "抽奖号", + "星段位", + "星段位", + "圣晶石", + "圣晶石", + "水晶", + "水晶", + "万兴神剪手", + "万兴神剪手", + "自付邮费", + "自付邮费", + "test", + "Test", + "TEST", + "加密", + "QQ", + "测试", + "測試", + "VX", + "vx", + "ce", + "shi", + "这是一个", + "lalall", + "第一波", + "第二波", + "第三波", + "测试用", + "抽奖标题", + "策是", + "房间抽奖", + "CESHI", + "ceshi", + "奖品A", + "奖品B", + "奖品C", + "硬币", + "无奖品", + "白名单", + "我是抽奖", + "0.1", + "五毛二", + "一分", + "一毛", + "0.52", + "0.66", + "0.01", + "0.77", + "0.16", + "照片", + "穷", + "0.5", + "0.88", + "双排", + "1毛", + "1分", + "1角", + "P口罩", + "素颜", + "写真", + "图包", + "五毛", + "一角", + "冥币", + "自拍", + "日历", + "0.22", + "加速器", + "越南盾", + "毛", + "分", + "限", + "0.", + "角", + "〇点", + "①元", + "一起玩", + "不包邮", + "邮费", + "续期卡", + "儿时", + "闪宠", + "大师球", + "一元", + "两元", + "两块", + "赛车", + "代币", + "一块", + "一局", + "好友位", + "通话", + "首胜", + "代金券", + "辣条", + "补贴", + "抵用券", + "主播素颜照", + "武器箱棺材板", + "游戏道具", + "优惠券", + "日元", + "发音课", + "壹元", + "零点", + "舰长五折券", + "上车", + "没有钱", + "女装", + "肥宅快乐水", + "哥斯拉", + "公主连结", + "pokemmo", + "宝可>梦", + "明日方舟", + "雪碧", + "公主连接", + "专属头衔", + "FF14", + "韩元", + "空洞骑士", + "老婆饼", + "稀世时装", + "洛克衣服", + "帮过图", + "证件照", + "自抽号", + "晶耀之星", + "伊洛纳", + "〇.", + "②元", + "③元", + "0·", + "繁华美化", + "喵喵喵", + "闪伊布", + "①圆", + "o点", + "金达摩", + "嗷呜", + "游戏位", + "S-追光者", + "OWL", + "勾玉", + "跟yo宝游戏", + "三元", + "怡宝", + "蛋闪迷>你冰", + "哥伦比亚比索", + "油条", + "代金卷", + "小堂包", + "返现券", + "上舰", + "舰长", + "开舰", + "帅照", + "靓照", + "1元红包", + "红包3.3元", + "5.2元红包", + "2.33元红包", + "测试", + "钓鱼", + "炸鱼", + "黑屋", + "脚本", + "空气", + "大航海", + "上船", + "舰长", + "返现", + "抵用", + "代金", + "上车", + "上反船", + "照片", + "素颜", + "自拍", + "皂片", + "开舰", + "上舰", + "自画像", + "封面", + "取关", + "美照", + "随机照", + "女装照", + "日常照", + "好友", + "给主播", + "照骗", + "连麦", + "情书", + "一局", + "舰涨优惠卷", + "开黑", + "test", + "Test", + "金币", + "元宝", + "代打", + "上分", + "上段", + "台历", + "一毛", + "五毛", + "王者荣耀", + "玩游戏", + "encrypt", + "壁纸", + "相片", + "排位", + "语音", + "车位", + "网剧", + "一起玩", + "一次", + "专属头衔", + "手游", + "宠物", + "蒸汽", + "月饼", + "加速", + "挂件", + "渔夫", + "小黑屋", + "头像", + "许愿码", + "电池", + "赛车", + "保底", + "代币", + "越南盾", + "网点", + "机器", + "话梅", + "志愿", + "令牌", + "永久", + "第五人格", + "大蒜", + "唢呐", + "皇冠", + "徽章", + "铜牌", + "动物园", + "植物", + "钻石", + "宝石", + "尖叫", + "扭蛋机", + "点播", + "数字版月历", + "点歌一首", + "体验", + "点歌", + "三次取关", + "大航海", + "3块钱之前的巨款", + "礼金" + ] + }, + "CapsuleLottery": { + "default": [ + "谢谢参与", + "未中奖", + "辣条" + ] + }, + "ActivityLottery": { + "default": [ + "谢谢参与", + "未中奖", + "辣条" + ] + }, + "Notice": { + "default": [ + "谢谢参与", + "未中奖", + "辣条" + ] + } +} \ No newline at end of file diff --git a/index.php b/index.php index ecdd05f..c977764 100644 --- a/index.php +++ b/index.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ @@ -14,6 +14,6 @@ require 'vendor/autoload.php'; $filename = isset($argv[1]) ? $argv[1] : 'user.conf'; -$app = new BiliHelper\Core\App(); -$app->load(__DIR__, $filename); +$app = new BiliHelper\Core\App(__DIR__); +$app->load($filename); $app->start(); diff --git a/src/core/App.php b/src/core/App.php index cb1df0c..fccc7d2 100644 --- a/src/core/App.php +++ b/src/core/App.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Core; @@ -19,21 +19,23 @@ class App { /** * App constructor. + * @param string $app_path */ - public function __construct() + public function __construct(string $app_path) { + define('APP_CONF_PATH', $app_path . "/conf/"); + define('APP_DATA_PATH', $app_path . "/data/"); + define('APP_LOG_PATH', $app_path . "/log/"); (new Env())->inspect_configure()->inspect_extension(); } /** * @use 加载配置 - * @param $app_path * @param string $load_file * @return $this */ - public function load($app_path, $load_file = 'user.conf') + public function load($load_file = 'user.conf') { - define('APP_PATH', $app_path); Config::load($load_file); return $this; } @@ -66,15 +68,14 @@ class App $plugins = [ 'Login', 'Schedule', - 'MasterSite', + 'MainSite', 'Daily', 'ManGa', - 'Match', + 'GameMatch', 'ActivityLottery', 'Competition', 'Heart', - 'Task', -// 'Silver', + 'DailyTask', 'Barrage', 'Silver2Coin', 'Judge', @@ -92,7 +93,10 @@ class App 'AnchorRaffle', 'AwardRecord', 'Statistics', - 'Forward' + 'Forward', + 'CapsuleLottery', + // 'Silver', + ]; foreach ($plugins as $plugin) { $this->newTask($plugin); diff --git a/src/core/Config.php b/src/core/Config.php index dc52fa1..1b8ce99 100644 --- a/src/core/Config.php +++ b/src/core/Config.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Core; @@ -49,7 +49,7 @@ class Config */ private static function _load($load_file) { - $config_path = str_replace("\\", "/", APP_PATH . "/conf/{$load_file}"); + $config_path = str_replace("\\", "/", APP_CONF_PATH . $load_file); if (!is_file($config_path)) { die("配置文件 {$load_file} 加载错误,请参照文档添加配置文件!"); } diff --git a/src/core/Curl.php b/src/core/Curl.php index 67c42aa..cd47744 100644 --- a/src/core/Curl.php +++ b/src/core/Curl.php @@ -5,17 +5,20 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Core; +use BiliHelper\Tool\Generator; + class Curl { private static $client; private static $async_opt; private static $results = []; private static $result = []; + private static $buvid = ''; /** * @use POST请求 @@ -150,7 +153,7 @@ class Curl 'timeout' => $timeout, ), ); - $result = @file_get_contents($url, false, stream_context_create($options)); + $result = $url ? @file_get_contents($url, false, stream_context_create($options)) : null; Log::debug($result); return $result ? $result : null; } @@ -189,8 +192,10 @@ class Curl // var_dump($e->getRequest()); if ($e->hasResponse()) var_dump($e->getResponse()); } catch (\Exception $e) { + // $e->getHandlerContext() // var_dump($e); } + Log::warning("Target -> URL: {$url} METHOD: {$method}"); Log::warning("CURl -> RETRY: {$retry} ERROR: {$e->getMessage()} ERRNO: {$e->getCode()} STATUS: Waiting for recovery!"); sleep(15); } @@ -227,14 +232,20 @@ class Curl */ private static function getHeaders(string $os = 'app', array $headers = []): array { + if (!self::$buvid) { + self::$buvid = Generator::buvid(); + } $app_headers = [ + 'env' => 'prod', + 'APP-KEY' => 'android', + 'Buvid' => self::$buvid, '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)', - 'User-Agent' => 'Mozilla/5.0 BiliDroid/6.3.0 (bbcallen@gmail.com) os/android model/MuMu mobi_app/android build/6030600 channel/bili innerVer/6030600 osVer/6.0.1 network/2', + 'User-Agent' => 'Mozilla/5.0 BiliDroid/6.20.5 (bbcallen@gmail.com) os/android model/MuMu mobi_app/android build/6205500 channel/bili innerVer/6205500 osVer/6.0.1 network/2', // 'Referer' => 'https://live.bilibili.com/', ]; $pc_headers = [ @@ -242,11 +253,11 @@ class Curl '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', + 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.30 Safari/537.36 Edg/90.0.818.8', // 'Referer' => 'https://live.bilibili.com/', ]; $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', + 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4450.0 Safari/537.36', ]; $default_headers = isset(${$os . "_headers"}) ? ${$os . "_headers"} : $other_headers; if (in_array($os, ['app', 'pc']) && getenv('COOKIE') != "") { diff --git a/src/core/Env.php b/src/core/Env.php index ade0ce6..6015082 100644 --- a/src/core/Env.php +++ b/src/core/Env.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Core; @@ -13,7 +13,7 @@ namespace BiliHelper\Core; class Env { private $app_name = 'BiliHelper Personal'; - private $app_version = '0.6.7.*'; + private $app_version = '0.8.1.*'; /** * Env constructor. @@ -56,8 +56,11 @@ class Env die("Please run this script from command line ."); } if (version_compare(PHP_VERSION, '7.0.0', '<')) { - die("Please upgrade PHP version >= 7.0.0 ."); + die("Please upgrade PHP version > 7.0.0 ."); } +// if (version_compare(PHP_VERSION, '8.0.0', '>')) { +// die("Please upgrade PHP version < 8.0.0 ."); +// } return $this; } } diff --git a/src/core/Log.php b/src/core/Log.php index d0db464..10d6a55 100644 --- a/src/core/Log.php +++ b/src/core/Log.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Core; @@ -13,7 +13,6 @@ namespace BiliHelper\Core; use Monolog\Logger; use Monolog\Handler\StreamHandler; use Bramus\Monolog\Formatter\ColoredLineFormatter; -use function GuzzleHttp\Psr7\str; class Log { @@ -27,7 +26,7 @@ class Log return self::$instance; } - protected static function configureInstance() + private static function configureInstance() { $logger = new Logger('BH'); $handler = new StreamHandler('php://stdout', getenv('APP_DEBUG') == 'true' ? Logger::DEBUG : Logger::INFO); @@ -46,8 +45,11 @@ class Log private static function writeLog($type, $message) { - if (getenv('APP_WRITELOG') == 'true') { - $path = './' . getenv("APP_WRITELOGPATH") . '/'; + if (getenv('APP_WRITE_LOG') == 'true') { + if ($type == 'DEBUG' && getenv("APP_DEBUG") != 'true') { + return; + } + $path = './' . getenv("APP_LOG_PATH") . '/'; if (!file_exists($path)) { mkdir($path); chmod($path, 0777); @@ -57,7 +59,12 @@ class Log $data = $date . ' Log.' . $type . ' ' . $message . PHP_EOL; file_put_contents($filename, $data, FILE_APPEND); } - return; + } + + private static function backtrace(): string + { + $backtraces = debug_backtrace(); + return "(" . pathinfo(basename($backtraces[1]['file']))['filename'] . ") => "; } public static function debug($message, array $context = []) @@ -68,7 +75,7 @@ class Log public static function info($message, array $context = []) { - $message = self::prefix() . $message; + $message = self::prefix() . self::backtrace() . $message; self::writeLog('INFO', $message); self::getLogger()->addInfo($message, $context); self::callback(Logger::INFO, 'INFO', $message); @@ -76,7 +83,7 @@ class Log public static function notice($message, array $context = []) { - $message = self::prefix() . $message; + $message = self::prefix() . self::backtrace() . $message; self::writeLog('NOTICE', $message); self::getLogger()->addNotice($message, $context); self::callback(Logger::NOTICE, 'NOTICE', $message); @@ -84,7 +91,7 @@ class Log public static function warning($message, array $context = []) { - $message = self::prefix() . $message; + $message = self::prefix() . self::backtrace() . $message; self::writeLog('WARNING', $message); self::getLogger()->addWarning($message, $context); self::callback(Logger::WARNING, 'WARNING', $message); @@ -92,7 +99,7 @@ class Log public static function error($message, array $context = []) { - $message = self::prefix() . $message; + $message = self::prefix() . self::backtrace() . $message; self::writeLog('ERROR', $message); self::getLogger()->addError($message, $context); self::callback(Logger::ERROR, 'ERROR', $message); diff --git a/src/plugin/ActivityLottery.php b/src/plugin/ActivityLottery.php index 644044a..2da9266 100644 --- a/src/plugin/ActivityLottery.php +++ b/src/plugin/ActivityLottery.php @@ -5,61 +5,118 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; use BiliHelper\Core\Curl; +use BiliHelper\Util\AllotTasks; use BiliHelper\Util\TimeLock; class ActivityLottery { use TimeLock; + use AllotTasks; - private static $activity_infos = [ - '2020SummerMusic' => [ - 'sid' => 'dd83a687-c800-11ea-8597-246e966235d8', - 'action_types' => [3, 4], // 4 关注 3 分享 - 'referer' => 'https://www.bilibili.com/blackboard/2020SummerMusic.html', - 'expired_time' => 1599318000, // 2020-09-05 23:00:00 - 'draw_times' => 3, - ], - ]; + private static $repository = APP_DATA_PATH . 'activity_infos.json'; public static function run() { if (self::getLock() > time() || getenv('USE_ACTIVITY') == 'false') { return; } - self::workTask(); - self::setLock(self::timing(5) + mt_rand(1, 180)); + self::allotTasks(); + if (self::workTask()) { + self::setLock(5 * 60); + } else { + self::setLock(self::timing(5) + mt_rand(1, 180)); + } } /** - * @use 运行任务 + * @use 分配任务 + * @return bool + * @throws \JsonDecodeStream\Exception\CollectorException + * @throws \JsonDecodeStream\Exception\ParserException + * @throws \JsonDecodeStream\Exception\SelectorException + * @throws \JsonDecodeStream\Exception\TokenizerException + */ + private static function allotTasks(): bool + { + if (self::$work_status['work_updated'] == date("Y/m/d")) { + return false; + } + $parser = self::loadJsonData(); + foreach ($parser->items('data[]') as $act) { + // 活动无效 + if (is_null($act->sid)) { + continue; + } + // 活动实效过期 + if (strtotime($act->expire_at) < time()) { + continue; + } + // init + if ($act->login == 'true') { + self::pushTask('login', $act); + } + // follow + if ($act->follow == 'true') { + self::pushTask('follow', $act); + } + // share + if ($act->share == 'true') { + self::pushTask('share', $act); + } + // draw_times + $arr = range(1, $act->draw_times); + foreach ($arr as $_) { + self::pushTask('draw', $act); + } + } + self::$work_status['work_updated'] = date("Y/m/d"); + Log::info('活动抽奖任务分配完成 ' . count(self::$tasks) . ' 个任务待执行'); + return true; + } + + /** + * @use 执行任务 + * @return bool */ private static function workTask() { - foreach (self::$activity_infos as $title => $activity) { - // 过期 - if ($activity['expired_time'] < time()) { - Log::info('跳过'); - continue; - } - Log::info("启动 {$title} 抽奖任务"); - self::initTimes($activity['sid'], $activity['referer']); - foreach ($activity['action_types'] as $action_type) { - sleep(1); - self::addTimes($activity['sid'], $activity['referer'], $action_type); - } - foreach (range(1, $activity['draw_times']) as $num) { - sleep(5); - self::doLottery($activity['sid'], $activity['referer'], $num); - } + if (self::$work_status['work_completed'] == date("Y/m/d")) { + return false; } + $task = self::pullTask(); + // 所有任务完成 标记 + if (!$task) { + self::$work_status['work_completed'] = date("Y/m/d"); + return false; + } + Log::info("执行 {$task['act']->title} #{$task['operation']} 任务"); + // 执行任务 + switch ($task['operation']) { + case 'login': + self::initTimes($task['act']->sid, $task['act']->url); + break; + case 'follow': + self::addTimes($task['act']->sid, $task['act']->url, 4); + break; + case 'share': + self::addTimes($task['act']->sid, $task['act']->url, 3); + break; + case 'draw': + self::doLottery($task['act']->sid, $task['act']->url, 0); + break; + default: + Log::info("当前 {$task['act']->title} #{$task['operation']} 任务不存在哦"); + break; + } + return true; } @@ -81,11 +138,12 @@ class ActivityLottery ]; $raw = Curl::get('pc', $url, $payload, $headers); $de_raw = json_decode($raw, true); - Log::info("获取抽奖机会 {$raw}"); // {"code":0,"message":"0","ttl":1,"data":{"times":2}} if ($de_raw['code'] == 0) { + Log::info("获取抽奖机会成功 {$raw}"); return true; } + Log::warning("获取抽奖机会失败 {$raw}"); return false; } @@ -104,6 +162,7 @@ class ActivityLottery 'referer' => $referer ]; $user_info = User::parseCookies(); + // $action_type 4 关注 3 分享 $payload = [ 'sid' => $sid, 'action_type' => $action_type, @@ -143,7 +202,10 @@ class ActivityLottery $de_raw = json_decode($raw, true); Log::notice("开始抽奖#{$num} {$raw}"); // {"code":0,"message":"0","ttl":1,"data":[{"id":0,"mid":4133274,"num":1,"gift_id":1152,"gift_name":"硬币x6","gift_type":0,"img_url":"https://i0.hdslb.com/bfs/activity-plat/static/b6e956937ee4aefd1e19c01283145fc0/JQ9Y9-KCm_w96_h102.png","type":5,"ctime":1596255796,"cid":0}]} + // {"code":0,"message":"0","ttl":1,"data":[{"id":0,"mid":4133274,"ip":0,"num":1,"gift_id":0,"gift_name":"未中奖0","gift_type":0,"img_url":"","type":1,"ctime":1616825625,"cid":0,"extra":{}}]} if ($de_raw['code'] == 0) { + $result = "活动->{$referer} 获得->{$de_raw['data'][0]['gift_name']}"; + Notice::push('activity_lottery', $result); return true; } return false; diff --git a/src/plugin/AloneTcpClient.php b/src/plugin/AloneTcpClient.php index 6a9d1fa..a4c6e3d 100644 --- a/src/plugin/AloneTcpClient.php +++ b/src/plugin/AloneTcpClient.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; diff --git a/src/plugin/AnchorRaffle.php b/src/plugin/AnchorRaffle.php index 06b6bf0..5d44579 100644 --- a/src/plugin/AnchorRaffle.php +++ b/src/plugin/AnchorRaffle.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -13,14 +13,13 @@ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; use BiliHelper\Core\Curl; use BiliHelper\Util\TimeLock; +use BiliHelper\Util\BaseRaffle; class AnchorRaffle extends BaseRaffle { const ACTIVE_TITLE = '天选时刻'; const ACTIVE_SWITCH = 'USE_ANCHOR'; - use TimeLock; - protected static $wait_list = []; protected static $finish_list = []; protected static $all_list = []; @@ -129,23 +128,7 @@ class AnchorRaffle extends BaseRaffle */ protected static function filterPrizeWords(string $prize_name): bool { - $default_words = [ - '拉黑', '黑名单', '脸皮厚', '没有奖品', '无奖', '脸皮厚', 'ceshi', '测试', '测试', '测试', '脚本', - '抽奖号', '星段位', '星段位', '圣晶石', '圣晶石', '水晶', '水晶', '万兴神剪手', '万兴神剪手', - '自付邮费', '自付邮费', 'test', 'Test', 'TEST', '加密', 'QQ', '测试', '測試', 'VX', 'vx', - 'ce', 'shi', '这是一个', 'lalall', '第一波', '第二波', '第三波', '测试用', '抽奖标题', '策是', - '房间抽奖', 'CESHI', 'ceshi', '奖品A', '奖品B', '奖品C', '硬币', '无奖品', '白名单', '我是抽奖', - '0.1', '五毛二', '一分', '一毛', '0.52', '0.66', '0.01', '0.77', '0.16', '照片', '穷', '0.5', - '0.88', '双排', '1毛', '1分', '1角', 'P口罩', '素颜', '写真', '图包', '五毛', '一角', '冥币', - '自拍', '日历', '0.22', '加速器', '越南盾','毛','分','限','0.','角','〇点','①元', - '一起玩','不包邮','邮费','续期卡','儿时','闪宠','大师球','一元','两元','两块','赛车', - '代币','一块','一局','好友位','通话','首胜','代金券','辣条','补贴','抵用券','主播素颜照', - '武器箱棺材板','游戏道具','优惠券','日元','发音课','壹元','零点','舰长五折券','上车', - '没有钱','女装','肥宅快乐水','哥斯拉','公主连结','pokemmo','宝可>梦','明日方舟','雪碧','公主连接', - '专属头衔','FF14','韩元','空洞骑士','老婆饼','稀世时装','洛克衣服','帮过图','证件照','自抽号', - '晶耀之星','伊洛纳','〇.','②元','③元','0·','繁华美化','喵喵喵','闪伊布','①圆','o点','金达摩','嗷呜', - '游戏位','S-追光者','OWL','勾玉','跟yo宝游戏','三元','怡宝','蛋闪迷>你冰','哥伦比亚比索','油条' - ]; + $default_words = self::$store->get("Anchor.default"); $custom_words = empty(getenv('ANCHOR_FILTER_WORDS')) ? [] : explode(',', getenv('ANCHOR_FILTER_WORDS')); $total_words = array_merge($default_words, $custom_words); foreach ($total_words as $word) { @@ -237,7 +220,7 @@ class AnchorRaffle extends BaseRaffle ]); } $results = Curl::async('app', $url, $tasks); - # print_r($results); + // print_r($results); return $results; } diff --git a/src/plugin/AwardRecord.php b/src/plugin/AwardRecord.php index c3c4c45..3a30903 100644 --- a/src/plugin/AwardRecord.php +++ b/src/plugin/AwardRecord.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; diff --git a/src/plugin/Barrage.php b/src/plugin/Barrage.php index e5c0ddd..dd8d674 100644 --- a/src/plugin/Barrage.php +++ b/src/plugin/Barrage.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -40,12 +40,31 @@ class Barrage self::setLock(30); } + /** + * @use 获取颜文字信息 + * @return string + */ + private static function getEmojiMsg(): string + { + $emoji_list = [ + "(⌒▽⌒)", "( ̄▽ ̄)", "(=・ω・=)", "(`・ω・´)", "(〜 ̄△ ̄)〜", "(・∀・)", + "(°∀°)ノ", "( ̄3 ̄)", "╮( ̄▽ ̄)╭", "_(:3」∠)_", "( ´_ゝ`)", "←_←", "→_→", + "(<_<)", "(>_>)", "(;¬_¬)", '("▔□▔)/', "(゚Д゚≡゚д゚)!?", "Σ(゚д゚;)", "Σ(  ̄□ ̄||)", + "(´;ω;`)", "(/TДT)/", "(^・ω・^ )", "(。・ω・。)", "(● ̄(エ) ̄●)", "ε=ε=(ノ≧∇≦)ノ", + "(´・_・`)", "(-_-#)", "( ̄へ ̄)", "( ̄ε(# ̄) Σ", "ヽ(`Д´)ノ", "(#-_-)┯━┯", + "(╯°口°)╯(┴—┴", "←◡←", "( ♥д♥)", "Σ>―(〃°ω°〃)♡→", "⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", + "(╬゚д゚)▄︻┻┳═一", "・*・:≡( ε:)", "(打卡)", "(签到)" + ]; + shuffle($emoji_list); + return $emoji_list[array_rand($emoji_list)]; + } + /** - * @use 获取随机弹幕 - * @return \Exception|false|mixed|string|null + * @use 获取一言api消息 + * @return string */ - private static function getMsgInfo() + private static function getMsgInfo():string { /** * 整理一部分API,收集于网络,侵权麻烦联系我删除. @@ -57,15 +76,13 @@ class Barrage 'https://api.ly522.com/yan.php?format=text', 'https://v1.hitokoto.cn/?encode=text', 'https://api.jysafe.cn/yy/', - 'https://api.ooopn.com/yan/api.php?type=text', 'https://api.imjad.cn/hitokoto/', 'https://www.ly522.com/hitokoto/', 'https://api.guoch.xyz/', - 'http://www.ooomg.cn/dutang/', 'https://api.gushi.ci/rensheng.txt', 'https://api.itswincer.com/hitokoto/v2/', - 'http://api.dsecret.com/yiyan/', - 'https://api.xygeng.cn/dailywd/api/api.php', +// 'http://www.ooomg.cn/dutang/', +// 'http://api.dsecret.com/yiyan/', ]; shuffle($apis); try { @@ -81,7 +98,7 @@ class Barrage return $data; } } catch (\Exception $e) { - return $e; + return $e->getMessage(); } } @@ -120,10 +137,10 @@ class Barrage //TODO 短期功能 有需求就修改 $response = self::sendMsg($info); if (isset($response['code']) && $response['code'] == 0) { - Log::info('活跃弹幕发送成功!'); + Log::info('弹幕发送成功'); return true; } else { - Log::warning("活跃代码发送失败, CODE -> {$response['code']} MSG -> {$response['msg']} "); + Log::warning("弹幕发送失败, CODE -> {$response['code']} MSG -> {$response['msg']} "); return false; } } diff --git a/src/plugin/CapsuleLottery.php b/src/plugin/CapsuleLottery.php new file mode 100644 index 0000000..fac5266 --- /dev/null +++ b/src/plugin/CapsuleLottery.php @@ -0,0 +1,164 @@ + time() || getenv('USE_CAPSULE') == 'false') { + return; + } + self::allotTasks(); + if (self::workTask()) { + self::setLock(self::$interval); + } else { + self::setLock(self::timing(5) + mt_rand(1, 180)); + } + } + + + /** + * @use 分配任务 + * @return bool + * @throws \JsonDecodeStream\Exception\CollectorException + * @throws \JsonDecodeStream\Exception\ParserException + * @throws \JsonDecodeStream\Exception\SelectorException + * @throws \JsonDecodeStream\Exception\TokenizerException + */ + private static function allotTasks(): bool + { + if (self::$work_status['work_updated'] == date("Y/m/d")) { + return false; + } + $parser = self::loadJsonData(); + foreach ($parser->items('data[]') as $act) { + // 活动无效 + if (is_null($act->coin_id)) { + continue; + } + // 活动实效过期 + if (strtotime($act->expire_at) < time()) { + continue; + } + if ($act->room_id == 0) { + $room_ids = Live::getAreaRoomList($act->parent_area_id, $act->area_id); + $act->room_id = array_shift($room_ids); + } + // 观看时间 + self::pushTask('watch', $act, true); + // 抽奖次数 + $arr = range(1, $act->draw_times); + foreach ($arr as $_) { + self::pushTask('draw', $act); + } + } + self::$work_status['work_updated'] = date("Y/m/d"); + Log::info('扭蛋抽奖任务分配完成 ' . count(self::$tasks) . ' 个任务待执行'); + return true; + } + + + /** + * @use 执行任务 + * @return bool + */ + private static function workTask(): bool + { + if (self::$work_status['work_completed'] == date("Y/m/d")) { + return false; + } + $task = self::pullTask(); + // 所有任务完成 标记 + if (!$task) { + self::$work_status['work_completed'] = date("Y/m/d"); + return false; + } + if ($task['time'] && is_null(self::$work_status['estimated_time'])) { + self::$work_status['estimated_time'] = time() + $task['act']->watch_time; + } + Log::info("执行 {$task['act']->title} #{$task['operation']} 任务"); + // 执行任务 + switch ($task['operation']) { + case 'watch': + $interval = self::xliveHeartBeatTask($task['act']->room_id,999,999); + self::$interval = $interval == 0 ? 60 : $interval; + break; + case 'draw': + self::doLottery($task['act']->coin_id, $task['act']->url, 0); + break; + default: + Log::info("当前 {$task['act']->title} #{$task['operation']} 任务不存在哦"); + break; + } + return true; + } + + /** + * @use 开始抽奖 + * @param int $coin_id + * @param string $referer + * @param int $num + * @return bool + */ + private static function doLottery(int $coin_id, string $referer, int $num): bool + { + $url = 'https://api.live.bilibili.com/xlive/web-ucenter/v1/capsule/open_capsule_by_id'; + $headers = [ + 'origin' => 'https://live.bilibili.com', + 'referer' => $referer + ]; + $user_info = User::parseCookies(); + $payload = [ + 'id' => $coin_id, + 'count' => 1, + 'type' => 1, + 'platform' => 'web', + '_' => time() * 1000, + 'csrf' => $user_info['token'], + 'csrf_token' => $user_info['token'], + 'visit_id' => '' + ]; + $raw = Curl::post('pc', $url, $payload, $headers); + $de_raw = json_decode($raw, true); + Log::notice("开始抽奖#{$num} {$raw}"); + // {"code":0,"message":"0","ttl":1,"data":{"status":false,"isEntity":false,"info":{"coin":1},"awards":[{"name":"谢谢参与","num":1,"text":"谢谢参与 X 1","web_url":"https://i0.hdslb.com/bfs/live/b0fccfb3bac2daae35d7e514a8f6d31530b9add2.png","mobile_url":"https://i0.hdslb.com/bfs/live/b0fccfb3bac2daae35d7e514a8f6d31530b9add2.png","usage":{"text":"很遗憾您未能中奖","url":""},"type":32,"expire":"当天","gift_type":"7290bc172e5ab9e151eb141749adb9dd","gift_value":""}],"text":["谢谢参与 X 1"],"isExCode":false}} + if ($de_raw['code'] == 0) { + $result = "活动->{$referer} 获得->{$de_raw['data']['text'][0]}"; + Notice::push('capsule_lottery', $result); + return true; + } + return false; + + } + +} \ No newline at end of file diff --git a/src/plugin/Competition.php b/src/plugin/Competition.php index aba68e9..8475ae0 100644 --- a/src/plugin/Competition.php +++ b/src/plugin/Competition.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; diff --git a/src/plugin/Daily.php b/src/plugin/Daily.php index 6a149ba..5a85b1c 100644 --- a/src/plugin/Daily.php +++ b/src/plugin/Daily.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; diff --git a/src/plugin/Task.php b/src/plugin/DailyTask.php similarity index 85% rename from src/plugin/Task.php rename to src/plugin/DailyTask.php index 1a88d12..3274374 100644 --- a/src/plugin/Task.php +++ b/src/plugin/DailyTask.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -14,7 +14,7 @@ use BiliHelper\Core\Log; use BiliHelper\Core\Curl; use BiliHelper\Util\TimeLock; -class Task +class DailyTask { use TimeLock; @@ -69,13 +69,14 @@ class Task $payload = []; $data = Curl::get('app',$url, Sign::common($payload)); $data = json_decode($data, true); - + // {"code":1011040,"message":"今日已签到过,无法重复签到","ttl":1,"data":null} + // {"code":0,"message":"0","ttl":1,"data":{"text":"3000点用户经验,2根辣条,50根辣条","specialText":"","allDays":31,"hadSignDays":20,"isBonusDay":1}} if (isset($data['code']) && $data['code']) { - Log::warning('签到失败', ['msg' => $data['message']]); + Log::warning("签到失败: {$data['message']}"); } else { - Log::info('签到成功'); + Log::info("签到成功: {$data['data']['text']}"); // 推送签到信息 - Notice::push('todaySign', $data['message']); + Notice::push('todaySign', $data['data']['text']); } } diff --git a/src/plugin/DataTreating.php b/src/plugin/DataTreating.php index df78789..1faef3b 100644 --- a/src/plugin/DataTreating.php +++ b/src/plugin/DataTreating.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; diff --git a/src/plugin/Forward.php b/src/plugin/Forward.php index fc12b7e..5e93fb0 100644 --- a/src/plugin/Forward.php +++ b/src/plugin/Forward.php @@ -1,10 +1,24 @@ 'web', + 'parent_area_id' => $parent_area_id, + 'area_id' => $area_id, + 'sort_type' => 'online', + 'page' => $page + ]; + $raw = Curl::get('other', $url, $payload); + $de_raw = json_decode($raw, true); + $room_ids = []; + + if ($de_raw['code'] == 0) { + foreach ($de_raw['data']['list'] as $room) { + array_push($room_ids, $room['roomid']); + } + } + return $room_ids; + } } diff --git a/src/plugin/Login.php b/src/plugin/Login.php index 2a385f8..0fd04ab 100644 --- a/src/plugin/Login.php +++ b/src/plugin/Login.php @@ -4,7 +4,7 @@ * Website: https://mudew.com/ * Author: Lkeme * License: The MIT License - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -13,6 +13,7 @@ use BiliHelper\Core\Log; use BiliHelper\Core\Curl; use BiliHelper\Core\Config; use BiliHelper\Util\TimeLock; +use BiliHelper\Tool\Common; class Login @@ -199,9 +200,10 @@ class Login private static function publicKeyEnc($plaintext): string { Log::info('正在载入公钥'); - $url = 'https://passport.bilibili.com/api/oauth2/getKey'; + // $url = 'https://passport.bilibili.com/api/oauth2/getKey'; + $url = 'https://passport.bilibili.com/x/passport-login/web/key'; $payload = []; - $data = Curl::post('app', $url, Sign::login($payload)); + $data = Curl::get('app', $url, Sign::login($payload)); $data = json_decode($data, true); if (isset($data['code']) && $data['code']) { Log::error('公钥载入失败', ['msg' => $data['message']]); @@ -209,6 +211,7 @@ class Login } else { Log::info('公钥载入完毕'); } + // print_r($data); $public_key = $data['data']['key']; $hash = $data['data']['hash']; openssl_public_encrypt($hash . $plaintext, $crypt, $public_key); @@ -291,7 +294,8 @@ class Login private static function accountLogin(string $validate = '', string $challenge = '', string $mode = '账密模式') { Log::info("尝试{$mode}登录"); - $url = 'https://passport.bilibili.com/api/v3/oauth2/login'; +// $url = 'https://passport.bilibili.com/api/v3/oauth2/login'; + $url = 'https://passport.bilibili.com/x/passport-login/oauth2/login'; $payload = [ 'seccode' => $validate ? "{$validate}|jordan" : '', 'validate' => $validate, @@ -308,17 +312,31 @@ class Login // {"ts":1593079322,"code":-629,"message":"账号或者密码错误"} // {"ts":1593082268,"code":-105,"data":{"url":"https://passport.bilibili.com/register/verification.html?success=1>=b6e5b7fad7ecd37f465838689732e788&challenge=7efb4020b22c0a9ac124aea624e11ad7&ct=1&hash=7fa8282ad93047a4d6fe6111c93b308a"},"message":"验证码错误"} // {"ts":1593082432,"code":0,"data":{"status":0,"token_info":{"mid":123456,"access_token":"123123","refresh_token":"123123","expires_in":2592000},"cookie_info":{"cookies":[{"name":"bili_jct","value":"123123","http_only":0,"expires":1595674432},{"name":"DedeUserID","value":"123456","http_only":0,"expires":1595674432},{"name":"DedeUserID__ckMd5","value":"123123","http_only":0,"expires":1595674432},{"name":"sid","value":"bd6aagp7","http_only":0,"expires":1595674432},{"name":"SESSDATA","value":"6d74d850%123%2Cf0e36b61","http_only":1,"expires":1595674432}],"domains":[".bilibili.com",".biligame.com",".bigfunapp.cn"]},"sso":["https://passport.bilibili.com/api/v2/sso","https://passport.biligame.com/api/v2/sso","https://passport.bigfunapp.cn/api/v2/sso"]}} + // {"ts":1610254019,"code":0,"data":{"status":2,"url":"https://passport.bilibili.com/account/mobile/security/managephone/phone/verify?tmp_token=2bc5dd260df7158xx860565fxx0d5311&requestId=dffcfxx052fe11xxa9c8e2667739c15c&source=risk","message":"您的账号存在高危异常行为,为了您的账号安全,请验证手机号后登录帐号"}} // https://passport.bilibili.com/mobile/verifytel_h5.html switch ($de_raw['code']) { case 0: - // 正常登录 - Log::info("{$mode}登录成功"); - $access_token = $de_raw['data']['token_info']['access_token']; - $refresh_token = $de_raw['data']['token_info']['refresh_token']; - self::saveConfig('ACCESS_TOKEN', $access_token); - self::saveConfig('REFRESH_TOKEN', $refresh_token); - self::saveCookie($de_raw); - Log::info('信息配置完毕'); + // 二次判断 + switch ($de_raw['data']['status']) { + case 0: + // 正常登录 + Log::info("{$mode}登录成功"); + $access_token = $de_raw['data']['token_info']['access_token']; + $refresh_token = $de_raw['data']['token_info']['refresh_token']; + self::saveConfig('ACCESS_TOKEN', $access_token); + self::saveConfig('REFRESH_TOKEN', $refresh_token); + self::saveCookie($de_raw); + Log::info('信息配置完毕'); + break; + case 2: + // 异常高危 + Log::error('登录失败', ['msg' => $de_raw['data']['message']]); + die(); + default: + Log::error('登录失败', ['msg' => '未知错误: ' . $de_raw['data']['message']]); + die(); + break; + } break; case -105: // 需要验证码 @@ -457,7 +475,7 @@ class Login private static function saveConfig(string $key, string $value, $hide = true) { Config::put($key, $value); - Log::info(" > {$key}: " . ($hide ? substr_replace($value, '********', mb_strlen($value) / 2, 8) : $value)); + Log::info(" > {$key}: " . ($hide ? Common::replaceStar($value,4,4) : $value)); } /** diff --git a/src/plugin/MasterSite.php b/src/plugin/MainSite.php similarity index 99% rename from src/plugin/MasterSite.php rename to src/plugin/MainSite.php index 1d39356..20e4e55 100644 --- a/src/plugin/MasterSite.php +++ b/src/plugin/MainSite.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -14,13 +14,13 @@ use BiliHelper\Core\Log; use BiliHelper\Core\Curl; use BiliHelper\Util\TimeLock; -class MasterSite +class MainSite { use TimeLock; public static function run() { - if (self::getLock() > time() || getenv('USE_MASTER_SITE') == 'false') { + if (self::getLock() > time() || getenv('USE_MAIN_SITE') == 'false') { return; } if (self::watchAid() && self::shareAid() && self::coinAdd()) { diff --git a/src/plugin/ManGa.php b/src/plugin/ManGa.php index 89ecea8..0c5cfdb 100644 --- a/src/plugin/ManGa.php +++ b/src/plugin/ManGa.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; diff --git a/src/plugin/MaterialObject.php b/src/plugin/MaterialObject.php index b1aab3b..0c49331 100644 --- a/src/plugin/MaterialObject.php +++ b/src/plugin/MaterialObject.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -13,10 +13,13 @@ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; use BiliHelper\Core\Curl; use BiliHelper\Util\TimeLock; +use BiliHelper\Util\FilterWords; + class MaterialObject { use TimeLock; + use FilterWords; private static $invalid_aids = []; private static $start_aid = 0; @@ -24,21 +27,19 @@ class MaterialObject public static function run() { - if (getenv('USE_MO') == 'false') { + if (getenv('USE_LIVE_BOX') == 'false') { return; } self::setPauseStatus(); if (self::getLock() > time()) { return; } - // TODO 优化计算AID算法 - self::calcAid(470, 770); + self::calcAid(700, 900); $lottery_list = self::fetchLottery(); self::drawLottery($lottery_list); self::setLock(mt_rand(6, 10) * 60); } - /** * @use 过滤抽奖Title * @param string $title @@ -46,10 +47,8 @@ class MaterialObject */ private static function filterTitleWords(string $title): bool { - $sensitive_words = [ - '测试', '加密', 'test', 'TEST', '钓鱼', '炸鱼', '调试', "123", "1111", "测试", "測試", "Test", - "测一测", "ce-shi", "test", "T-E-S-T", "lala", "我是抽奖标题", "压测", "測一測", "t-e-s-t" - ]; + self::loadJsonData(); + $sensitive_words = self::$store->get("MaterialObject.sensitive"); foreach ($sensitive_words as $word) { if (strpos($title, $word) !== false) { return true; @@ -204,6 +203,7 @@ class MaterialObject */ private static function calcAid($min, $max): bool { + // TODO 优化计算AID算法 if (self::$end_aid != 0 && self::$start_aid != 0) { return false; } diff --git a/src/plugin/Notice.php b/src/plugin/Notice.php index f092e83..30b9374 100644 --- a/src/plugin/Notice.php +++ b/src/plugin/Notice.php @@ -5,22 +5,18 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; use BiliHelper\Core\Curl; -use BiliHelper\Util\TimeLock; +use BiliHelper\Util\FilterWords; class Notice { - protected static $type = ''; - protected static $result = ''; - protected static $uname = ''; - protected static $sckey = ''; - + use FilterWords; /** * @use 推送消息 @@ -29,17 +25,14 @@ class Notice */ public static function push(string $type, string $result = '') { - if (getenv('USE_SC') == 'false' || getenv('SC_KEY') == "") { + if (getenv('USE_NOTIFY') == 'false') { return; } - self::$type = $type; - self::$result = $result; - self::$sckey = getenv('SC_KEY'); - self::$uname = User::userInfo() ? getenv('APP_UNAME') : getenv('APP_USER'); if (self::filterResultWords($result)) { return; } - self::sendInfoHandle(); + $uname = User::userInfo() ? getenv('APP_UNAME') : getenv('APP_USER'); + self::sendInfoHandle($type, $uname, $result); } /** @@ -49,8 +42,9 @@ class Notice */ private static function filterResultWords(string $result): bool { - $default_words = []; - $custom_words = empty(getenv('SC_FILTER_WORDS')) ? [] : explode(',', getenv('SC_FILTER_WORDS')); + self::loadJsonData(); + $default_words = self::$store->get("Notice.default");; + $custom_words = empty(getenv('NOTIFY_FILTER_WORDS')) ? [] : explode(',', getenv('NOTIFY_FILTER_WORDS')); $total_words = array_merge($default_words, $custom_words); foreach ($total_words as $word) { if (strpos($result, $word) !== false) { @@ -60,97 +54,280 @@ class Notice return false; } + /** * @use 处理信息 + * @param string $type + * @param string $uname + * @param string $result * @return bool */ - private static function sendInfoHandle(): bool + private static function sendInfoHandle(string $type, string $uname, string $result): bool { $now_time = date('Y-m-d H:i:s'); - switch (self::$type) { + switch ($type) { case 'update': $info = [ 'title' => '程序更新通知', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 程序更新通知' . self::$result, + 'content' => "[{$now_time}] 用户: {$uname} 程序更新通知: {$result}" ]; break; case 'anchor': $info = [ 'title' => '天选时刻获奖记录', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 在天选时刻中获得: ' . self::$result, + 'content' => "[{$now_time}] 用户: {$uname} 在天选时刻中获得: {$result}" ]; break; case 'raffle': $info = [ 'title' => '实物奖励获奖纪录', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 在实物奖励中获得: ' . self::$result, + 'content' => "[{$now_time}] 用户: {$uname} 在实物奖励中获得: {$result}" ]; break; case 'gift': $info = [ 'title' => '活动礼物获奖纪录', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 在活动礼物中获得: ' . self::$result, + 'content' => "[{$now_time}] 用户: {$uname} 在活动礼物中获得: {$result}" ]; break; case 'storm': $info = [ 'title' => '节奏风暴获奖纪录', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 在节奏风暴中获得: ' . self::$result, + 'content' => "[{$now_time}] 用户: {$uname} 在节奏风暴中获得: {$result}" ]; break; case 'cookieRefresh': $info = [ 'title' => 'Cookie刷新', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 刷新Cookie: ' . self::$result, + 'content' => "[{$now_time}] 用户: {$uname} 刷新Cookie: {$result}" ]; break; case 'todaySign': $info = [ 'title' => '每日签到', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 签到: ' . self::$result, + 'content' => "[{$now_time}] 用户: {$uname} 签到: {$result}" ]; break; case 'banned': $info = [ 'title' => '任务小黑屋', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 小黑屋: ' . self::$result, + 'content' => "[{$now_time}] 用户: {$uname} 小黑屋: {$result}" ]; break; case 'error': $info = [ - 'title' => '程序错误', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 程序运行错误: ' . self::$result, + 'title' => '程序运行错误', + 'content' => "[{$now_time}] 用户: {$uname} 错误详情: {$result}" ]; break; case 'key_expired': $info = [ 'title' => '监控KEY异常', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 监控KEY到期或者错误,请及时查错或续期后重试哦~', + 'content' => "[{$now_time}] 用户: {$uname} 监控KEY到期或者错误,请及时查错或续期后重试哦~" + ]; + break; + case 'capsule_lottery': + $info = [ + 'title' => '直播扭蛋抽奖活动', + 'content' => "[{$now_time}] 用户: {$uname} 详情: {$result}" + ]; + break; + case 'activity_lottery': + $info = [ + 'title' => '主站九宫格抽奖活动', + 'content' => "[{$now_time}] 用户: {$uname} 详情: {$result}" ]; break; default: $info = [ 'title' => '推送消息异常记录', - 'content' => '[' . $now_time . ']' . ' 用户: ' . self::$uname . ' 推送消息key错误' . self::$type . self::$result, + 'content' => "[{$now_time}] 用户: {$uname} 推送消息key错误: {$type}->{$result}" ]; break; } - self::scSend($info); + self::sendLog($info); return true; } + /** + * @use 推送消息 + * @param array $info + */ + private static function sendLog(array $info) + { + if (getenv('NOTIFY_SCTKEY')) { + self::sctSend($info); + } + if (getenv('NOTIFY_SCKEY')) { + self::scSend($info); + } + if (getenv('NOTIFY_TELE_BOTTOKEN') && getenv('NOTIFY_TELE_CHATID')) { + self::teleSend($info); + } + if (getenv('NOTIFY_DINGTALK_TOKEN')) { + self::dingTalkSend($info); + } + if (getenv('NOTIFY_PUSHPLUS_TOKEN')) { + self::pushPlusSend($info); + } + if (getenv('NOTIFY_CQ_URL') && getenv('NOTIFY_CQ_TOKEN') && getenv('NOTIFY_CQ_QQ')) { + self::goCqhttp($info); + } + } + /** - * @use ServerChan发送信息 + * @use DingTalkbot推送 + * @doc https://developers.dingtalk.com/document/app/document-upgrade-notice#/serverapi2/qf2nxq + * @param array $info + */ + private static function dingTalkSend(array $info) + { + Log::info('使用DingTalk机器人推送消息'); + $url = 'https://oapi.dingtalk.com/robot/send?access_token=' . getenv('NOTIFY_DINGTALK_TOKEN'); + $payload = [ + 'msgtype' => 'markdown', + 'markdown' => [ + 'title' => $info['title'], + 'content' => $info['content'], + ] + ]; + $headers = [ + 'Content-Type' => 'application/json;charset=utf-8' + ]; + $raw = Curl::put('other', $url, $payload, $headers); + $de_raw = json_decode($raw, true); + if ($de_raw['errcode'] == 0) { + Log::info("推送消息成功: {$de_raw['errmsg']}"); + } else { + Log::warning("推送消息失败: {$raw}"); + } + } + + + /** + * @use TeleBot推送 + * @doc https://core.telegram.org/bots/api#sendmessage + * @param array $info + */ + private static function teleSend(array $info) + { + Log::info('使用Tele机器人推送消息'); + $url = 'https://api.telegram.org/bot' . getenv('NOTIFY_TELE_BOTTOKEN'); + $payload = [ + 'method' => 'sendMessage', + 'chat_id' => getenv('NOTIFY_TELE_CHATID'), + 'text' => $info['content'] + ]; + $raw = Curl::post('other', $url, $payload); + $de_raw = json_decode($raw, true); + if (array_key_exists('message_id', $de_raw)) { + Log::info("推送消息成功: {$de_raw['message_id']}"); + } else { + Log::info("推送消息失败: {$raw}"); + } + } + + + /** + * @use ServerChan推送 + * @use https://sc.ftqq.com/ * @param array $info */ private static function scSend(array $info) { - $url = "https://sc.ftqq.com/" . self::$sckey . ".send?text=" . urlencode($info['title']) . "&desp=" . urlencode($info['content']); - $data = Curl::request('get', $url); - if (is_null($data)) { - Log::warning('Server酱推送信息失败,请检查!'); - }; + Log::info('使用ServerChan推送消息'); + $url = 'https://sc.ftqq.com/' . getenv('NOTIFY_SCKEY') . '.send'; + $payload = [ + 'text' => $info['title'], + 'desp' => $info['content'], + ]; + $raw = Curl::post('other', $url, $payload); + $de_raw = json_decode($raw, true); + + if ($de_raw['errno'] == 0) { + Log::info("推送消息成功: {$de_raw['errmsg']}"); + } else { + Log::warning("推送消息失败: {$raw}"); + } } + + + /** + * @use ServerChan(Turbo)推送 + * @doc https://sct.ftqq.com/ + * @param array $info + */ + private static function sctSend(array $info) + { + Log::info('使用ServerChan(Turbo)推送消息'); + $url = 'https://sctapi.ftqq.com/' . getenv('NOTIFY_SCTKEY') . '.send'; + $payload = [ + 'text' => $info['title'], + 'desp' => $info['content'], + ]; + $raw = Curl::post('other', $url, $payload); + $de_raw = json_decode($raw, true); + // {'message': '[AUTH]用户不存在或者权限不足', 'code': 40001, 'info': '用户不存在或者权限不足', 'args': [None]} + // {'code': 0, 'message': '', 'data': {'pushid': 'xxxx', 'readkey': 'xxxxx', 'error': 'SUCCESS', 'errno': 0}} + if ($de_raw['code'] == 0) { + Log::info("推送消息成功: {$de_raw['data']['pushid']}"); + } else { + Log::warning("推送消息失败: {$raw}"); + } + } + + /** + * @use PushPlus酱推送 + * @doc http://www.pushplus.plus/doc/ + * @param array $info + */ + private static function pushPlusSend(array $info) + { + Log::info('使用PushPlus酱推送消息'); + $url = 'http://www.pushplus.plus/send'; + $payload = [ + 'token' => getenv('NOTIFY_PUSHPLUS_TOKEN'), + 'title' => $info['title'], + 'content' => $info['content'] + ]; + $headers = [ + 'Content-Type' => 'application/json' + ]; + $raw = Curl::put('other', $url, $payload, $headers); + // {"code":200,"msg":"请求成功","data":"发送消息成功"} + $de_raw = json_decode($raw, true); + if ($de_raw['code'] == 200) { + Log::info("推送消息成功: {$de_raw['data']}"); + } else { + Log::warning("推送消息失败: {$raw}"); + } + } + + + /** + * @use GO-CQHTTP推送 + * @doc https://docs.go-cqhttp.org/api/ + * @param array $info + */ + private static function goCqhttp(array $info) + { + Log::info('使用GoCqhttp推送消息'); + $url = getenv('NOTIFY_CQ_URL'); + $payload = [ + 'access_token' => getenv('NOTIFY_CQ_TOKEN'), + 'user_id' => getenv('NOTIFY_CQ_QQ'), + 'message' => $info['content'] + ]; + $raw = Curl::get('other', $url, $payload); + // {"data":{"message_id":123456},"retcode":0,"status":"ok"} + $de_raw = json_decode($raw, true); + if ($de_raw['retcode'] == 0) { + Log::info("推送消息成功: {$de_raw['status']}"); + } else { + Log::warning("推送消息失败: {$raw}"); + } + } + } \ No newline at end of file diff --git a/src/plugin/PkRaffle.php b/src/plugin/PkRaffle.php index c6bb135..3cce163 100644 --- a/src/plugin/PkRaffle.php +++ b/src/plugin/PkRaffle.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -13,6 +13,7 @@ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; use BiliHelper\Core\Curl; use BiliHelper\Util\TimeLock; +use BiliHelper\Util\BaseRaffle; class PkRaffle extends BaseRaffle @@ -20,8 +21,6 @@ class PkRaffle extends BaseRaffle const ACTIVE_TITLE = '大乱斗'; const ACTIVE_SWITCH = 'USE_PK'; - use TimeLock; - protected static $wait_list = []; protected static $finish_list = []; protected static $all_list = []; @@ -95,7 +94,7 @@ class PkRaffle extends BaseRaffle ]); } $results = Curl::async('app', $url, $tasks); - # print_r($results); + // print_r($results); return $results; } diff --git a/src/plugin/Schedule.php b/src/plugin/Schedule.php index 4563193..ce75d22 100644 --- a/src/plugin/Schedule.php +++ b/src/plugin/Schedule.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -23,7 +23,7 @@ class Schedule private static $unlock_timers = []; private static $sleep_section = []; // 日常类 - private static $fillable = ['Login', 'Schedule', 'Daily', 'Judge', 'MasterSite', 'GiftSend', 'Task', 'Silver2Coin', 'ManGa', 'Match', 'GroupSignIn', 'AwardRecord', 'Statistics']; + private static $fillable = ['Login', 'Schedule', 'Daily', 'Judge', 'MainSite', 'GiftSend', 'DailyTask', 'Silver2Coin', 'ManGa', 'GameMatch', 'GroupSignIn', 'AwardRecord', 'Statistics']; // 任务类 private static $guarded_first = ['Barrage', 'GiftHeart', 'Silver', 'MaterialObject']; // 监控类 @@ -32,6 +32,8 @@ class Schedule private static $guarded_third = ['StormRaffle', 'GuardRaffle', 'PkRaffle', 'GiftRaffle', 'AnchorRaffle']; // 特殊 老爷处理 private static $guarded_fourth = ['Heart']; + // 暂定不做处理,后期看情况再定 + private static $release = ['ActivityLottery', 'SmallHeart', 'Competition', 'SmallHeart', 'Forward', 'CapsuleLottery']; public static function run() { diff --git a/src/plugin/Sign.php b/src/plugin/Sign.php index e4aeb81..fca7219 100644 --- a/src/plugin/Sign.php +++ b/src/plugin/Sign.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -55,8 +55,8 @@ class Sign 'access_key' => getenv('ACCESS_TOKEN'), 'actionKey' => 'appkey', 'appkey' => $appkey, - 'build' => 6030600, - 'channel'=>'bili', + 'build' => 6205500, + 'channel' => 'bili', 'device' => 'phone', 'mobi_app' => 'android', 'platform' => 'android', @@ -84,7 +84,7 @@ class Sign 'access_key' => getenv('ACCESS_TOKEN'), 'actionKey' => 'appkey', 'appkey' => $appkey, - 'build' => 5511400, + 'build' => 6205500, 'device' => 'android', 'mobi_app' => 'android', 'platform' => 'android', diff --git a/src/plugin/Silver.php b/src/plugin/Silver.php index c49e5a9..80e8a46 100644 --- a/src/plugin/Silver.php +++ b/src/plugin/Silver.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; diff --git a/src/plugin/Silver2Coin.php b/src/plugin/Silver2Coin.php index d351903..64a3a9c 100644 --- a/src/plugin/Silver2Coin.php +++ b/src/plugin/Silver2Coin.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -46,7 +46,7 @@ class Silver2Coin if (!$de_raw['code'] && $de_raw['msg'] == '兑换成功') { Log::info('[APP]银瓜子兑换硬币: ' . $de_raw['msg']); } elseif ($de_raw['code'] == 403) { - Log::info('[APP]银瓜子兑换硬币: ' . $de_raw['msg']); + Log::warning('[APP]银瓜子兑换硬币: ' . $de_raw['msg']); } else { Log::warning('[APP]银瓜子兑换硬币: ' . $de_raw['msg']); return false; diff --git a/src/plugin/SmallHeart.php b/src/plugin/SmallHeart.php index 8ffa1ec..328d5fa 100644 --- a/src/plugin/SmallHeart.php +++ b/src/plugin/SmallHeart.php @@ -5,39 +5,31 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; -use BiliHelper\Core\Log; -use BiliHelper\Core\Curl; use BiliHelper\Util\TimeLock; -use BiliHelper\Tool\Generator; +use BiliHelper\Util\XliveHeartBeat; class SmallHeart { use TimeLock; + use XliveHeartBeat; - private static $enc_server = null; // 加密服务器 配置文件 - - private static $hb_payload = []; // 心跳请求数据 - private static $hb_headers = []; // 心跳请求头 - - private static $hb_count = 0; // 心跳次数 max 24 - private static $hb_room_info = []; // 心跳带勋章房间信息 private static $fans_medals = []; // 全部勋章 private static $grey_fans_medals = []; // 灰色勋章 - private static $metal_lock = 0; // 勋章时间锁 - - private static $heartbeat_interval = 60; // 每次跳动时间 + private static $interval = 60; // 每次跳动时间 + private static $total_time = 0; + private static $metal = null; public static function run() { - if (!self::init()) { + if (getenv('USE_HEARTBEAT') == 'false') { return; } @@ -47,44 +39,16 @@ class SmallHeart } if (self::getLock() < time()) { self::heartBeat(); - if (self::$hb_count >= 200) { - self::resetVar(); + if (self::$total_time >= 12000) { + self::$total_time = 0; + self::$metal = null; self::setLock(self::timing(2)); } else { - self::setLock(self::$heartbeat_interval); + self::setLock(self::$interval); } } } - /** - * @use 重置变量 - */ - private static function resetVar() - { - self::$hb_payload = []; // 心跳请求数据 - self::$hb_headers = []; // 心跳请求头 - - self::$hb_count = 0; // 心跳次数 max 24 - self::$hb_room_info = []; // 心跳带勋章房间信息 - - self::$heartbeat_interval = 60; // 跳变时间 - } - - /** - * @use init - * @return bool - */ - private static function init(): bool - { - if (getenv('USE_HEARTBEAT') == 'false' || getenv('ENC_SERVER') == '') { - return false; - } - if (is_null(self::$enc_server)) { - self::$enc_server = getenv('ENC_SERVER'); - } - return true; - } - /** * @use 勋章处理 @@ -111,8 +75,6 @@ class SmallHeart Live::sendGift($grey_fans_medal, $gift, 1); } } - - } @@ -124,159 +86,14 @@ class SmallHeart if (empty(self::$fans_medals)) { return; } - if (empty(self::$hb_room_info)) { - $metal = self::$fans_medals[array_rand(self::$fans_medals)]; - $room_info = Live::webGetRoomInfo($metal['roomid']); + if (is_null(self::$metal)){ + self::$metal = self::$fans_medals[array_rand(self::$fans_medals)]; } - if (self::$hb_count == 0) { - $e_data = self::eHeartBeat($room_info['data']['room_info']); - if (!$e_data['status']) { - // 错误级别 - return; - } - self::$hb_count += 1; - self::$hb_payload = $e_data['payload']; - self::$hb_headers = $e_data['headers']; - return; + $interval = self::xliveHeartBeatTask(self::$metal['roomid'], 999, 999); + if ($interval != 0) { + self::$total_time += $interval; } - $x_data = self::xHeartBeat(self::$hb_count); - if (!$x_data['status']) { - // 错误级别 - self::resetVar(); - return; - } - self::$hb_count += 1; - } - - /** - * @use E心跳 - * @param array $room_info - * @param int $index - * @return array|bool[] - */ - private static function eHeartBeat(array $room_info, $index = 0): array - { - $url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/E'; - $headers = [ - 'Content-Type' => 'application/x-www-form-urlencoded', - 'Origin' => 'https://live.bilibili.com', - 'Referer' => 'https://live.bilibili.com/' . $room_info['room_id'], - ]; - $user_info = User::parseCookies(); - $payload = [ - 'id' => json_encode([$room_info['parent_area_id'], $room_info['area_id'], $index, $room_info['room_id']], true), - 'device' => json_encode([ - Generator::hash(), Generator::uuid4() - ], true), - 'ts' => time() * 1000, - 'is_patch' => 0, - 'heart_beat' => [], - 'ua' => 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0', - 'csrf_token' => $user_info['token'], - 'csrf' => $user_info['token'], - 'visit_id' => '' - ]; - $raw = Curl::post('pc', $url, $payload, $headers); - $de_raw = json_decode($raw, true); - // {"code":0,"message":"0","ttl":1,"data":{"timestamp":1595342828,"heartbeat_interval":300,"secret_key":"seacasdgyijfhofiuxoannn","secret_rule":[2,5,1,4],"patch_status":2}} - if ($de_raw['code'] != 0) { - Log::warning("小心心礼物E-{$index}心跳失败"); - return ['status' => false]; - } - Log::info("小心心礼物E-{$index}心跳成功"); - // Log::info($raw); - $payload['ets'] = $de_raw['data']['timestamp']; - $payload['secret_key'] = $de_raw['data']['secret_key']; - $payload['heartbeat_interval'] = $de_raw['data']['heartbeat_interval']; - $payload['secret_rule'] = $de_raw['data']['secret_rule']; - // 自动跳变时间 - self::$heartbeat_interval = $de_raw['data']['heartbeat_interval']; - return [ - 'status' => true, - 'payload' => $payload, - 'headers' => $headers, - ]; - } - - /** - * @use X心跳 - * @param int $index - * @return array|bool[] - */ - private static function xHeartBeat(int $index = 1): array - { - $s_data = self::encParamS($index); - $s = $s_data['s']; - $t = $s_data['payload']; - - $url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/X'; - $user_info = User::parseCookies(); - $payload = [ - 's' => $s, - 'id' => $t['id'], - 'device' => $t['device'], - 'ets' => $t['ets'], - 'benchmark' => $t['benchmark'], - 'time' => $t['time'], - 'ts' => $t['ts'], - 'ua' => $t['ua'], - 'csrf_token' => $user_info['token'], - 'csrf' => $user_info['token'], - 'visit_id' => '' - ]; - // print_r($payload); - $raw = Curl::post('pc', $url, $payload, self::$hb_headers); - $de_raw = json_decode($raw, true); - # {"code":0,"message":"0","ttl":1,"data":{"heartbeat_interval":300,"timestamp":1595346846,"secret_rule":[2,5,1,4],"secret_key":"seacasdgyijfhofiuxoannn"}} - if ($de_raw['code'] != 0) { - Log::warning("小心心礼物X-{$index}心跳失败"); - return ['status' => false]; - } - self::$hb_payload['ets'] = $de_raw['data']['timestamp']; - self::$hb_payload['secret_key'] = $de_raw['data']['secret_key']; - self::$hb_payload['heartbeat_interval'] = $de_raw['data']['heartbeat_interval']; - // 自动跳变时间 - self::$heartbeat_interval = $de_raw['data']['heartbeat_interval']; - Log::info("小心心礼物X-{$index}心跳成功"); - return ['status' => true]; - } - - - /** - * @use 加密参数S - * @param int $index - * @return array - */ - private static function encParamS(int $index): array - { - // 转换index - $temp = json_decode(self::$hb_payload['id'], true); - $temp[2] += 1; - self::$hb_payload['id'] = json_encode($temp, true); - // 加密部分 - $payload = [ - 't' => [ - 'id' => self::$hb_payload['id'], - 'device' => self::$hb_payload['device'], - 'ets' => self::$hb_payload['ets'], - 'benchmark' => self::$hb_payload['secret_key'], - 'time' => self::$hb_payload['heartbeat_interval'], - 'ts' => time() * 1000, - 'ua' => self::$hb_payload['ua'] - ], - 'r' => self::$hb_payload['secret_rule'] - ]; - $headers = [ - 'Content-Type' => 'application/json', - ]; - $data = Curl::put('other', self::$enc_server, $payload, $headers); - $de_raw = json_decode($data, true); - Log::info("S参数加密 {$de_raw['s']}"); - - return [ - 's' => $de_raw['s'], - 'payload' => $payload['t'] - ]; + self::$interval = $interval == 0 ? 60 : $interval; } diff --git a/src/plugin/Statistics.php b/src/plugin/Statistics.php index fd7551c..594014c 100644 --- a/src/plugin/Statistics.php +++ b/src/plugin/Statistics.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -32,7 +32,7 @@ class Statistics } self::outputResult(); - self::setLock(5 * 60); + self::setLock(20 * 60); } diff --git a/src/plugin/StormRaffle.php b/src/plugin/StormRaffle.php index bd50464..ab239f1 100644 --- a/src/plugin/StormRaffle.php +++ b/src/plugin/StormRaffle.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -13,14 +13,13 @@ namespace BiliHelper\Plugin; use BiliHelper\Core\Log; use BiliHelper\Core\Curl; use BiliHelper\Util\TimeLock; +use BiliHelper\Util\BaseRaffle; class StormRaffle extends BaseRaffle { const ACTIVE_TITLE = '节奏风暴'; const ACTIVE_SWITCH = 'USE_STORM'; - use TimeLock; - protected static $wait_list = []; protected static $finish_list = []; protected static $all_list = []; diff --git a/src/plugin/User.php b/src/plugin/User.php index f08c470..21031d0 100644 --- a/src/plugin/User.php +++ b/src/plugin/User.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; diff --git a/src/plugin/ZoneTcpClient.php b/src/plugin/ZoneTcpClient.php index 87744a0..2d6bc8c 100644 --- a/src/plugin/ZoneTcpClient.php +++ b/src/plugin/ZoneTcpClient.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ namespace BiliHelper\Plugin; @@ -495,15 +495,17 @@ class ZoneTcpClient throw new Exception("Socket error: [{$ret}] [{$length}]"); } $cnt = 0; - $r = array($socket); $w = NULL; $e = NULL; while ($cnt++ < 60) { + // reset read fdset when timeout + $r = array($socket); $ret = socket_select($r, $w, $e, 1); if ($ret === false) throw new Exception("Socket error: ret == false"); if ($ret) break; + Log::debug("Socket debug: select timeout" . PHP_EOL); } // TODO unable to read from socket[104]: Connection reset by peer $ret = socket_recv($socket, $buffer, $length, 0); diff --git a/src/tool/BvToAv.php b/src/tool/BvToAv.php index 9ca26c6..64f740d 100644 --- a/src/tool/BvToAv.php +++ b/src/tool/BvToAv.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 * Source: https://github.com/anhao/bv2av/ */ diff --git a/src/tool/Common.php b/src/tool/Common.php new file mode 100644 index 0000000..0738cd4 --- /dev/null +++ b/src/tool/Common.php @@ -0,0 +1,52 @@ + $len) { + $start = 1; + } + if ($end != 0 && $end > $len) { + $end = $len - 2; + } + $endStart = $len - $end; + $top = mb_substr($str, 0, $start, $charset); + $bottom = ""; + if ($endStart > 0) { + $bottom = mb_substr($str, $endStart, $end, $charset); + } + $len = $len - mb_strlen($top, $charset); + $len = $len - mb_strlen($bottom, $charset); + $newStr = $top; + for ($i = 0; $i < $len; $i++) { + $newStr .= $dot; + } + $newStr .= $bottom; + return $newStr; + } + + +} + + diff --git a/src/tool/DumpMemory.php b/src/tool/DumpMemory.php index a99dca9..a5615d4 100644 --- a/src/tool/DumpMemory.php +++ b/src/tool/DumpMemory.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 * Source: https://github.com/anhao/bv2av/ */ diff --git a/src/tool/Faker.php b/src/tool/Faker.php new file mode 100644 index 0000000..d1e7c41 --- /dev/null +++ b/src/tool/Faker.php @@ -0,0 +1,238 @@ += $except) { + $result++; + } + return $result; + } + + /** + * Replaces * signs with random numbers and letters and special characters + * + * @example $faker->asciify(''********'); // "s5'G!uC3" + * + * @param string $string String that needs to bet parsed + * @return string + */ + public static function asciify($string = '****') + { + return preg_replace_callback('/\*/u', 'static::randomAscii', $string); + } + + + /** + * @example 'fY4èHdZv68' + */ + public function password($minLength = 6, $maxLength = 20) + { + $pattern = str_repeat('*', $this->numberBetween($minLength, $maxLength)); + + return $this->asciify($pattern); + } + + + /** + * @example '237.149.115.38' + */ + public function ipv4() + { + return long2ip(mt_rand(0, 1) == 0 ? mt_rand(-2147483648, -2) : mt_rand(16777216, 2147483647)); + } + + /** + * @example '35cd:186d:3e23:2986:ef9f:5b41:42a4:e6f1' + */ + public function ipv6() + { + $res = array(); + for ($i = 0; $i < 8; $i++) { + $res [] = dechex(mt_rand(0, "65535")); + } + + return join(':', $res); + } + + /** + * @example '10.1.1.17' + */ + public static function localIpv4() + { + if (static::numberBetween(0, 1) === 0) { + // 10.x.x.x range + return long2ip(static::numberBetween(ip2long("10.0.0.0"), ip2long("10.255.255.255"))); + } + + // 192.168.x.x range + return long2ip(static::numberBetween(ip2long("192.168.0.0"), ip2long("192.168.255.255"))); + } + + /** + * @example '32:F1:39:2F:D6:18' + */ + public static function macAddress() + { + for ($i = 0; $i < 6; $i++) { + $mac[] = sprintf('%02X', static::numberBetween(0, 0xff)); + } + $mac = implode(':', $mac); + + return $mac; + } + + protected static function toAscii($string) + { + static $arrayFrom, $arrayTo; + + if (empty($arrayFrom)) { + $transliterationTable = array( + 'IJ' => 'I', 'Ö' => 'O', 'Œ' => 'O', 'Ü' => 'U', 'ä' => 'a', 'æ' => 'a', + 'ij' => 'i', 'ö' => 'o', 'œ' => 'o', 'ü' => 'u', 'ß' => 's', 'ſ' => 's', + 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', + 'Æ' => 'A', 'Ā' => 'A', 'Ą' => 'A', 'Ă' => 'A', 'Ç' => 'C', 'Ć' => 'C', + 'Č' => 'C', 'Ĉ' => 'C', 'Ċ' => 'C', 'Ď' => 'D', 'Đ' => 'D', 'È' => 'E', + 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ē' => 'E', 'Ę' => 'E', 'Ě' => 'E', + 'Ĕ' => 'E', 'Ė' => 'E', 'Ĝ' => 'G', 'Ğ' => 'G', 'Ġ' => 'G', 'Ģ' => 'G', + 'Ĥ' => 'H', 'Ħ' => 'H', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', + 'Ī' => 'I', 'Ĩ' => 'I', 'Ĭ' => 'I', 'Į' => 'I', 'İ' => 'I', 'Ĵ' => 'J', + 'Ķ' => 'K', 'Ľ' => 'K', 'Ĺ' => 'K', 'Ļ' => 'K', 'Ŀ' => 'K', 'Ł' => 'L', + 'Ñ' => 'N', 'Ń' => 'N', 'Ň' => 'N', 'Ņ' => 'N', 'Ŋ' => 'N', 'Ò' => 'O', + 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ø' => 'O', 'Ō' => 'O', 'Ő' => 'O', + 'Ŏ' => 'O', 'Ŕ' => 'R', 'Ř' => 'R', 'Ŗ' => 'R', 'Ś' => 'S', 'Ş' => 'S', + 'Ŝ' => 'S', 'Ș' => 'S', 'Š' => 'S', 'Ť' => 'T', 'Ţ' => 'T', 'Ŧ' => 'T', + 'Ț' => 'T', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ū' => 'U', 'Ů' => 'U', + 'Ű' => 'U', 'Ŭ' => 'U', 'Ũ' => 'U', 'Ų' => 'U', 'Ŵ' => 'W', 'Ŷ' => 'Y', + 'Ÿ' => 'Y', 'Ý' => 'Y', 'Ź' => 'Z', 'Ż' => 'Z', 'Ž' => 'Z', 'à' => 'a', + 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ā' => 'a', 'ą' => 'a', 'ă' => 'a', + 'å' => 'a', 'ç' => 'c', 'ć' => 'c', 'č' => 'c', 'ĉ' => 'c', 'ċ' => 'c', + 'ď' => 'd', 'đ' => 'd', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', + 'ē' => 'e', 'ę' => 'e', 'ě' => 'e', 'ĕ' => 'e', 'ė' => 'e', 'ƒ' => 'f', + 'ĝ' => 'g', 'ğ' => 'g', 'ġ' => 'g', 'ģ' => 'g', 'ĥ' => 'h', 'ħ' => 'h', + 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ī' => 'i', 'ĩ' => 'i', + 'ĭ' => 'i', 'į' => 'i', 'ı' => 'i', 'ĵ' => 'j', 'ķ' => 'k', 'ĸ' => 'k', + 'ł' => 'l', 'ľ' => 'l', 'ĺ' => 'l', 'ļ' => 'l', 'ŀ' => 'l', 'ñ' => 'n', + 'ń' => 'n', 'ň' => 'n', 'ņ' => 'n', 'ʼn' => 'n', 'ŋ' => 'n', 'ò' => 'o', + 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ø' => 'o', 'ō' => 'o', 'ő' => 'o', + 'ŏ' => 'o', 'ŕ' => 'r', 'ř' => 'r', 'ŗ' => 'r', 'ś' => 's', 'š' => 's', + 'ť' => 't', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ū' => 'u', 'ů' => 'u', + 'ű' => 'u', 'ŭ' => 'u', 'ũ' => 'u', 'ų' => 'u', 'ŵ' => 'w', 'ÿ' => 'y', + 'ý' => 'y', 'ŷ' => 'y', 'ż' => 'z', 'ź' => 'z', 'ž' => 'z', 'Α' => 'A', + 'Ά' => 'A', 'Ἀ' => 'A', 'Ἁ' => 'A', 'Ἂ' => 'A', 'Ἃ' => 'A', 'Ἄ' => 'A', + 'Ἅ' => 'A', 'Ἆ' => 'A', 'Ἇ' => 'A', 'ᾈ' => 'A', 'ᾉ' => 'A', 'ᾊ' => 'A', + 'ᾋ' => 'A', 'ᾌ' => 'A', 'ᾍ' => 'A', 'ᾎ' => 'A', 'ᾏ' => 'A', 'Ᾰ' => 'A', + 'Ᾱ' => 'A', 'Ὰ' => 'A', 'ᾼ' => 'A', 'Β' => 'B', 'Γ' => 'G', 'Δ' => 'D', + 'Ε' => 'E', 'Έ' => 'E', 'Ἐ' => 'E', 'Ἑ' => 'E', 'Ἒ' => 'E', 'Ἓ' => 'E', + 'Ἔ' => 'E', 'Ἕ' => 'E', 'Ὲ' => 'E', 'Ζ' => 'Z', 'Η' => 'I', 'Ή' => 'I', + 'Ἠ' => 'I', 'Ἡ' => 'I', 'Ἢ' => 'I', 'Ἣ' => 'I', 'Ἤ' => 'I', 'Ἥ' => 'I', + 'Ἦ' => 'I', 'Ἧ' => 'I', 'ᾘ' => 'I', 'ᾙ' => 'I', 'ᾚ' => 'I', 'ᾛ' => 'I', + 'ᾜ' => 'I', 'ᾝ' => 'I', 'ᾞ' => 'I', 'ᾟ' => 'I', 'Ὴ' => 'I', 'ῌ' => 'I', + 'Θ' => 'T', 'Ι' => 'I', 'Ί' => 'I', 'Ϊ' => 'I', 'Ἰ' => 'I', 'Ἱ' => 'I', + 'Ἲ' => 'I', 'Ἳ' => 'I', 'Ἴ' => 'I', 'Ἵ' => 'I', 'Ἶ' => 'I', 'Ἷ' => 'I', + 'Ῐ' => 'I', 'Ῑ' => 'I', 'Ὶ' => 'I', 'Κ' => 'K', 'Λ' => 'L', 'Μ' => 'M', + 'Ν' => 'N', 'Ξ' => 'K', 'Ο' => 'O', 'Ό' => 'O', 'Ὀ' => 'O', 'Ὁ' => 'O', + 'Ὂ' => 'O', 'Ὃ' => 'O', 'Ὄ' => 'O', 'Ὅ' => 'O', 'Ὸ' => 'O', 'Π' => 'P', + 'Ρ' => 'R', 'Ῥ' => 'R', 'Σ' => 'S', 'Τ' => 'T', 'Υ' => 'Y', 'Ύ' => 'Y', + 'Ϋ' => 'Y', 'Ὑ' => 'Y', 'Ὓ' => 'Y', 'Ὕ' => 'Y', 'Ὗ' => 'Y', 'Ῠ' => 'Y', + 'Ῡ' => 'Y', 'Ὺ' => 'Y', 'Φ' => 'F', 'Χ' => 'X', 'Ψ' => 'P', 'Ω' => 'O', + 'Ώ' => 'O', 'Ὠ' => 'O', 'Ὡ' => 'O', 'Ὢ' => 'O', 'Ὣ' => 'O', 'Ὤ' => 'O', + 'Ὥ' => 'O', 'Ὦ' => 'O', 'Ὧ' => 'O', 'ᾨ' => 'O', 'ᾩ' => 'O', 'ᾪ' => 'O', + 'ᾫ' => 'O', 'ᾬ' => 'O', 'ᾭ' => 'O', 'ᾮ' => 'O', 'ᾯ' => 'O', 'Ὼ' => 'O', + 'ῼ' => 'O', 'α' => 'a', 'ά' => 'a', 'ἀ' => 'a', 'ἁ' => 'a', 'ἂ' => 'a', + 'ἃ' => 'a', 'ἄ' => 'a', 'ἅ' => 'a', 'ἆ' => 'a', 'ἇ' => 'a', 'ᾀ' => 'a', + 'ᾁ' => 'a', 'ᾂ' => 'a', 'ᾃ' => 'a', 'ᾄ' => 'a', 'ᾅ' => 'a', 'ᾆ' => 'a', + 'ᾇ' => 'a', 'ὰ' => 'a', 'ᾰ' => 'a', 'ᾱ' => 'a', 'ᾲ' => 'a', 'ᾳ' => 'a', + 'ᾴ' => 'a', 'ᾶ' => 'a', 'ᾷ' => 'a', 'β' => 'b', 'γ' => 'g', 'δ' => 'd', + 'ε' => 'e', 'έ' => 'e', 'ἐ' => 'e', 'ἑ' => 'e', 'ἒ' => 'e', 'ἓ' => 'e', + 'ἔ' => 'e', 'ἕ' => 'e', 'ὲ' => 'e', 'ζ' => 'z', 'η' => 'i', 'ή' => 'i', + 'ἠ' => 'i', 'ἡ' => 'i', 'ἢ' => 'i', 'ἣ' => 'i', 'ἤ' => 'i', 'ἥ' => 'i', + 'ἦ' => 'i', 'ἧ' => 'i', 'ᾐ' => 'i', 'ᾑ' => 'i', 'ᾒ' => 'i', 'ᾓ' => 'i', + 'ᾔ' => 'i', 'ᾕ' => 'i', 'ᾖ' => 'i', 'ᾗ' => 'i', 'ὴ' => 'i', 'ῂ' => 'i', + 'ῃ' => 'i', 'ῄ' => 'i', 'ῆ' => 'i', 'ῇ' => 'i', 'θ' => 't', 'ι' => 'i', + 'ί' => 'i', 'ϊ' => 'i', 'ΐ' => 'i', 'ἰ' => 'i', 'ἱ' => 'i', 'ἲ' => 'i', + 'ἳ' => 'i', 'ἴ' => 'i', 'ἵ' => 'i', 'ἶ' => 'i', 'ἷ' => 'i', 'ὶ' => 'i', + 'ῐ' => 'i', 'ῑ' => 'i', 'ῒ' => 'i', 'ῖ' => 'i', 'ῗ' => 'i', 'κ' => 'k', + 'λ' => 'l', 'μ' => 'm', 'ν' => 'n', 'ξ' => 'k', 'ο' => 'o', 'ό' => 'o', + 'ὀ' => 'o', 'ὁ' => 'o', 'ὂ' => 'o', 'ὃ' => 'o', 'ὄ' => 'o', 'ὅ' => 'o', + 'ὸ' => 'o', 'π' => 'p', 'ρ' => 'r', 'ῤ' => 'r', 'ῥ' => 'r', 'σ' => 's', + 'ς' => 's', 'τ' => 't', 'υ' => 'y', 'ύ' => 'y', 'ϋ' => 'y', 'ΰ' => 'y', + 'ὐ' => 'y', 'ὑ' => 'y', 'ὒ' => 'y', 'ὓ' => 'y', 'ὔ' => 'y', 'ὕ' => 'y', + 'ὖ' => 'y', 'ὗ' => 'y', 'ὺ' => 'y', 'ῠ' => 'y', 'ῡ' => 'y', 'ῢ' => 'y', + 'ῦ' => 'y', 'ῧ' => 'y', 'φ' => 'f', 'χ' => 'x', 'ψ' => 'p', 'ω' => 'o', + 'ώ' => 'o', 'ὠ' => 'o', 'ὡ' => 'o', 'ὢ' => 'o', 'ὣ' => 'o', 'ὤ' => 'o', + 'ὥ' => 'o', 'ὦ' => 'o', 'ὧ' => 'o', 'ᾠ' => 'o', 'ᾡ' => 'o', 'ᾢ' => 'o', + 'ᾣ' => 'o', 'ᾤ' => 'o', 'ᾥ' => 'o', 'ᾦ' => 'o', 'ᾧ' => 'o', 'ὼ' => 'o', + 'ῲ' => 'o', 'ῳ' => 'o', 'ῴ' => 'o', 'ῶ' => 'o', 'ῷ' => 'o', 'А' => 'A', + 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', 'Е' => 'E', 'Ё' => 'E', + 'Ж' => 'Z', 'З' => 'Z', 'И' => 'I', 'Й' => 'I', 'К' => 'K', 'Л' => 'L', + 'М' => 'M', 'Н' => 'N', 'О' => 'O', 'П' => 'P', 'Р' => 'R', 'С' => 'S', + 'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 'Х' => 'K', 'Ц' => 'T', 'Ч' => 'C', + 'Ш' => 'S', 'Щ' => 'S', 'Ы' => 'Y', 'Э' => 'E', 'Ю' => 'Y', 'Я' => 'Y', + 'а' => 'A', 'б' => 'B', 'в' => 'V', 'г' => 'G', 'д' => 'D', 'е' => 'E', + 'ё' => 'E', 'ж' => 'Z', 'з' => 'Z', 'и' => 'I', 'й' => 'I', 'к' => 'K', + 'л' => 'L', 'м' => 'M', 'н' => 'N', 'о' => 'O', 'п' => 'P', 'р' => 'R', + 'с' => 'S', 'т' => 'T', 'у' => 'U', 'ф' => 'F', 'х' => 'K', 'ц' => 'T', + 'ч' => 'C', 'ш' => 'S', 'щ' => 'S', 'ы' => 'Y', 'э' => 'E', 'ю' => 'Y', + 'я' => 'Y', 'ð' => 'd', 'Ð' => 'D', 'þ' => 't', 'Þ' => 'T', 'ა' => 'a', + 'ბ' => 'b', 'გ' => 'g', 'დ' => 'd', 'ე' => 'e', 'ვ' => 'v', 'ზ' => 'z', + 'თ' => 't', 'ი' => 'i', 'კ' => 'k', 'ლ' => 'l', 'მ' => 'm', 'ნ' => 'n', + 'ო' => 'o', 'პ' => 'p', 'ჟ' => 'z', 'რ' => 'r', 'ს' => 's', 'ტ' => 't', + 'უ' => 'u', 'ფ' => 'p', 'ქ' => 'k', 'ღ' => 'g', 'ყ' => 'q', 'შ' => 's', + 'ჩ' => 'c', 'ც' => 't', 'ძ' => 'd', 'წ' => 't', 'ჭ' => 'c', 'ხ' => 'k', + 'ჯ' => 'j', 'ჰ' => 'h', 'ţ' => 't', 'ʼ' => "'", '̧' => '', 'ḩ' => 'h', + '‘' => "'", '’' => "'", 'ừ' => 'u', '/' => '', 'ế' => 'e', 'ả' => 'a', + 'ị' => 'i', 'ậ' => 'a', 'ệ' => 'e', 'ỉ' => 'i', 'ồ' => 'o', 'ề' => 'e', + 'ơ' => 'o', 'ạ' => 'a', 'ẵ' => 'a', 'ư' => 'u', 'ằ' => 'a', 'ầ' => 'a', + 'ḑ' => 'd', 'Ḩ' => 'H', 'Ḑ' => 'D', 'ș' => 's', 'ț' => 't', 'ộ' => 'o', + 'ắ' => 'a', 'ş' => 's', "'" => '', 'ու' => 'u', 'ա' => 'a', 'բ' => 'b', + 'գ' => 'g', 'դ' => 'd', 'ե' => 'e', 'զ' => 'z', 'է' => 'e', 'ը' => 'y', + 'թ' => 't', 'ժ' => 'zh', 'ի' => 'i', 'լ' => 'l', 'խ' => 'kh', 'ծ' => 'ts', + 'կ' => 'k', 'հ' => 'h', 'ձ' => 'dz', 'ղ' => 'gh', 'ճ' => 'ch', 'մ' => 'm', + 'յ' => 'y', 'ն' => 'n', 'շ' => 'sh', 'ո' => 'o', 'չ' => 'ch', 'պ' => 'p', + 'ջ' => 'j', 'ռ' => 'r', 'ս' => 's', 'վ' => 'v', 'տ' => 't', 'ր' => 'r', + 'ց' => 'ts', 'փ' => 'p', 'ք' => 'q', 'և' => 'ev', 'օ' => 'o', 'ֆ' => 'f', + ); + $arrayFrom = array_keys($transliterationTable); + $arrayTo = array_values($transliterationTable); + } + + return str_replace($arrayFrom, $arrayTo, $string); + } +} \ No newline at end of file diff --git a/src/tool/File.php b/src/tool/File.php new file mode 100644 index 0000000..30abcb8 --- /dev/null +++ b/src/tool/File.php @@ -0,0 +1,274 @@ + basename($filename), + "文件类型" => filetype($filename), + "文件大小" => trans_byte(filesize($filename)), + "创建时间" => date('Y-m-d H:i:s', filectime($filename)), + "修改时间" => date('Y-m-d H:i:s', filemtime($filename)), + "上一次访问时间" => date('Y-m-d H:i:s', fileatime($filename)), + ]; + } + + + /** + * @use 转换字节大小 + * @param int $byte 字节大小 + * @param int $precision 小数点保留位数 + * @return string 转换后的单位 + */ + public static function transByte(int $byte, $precision = 2): string + { + $kb = 1024; + $mb = 1024 * $kb; + $gb = 1024 * $mb; + $tb = 1024 * $gb; + + if ($byte < $kb) { + return $byte . 'B'; + } + + if ($byte < $mb) { + // 默认四舍五入, 保留两位小数 + return round($byte / $kb, $precision) . ' KB'; + } + + if ($byte < $gb) { + return round($byte / $mb, $precision) . ' MB'; + } + + if ($byte < $tb) { + return round($byte / $tb, $precision) . ' GB'; + } + } + + + /** + * @use 以字符串形式读取内容 + * @param string $filename + * @return false|string + */ + public static function readString(string $filename) + { + if (is_file($filename) && is_readable($filename)) { + return file_get_contents($filename); + } + return false; + } + + + /** + * @use 以数组形式读取内容 + * @param string $filename + * @param bool $skip_empty_lines + * @return array|false + */ + public static function readArray(string $filename, bool $skip_empty_lines = false) + { + if (is_file($filename) && is_readable($filename)) { + if ($skip_empty_lines) { + // 忽略空行读取 + return file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + } else { + // 以数组形式直接读取, 不忽略空行 + return file($filename); + } + } + } + + + /** + * @use 增加文件内容升级版 + * @param string $filename 路径名称 + * @param mixed $data 需要写入的数据 + * @param boolean $clear_content 是否清空原始内容再写入 + * @return bool true|false + */ + public static function write(string $filename, $data, bool $clear_content = false) + { + $dirname = dirname($filename); + // 检测目标路径是否存在 + if (!file_exists($dirname)) { + mkdir($dirname, 0777, true); + } + // 文件存在并且不清空原始文件 + if (is_file($filename) && !$clear_content) { + $srcData = file_get_contents($filename); + } + + // 检测数据是否为数组或者对象 + if (is_array($data) || is_object($data)) { + // 序列化数据 + $data = serialize($data); + } + // 拼装数据 + $data = $srcData . $data; + // 写入数据 + if (file_put_contents($filename, $data) !== false) { + return true; + } + return false; + } + + /** + * @use 截断文本 + * @param string $filename 文件名称 + * @param int $length 截断文本长度 + * @return boolean true|false + */ + public static function truncate(string $filename, int $length): bool + { + // 判断文件是否存在并且是可写的 + if (is_file($filename) && is_writeable($filename)) { + // 创建文件句柄, 以读写方式打开 + $handler = fopen($filename, 'rb+'); + $length = $length < 0 ? 0 : $length; + ftruncate($handler, $length); + fclose($handler); + } + return false; + } + +} diff --git a/src/tool/Generator.php b/src/tool/Generator.php index 0065314..3c5a65b 100644 --- a/src/tool/Generator.php +++ b/src/tool/Generator.php @@ -5,7 +5,7 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 * Source: https://github.com/anhao/bv2av/ */ @@ -49,4 +49,16 @@ class Generator } + /** + * @use 生成BUVID + * @return string + */ + public static function buvid():string{ + // XYD5B85DA7212341F51C612344A6B8C6C21234 + $mac = Faker::macAddress(); + $md5 = md5($mac); + $md5_arr = str_split($md5); + return strtoupper("XY{$md5_arr[2]}{$md5_arr[12]}{$md5_arr[22]}{$md5}"); + } + } diff --git a/src/util/AllotTasks.php b/src/util/AllotTasks.php new file mode 100644 index 0000000..8602049 --- /dev/null +++ b/src/util/AllotTasks.php @@ -0,0 +1,92 @@ + null, + 'estimated_time' => null, + 'work_completed' => null, + ]; + + + /** + * @use 加载json数据 + * @return Parser + */ + protected static function loadJsonData() + { + return Parser::fromFile(static::$repository); + } + + /** + * @use 提交任务 + * @param string $operation + * @param \stdClass $act + * @param bool $time + * @return bool + */ + protected static function pushTask(string $operation, \stdClass $act, bool $time = false): bool + { + $task = [ + 'operation' => $operation, + 'act' => $act, + 'time' => false + ]; + if ($time) { + $task['time'] = $time; + } + array_push(static::$tasks, $task); + return true; + } + + /** + * @use 拉取任务 + * @return false|mixed + */ + protected static function pullTask() + { + // 任务列表为空 + if (empty(static::$tasks)) { + return false; + } + // 先进先出 弹出一个任务 + $task = array_shift(static::$tasks); + if ($task['time']) { + if (is_null(static::$work_status['estimated_time']) || time() < intval(static::$work_status['estimated_time'])) { + array_unshift(static::$tasks, $task); + } + } + return $task; + } + + + +// /** +// * @use 执行任务 +// * @return bool +// */ +// abstract protected function workTask(): bool; +// +// +// /** +// * @use 分配任务 +// * @return bool +// */ +// abstract protected function allotTasks(): bool; +} diff --git a/src/plugin/BaseRaffle.php b/src/util/BaseRaffle.php similarity index 96% rename from src/plugin/BaseRaffle.php rename to src/util/BaseRaffle.php index cd488eb..8b904f0 100644 --- a/src/plugin/BaseRaffle.php +++ b/src/util/BaseRaffle.php @@ -6,16 +6,21 @@ * Author: Lkeme * License: The MIT License * Email: Useri@live.cn - * Updated: 2020 ~ 2021 + * Updated: 2021 ~ 2022 */ -namespace BiliHelper\Plugin; +namespace BiliHelper\Util; use BiliHelper\Core\Log; use BiliHelper\Core\Curl; +use BiliHelper\Plugin\Live; +use BiliHelper\Plugin\Sign; +use BiliHelper\Plugin\Statistics; abstract class BaseRaffle { + use TimeLock; + use FilterWords; const ACTIVE_TITLE = ''; const ACTIVE_SWITCH = ''; @@ -33,6 +38,7 @@ abstract class BaseRaffle return; } static::setPauseStatus(); + static::loadJsonData(); static::startLottery(); } diff --git a/src/util/FilterWords.php b/src/util/FilterWords.php new file mode 100644 index 0000000..2bd744d --- /dev/null +++ b/src/util/FilterWords.php @@ -0,0 +1,39 @@ + []]; // data [ets, benchmark, time, secret_rule, id] data->id [parent_area_id, area_id, 0, room_id] + protected static $_secret_rule = []; // secret_rule [2, 3, 1, 5] + protected static $_room_info = []; // 心跳房间信息 + + protected static $_retry = 3; // 重试次数 + protected static $_count_num = 0; // 计数 + protected static $_count_time = 0; // 计时间 + + protected static $_current_room_id = 0; // 当前运行的ROOM_ID + protected static $_enc_server = null; // 加密服务器 依赖配置文件 + + protected static $_default = 0; // 默认值 + + + /** + * @use 重置变量 + * @param false $force + */ + protected static function resetVar($force = false) + { + if ($force) { + static::$_room_info = []; + static::$_current_room_id = 0; + + static::$_retry = 3; + static::$_count_num = 0; + static::$_count_time = 0; + } + $data = [ + 'id' => static::$_data['id'], + ]; + $data["id"][2] = 0; + static::$_data = $data; + } + + + /** + * @use 任务接口 + * @param int $room_id + * @param int $max_time + * @param int $max_num + * @return int|mixed + */ + protected static function xliveHeartBeatTask(int $room_id, int $max_time, int $max_num) + { + // 加载依赖 + if (!static::depend()) { + return static::$_default; + } + // 对比当前运行 + if (static::$_current_room_id != $room_id) { + static::resetVar(true); + static::$_current_room_id = $room_id; + } + // 加载房间信息 + if (empty(static::$_room_info)) { + $r_data = Live::webGetRoomInfo($room_id); + if ($r_data['code'] != 0) { + Log::warning('直播间信息获取失败'); + return static::$_default; + } + static::$_room_info = $r_data; + $rdata = $r_data['data']; + $parent_area_id = $rdata['room_info']['parent_area_id']; + $area_id = $rdata['room_info']['area_id']; + # 短位转长位 + $room_id = $rdata['room_info']['room_id']; + static::$_data['id'] = [$parent_area_id, $area_id, 0, $room_id]; + } + // 执行心跳 + $r_data = static::heartBeatIterator(); + $index = static::$_data['id'][2]; + if ($r_data['code'] != 0) { + if (static::$_retry) { + Log::warning("心跳失败-$index {$r_data['message']}"); + static::resetVar(); + static::$_retry -= 1; + return static::$_default; + } + } + static::$_count_num += 1; + static::$_count_time += $r_data['heartbeat_interval']; + + // 最大次数限制 + if ($max_num <= static::$_count_num) { + // 成功在id为{room_id}的直播间发送完{ii}次心跳,退出直播心跳(达到最大心跳次数) + } + // 最大时间限制 + if ($max_time <= static::$_count_time) { + //成功在id为{room_id}的直播间发送第{ii}次心跳 + } + $minute = round(static::$_count_time / 60); + Log::info("已在直播间 $room_id 连续观看了 $minute 分钟"); + return $r_data['heartbeat_interval']; + + } + + /** + * @use 检查依赖 + * @return bool + */ + protected static function depend(): bool + { + if (getenv('ENC_SERVER') == '') { + return false; + } + // 加载加密服务器 + if (is_null(static::$_enc_server)) { + static::$_enc_server = getenv('ENC_SERVER'); + } + return true; + } + + + /** + * @use 心跳迭代 + * @return array + */ + protected static function heartBeatIterator(): array + { + $rdata = []; + # 第1次执行 eHeartBeat + if (static::$_data['id'][2] == 0) { + $r_data = static::eHeartBeat(static::$_data['id']); + } else { + # 第1次之后执行 xHeartBeat + static::$_data['ts'] = time() * 1000; + static::$_data['s'] = static::encParamS(static::$_data, static::$_secret_rule); + $r_data = static::xHeartBeat(static::$_data['id']); + } + if ($r_data['code'] == 0) { + $rdata = $r_data['data']; + static::$_data['ets'] = $rdata['timestamp']; + static::$_data['benchmark'] = $rdata['secret_key']; + static::$_data['time'] = $rdata['heartbeat_interval']; + static::$_secret_rule = $rdata['secret_rule']; + static::$_data['id'][2] += 1; + } + Log::debug(json_encode(static::$_data['id'], true)); + return [ + 'code' => $r_data['code'], + 'message' => $r_data['message'], + 'heartbeat_interval' => $rdata['heartbeat_interval'] + ]; + } + + + /** + * @use E心跳 + * @param array $id + * @return array|false[] + */ + protected static function eHeartBeat(array $id): array + { + $url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/E'; + $headers = [ + 'Content-Type' => 'application/x-www-form-urlencoded', + 'Origin' => 'https://live.bilibili.com', + 'Referer' => 'https://live.bilibili.com/' . $id[3], + ]; + $user_info = User::parseCookies(); + $payload = [ + 'id' => json_encode([$id[0], $id[1], $id[2], $id[3]], true), + 'device' => json_encode([Generator::hash(), Generator::uuid4()], true), + 'ts' => time() * 1000, + 'is_patch' => 0, + 'heart_beat' => [], + 'ua' => 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0', + 'csrf_token' => $user_info['token'], + 'csrf' => $user_info['token'], + 'visit_id' => '' + ]; + // print_r($payload); + Log::debug(json_encode($payload, true)); + $raw = Curl::post('pc', $url, $payload, $headers); + // {'code':0,'message':'0','ttl':1,'data':{'timestamp':1595342828,'heartbeat_interval':300,'secret_key':'seacasdgyijfhofiuxoannn','secret_rule':[2,5,1,4],'patch_status':2}} + + unset($payload['id']); + static::$_data = array_merge_recursive(static::$_data, $payload); + + return json_decode($raw, true); + } + + /** + * @use X心跳 + * @param array $id + * @return array|bool[] + */ + protected static function xHeartBeat(array $id): array + { + $url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/X'; + $user_info = User::parseCookies(); + $headers = [ + 'Content-Type' => 'application/x-www-form-urlencoded', + 'Origin' => 'https://live.bilibili.com', + 'Referer' => 'https://live.bilibili.com/' . $id[3], + ]; + $payload = [ + 's' => static::$_data['s'], + 'id' => json_encode([$id[0], $id[1], $id[2], $id[3]], true), + 'device' => static::$_data['device'], + 'ets' => static::$_data['ets'], + 'benchmark' => static::$_data['benchmark'], + 'time' => static::$_data['time'], + 'ts' => static::$_data['ts'], + 'ua' => static::$_data['ua'], + 'csrf_token' => $user_info['token'], + 'csrf' => $user_info['token'], + 'visit_id' => '' + ]; +// print_r($payload); + Log::debug(json_encode($payload, true)); + $raw = Curl::post('pc', $url, $payload, $headers); + # {'code':0,'message':'0','ttl':1,'data':{'heartbeat_interval':300,'timestamp':1595346846,'secret_rule':[2,5,1,4],'secret_key':'seacasdgyijfhofiuxoannn'}} + return json_decode($raw, true); + } + + /** + * @use 加密参数S + * @param array $t + * @param array $r + * @return string|false + */ + protected static function encParamS(array $t, array $r) + { + $headers = [ + 'Content-Type' => 'application/json', + ]; + // 加密部分 + $payload = ['t' => $t, 'r' => $r]; + $data = Curl::put('other', static::$_enc_server, $payload, $headers); + $de_raw = json_decode($data, true); + if ($de_raw['code'] == 0) { + // Log::info("S加密成功 {$de_raw['s']}"); + return $de_raw['s']; + } else { + Log::warning("S加密失败 {$de_raw['message']}"); + return false; + } + } + + +} \ No newline at end of file