From 374591393e3e30aa851229bfceac033c0205bb4e Mon Sep 17 00:00:00 2001
From: Lkeme <19500576+lkeme@users.noreply.github.com>
Date: Thu, 4 Sep 2025 13:01:55 +0800
Subject: [PATCH] .\.editorconfig
---
README.md | 2 +-
docs/CHANGELOG.md | 19 +++
docs/DOC.md | 79 +++++-----
plugin/VipPrivilege/VipPrivilege.php | 213 ++++++++++++++-------------
profile/example/device/device.yaml | 6 +-
resources/version.json | 4 +-
src/Api/Vip/ApiPrivilegeAssets.php | 66 +++++++++
src/Api/Vip/ApiVipCenter.php | 48 ++++++
8 files changed, 291 insertions(+), 146 deletions(-)
create mode 100644 src/Api/Vip/ApiPrivilegeAssets.php
create mode 100644 src/Api/Vip/ApiVipCenter.php
diff --git a/README.md b/README.md
index 032fba3..69dfe81 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@
-
+
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 5b09fa3..3184aff 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -8,6 +8,25 @@
[comment]: <> ()
+## v2.5.1.250904 alpha (2025-09-04)
+
+### Added
+
+-
+
+### Changed
+
+- 更新设备信息
+- 更新部分使用文档
+
+### Fixed
+
+- 尝试修复年度大会员领取权益**特色权益二选一**
+
+### Remarks
+
+-
+
## v2.5.0.250823 alpha (2025-08-23)
### Added
diff --git a/docs/DOC.md b/docs/DOC.md
index ea4a21e..cf64d52 100644
--- a/docs/DOC.md
+++ b/docs/DOC.md
@@ -45,7 +45,7 @@
+ 阿里云(全量镜像)
-```shell script
+```shell
# 使用帮助
> https://developer.aliyun.com/composer
# 使用命令
@@ -54,7 +54,7 @@
+ 恢复默认镜像|Composer.phar加速下载
-```shell script
+```shell
> composer config -g --unset repos.packagist
> https://mirrors.cloud.tencent.com/composer/composer.phar
@@ -67,7 +67,7 @@
+ cnpkg(全量镜像)
-```shell script
+```shell
# 使用帮助
> https://php.cnpkg.org/
# 使用命令
@@ -76,7 +76,7 @@
+ 腾讯云(全量镜像)
-```shell script
+```shell
# 使用帮助
> https://mirrors.cloud.tencent.com/help/composer.html
# 使用命令
@@ -85,7 +85,7 @@
+ PhpComposer(全量镜像)
-```shell script
+```shell
# 使用帮助
> https://pkg.phpcomposer.com/
# 使用命令
@@ -94,7 +94,7 @@
+ 华为云(全量镜像)
-```shell script
+```shell
# 使用帮助
> https://mirrors.huaweicloud.com/repository/php/
# 使用命令
@@ -103,7 +103,7 @@
+ 交通大学(非全量镜像)
-```shell script
+```shell
# 使用帮助
> https://packagist.mirrors.sjtug.sjtu.edu.cn/
# 使用命令
@@ -118,31 +118,27 @@
1. 下载(克隆)项目代码,初始化项目
-```shell script
+```shell
$ git clone https://github.com/lkeme/BiliHelper-personal.git
$ cp -r profile/example profile/user
```
2. 使用 [composer](https://getcomposer.org/download/) 工具进行安装
-```shell script
+```shell
$ composer install
```
-[comment]: <> (composer dump-autoload (-o))
-
-[comment]: <> (composer dumpautoload (-o))
-
3. 按照说明修改配置文件 `profile/user/config/user.ini`
- ```shell script
+ ```shell
# 默认只需填写帐号密码,按需求开启其他功能即可
...
```
4. 运行测试
-```shell script
+```shell
$ php app.php
# 默认配置user
$ php app.php m:a
@@ -152,7 +148,7 @@ $ php app.php m:a
5. 复制一份profile/example配置文件夹,修改账号密码即可
- ```shell script
+ ```shell
# 默认配置 darling {darling}是配置文件名,可任意
$ php app.php darling m:a
# 如果写了用户参数 不带m:a 与上同等效果
@@ -165,7 +161,7 @@ $ php app.php m:a
7. 命令模式
-```shell script
+```shell
# 获取所有命令
$ php app.php
mode:app m:a [主要模式] 默认功能
@@ -219,30 +215,23 @@ $ php app.php test m:d -P VipPoint,Lottery # 多个插件
- 通过环境变量进行传入
-```shell script
+```shell
$ docker run -itd --rm -e USER_NAME=你的B站登录账号 -e USER_PASSWORD=你的B站密码 lkeme/bilihelper-personal
```
- 通过配置文件进行传入(能保留登录状态,自定义配置)
-[//]: # (1. 下载[配置文件](https://raw.githubusercontent.com/lkeme/BiliHelper-personal/master/conf/user.ini.example))
-
-[//]: # (2. 修改)
-
-1.
-
-下载 [配置文件夹](https://github.com/lkeme/BiliHelper-personal/tree/master/profile) `注意是文件夹,可以完整下载后提出来`
-
-2. 重命名 `profile/example -> profile/user` , 修改 `profile/user/config/user.ini`
+1. 下载 [代码压缩包](https://ghfast.top/https://github.com/lkeme/BiliHelper-personal/archive/refs/heads/master.zip),解压后提取`profile`目录
+2. 将`profile/example`重命名为`profile/user`, 修改 `profile/user/config/user.ini`
3. 通过下面的命令进行挂载并运行
-```shell script
+```shell
$ docker run -itd --rm -v /path/to/your/confFilePath:/app/profile/user lkeme/bilihelper-personal
```
- 版本兼容
-```shell script
+```shell
$ -e VERSION=1 # 使用 版本 V1.x.x(兼容处理)
$ -e VERSION=2 # 使用 版本 V2.x.x(默认选项)
```
@@ -251,7 +240,7 @@ $ -e VERSION=2 # 使用 版本 V2.x.x(默认选项)
> 以下加速镜像均为网络收集,感谢公益提供者,如有问题请联系删除
-```shell script
+```shell
$ -e MIRRORS=0 # 使用 github.com(RAW|源站|默认)
$ -e MIRRORS=1 # 使用 ghfast.top(US|美国)
$ -e MIRRORS=2 # 使用 gitclone.com(CN|中国)
@@ -261,13 +250,22 @@ $ -e MIRRORS=5 # 使用 hub.gitmirror.com(US|美国)
$ -e MIRRORS=custom -e CUSTOM_CLONE_URL=https://github.com/lkeme/BiliHelper-personal.git # 使用 自定义克隆地址
```
-- 相关参数
+- 👉 相关参数
-```ps
- -it 前台运行
- -itd 后台运行
- -v 本地文件:容器内部文件 ==> 挂载本地文件到容器中。本地文件路径随便变,容器内部文件路径不能变。
-```
+| 选项 | 简单易懂的含义 |
+|--------|----------------------------------------------------|
+| `-i` | 让你能往容器里输入内容(保持输入通道打开) |
+| `-t` | 给容器“配一个键盘和屏幕”,让它像在电脑前运行一样 |
+| `-d` | 让容器在后台悄悄运行,不占当前窗口 |
+| `--rm` | 容器一停止,自动删掉它,不留下“垃圾”。(临时测试用,跑完就干净删除,省得手动 docker rm) |
+| `-v` | 把电脑上的文件夹或文件“共享”给容器用(双向同步) |
+
+- ✅ 组合小贴士
+
+| 组合 | 含义 | 必须 |
+|--------|----------------------|----|
+| `-it` | 搭配使用,就像“打开一个能打字的控制台” | ✔ |
+| `-itd` | 既能输入又有终端,还在后台跑 | ✔ |
- -v模式使用短信登录
@@ -275,15 +273,18 @@ $ -e MIRRORS=custom -e CUSTOM_CLONE_URL=https://github.com/lkeme/BiliHelper-pers
```shell
$ docker attach 容器ID
+$ docker attach --sig-proxy=false 容器ID # 关闭信号代理:本地终端按键(如 Ctrl+C)不会转发给容器进程,防止误关闭容器
```
```
Q: 容器停止后,容器不见了?
A: 请删除运行时的 --rm 参数
+Q: 短信发送后,容器没有等待输入验证码就退出了?
+A: 检查docker运行参数是否少了(-it/-itd)参数。
+
Q: docker attach方式使用ctrl+c退出容器,容器会停止运行怎么办?
A: 请用ctrl+p+q退出容器,容器不会停止运行。
-A1: 添加-sig-proxy=false参数,docker attach --sig-proxy=false 容器ID,ctrl+c退出容器,容器不会停止运行。
Q: 使用portainer容器管理新建的容器,命令行无法输入直接验证失败怎么办?
A: 在容器设置Advanced container settings -> Commands & logging -> Console -> 勾选 Interactive & TTY (-i -t) ,保存后重新部署容器即可。
@@ -293,7 +294,7 @@ A: 在容器设置Advanced container settings -> Commands & logging -> Console -
- 不需要自动更新
-```shell script
+```shell
$ -e AUTO_UPDATE=0 # 不自动更新
```
@@ -404,7 +405,7 @@ APP_CALLBACK="https://api.telegram.org/bot/sendMessage?chat_id=&
通常可以在直播间页面的 url 获取到它
```
-http://live.bilibili.com/9522051
+https://live.bilibili.com/9522051
```
长位直播间ID获取
diff --git a/plugin/VipPrivilege/VipPrivilege.php b/plugin/VipPrivilege/VipPrivilege.php
index 5053a20..41e8b31 100644
--- a/plugin/VipPrivilege/VipPrivilege.php
+++ b/plugin/VipPrivilege/VipPrivilege.php
@@ -16,7 +16,8 @@
*/
use Bhp\Api\Vip\ApiExperience;
-use Bhp\Api\Vip\ApiPrivilege;
+use Bhp\Api\Vip\ApiPrivilegeAssets;
+use Bhp\Api\Vip\ApiVipCenter;
use Bhp\Log\Log;
use Bhp\Plugin\BasePlugin;
use Bhp\Plugin\Plugin;
@@ -41,60 +42,6 @@ class VipPrivilege extends BasePlugin
'cycle' => '24(小时)', // 运行周期
];
- /**
- * @var array|string[]
- * BCoin: 1,
- * MallCoupon: 2,
- * ComicCoupon: 3,
- * FreightCoupon: 4,
- * ComicMallCoupon: 5,
- * GarbFreeCoupon: 6,
- * CheeseClasseCoupon: 7,
- * KingOfGloryCoupon: 8,
- * LevelAcceleration: 9,
- * CakeCoupon: 10,
- * MovieCoupon: 11,
- * DisneyCoupon: 12,
- * BirthdayImage: 13,
- * MovieVoucher: 14,
- * StarBox: 15,
- * MagicStone: 16,
- * GameCoupon: 17
- */
- protected array $privilege = [
- 0 => '未知奖励0(未知奖励0)',
- 1 => '年度专享B币赠送(B币券)',
- 2 => '年度专享会员购优惠券(会员购优惠券)',
- 3 => '年度专享漫画礼包(漫画福利券)',
- 4 => '大会员专享会员购包邮券(会员购包邮券)',
- 5 => '年度专享漫画礼包(漫画商城优惠券)',
- 6 => '大会员专享会员体验卡(装扮体验卡)',
- 7 => '大会员专享课堂优惠券(课堂优惠券)',
- 8 => '大会员专享王者荣耀优惠券(游戏优惠券)',
- 9 => '会员观看任意1个视频即可领取,日限1次(额外经验)',
- 10 => '大会员专享蛋糕优惠券(蛋糕优惠券)',
- 11 => '大会员专享电影优惠券(电影优惠券)',
- 12 => '大会员专享迪士尼优惠券(迪士尼优惠券)',
- 13 => '大会员专享生日礼图(生日礼图)',
- 14 => '大会员专享电影券(电影券)',
- 15 => '年度专享会员购星光宝盒88折券(折扣券)',
- 16 => '大会员专享会员购10魔晶(魔晶)',
- 17 => '大会员专享游戏优惠券(游戏优惠券)',
- ];
-
- /**
- * @var array|string[]
- */
- protected array $privilege_blacklists = [
- 18 => '淘宝账号查询异常,请退出重试',
- 20 => '饿了么领取活动已经过期~',
- 21 => '超大会员身份状态异常',
- 24 => '请求错误', // 未知
- 25 => '请求错误', // 未知
- 26 => '请求错误', // 正式大会员专属票务优惠券-229减18
- 27 => '请求错误', // 正式漫展-大会员专属票务优惠券169减10
- ];
-
/**
* @param Plugin $plugin
*/
@@ -121,6 +68,7 @@ class VipPrivilege extends BasePlugin
TimeLock::setTimes(TimeLock::timing(23) + mt_rand(10, 30) * 60);
}
+
/**
* 领取
* @return void
@@ -131,7 +79,12 @@ class VipPrivilege extends BasePlugin
// 如果为年度大会员
if (!User::isYearVip('大会员权益')) return;
//
- $privilege_list = $this->filterCanReceive($this->myVipPrivilege());
+ $privilege_list = array_merge($this->vipExtraEx(), $this->filterCanReceive());
+ if (empty($privilege_list)) {
+ Log::info('大会员权益: 当前无可领取权益');
+ return;
+ }
+
Log::info('大会员权益: 可领取权益数 ' . count($privilege_list));
//
foreach ($privilege_list as $privilege) {
@@ -140,26 +93,103 @@ class VipPrivilege extends BasePlugin
// 特殊类型 9 每日10经验 需要观看视频
if ($privilege['type'] == 9) {
// 领取额外经验
- $this->myVipExtraExp();
+ $this->extraExp();
continue;
}
// 领取奖励
- $this->myVipPrivilegeReceive($privilege['type']);
+ $this->privilegeAssetReceive($privilege);
}
}
+ /**
+ * 大会员额外权益
+ * @return array|array[]
+ */
+ protected function vipExtraEx(): array
+ {
+ $response = ApiVipCenter::v2();
+ //
+ if ($response['code']) {
+ Log::warning("大会员权益: 获取大会员额外经验领取状态失败 {$response['code']} -> {$response['message']}");
+ return [];
+ }
+ //data.experience.state 0-未领取 1-已领取
+ if (isset($response['data']['experience']['state']) && $response['data']['experience']['state'] == 0) {
+ return [
+ [
+ 'type' => 9,
+ 'title' => '专属等级加速包',
+ 'token' => '',
+ 'state' => 0,
+ 'customized_text' => '每日10经验',
+ ]
+ ];
+ }
+ return [];
+ }
+
+
/**
* 过滤可领取的权益
- * @param array $privilege_list
* @return array
*/
- protected function filterCanReceive(array $privilege_list): array
+ protected function filterCanReceive(): array
{
- // 是否领取状态 0:未兑换 | 1:已兑换 | 2:未完成(若需要完成)
- // 黑名单
- return array_filter($privilege_list, function ($privilege) {
- return $privilege['state'] == 0 && !array_key_exists($privilege['type'], $this->privilege_blacklists);
+ $response = ApiPrivilegeAssets::list();
+ // 请求失败
+ if ($response['code']) {
+ Log::warning("大会员权益: 获取APP端权益列表失败 {$response['code']} -> {$response['message']}");
+ return [];
+ }
+ // 过滤tabs
+ $tab = array_filter($response['data']['tabs'], function ($tab) {
+ return $tab['name'] == '站内福利' && $tab['type'] == 1 && $tab['type_code'] == 'welfare';
});
+ if (empty($tab)) {
+ Log::warning("大会员权益: 获取APP端权益列表失败,未找到站内福利");
+ return [];
+ }
+ $tab = array_values($tab)[0];
+ /// 遍历groups
+ $privilege_list = [];
+ foreach ($tab['groups'] as $group) {
+ // 跳过年度专享游戏礼包
+ if (isset($group['title']) && $group['title'] === '年度专享游戏礼包') {
+ continue;
+ }
+ // 特色权益二选一,只选B币券
+ if (isset($group['title']) && $group['title'] === '特色权益二选一') {
+ foreach ($group['privilege_skus'] as $sku) {
+ if ($sku['title'] === 'B币券' && isset($sku['exchange']['can_exchange'], $sku['exchange']['hit_exchange_limit']) && $sku['exchange']['can_exchange'] && !$sku['exchange']['hit_exchange_limit']) {
+ $customized_text = $this->getCustomizedText($sku);
+ $privilege_list[] = [
+ 'type' => $sku['type'],
+ 'title' => $sku['title'],
+ 'token' => $sku['token'],
+ 'state' => $sku['exchange']['state'] ?? 0,
+ 'customized_text' => $customized_text,
+ ];
+ break; // 只选一个
+ }
+ }
+ continue;
+ }
+ // 其他group,遍历privilege_skus
+ foreach ($group['privilege_skus'] as $sku) {
+ if (isset($sku['exchange']['can_exchange'], $sku['exchange']['hit_exchange_limit']) && $sku['exchange']['can_exchange'] && !$sku['exchange']['hit_exchange_limit']) {
+ $customized_text = $this->getCustomizedText($sku);
+ $privilege_list[] = [
+ 'type' => $sku['type'],
+ 'title' => $sku['title'],
+ 'token' => $sku['token'],
+ 'state' => $sku['exchange']['state'] ?? 0,
+ 'customized_text' => $customized_text,
+ ];
+ }
+ }
+ }
+ //
+ return $privilege_list;
}
@@ -167,7 +197,7 @@ class VipPrivilege extends BasePlugin
* 大会员额外经验
* @return void
*/
- protected function myVipExtraExp(): void
+ protected function extraExp(): void
{
$response = ApiExperience::add();
//
@@ -182,54 +212,35 @@ class VipPrivilege extends BasePlugin
/**
- * 获取我的大会员权益列表
- * @return array
- */
- protected function myVipPrivilege(): array
- {
- // {"code":0,"message":"0","ttl":1,"data":{"list":[{"type":1,"state":0,"expire_time":1622476799},{"type":2,"state":0,"expire_time":1622476799}]}}
- $response = ApiPrivilege::my();
- //
- if ($response['code']) {
- Log::warning("大会员权益: 获取权益列表失败 {$response['code']} -> {$response['message']}");
- return [];
- } else {
- Log::info('大会员权益: 获取权益列表成功 ' . count($response['data']['list']));
- return $response['data']['list'];
- }
- }
-
- /**
- * 领取我的大会员权益
- * @param int $type
+ * 领取大会员权益
+ * @param array $asset
* @throws NoLoginException
*/
- protected function myVipPrivilegeReceive(int $type): void
+ protected function privilegeAssetReceive(array $asset): void
{
- // {"code":0,"message":"0","ttl":1}
- // {"code":73319,"message":"73319","ttl":1}
- // {-101: "账号未登录", -111: "csrf 校验失败", -400: "请求错误", 69800: "网络繁忙 请稍后重试", 69801: "你已领取过该权益"}
- $response = ApiPrivilege::receive($type);
- // 判断type是否在$this->privilege
- if (!array_key_exists($type, $this->privilege)) {
- $type = "未知奖励$type";
- } else {
- $type = $this->privilege[$type];
- }
+ $response = ApiPrivilegeAssets::exchange($asset['token']);
//
switch ($response['code']) {
case -101:
throw new NoLoginException($response['message']);
case 0:
- Log::notice("大会员权益: 领取权益[$type]成功");
- break;
- case 73319:
- Log::warning("大会员权益: 领取权益[$type]失败,暂时未到可领取时间");
+ Log::notice("大会员权益: 领取权益[{$asset['title']} * {$asset['customized_text']}]成功");
break;
default:
- Log::warning("大会员权益: 领取权益[$type]失败, {$response['code']} -> {$response['message']}");
+ Log::warning("大会员权益: 领取权益[{$asset['title']} * {$asset['customized_text']}]失败 {$response['code']} -> {$response['message']}");
break;
}
}
+ /**
+ * 获取并格式化权益自定义文本
+ * @param array $sku
+ * @return string
+ */
+ protected function getCustomizedText(array $sku): string
+ {
+ $customized = $sku['icon']['customized'] ?? [];
+ if (empty($customized)) return '';
+ return ($customized['number'] ?? '') . ($customized['currency_symbol'] ?? '') . ($customized['unit'] ?? '') . ($customized['logo_text'] ?? '');
+ }
}
diff --git a/profile/example/device/device.yaml b/profile/example/device/device.yaml
index c87c377..f3bfb6b 100644
--- a/profile/example/device/device.yaml
+++ b/profile/example/device/device.yaml
@@ -3,8 +3,8 @@ device_version: 0.0.1
app:
bili_a: # Android
package: "tv.danmaku.bili"
- version: "8.59.0"
- build: "8590200"
+ version: "8.61.0"
+ build: "8610300"
channel: "bili"
device: "phone"
mobi_app: "android"
@@ -15,7 +15,7 @@ app:
secret_key: "NTYwYzUyY2NkMjg4ZmVkMDQ1ODU5ZWQxOGJmZmQ5NzM"
app_key_n: "NzgzYmJiNzI2NDQ1MWQ4Mg=="
secret_key_n: "MjY1MzU4M2M4ODczZGVhMjY4YWI5Mzg2OTE4YjFkNjU="
- statistics: '{"appId":1,"platform":3,"version":"8.59.0","abtest":""}'
+ statistics: '{"appId":1,"platform":3,"version":"8.61.0","abtest":""}'
bili_i: # IOS
app_key: "MjdlYjUzZmM5MDU4ZjhjMw=="
secret_key: "YzJlZDUzYTc0ZWVlZmUzY2Y5OWZiZDAxZDhjOWMzNzU="
diff --git a/resources/version.json b/resources/version.json
index 7e3bcf1..1c9c436 100644
--- a/resources/version.json
+++ b/resources/version.json
@@ -8,7 +8,7 @@
"dev_raw_url": "https://raw.githubusercontent.com/lkeme/BiliHelper-personal/dev/resources/version.json",
"master_purge_url": "https://cdn.staticaly.com/gh/lkeme/BiliHelper-personal/master/resources/version.json",
"dev_purge_url": "https://cdn.staticaly.com/gh/lkeme/BiliHelper-personal/dev/resources/version.json",
- "version": "2.5.0.250823",
- "update_time": "2025-08-23",
+ "version": "2.5.1.250904",
+ "update_time": "2025-09-04",
"update_description": "程序有更新,请及时线上查看更新哦~"
}
diff --git a/src/Api/Vip/ApiPrivilegeAssets.php b/src/Api/Vip/ApiPrivilegeAssets.php
new file mode 100644
index 0000000..c4244a3
--- /dev/null
+++ b/src/Api/Vip/ApiPrivilegeAssets.php
@@ -0,0 +1,66 @@
+ 'https://big.bilibili.com/mobile/cardBag?closable=1&navhide=1&tab=all'
+ ];
+
+ /**
+ * 获取大会员权益列表
+ * @return array
+ */
+ public static function list(): array
+ {
+ $user = User::parseCookie();
+ //
+ $url = 'https://api.bilibili.com/x/vip/privilege_assets/list';
+ $payload = [
+ 'csrf' => $user['csrf'],
+ ];
+ $headers = array_merge([], self::$headers);
+ return Request::getJson(true, 'app', $url, Sign::common($payload), $headers);
+ }
+
+ /**
+ * 兑换大会员权益
+ * @param string $token
+ * @return array
+ */
+ public static function exchange(string $token): array
+ {
+ $user = User::parseCookie();
+ //
+ $url = 'https://api.bilibili.com/x/vip/privilege_assets/exchange';
+ $payload = [
+ 'token' => $token,
+ 'csrf' => $user['csrf'],
+ ];
+ $headers = array_merge([], self::$headers);
+ return Request::postJson(true, 'app', $url, Sign::common($payload), $headers);
+ }
+}
diff --git a/src/Api/Vip/ApiVipCenter.php b/src/Api/Vip/ApiVipCenter.php
new file mode 100644
index 0000000..c2db36e
--- /dev/null
+++ b/src/Api/Vip/ApiVipCenter.php
@@ -0,0 +1,48 @@
+ 'https://big.bilibili.com/mobile/index'
+ ];
+
+ /**
+ * 大会员中心
+ * @return array
+ */
+ public static function v2(): array
+ {
+ $user = User::parseCookie();
+ //
+ $url = 'https://api.bilibili.com/x/vip/web/vip_center/v2';
+ $payload = [
+ 'csrf' => $user['csrf'],
+ ];
+ $headers = array_merge([], self::$headers);
+ return Request::getJson(true, 'app', $url, Sign::common($payload), $headers);
+ }
+}