diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index c90bfb4ce..f3f18a05e 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -21,7 +21,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v3 with: - dotnet-version: '6.0.x' + dotnet-version: '8.0.x' - name: Publish and Zip Release run: | @@ -47,7 +47,7 @@ jobs: files: './src/Ray.BiliBiliTool.Console/bin/Publish/*.zip' token: ${{ secrets.GITHUB_TOKEN }} name: "BiliBiliToolPro-V${{ steps.release_notes.outputs.version }}" - tag_name: ${{ github.event.inputs.version }} + tag_name: ${{ steps.release_notes.outputs.version }} body: '${{ steps.release_notes.outputs.content }}' discussion_category_name: Announcements generate_release_notes: true diff --git a/.gitignore b/.gitignore index 6a25dffb9..006aee7e4 100644 --- a/.gitignore +++ b/.gitignore @@ -372,3 +372,6 @@ kustomization.yaml # ut coveragereport + +# bruno +bruno/.env diff --git a/CHANGELOG.md b/CHANGELOG.md index c0b04a622..3df171270 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,14 @@ +## 2.2.0 +- Migrate from dotnet 6.0 to dotnet 8.0 +- Add Bruno to document the APIs +- Fix[#824]: Log cookie when qinglong save env failed +- Fix[#648]: Set DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 in qinglong to ignore random "Couldn't find a valid ICU package" issue ## 2.1.3 - Code refactory - Fix[#791]:修复VipBigPoint任务异常导致终止的问题 ## 2.1.2 - Feature: enhancement CICD scripts -- Fix[#728]: compatible with qinglong history versions +- Fix[#728]: compatible with qinglong history versions ## 2.1.1 - Feature: listen ctrl+c at the very beginning - Fix: fix qinglong read cron error diff --git a/Dockerfile b/Dockerfile index 576d105e3..9dbde9f11 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. -FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base WORKDIR /app -FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /code COPY ["src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj", "src/Ray.BiliBiliTool.Console/"] COPY ["src/Ray.BiliBiliTool.DomainService/Ray.BiliBiliTool.DomainService.csproj", "src/Ray.BiliBiliTool.DomainService/"] @@ -25,11 +25,9 @@ WORKDIR /app ENV TIME_ZONE=Asia/Shanghai COPY --from=publish /app/publish . COPY ./docker/scripts/* ./docker/crontab /app/scripts/ +RUN apt-get update RUN ln -fs /usr/share/zoneinfo/$TIME_ZONE /etc/localtime \ && echo $TIME_ZONE > /etc/timezone \ - && cp /etc/apt/sources.list /etc/apt/sources.list.bak \ - && sed -i 's/deb.debian.org/mirrors.163.com/g' /etc/apt/sources.list \ - && sed -i 's/security.debian.org/mirrors.163.com/g' /etc/apt/sources.list \ && apt-get clean \ && apt-get update \ && apt-get install -y cron tzdata tofrodos \ diff --git a/Ray.BiliBiliTool.sln b/Ray.BiliBiliTool.sln index 617db82c4..7297a54a1 100644 --- a/Ray.BiliBiliTool.sln +++ b/Ray.BiliBiliTool.sln @@ -42,7 +42,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution common.props = common.props Dockerfile = Dockerfile LICENSE = LICENSE - publish.bat = publish.bat README.md = README.md EndProjectSection EndProject @@ -66,7 +65,6 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{A93210FD-27B6-40E4-B08D-391F96CA2754}" ProjectSection(SolutionItems) = preProject docker\crontab = docker\crontab - docker\entry.sh = docker\entry.sh docker\README.md = docker\README.md EndProjectSection EndProject @@ -124,7 +122,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BiliAgentTest", "test\BiliA EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{75A9CC5C-DF92-4D72-A14C-625AA902855B}" ProjectSection(SolutionItems) = preProject - docker\build\buildAndPushImage_multiArch.cmd = docker\build\buildAndPushImage_multiArch.cmd docker\build\buildImage.cmd = docker\build\buildImage.cmd docker\build\buildImage_amd64.cmd = docker\build\buildImage_amd64.cmd docker\build\buildImage_arm64.cmd = docker\build\buildImage_arm64.cmd diff --git a/bruno/.env.sample b/bruno/.env.sample new file mode 100644 index 000000000..dc4bb49f9 --- /dev/null +++ b/bruno/.env.sample @@ -0,0 +1,8 @@ +phone= +pwd= +mid= +buvid= +csrf= +access_key= +cookieStr= +device_id= \ No newline at end of file diff --git a/bruno/api.bilibili.com/x/vip_point/task/combine.bru b/bruno/api.bilibili.com/x/vip_point/task/combine.bru new file mode 100644 index 000000000..a74bd3c65 --- /dev/null +++ b/bruno/api.bilibili.com/x/vip_point/task/combine.bru @@ -0,0 +1,64 @@ +meta { + name: combine + type: http + seq: 1 +} + +get { + url: https://api.bilibili.com/x/vip_point/task/combine?access_key={{access_key}}&appKey={{appKey}}&appkey={{appKey}}&bili_local_id={{device_id}}&build=7720200&buvid={{buvid}}&channel=yingyongbao&containerName=AbstractWebActivity&csrf={{csrf}}&device=phone&deviceId=f9abaee74692f9e9&deviceName=samsungNexus&devicePlatform=Android10samsungNexus&device_id={{device_id}}&device_name=samsungNexus&device_platform=Android10samsungNexus&disable_rcmd=0&fingerprint={{device_id}}&isPad=false&localFingerprint={{device_id}}&local_id={{buvid}}&mobi_app=android&modelName=Nexus&networkState=2&networkstate=2&osVer=10&platform=android&sessionID=029d1ab7&statistics={"appId":1,"platform":3,"version":"7.72.0","abtest":""}&statusBarHeight=77&ts=1735731151&sign=1bb77731bc5b2b6948da2c7361fabb26 + body: none + auth: none +} + +params:query { + access_key: {{access_key}} + appKey: {{appKey}} + appkey: {{appKey}} + bili_local_id: {{device_id}} + build: 7720200 + buvid: {{buvid}} + channel: yingyongbao + containerName: AbstractWebActivity + csrf: {{csrf}} + device: phone + deviceId: f9abaee74692f9e9 + deviceName: samsungNexus + devicePlatform: Android10samsungNexus + device_id: {{device_id}} + device_name: samsungNexus + device_platform: Android10samsungNexus + disable_rcmd: 0 + fingerprint: {{device_id}} + isPad: false + localFingerprint: {{device_id}} + local_id: {{buvid}} + mobi_app: android + modelName: Nexus + networkState: 2 + networkstate: 2 + osVer: 10 + platform: android + sessionID: 029d1ab7 + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + statusBarHeight: 77 + ts: 1735731151 + sign: 1bb77731bc5b2b6948da2c7361fabb26 +} + +headers { + Host: api.bilibili.com + Cookie: {{cookieStr}} + native_api_from: h5 + buvid: {{buvid}} + accept: application/json, text/plain, */* + referer: https://big.bilibili.com/mobile/bigPoint/task + content-type: application/json + user-agent: {{user-agent}} + x-bili-trace-id: be9823849864b71718b2fd385b677527:18b2fd385b677527:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3NTk1NTIsImlhdCI6MTczNTczMDQ1MiwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.wg0stqcv1_NO4GwHuC70gzuk-O_ROX5bJJoCKfa5EdA + bili-http-engine: cronet +} diff --git a/bruno/app.bilibili.com/folder.bru b/bruno/app.bilibili.com/folder.bru new file mode 100644 index 000000000..5117601bc --- /dev/null +++ b/bruno/app.bilibili.com/folder.bru @@ -0,0 +1,48 @@ +meta { + name: app.bilibili.com +} + +script:pre-request { + const CryptoJS = require('crypto-js'); + + console.log("start"); + + const md5 = (str) => CryptoJS.MD5(str).toString(CryptoJS.enc.Hex); + + const replacePlaceholders = (body) => { + for (const key in body) { + if (typeof body[key] === 'string') { + // Check if value contains {{}} placeholders + const matches = body[key].match(/{{(.*?)}}/g); + if (matches) { + matches.forEach(match => { + const placeholder = match.slice(2, -2); // Remove the {{ and }} + const value = bru.getEnvVar(placeholder); + body[key] = body[key].replace(match, value); + }); + } + } + } + }; + + function appSign(params, appkey, appsec) { + params.appkey = appkey; + delete body.sign; + const sortedKeys = Object.keys(params).sort(); + const sortedParams = sortedKeys.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&'); + console.log(sortedParams); + return md5(sortedParams + appsec); + } + + const body = req.getBody(); + + if (body && body.hasOwnProperty('sign')) { + replacePlaceholders(body); + const sign = appSign(body, bru.getEnvVar("appKey"), bru.getEnvVar("appSec")); + console.log("calculate sign:" + sign); + + body.sign = sign; + } + + req.setBody(body); +} diff --git a/bruno/app.bilibili.com/pgc/activity/deliver/material/receive.bru b/bruno/app.bilibili.com/pgc/activity/deliver/material/receive.bru new file mode 100644 index 000000000..721caa8b8 --- /dev/null +++ b/bruno/app.bilibili.com/pgc/activity/deliver/material/receive.bru @@ -0,0 +1,96 @@ +meta { + name: receive + type: http + seq: 1 +} + +post { + url: https://app.bilibili.com/pgc/activity/deliver/material/receive + body: formUrlEncoded + auth: none +} + +headers { + Host: api.bilibili.com + buvid: {{buvid}} + fp_local: {{device_id}} + fp_remote: {{device_id}} + session_id: e04d2e05 + env: prod + app-key: android64 + user-agent: {{user-agent}} + x-bili-trace-id: 0564afa825e0e1ec59164fe59367755a:59164fe59367755a:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3NzI2NDcsImlhdCI6MTczNTc0MzU0NywiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.eafhpooLoe2q6cA45_Xrgq1VO-y490pxP5gwJ4qm_ik + bili-http-engine: cronet + Cookie: {{cookieStr}} +} + +body:form-urlencoded { + activity_code: + appkey: {{appKey}} + build: 7720200 + c_locale: zh_CN + channel: yingyongbao + disable_rcmd: 0 + ep_id: 328482 + from_spmid: united.player-video-detail.player.continue + mobi_app: android + platform: android + s_locale: zh_CN + season_id: 12548 + spmid: united.player-video-detail.0.0 + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + ts: 1736179521 + sign: 132d2532467ef649a925aece247cdb4b + access_key: {{access_key}} +} + +docs { + 终端:APP + + 作用:开始大会员赚大积分任务-观看剧集内容 + + 入口: + - 我的->会员中心->赚大积分->查看8项任务,点击“观看剧集内容”,选择视频后触发 + + 传入剧集的id,会返回task_id和token,用于标识该次观看任务 + + 该sample的视频为《让子弹飞》 + + 完整的观看剧集内容任务调用接口如下: + + - 领取:app.bilibili.com/pgc/activity/score/task/receive/v2 + - 开始:app.bilibili.com/pgc/activity/deliver/material/receive + - 上报完成:app.bilibili.com/pgc/activity/deliver/task/complete + + Response Sample: + + ```json + { + "code": 0, + "data": { + "closeType": "close_win", + "container": [], + "showTime": "", + "watch_count_down_cfg": { + "action": "url", + "closeType": "close_win", + "complete_status_desc": "大积分已到账", + "complete_status_jump_url": "https://big.bilibili.com/mobile/bigPoint?navhide=1&closable=1", + "count_down_status_desc": "看${time}获大积分", + "login": true, + "milliseconds": 600000, + "pause_status_desc": "计时暂停", + "showTime": "ENTER", + "task_id": "4320003", + "token": "67ba5888e7" + } + }, + "message": "success" + } + ``` +} diff --git a/bruno/app.bilibili.com/pgc/activity/deliver/task/complete.bru b/bruno/app.bilibili.com/pgc/activity/deliver/task/complete.bru new file mode 100644 index 000000000..7c36642dd --- /dev/null +++ b/bruno/app.bilibili.com/pgc/activity/deliver/task/complete.bru @@ -0,0 +1,70 @@ +meta { + name: complete + type: http + seq: 1 +} + +post { + url: https://app.bilibili.com/pgc/activity/deliver/task/complete + body: formUrlEncoded + auth: none +} + +headers { + Host: api.bilibili.com + buvid: {{buvid}} + fp_local: {{device_id}} + fp_remote: {{device_id}} + session_id: e04d2e05 + env: prod + app-key: android64 + user-agent: {{user-agent}} + x-bili-trace-id: a301946d9621645a707b40973f67755c:707b40973f67755c:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3NzI2NDcsImlhdCI6MTczNTc0MzU0NywiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.eafhpooLoe2q6cA45_Xrgq1VO-y490pxP5gwJ4qm_ik + bili-http-engine: cronet + Cookie: {{cookieStr}} +} + +body:form-urlencoded { + build: 7720200 + c_locale: zh_CN + channel: yingyongbao + disable_rcmd: 0 + mobi_app: android + platform: android + s_locale: zh_CN + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + task_id: 4320003 + token: abe88f72be + access_key: {{access_key}} + timestamp: 1735744760834 + ts: 1735744760 + sign: 2292d647d9b3f6dbd2f99b5a90cbddaf + appkey: {{appKey}} + task_sign: 93a1c64da4c02c31ca7575c08212e08f +} + +docs { + 终端:APP + + 作用:上报完成大会员赚大积分任务-观看剧集内容 + + 入口: + - 我的->会员中心->赚大积分->查看8项任务,点击“观看剧集内容”,挑选视频,观看10分钟后,自动触发 + + 传入剧集的id,会返回task_id和token,用于标识该次观看任务 + + task_sign必传,与sign的生成方式相同。即,先排除掉task_sign和sign,生成签名后赋值给task_sign,然后在签名一次得到sign + + 且只能调用成功一次,第二次及之后会返回400 + + 完整的观看剧集内容任务调用接口如下: + + - 领取:app.bilibili.com/pgc/activity/score/task/receive/v2 + - 开始:app.bilibili.com/pgc/activity/deliver/material/receive + - 上报完成:app.bilibili.com/pgc/activity/deliver/task/complete +} diff --git a/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/dressbuyamount.bru b/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/dressbuyamount.bru new file mode 100644 index 000000000..322152d9c --- /dev/null +++ b/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/dressbuyamount.bru @@ -0,0 +1,73 @@ +meta { + name: dressbuyamount + type: http + seq: 3 +} + +post { + url: https://api.bilibili.com/pgc/activity/score/task/receive/v2 + body: formUrlEncoded + auth: none +} + +headers { + Host: api.bilibili.com + Cookie: {{cookieStr}} + native_api_from: h5 + buvid: {{buvid}} + accept: application/json, text/plain, */* + referer: https://big.bilibili.com/mobile/bigPoint/task + user-agent: {{user-agent}} + x-bili-trace-id: 39dab959605906ee420167e8af677533:420167e8af677533:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3NjI4NDksImlhdCI6MTczNTczMzc0OSwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.EIrjYHrmFeTJXZjxsWki_ZloVvL9IK_aDgpqslMASy0 + bili-http-engine: cronet +} + +body:form-urlencoded { + access_key: {{access_key}} + appKey: {{appKey}} + appkey: {{appKey}} + bili_local_id: {{device_id}} + build: 7720200 + buvid: {{buvid}} + channel: yingyongbao + containerName: AbstractWebActivity + csrf: {{csrf}} + device: phone + deviceId: f9abaee74692f9e9 + deviceName: samsungNexus + devicePlatform: Android10samsungNexus + device_id: {{device_id}} + device_name: samsungNexus + device_platform: Android10samsungNexus + disable_rcmd: 0 + fingerprint: {{device_id}} + isPad: false + localFingerprint: {{device_id}} + local_id: {{buvid}} + mobi_app: android + modelName: Nexus + networkState: 2 + networkstate: 2 + osVer: 10 + platform: android + sessionID: 92c5ad7a + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + statusBarHeight: 77 + taskCode: dressbuyamount + ts: 1735734245 + sign: 293cc4d525cf41cfb8adb69f42185ec0: +} + +docs { + 终端:APP + + 作用:领取大会员赚大积分任务-购买指定装扮商品 + + 入口: + - 我的->会员中心->赚大积分->查看8项任务->领取任务 +} diff --git a/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/ogvwatchnew.bru b/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/ogvwatchnew.bru new file mode 100644 index 000000000..05681852e --- /dev/null +++ b/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/ogvwatchnew.bru @@ -0,0 +1,79 @@ +meta { + name: ogvwatchnew + type: http + seq: 4 +} + +post { + url: https://app.bilibili.com/pgc/activity/score/task/receive/v2 + body: formUrlEncoded + auth: none +} + +headers { + Host: api.bilibili.com + Cookie: {{cookieStr}} + native_api_from: h5 + buvid: {{buvid}} + accept: application/json, text/plain, */* + referer: https://big.bilibili.com/mobile/bigPoint/task + user-agent: {{user-agent}} + x-bili-trace-id: 9e3ed57f35a83d4edb8160805867752f:db8160805867752f:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3NjE2NjQsImlhdCI6MTczNTczMjU2NCwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.YVtwH53dLJ1l6n6aFcvwNZ4MBkgnBPtxE8UfD7u9J4I + bili-http-engine: cronet +} + +body:form-urlencoded { + access_key: {{access_key}} + appKey: {{appKey}} + appkey: {{appKey}} + bili_local_id: {{device_id}} + build: 7720200 + buvid: {{buvid}} + channel: yingyongbao + containerName: AbstractWebActivity + csrf: {{csrf}} + device: phone + deviceId: f9abaee74692f9e9 + deviceName: samsungNexus + devicePlatform: Android10samsungNexus + device_id: {{device_id}} + device_name: samsungNexus + device_platform: Android10samsungNexus + disable_rcmd: 0 + fingerprint: {{device_id}} + isPad: false + localFingerprint: {{device_id}} + local_id: {{buvid}} + mobi_app: android + modelName: Nexus + networkState: 2 + networkstate: 2 + osVer: 10 + platform: android + sessionID: 120548f6 + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + statusBarHeight: 77 + taskCode: ogvwatchnew + ts: 1735733021 + sign: 5cc38f578700cfdb506f7e489abdf442: +} + +docs { + 终端:APP + + 作用:领取大会员赚大积分任务-观看剧集内容 + + 入口: + - 我的->会员中心->赚大积分->查看8项任务->领取任务 + + 完整的观看剧集内容任务调用接口如下: + + - 领取:app.bilibili.com/pgc/activity/score/task/receive/v2 + - 开始:app.bilibili.com/pgc/activity/deliver/material/receive + - 上报完成:app.bilibili.com/pgc/activity/deliver/task/complete +} diff --git a/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/tvodbuy.bru b/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/tvodbuy.bru new file mode 100644 index 000000000..889ab35ba --- /dev/null +++ b/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/tvodbuy.bru @@ -0,0 +1,73 @@ +meta { + name: tvodbuy + type: http + seq: 2 +} + +post { + url: https://api.bilibili.com/pgc/activity/score/task/receive/v2 + body: formUrlEncoded + auth: none +} + +headers { + Host: api.bilibili.com + Cookie: {{cookieStr}} + native_api_from: h5 + buvid: {{buvid}} + accept: application/json, text/plain, */* + referer: https://big.bilibili.com/mobile/bigPoint/task + user-agent: {{user-agent}} + x-bili-trace-id: 39dab959605906ee420167e8af677533:420167e8af677533:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3NjI4NDksImlhdCI6MTczNTczMzc0OSwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.EIrjYHrmFeTJXZjxsWki_ZloVvL9IK_aDgpqslMASy0 + bili-http-engine: cronet +} + +body:form-urlencoded { + access_key: {{access_key}} + appKey: {{appKey}} + appkey: {{appKey}} + bili_local_id: {{device_id}} + build: 7720200 + buvid: {{buvid}} + channel: yingyongbao + containerName: AbstractWebActivity + csrf: {{csrf}} + device: phone + deviceId: f9abaee74692f9e9 + deviceName: samsungNexus + devicePlatform: Android10samsungNexus + device_id: {{device_id}} + device_name: samsungNexus + device_platform: Android10samsungNexus + disable_rcmd: 0 + fingerprint: {{device_id}} + isPad: false + localFingerprint: {{device_id}} + local_id: {{buvid}} + mobi_app: android + modelName: Nexus + networkState: 2 + networkstate: 2 + osVer: 10 + platform: android + sessionID: 92c5ad7a + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + statusBarHeight: 77 + taskCode: tvodbuy + ts: 1735734245 + sign: 293cc4d525cf41cfb8adb69f42185ec0: +} + +docs { + 终端:APP + + 作用:领取大会员赚大积分任务-购买单点付费影片 + + 入口: + - 我的->会员中心->赚大积分->查看8项任务->领取任务 +} diff --git a/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/vipmallbuy.bru b/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/vipmallbuy.bru new file mode 100644 index 000000000..1e554aa0a --- /dev/null +++ b/bruno/app.bilibili.com/pgc/activity/score/task/receive/v2/vipmallbuy.bru @@ -0,0 +1,73 @@ +meta { + name: vipmallbuy + type: http + seq: 1 +} + +post { + url: https://app.bilibili.com/pgc/activity/score/task/receive/v2 + body: formUrlEncoded + auth: none +} + +headers { + Host: api.bilibili.com + Cookie: {{cookieStr}} + native_api_from: h5 + buvid: {{buvid}} + accept: application/json, text/plain, */* + referer: https://big.bilibili.com/mobile/bigPoint/task + user-agent: {{user-agent}} + x-bili-trace-id: 9e3ed57f35a83d4edb8160805867752f:db8160805867752f:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3NjE2NjQsImlhdCI6MTczNTczMjU2NCwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.YVtwH53dLJ1l6n6aFcvwNZ4MBkgnBPtxE8UfD7u9J4I + bili-http-engine: cronet +} + +body:form-urlencoded { + access_key: {{access_key}} + appKey: {{appKey}} + appkey: {{appKey}} + bili_local_id: {{device_id}} + build: 7720200 + buvid: {{buvid}} + channel: yingyongbao + containerName: AbstractWebActivity + csrf: {{csrf}} + device: phone + deviceId: f9abaee74692f9e9 + deviceName: samsungNexus + devicePlatform: Android10samsungNexus + device_id: {{device_id}} + device_name: samsungNexus + device_platform: Android10samsungNexus + disable_rcmd: 0 + fingerprint: {{device_id}} + isPad: false + localFingerprint: {{device_id}} + local_id: {{buvid}} + mobi_app: android + modelName: Nexus + networkState: 2 + networkstate: 2 + osVer: 10 + platform: android + sessionID: 120548f6 + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + statusBarHeight: 77 + taskCode: vipmallbuy + ts: 1735733021 + sign: 5cc38f578700cfdb506f7e489abdf442: +} + +docs { + 终端:APP + + 作用:领取大会员赚大积分任务-购买指定会员购商品 + + 入口: + - 我的->会员中心->赚大积分->查看8项任务->领取任务 +} diff --git a/bruno/app.bilibili.com/x/report/heartbeat/mobile/end.bru b/bruno/app.bilibili.com/x/report/heartbeat/mobile/end.bru new file mode 100644 index 000000000..00964961a --- /dev/null +++ b/bruno/app.bilibili.com/x/report/heartbeat/mobile/end.bru @@ -0,0 +1,76 @@ +meta { + name: end + type: http + seq: 1 +} + +post { + url: https://app.bilibili.com/x/report/heartbeat/mobile + body: formUrlEncoded + auth: none +} + +headers { + Host: api.bilibili.com + buvid: {{buvid}} + fp_local: {{device_id}} + fp_remote: {{device_id}} + session_id: e04d2e05 + env: prod + app-key: android64 + user-agent: {{user-agent}} + x-bili-trace-id: 2c64470432d0c5346a475a449467755d:6a475a449467755d:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3NzI2NDcsImlhdCI6MTczNTc0MzU0NywiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.eafhpooLoe2q6cA45_Xrgq1VO-y490pxP5gwJ4qm_ik + bili-http-engine: cronet +} + +body:form-urlencoded { + access_key: {{access_key}} + actual_played_time: 548 + aid: 726710400 + appkey: {{appKey}} + auto_play: 99 + build: 7720200 + c_locale: zh_CN + channel: yingyongbao + cid: 785731972 + disable_rcmd: 0 + epid: 511578 + epid_status: 13 + extra: {"from_outer_spmid":"activity.h5.0.0"} + from: 12 + from_spmid: united.player-video-detail.player.continue + last_play_progress_time: 638 + list_play_time: 0 + max_play_progress_time: 638 + mid: {{mid}} + miniplayer_play_time: 0 + mobi_app: android + network_type: 1 + paused_time: 0 + platform: android + play_mode: 1 + play_status: 1 + play_type: + played_time: 548 + quality: 64 + report_flow_data: + s_locale: zh_CN + session: 2edcb8dc8ff0b6f13dd685a23aff692b72bf2869 + sid: 41410 + spmid: united.player-video-detail.0.0 + start_ts: 1735744223 + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + sub_type: 1 + total_time: 548 + track_id: + ts: 1735744771 + type: 4 + user_status: 1 + video_duration: 1450 + sign: 1021d178fb342c0c48617d3692c97d46 +} diff --git a/bruno/app.bilibili.com/x/report/heartbeat/mobile/start.bru b/bruno/app.bilibili.com/x/report/heartbeat/mobile/start.bru new file mode 100644 index 000000000..e38b7346d --- /dev/null +++ b/bruno/app.bilibili.com/x/report/heartbeat/mobile/start.bru @@ -0,0 +1,76 @@ +meta { + name: start + type: http + seq: 2 +} + +post { + url: https://app.bilibili.com/x/report/heartbeat/mobile + body: formUrlEncoded + auth: none +} + +headers { + Host: api.bilibili.com + buvid: {{buvid}} + fp_local: {{device_id}} + fp_remote: {{device_id}} + session_id: e04d2e05 + env: prod + app-key: android64 + user-agent: {{user-agent}} + x-bili-trace-id: 8fcda5ac30f6510905b2834bbb67755a:05b2834bbb67755a:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3NzI2NDcsImlhdCI6MTczNTc0MzU0NywiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.eafhpooLoe2q6cA45_Xrgq1VO-y490pxP5gwJ4qm_ik + bili-http-engine: cronet +} + +body:form-urlencoded { + access_key: {{access_key}} + actual_played_time: 0 + aid: 726710400 + appkey: {{appKey}} + auto_play: 99 + build: 7720200 + c_locale: zh_CN + channel: yingyongbao + cid: 785731972 + disable_rcmd: 0 + epid: 511578 + epid_status: 13 + extra: {"from_outer_spmid":"activity.h5.0.0"} + from: 12 + from_spmid: united.player-video-detail.player.continue + last_play_progress_time: 0 + list_play_time: 0 + max_play_progress_time: 0 + mid: {{mid}} + miniplayer_play_time: 0 + mobi_app: android + network_type: 1 + paused_time: 0 + platform: android + play_mode: 1 + play_status: 1 + play_type: + played_time: 0 + quality: 64 + report_flow_data: + s_locale: zh_CN + session: 2edcb8dc8ff0b6f13dd685a23aff692b72bf2869 + sid: 41410 + spmid: united.player-video-detail.0.0 + start_ts: 0 + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + sub_type: 1 + total_time: 0 + track_id: + ts: 1735744223 + type: 4 + user_status: 1 + video_duration: 1450 + sign: 37b0acd3bab7b40a082ce510041a0a2b +} diff --git a/bruno/app.bilibili.com/x/vip_point/task/combine.bru b/bruno/app.bilibili.com/x/vip_point/task/combine.bru new file mode 100644 index 000000000..84edbd92e --- /dev/null +++ b/bruno/app.bilibili.com/x/vip_point/task/combine.bru @@ -0,0 +1,73 @@ +meta { + name: combine + type: http + seq: 1 +} + +get { + url: https://app.bilibili.com/x/vip_point/task/combine?access_key={{access_key}}&appKey={{appKey}}&appkey={{appKey}}&bili_local_id={{device_id}}&build=7720200&buvid={{buvid}}&channel=yingyongbao&containerName=AbstractWebActivity&csrf={{csrf}}&device=phone&deviceId=f9abaee74692f9e9&deviceName=samsungNexus&devicePlatform=Android10samsungNexus&device_id={{device_id}}&device_name=samsungNexus&device_platform=Android10samsungNexus&disable_rcmd=0&fingerprint={{device_id}}&isPad=false&localFingerprint={{device_id}}&local_id={{buvid}}&mobi_app=android&modelName=Nexus&networkState=2&networkstate=2&osVer=10&platform=android&sessionID=120548f6&statistics={"appId":1,"platform":3,"version":"7.72.0","abtest":""}&statusBarHeight=77&ts=1735733022&sign=638c21a29c9b0da27b871f6fd30d22ae + body: none + auth: none +} + +params:query { + access_key: {{access_key}} + appKey: {{appKey}} + appkey: {{appKey}} + bili_local_id: {{device_id}} + build: 7720200 + buvid: {{buvid}} + channel: yingyongbao + containerName: AbstractWebActivity + csrf: {{csrf}} + device: phone + deviceId: f9abaee74692f9e9 + deviceName: samsungNexus + devicePlatform: Android10samsungNexus + device_id: {{device_id}} + device_name: samsungNexus + device_platform: Android10samsungNexus + disable_rcmd: 0 + fingerprint: {{device_id}} + isPad: false + localFingerprint: {{device_id}} + local_id: {{buvid}} + mobi_app: android + modelName: Nexus + networkState: 2 + networkstate: 2 + osVer: 10 + platform: android + sessionID: 120548f6 + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + statusBarHeight: 77 + ts: 1735733022 + sign: 638c21a29c9b0da27b871f6fd30d22ae +} + +headers { + Host: api.bilibili.com + Cookie: {{cookieStr}} + native_api_from: h5 + buvid: {{buvid}} + accept: application/json, text/plain, */* + referer: https://big.bilibili.com/mobile/bigPoint/task + content-type: application/json + user-agent: {{user-agent}} + x-bili-trace-id: a3f5253d65441a9b03cf42f84d67752f:03cf42f84d67752f:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3NjE2NjQsImlhdCI6MTczNTczMjU2NCwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.YVtwH53dLJ1l6n6aFcvwNZ4MBkgnBPtxE8UfD7u9J4I + bili-http-engine: cronet +} + +docs { + 终端:APP + + 作用:获取大会员赚大积分的任务列表 + + 入口: + - 我的->会员中心->赚大积分->查看8项任务 +} diff --git a/bruno/big.bilibili.com/pgc/activity/score/task/sign.bru b/bruno/big.bilibili.com/pgc/activity/score/task/sign.bru new file mode 100644 index 000000000..b8f810e12 --- /dev/null +++ b/bruno/big.bilibili.com/pgc/activity/score/task/sign.bru @@ -0,0 +1,40 @@ +meta { + name: sign + type: http + seq: 1 +} + +post { + url: https://api.bilibili.com/pgc/activity/score/task/sign + body: formUrlEncoded + auth: none +} + +headers { + Host: api.bilibili.com + Cookie: {{cookieStr}} + native_api_from: h5 + buvid: {{buvid}} + accept: application/json, text/plain, */* + referer: https://big.bilibili.com/mobile/index?exp_symbol=release_version&oflAb=1 + user-agent: {{user-agent}} + x-bili-trace-id: 9c642fae280ce80077653eef826774e3:77653eef826774e3:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3MzgxMTEsImlhdCI6MTczNTcwOTAxMSwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.J28IlxZ6SjllQEQkq_OvFUiRYAEL2VhQG_WWBcmNppE + bili-http-engine: cronet +} + +body:form-urlencoded { + access_key: {{access_key}} + appkey: {{appKey}} + csrf: {{csrf}} + disable_rcmd: 0 + mobi_app: android + platform: android + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + ts: 1735713546 + sign: aeaeff881a147dd5cd2c6e24df9dc21b +} diff --git a/bruno/big.bilibili.com/x/vip/experience/add.bru b/bruno/big.bilibili.com/x/vip/experience/add.bru new file mode 100644 index 000000000..7cab117ae --- /dev/null +++ b/bruno/big.bilibili.com/x/vip/experience/add.bru @@ -0,0 +1,41 @@ +meta { + name: add + type: http + seq: 2 +} + +post { + url: https://big.bilibili.com/x/vip/experience/add + body: formUrlEncoded + auth: none +} + +headers { + Host: api.bilibili.com + Cookie: {{cookieStr}} + native_api_from: h5 + buvid: {{buvid}} + accept: application/json, text/plain, */* + referer: https://big.bilibili.com/mobile/index?exp_symbol=release_version&oflAb=1 + user-agent: {{user-agent}} + x-bili-trace-id: 46656ec97cb019beac1da03fd56774d6:ac1da03fd56774d6:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3MzgxMTEsImlhdCI6MTczNTcwOTAxMSwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.J28IlxZ6SjllQEQkq_OvFUiRYAEL2VhQG_WWBcmNppE + bili-http-engine: cronet +} + +body:form-urlencoded { + access_key: {{access_key}} + appkey: {{appKey}} + buvid: {{buvid}} + csrf: {{csrf}} + disable_rcmd: 0 + mobi_app: android + platform: android + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + ts: 1735710395 + sign: 694521e34b88ec0593a8cc3edbc4e117 +} diff --git a/bruno/bruno.json b/bruno/bruno.json new file mode 100644 index 000000000..673ba4265 --- /dev/null +++ b/bruno/bruno.json @@ -0,0 +1,9 @@ +{ + "version": "1", + "name": "Bili", + "type": "collection", + "ignore": [ + "node_modules", + ".git" + ] +} \ No newline at end of file diff --git a/bruno/environments/default.bru b/bruno/environments/default.bru new file mode 100644 index 000000000..62d8077f5 --- /dev/null +++ b/bruno/environments/default.bru @@ -0,0 +1,14 @@ +vars { + phone: {{process.env.phone}} + pwd: {{process.env.pwd}} + mid: {{process.env.mid}} + buvid: {{process.env.buvid}} + csrf: {{process.env.csrf}} + appKey: 1d8b6e7d45233436 + access_key: {{process.env.access_key}} + cookieStr: {{process.env.cookieStr}} + user-agent: Mozilla/5.0 (Linux; Android 10; Nexus Build/KOT49H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.186 Mobile Safari/537.36 os/android model/Nexus build/7720200 osVer/10 sdkInt/29 network/2 BiliApp/7720200 mobi_app/android channel/yingyongbao Buvid/{{buvid}} sessionID/92c5ad7a innerVer/7720210 c_locale/zh_CN s_locale/zh_CN disable_rcmd/0 7.72.0 os/android model/Nexus mobi_app/android build/7720200 channel/yingyongbao innerVer/7720210 osVer/10 network/2 + device_id: {{device_id}} + user-agent-simple: Mozilla/5.0 (Linux; Android 12; SM-S9080 Build/V417IR; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.114 Mobile Safari/537.36 os/android model/SM-S9080 build/7760700 osVer/12 sdkInt/32 network/2 BiliApp/7760700 mobi_app/android channel/bili innerVer/7760710 c_locale/zh_CN s_locale/zh_CN disable_rcmd/0 7.76.0 os/android model/SM-S9080 mobi_app/android build/7760700 channel/bili innerVer/7760710 osVer/12 network/2 + appSec: 560c52ccd288fed045859ed18bffd973 +} diff --git a/bruno/passport.bilibili.com/x/passport-login/oauth2/login.bru b/bruno/passport.bilibili.com/x/passport-login/oauth2/login.bru new file mode 100644 index 000000000..b841a80e8 --- /dev/null +++ b/bruno/passport.bilibili.com/x/passport-login/oauth2/login.bru @@ -0,0 +1,56 @@ +meta { + name: login + type: http + seq: 1 +} + +post { + url: https://passport.bilibili.com/x/passport-login/oauth2/login + body: formUrlEncoded + auth: none +} + +headers { + Host: passport.bilibili.com + buvid: {{buvid}} + env: prod + app-key: android64 + user-agent: Mozilla/5.0 BiliDroid/7.72.0 (bbcallen@gmail.com) os/android model/Nexus mobi_app/android build/7720200 channel/yingyongbao innerVer/7720210 osVer/10 network/2 + x-bili-trace-id: fe7876684669e19624e1290d506774bf:24e1290d506774bf:0:0 + x-bili-aurora-eid: + x-bili-mid: + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3MzI4OTIsImlhdCI6MTczNTcwMzc5MiwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.hEDtIHZoN5Wyoja2hNuPcfy-laa1r05ObiEhJ5gPSt4 + bili-http-engine: cronet + content-type: application/x-www-form-urlencoded; charset=utf-8 +} + +body:form-urlencoded { + appkey: 783bbb7264451d82 + bili_local_id: {{device_id}} + build: 7720200 + buvid: {{buvid}} + c_locale: zh_CN + channel: yingyongbao + device: phone + device_id: {{device_id}} + device_meta: EA0906375AA2116F395747958E296DABD2DB115A596F20FEF9C281BC443B52439A8897F1E1E39D2C396B1320F5B47A22120559402BE3F2F6FAB4089CB04B0BA42436E3E28CDBDB46920F42E9B3C6ABB0D26C1B8E3808C143962BD06CAE0B555F01917334431CEF6E5F0372B1B8043D01FEDE6E8406EAA6580005ECEA5771FA1F12252FCA1DAF83A135061B5950D1A0E98C94B5AB91C5916B5CF9A363977BA21F511D742A58ED1E414E1350CA6CDE755086D72BB9FAA7718B497093723E77CA976C0F6946445E8862923DB59F632C4952446ADABF9B07D6022FBF40C821797FCEE2231F5F7ABBB85C1769CEF82A43A5EF9A662A2FDC9C9E1F028FDC66E46D654838A7D3737092C6AC52C2895903DAC8DAB3DCF14E917A9AA246220C3CFCD33175C55E5A1C122FF73F7E99495DE0EED8FCD4037C4A053372EBACED4C5BCB99AFFB24002936B00E90A6B52B4BBCCF2A4BD9680F16B58864E065B94B9D3C4F7216BED851F830D8BF0FD56B16893914E38095DC928F8A9C00DDABE8A7533245F53509582939293D7307A0839A3FE6CA0974C9FE545D8D796955804E63A65D776FD4160A47FC4C9A45C5C5CA3B233AF162CE8458F20D8762C02815E4F1645276D1764AFC6D0785F94D8D0534E266A316BAC348924E9199A07CBDAEC49869CEC41B0263A5A725C86F154297E3F6F62AA118F0DB34B2B5ABF04E97AADED2820A1AA45E0660FFC34289AB519146F4D59EFFAADE07E83AEE64ED995239DA23F3A8FF73E4735BF913FC8E5742251815DF403AE367526F4D660857799852F39904C5AB0AAA7E5ABCEE2EB05DD50D119A9E0D99B7ADF4AB4EEC86FE3504D4E6F7E255642CC94E26BD14FA28D67CC18BFE055A460E19320E923B44F5EBBD29E0495AC23B81861FFCE52E30E61A27A65C3D0AE4D8A9AB5E4E4E92804553EBA0AB9A53B6E5FA0215ABF5E91AD6F1F53E654617ED23EE4B2A97EE5A05C1F491FA424C13431D1760E792E90E9E1886C2CE4E72F77669BB408D45005E306001D6F9ECC714A539224751E750A73E378F62E158293B3C3AD4354A3580F802F3DE34F9031204380F50C7F0513985B8CA09DC1BF7A78755AF12243BB3227EA00A176EC17005C681569DB6CA2FAA8ADB0454939567BD96608271536D459C42CCA16EA7A55F0CC975F526C278055D36AB45B3F2D72216FFA4B0107A7EC826ED08F8570B3D44BB518FA82A1A9A4E527FEA59A32E5354F5B53B3305AAC80C36488D736E40AE6A530DEBA491D77E44F68E2DE54B074D98D87B8FB2789105C19729E38BF0A01C5B86F9E14750DDE66D8E308D48045E567169F0122500CE1A7C30838F1B84C41C4B55B9AFFA3F3A7E2DF4D86505A93E9EC3C376C8C3BE935D783722C010065EB23DA93D7B338C8DA9C1424FB15866E87160DFB9AD9C2954C9B1D2D568296329FC5FFB8F0A7F1D7C4E3269E95679031791D18EB5447760A6A8BD824D7DFF68119D5B38C78E180410CE877B232BD65770751EEB84A1A76696752304614717403DCB9C57AB5C9F2AF82D3C30C9A15254EC7CB623F52693BC9F15A7416934DB23BD1671BA4A98FCA7AB5E3D037C3655FBF3AFD0D4C6079DE045AB1A00E00469300C0F3F27A482924926319709C20E7A06BEA10E69F975BDF155FD66600729DD0514A896E061ACC14EF9EBD74E5E33B266050F602666CEDB0ED5A35A567048EFAD88AF4CFD54783C23F40F35FC950CEF3A4E4459D745F6FEE67CB09CE8E60BC4A1603AE90680382A90D2A98E9B70BB8497002E8EBCB200AD83317CFAA6CD58663CA16FA3E6145DE9B0AD761033E43C6DC01B14331116EB683037BDAA4341809DCA05E43F80BBDA548EF6D6E1509026F9883F696A19F96BDD58239DE87B1A16F2AABF5A8FF56B25FA4897E5E7EBDECA944732EF157F7AE6475EDB9B17CAB70654119992EBB00C355DB400FCD2671EB7101D9E171B390320109975FE77850A080B1D786DD5AD05D2833B65CCA3626C6FA1884991637C2DFE2DEDD6B76624568AC4E09E884174D3072A11F1584E141D53CE0DEBD9D3109827B33DEC12672663A9093D010FA7E7D6B7F2C4524AB3433D7E2D9B2E40B604D995601FCC81E29997D1BBB39D9C74986BCDEAB84CB3D95529F4B676C12F3DEEE32E62C23DBB1388CFA8DAA5E4F02D53C5545DE65AA023071F6D362A2AB090A9AB7EE1333066835E91564396AAE679644D682515D022C116E6F2DBEAF1EC3A12327825B8132E0872D7BDAE6357D9C657CB68AFCBC1985F33B005347176717CE5317EB47CA0EE3E1F0EE4EC6C07FCE9A61D3B71DDDC9917662AF3BE68407FCCBD973CEA8AF37661781D2B332D0C9D69F2963642937DCAEC62E42678C11EF2DBB1F3EA1F30D5081645C6A43D5A3B539DA8FAF33654D7C41FD5F0AACDF0CEB0E6510A270F3A306ED3C57D13E9FDD530D49EADDAC6BDB93566F4AAF1328CFB20C1D1DE8896120CF3FA6B4710297FD0BE05939FC62E0136F8AF12169534DC83519E2F520541346F1AB93E61E6C1D3ECA062EE9BB6328C2185EA9D36384B542C872D50D2E8BD660E18AE26148ED203596EF04457BC40862A5FC7F23D64019ED7FB6483F72979F3882ADDF890F0E39088B2182C796C5C4120799EF9043C246B5AEC140938D6133EFD2DBF272651754157D3D463DF90E7FD7F692D2261AAEFD91B7FB37CFD646C3008F9E3DDA06C9CCCB294A468289FA1C35F040E3B65FC81635552229D58E1E59B1DF70DEC36083DAB04AED854F9B0915E5A3F038895E1F839730954C76EEB92C2B2B48AFD994C2F2A3EACBFF3B7AAC91240F24A21DD2DCDF772BABA21040977080139F202E84D22CBF15C8D0082AC647D52D3C931C4ECDFED19A4FDB832E551894DC329CB66AEC1C490C002EA2A87BE236789E1038944CF81584701051CD131C9FD4942A6E1AE168FDB9B8FB9FBF64FD0CDA77CC1071F5469FFDBC2AD94B67829814BD3367BE5AE6CE485B4EA943D8047482BDB28B2CFD4C78A1473F126466369711E8543C9D313F7F8E06E6ECDF4F49889D72BCDE39C75514D0FCD027F0B7EBC698BD89B4843440C031CF9C0F63D689B3C1419877BC623D56E0FC1876D9F6E294D6D8D9B7AEC70D28ECB9395F1813A1E197B95ABD2BF8151ADB0D54ED9D59246B485B9D51CA5A624617E71580C40AA966663092F3CE88A559133ADA2352C32AD1F4B6114AB670DEB4BB0BACBA0134E481B12C9B38BEF3DEE328ED49997CDEDB41A94B8F4875FFA108CA78F698953976161C90E8DB99CFFC7740AF12785311B1F554CA497D69EACF83D5BD64926186BC7DFC4C965BE60071F9BEF65ABE0282C67FF0B2C199657FB7D147658607E57D016184A96F8FF7CEDCE6BCD5593A8FF848F2BD1FA23CB6AF63AFAC95BF31557206417F45F3AAB9E193513B1CDB35F74A9D064218D09699143114CB98E8D0463C43C107EDE52EB64E7E032A6217A15BB91A6E117849BF2FCFB5A23CD4A5F111572C57C961271E4E1A6FC85D749686A1F9346CC8CF4A5AF4C031A6F11189AD04C1232BCC05CF7AECA80723E446007F3248780EDF99A21DB5A8CC0ABDFD480CFE0357F7035DD0527B103EA5C4303EB4AA061230187C4DF51D65654EE047E82B19D1B4BBC22027C8D3B597D5FAB7DF992F99DD81EE2DDA6CA6C1C82922ED4C7456A0A5078C20BE8AEC82A509D55CDE8217DEF4C9C504D7358F377C54BE5B2EA10192D7C32B24A14F49DC759812285559510223866DFEF358C00F5D5F3DABBD1228C0A54835F591B788BA543376E4A816596FA3148112FBB3778F32BF3B4C21D608F767CA99CFB7E51424826D20D9F3436545598E8720687172DC5D5F8A6BCBD27E441CE5D0AE672DDD24557A9E8671E63E809DF220EB02B0FF519BFF5F646F92049225A44285E503875719DE7205BE2D472A84B7613A3DBE0DA3F0F668F5545F77B86A5AFEAC127B09E78720A5EF3E127B97CE7370C1E2243298E884FA65CA91A21178A2F4DDC8497364B9E9A37D3901DACA2F3D05D6A71416BFD1A2A33B36964C0CED3C00CCF0AEE0D35054B7BDFDA79198F4EFE7517F2009125C46F4AEF4E044FF438B6583636772E2A0D0CEE5E2555D5BF2A4B0602F6D998319D922936F8D831A9335785DE5169B4CB7CCD00AC2052774E30EE4C33AA8603075A2BB4DFFD3907AB85032A72A23C95DF301ACE087FD36291735CC04A7290069BDA5F1EAEA8ACBD169D73FADE59FA71F530728098FDF42E87123BC87C4870E24105B90B47871C2B7AE9F4029EC26A6B72A6B96758C9504881A535D8B8D3CDE5C8CCFCFD6E9A4DCFA61611413AE1AB248ACF95F95586914FCCD2791B7BA7314F930D2C24CDF520527094C0B5430D3D4B042C2CBA7E0174A633BE17CB97D1AE0A4B9E2D0220F5DAEC396D4A4781901AC61B3A065C18EFEC22E1DD40B47AAF4E464D749227028C63E1B81B6DDA8821D860B414366744A81069C8B7AC71BE44A3C3A2E3054C684900B446F3B534AC5AA325690C38539FF37F26E49B151D352F819777B071C85716640AE82DE9CCFA04B3AA3ECDA1F9553070C577FC6855A14E0C6493B4BCED3680D3896761031871B74F9CE2A630A4185FBD105B90224F2E7AD989F76997048A683EFAE693D521703E5F2AD15A3A9C449DA07A5731F75034C63A84FFA4D6CA3914CF83041FCC33815F46E06C5821136EF6B2325ECC845D227C20D2A698F99C6A8BBA74A5DFC22381E1A087EF26E20583D4A57EB8690C55AC3377C0E5E3E9897B635C2F4506C4AF4F5F40456A462A794095CF4E6ED733C58E924E932D87E00F051391425AFD3E57970AE9830F9E6D7846BBC66F9363DF568D9E6DDE1B496C18D38DD43B08191A7C147927F127B05E2D64EE8839B15968EBBCB55332F561E9E63B85AB048B95B6A80C63B3D7998F8F514D77E9902C70364F657EB3669D208C9E0E008BB76F1723FEAF644CF82111245B649C3EC5C2A52421C8F6B30B03921897067350C20B911FA67512BC7B0EFA9FDDA3300D370489B901605A895FDAF8DD205268C4DB9A9CFD225502DF03A9930843D788C50324D0DDF393897D65E4BB1B9960F0237B58C218382AE361D82B558CEBEA9DA0217D1D55B969FC0A56F8776ED3B874832AC1B71B2908A957391C5CA97FCF13346E6A4F2F39C9924551156D1AEFA500FEEEE335AD0F549AB711BEFACDD7166E8D3AA436BFB8DF6C16AE712A43D221C1D40A7F4F38993213B6CCA83DA41EC3F781613954B3C52899ECBC4B38594C6D3F0D5823795C68B67D014119483092754B388882F03148903ABA902C89F353156256587F62057B53E4F5EB043E0346254AA713A822C6A6DE931AC5F43F8462FC86BAF475B338A63F33DC534D5E5CFC7D4368E1A769A25F5ADD8EAF8020781EB07B9FD30CAC6E7343ABC70250FF724E7C31958FB1876513A43B0ADB807264AF52136FFE68A2BCDBAA8A3F372DD416F689016E544C197B8C116CC94CBD6C4A2DD7A2EFE15FC35D709AD6512144755F8364452CF80AD09C90120DB0C78D322F6F535574CDF5F9F5C04B72E86D4B8602A0656BADEF45FE5F818D628DB4A72337C4FF8CABF129C6EF529A504B0BADC8B89030F0E4BBBC70BAFE3A472DC08847DDA2E5D71C6BA767D80F18B40DA4B8FB1A094E15CFFE77AE5CCB25238B10DD3F298511914F20BC5C11E38F2D8011DEF03A4284E7CF1E525B603BCB61FCFF3342B03B8E1EF6B74F5530DD30D25DB311B148071D56FCA5377F2A7BD41D6348E4DB340DD8E45E12158925A5EB644324125AE882D933AAA0F58DCB03F2A95EBE5501A787EDFF9E067AADB42EDEBBF9753144C84E24336626F1735E3C786B4F6A61CA6C4F36C313097CA9B64FF9A2BE05A678AD55FB2276BA2D3161539320D1389AE6FB0B2D161AD1E7921DECF79A7D814DA30A59F98A7D9640A80A4502E42B7AB0024357B2017353F8361ED497A8DEEFC2C054D1C4EA0BA95637F4153CDB67A408ADFEF0ABE8EA55399382374974D034087E638E0DBBC7274E5E42A9D6D777B3C61A82BA47ED9045FE3F6F063AC86BD5A22AF161036F0B96B19449885F079395271A4CCC9B5A904F00BBF1F432B94DC5BF34BED9AB3FE2FBBF8CB9E2E4DA44ABB262EEA72318409D1A6DE2AE36718FDC5B7E6E90177F245BB92F18684DD5390289E2984F86382FA724081CF6C2F179C94F234064A9B35F62F6ACA14C3EE82AA862215DE77320DE15D6F0E82F349ECD735CEBE6DCFC493A5C93627C81D37371F47371F3625C5ACFBDC721FFF6CAEBF7A46A25D90681BEC8868B9AD9434B34AC75C30F035A9F7AAD16437D80CFA45F0E5F26430A9FF904E3A62EF8E668883DBB5D2C3EC4C4AC56D230B9A93BEC4538CC10F4E20BFDAD8FB5523EEA944825746B78E7CE581324457958FA6E736BCC2FCAA269545458BB63D085F2C08DE4053CC9B4897A007707BB32572693261B86E04B26DE98048A5B37ABBB49886D9997AA34D4A0E0B0AC3CDA15A016EC3B38B02C40D6C9839F0B48F0D8795E6CD0B899A020EB4F8B869E7347061FD2DD263C1361A7AE664B117312AFCC63939D75451087B49C8E86B95A4EEA9A0F00CE43CA81C8BB0194332A57BDF62CB3F681C940B0BB6C06F8ADDCD0D7BBCCAEF87F5FF63073EBBA5508A7D2A6A8567D9F5B297577E83987341A1E5BF61934935DA606A2B1FCA0D12B4235BC188519FC5764F6464809E642B53FAA76DB9FDF8D880AADED5FF58324E0F22C7ECC16D4BE16A81F69103FD5F118AA02E4BC9450383A8B87BE2000064C9FE23D6567A9C8C99CC246B8791D28C60B4B5E0198A07A34A571CEE3B63DDF5F0C25F6761B40797D0EF2D23938AF7600F873F65A3BC42B7A71D039B9C29CC134ED162A684E9104618D7C97C8FFA687A7D48FD55F09853D0C061C158BE47D184084604CD41C4AEBC3C1AD387B63EF41B5C1C58503BFA05A99015B74C3062ACCA33676E1C4D5EC64E20A423946A08553428BAD7D6B01495666F9375E5092E252CFAFACB20340A9B55C9886F76991DFA31BAC377CD852983162E078F5028C47944B019513113B2CB2E4015CE2FC3D8A40AAAE7F0DCE5E4935C796E959700963BA3BCEDFFC464DD76473A3FC3381888FEF753D6D743654603F56A87B3C323AA6D725381A52F7C89E5AE05B96100FC3B077A0501AE8918D807881529C4991663C6233BDB62E3CCBE8A4A73751683BB5BE15661D0992D635E4B1ED6B12A80B7BE6D87FB4CFE546E2FDA3C71E79CC5BE1F4112E3B02E2FAC33661AC208606DCDD418603D396E3E277762EC5C63168EA48374326EE80749423B63F46326E4E9D0D36D68C9C735ECEBB2DD5247C6199CE2B3D5EDC5D919DF07B4ACC87CD35E57E090200F50B8514196BEDCEA0F9D19214AFA3EE875C315E911C1842BFB9DEF6ECE97C5FCC12A0151C29E37316C2B225B8B36BBCBC44B69BD3C712C38D820028DC50264D1E6F6D6162D9209D4FD89E4EF2E79A56BE34C8145A29E83E3D05EB81076B42BD7505183579E0E3A25AA164EFA33FEC0AA7AAF6AA953416ECC762914EB03BCA6592514B4BC9007285A479E422BC15ADEADF0C652CF2719B9A79F71E7EDD2AABF8933B1A06FAD6DFE948B99C5AAA3B07D92A05A9CB1D54A7D342708CF3ECDE444AAF2B9E434D5FB4AB41AABFBD104377C69C3055814B83553E25DA9B0B235BE8FB87A63D8FFD4B95D76B30245A23BF06A33D169A2FF19159FDDCF3382B28BFF68C6DD64E30D9EDCE62A08FE6552165D622A45C9A42A665F5C0F7A24DBB8C76B55494349C9F7F87DE83B37FBC58211F556C9EFC6DEBB1E37883DE50FFCE0CA41912B4CEDCAB0BBF90207CD88CFA485BBB33E458D916952ADCE46431B6DE783143C31A0E1CF0E21EF66542FC17FC8BE2D6FE34325AC37AA22BE0DE92BDBC92282A459A5D74E7161890CC0D4BF41CD437DF31DE31A8BFD7A628FBF870470566655D5E282E3CFD89FEB57FFBA315090952922BA2FAF2F3BD0D7AD8C8E1CBF2CB32E6EC254DCBEABFC0CF303741FABCE6360998F9CF147F4450C54F96AAAD028286E12DB2BCCFC7FB0B2163F28F668D2D9ACBD616847845E71547E121D188DAD69EA6A75909B65446B30C478F254AA3C305DE58DF000B2C11F6B9EE82ED3EB1562D2EEE945C599E5D9BF2C1B0618A919721CB3E2C1A2B8306BFD95D2DEF0B4AF06FDEA71CD8A4B5BCB1F38D7379D772F0DB83960B13A0E269184E9D927A149B1916F3CC1E3352E624FE5C58C1C45B8B06B6072D08F02C29346C0D7B252EAC17BCFD723515C0428F99CD5DA4F58B7E027ABAC931EADD17FB978348629EA6B2AA210E368D80A37C686E1F3E2FF818148A9B69FACEB1E571F0C3F52F794683924CE8C5B6F236F3C93F247C722EC89BB7637F08CD84412FD9A18C9767F74E6286B9938CA984592343B56E6350A85A0FB0819F9B49A6CD4F8C549FAA5399E8A07BEE0EBE54CD6137FC3F5A909B730C1C9FAE2BEFF9316B3457EB99B46B4DCF00EDE7BC23738E2F9108C3631B3C31573C636D7F8047386EBDC115C67097F5D282053E10FE726A9369F22F2D72734E559DCC8B36D3D4FA2E08CA6F4AF32A3FD8897CB88FFECF8CF91D6C0537F160CF56B5B9427E0BFBD968F0659979053476A228ED7047F07A480473C9C04C8EE6892FD7C703B9AFC9B936944EB6E957EAEAB75310F0ADE94B840BB06FD85373C8CD0A54A746E7EA1B42C9F0046C7879A35081F3D25CB877CFE70705188D23C6DD44F2D0D9C881D2991EB64D2923023D152EA2CC0A8804310D4B50142319A2E3C85AB50D75B02C525D69955A900ED33E5F49DB02BF449173651FE1D9F512E46B3117D0214C71B0719726F19B0A59EA691224BF5EBD82ED5815F2B80CA0EF26F7ED2ACECFFBCE6B1CB1372BA53225FD4628B064D565FCE9427A365A1E49AA2FFDF171D21208A5AFDCE7FEB60FDE9F2D1EC0648C6E7A9E8B5C7FE6A5514D238C929A6CBF8CD2464C8E006DFF01A099F6DD154EE7E01E1E79A564F5D27FEDA26E3D687D08F50ABF4F3C459206011ADDE63AC54CB718A60734F3466277158AB6E6FF59BDAF1A36D6C4ADFC6E40A338CAFC8B4F59ADCF1E86A16123B55344B93BDFB37CF17CF4512836D398043E8E4F0C89E1289BD8EAEABC4B9DA0FDA507A4140E95302E9C52FAB622D7644FBB16F7FFBC87C3CE74CFC3E919699E693888D12104D3863D5929CCE1387D408A85DAE5495316B34992CC95280F607EFDA67E73166A7FC6111D94CE6A402C37A9EC67234ECC16FB9E7F3D17ABFCB672C530E56073B68FBD025487DC88C01B6ADDD7DFCC4000EB233CD11D444F068E4E1DF0E9E6E4E06B85CD80FEDDEC6FF5A4AD6F03ED29BC40B999219405AD4466E389F6CE82B14318FA32B1FA0F7CC53159BBA39B6398E03A0617A369C2CB8D991C1A131954C26229B6C133C68C5C311361F5433683314A91F75DF81344D0D7834CD8E6BFABBF6A0A2B0F08347AAE64B96392AD9D00FEE690F388715704B480DEC6AA025728049217799149D191305B7FFCD64EC57A4D671A1FD95A91706C04224C35B3F1D92CB95AB102A92E3CD7DAE6041ED24CB1588F88ED82D9DE4885B4F074EFACDF70CB700176BEEB62312045C950F37795D8666943C4D97554D0850F5F8AD2D7315201E3F214D4C005AFDBED5AD4FB9E7395B9EC7432F20A23F6EB944D7D9CD26BA6AB7E0BFA9E6050DAB043CC6E2772D4F7B6DECD8C7AFE35D6D7BBE512EE47C473456A0F2C97B7890F14D6344658B34A6067C94B0AF7BF4235C2A78F8CF7B59F677F3B5EFC3E891DB6D5DC3C1466A546FE9EF712FB1BC40C3685E014541625574A68891C06B8E11FE501E2DDA57B32EF1DDFD4102793F1CA6808B8E3B0E2058C811C945C2C0823BBA25F0A38684B5E965BB1BCE48E41C90BA910DF0B1C0367CF19A8616F48D77A65A3B39F8833CC54CE708D9CF9B6FC299788335DFE3165B0E4D070EFF602B1588E9204721379440A26C496AACBC1409AE4805FAB0E9FAB25341B92565B09C7591205AF8F2597CB8405094CAC8CF2AE0562866284EA1C35B5B759A877214E5C3056BADCEC3CA4A4747CFB3CAB2EA8F02FEC668722A78CDC6488C04D5C54EC5DD921B7755FE692954309A7AA43298682DB89AAA0AF82BBD4CE9229B4EFB90DF78D49AC1F590556827DDE9071B666FB4E1FB03D19219A132C5FC5ABDFE6B6F504F62268C1479EA87B778F726A48F563DBD7D6A1C9DB0FAE4A872A1F2B873B1E6ED1B8CF02C7C0D58A99EE8B287A50FB2AA04D9258D6FBA6BB53EA50203BBE49D4E7C7E1924E2BA18497DA1B77947B5A5BDCCBE93F7AF9A24E9BF74C47A625637CB9821585DC93BFBF28D01B909DB9190CC82EFF00018388071FE305B04D66C1F613AE7E167EB76F09DA46FC3B14E6DD666621EE24649B203C6C5286A56DA0EA36DC166E5F4D4B88E3003CAEF412E2480FC8ECB333361660275249F4AA339BFF0C56890E9BF1BB5AB7526AE4ED62CE01A2D1968ADDD5A7BC38E5C1C289BE8C185D6C8B537D801A7C5AD939923B0D1D92762753E719D1AFB7D7AA3377B6906E9CEAC848CEFB9BC725D30129542AFEED2BABE1B025839C1108EAAA6A10A0B9B30CF05CE6157BE309F09968A4B4CC291F0221C2C9783B65A3F66E64A21841F4AE7B46A897246E8440F315136FC07499917DB63B8B6FC980B8BD7BA804023A350BD1009AE049EF609C287D6D2EB77CF4FECE55F59B9E4FCC91D2BC599FC46F07F430209A52DFC12734057C59B578BB5959C0D305EECFC679990A50D739954922E57111D0D65C5D5805EF36FE0EFE7A6E8548507D514508E70ABDF13DF85FD9EB9582A22E8EE4A1AAE000627FE1A13C8D4AB02613E3E70E593D1C204712FC81D256F82760C02ED4D85681B9F0DB7120BA0F8D6203767E7EE111B859759F7F9935DE6A9CED4F61AEFF0443D865B36FAA4B7DE70BE9A2C70C6EF1AF0C18D9F1077D5540266D55F67930F7EE5D91A3DFFA2774F7A88B540E3EE3D6C1EFC7505E7FCC8EDCBB4A31308A471E9A8F7018B8D3B8000F304FB8878DD89CB5CAF98EF312DBD2D15C4E9153B0F47B51921C429CBD7B3873FC74C139352FCD83F42367D6C72E23DBF5D640C6B2FA43827673146F44FF46D5B5143AE4137D92E44C87D196CE375B7670E61C4D94C9A1ECCBD873C8703C2A5A85BC847486BB6375F10B85A343F95A8B01E028E22F1064EBFA92808D5A78153F025D9EF1D4FF57CEBFF07DECC463293ED0ADEBA54D21F9AFBD9F506B58FBB5F4A7857EB2AEE6C412F1003DCD4A780EDBC0A7F1B1F669DCEB5DA50C7CA45112AA8FBB8E48215ACAD0C379494BB6C05219BA77BD4166885B25E08685A06CBFA84B4709F5499AEECD9503DDF7C5BA88D379F35500CD35D9C9A74B2EE86FC962DE5A1D6488AFEC573CAF55EAD16413E2531AEA8C7B1F79059EDA8F179C25F6DC80FCF842BDD453C15CFE20A7DB3BF2BB8067880D74F909DC64936583DEA5143EE7D479D53ED60698626A050A962B073E1E9F1F5A1CBE5A0D0ECD4C385271B95806D7190BAA23688AADD2D461C14781424B7B6295F6F56D49F6790569E1B8765B098B476A054161465D0CDD378AD6A24C1EB84A6CC0571AE5E015987246AD2633BD123B62667A536EB330209ACE3BA68EC30F9FD0DB97B3C06CE74953B7EAE7D1E1844F7E4502A58141B1B569E650CA64EC7CC613B07384C557A2B1742A578069E2DE57ED3A0446A55F241F38BBC6AA2FA045F0CA5F01F2E1115A031F4C05A01E1CFFE344107532A0B5549DDBF4683F1C41F66D971A5DBFDE6B077FA01C068718C860E0DCD22AF7840206747CEF5983BB1EF3F198924C3B0E15013938E19DF84257A6ED54CF66FA7F567B7BD2B35DE92DA58CDBFD2F294774DF731920B3A64791E8FE65C1F263F959 + device_name: samsungNexus + device_platform: Android10samsungNexus + device_tourist_id: 22824046377449 + disable_rcmd: 0 + dt: VvUCfbGyEyKA%2FoHRmvCgKyJ%2FzeDQ17WLhT6pA%2BqzF2DGxKKaHBadIZFgk%2BG6ZW%2FP72Ft1nuhWki1%0Ay551QsLAenLneTaD3Rhf7BSXtY5MykDkH9MTWDWyxuWVDwjhLduCzDywgq%2BtxjVgXV1sBQWvyISh%0AkIlGGuAp40TzbQi%2Br0Y%3D%0A + from_pv: main.homepage.avatar-nologin.all.click + from_url: bilibili%3A%2F%2Fpegasus%2Fpromo + local_id: {{buvid}} + login_session_id: f152581bf6b3a1b4bad532f836a4e878 + mobi_app: android + password: {{pwd}} + platform: android + s_locale: zh_CN + statistics: %7B%22appId%22%3A1%2C%22platform%22%3A3%2C%22version%22%3A%227.72.0%22%2C%22abtest%22%3A%22%22%7D + ts: 1735704456 + username: {{phone}} + sign: 8e9d9f9da8d5a9355ef8ba620de75175 +} diff --git a/bruno/passport.bilibili.com/x/passport-login/web/key.bru b/bruno/passport.bilibili.com/x/passport-login/web/key.bru new file mode 100644 index 000000000..9bd487533 --- /dev/null +++ b/bruno/passport.bilibili.com/x/passport-login/web/key.bru @@ -0,0 +1,26 @@ +meta { + name: key + type: http + seq: 1 +} + +get { + url: https://passport.bilibili.com/x/passport-login/web/key + body: none + auth: none +} + +headers { + Host: passport.bilibili.com + buvid: {{buvid}} + env: prod + app-key: android64 + user-agent: Mozilla/5.0 BiliDroid/7.72.0 (bbcallen@gmail.com) os/android model/Nexus mobi_app/android build/7720200 channel/yingyongbao innerVer/7720210 osVer/10 network/2 + x-bili-trace-id: 43e1a54f60cfbf0bb9788d4d9e6774bf:b9788d4d9e6774bf:0:0 + x-bili-aurora-eid: + x-bili-mid: + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3MzI4OTIsImlhdCI6MTczNTcwMzc5MiwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.hEDtIHZoN5Wyoja2hNuPcfy-laa1r05ObiEhJ5gPSt4 + bili-http-engine: cronet +} diff --git a/bruno/passport.bilibili.com/x/relation/followings/simple.bru b/bruno/passport.bilibili.com/x/relation/followings/simple.bru new file mode 100644 index 000000000..759c53877 --- /dev/null +++ b/bruno/passport.bilibili.com/x/relation/followings/simple.bru @@ -0,0 +1,49 @@ +meta { + name: simple + type: http + seq: 1 +} + +get { + url: https://passport.bilibili.com/x/relation/followings/simple?_device=android&_hwid=e0N3QnRBJEV0QiEXaxdrXG8LPgw1UDECYFU0AWJTZQ&access_key={{access_key}}&appkey={{appKey}}&build=7720200&c_locale=zh_CN&channel=yingyongbao&disable_rcmd=0&mobi_app=android&platform=android&s_locale=zh_CN&src=yingyongbao&statistics={"appId":1,"platform":3,"version":"7.72.0","abtest":""}&trace_id=20250101120700037&ts=1735704457&version=7.72.0.7720200&sign=3a7ddaa98dbf792b654bdaabdf3dcd1d + body: none + auth: none +} + +params:query { + _device: android + _hwid: e0N3QnRBJEV0QiEXaxdrXG8LPgw1UDECYFU0AWJTZQ + access_key: {{access_key}} + appkey: {{appKey}} + build: 7720200 + c_locale: zh_CN + channel: yingyongbao + disable_rcmd: 0 + mobi_app: android + platform: android + s_locale: zh_CN + src: yingyongbao + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + trace_id: 20250101120700037 + ts: 1735704457 + version: 7.72.0.7720200 + sign: 3a7ddaa98dbf792b654bdaabdf3dcd1d +} + +headers { + Host: api.bilibili.com + buvid: {{buvid}} + fp_local: {{device_id}} + fp_remote: {{device_id}} + session_id: 3160e892 + env: prod + app-key: android64 + user-agent: Mozilla/5.0 BiliDroid/7.72.0 (bbcallen@gmail.com) os/android model/Nexus mobi_app/android build/7720200 channel/yingyongbao innerVer/7720210 osVer/10 network/2 + x-bili-trace-id: 97831b4bddcb6011ee84ae59806774bf:ee84ae59806774bf:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3MzI4OTIsImlhdCI6MTczNTcwMzc5MiwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.hEDtIHZoN5Wyoja2hNuPcfy-laa1r05ObiEhJ5gPSt4 + bili-http-engine: cronet +} diff --git a/bruno/passport.bilibili.com/x/relation/tag/special.bru b/bruno/passport.bilibili.com/x/relation/tag/special.bru new file mode 100644 index 000000000..f10c5fbc0 --- /dev/null +++ b/bruno/passport.bilibili.com/x/relation/tag/special.bru @@ -0,0 +1,49 @@ +meta { + name: special + type: http + seq: 1 +} + +get { + url: https://passport.bilibili.com/x/relation/tag/special?_device=android&_hwid=e0N3QnRBJEV0QiEXaxdrXG8LPgw1UDECYFU0AWJTZQ&access_key={{access_key}}&appkey={{appKey}}&build=7720200&c_locale=zh_CN&channel=yingyongbao&disable_rcmd=0&mobi_app=android&platform=android&s_locale=zh_CN&src=yingyongbao&statistics={"appId":1,"platform":3,"version":"7.72.0","abtest":""}&trace_id=20250101120700047&ts=1735704467&version=7.72.0.7720200&sign=c49a2ca7bf93e8e65e77fe285fb71b1e + body: none + auth: none +} + +params:query { + _device: android + _hwid: e0N3QnRBJEV0QiEXaxdrXG8LPgw1UDECYFU0AWJTZQ + access_key: {{access_key}} + appkey: {{appKey}} + build: 7720200 + c_locale: zh_CN + channel: yingyongbao + disable_rcmd: 0 + mobi_app: android + platform: android + s_locale: zh_CN + src: yingyongbao + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + trace_id: 20250101120700047 + ts: 1735704467 + version: 7.72.0.7720200 + sign: c49a2ca7bf93e8e65e77fe285fb71b1e +} + +headers { + Host: api.bilibili.com + buvid: {{buvid}} + fp_local: {{device_id}} + fp_remote: {{device_id}} + session_id: 3160e892 + env: prod + app-key: android64 + user-agent: Mozilla/5.0 BiliDroid/7.72.0 (bbcallen@gmail.com) os/android model/Nexus mobi_app/android build/7720200 channel/yingyongbao innerVer/7720210 osVer/10 network/2 + x-bili-trace-id: f8209f943aca4379b5b407142a6774bf:b5b407142a6774bf:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3MzI4OTIsImlhdCI6MTczNTcwMzc5MiwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.hEDtIHZoN5Wyoja2hNuPcfy-laa1r05ObiEhJ5gPSt4 + bili-http-engine: cronet +} diff --git a/bruno/passport.bilibili.com/x/v2/account/myinfo.bru b/bruno/passport.bilibili.com/x/v2/account/myinfo.bru new file mode 100644 index 000000000..97ce44dbc --- /dev/null +++ b/bruno/passport.bilibili.com/x/v2/account/myinfo.bru @@ -0,0 +1,43 @@ +meta { + name: myinfo + type: http + seq: 1 +} + +get { + url: https://passport.bilibili.com/x/v2/account/myinfo?access_key={{access_key}}&appkey=783bbb7264451d82&build=7720200&buvid={{buvid}}&c_locale=zh_CN&channel=yingyongbao&disable_rcmd=0&local_id={{buvid}}&mobi_app=android&platform=android&s_locale=zh_CN&statistics={"appId":1,"platform":3,"version":"7.72.0","abtest":""}&ts=1735704457&sign=b33e7a0aa1aef3d1d4284c759fa12857 + body: none + auth: none +} + +params:query { + access_key: {{access_key}} + appkey: 783bbb7264451d82 + build: 7720200 + buvid: {{buvid}} + c_locale: zh_CN + channel: yingyongbao + disable_rcmd: 0 + local_id: {{buvid}} + mobi_app: android + platform: android + s_locale: zh_CN + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + ts: 1735704457 + sign: b33e7a0aa1aef3d1d4284c759fa12857 +} + +headers { + Host: app.bilibili.com + buvid: {{buvid}} + env: prod + app-key: android64 + user-agent: Mozilla/5.0 BiliDroid/7.72.0 (bbcallen@gmail.com) os/android model/Nexus mobi_app/android build/7720200 channel/yingyongbao innerVer/7720210 osVer/10 network/2 + x-bili-trace-id: 46e70b4538aaf4001079cf97f86774bf:1079cf97f86774bf:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3MzI4OTIsImlhdCI6MTczNTcwMzc5MiwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.hEDtIHZoN5Wyoja2hNuPcfy-laa1r05ObiEhJ5gPSt4 + bili-http-engine: cronet +} diff --git a/bruno/passport.bilibili.com/x/v2/feed/index.bru b/bruno/passport.bilibili.com/x/v2/feed/index.bru new file mode 100644 index 000000000..8e58e02a4 --- /dev/null +++ b/bruno/passport.bilibili.com/x/v2/feed/index.bru @@ -0,0 +1,29 @@ +meta { + name: index + type: http + seq: 1 +} + +get { + url: https://passport.bilibili.com/x/v2/feed/index + body: none + auth: none +} + +headers { + Host: app.bilibili.com + buvid: {{buvid}} + fp_local: {{device_id}} + fp_remote: {{device_id}} + session_id: 3160e892 + env: prod + app-key: android64 + user-agent: Mozilla/5.0 BiliDroid/7.72.0 (bbcallen@gmail.com) os/android model/Nexus mobi_app/android build/7720200 channel/yingyongbao innerVer/7720210 osVer/10 network/2 + x-bili-trace-id: ce74f22f44dec31cc331a61b2a6774bf:c331a61b2a6774bf:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3MzI4OTIsImlhdCI6MTczNTcwMzc5MiwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.hEDtIHZoN5Wyoja2hNuPcfy-laa1r05ObiEhJ5gPSt4 + bili-http-engine: cronet +} diff --git a/bruno/passport.bilibili.com/x/vip/web/vip_center/v2.bru b/bruno/passport.bilibili.com/x/vip/web/vip_center/v2.bru new file mode 100644 index 000000000..0c4236b5c --- /dev/null +++ b/bruno/passport.bilibili.com/x/vip/web/vip_center/v2.bru @@ -0,0 +1,29 @@ +meta { + name: v2 + type: http + seq: 1 +} + +get { + url: https://api.bilibili.com/x/vip/web/vip_center/v2 + body: none + auth: none +} + +headers { + Host: api.bilibili.com + Cookie: {{cookieStr}} + native_api_from: h5 + buvid: {{buvid}} + accept: application/json, text/plain, */* + referer: https://big.bilibili.com/mobile/index?exp_symbol=release_version&oflAb=1 + content-type: application/json + user-agent: {{user-agent}} + x-bili-trace-id: 0b9853d9388b01892edb6939c16774d4:2edb6939c16774d4:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3MzgxMTEsImlhdCI6MTczNTcwOTAxMSwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.J28IlxZ6SjllQEQkq_OvFUiRYAEL2VhQG_WWBcmNppE + bili-http-engine: cronet +} diff --git a/bruno/www.bilibili.com/x/vip_point/task/combine.bru b/bruno/www.bilibili.com/x/vip_point/task/combine.bru new file mode 100644 index 000000000..a9a30b35f --- /dev/null +++ b/bruno/www.bilibili.com/x/vip_point/task/combine.bru @@ -0,0 +1,64 @@ +meta { + name: combine + type: http + seq: 1 +} + +get { + url: https://www.bilibili.com/x/vip_point/task/combine?access_key={{access_key}}&appKey={{appKey}}&appkey={{appKey}}&bili_local_id={{device_id}}&build=7720200&buvid={{buvid}}&channel=yingyongbao&containerName=AbstractWebActivity&csrf={{csrf}}&device=phone&deviceId=f9abaee74692f9e9&deviceName=samsungNexus&devicePlatform=Android10samsungNexus&device_id={{device_id}}&device_name=samsungNexus&device_platform=Android10samsungNexus&disable_rcmd=0&fingerprint={{device_id}}&isPad=false&localFingerprint={{device_id}}&local_id={{buvid}}&mobi_app=android&modelName=Nexus&networkState=2&networkstate=2&osVer=10&platform=android&sessionID=45f5e4c1&statistics={"appId":1,"platform":3,"version":"7.72.0","abtest":""}&statusBarHeight=77&ts=1735714135&sign=36a02edf4927fb34242051a1dec8c1c0 + body: none + auth: none +} + +params:query { + access_key: {{access_key}} + appKey: {{appKey}} + appkey: {{appKey}} + bili_local_id: {{device_id}} + build: 7720200 + buvid: {{buvid}} + channel: yingyongbao + containerName: AbstractWebActivity + csrf: {{csrf}} + device: phone + deviceId: f9abaee74692f9e9 + deviceName: samsungNexus + devicePlatform: Android10samsungNexus + device_id: {{device_id}} + device_name: samsungNexus + device_platform: Android10samsungNexus + disable_rcmd: 0 + fingerprint: {{device_id}} + isPad: false + localFingerprint: {{device_id}} + local_id: {{buvid}} + mobi_app: android + modelName: Nexus + networkState: 2 + networkstate: 2 + osVer: 10 + platform: android + sessionID: 45f5e4c1 + statistics: {"appId":1,"platform":3,"version":"7.72.0","abtest":""} + statusBarHeight: 77 + ts: 1735714135 + sign: 36a02edf4927fb34242051a1dec8c1c0 +} + +headers { + Host: api.bilibili.com + Cookie: {{cookieStr}} + native_api_from: h5 + buvid: {{buvid}} + accept: application/json, text/plain, */* + referer: https://big.bilibili.com/mobile/bigPoint/task + content-type: application/json + user-agent: {{user-agent}} + x-bili-trace-id: 4b01128efdcc4aee05264954296774e5:05264954296774e5:0:0 + x-bili-aurora-eid: UlAAQFkMBVkH + x-bili-mid: {{mid}} + x-bili-aurora-zone: + x-bili-gaia-vtoken: + x-bili-ticket: eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU3MzgxMTEsImlhdCI6MTczNTcwOTAxMSwiYnV2aWQiOiJYVzcyNEQxNzI0Njg3MTlDQzI1NjA1REIyNDI0NzhEMkUxMjE5In0.J28IlxZ6SjllQEQkq_OvFUiRYAEL2VhQG_WWBcmNppE + bili-http-engine: cronet +} diff --git a/common.props b/common.props index e3a3f38b0..e0282d289 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ Ray - 2.1.3 + 2.2.0 $(NoWarn);CS1591;CS0436 diff --git a/docker/README.md b/docker/README.md index 7df2310ab..8c32c6439 100644 --- a/docker/README.md +++ b/docker/README.md @@ -156,9 +156,9 @@ docker run --rm \ ## 7. 其他 -代码编译和发布环境: mcr.microsoft.com/dotnet/sdk:6.0 +代码编译和发布环境: mcr.microsoft.com/dotnet/sdk:8.0 -代码运行环境: mcr.microsoft.com/dotnet/runtime:6.0 +代码运行环境: mcr.microsoft.com/dotnet/runtime:8.0 apt-get 包源用的国内网易的 diff --git a/docker/build/buildImage.cmd b/docker/build/buildImage.cmd index 2f9d0676a..6a845849c 100644 --- a/docker/build/buildImage.cmd +++ b/docker/build/buildImage.cmd @@ -3,6 +3,6 @@ REM start to build echo Start to build docker image @echo on -docker build --tag zai7lou/bilibili_tool_pro:0.2.2 --tag zai7lou/bilibili_tool_pro:latest ../.. +docker build --tag zai7lou/bilibili_tool_pro:latest ../.. @echo off pause diff --git a/docker/build/buildImage_amd64.cmd b/docker/build/buildImage_amd64.cmd index 7542df871..58255a917 100644 --- a/docker/build/buildImage_amd64.cmd +++ b/docker/build/buildImage_amd64.cmd @@ -5,6 +5,6 @@ REM https://www.docker.com/blog/multi-arch-build-and-images-the-simple-way/ REM https://segmentfault.com/a/1190000021166703 echo Start to build docker image with amd64-arch @echo on -docker buildx build --tag zai7lou/bilibili_tool_pro:0.0.5 --output "type=image,push=false" --platform linux/amd64 ../.. +docker buildx build --tag zai7lou/bilibili_tool_pro:latest --output "type=image,push=false" --platform linux/amd64 ../.. @echo off pause diff --git a/docker/sample/docker-compose.yml b/docker/sample/docker-compose.yml index b2a8d404b..cade36c07 100644 --- a/docker/sample/docker-compose.yml +++ b/docker/sample/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3.9' services: bilibili_tool: image: ghcr.io/raywangqvq/bilibili_tool_pro diff --git a/docs/questions.md b/docs/questions.md index 182d96663..9ba3b24de 100644 --- a/docs/questions.md +++ b/docs/questions.md @@ -214,7 +214,7 @@ curl -sSL https://ghproxy.com/https://raw.githubusercontent.com/RayWangQvQ/BiliB Windows: ``` # Run a separate PowerShell process because the script calls exit, so it will end the current PowerShell session. -&powershell -NoProfile -ExecutionPolicy unrestricted -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) --channel 6.0 --no-cdn --verbose" +&powershell -NoProfile -ExecutionPolicy unrestricted -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) --channel 8.0 --no-cdn --verbose" ``` 其他问题请见[官方文档](https://learn.microsoft.com/zh-cn/dotnet/core/tools/dotnet-install-script) diff --git a/docs/runInLocal.md b/docs/runInLocal.md index c45da5b27..6aa999461 100644 --- a/docs/runInLocal.md +++ b/docs/runInLocal.md @@ -2,7 +2,7 @@ -- [1. 任意系统,但已安装`.NET 6.0`](#1-任意系统但已安装net-60) +- [1. 任意系统,但已安装`.NET 8.0`](#1-任意系统但已安装net-80) - [2. Win](#2-win) - [3. Linux:](#3-linux) - [4. macOS](#4-macos) @@ -16,9 +16,9 @@ 对于不是开发者的朋友,可以通过下载 [BiliBiliTool/release](https://github.com/RayWangQvQ/BiliBiliToolPro/releases) 到本地或任意服务器运行。 -## 1. 任意系统,但已安装`.NET 6.0` +## 1. 任意系统,但已安装`.NET 8.0` -任何操作系统,不管是Win还是Linux还是mac,只要已安装了`.NET 6.0` 环境,均可通过下载`net-dependent.zip`运行。 +任何操作系统,不管是Win还是Linux还是mac,只要已安装了`.NET 8.0` 环境,均可通过下载`net-dependent.zip`运行。 下载解压后,进入应用目录,执行`dotnet ./Ray.BiliBiliTool.Console.dll --runTasks=Login` @@ -28,7 +28,7 @@ ![运行图示](imgs/run-exe.png) -P.S.这里的运行环境指的是 `.NET Runtime 6.0.0` ,安装方法可详见 [常见问题](questions.md) 中的 **本地或服务器如何安装.net环境** +P.S.这里的运行环境指的是 `.NET Runtime 8.0.0` ,安装方法可详见 [常见问题](questions.md) 中的 **本地或服务器如何安装.net环境** ## 2. Win diff --git a/podman/build/buildImage.cmd b/podman/build/buildImage.cmd index 087533c3b..6804631c2 100644 --- a/podman/build/buildImage.cmd +++ b/podman/build/buildImage.cmd @@ -3,6 +3,6 @@ REM start to build echo Start to build image @echo on -podman build -t docker.io/zai7lou/bilibili_tool_pro:0.2.2 -t docker.io/zai7lou/bilibili_tool_pro:latest ../.. +podman build -t docker.io/zai7lou/bilibili_tool_pro:latest ../.. @echo off pause diff --git a/qinglong/DefaultTasks/bili_task_base.sh b/qinglong/DefaultTasks/bili_task_base.sh index fc4629f1d..8ce33f909 100644 --- a/qinglong/DefaultTasks/bili_task_base.sh +++ b/qinglong/DefaultTasks/bili_task_base.sh @@ -15,6 +15,7 @@ bili_repo="raywangqvq/bilibilitoolpro" # 仓库地址 bili_branch="" # 分支名,空或_develop prefer_mode=${BILI_MODE:-"dotnet"} # dotnet或bilitool,需要通过环境变量配置 github_proxy=${BILI_GITHUB_PROXY:-""} # 下载github release包时使用的代理,会拼在地址前面,需要通过环境变量配置 +export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 # 解决抽风问题 # Use in the the functions: eval $invocation invocation='say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"' @@ -321,7 +322,7 @@ install_dotnet_by_script() { eval $invocation say "再尝试使用官方脚本安装" - curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 6.0 --no-cdn --verbose + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 8.0 --verbose say "添加到PATH" local exportFile="/root/.bashrc" @@ -353,7 +354,7 @@ install_dotnet() { curl -o packages-microsoft-prod.deb https://packages.microsoft.com/config/debian/$VERSION_ID/packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb - apt-get update && apt-get install -y dotnet-sdk-6.0 + apt-get update && apt-get install -y dotnet-sdk-8.0 } || { install_dotnet_by_script } @@ -367,7 +368,7 @@ install_dotnet() { apk update fi { - apk add dotnet6-sdk + apk add dotnet8-sdk # https://pkgs.alpinelinux.org/packages } || { install_dotnet_by_script } @@ -428,7 +429,6 @@ install() { if check_installed; then say "环境正常,本次无需安装" - return 0 else say "开始安装环境" if [ "$prefer_mode" == "dotnet" ]; then @@ -436,7 +436,6 @@ install() { say_err "安装失败" say_err "请根据文档自行在青龙容器中安装dotnet:https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-$current_linux_os" say_err "或者尝试切换运行模式为bilitool,它不需要安装dotnet:https://github.com/RayWangQvQ/BiliBiliToolPro/blob/develop/qinglong/README.md" - exit 1 } fi @@ -444,10 +443,8 @@ install() { install_bilitool || { say_err "安装失败,请检查日志并重试" say_err "或者尝试切换运行模式为dotnet:https://github.com/RayWangQvQ/BiliBiliToolPro/blob/develop/qinglong/README.md" - exit 1 } fi - return $? fi } diff --git a/qinglong/DefaultTasks/dev/bili_dev_task_base.sh b/qinglong/DefaultTasks/dev/bili_dev_task_base.sh index 84019263e..900bb9480 100644 --- a/qinglong/DefaultTasks/dev/bili_dev_task_base.sh +++ b/qinglong/DefaultTasks/dev/bili_dev_task_base.sh @@ -15,6 +15,7 @@ bili_repo="raywangqvq/bilibilitoolpro" # 仓库地址 bili_branch="_develop" # 分支名,空或_develop prefer_mode=${BILI_MODE:-"dotnet"} # dotnet或bilitool,需要通过环境变量配置 github_proxy=${BILI_GITHUB_PROXY:-""} # 下载github release包时使用的代理,会拼在地址前面,需要通过环境变量配置 +export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 # 解决抽风问题 # Use in the the functions: eval $invocation invocation='say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"' @@ -262,7 +263,7 @@ check_dotnet() { eval $invocation dotnetVersion=$(dotnet --version) - if [[ $dotnetVersion == 6.* ]]; then + if [[ $dotnetVersion == 8.* ]]; then say "已安装dotnet,当前版本:$dotnetVersion" say "which dotnet: $(which dotnet)" return 0 @@ -321,7 +322,7 @@ install_dotnet_by_script() { eval $invocation say "再尝试使用官方脚本安装" - curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 6.0 --no-cdn --verbose + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 8.0 --verbose say "添加到PATH" local exportFile="/root/.bashrc" @@ -353,7 +354,7 @@ install_dotnet() { curl -o packages-microsoft-prod.deb https://packages.microsoft.com/config/debian/$VERSION_ID/packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb - apt-get update && apt-get install -y dotnet-sdk-6.0 + apt-get update && apt-get install -y dotnet-sdk-8.0 } || { install_dotnet_by_script } @@ -367,7 +368,7 @@ install_dotnet() { apk update fi { - apk add dotnet6-sdk + apk add dotnet8-sdk # https://pkgs.alpinelinux.org/packages } || { install_dotnet_by_script } @@ -428,7 +429,6 @@ install() { if check_installed; then say "环境正常,本次无需安装" - return 0 else say "开始安装环境" if [ "$prefer_mode" == "dotnet" ]; then @@ -436,7 +436,6 @@ install() { say_err "安装失败" say_err "请根据文档自行在青龙容器中安装dotnet:https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-$current_linux_os" say_err "或者尝试切换运行模式为bilitool,它不需要安装dotnet:https://github.com/RayWangQvQ/BiliBiliToolPro/blob/develop/qinglong/README.md" - exit 1 } fi @@ -444,10 +443,8 @@ install() { install_bilitool || { say_err "安装失败,请检查日志并重试" say_err "或者尝试切换运行模式为dotnet:https://github.com/RayWangQvQ/BiliBiliToolPro/blob/develop/qinglong/README.md" - exit 1 } fi - return $? fi } diff --git a/qinglong/ray-dotnet-install.sh b/qinglong/ray-dotnet-install.sh index 1310277b2..7c429aad2 100644 --- a/qinglong/ray-dotnet-install.sh +++ b/qinglong/ray-dotnet-install.sh @@ -12,7 +12,7 @@ install_dependency() { # 通过官方脚本安装dotnet install_by_offical() { echo "install by offical script..." - curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 6.0 --no-cdn --verbose + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 8.0 --no-cdn --verbose } # 创建软链接 diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/BaseAppRequest.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/BaseAppRequest.cs new file mode 100644 index 000000000..ab2187ca7 --- /dev/null +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/BaseAppRequest.cs @@ -0,0 +1,29 @@ +namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos; + +public class BaseAppRequest +{ + // public string access_key { get; set; } + // public string appkey { get; set; } + + public string build { get; } = "7720200"; + + public string c_locale { get; } = "zh_CN"; + + public string channel { get; } = Constants.Channel; + + public int disable_rcmd { get; } = 0; + + public string from_spmid { get; } = "united.player-video-detail.player.continue"; + + public string mobi_app { get; } = "android"; + + public string platform { get; } = "android"; + + public string s_locale { get; } = "zh_CN"; + + public string statistics { get; } = "{\"appId\":1,\"platform\":3,\"version\":\"7.72.0\",\"abtest\":\"\"}"; + + // public long ts { get; set; } + + public string sign { get; set; } +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/CompleteOgvWatchRequest.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/CompleteOgvWatchRequest.cs new file mode 100644 index 000000000..86cc27768 --- /dev/null +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/CompleteOgvWatchRequest.cs @@ -0,0 +1,18 @@ +namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.VipTask; + +public class CompleteOgvWatchRequest: BaseAppRequest +{ + public CompleteOgvWatchRequest(long taskId, string token) + { + task_id = taskId; + this.token = token; + } + + public long task_id { get; set; } + + public string token { get; set; } + + public string task_sign { get; set; } + + public long timestamp { get; set; } +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/StartOgvWatchRequest.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/StartOgvWatchRequest.cs new file mode 100644 index 000000000..ce3050576 --- /dev/null +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/StartOgvWatchRequest.cs @@ -0,0 +1,12 @@ +namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.VipTask; + +public class StartOgvWatchRequest: BaseAppRequest +{ + public long ep_id { get; } = 328482; + + public long season_id { get; } = 12548; + + public string Activity_code { get; } = ""; + + public string spmid { get; } = "united.player-video-detail.0.0"; +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/StartOgvWatchResponse.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/StartOgvWatchResponse.cs new file mode 100644 index 000000000..d4edbd457 --- /dev/null +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/StartOgvWatchResponse.cs @@ -0,0 +1,12 @@ +namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.VipTask; + +public class StartOgvWatchResponse +{ + public string closeType { get; set; } + + public string showTime { get; set; } + + public long task_id { get; set; } + + public string token { get; set; } +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/ViewRequest.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/ViewRequest.cs index d2459a3c9..505ce0aac 100644 --- a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/ViewRequest.cs +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/VipTask/ViewRequest.cs @@ -1,32 +1,25 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.VipTask; -namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.VipTask +public class ViewRequest { - public class ViewRequest + public ViewRequest(string position) { - public ViewRequest(string position) - { - this.position=position; - } + this.position=position; + } - public string position { get; set; } + public string position { get; } - public string c_locale { get; set; } = "zh_CN"; + public string c_locale { get; } = "zh_CN"; - public string channel { get; set; } = "html5_search_baidu"; + public string channel { get; } = Constants.Channel; - public int disable_rcmd { get; set; } = 0; + public int disable_rcmd { get; } = 0; - public string mobi_app { get; set; } = "android"; + public string mobi_app { get; } = "android"; - public string platform { get; set; } = "android"; + public string platform { get; } = "android"; - public string s_locale { get; set; } = "zh_CN"; + public string s_locale { get; } = "zh_CN"; - public string statistics { get; set; } = "{\"appId\":1,\"platform\":3,\"version\":\"6.85.0\",\"abtest\":\"\"}"; - } -} + public string statistics { get; } = "{\"appId\":1,\"platform\":3,\"version\":\"6.85.0\",\"abtest\":\"\"}"; +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IVipBigPointApi.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IVipBigPointApi.cs index 8199b316b..c22106895 100644 --- a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IVipBigPointApi.cs +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IVipBigPointApi.cs @@ -2,6 +2,7 @@ using Ray.BiliBiliTool.Agent.Attributes; using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos; using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.VipTask; +using System; using WebApiClientCore.Attributes; namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces; @@ -9,7 +10,7 @@ namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces; /// /// 大会员大积分 /// -[Header("Host", "api.bilibili.com")] +[Header("Host", "api.bilibili.com")] [Header("Referer", "https://big.bilibili.com/mobile/bigPoint/task")] [LogFilter] public interface IVipBigPointApi @@ -34,20 +35,39 @@ public interface IVipBigPointApi /// /// /// + [Obsolete] [HttpPost("/pgc/activity/score/task/receive")] Task Receive([JsonContent] ReceiveOrCompleteTaskRequest request); + /// + /// 领取任务 + /// + /// + /// [HttpPost("/pgc/activity/score/task/receive/v2")] Task ReceiveV2([FormContent] ReceiveOrCompleteTaskRequest request); - + /// + /// 完成任务 + /// + /// + /// [HttpPost("/pgc/activity/score/task/complete")] Task CompleteAsync([JsonContent] ReceiveOrCompleteTaskRequest request); + /// + /// 完成任务 + /// + /// + /// [HttpPost("/pgc/activity/score/task/complete/v2")] Task CompleteV2([FormContent] ReceiveOrCompleteTaskRequest request); - + /// + /// 完成浏览页面任务 + /// + /// + /// [HttpPost("/pgc/activity/deliver/task/complete")] Task ViewComplete([FormContent] ViewRequest request); @@ -61,4 +81,18 @@ public interface IVipBigPointApi /// [HttpPost("/x/vip/experience/add")] Task ObtainVipExperienceAsync([FormContent] VipExperienceRequest request); + + /// + /// 开始观看剧集任务 + /// + /// + /// + Task> StartOgvWatchAsync(StartOgvWatchRequest request); + + /// + /// 完成观看剧集任务 + /// + /// + /// + Task CompleteOgvWatchAsync(CompleteOgvWatchRequest request); } diff --git a/src/Ray.BiliBiliTool.Agent/BiliCookie.cs b/src/Ray.BiliBiliTool.Agent/BiliCookie.cs index 0edd8ea19..0b8a95aed 100644 --- a/src/Ray.BiliBiliTool.Agent/BiliCookie.cs +++ b/src/Ray.BiliBiliTool.Agent/BiliCookie.cs @@ -95,7 +95,7 @@ public override void Check() } if (!result) - throw new Exception($"请正确配置Cookie后再运行,配置方式见 {Constants.SourceCodeUrl}"); + throw new Exception($"请正确配置Cookie后再运行,配置方式见 {Config.Constants.SourceCodeUrl}"); } private string GetPropertyDescription(string propertyName) diff --git a/src/Ray.BiliBiliTool.Agent/BiliHosts.cs b/src/Ray.BiliBiliTool.Agent/BiliHosts.cs index e70d8d275..6b511c28b 100644 --- a/src/Ray.BiliBiliTool.Agent/BiliHosts.cs +++ b/src/Ray.BiliBiliTool.Agent/BiliHosts.cs @@ -3,6 +3,7 @@ public static class BiliHosts { public const string Api = "https://api.bilibili.com"; + public const string App = "https://app.bilibili.com"; public const string Show = "https://show.bilibili.com"; public const string Passport = "http://passport.bilibili.com"; public const string LiveTrace = "https://live-trace.bilibili.com"; diff --git a/src/Ray.BiliBiliTool.Agent/Constants.cs b/src/Ray.BiliBiliTool.Agent/Constants.cs new file mode 100644 index 000000000..cfa65d411 --- /dev/null +++ b/src/Ray.BiliBiliTool.Agent/Constants.cs @@ -0,0 +1,6 @@ +namespace Ray.BiliBiliTool.Agent; + +public static class Constants +{ + public const string Channel = "yingyongbao"; +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Agent/Extensions/ServiceCollectionExtension.cs b/src/Ray.BiliBiliTool.Agent/Extensions/ServiceCollectionExtension.cs index f3edeb53f..367ab5908 100644 --- a/src/Ray.BiliBiliTool.Agent/Extensions/ServiceCollectionExtension.cs +++ b/src/Ray.BiliBiliTool.Agent/Extensions/ServiceCollectionExtension.cs @@ -86,7 +86,7 @@ public static IServiceCollection AddBiliBiliClientApi(this IServiceCollection se services.AddBiliBiliClientApi(BiliHosts.Account, config); services.AddBiliBiliClientApi(BiliHosts.Live, config); - services.AddBiliBiliClientApi(BiliHosts.Api, configApp); + services.AddBiliBiliClientApi(BiliHosts.App, configApp); //qinglong diff --git a/src/Ray.BiliBiliTool.Agent/Ray.BiliBiliTool.Agent.csproj b/src/Ray.BiliBiliTool.Agent/Ray.BiliBiliTool.Agent.csproj index cb5bbf08c..69242f895 100644 --- a/src/Ray.BiliBiliTool.Agent/Ray.BiliBiliTool.Agent.csproj +++ b/src/Ray.BiliBiliTool.Agent/Ray.BiliBiliTool.Agent.csproj @@ -1,15 +1,15 @@  - net6.0 + net8.0 - - - + + + - + diff --git a/src/Ray.BiliBiliTool.Application.Contracts/IVipBigPointAppService.cs b/src/Ray.BiliBiliTool.Application.Contracts/IVipBigPointAppService.cs index db57c0539..e0c841863 100644 --- a/src/Ray.BiliBiliTool.Application.Contracts/IVipBigPointAppService.cs +++ b/src/Ray.BiliBiliTool.Application.Contracts/IVipBigPointAppService.cs @@ -1,22 +1,12 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Text; -using System.Threading.Tasks; -using Ray.BiliBiliTool.DomainService.Dtos; +using System.ComponentModel; -namespace Ray.BiliBiliTool.Application.Contracts -{ - /// - /// 每日自动任务 - /// - [Description("VipBigPoint")] - - public interface IVipBigPointAppService : IAppService - { - Task VipExpress(); - Task WatchBangumi(); - } +namespace Ray.BiliBiliTool.Application.Contracts; +/// +/// 每日自动任务 +/// +[Description("VipBigPoint")] -} +public interface IVipBigPointAppService : IAppService +{ +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Application.Contracts/Ray.BiliBiliTool.Application.Contracts.csproj b/src/Ray.BiliBiliTool.Application.Contracts/Ray.BiliBiliTool.Application.Contracts.csproj index 90b5e4c9b..1bdacc669 100644 --- a/src/Ray.BiliBiliTool.Application.Contracts/Ray.BiliBiliTool.Application.Contracts.csproj +++ b/src/Ray.BiliBiliTool.Application.Contracts/Ray.BiliBiliTool.Application.Contracts.csproj @@ -1,11 +1,11 @@  - net6.0 + net8.0 - + diff --git a/src/Ray.BiliBiliTool.Application/DailyTaskAppService.cs b/src/Ray.BiliBiliTool.Application/DailyTaskAppService.cs index 191c080f2..6b4036875 100644 --- a/src/Ray.BiliBiliTool.Application/DailyTaskAppService.cs +++ b/src/Ray.BiliBiliTool.Application/DailyTaskAppService.cs @@ -52,7 +52,7 @@ public DailyTaskAppService( BiliCookie biliCookie) { _logger = logger; - _expDic = dicOptions.Get(Constants.OptionsNames.ExpDictionaryName); + _expDic = dicOptions.Get(Config.Constants.OptionsNames.ExpDictionaryName); _accountDomainService = accountDomainService; _videoDomainService = videoDomainService; _articleDomainService = articleDomainService; diff --git a/src/Ray.BiliBiliTool.Application/LoginTaskAppService.cs b/src/Ray.BiliBiliTool.Application/LoginTaskAppService.cs index 06571f45c..884adc3d1 100644 --- a/src/Ray.BiliBiliTool.Application/LoginTaskAppService.cs +++ b/src/Ray.BiliBiliTool.Application/LoginTaskAppService.cs @@ -1,88 +1,63 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.FileProviders; -using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using QRCoder; using Ray.BiliBiliTool.Agent; -using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Passport; -using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos; -using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces; -using Ray.BiliBiliTool.Agent.QingLong; using Ray.BiliBiliTool.Application.Attributes; using Ray.BiliBiliTool.Application.Contracts; using Ray.BiliBiliTool.Infrastructure.Enums; using System.Threading; using Ray.BiliBiliTool.DomainService.Interfaces; -using Ray.BiliBiliTool.Infrastructure.Cookie; -namespace Ray.BiliBiliTool.Application +namespace Ray.BiliBiliTool.Application; + +public class LoginTaskAppService( + IConfiguration configuration, + ILogger logger, + ILoginDomainService loginDomainService) + : AppService, ILoginTaskAppService { - public class LoginTaskAppService : AppService, ILoginTaskAppService + [TaskInterceptor("扫码登录", TaskLevel.One)] + public override async Task DoTaskAsync(CancellationToken cancellationToken = default) { - private readonly ILogger _logger; - private readonly ILoginDomainService _loginDomainService; - private readonly IConfiguration _configuration; + //扫码登录 + var cookieInfo = await QrCodeLoginAsync(cancellationToken); + if (cookieInfo == null) return; - public LoginTaskAppService( - IConfiguration configuration, - ILogger logger, - ILoginDomainService loginDomainService) - { - _configuration = configuration; - _logger = logger; - _loginDomainService = loginDomainService; - } + //set cookie + cookieInfo = await SetCookiesAsync(cookieInfo, cancellationToken); - [TaskInterceptor("扫码登录", TaskLevel.One)] - public override async Task DoTaskAsync(CancellationToken cancellationToken) - { - //扫码登录 - var cookieInfo = await QrCodeLoginAsync(cancellationToken); - if (cookieInfo == null) return; + //持久化cookie + await SaveCookieAsync(cookieInfo, cancellationToken); + } - //set cookie - cookieInfo = await SetCookiesAsync(cookieInfo, cancellationToken); + [TaskInterceptor("获取二维码")] + private async Task QrCodeLoginAsync(CancellationToken cancellationToken) + { + var biliCookie = await loginDomainService.LoginByQrCodeAsync(cancellationToken); + return biliCookie; + } - //持久化cookie - await SaveCookieAsync(cookieInfo, cancellationToken); - } + [TaskInterceptor("Set Cookie")] + private async Task SetCookiesAsync(BiliCookie biliCookie, CancellationToken cancellationToken) + { + var ck= await loginDomainService.SetCookieAsync(biliCookie, cancellationToken); + return ck; + } - [TaskInterceptor("获取二维码", TaskLevel.Two)] - protected async Task QrCodeLoginAsync(CancellationToken cancellationToken) - { - var biliCookie = await _loginDomainService.LoginByQrCodeAsync(cancellationToken); - return biliCookie; - } + [TaskInterceptor("持久化Cookie")] + private async Task SaveCookieAsync(BiliCookie ckInfo, CancellationToken cancellationToken) + { + var platformType = configuration.GetSection("PlateformType").Get(); + logger.LogInformation("当前运行平台:{platform}",platformType); - [TaskInterceptor("Set Cookie", TaskLevel.Two)] - protected async Task SetCookiesAsync(BiliCookie biliCookie, CancellationToken cancellationToken) + //更新cookie到青龙env + if (platformType == PlatformType.QingLong) { - var ck= await _loginDomainService.SetCookieAsync(biliCookie, cancellationToken); - return ck; + await loginDomainService.SaveCookieToQinLongAsync(ckInfo, cancellationToken); + return; } - [TaskInterceptor("持久化Cookie", TaskLevel.Two)] - protected async Task SaveCookieAsync(BiliCookie ckInfo, CancellationToken cancellationToken) - { - var platformType = _configuration.GetSection("PlateformType").Get(); - _logger.LogInformation("当前运行平台:{platform}",platformType); - - //更新cookie到青龙env - if (platformType == PlatformType.QingLong) - { - await _loginDomainService.SaveCookieToQinLongAsync(ckInfo, cancellationToken); - return; - } - - //更新cookie到json - await _loginDomainService.SaveCookieToJsonFileAsync(ckInfo, cancellationToken); - } + //更新cookie到json + await loginDomainService.SaveCookieToJsonFileAsync(ckInfo, cancellationToken); } -} +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Application/Ray.BiliBiliTool.Application.csproj b/src/Ray.BiliBiliTool.Application/Ray.BiliBiliTool.Application.csproj index 46d04486a..ff2aa17da 100644 --- a/src/Ray.BiliBiliTool.Application/Ray.BiliBiliTool.Application.csproj +++ b/src/Ray.BiliBiliTool.Application/Ray.BiliBiliTool.Application.csproj @@ -1,14 +1,14 @@  - net6.0 + net8.0 - - - - + + + + diff --git a/src/Ray.BiliBiliTool.Application/VipBigPointAppService.cs b/src/Ray.BiliBiliTool.Application/VipBigPointAppService.cs index 73979d46c..e267ed9e4 100644 --- a/src/Ray.BiliBiliTool.Application/VipBigPointAppService.cs +++ b/src/Ray.BiliBiliTool.Application/VipBigPointAppService.cs @@ -55,26 +55,27 @@ public VipBigPointAppService( public override async Task DoTaskAsync(CancellationToken cancellationToken = default) { // TODO 解决taskInfo在一个任务出错后,后续的任务均会报空引用错误 - var ui = await GetUserInfo(); + var userInfo = await GetUserInfo(); - if (ui.GetVipType() == VipType.None) + if (userInfo.GetVipType() == VipType.None) { - _logger.LogInformation("当前不是大会员或已过期,跳过任务"); + _logger.LogInformation("当前不是大会员,跳过任务"); return; } - var re = await _vipApi.GetTaskListAsync(); - - if (re.Code != 0) throw new Exception(re.ToJsonStr()); - - VipTaskInfo taskInfo = re.Data; + var allTasks = await _vipApi.GetTaskListAsync(); + if (allTasks.Code != 0) throw new Exception(allTasks.ToJsonStr()); + VipTaskInfo taskInfo = allTasks.Data; taskInfo.LogInfo(_logger); - await VipExpress(); + await VipExpressAsync(); //签到 taskInfo = await Sign(taskInfo); + //领取 + taskInfo = await ReceiveTasksAsync(taskInfo); + //福利任务 taskInfo = await Bonus(taskInfo); @@ -82,7 +83,6 @@ public override async Task DoTaskAsync(CancellationToken cancellationToken = def taskInfo = await Privilege(taskInfo); //日常任务 - //浏览追番频道页10秒 taskInfo = await ViewAnimate(taskInfo); @@ -93,21 +93,26 @@ public override async Task DoTaskAsync(CancellationToken cancellationToken = def taskInfo = await ViewDressMall(taskInfo); //观看剧集内容 - taskInfo = await ViewVideo(taskInfo); - - //领取购买任务 - taskInfo = await BuyVipVideo(taskInfo); - taskInfo = await BuyVipMall(taskInfo); + taskInfo = await OgvWatchAsync(taskInfo); taskInfo.LogInfo(_logger); } + [TaskInterceptor("测试Cookie")] + private async Task GetUserInfo() + { + UserInfo userInfo = await _loginDomainService.LoginByCookie(); + if (userInfo == null) throw new Exception("登录失败,请检查Cookie"); //终止流程 + + return userInfo; + } + /// /// 领取大会员专属经验包 /// - public async Task VipExpress() + [TaskInterceptor("大会员经验领取任务", TaskLevel.Two, false)] + private async Task VipExpressAsync() { - _logger.LogInformation("大会员经验领取任务开始"); var re = await _vipApi.GetVouchersInfoAsync(); if (re.Code == 0) { @@ -151,15 +156,6 @@ public async Task VipExpress() } } - [TaskInterceptor("测试Cookie")] - private async Task GetUserInfo() - { - UserInfo userInfo = await _loginDomainService.LoginByCookie(); - if (userInfo == null) throw new Exception("登录失败,请检查Cookie"); //终止流程 - - return userInfo; - } - [TaskInterceptor("签到", TaskLevel.Two, false)] private async Task Sign(VipTaskInfo info) { @@ -186,6 +182,31 @@ private async Task Sign(VipTaskInfo info) return info; } + [TaskInterceptor("领取任务", TaskLevel.Two, false)] + private async Task ReceiveTasksAsync(VipTaskInfo info) + { + const string moduleCode = "日常任务"; + + var module = info.Task_info.Modules.FirstOrDefault(x => x.module_title == moduleCode); + var needReceiveTasks= module? + .common_task_item + .Where(x => x.state == 0) + .ToList(); + if (needReceiveTasks == null || !needReceiveTasks.Any()) + { + _logger.LogInformation("均已领取,跳过"); + return info; + } + + foreach (var targetTask in needReceiveTasks) + { + _logger.LogInformation("开始领取任务:{task}", targetTask.title); + await TryReceive(targetTask.task_code); + } + + return info; + } + [TaskInterceptor("福利任务", TaskLevel.Two, false)] private async Task Bonus(VipTaskInfo info) { @@ -372,11 +393,11 @@ private async Task ViewVipMall(VipTaskInfo info) return info; } - [TaskInterceptor("观看剧集内容", TaskLevel.Two, false)] - private async Task ViewVideo(VipTaskInfo info) + [TaskInterceptor("浏览装扮商城主页", TaskLevel.Two, false)] + private async Task ViewDressMall(VipTaskInfo info) { const string moduleCode = "日常任务"; - const string taskCode = "ogvwatchnew"; + const string taskCode = "dress-view"; CommonTaskItem targetTask = GetTarget(info, moduleCode, taskCode); @@ -386,7 +407,7 @@ private async Task ViewVideo(VipTaskInfo info) return info; } - // 如果状态不等于3,则做 + //如果状态不等于3,则做 if (targetTask.state == 3) { _logger.LogInformation("已完成,跳过"); @@ -401,82 +422,27 @@ private async Task ViewVideo(VipTaskInfo info) } _logger.LogInformation("开始完成任务"); + var re = await CompleteV2(targetTask.task_code); - // 观看剧集内容 - _logger.LogInformation("api变更,暂未实现"); - - return info; - } - - [TaskInterceptor("购买单点付费影片(仅领取)", TaskLevel.Two, false)] - private async Task BuyVipVideo(VipTaskInfo info) - { - const string moduleCode = "日常任务"; - const string taskCode = "tvodbuy"; - - CommonTaskItem targetTask = GetTarget(info, moduleCode, taskCode); - - if (targetTask == null) - { - _logger.LogInformation("任务失效"); - return info; - } - - if (targetTask.state is 3 or 1) - { - var re = targetTask.state == 1 ? "已领取" : "已完成"; - _logger.LogInformation("{re},跳过", re); - return info; - } - - //0需要领取 - if (targetTask.state == 0) - { - _logger.LogInformation("开始领取任务"); - await TryReceive(targetTask.task_code); - } - - return info; - } - - [TaskInterceptor("购买指定会员购商品(仅领取)", TaskLevel.Two, false)] - private async Task BuyVipMall(VipTaskInfo info) - { - const string moduleCode = "日常任务"; - const string taskCode = "vipmallbuy"; - - CommonTaskItem targetTask = GetTarget(info, moduleCode, taskCode); - - if (targetTask == null) - { - _logger.LogInformation("任务失效"); - return info; - } - - if (targetTask.state is 3 or 1) + //确认 + if (re) { - var re = targetTask.state == 1 ? "已领取" : "已完成"; - _logger.LogInformation("{re},跳过", re); - return info; - } + var infoResult = await _vipApi.GetTaskListAsync(); + if (infoResult.Code != 0) throw new Exception(infoResult.ToJsonStr()); + info = infoResult.Data; + targetTask = GetTarget(info, moduleCode, taskCode); - //0需要领取 - if (targetTask.state == 0) - { - _logger.LogInformation("开始领取任务"); - await TryReceive(targetTask.task_code); + _logger.LogInformation("确认:{re}", targetTask.state == 3 && targetTask.complete_times >= 1); } return info; } - [TaskInterceptor("浏览装扮商城主页", TaskLevel.Two, false)] - private async Task ViewDressMall(VipTaskInfo info) + [TaskInterceptor("观看剧集", TaskLevel.Two, false)] + private async Task OgvWatchAsync(VipTaskInfo info) { const string moduleCode = "日常任务"; - const string taskCode = "dress-view"; - - //var code = "dress-view"; + const string taskCode = "ogvwatchnew"; CommonTaskItem targetTask = GetTarget(info, moduleCode, taskCode); @@ -500,19 +466,7 @@ private async Task ViewDressMall(VipTaskInfo info) await TryReceive(targetTask.task_code); } - _logger.LogInformation("开始完成任务"); - var re = await CompleteV2(targetTask.task_code); - - //确认 - if (re) - { - var infoResult = await _vipApi.GetTaskListAsync(); - if (infoResult.Code != 0) throw new Exception(infoResult.ToJsonStr()); - info = infoResult.Data; - targetTask = GetTarget(info, moduleCode, taskCode); - - _logger.LogInformation("确认:{re}", targetTask.state == 3 && targetTask.complete_times >= 1); - } + _logger.LogInformation("暂未实现"); return info; } @@ -536,7 +490,7 @@ private async Task TryReceive(string taskCode) try { var request = new ReceiveOrCompleteTaskRequest(taskCode); - re = await _vipApi.Receive(request); + re = await _vipApi.ReceiveV2(request); if (re.Code == 0) _logger.LogInformation("领取任务成功"); else @@ -603,7 +557,7 @@ private async Task CompleteView(string code) } } - public async Task WatchBangumi() + private async Task WatchBangumi() { if (_vipBigPointOptions.ViewBangumiList == null || _vipBigPointOptions.ViewBangumiList.Count == 0) return false; diff --git a/src/Ray.BiliBiliTool.Config/Ray.BiliBiliTool.Config.csproj b/src/Ray.BiliBiliTool.Config/Ray.BiliBiliTool.Config.csproj index 1295b7399..40557d41a 100644 --- a/src/Ray.BiliBiliTool.Config/Ray.BiliBiliTool.Config.csproj +++ b/src/Ray.BiliBiliTool.Config/Ray.BiliBiliTool.Config.csproj @@ -1,16 +1,16 @@  - net6.0 + net8.0 - - - - - - + + + + + + diff --git a/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj b/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj index 7900ba23f..d68112340 100644 --- a/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj +++ b/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj @@ -4,7 +4,7 @@ Exe - net6.0 + net8.0 3cc5407e-fe0e-4df6-a127-7385c75abd8a Linux ..\.. @@ -29,22 +29,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/src/Ray.BiliBiliTool.DomainService/DonateCoinDomainService.cs b/src/Ray.BiliBiliTool.DomainService/DonateCoinDomainService.cs index 7e3eb9b70..9867f8625 100644 --- a/src/Ray.BiliBiliTool.DomainService/DonateCoinDomainService.cs +++ b/src/Ray.BiliBiliTool.DomainService/DonateCoinDomainService.cs @@ -60,8 +60,8 @@ IVideoApi videoApi _videoDomainService = videoDomainService; _relationApi = relationApi; _videoApi = videoApi; - _expDic = expDicOptions.Get(Constants.OptionsNames.ExpDictionaryName); - _donateContinueStatusDic = donateContinueStatusDicOptions.Get(Constants.OptionsNames.DonateCoinCanContinueStatusDictionaryName); + _expDic = expDicOptions.Get(Config.Constants.OptionsNames.ExpDictionaryName); + _donateContinueStatusDic = donateContinueStatusDicOptions.Get(Config.Constants.OptionsNames.DonateCoinCanContinueStatusDictionaryName); } /// diff --git a/src/Ray.BiliBiliTool.DomainService/Interfaces/ILoginDomainService.cs b/src/Ray.BiliBiliTool.DomainService/Interfaces/ILoginDomainService.cs index f323b8e16..0fc4215f6 100644 --- a/src/Ray.BiliBiliTool.DomainService/Interfaces/ILoginDomainService.cs +++ b/src/Ray.BiliBiliTool.DomainService/Interfaces/ILoginDomainService.cs @@ -1,38 +1,38 @@ using System.Threading; using System.Threading.Tasks; using Ray.BiliBiliTool.Agent; -using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos; -namespace Ray.BiliBiliTool.DomainService.Interfaces +namespace Ray.BiliBiliTool.DomainService.Interfaces; + +/// +/// 账户 +/// +public interface ILoginDomainService : IDomainService { /// - /// 账户 + /// 扫描二维码登录 /// - public interface ILoginDomainService : IDomainService - { - /// - /// 扫描二维码登录 - /// - /// - Task LoginByQrCodeAsync(CancellationToken cancellationToken); + /// + Task LoginByQrCodeAsync(CancellationToken cancellationToken); - /// - /// Set Cookie - /// - /// - /// - Task SetCookieAsync(BiliCookie cookie, CancellationToken cancellationToken); + /// + /// Set Cookie + /// + /// + /// + Task SetCookieAsync(BiliCookie cookie, CancellationToken cancellationToken); - /// - /// 持久化Cookie到配置文件 - /// - /// - Task SaveCookieToJsonFileAsync(BiliCookie ckInfo, CancellationToken cancellationToken); + /// + /// 持久化Cookie到配置文件 + /// + /// + Task SaveCookieToJsonFileAsync(BiliCookie ckInfo, CancellationToken cancellationToken); - /// - /// 持久化Cookie到青龙环境变量 - /// - /// - Task SaveCookieToQinLongAsync(BiliCookie ckInfo, CancellationToken cancellationToken); - } -} + /// + /// 持久化Cookie到青龙环境变量 + /// + /// + /// + /// + Task SaveCookieToQinLongAsync(BiliCookie ckInfo, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.DomainService/LoginDomainService.cs b/src/Ray.BiliBiliTool.DomainService/LoginDomainService.cs index 6a834650c..b0a767de0 100644 --- a/src/Ray.BiliBiliTool.DomainService/LoginDomainService.cs +++ b/src/Ray.BiliBiliTool.DomainService/LoginDomainService.cs @@ -19,219 +19,203 @@ using Ray.BiliBiliTool.Agent.QingLong; using Ray.BiliBiliTool.Infrastructure.Cookie; -namespace Ray.BiliBiliTool.DomainService +namespace Ray.BiliBiliTool.DomainService; + +/// +/// 账户 +/// +public class LoginDomainService( + ILogger logger, + IPassportApi passportApi, + IHostEnvironment hostingEnvironment, + IQingLongApi qingLongApi, + IHomeApi homeApi, + IConfiguration configuration) + : ILoginDomainService { - /// - /// 账户 - /// - public class LoginDomainService : ILoginDomainService + public async Task LoginByQrCodeAsync(CancellationToken cancellationToken) { - private readonly ILogger _logger; - private readonly IPassportApi _passportApi; - private readonly IHostEnvironment _hostingEnvironment; - private readonly IQingLongApi _qingLongApi; - private readonly IHomeApi _homeApi; - private readonly IConfiguration _configuration; - - public LoginDomainService( - ILogger logger, - IPassportApi passportApi, - IHostEnvironment hostingEnvironment, - IQingLongApi qingLongApi, - IHomeApi homeApi, - IConfiguration configuration) + BiliCookie cookieInfo = null; + + var re = await passportApi.GenerateQrCode(); + if (re.Code != 0) { - _logger = logger; - _passportApi = passportApi; - _hostingEnvironment = hostingEnvironment; - _qingLongApi = qingLongApi; - _homeApi = homeApi; - _configuration = configuration; + logger.LogWarning("获取二维码失败:{msg}", re.ToJsonStr()); + return null; } - public async Task LoginByQrCodeAsync(CancellationToken cancellationToken) - { - BiliCookie cookieInfo = null; + var url = re.Data.Url; + GenerateQrCode(url); - var re = await _passportApi.GenerateQrCode(); - if (re.Code != 0) - { - _logger.LogWarning("获取二维码失败:{msg}", re.ToJsonStr()); - return null; - } + var online = GetOnlinePic(url); + logger.LogInformation(Environment.NewLine + Environment.NewLine); + logger.LogInformation("如果上方二维码显示异常,或扫描失败,请使用浏览器访问如下链接,查看高清二维码:"); + logger.LogInformation(online + Environment.NewLine + Environment.NewLine); - var url = re.Data.Url; - GenerateQrCode(url); + var waitTimes = 10; + logger.LogInformation("我数到{num},动作快点", waitTimes); + for (int i = 0; i < waitTimes; i++) + { + logger.LogInformation("[{num}]等待扫描...", i + 1); - var online = GetOnlinePic(url); - _logger.LogInformation(Environment.NewLine + Environment.NewLine); - _logger.LogInformation("如果上方二维码显示异常,或扫描失败,请使用浏览器访问如下链接,查看高清二维码:"); - _logger.LogInformation(online + Environment.NewLine + Environment.NewLine); + await Task.Delay(5 * 1000, cancellationToken); - var waitTimes = 10; - _logger.LogInformation("我数到{num},动作快点", waitTimes); - for (int i = 0; i < waitTimes; i++) + var check = await passportApi.CheckQrCodeHasScaned(re.Data.Qrcode_key); + if (!check.IsSuccessStatusCode) { - _logger.LogInformation("[{num}]等待扫描...", i + 1); - - await Task.Delay(5 * 1000, cancellationToken); - - var check = await _passportApi.CheckQrCodeHasScaned(re.Data.Qrcode_key); - if (!check.IsSuccessStatusCode) - { - _logger.LogWarning("调用检测接口异常"); - continue; - } - - var content = JsonConvert.DeserializeObject>(await check.Content.ReadAsStringAsync(cancellationToken)); - if (content.Code != 0) - { - _logger.LogWarning("调用检测接口异常:{msg}", check.ToJsonStr()); - break; - } + logger.LogWarning("调用检测接口异常"); + continue; + } - if (content.Data.Code == 86038)//已失效 - { - _logger.LogInformation(content.Data.Message); - break; - } + var content = JsonConvert.DeserializeObject>(await check.Content.ReadAsStringAsync(cancellationToken)); + if (content.Code != 0) + { + logger.LogWarning("调用检测接口异常:{msg}", check.ToJsonStr()); + break; + } - if (content.Data.Code == 0) - { - _logger.LogInformation("扫描成功!"); - IEnumerable cookies = check.Headers.SingleOrDefault(header => header.Key == "Set-Cookie").Value; + if (content.Data.Code == 86038)//已失效 + { + logger.LogInformation(content.Data.Message); + break; + } - var cookieStr = CookieInfo.ConvertSetCkHeadersToCkStr(cookies); - cookieInfo = new BiliCookie(cookieStr); - cookieInfo.Check(); + if (content.Data.Code == 0) + { + logger.LogInformation("扫描成功!"); + IEnumerable cookies = check.Headers.SingleOrDefault(header => header.Key == "Set-Cookie").Value; - break; - } + var cookieStr = CookieInfo.ConvertSetCkHeadersToCkStr(cookies); + cookieInfo = new BiliCookie(cookieStr); + cookieInfo.Check(); - _logger.LogInformation("{msg}", content.Data.Message + Environment.NewLine); + break; } - return cookieInfo; + logger.LogInformation("{msg}", content.Data.Message + Environment.NewLine); } - public async Task SetCookieAsync(BiliCookie biliCookie, CancellationToken cancellationToken) + return cookieInfo; + } + + public async Task SetCookieAsync(BiliCookie biliCookie, CancellationToken cancellationToken) + { + try { - try - { - var homePage = await _homeApi.GetHomePageAsync(biliCookie.ToString()); - if (homePage.IsSuccessStatusCode) - { - _logger.LogInformation("访问主站成功"); - IEnumerable setCookieHeaders = homePage.Headers.SingleOrDefault(header => header.Key == "Set-Cookie").Value; - biliCookie.MergeCurrentCookieBySetCookieHeaders(setCookieHeaders); - _logger.LogInformation("SetCookie成功"); - return biliCookie; - } - _logger.LogError("访问主站失败:{msg}", homePage.ToJsonStr()); - } - catch (Exception e) + var homePage = await homeApi.GetHomePageAsync(biliCookie.ToString()); + if (homePage.IsSuccessStatusCode) { - //buvid只影响分享和投币,可以吞掉异常 - _logger.LogError(e.ToJsonStr()); + logger.LogInformation("访问主站成功"); + IEnumerable setCookieHeaders = homePage.Headers.SingleOrDefault(header => header.Key == "Set-Cookie").Value; + biliCookie.MergeCurrentCookieBySetCookieHeaders(setCookieHeaders); + logger.LogInformation("SetCookie成功"); + return biliCookie; } + logger.LogError("访问主站失败:{msg}", homePage.ToJsonStr()); + } + catch (Exception e) + { + //buvid只影响分享和投币,可以吞掉异常 + logger.LogError(e.ToJsonStr()); + } + + return biliCookie; + } - return biliCookie; + public async Task SaveCookieToJsonFileAsync(BiliCookie ckInfo, CancellationToken cancellationToken) + { + //读取json + var path = hostingEnvironment.ContentRootPath; + var indexOfBin = path.LastIndexOf("bin"); + if (indexOfBin != -1) path = path[..indexOfBin]; + var fileProvider = new PhysicalFileProvider(path); + IFileInfo fileInfo = fileProvider.GetFileInfo("cookies.json"); + logger.LogInformation("目标json地址:{path}", fileInfo.PhysicalPath); + + if (!fileInfo.Exists) + { + await using var stream = File.Create(fileInfo.PhysicalPath); + await using var sw = new StreamWriter(stream); + await sw.WriteAsync($"{{{Environment.NewLine}}}"); } - public async Task SaveCookieToJsonFileAsync(BiliCookie ckInfo, CancellationToken cancellationToken) + string json; + await using (var stream = new FileStream(fileInfo.PhysicalPath, FileMode.Open)) { - //读取json - var path = _hostingEnvironment.ContentRootPath; - var indexOfBin = path.LastIndexOf("bin"); - if (indexOfBin != -1) path = path[..indexOfBin]; - var fileProvider = new PhysicalFileProvider(path); - IFileInfo fileInfo = fileProvider.GetFileInfo("cookies.json"); - _logger.LogInformation("目标json地址:{path}", fileInfo.PhysicalPath); - - if (!fileInfo.Exists) - { - await using var stream = File.Create(fileInfo.PhysicalPath); - await using var sw = new StreamWriter(stream); - await sw.WriteAsync($"{{{Environment.NewLine}}}"); - } + using var reader = new StreamReader(stream); + json = await reader.ReadToEndAsync(); + } + var lines = json.Split(Environment.NewLine).ToList(); - string json; - await using (var stream = new FileStream(fileInfo.PhysicalPath, FileMode.Open)) - { - using var reader = new StreamReader(stream); - json = await reader.ReadToEndAsync(); - } - var lines = json.Split(Environment.NewLine).ToList(); + var indexOfCkConfigKey = lines.FindIndex(x => x.TrimStart().StartsWith("\"BiliBiliCookies\"")); + if (indexOfCkConfigKey == -1) + { + logger.LogInformation("未配置过cookie,初始化并新增"); - var indexOfCkConfigKey = lines.FindIndex(x => x.TrimStart().StartsWith("\"BiliBiliCookies\"")); - if (indexOfCkConfigKey == -1) + var indexOfInsert = lines.FindIndex(x => x.TrimStart().StartsWith("{")); + lines.InsertRange(indexOfInsert + 1, new List() { - _logger.LogInformation("未配置过cookie,初始化并新增"); - - var indexOfInsert = lines.FindIndex(x => x.TrimStart().StartsWith("{")); - lines.InsertRange(indexOfInsert + 1, new List() - { - " \"BiliBiliCookies\":[", - $@" ""{ckInfo.CookieStr}"",", - " ]," - }); - - await SaveJson(lines, fileInfo); - _logger.LogInformation("新增成功!"); - return; - } + " \"BiliBiliCookies\":[", + $@" ""{ckInfo.CookieStr}"",", + " ]," + }); - ckInfo.CookieItemDictionary.TryGetValue("DedeUserID", out string userId); - userId ??= ckInfo.CookieStr; - var indexOfCkConfigEnd = lines.FindIndex(indexOfCkConfigKey, x => x.TrimStart().StartsWith("]")); - var indexOfTargetCk = lines.FindIndex(indexOfCkConfigKey, - indexOfCkConfigEnd - indexOfCkConfigKey, - x => x.Contains(userId) && !x.TrimStart().StartsWith("//")); + await SaveJson(lines, fileInfo); + logger.LogInformation("新增成功!"); + return; + } - if (indexOfTargetCk == -1) - { - _logger.LogInformation("不存在该用户,新增cookie"); - lines.Insert(indexOfCkConfigEnd, $@" ""{ckInfo.CookieStr}"","); - await SaveJson(lines, fileInfo); - _logger.LogInformation("新增成功!"); - return; - } + ckInfo.CookieItemDictionary.TryGetValue("DedeUserID", out string userId); + userId ??= ckInfo.CookieStr; + var indexOfCkConfigEnd = lines.FindIndex(indexOfCkConfigKey, x => x.TrimStart().StartsWith("]")); + var indexOfTargetCk = lines.FindIndex(indexOfCkConfigKey, + indexOfCkConfigEnd - indexOfCkConfigKey, + x => x.Contains(userId) && !x.TrimStart().StartsWith("//")); - _logger.LogInformation("已存在该用户,更新cookie"); - lines[indexOfTargetCk] = $@" ""{ckInfo.CookieStr}"","; + if (indexOfTargetCk == -1) + { + logger.LogInformation("不存在该用户,新增cookie"); + lines.Insert(indexOfCkConfigEnd, $@" ""{ckInfo.CookieStr}"","); await SaveJson(lines, fileInfo); - _logger.LogInformation("更新成功!"); + logger.LogInformation("新增成功!"); + return; } - public async Task SaveCookieToQinLongAsync(BiliCookie ckInfo, CancellationToken cancellationToken) + logger.LogInformation("已存在该用户,更新cookie"); + lines[indexOfTargetCk] = $@" ""{ckInfo.CookieStr}"","; + await SaveJson(lines, fileInfo); + logger.LogInformation("更新成功!"); + } + + public async Task SaveCookieToQinLongAsync(BiliCookie ckInfo, CancellationToken cancellationToken) + { + try { - //拿token var token = await GetQingLongAuthTokenAsync(); - - if (token.IsNullOrEmpty()) return; + if (token.IsNullOrEmpty()) + { + throw new Exception("获取青龙token失败"); + } token = $"Bearer {token}"; - //查env - var re = await _qingLongApi.GetEnvs("Ray_BiliBiliCookies__", token); - - if (re.Code != 200) + var qlEnvList = await qingLongApi.GetEnvs("Ray_BiliBiliCookies__", token); + if (qlEnvList.Code != 200) { - _logger.LogInformation($"查询环境变量失败:{re}", re.ToJsonStr()); - return; + throw new Exception($"查询环境变量失败:{qlEnvList.ToJsonStr()}"); } - _logger.LogDebug(re.Data.ToJsonStr()); - _logger.LogDebug(ckInfo.ToString()); + logger.LogDebug(qlEnvList.Data.ToJsonStr()); + logger.LogDebug(ckInfo.ToString()); - var list = re.Data.Where(x => x.name.StartsWith("Ray_BiliBiliCookies__")).ToList(); + var list = qlEnvList.Data.Where(x => x.name.StartsWith("Ray_BiliBiliCookies__")).ToList(); QingLongEnv oldEnv = list.FirstOrDefault(x => x.value.Contains(ckInfo.UserId)); if (oldEnv != null) { - _logger.LogInformation("用户已存在,更新cookie"); - _logger.LogInformation("Key:{key}", oldEnv.name); - var update = new UpdateQingLongEnv() + logger.LogInformation("用户已存在,更新cookie"); + logger.LogInformation("Key:{key}", oldEnv.name); + var update = new UpdateQingLongEnv { id = oldEnv.id, name = oldEnv.name, @@ -241,13 +225,13 @@ public async Task SaveCookieToQinLongAsync(BiliCookie ckInfo, CancellationToken : oldEnv.remarks, }; - var updateRe = await _qingLongApi.UpdateEnvs(update, token); - _logger.LogInformation(updateRe.Code == 200 ? "更新成功!" : updateRe.ToJsonStr()); + var updateRe = await qingLongApi.UpdateEnvs(update, token); + logger.LogInformation(updateRe.Code == 200 ? "更新成功!" : updateRe.ToJsonStr()); - return; + return true; } - _logger.LogInformation("用户不存在,新增cookie"); + logger.LogInformation("用户不存在,新增cookie"); var maxNum = -1; if (list.Any()) { @@ -258,153 +242,164 @@ public async Task SaveCookieToQinLongAsync(BiliCookie ckInfo, CancellationToken return parseSuc ? envNum : 0; }).Max(); } + var name = $"Ray_BiliBiliCookies__{maxNum + 1}"; - _logger.LogInformation("Key:{key}", name); + logger.LogInformation("Key:{key}", name); - var add = new AddQingLongEnv() - { - name = name, - value = ckInfo.CookieStr, - remarks = $"bili-{ckInfo.UserId}" - }; - var addRe = await _qingLongApi.AddEnvs(new List { add }, token); - _logger.LogInformation(addRe.Code == 200 ? "新增成功!" : addRe.ToJsonStr()); + var add = new AddQingLongEnv {name = name, value = ckInfo.CookieStr, remarks = $"bili-{ckInfo.UserId}"}; + var addRe = await qingLongApi.AddEnvs([add], token); + logger.LogInformation(addRe.Code == 200 ? "新增成功!" : addRe.ToJsonStr()); + return true; + } + catch + { + await PrintIfSaveCookieFailAsync(ckInfo, cancellationToken); + return false; } + } - #region private + #region private - private void GenerateQrCode(string str) - { - var qrGenerator = new QRCodeGenerator(); - QRCodeData qrCodeData = qrGenerator.CreateQrCode(str, QRCodeGenerator.ECCLevel.L); + private void GenerateQrCode(string str) + { + var qrGenerator = new QRCodeGenerator(); + QRCodeData qrCodeData = qrGenerator.CreateQrCode(str, QRCodeGenerator.ECCLevel.L); - _logger.LogInformation("AsciiQRCode:"); - //var qrCode = new AsciiQRCode(qrCodeData); - //var qrCodeStr = qrCode.GetGraphic(1, drawQuietZones: false); - //_logger.LogInformation(Environment.NewLine + qrCodeStr); + logger.LogInformation("AsciiQRCode:"); + //var qrCode = new AsciiQRCode(qrCodeData); + //var qrCodeStr = qrCode.GetGraphic(1, drawQuietZones: false); + //_logger.LogInformation(Environment.NewLine + qrCodeStr); - //Console.WriteLine("Console:"); - //Print(qrCodeData); - PrintSmall(qrCodeData); - } + //Console.WriteLine("Console:"); + //Print(qrCodeData); + PrintSmall(qrCodeData); + } - private void Print(QRCodeData qrCodeData) + private void Print(QRCodeData qrCodeData) + { + Console.BackgroundColor = ConsoleColor.White; + for (int i = 0; i < qrCodeData.ModuleMatrix.Count + 2; i++) Console.Write(" ");//中文全角的空格符 + Console.WriteLine(); + for (int j = 0; j < qrCodeData.ModuleMatrix.Count; j++) { - Console.BackgroundColor = ConsoleColor.White; - for (int i = 0; i < qrCodeData.ModuleMatrix.Count + 2; i++) Console.Write(" ");//中文全角的空格符 - Console.WriteLine(); - for (int j = 0; j < qrCodeData.ModuleMatrix.Count; j++) + for (int i = 0; i < qrCodeData.ModuleMatrix.Count; i++) { - for (int i = 0; i < qrCodeData.ModuleMatrix.Count; i++) - { - //char charToPoint = qrCode.Matrix[i, j] ? '█' : ' '; - Console.Write(i == 0 ? " " : "");//中文全角的空格符 - Console.BackgroundColor = qrCodeData.ModuleMatrix[i][j] ? ConsoleColor.Black : ConsoleColor.White; - Console.Write(' ');//中文全角的空格符 - Console.BackgroundColor = ConsoleColor.White; - Console.Write(i == qrCodeData.ModuleMatrix.Count - 1 ? " " : "");//中文全角的空格符 - } - Console.WriteLine(); + //char charToPoint = qrCode.Matrix[i, j] ? '█' : ' '; + Console.Write(i == 0 ? " " : "");//中文全角的空格符 + Console.BackgroundColor = qrCodeData.ModuleMatrix[i][j] ? ConsoleColor.Black : ConsoleColor.White; + Console.Write(' ');//中文全角的空格符 + Console.BackgroundColor = ConsoleColor.White; + Console.Write(i == qrCodeData.ModuleMatrix.Count - 1 ? " " : "");//中文全角的空格符 } - for (int i = 0; i < qrCodeData.ModuleMatrix.Count + 2; i++) Console.Write(" ");//中文全角的空格符 - Console.WriteLine(); } + for (int i = 0; i < qrCodeData.ModuleMatrix.Count + 2; i++) Console.Write(" ");//中文全角的空格符 - private void PrintSmall(QRCodeData qrCodeData) + Console.WriteLine(); + } + + private void PrintSmall(QRCodeData qrCodeData) + { + //黑黑(" ") + //白白("█") + //黑白("▄") + //白黑("▀") + var dic = new Dictionary() { - //黑黑(" ") - //白白("█") - //黑白("▄") - //白黑("▀") - var dic = new Dictionary() - { - {"11", ' '}, - {"00", '█'}, - {"10", '▄'}, - {"01", '▀'},//todo:win平台的cmd会显示?,是已知问题,待想办法解决 - //{"01", '^'},//▼▔ - }; + {"11", ' '}, + {"00", '█'}, + {"10", '▄'}, + {"01", '▀'},//todo:win平台的cmd会显示?,是已知问题,待想办法解决 + //{"01", '^'},//▼▔ + }; - var count = qrCodeData.ModuleMatrix.Count; + var count = qrCodeData.ModuleMatrix.Count; - var list = new List(); - for (int rowNum = 0; rowNum < count; rowNum++) + var list = new List(); + for (int rowNum = 0; rowNum < count; rowNum++) + { + var rowStr = ""; + for (int colNum = 0; colNum < count; colNum++) { - var rowStr = ""; - for (int colNum = 0; colNum < count; colNum++) - { - var num = qrCodeData.ModuleMatrix[colNum][rowNum] ? "1" : "0"; - var numDown = "0"; - if (rowNum + 1 < count) - numDown = qrCodeData.ModuleMatrix[colNum][rowNum + 1] ? "1" : "0"; - - rowStr += dic[num + numDown]; - } - list.Add(rowStr); - rowNum++; - } + var num = qrCodeData.ModuleMatrix[colNum][rowNum] ? "1" : "0"; + var numDown = "0"; + if (rowNum + 1 < count) + numDown = qrCodeData.ModuleMatrix[colNum][rowNum + 1] ? "1" : "0"; - _logger.LogInformation(Environment.NewLine + string.Join(Environment.NewLine, list)); + rowStr += dic[num + numDown]; + } + list.Add(rowStr); + rowNum++; } - private string GetOnlinePic(string str) - { - var encode = System.Web.HttpUtility.UrlEncode(str); ; - return $"https://tool.lu/qrcode/basic.html?text={encode}"; - } + logger.LogInformation(Environment.NewLine + string.Join(Environment.NewLine, list)); + } - private string GetCookieStr(IEnumerable setCookies) - { - var ckItemList = new List(); - foreach (var item in setCookies) - { - ckItemList.Add(item.Split(';').FirstOrDefault()); - } - var biliCk = string.Join("; ", ckItemList); - return biliCk; - } + private string GetOnlinePic(string str) + { + var encode = System.Web.HttpUtility.UrlEncode(str); ; + return $"https://tool.lu/qrcode/basic.html?text={encode}"; + } - private async Task SaveJson(List lines, IFileInfo fileInfo) + private string GetCookieStr(IEnumerable setCookies) + { + var ckItemList = new List(); + foreach (var item in setCookies) { - var newJson = string.Join(Environment.NewLine, lines); - - await using var sw = new StreamWriter(fileInfo.PhysicalPath); - await sw.WriteAsync(newJson); + ckItemList.Add(item.Split(';').FirstOrDefault()); } + var biliCk = string.Join("; ", ckItemList); + return biliCk; + } - #region qinglong - - private async Task GetQingLongAuthTokenAsync() - { - var token = ""; + private async Task SaveJson(List lines, IFileInfo fileInfo) + { + var newJson = string.Join(Environment.NewLine, lines); - var qlDir = _configuration["QL_DIR"] ?? "/ql"; + await using var sw = new StreamWriter(fileInfo.PhysicalPath); + await sw.WriteAsync(newJson); + } - string authFile = qlDir; - if (_hostingEnvironment.ContentRootPath.Contains($"{qlDir}/data/")) - { - authFile = Path.Combine(authFile, "data"); - } - authFile = Path.Combine(authFile, "config/auth.json"); + #region qinglong - if (!File.Exists(authFile)) - { - _logger.LogWarning("获取青龙授权失败,文件不在:{authFile}", authFile); - return token; - } + private async Task GetQingLongAuthTokenAsync() + { + var token = ""; - var authJson = await File.ReadAllTextAsync(authFile); + var qlDir = configuration["QL_DIR"] ?? "/ql"; - var jb = JsonConvert.DeserializeObject(authJson); - token = jb["token"]?.ToString(); + string authFile = qlDir; + if (hostingEnvironment.ContentRootPath.Contains($"{qlDir}/data/")) + { + authFile = Path.Combine(authFile, "data"); + } + authFile = Path.Combine(authFile, "config/auth.json"); + if (!File.Exists(authFile)) + { + logger.LogWarning("获取青龙授权失败,文件不存在:{authFile}", authFile); return token; } - #endregion + var authJson = await File.ReadAllTextAsync(authFile); - #endregion + var jb = JsonConvert.DeserializeObject(authJson); + token = jb["token"]?.ToString(); + return token; } -} + + private Task PrintIfSaveCookieFailAsync(BiliCookie ckInfo, CancellationToken cancellationToken) + { + logger.LogError("持久化失败,青龙版本高于2.18,请手动添加环境变量到青龙"); + logger.LogWarning("变量Key:{key}", "Ray_BiliBiliCookies__0"); + logger.LogWarning("变量值:{value}", ckInfo.CookieStr); + logger.LogWarning("如果Key已存在,请自行+1,如Ray_BiliBiliCookies__1,Ray_BiliBiliCookies__2..."); + return Task.CompletedTask; + } + + #endregion + + #endregion + +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.DomainService/Ray.BiliBiliTool.DomainService.csproj b/src/Ray.BiliBiliTool.DomainService/Ray.BiliBiliTool.DomainService.csproj index 33c379df6..34128c618 100644 --- a/src/Ray.BiliBiliTool.DomainService/Ray.BiliBiliTool.DomainService.csproj +++ b/src/Ray.BiliBiliTool.DomainService/Ray.BiliBiliTool.DomainService.csproj @@ -1,16 +1,16 @@  - net6.0 + net8.0 - - - - + + + + - + diff --git a/src/Ray.BiliBiliTool.DomainService/VideoDomainService.cs b/src/Ray.BiliBiliTool.DomainService/VideoDomainService.cs index 35a809451..63251300f 100644 --- a/src/Ray.BiliBiliTool.DomainService/VideoDomainService.cs +++ b/src/Ray.BiliBiliTool.DomainService/VideoDomainService.cs @@ -50,7 +50,7 @@ IWbiService wbiService _videoWithoutCookieApi = videoWithoutCookieApi; _wbiService = wbiService; _biliBiliCookie = biliBiliCookie; - _expDic = dicOptions.Get(Constants.OptionsNames.ExpDictionaryName); + _expDic = dicOptions.Get(Config.Constants.OptionsNames.ExpDictionaryName); _dailyTaskOptions = dailyTaskOptions.CurrentValue; } diff --git a/src/Ray.BiliBiliTool.Infrastructure/Ray.BiliBiliTool.Infrastructure.csproj b/src/Ray.BiliBiliTool.Infrastructure/Ray.BiliBiliTool.Infrastructure.csproj index ce2d959f5..c32603107 100644 --- a/src/Ray.BiliBiliTool.Infrastructure/Ray.BiliBiliTool.Infrastructure.csproj +++ b/src/Ray.BiliBiliTool.Infrastructure/Ray.BiliBiliTool.Infrastructure.csproj @@ -1,13 +1,13 @@  - net6.0 + net8.0 - - - + + + \ No newline at end of file diff --git a/test/AppServiceTest/AppServiceTest.csproj b/test/AppServiceTest/AppServiceTest.csproj index b0f835762..8e7268303 100644 --- a/test/AppServiceTest/AppServiceTest.csproj +++ b/test/AppServiceTest/AppServiceTest.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable @@ -9,13 +9,13 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/test/AppServiceTest/VipServiceTest.cs b/test/AppServiceTest/VipServiceTest.cs index 216aea8a9..0b2abfcdc 100644 --- a/test/AppServiceTest/VipServiceTest.cs +++ b/test/AppServiceTest/VipServiceTest.cs @@ -14,23 +14,6 @@ public VipServiceTest() Program.CreateHost(new[] { "--ENVIRONMENT=Development" }); } - [Fact] - public async Task VipExpressTest() - { - using var scope = Global.ServiceProviderRoot.CreateScope(); - var appService = scope.ServiceProvider.GetRequiredService(); - await appService.VipExpress(); - } - - [Fact] - public async Task WatchVideo() - { - using var scope = Global.ServiceProviderRoot.CreateScope(); - var appService = scope.ServiceProvider.GetRequiredService(); - var res = await appService.WatchBangumi(); - } - - [Fact] public async Task CompleteV2Test() { diff --git a/test/BiliAgentTest/BiliAgentTest.csproj b/test/BiliAgentTest/BiliAgentTest.csproj index bc95c8a9c..0b250a9c8 100644 --- a/test/BiliAgentTest/BiliAgentTest.csproj +++ b/test/BiliAgentTest/BiliAgentTest.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable false @@ -10,13 +10,13 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/test/ConfigTest/ConfigTest.csproj b/test/ConfigTest/ConfigTest.csproj index 2355e2c7b..8c1a57a22 100644 --- a/test/ConfigTest/ConfigTest.csproj +++ b/test/ConfigTest/ConfigTest.csproj @@ -1,18 +1,18 @@  - net6.0 + net8.0 false - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/DomainServiceTest/DomainServiceTest.csproj b/test/DomainServiceTest/DomainServiceTest.csproj index 869f6c876..c8c44468e 100644 --- a/test/DomainServiceTest/DomainServiceTest.csproj +++ b/test/DomainServiceTest/DomainServiceTest.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable @@ -9,13 +9,13 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/test/InfrastructureTest/InfrastructureTest.csproj b/test/InfrastructureTest/InfrastructureTest.csproj index 02e3b87c0..98ae632fe 100644 --- a/test/InfrastructureTest/InfrastructureTest.csproj +++ b/test/InfrastructureTest/InfrastructureTest.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable @@ -10,13 +10,13 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/test/LogTest/LogTest.csproj b/test/LogTest/LogTest.csproj index 90f0c86ed..e0f7c6e13 100644 --- a/test/LogTest/LogTest.csproj +++ b/test/LogTest/LogTest.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false @@ -9,13 +9,13 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Ray.BiliBiliTool.Agent.FunctionalTests/Ray.BiliBiliTool.Agent.FunctionalTests.csproj b/test/Ray.BiliBiliTool.Agent.FunctionalTests/Ray.BiliBiliTool.Agent.FunctionalTests.csproj index b5c2eb240..4f5e618c6 100644 --- a/test/Ray.BiliBiliTool.Agent.FunctionalTests/Ray.BiliBiliTool.Agent.FunctionalTests.csproj +++ b/test/Ray.BiliBiliTool.Agent.FunctionalTests/Ray.BiliBiliTool.Agent.FunctionalTests.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable @@ -10,11 +10,17 @@ - - - - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive +