From 33d90ea933dcb90beb15c9a03d4c77f776d3f638 Mon Sep 17 00:00:00 2001 From: andywang425 <56548456+andywang425@users.noreply.github.com> Date: Fri, 14 Aug 2026 23:00:08 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E2=9C=A8=20feat:=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E3=80=90=E5=B1=8F=E8=94=BD=E6=8C=82=E6=9C=BA=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E3=80=91=E6=A8=A1=E5=9D=97=EF=BC=8C=E4=BD=BF=E5=85=B6=E5=B0=BD?= =?UTF-8?q?=E6=97=A9=E8=BF=90=E8=A1=8C=EF=BC=9B=E5=A2=9E=E5=8A=A0=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E7=84=A6=E7=82=B9=E7=8A=B6=E6=80=81=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E7=9A=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ src/modules/enhanceExperience/noSleep.ts | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c262d6ef..75d8579d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### 新增 + +- 优化【屏蔽挂机检测】模块,使其尽早运行;增加页面焦点状态属性的修改 + ## [7.3.3] - 2026-7-25 ### 新增 diff --git a/src/modules/enhanceExperience/noSleep.ts b/src/modules/enhanceExperience/noSleep.ts index 4cc98edb..ff63565d 100644 --- a/src/modules/enhanceExperience/noSleep.ts +++ b/src/modules/enhanceExperience/noSleep.ts @@ -4,7 +4,7 @@ import { useModuleStore } from '@/stores' class NoSleep extends BaseModule { static runOnMultiplePages: boolean = true - static runAt: RunAtMoment = 'window-load' + static runAt: RunAtMoment = 'document-start' static onFrame: OnFrameTypes = 'top' static runAfterDefault: boolean = false @@ -17,14 +17,15 @@ class NoSleep extends BaseModule { document.dispatchEvent(new MouseEvent('mousemove')) }, 60e3) - // 修改页面可见性相关属性 + // 修改页面可见性和焦点状态相关属性 try { Object.defineProperties(document, { visibilityState: { value: 'visible' }, hidden: { value: false }, + hasFocus: { value: () => true }, }) } catch (e) { - this.logger.warn('修改页面可见性相关属性失败,可能已被其它脚本锁定', e) + this.logger.warn('修改页面可见性和焦点状态相关属性失败,可能已被其它脚本锁定', e) } } } From dc28ba39c052986d4e5a497a6ef10a13fb8b2c37 Mon Sep 17 00:00:00 2001 From: andywang425 <56548456+andywang425@users.noreply.github.com> Date: Fri, 14 Aug 2026 23:01:43 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=90=B3=20chore(.gitignore):=20add=20`?= =?UTF-8?q?artifacts`=20(Deepseek=20Harness=20directory)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 595f4f66..9967b193 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ node_modules .agents .qoder opencode.json +artifacts # Notes notes From 0f87d314f287f5261c7253fb9809734d7e150734 Mon Sep 17 00:00:00 2001 From: andywang425 <56548456+andywang425@users.noreply.github.com> Date: Mon, 24 Aug 2026 23:23:54 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E2=9C=A8=20feat:=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E8=B6=85=E8=83=BD=E7=B2=89=E4=B8=9D=E8=8A=82-=E7=B2=89?= =?UTF-8?q?=E4=B8=9D=E7=A6=8F=E5=88=A9-=E4=BA=B2=E5=AF=86=E5=96=82?= =?UTF-8?q?=E5=85=BB=EF=BC=88=E5=85=BB=E7=8C=AB=E6=B4=BB=E5=8A=A8=EF=BC=89?= =?UTF-8?q?=E7=9A=845=E4=B8=AAAPI=EF=BC=9B=E6=9B=B4=E6=96=B0GetActivatedMe?= =?UTF-8?q?dalInfo=E5=93=8D=E5=BA=94=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/library/bili-api/api.d.ts | 23 ++++++ src/library/bili-api/data.d.ts | 126 +++++++++++++++++++++++++++++ src/library/bili-api/index.ts | 98 ++++++++++++++++++++++ src/library/bili-api/response.d.ts | 35 ++++++++ src/library/request/index.ts | 2 +- 5 files changed, 283 insertions(+), 1 deletion(-) diff --git a/src/library/bili-api/api.d.ts b/src/library/bili-api/api.d.ts index 95115147..91579b25 100644 --- a/src/library/bili-api/api.d.ts +++ b/src/library/bili-api/api.d.ts @@ -57,6 +57,29 @@ interface BapiMethods { supported_drms?: string, web_location?: string, ) => Promise + Q3FansS1MiaoZaiHome: ( + room_id: number, + ruid: number, + target_uid?: number | string, + act_id?: number, + web_location?: string, + ) => Promise + Q3FansS1MiaoZaiSelectCat: ( + ruid: number, + cat_type?: number, + act_id?: number, + ) => Promise + Q3FansS1MiaoZaiSignIn: (ruid: number, act_id?: number) => Promise + Q3FansS1MiaoZaiPetCat: ( + ruid: number, + target_uid?: number, + act_id?: number, + ) => Promise + Q3FansS1MiaoZaiFeedCat: ( + ruid: number, + target_uid?: number, + act_id?: number, + ) => Promise } liveTrace: { E: ( diff --git a/src/library/bili-api/data.d.ts b/src/library/bili-api/data.d.ts index a7cf165f..7af12d58 100644 --- a/src/library/bili-api/data.d.ts +++ b/src/library/bili-api/data.d.ts @@ -123,6 +123,27 @@ declare namespace LiveData { light_source: number free_intimacy: number reach_free_intimacy_limit: boolean + intimacy_journey_info: IntimacyJourneyInfo + } + + interface IntimacyJourneyInfo { + enable: boolean + title_icon: string + completed_icon: string + incomplete_icon: string + gift_icon: string + badge_icon_intimacy: string + badge_icon_day: string + badge_icon_hour: string + total_days: number + completed_days: number + has_task_intimacy_journey_gift: boolean + task_intimacy_journey_gift_expire_ts: number + gift_intimacy: number + gift_id: number + background_color: string + font_color: string + gift_multiplier: string } interface TaskInfo { @@ -1339,6 +1360,111 @@ declare namespace LiveData { skip_frame_threshold: number } } + + namespace Q3FansS1MiaoZai { + interface HomeData { + current_time: number + start_time: number + end_time: number + activity_status: number + /** 猫主人的 uid */ + target_uid: number + fan_relation_status: number + cat_selected: boolean + cat_info: CatInfo | null + food_info: FoodInfo | null + cat_home_level: number + daily_tasks: DailyTask[] | null + level_configs: LevelConfig[] | null + food_level_configs: FoodLevelConfig[] | null + gift_open_time: number + gift_claim_status: number + gift_by_cat_level: GiftByCatLevel[] | null + medal_name: string + gift_intimacy: number + room_type: number + can_intimacy_journey: boolean + } + + interface ActionData { + /** code: 0 表示成功 */ + code: number + msg: string + cat_level: number + growth: number + food_balance: number + level_up_list: LevelUpInfo[] | null + growth_delta: number + cat_type: number + } + + interface CatInfo { + cat_type: number + cat_name: string + growth: number + level: number + level_name: string + level_start_growth: number + next_level_growth: number + } + + interface FoodInfo { + level: number + balance: number + growth_per_food: number + } + + interface DailyTask { + task_key: string + progress: number + level_list: TaskLevel[] + } + + interface TaskLevel { + level: number + target: number + reward_food: number + task_status: number + } + + interface LevelConfig { + level: number + level_name: string + growth_threshold: number + rewards: Reward[] | null + } + + interface FoodLevelConfig { + level: number + name: string + growth_per_food: number + price: number + can_upgrade: boolean + growth_boost_text: string + } + + interface GiftByCatLevel { + level: number + name: string + desc: string + low: number + high: number + } + + interface LevelUpInfo { + level: number + level_name: string + title: string + rewards: Reward[] | null + } + + interface Reward { + reward_type: string + name: string + desc: string + image: string + } + } } declare namespace LiveTraceData { diff --git a/src/library/bili-api/index.ts b/src/library/bili-api/index.ts index 370cc0a7..67fe7c81 100644 --- a/src/library/bili-api/index.ts +++ b/src/library/bili-api/index.ts @@ -155,6 +155,104 @@ const BAPI: BapiMethods = { }), ) }, + /** + * 获取超能粉丝节——粉丝福利——亲密喂养(养猫活动)主页数据 + */ + Q3FansS1MiaoZaiHome: ( + room_id, + ruid, + target_uid = '', + act_id = 110505, + web_location = '445.25', + ) => { + const bili_jct = useBiliStore().cookies!.bili_jct + return request.live.get( + '/xlive/custom-activity-interface/activities2026/Q3FansS1MiaoZaiHome', + { + act_id, + csrf: bili_jct, + room_id, + ruid, // 主播 uid + target_uid, // 如果为空字符串,默认为当前用户的 uid + web_location, + }, + ) + }, + /** + * 亲密喂养:选择一只要养的猫 + */ + Q3FansS1MiaoZaiSelectCat: (ruid, cat_type = 2, act_id = 110505) => { + const bili_jct = useBiliStore().cookies!.bili_jct + return request.live.post( + '/xlive/custom-activity-interface/activities2026/Q3FansS1MiaoZaiSelectCat', + JSON.stringify({ + act_id, + ruid: String(ruid), // 主播 uid + cat_type, + }), + { + params: { csrf: bili_jct }, + headers: { 'Content-Type': 'application/json' }, + }, + ) + }, + /** + * 亲密喂养:每日签到,获得猫粮 + */ + Q3FansS1MiaoZaiSignIn: (ruid, act_id = 110505) => { + const bili_jct = useBiliStore().cookies!.bili_jct + return request.live.post( + '/xlive/custom-activity-interface/activities2026/Q3FansS1MiaoZaiSignIn', + JSON.stringify({ + act_id, + ruid: String(ruid), // 主播 uid + }), + { + params: { csrf: bili_jct }, + headers: { 'Content-Type': 'application/json' }, + }, + ) + }, + /** + * 亲密喂养:撸猫(摸猫),有概率获得成长值 + */ + Q3FansS1MiaoZaiPetCat: (ruid, target_uid, act_id = 110505) => { + const biliStore = useBiliStore() + const bili_jct = biliStore.cookies!.bili_jct + const uid = target_uid ?? biliStore.BilibiliLive!.UID + return request.live.post( + '/xlive/custom-activity-interface/activities2026/Q3FansS1MiaoZaiPetCat', + JSON.stringify({ + act_id, + ruid: String(ruid), // 主播 uid + target_uid: String(uid), + }), + { + params: { csrf: bili_jct }, + headers: { 'Content-Type': 'application/json' }, + }, + ) + }, + /** + * 亲密喂养:喂猫,消耗一份猫粮获得成长值 + */ + Q3FansS1MiaoZaiFeedCat: (ruid, target_uid, act_id = 110505) => { + const biliStore = useBiliStore() + const bili_jct = biliStore.cookies!.bili_jct + const uid = target_uid ?? biliStore.BilibiliLive!.UID + return request.live.post( + '/xlive/custom-activity-interface/activities2026/Q3FansS1MiaoZaiFeedCat', + JSON.stringify({ + act_id, + ruid: String(ruid), // 主播 uid + target_uid: String(uid), + }), + { + params: { csrf: bili_jct }, + headers: { 'Content-Type': 'application/json' }, + }, + ) + }, }, liveTrace: { E: (id, device, ruid, is_patch = 0, heart_beat = [], web_location = '444.8') => { diff --git a/src/library/bili-api/response.d.ts b/src/library/bili-api/response.d.ts index f2f36598..6bfddb47 100644 --- a/src/library/bili-api/response.d.ts +++ b/src/library/bili-api/response.d.ts @@ -54,6 +54,41 @@ declare namespace Live { ttl: number data: LiveData.GetRoomPlayInfo.Data } + + interface Q3FansS1MiaoZaiHome { + code: number + message: string + ttl: number + data: LiveData.Q3FansS1MiaoZai.HomeData + } + + interface Q3FansS1MiaoZaiSelectCat { + code: number + message: string + ttl: number + data: LiveData.Q3FansS1MiaoZai.ActionData + } + + interface Q3FansS1MiaoZaiSignIn { + code: number + message: string + ttl: number + data: LiveData.Q3FansS1MiaoZai.ActionData + } + + interface Q3FansS1MiaoZaiPetCat { + code: number + message: string + ttl: number + data: LiveData.Q3FansS1MiaoZai.ActionData + } + + interface Q3FansS1MiaoZaiFeedCat { + code: number + message: string + ttl: number + data: LiveData.Q3FansS1MiaoZai.ActionData + } } declare namespace LiveTrace { diff --git a/src/library/request/index.ts b/src/library/request/index.ts index d8610ab4..892d5cd4 100644 --- a/src/library/request/index.ts +++ b/src/library/request/index.ts @@ -86,7 +86,7 @@ class Request { } else if (typeof data === 'string') { // data 类型为 string,不做处理 } else { - // data 类型为 Record,转换为 string + // data 类型为 Record,转换为 string(URL 编码的表单数据) data = new URLSearchParams(data).toString() } From c438593053026f56b46c4691c400a86e45b4c5a6 Mon Sep 17 00:00:00 2001 From: andywang425 <56548456+andywang425@users.noreply.github.com> Date: Tue, 25 Aug 2026 20:21:41 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E2=9C=A8=20feat:=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E3=80=90=E4=BA=B2=E5=AF=86=E5=96=82=E5=85=BB=E3=80=91=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 亲密度储蓄提示日志输出由 `log` 改为 `warn` - AGENTS.md 增加内部库说明 --- AGENTS.md | 4 + CHANGELOG.md | 5 + src/components/LiveTasks.vue | 28 +- src/library/help-info/index.ts | 39 +- src/library/storage/defaultValues.ts | 7 + .../liveTasks/medalTasks/MedalModule.ts | 4 +- .../dailyTasks/liveTasks/medalTasks/index.ts | 1 + .../liveTasks/medalTasks/miaoZaiTask.ts | 443 ++++++++++++++++++ .../liveTasks/medalTasks/types.d.ts | 21 +- src/modules/default/fansMedals.ts | 8 +- src/stores/useModuleStore.ts | 8 + src/types/helpInfo.d.ts | 1 + src/types/module.d.ts | 1 + src/types/storage.d.ts | 7 + 14 files changed, 567 insertions(+), 10 deletions(-) create mode 100644 src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts diff --git a/AGENTS.md b/AGENTS.md index 81d11b4e..eeaa6de9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,6 +26,10 @@ npm run preview # 打开提供编译产物安装链接的本地预览网页 - **默认模块**(`src/modules/default/`):做准备工作,如基础数据获取,先于大多数功能模块加载 - **功能模块**:实现具体业务逻辑,如完成每日任务 +## 内部库 + +位于 `src/library/`,每个子目录对应一个库,均通过 `index.ts` 默认导出。 + ## 配置持久化 `src/library/storage/` 通过 `GM_setValue`/`GM_getValue` 存取配置。 diff --git a/CHANGELOG.md b/CHANGELOG.md index 75d8579d..7fd69fbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,13 @@ ### 新增 +- 新增【亲密喂养】模块,自动完成亲密喂养活动(B站超能粉丝节的养猫活动)的选猫,每日签到,喂猫粮和撸猫。支持黑白名单。 - 优化【屏蔽挂机检测】模块,使其尽早运行;增加页面焦点状态属性的修改 +### 调整 + +- 亲密度储蓄提示日志的等级提升为警告(`console.warn`) + ## [7.3.3] - 2026-7-25 ### 新增 diff --git a/src/components/LiveTasks.vue b/src/components/LiveTasks.vue index 1cb82ef0..7e059a97 100644 --- a/src/components/LiveTasks.vue +++ b/src/components/LiveTasks.vue @@ -15,7 +15,7 @@ interface MedalInfoRow { roomid: number } -type MedalTaskKey = 'light' | 'like' | 'danmu' | 'watch' +type MedalTaskKey = 'light' | 'like' | 'danmu' | 'watch' | 'miaoZai' type DanmuTaskKey = 'light' | 'danmu' const TASK_LABELS: Record = { @@ -23,6 +23,7 @@ const TASK_LABELS: Record = { like: '点赞', danmu: '发弹幕', watch: '观看直播', + miaoZai: '亲密喂养', } const moduleStore = useModuleStore() @@ -399,6 +400,31 @@ function handleRowClick(row: MedalInfoRow) { + + + + + + + + + + + + 编辑名单 + + + + + + + 粉丝团任务相关信息可在 diff --git a/src/library/help-info/index.ts b/src/library/help-info/index.ts index 9dbf4c16..d4c97ca6 100644 --- a/src/library/help-info/index.ts +++ b/src/library/help-info/index.ts @@ -119,7 +119,7 @@ const helpInfo: HelpInfo = { h('li', '点赞、发弹幕和观看直播任务都会等点亮熄灭勋章任务完成后再执行。'), h( 'li', - '熄灭的勋章被点亮后,通过完成任务获得的亲密度会被储蓄,且储蓄量存在上限(根据观察上限是100)。需要投喂一个粉丝灯牌才能领取这些亲密度。脚本会在控制台日志中提示储蓄的亲密度量以及是否达到上限。', + '熄灭的勋章以完成点亮任务的方式被点亮后,通过完成任务获得的亲密度会被储蓄,且储蓄量存在上限(根据观察上限是100)。需要投喂一个粉丝灯牌才能领取这些亲密度。脚本会在控制台日志中提示储蓄的亲密度量以及是否达到上限。', ), ]), ]), @@ -216,6 +216,37 @@ const helpInfo: HelpInfo = { ]), ]), }, + miaoZai: { + title: '亲密喂养(养猫)', + message: () => + h('p', [ + h('div', '完成超能粉丝节活动中粉丝福利→亲密喂养的每日任务,赚取喵崽成长值。'), + h('div', '对于每个粉丝勋章对应的直播间,脚本会依次执行:'), + h('ol', [ + h('li', '若还没有选择喵崽,自动选择一只(默认暖系橘猫)。'), + h('li', '签到,领取猫粮。'), + h('li', '喂猫,直到猫粮用完。'), + h('li', '撸猫,直到不再获得成长值。'), + ]), + h('hr'), + h('ul', []), + h('div', [ + h('strong', '注意:'), + h('ul', [ + h('li', '该活动为限时活动,活动结束(2026-09-13 23:59:59)后本模块会自动禁用。'), + h( + 'li', + '尚未支持于9月13日自动领取喵崽的馈赠并赠送,预计在脚本的下一个版本中添加该功能。', + ), + h( + 'li', + '喵崽升级时会获得大量亲密度奖励,如果你没有在粉丝勋章熄灭后送过粉丝灯牌,很容易超过亲密度储蓄上限(详见【点亮熄灭勋章】内置说明),建议提前手动投喂粉丝灯牌。', + ), + h('li', '超能粉丝节活动入口会被【移除直播画面上方杂项】功能移除。'), + ]), + ]), + ]), + }, }, }, OtherTasks: { @@ -352,7 +383,11 @@ const helpInfo: HelpInfo = { }, removeHeaderStuff: { title: '移除直播画面上方杂项', - message: '移除直播画面上方各种杂七杂八的东西,比如排行榜、活动轮播图等。', + message: () => + h('p', [ + h('div', '移除直播画面上方各种杂七杂八的东西,比如排行榜、活动轮播图等。'), + h('div', [h('strong', '注意:'), h('span', '超能粉丝节活动入口会被该功能移除。')]), + ]), }, removeFlipView: { title: '移除礼物栏下方广告', diff --git a/src/library/storage/defaultValues.ts b/src/library/storage/defaultValues.ts index 67b20db3..04f8e2e9 100644 --- a/src/library/storage/defaultValues.ts +++ b/src/library/storage/defaultValues.ts @@ -17,6 +17,7 @@ const defaultValues: DefaultValues = { like: false, danmu: false, watch: false, + miaoZai: false, }, }, modules: { @@ -111,6 +112,12 @@ const defaultValues: DefaultValues = { roomidList: [], _lastCompleteTime: 0, }, + miaoZai: { + enabled: false, + isWhiteList: false, + roomidList: [], + _lastCompleteTime: 0, + }, }, }, OtherTasks: { diff --git a/src/modules/dailyTasks/liveTasks/medalTasks/MedalModule.ts b/src/modules/dailyTasks/liveTasks/medalTasks/MedalModule.ts index 89577719..f49f0cb4 100644 --- a/src/modules/dailyTasks/liveTasks/medalTasks/MedalModule.ts +++ b/src/modules/dailyTasks/liveTasks/medalTasks/MedalModule.ts @@ -611,13 +611,13 @@ class MedalModule extends BaseModule { /** * 记录储蓄亲密度信息日志 */ - private logFreeIntimacyFromData( + protected logFreeIntimacyFromData( medal: LiveData.FansMedalPanel.List, data: LiveData.GetActivatedMedalInfo.Data, ): void { if (data.free_intimacy > 0) { const reachLimitText = data.reach_free_intimacy_limit ? '(已达到储蓄亲密度上限)' : '' - this.logger.log( + this.logger.warn( `粉丝勋章【${medal.medal.medal_name}】储蓄了 ${data.free_intimacy} 亲密度${reachLimitText},投喂一个粉丝灯牌即可领取这些亲密度`, ) } diff --git a/src/modules/dailyTasks/liveTasks/medalTasks/index.ts b/src/modules/dailyTasks/liveTasks/medalTasks/index.ts index c19d3d30..0588a2c8 100644 --- a/src/modules/dailyTasks/liveTasks/medalTasks/index.ts +++ b/src/modules/dailyTasks/liveTasks/medalTasks/index.ts @@ -2,3 +2,4 @@ export { default as DailyTask_LiveTask_LightTask } from './lightTask' export { default as DailyTask_LiveTask_LikeTask } from './likeTask' export { default as DailyTask_LiveTask_DanmuTask } from './danmuTask' export { default as DailyTask_LiveTask_WatchTask } from './watchTask' +export { default as DailyTask_LiveTask_MiaoZaiTask } from './miaoZaiTask' diff --git a/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts b/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts new file mode 100644 index 00000000..87b6d53c --- /dev/null +++ b/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts @@ -0,0 +1,443 @@ +import { delayToNextMoment, isNowBefore, isTimestampToday, ts, tsm } from '@/library/luxon' +import BAPI from '@/library/bili-api' +import { useBiliStore, useModuleStore } from '@/stores' +import { sleep } from '@/library/utils' +import type { ModuleStatusTypes } from '@/types' +import MedalModule from '@/modules/dailyTasks/liveTasks/medalTasks/MedalModule' +import type { LiveData } from '@/library/bili-api/data' +import _ from 'lodash' +import type { MiaoZaiTaskResult } from './types' + +/** + * 超能粉丝节——粉丝福利——亲密喂养(养猫活动) + * + * 每天给每个粉丝勋章对应的直播间签到领猫粮、喂猫、撸猫,赚取成长值 + */ +class MiaoZaiTask extends MedalModule { + /** 活动结束时间戳(秒) */ + private static readonly ACTIVITY_END_TIME = 1789315199 // 2026-09-13 23:59:59 + /** 活动进行中的 activity_status */ + private static readonly ACTIVITY_STATUS_ONGOING = 1 + /** 签到任务的 task_key */ + private static readonly SIGN_IN_TASK_KEY = 'signin' + /** 任务已完成的 task_status */ + private static readonly TASK_STATUS_DONE = 1 + /** 连续多少次撸猫没有获得成长值就视为今日撸猫任务已完成 */ + private static readonly PET_CAT_ZERO_GROWTH_LIMIT = 5 + /** 单个直播间最多喂猫次数(兜底,避免猫粮数量异常时无限循环) */ + private static readonly FEED_CAT_MAX_TIMES = 40 + /** 单个直播间最多撸猫次数(兜底,避免 growth_delta 一直大于 0 时无限循环) */ + private static readonly PET_CAT_MAX_TIMES = 30 + /** 相邻两次不同类型的养猫操作之间的动态间隔时间(长) */ + private static get ACTION_DYNAMIC_LONG_INTERVAL() { + return _.random(1500, 2000) + } + /** 相邻两次撸猫或喂猫粮操作之间的动态间隔时间(短) */ + private static get ACTION_DYNAMIC_SHORT_INTERVAL() { + return _.random(300, 500) + } + /** 相邻两个直播间之间的动态间隔时间 */ + private static get ROOM_DYNAMIC_INTERVAL() { + return _.random(3000, 5000) + } + + config = this.medalTasksConfig.miaoZai + + set status(s: ModuleStatusTypes) { + useModuleStore().moduleStatus.DailyTasks.LiveTasks.medalTasks.miaoZai = s + } + + /** + * 获取黑白名单过滤后的粉丝勋章 + * + * 养猫活动不要求勋章已点亮,也不受 120 级上限影响 + */ + private getMedals(): LiveData.FansMedalPanel.List[] { + const result = useBiliStore().filteredFansMedals.filter((medal) => + this.SHARED_MEDAL_FILTERS.meetWhiteOrBlackList(medal), + ) + + if (this.config.isWhiteList) { + this.sortMedals(result) + } + + return result + } + + /** + * 获取养猫活动主页数据 + * + * @param medal 粉丝勋章 + * @returns 成功返回主页数据,失败返回 null + */ + private async fetchHome( + medal: LiveData.FansMedalPanel.List, + ): Promise { + const room_id = medal.room_info.room_id + const ruid = medal.medal.target_id + + try { + const response = await BAPI.live.Q3FansS1MiaoZaiHome(room_id, ruid) + this.logger.log(`BAPI.live.Q3FansS1MiaoZaiHome(${room_id}, ${ruid}) response`, response) + if (response.code === 0) { + return response.data + } + this.logger.error(`BAPI.live.Q3FansS1MiaoZaiHome(${room_id}, ${ruid}) 失败`, response.message) + } catch (error) { + this.logger.error(`BAPI.live.Q3FansS1MiaoZaiHome(${room_id}, ${ruid}) 出错`, error) + } + + return null + } + /** + * 判断签到任务是否已完成 + * + * @returns 已完成返回 true,未完成或找不到签到任务返回 false + */ + private static isSignInDone(home: LiveData.Q3FansS1MiaoZai.HomeData): boolean { + const task = home.daily_tasks?.find((t) => t.task_key === MiaoZaiTask.SIGN_IN_TASK_KEY) + return task?.level_list?.[0]?.task_status === MiaoZaiTask.TASK_STATUS_DONE + } + + /** + * 执行一次养猫操作(选猫/签到/喂猫/撸猫) + * + * 外层 code 和 data.code 都为 0 才算成功 + * + * @param actionText 操作名称,用于日志 + * @param logMessage 直播间描述信息,用于日志 + * @param requester 请求函数 + * @returns 成功返回 ActionData,失败返回 null + */ + private async executeAction( + actionText: string, + logMessage: string, + requester: () => Promise<{ + code: number + message: string + data: LiveData.Q3FansS1MiaoZai.ActionData + }>, + ): Promise { + try { + const response = await requester() + this.logger.log(`${actionText} ${logMessage} response`, response) + + if (response.code !== 0) { + this.logger.error(`${actionText} ${logMessage} 失败`, response.message) + return null + } + if (response.data.code !== 0) { + this.logger.error(`${actionText} ${logMessage} 失败`, response.data.msg) + return null + } + + if (response.data.level_up_list && response.data.level_up_list.length > 0) { + // 喂猫或撸猫后升级了 + const levelUpInfo = response.data.level_up_list[0] + const rewardInfo = levelUpInfo.rewards?.map((r) => `${r.name}${r.desc}`).join(',') + this.logger.log( + `${actionText} ${logMessage} 已升级到 ${levelUpInfo.level_name}(Lv.${levelUpInfo.level})${rewardInfo ? `,获得奖励:${rewardInfo}` : ''}`, + ) + } + + return response.data + } catch (error) { + this.logger.error(`${actionText} ${logMessage} 出错`, error) + return null + } + } + + /** + * 喂猫,消耗掉所有剩余猫粮 + * + * @param medal 粉丝勋章 + * @param logMessage 直播间描述信息,用于日志 + * @param balance 剩余猫粮数量 + * @returns 是否把猫粮都喂完了 + */ + private async feedCat( + medal: LiveData.FansMedalPanel.List, + logMessage: string, + balance: number, + ): Promise { + if (balance <= 0) { + this.logger.log(`${logMessage} 没有剩余猫粮,跳过喂猫`) + return true + } + + const ruid = medal.medal.target_id + this.logger.log(`${logMessage} 开始喂猫,剩余猫粮 ${balance} 份`) + + for (let i = 0; i < MiaoZaiTask.FEED_CAT_MAX_TIMES; i++) { + const data = await this.executeAction('喂猫', logMessage, () => + BAPI.live.Q3FansS1MiaoZaiFeedCat(ruid), + ) + + if (!data) return false + + this.logger.log( + `${logMessage} 喂猫成功,获得 ${data.growth_delta} 点成长值(当前成长值 ${data.growth}),剩余猫粮 ${data.food_balance} 份`, + ) + + if (data.food_balance <= 0) return true + + await sleep(MiaoZaiTask.ACTION_DYNAMIC_SHORT_INTERVAL) + } + + this.logger.warn(`${logMessage} 喂猫次数已达上限 ${MiaoZaiTask.FEED_CAT_MAX_TIMES},停止喂猫`) + return false + } + + /** + * 撸猫,直到连续多次没有获得成长值 + * + * @param medal 粉丝勋章 + * @param logMessage 直播间描述信息,用于日志 + * @returns 是否正常完成今日撸猫任务 + */ + private async petCat(medal: LiveData.FansMedalPanel.List, logMessage: string): Promise { + const ruid = medal.medal.target_id + let zeroGrowthCount = 0 + let totalGrowth = 0 + + this.logger.log(`${logMessage} 开始撸猫`) + + for (let i = 0; i < MiaoZaiTask.PET_CAT_MAX_TIMES; i++) { + const data = await this.executeAction('撸猫', logMessage, () => + BAPI.live.Q3FansS1MiaoZaiPetCat(ruid), + ) + + if (!data) return false + + if (data.growth_delta > 0) { + zeroGrowthCount = 0 + totalGrowth += data.growth_delta + this.logger.log( + `${logMessage} 撸猫成功,获得 ${data.growth_delta} 点成长值(当前成长值 ${data.growth})`, + ) + } else { + zeroGrowthCount++ + this.logger.log(`${logMessage} 撸猫成功,但没有获得成长值(连续 ${zeroGrowthCount} 次)`) + + if (zeroGrowthCount >= MiaoZaiTask.PET_CAT_ZERO_GROWTH_LIMIT) { + this.logger.log( + `${logMessage} 连续 ${MiaoZaiTask.PET_CAT_ZERO_GROWTH_LIMIT} 次撸猫没有获得成长值,今日撸猫任务已完成,本次共获得 ${totalGrowth} 点成长值`, + ) + return true + } + } + + await sleep(MiaoZaiTask.ACTION_DYNAMIC_SHORT_INTERVAL) + } + + this.logger.warn(`${logMessage} 撸猫次数已达上限 ${MiaoZaiTask.PET_CAT_MAX_TIMES},停止撸猫`) + return false + } + + /** + * 复查养猫结果并输出喵崽的当前数据 + * + * @param medal 粉丝勋章 + * @param logMessage 直播间描述信息,用于日志 + * @returns 签到和喂猫是否都已完成 + */ + private async verifyResult( + medal: LiveData.FansMedalPanel.List, + logMessage: string, + ): Promise { + const home = await this.fetchHome(medal) + + if (!home) { + this.logger.error(`${logMessage} 无法获取最新养猫活动数据,无法确认任务是否完成,默认已完成`) + return true + } + + const cat = home.cat_info + if (cat) { + this.logger.log( + `${logMessage} 喵崽【${cat.cat_name}】当前为 ${cat.level_name}(Lv.${cat.level}),成长值 ${cat.growth}/${cat.next_level_growth}`, + ) + } + + let completed = true + + if (!MiaoZaiTask.isSignInDone(home)) { + this.logger.warn(`${logMessage} 签到任务仍未完成,下次运行会继续尝试`) + completed = false + } + + const balance = home.food_info?.balance ?? 0 + if (balance > 0) { + this.logger.warn(`${logMessage} 仍剩余 ${balance} 份猫粮没有喂完,下次运行会继续尝试`) + completed = false + } + + await this.logFreeIntimacy(medal) + + return completed + } + + /** + * 获取并记录已储蓄的亲密度信息 + */ + private async logFreeIntimacy(medal: LiveData.FansMedalPanel.List): Promise { + const data = await this.fetchMedalData(medal.medal.target_id) + if (data) { + this.logFreeIntimacyFromData(medal, data) + } + } + + /** + * 执行单个直播间的养猫任务 + * + * @param medal 粉丝勋章 + * @returns 执行结果 + */ + private async executeMiaoZaiTask( + medal: LiveData.FansMedalPanel.List, + ): Promise { + const room_id = medal.room_info.room_id + const ruid = medal.medal.target_id + const nick_name = medal.anchor_info.nick_name + const medal_name = medal.medal.medal_name + const logMessage = `粉丝勋章【${medal_name}】(主播【${nick_name}】,UID:${ruid},直播间:${room_id})` + + let home = await this.fetchHome(medal) + if (!home) { + this.logger.error(`${logMessage} 无法获取养猫活动数据,跳过该直播间`) + return 'uncompleted' + } + + if (home.activity_status !== MiaoZaiTask.ACTIVITY_STATUS_ONGOING) { + this.logger.warn( + `超能粉丝节——亲密喂养活动当前不可用(activity_status:${home.activity_status}),中断养猫任务`, + ) + return 'activityInvalid' + } + + // 还没选猫,先选一只 + if (!home.cat_selected) { + this.logger.log(`${logMessage} 还没有选择喵崽,先选择一只`) + + const data = await this.executeAction('选择喵崽', logMessage, () => + BAPI.live.Q3FansS1MiaoZaiSelectCat(ruid), + ) + + if (!data) { + this.logger.error(`${logMessage} 选择喵崽失败,跳过该直播间`) + return 'uncompleted' + } + + await sleep(MiaoZaiTask.ACTION_DYNAMIC_LONG_INTERVAL) + + // 重新获取主页数据,拿到选完猫之后的猫粮数量和任务状态 + home = await this.fetchHome(medal) + if (!home) { + this.logger.error(`${logMessage} 选择喵崽后无法获取养猫活动数据,跳过该直播间`) + return 'uncompleted' + } + } + + let balance = home.food_info?.balance ?? 0 + + // 签到领猫粮 + if (MiaoZaiTask.isSignInDone(home)) { + this.logger.log(`${logMessage} 今天已经签到过了`) + } else { + const data = await this.executeAction('签到', logMessage, () => + BAPI.live.Q3FansS1MiaoZaiSignIn(ruid), + ) + + if (data) { + this.logger.log(`${logMessage} 签到成功,当前共有 ${data.food_balance} 份猫粮`) + balance = data.food_balance + } else { + this.logger.error(`${logMessage} 签到失败,仍然尝试喂完已有的猫粮`) + } + + await sleep(MiaoZaiTask.ACTION_DYNAMIC_LONG_INTERVAL) + } + + // 喂猫 + const fed = await this.feedCat(medal, logMessage, balance) + await sleep(MiaoZaiTask.ACTION_DYNAMIC_LONG_INTERVAL) + + // 撸猫 + const petted = await this.petCat(medal, logMessage) + await sleep(MiaoZaiTask.ACTION_DYNAMIC_LONG_INTERVAL) + + const verified = await this.verifyResult(medal, logMessage) + + return fed && petted && verified ? 'completed' : 'uncompleted' + } + + public async run(): Promise { + this.logger.log('亲密喂养模块开始运行') + + if (ts() > MiaoZaiTask.ACTIVITY_END_TIME) { + this.logger.warn('超能粉丝节——亲密喂养活动已结束,亲密喂养模块自动禁用') + this.config.enabled = false + return + } + + if (!isTimestampToday(this.config._lastCompleteTime)) { + if (!(await MedalModule.waitForFansMedals())) { + this.logger.error('粉丝勋章数据不存在,不执行养猫任务') + this.status = 'error' + return + } + + this.status = 'running' + const fansMedals = this.getMedals() + + if (fansMedals.length > 0) { + let allCompleted = true + + for (let i = 0; i < fansMedals.length; i++) { + if (MedalModule.shouldStopForCrossDay()) { + this.logger.log('即将或刚刚发生跨天,提早结束本轮养猫任务') + allCompleted = false + break + } + + const result = await this.executeMiaoZaiTask(fansMedals[i]) + + if (result === 'activityInvalid') { + allCompleted = false + break + } else if (result === 'uncompleted') { + allCompleted = false + } + + if (i < fansMedals.length - 1) { + await sleep(MiaoZaiTask.ROOM_DYNAMIC_INTERVAL) + } + } + + if (allCompleted) { + this.config._lastCompleteTime = tsm() + this.logger.log('养猫任务已完成') + this.status = 'done' + } else { + this.status = '' + } + } else { + this.status = 'done' + this.config._lastCompleteTime = tsm() + } + } else { + if (isNowBefore(0, 5)) { + this.logger.log('昨天的养猫任务已经完成过了,等到今天的00:05再执行') + } else { + this.logger.log('今天已经完成过养猫任务了') + this.status = 'done' + } + } + + const diff = delayToNextMoment() + this.nextRunTimer = setTimeout(() => this.run(), diff.ms) + this.logger.log('距离亲密喂养模块下次运行时间:', diff.str) + } +} + +export default MiaoZaiTask diff --git a/src/modules/dailyTasks/liveTasks/medalTasks/types.d.ts b/src/modules/dailyTasks/liveTasks/medalTasks/types.d.ts index c55f084b..144971b5 100644 --- a/src/modules/dailyTasks/liveTasks/medalTasks/types.d.ts +++ b/src/modules/dailyTasks/liveTasks/medalTasks/types.d.ts @@ -4,7 +4,11 @@ import type { ModuleConfig } from '@/types' type _MedalTasks = ModuleConfig['DailyTasks']['LiveTasks']['medalTasks'] type MedalTaskSharedConfig = - _MedalTasks['light'] | _MedalTasks['like'] | _MedalTasks['danmu'] | _MedalTasks['watch'] + | _MedalTasks['light'] + | _MedalTasks['like'] + | _MedalTasks['danmu'] + | _MedalTasks['watch'] + | _MedalTasks['miaoZai'] interface SharedMedalFilters { meetWhiteOrBlackList: (medal: LiveData.FansMedalPanel.List) => boolean @@ -27,7 +31,7 @@ interface LiveStatusSnapshot { } /** - * 直播间任务执行前直播状态校验结论 + * 直播间任务(点赞/发弹幕)执行前直播状态校验结论 * * - `pass`:符合目标状态 * - `fail`:不符合目标状态 @@ -36,13 +40,13 @@ interface LiveStatusSnapshot { type PreExecuteVerdict = 'pass' | 'fail' | 'error' /** - * 直播间任务执行后操作 + * 直播间任务(点赞/发弹幕)执行后操作 * * - `stop`:终止后续直播间任务 * - `markUncompleted`:把当前任务(点赞/发弹幕)标记为未完成 * - `stopAndMarkUncompleted`:终止后续直播间任务并且把当前任务标记为未完成 * - `requeue`:把直播间放到等待队列 - * - `skipSleep`:跳过执行下一个直播间任务之间的等待时间 + * - `skipSleep`:跳过执行下一个直播间任务前的等待时间 * - `null`:无操作 */ type AfterExecutionAction = @@ -55,6 +59,14 @@ interface BatchExecutionResult { /** 放到等待队列的直播间id列表 */ requeueRoomids?: number[] } +/** + * 养猫任务执行结果 + * + * - `activityInvalid`:活动无效,应中断后续所有直播间的任务 + * - `completed`:该直播间的任务已完成 + * - `uncompleted`:该直播间的任务未完成 + */ +type MiaoZaiTaskResult = 'activityInvalid' | 'completed' | 'uncompleted' export { MedalTaskSharedConfig, @@ -66,4 +78,5 @@ export { PreExecuteVerdict, AfterExecutionAction, BatchExecutionResult, + MiaoZaiTaskResult, } diff --git a/src/modules/default/fansMedals.ts b/src/modules/default/fansMedals.ts index 5cd25127..f8ce9dce 100644 --- a/src/modules/default/fansMedals.ts +++ b/src/modules/default/fansMedals.ts @@ -61,7 +61,13 @@ class FansMedals extends BaseModule { const biliStore = useBiliStore() const medalTasks = useModuleStore().moduleConfig.DailyTasks.LiveTasks.medalTasks - const taskValues = [medalTasks.light, medalTasks.like, medalTasks.danmu, medalTasks.watch] + const taskValues = [ + medalTasks.light, + medalTasks.like, + medalTasks.danmu, + medalTasks.watch, + medalTasks.miaoZai, + ] if ( force || diff --git a/src/stores/useModuleStore.ts b/src/stores/useModuleStore.ts index 3b180e24..5428d054 100644 --- a/src/stores/useModuleStore.ts +++ b/src/stores/useModuleStore.ts @@ -28,6 +28,7 @@ const defaultModuleStatus: ModuleStatus = { like: '', danmu: '', watch: '', + miaoZai: '', }, }, OtherTasks: { @@ -129,6 +130,13 @@ export const useModuleStore = defineStore('module', () => { rerunModule('Default_FansMedals', true) rerunModule('DailyTask_LiveTask_WatchTask') }, + miaoZai: () => { + moduleStatus.value.DailyTasks.LiveTasks.medalTasks.miaoZai = '' + moduleConfig.value.DailyTasks.LiveTasks.medalTasks.miaoZai._lastCompleteTime = 0 + + rerunModule('Default_FansMedals', true) + rerunModule('DailyTask_LiveTask_MiaoZaiTask') + }, }, }, OtherTasks: { diff --git a/src/types/helpInfo.d.ts b/src/types/helpInfo.d.ts index 218404d8..e7819b1c 100644 --- a/src/types/helpInfo.d.ts +++ b/src/types/helpInfo.d.ts @@ -23,6 +23,7 @@ interface HelpInfo { danmu: HelpInfoItem danmuWaitUntilNotLiving: HelpInfoItem watch: HelpInfoItem + miaoZai: HelpInfoItem } } OtherTasks: { diff --git a/src/types/module.d.ts b/src/types/module.d.ts index ec5c516d..fa80c00e 100644 --- a/src/types/module.d.ts +++ b/src/types/module.d.ts @@ -23,6 +23,7 @@ interface ModulesNeedStatus { like: T danmu: T watch: T + miaoZai: T } } OtherTasks: { diff --git a/src/types/storage.d.ts b/src/types/storage.d.ts index f1d83b33..caf1677e 100644 --- a/src/types/storage.d.ts +++ b/src/types/storage.d.ts @@ -58,6 +58,12 @@ interface ModuleConfig { roomidList: number[] _lastCompleteTime: number } + miaoZai: { + enabled: boolean + isWhiteList: boolean + roomidList: number[] + _lastCompleteTime: number + } } } OtherTasks: { @@ -146,6 +152,7 @@ interface UiConfig { like: boolean danmu: boolean watch: boolean + miaoZai: boolean } } From 4f09c60c877b3e124a421a9ecdc24d5580931ceb Mon Sep 17 00:00:00 2001 From: andywang425 <56548456+andywang425@users.noreply.github.com> Date: Tue, 25 Aug 2026 20:34:09 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=F0=9F=90=9E=20fix:=E3=80=90=E4=BA=B2?= =?UTF-8?q?=E5=AF=86=E5=96=82=E5=85=BB=E3=80=91=E6=A8=A1=E5=9D=97=E8=B7=B3?= =?UTF-8?q?=E8=BF=87=E4=B8=8D=E6=94=AF=E6=8C=81=E8=AF=A5=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=E7=9A=84=E7=9B=B4=E6=92=AD=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts b/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts index 87b6d53c..ba218149 100644 --- a/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts +++ b/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts @@ -315,6 +315,12 @@ class MiaoZaiTask extends MedalModule { return 'activityInvalid' } + if (!home.can_intimacy_journey) { + this.logger.warn(`${logMessage} 不支持亲密喂养活动,跳过该直播间`) + // 不支持养猫活动,视为完成 + return 'completed' + } + // 还没选猫,先选一只 if (!home.cat_selected) { this.logger.log(`${logMessage} 还没有选择喵崽,先选择一只`) From 0ecd3311b34d0e951933dba0722cf9c0490476a1 Mon Sep 17 00:00:00 2001 From: andywang425 <56548456+andywang425@users.noreply.github.com> Date: Tue, 25 Aug 2026 20:45:19 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=F0=9F=90=B3=20chore:=20=E4=BA=B2=E5=AF=86?= =?UTF-8?q?=E5=96=82=E5=85=BB=E6=A8=A1=E5=9D=97=E7=BB=86=E8=8A=82=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts b/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts index ba218149..2841bd89 100644 --- a/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts +++ b/src/modules/dailyTasks/liveTasks/medalTasks/miaoZaiTask.ts @@ -96,7 +96,7 @@ class MiaoZaiTask extends MedalModule { */ private static isSignInDone(home: LiveData.Q3FansS1MiaoZai.HomeData): boolean { const task = home.daily_tasks?.find((t) => t.task_key === MiaoZaiTask.SIGN_IN_TASK_KEY) - return task?.level_list?.[0]?.task_status === MiaoZaiTask.TASK_STATUS_DONE + return task?.level_list?.[0].task_status === MiaoZaiTask.TASK_STATUS_DONE } /** @@ -184,7 +184,9 @@ class MiaoZaiTask extends MedalModule { await sleep(MiaoZaiTask.ACTION_DYNAMIC_SHORT_INTERVAL) } - this.logger.warn(`${logMessage} 喂猫次数已达上限 ${MiaoZaiTask.FEED_CAT_MAX_TIMES},停止喂猫`) + this.logger.warn( + `${logMessage} 喂猫次数已达上限(${MiaoZaiTask.FEED_CAT_MAX_TIMES} 次),停止喂猫`, + ) return false } @@ -221,7 +223,7 @@ class MiaoZaiTask extends MedalModule { if (zeroGrowthCount >= MiaoZaiTask.PET_CAT_ZERO_GROWTH_LIMIT) { this.logger.log( - `${logMessage} 连续 ${MiaoZaiTask.PET_CAT_ZERO_GROWTH_LIMIT} 次撸猫没有获得成长值,今日撸猫任务已完成,本次共获得 ${totalGrowth} 点成长值`, + `${logMessage} 连续 ${MiaoZaiTask.PET_CAT_ZERO_GROWTH_LIMIT} 次撸猫没有获得成长值,今日撸猫任务已完成,共获得 ${totalGrowth} 点成长值`, ) return true } @@ -230,7 +232,9 @@ class MiaoZaiTask extends MedalModule { await sleep(MiaoZaiTask.ACTION_DYNAMIC_SHORT_INTERVAL) } - this.logger.warn(`${logMessage} 撸猫次数已达上限 ${MiaoZaiTask.PET_CAT_MAX_TIMES},停止撸猫`) + this.logger.warn( + `${logMessage} 撸猫次数已达上限(${MiaoZaiTask.PET_CAT_MAX_TIMES} 次),停止撸猫`, + ) return false } From 1cc1e4a47bd0f48fdc18595c21a42b5dc0801666 Mon Sep 17 00:00:00 2001 From: andywang425 <56548456+andywang425@users.noreply.github.com> Date: Tue, 25 Aug 2026 21:01:05 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=F0=9F=90=B3=20chore:=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=86=97=E4=BD=99=E4=BB=A3=E7=A0=81=EF=BC=88`h('ul',=20[])`?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/library/help-info/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/library/help-info/index.ts b/src/library/help-info/index.ts index d4c97ca6..609c8b55 100644 --- a/src/library/help-info/index.ts +++ b/src/library/help-info/index.ts @@ -229,7 +229,6 @@ const helpInfo: HelpInfo = { h('li', '撸猫,直到不再获得成长值。'), ]), h('hr'), - h('ul', []), h('div', [ h('strong', '注意:'), h('ul', [ From 08f0357a904427f3f77ed7f70991247d2aa3c35c Mon Sep 17 00:00:00 2001 From: andywang425 <56548456+andywang425@users.noreply.github.com> Date: Tue, 25 Aug 2026 21:13:25 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=F0=9F=90=B3=20chore:=20Update=20.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add .dsh --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9967b193..a99f094c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ node_modules # MacOS .DS_Store -# Editor directories and files +# Editor/Agent directories and files .vscode/* !.vscode/extensions.json .idea @@ -14,6 +14,7 @@ node_modules .qoder opencode.json artifacts +.dsh # Notes notes From 2b2e536a05f9eea4060b4d2cf5bd770ce45c08b4 Mon Sep 17 00:00:00 2001 From: andywang425 <56548456+andywang425@users.noreply.github.com> Date: Tue, 25 Aug 2026 21:17:41 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=F0=9F=90=B3=20chore:=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=89=8D=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fd69fbe..65b13558 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [7.3.4] - 2026-8-25 + ### 新增 - 新增【亲密喂养】模块,自动完成亲密喂养活动(B站超能粉丝节的养猫活动)的选猫,每日签到,喂猫粮和撸猫。支持黑白名单。 diff --git a/package-lock.json b/package-lock.json index 17d21814..0c3857f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bilibili-live-tasks-helper", - "version": "7.3.3", + "version": "7.3.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bilibili-live-tasks-helper", - "version": "7.3.3", + "version": "7.3.4", "dependencies": { "ajax-hook": "^3.0.3", "crypto-js": "^4.2.0", diff --git a/package.json b/package.json index abaa4f5c..0813b2f4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "bilibili-live-tasks-helper", "private": true, - "version": "7.3.3", + "version": "7.3.4", "type": "module", "scripts": { "dev": "vite",