karin-plugin-kkk 2.40.2 → 2.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -571,6 +571,15 @@ var BilibiliAPI = class {
571
571
  getUserCard(data) {
572
572
  return `https://api.bilibili.com/x/web-interface/card?mid=${data.host_mid}&photo=true`;
573
573
  }
574
+ /**
575
+ * 按用户 UID 获取直播状态。
576
+ *
577
+ * @remarks
578
+ * 该接口直接返回用户当前直播状态,不依赖空间动态中的直播推荐卡片。
579
+ */
580
+ getUserLiveStatus(data) {
581
+ return `https://api.live.bilibili.com/room/v1/Room/getRoomInfoOld?mid=${data.host_mid}`;
582
+ }
574
583
  /** 获取直播间信息 */
575
584
  getLiveRoomInfo(data) {
576
585
  return `https://api.live.bilibili.com/room/v1/Room/get_info?room_id=${data.room_id}`;
@@ -1016,6 +1025,7 @@ var BilibiliUserParamsSchema = zod_default.object({
1016
1025
  methodType: zod_default.enum([
1017
1026
  "userCard",
1018
1027
  "userDynamicList",
1028
+ "userLiveStatus",
1019
1029
  "uploaderTotalViews",
1020
1030
  "userSpaceInfo"
1021
1031
  ], { error: "方法类型必须是指定的枚举值之一" }),
@@ -1116,6 +1126,7 @@ var BilibiliValidationSchemas = {
1116
1126
  commentReplies: BilibiliCommentReplyParamsSchema,
1117
1127
  userCard: BilibiliUserParamsSchema,
1118
1128
  userDynamicList: BilibiliUserParamsSchema,
1129
+ userLiveStatus: BilibiliUserParamsSchema,
1119
1130
  userSpaceInfo: BilibiliUserParamsSchema,
1120
1131
  emojiList: BilibiliEmojiParamsSchema,
1121
1132
  bangumiInfo: BilibiliBangumiInfoParamsSchema,
@@ -1146,6 +1157,7 @@ var BilibiliMethodRoutes = {
1146
1157
  commentReplies: "/fetch_comment_reply",
1147
1158
  userCard: "/fetch_user_profile",
1148
1159
  userDynamicList: "/fetch_user_dynamic",
1160
+ userLiveStatus: "/fetch_user_live_status",
1149
1161
  userSpaceInfo: "/fetch_user_space_info",
1150
1162
  emojiList: "/fetch_emoji_list",
1151
1163
  bangumiInfo: "/fetch_bangumi_video_info",
@@ -2417,6 +2429,27 @@ async function fetchUserDynamicList(options, cookie, requestConfig) {
2417
2429
  });
2418
2430
  }
2419
2431
  /**
2432
+ * 按用户 UID 获取B站直播状态
2433
+ * @param options - 用户参数
2434
+ * @param options.host_mid - 用户 UID
2435
+ * @param cookie - B站 Cookie (可选)
2436
+ * @param requestConfig - 请求配置 (可选)
2437
+ * @returns 用户直播状态与直播间基础信息
2438
+ * @example
2439
+ * ```typescript
2440
+ * const result = await fetchUserLiveStatus({ host_mid: 123456, typeMode: 'strict' }, cookie)
2441
+ * if (result.success && result.data.data.liveStatus === 1) {
2442
+ * console.log(result.data.data.roomid) // 正在直播的房间 ID
2443
+ * }
2444
+ * ```
2445
+ */
2446
+ async function fetchUserLiveStatus(options, cookie, requestConfig) {
2447
+ return fetchBilibiliInternal("userLiveStatus", options, {
2448
+ cookie,
2449
+ requestConfig
2450
+ });
2451
+ }
2452
+ /**
2420
2453
  * 获取B站用户空间详细信息
2421
2454
  * @param options - 用户参数
2422
2455
  * @param options.host_mid - 用户 UID
@@ -2574,6 +2607,37 @@ async function fetchVideoDanmaku(options, cookie, requestConfig) {
2574
2607
  });
2575
2608
  }
2576
2609
  //#endregion
2610
+ //#region ../amagi/packages/core/src/model/fetchers/shared/request-config.ts
2611
+ /**
2612
+ * 合并 Fetcher 的实例级请求配置与单次请求配置。
2613
+ *
2614
+ * 单次配置优先,请求头单独合并。函数不会修改任一入参,因此同一绑定
2615
+ * Fetcher 可以安全地在并发任务中为不同请求使用不同配置。
2616
+ */
2617
+ var mergeRequestConfig = (base, override) => {
2618
+ if (!override) return base;
2619
+ return {
2620
+ ...base ?? {},
2621
+ ...override,
2622
+ headers: {
2623
+ ...base?.headers ?? {},
2624
+ ...override.headers ?? {}
2625
+ }
2626
+ };
2627
+ };
2628
+ /**
2629
+ * 解析绑定 Fetcher 当前调用实际使用的 cookie 与请求配置。
2630
+ *
2631
+ * 实例级或单次配置显式提供大写 `headers.Cookie` 时,合并后的值同时替换
2632
+ * 底层 Fetcher 的 cookie 参数,确保平台签名、前置请求和最终请求处于同一身份状态。
2633
+ */
2634
+ var resolveBoundRequest = (boundCookie, base, override) => {
2635
+ const requestConfig = mergeRequestConfig(base, override);
2636
+ const headers = requestConfig?.headers;
2637
+ const cookieOverride = Boolean(headers && Object.prototype.hasOwnProperty.call(headers, "Cookie")) ? headers.Cookie : void 0;
2638
+ return [typeof cookieOverride === "string" ? cookieOverride : boundCookie, requestConfig];
2639
+ };
2640
+ //#endregion
2577
2641
  //#region ../amagi/packages/core/src/model/fetchers/bilibili/bound.ts
2578
2642
  /**
2579
2643
  * 创建绑定了 Cookie 和请求配置的 B站 Fetcher
@@ -2589,35 +2653,37 @@ async function fetchVideoDanmaku(options, cookie, requestConfig) {
2589
2653
  * ```
2590
2654
  */
2591
2655
  function createBoundBilibiliFetcher(cookie, requestConfig) {
2656
+ const resolveRequest = (override) => resolveBoundRequest(cookie, requestConfig, override);
2592
2657
  return {
2593
- fetchVideoInfo: (options) => fetchVideoInfo(options, cookie, requestConfig),
2594
- fetchVideoStreamUrl: (options) => fetchVideoStreamUrl(options, cookie, requestConfig),
2595
- fetchVideoDanmaku: (options) => fetchVideoDanmaku(options, cookie, requestConfig),
2596
- fetchComments: (options) => fetchComments(options, cookie, requestConfig),
2597
- fetchCommentReplies: (options) => fetchCommentReplies$1(options, cookie, requestConfig),
2598
- fetchUserCard: (options) => fetchUserCard(options, cookie, requestConfig),
2599
- fetchUserDynamicList: (options) => fetchUserDynamicList(options, cookie, requestConfig),
2600
- fetchUserSpaceInfo: (options) => fetchUserSpaceInfo(options, cookie, requestConfig),
2601
- fetchUploaderTotalViews: (options) => fetchUploaderTotalViews(options, cookie, requestConfig),
2602
- fetchDynamicDetail: (options) => fetchDynamicDetail(options, cookie, requestConfig),
2658
+ fetchVideoInfo: (options, override) => fetchVideoInfo(options, ...resolveRequest(override)),
2659
+ fetchVideoStreamUrl: (options, override) => fetchVideoStreamUrl(options, ...resolveRequest(override)),
2660
+ fetchVideoDanmaku: (options, override) => fetchVideoDanmaku(options, ...resolveRequest(override)),
2661
+ fetchComments: (options, override) => fetchComments(options, ...resolveRequest(override)),
2662
+ fetchCommentReplies: (options, override) => fetchCommentReplies$1(options, ...resolveRequest(override)),
2663
+ fetchUserCard: (options, override) => fetchUserCard(options, ...resolveRequest(override)),
2664
+ fetchUserDynamicList: (options, override) => fetchUserDynamicList(options, ...resolveRequest(override)),
2665
+ fetchUserLiveStatus: (options, override) => fetchUserLiveStatus(options, ...resolveRequest(override)),
2666
+ fetchUserSpaceInfo: (options, override) => fetchUserSpaceInfo(options, ...resolveRequest(override)),
2667
+ fetchUploaderTotalViews: (options, override) => fetchUploaderTotalViews(options, ...resolveRequest(override)),
2668
+ fetchDynamicDetail: (options, override) => fetchDynamicDetail(options, ...resolveRequest(override)),
2603
2669
  /** @deprecated v6.1.3 已废弃,调用将返回错误信息 */
2604
- fetchDynamicCard: (options) => fetchDynamicCard(options, cookie, requestConfig),
2605
- fetchBangumiInfo: (options) => fetchBangumiInfo(options, cookie, requestConfig),
2606
- fetchBangumiStreamUrl: (options) => fetchBangumiStreamUrl(options, cookie, requestConfig),
2607
- fetchLiveRoomInfo: (options) => fetchLiveRoomInfo$2(options, cookie, requestConfig),
2608
- fetchLiveRoomInitInfo: (options) => fetchLiveRoomInitInfo(options, cookie, requestConfig),
2609
- fetchArticleContent: (options) => fetchArticleContent(options, cookie, requestConfig),
2610
- fetchArticleCards: (options) => fetchArticleCards(options, cookie, requestConfig),
2611
- fetchArticleInfo: (options) => fetchArticleInfo(options, cookie, requestConfig),
2612
- fetchArticleListInfo: (options) => fetchArticleListInfo(options, cookie, requestConfig),
2613
- fetchLoginStatus: (options) => fetchLoginStatus(options, cookie, requestConfig),
2614
- requestLoginQrcode: (options) => requestLoginQrcode$1(options, cookie, requestConfig),
2615
- checkQrcodeStatus: (options) => checkQrcodeStatus(options, cookie, requestConfig),
2616
- requestCaptchaFromVoucher: (options) => requestCaptchaFromVoucher(options, cookie, requestConfig),
2617
- validateCaptchaResult: (options) => validateCaptchaResult(options, cookie, requestConfig),
2618
- convertAvToBv: (options) => convertAvToBv(options, cookie, requestConfig),
2619
- convertBvToAv: (options) => convertBvToAv(options, cookie, requestConfig),
2620
- fetchEmojiList: (options) => fetchEmojiList$3(options, cookie, requestConfig)
2670
+ fetchDynamicCard: (options, override) => fetchDynamicCard(options, ...resolveRequest(override)),
2671
+ fetchBangumiInfo: (options, override) => fetchBangumiInfo(options, ...resolveRequest(override)),
2672
+ fetchBangumiStreamUrl: (options, override) => fetchBangumiStreamUrl(options, ...resolveRequest(override)),
2673
+ fetchLiveRoomInfo: (options, override) => fetchLiveRoomInfo$2(options, ...resolveRequest(override)),
2674
+ fetchLiveRoomInitInfo: (options, override) => fetchLiveRoomInitInfo(options, ...resolveRequest(override)),
2675
+ fetchArticleContent: (options, override) => fetchArticleContent(options, ...resolveRequest(override)),
2676
+ fetchArticleCards: (options, override) => fetchArticleCards(options, ...resolveRequest(override)),
2677
+ fetchArticleInfo: (options, override) => fetchArticleInfo(options, ...resolveRequest(override)),
2678
+ fetchArticleListInfo: (options, override) => fetchArticleListInfo(options, ...resolveRequest(override)),
2679
+ fetchLoginStatus: (options, override) => fetchLoginStatus(options, ...resolveRequest(override)),
2680
+ requestLoginQrcode: (options, override) => requestLoginQrcode$1(options, ...resolveRequest(override)),
2681
+ checkQrcodeStatus: (options, override) => checkQrcodeStatus(options, ...resolveRequest(override)),
2682
+ requestCaptchaFromVoucher: (options, override) => requestCaptchaFromVoucher(options, ...resolveRequest(override)),
2683
+ validateCaptchaResult: (options, override) => validateCaptchaResult(options, ...resolveRequest(override)),
2684
+ convertAvToBv: (options, override) => convertAvToBv(options, ...resolveRequest(override)),
2685
+ convertBvToAv: (options, override) => convertBvToAv(options, ...resolveRequest(override)),
2686
+ fetchEmojiList: (options, override) => fetchEmojiList$3(options, ...resolveRequest(override))
2621
2687
  };
2622
2688
  }
2623
2689
  //#endregion
@@ -2644,6 +2710,7 @@ var bilibiliFetcher$1 = {
2644
2710
  fetchCommentReplies: fetchCommentReplies$1,
2645
2711
  fetchUserCard,
2646
2712
  fetchUserDynamicList,
2713
+ fetchUserLiveStatus,
2647
2714
  fetchUserSpaceInfo,
2648
2715
  fetchUploaderTotalViews,
2649
2716
  fetchDynamicDetail,
@@ -5196,26 +5263,27 @@ async function fetchDanmakuList(options, cookie, requestConfig) {
5196
5263
  * ```
5197
5264
  */
5198
5265
  function createBoundDouyinFetcher(cookie, requestConfig) {
5266
+ const resolveRequest = (override) => resolveBoundRequest(cookie, requestConfig, override);
5199
5267
  return {
5200
- fetchVideoWork: (options, reqConfig) => fetchVideoWork$1(options, cookie, reqConfig ?? requestConfig),
5201
- fetchImageAlbumWork: (options, reqConfig) => fetchImageAlbumWork(options, cookie, reqConfig ?? requestConfig),
5202
- fetchSlidesWork: (options, reqConfig) => fetchSlidesWork(options, cookie, reqConfig ?? requestConfig),
5203
- fetchTextWork: (options, reqConfig) => fetchTextWork(options, cookie, reqConfig ?? requestConfig),
5204
- parseWork: (options, reqConfig) => parseWork(options, cookie, reqConfig ?? requestConfig),
5205
- fetchDanmakuList: (options, reqConfig) => fetchDanmakuList(options, cookie, reqConfig ?? requestConfig),
5206
- fetchWorkComments: (options, reqConfig) => fetchWorkComments$1(options, cookie, reqConfig ?? requestConfig),
5207
- fetchCommentReplies: (options, reqConfig) => fetchCommentReplies(options, cookie, reqConfig ?? requestConfig),
5208
- fetchUserProfile: (options, reqConfig) => fetchUserProfile$2(options, cookie, reqConfig ?? requestConfig),
5209
- fetchUserVideoList: (options, reqConfig) => fetchUserVideoList(options, cookie, reqConfig ?? requestConfig),
5210
- fetchUserFavoriteList: (options, reqConfig) => fetchUserFavoriteList(options, cookie, reqConfig ?? requestConfig),
5211
- fetchUserRecommendList: (options, reqConfig) => fetchUserRecommendList(options, cookie, reqConfig ?? requestConfig),
5212
- searchContent: (options, reqConfig) => searchContent(options, cookie, reqConfig ?? requestConfig),
5213
- fetchSuggestWords: (options, reqConfig) => fetchSuggestWords(options, cookie, reqConfig ?? requestConfig),
5214
- fetchMusicInfo: (options, reqConfig) => fetchMusicInfo(options, cookie, reqConfig ?? requestConfig),
5215
- fetchLiveRoomInfo: (options, reqConfig) => fetchLiveRoomInfo$1(options, cookie, reqConfig ?? requestConfig),
5216
- requestLoginQrcode: (options, reqConfig) => requestLoginQrcode(options, cookie, reqConfig ?? requestConfig),
5217
- fetchEmojiList: (options, reqConfig) => fetchEmojiList$2(options, cookie, reqConfig ?? requestConfig),
5218
- fetchDynamicEmojiList: (options, reqConfig) => fetchDynamicEmojiList(options, cookie, reqConfig ?? requestConfig)
5268
+ fetchVideoWork: (options, override) => fetchVideoWork$1(options, ...resolveRequest(override)),
5269
+ fetchImageAlbumWork: (options, override) => fetchImageAlbumWork(options, ...resolveRequest(override)),
5270
+ fetchSlidesWork: (options, override) => fetchSlidesWork(options, ...resolveRequest(override)),
5271
+ fetchTextWork: (options, override) => fetchTextWork(options, ...resolveRequest(override)),
5272
+ parseWork: (options, override) => parseWork(options, ...resolveRequest(override)),
5273
+ fetchDanmakuList: (options, override) => fetchDanmakuList(options, ...resolveRequest(override)),
5274
+ fetchWorkComments: (options, override) => fetchWorkComments$1(options, ...resolveRequest(override)),
5275
+ fetchCommentReplies: (options, override) => fetchCommentReplies(options, ...resolveRequest(override)),
5276
+ fetchUserProfile: (options, override) => fetchUserProfile$2(options, ...resolveRequest(override)),
5277
+ fetchUserVideoList: (options, override) => fetchUserVideoList(options, ...resolveRequest(override)),
5278
+ fetchUserFavoriteList: (options, override) => fetchUserFavoriteList(options, ...resolveRequest(override)),
5279
+ fetchUserRecommendList: (options, override) => fetchUserRecommendList(options, ...resolveRequest(override)),
5280
+ searchContent: (options, override) => searchContent(options, ...resolveRequest(override)),
5281
+ fetchSuggestWords: (options, override) => fetchSuggestWords(options, ...resolveRequest(override)),
5282
+ fetchMusicInfo: (options, override) => fetchMusicInfo(options, ...resolveRequest(override)),
5283
+ fetchLiveRoomInfo: (options, override) => fetchLiveRoomInfo$1(options, ...resolveRequest(override)),
5284
+ requestLoginQrcode: (options, override) => requestLoginQrcode(options, ...resolveRequest(override)),
5285
+ fetchEmojiList: (options, override) => fetchEmojiList$2(options, ...resolveRequest(override)),
5286
+ fetchDynamicEmojiList: (options, override) => fetchDynamicEmojiList(options, ...resolveRequest(override))
5219
5287
  };
5220
5288
  }
5221
5289
  //#endregion
@@ -7608,13 +7676,14 @@ var kuaishouFetcher$1 = {
7608
7676
  * ```
7609
7677
  */
7610
7678
  function createBoundKuaishouFetcher(cookie, requestConfig) {
7679
+ const resolveRequest = (override) => resolveBoundRequest(cookie, requestConfig, override);
7611
7680
  return {
7612
- fetchVideoWork: (options, reqConfig) => fetchVideoWork(options, cookie, reqConfig ?? requestConfig),
7613
- fetchWorkComments: (options, reqConfig) => fetchWorkComments(options, cookie, reqConfig ?? requestConfig),
7614
- fetchUserProfile: (options, reqConfig) => fetchUserProfile$1(options, cookie, reqConfig ?? requestConfig),
7615
- fetchUserWorkList: (options, reqConfig) => fetchUserWorkList(options, cookie, reqConfig ?? requestConfig),
7616
- fetchLiveRoomInfo: (options, reqConfig) => fetchLiveRoomInfo(options, cookie, reqConfig ?? requestConfig),
7617
- fetchEmojiList: (options, reqConfig) => fetchEmojiList$1(options, cookie, reqConfig ?? requestConfig)
7681
+ fetchVideoWork: (options, override) => fetchVideoWork(options, ...resolveRequest(override)),
7682
+ fetchWorkComments: (options, override) => fetchWorkComments(options, ...resolveRequest(override)),
7683
+ fetchUserProfile: (options, override) => fetchUserProfile$1(options, ...resolveRequest(override)),
7684
+ fetchUserWorkList: (options, override) => fetchUserWorkList(options, ...resolveRequest(override)),
7685
+ fetchLiveRoomInfo: (options, override) => fetchLiveRoomInfo(options, ...resolveRequest(override)),
7686
+ fetchEmojiList: (options, override) => fetchEmojiList$1(options, ...resolveRequest(override))
7618
7687
  };
7619
7688
  }
7620
7689
  //#endregion
@@ -8053,14 +8122,15 @@ var xiaohongshuFetcher$1 = {
8053
8122
  * ```
8054
8123
  */
8055
8124
  function createBoundXiaohongshuFetcher(cookie, requestConfig) {
8125
+ const resolveRequest = (override) => resolveBoundRequest(cookie, requestConfig, override);
8056
8126
  return {
8057
- fetchHomeFeed: (options = {}, reqConfig) => fetchHomeFeed(options, cookie, reqConfig ?? requestConfig),
8058
- fetchNoteDetail: (options, reqConfig) => fetchNoteDetail(options, cookie, reqConfig ?? requestConfig),
8059
- fetchNoteComments: (options, reqConfig) => fetchNoteComments(options, cookie, reqConfig ?? requestConfig),
8060
- fetchUserProfile: (options, reqConfig) => fetchUserProfile(options, cookie, reqConfig ?? requestConfig),
8061
- fetchUserNoteList: (options, reqConfig) => fetchUserNoteList(options, cookie, reqConfig ?? requestConfig),
8062
- searchNotes: (options, reqConfig) => searchNotes(options, cookie, reqConfig ?? requestConfig),
8063
- fetchEmojiList: (options, reqConfig) => fetchEmojiList(options, cookie, reqConfig ?? requestConfig)
8127
+ fetchHomeFeed: (options = {}, override) => fetchHomeFeed(options, ...resolveRequest(override)),
8128
+ fetchNoteDetail: (options, override) => fetchNoteDetail(options, ...resolveRequest(override)),
8129
+ fetchNoteComments: (options, override) => fetchNoteComments(options, ...resolveRequest(override)),
8130
+ fetchUserProfile: (options, override) => fetchUserProfile(options, ...resolveRequest(override)),
8131
+ fetchUserNoteList: (options, override) => fetchUserNoteList(options, ...resolveRequest(override)),
8132
+ searchNotes: (options, override) => searchNotes(options, ...resolveRequest(override)),
8133
+ fetchEmojiList: (options, override) => fetchEmojiList(options, ...resolveRequest(override))
8064
8134
  };
8065
8135
  }
8066
8136
  //#endregion
@@ -8823,6 +8893,10 @@ var fetchBilibili = async (data, cookie, requestConfig) => {
8823
8893
  url: bilibiliApiUrls.getUserCard({ host_mid })
8824
8894
  });
8825
8895
  }
8896
+ case "userLiveStatus": return await GlobalGetData(data.methodType, {
8897
+ ...baseRequestConfig,
8898
+ url: bilibiliApiUrls.getUserLiveStatus({ host_mid: data.host_mid })
8899
+ });
8826
8900
  case "userSpaceInfo": {
8827
8901
  const wbiSignQuery = await wbi_sign(bilibiliApiUrls.getUserSpaceInfo({ host_mid: data.host_mid }), baseRequestConfig.headers?.cookie);
8828
8902
  return await GlobalGetData(data.methodType, {
@@ -9910,6 +9984,7 @@ var BilibiliInternalMethods = {
9910
9984
  COMMENT_REPLIES: "指定评论的回复",
9911
9985
  USER_CARD: "用户主页数据",
9912
9986
  USER_DYNAMICS: "用户主页动态列表数据",
9987
+ USER_LIVE_STATUS: "用户直播状态",
9913
9988
  USER_SPACE_INFO: "用户空间详细信息",
9914
9989
  USER_TOTAL_VIEWS: "获取UP主总播放量",
9915
9990
  DYNAMIC_DETAIL: "动态详情数据",
@@ -9940,6 +10015,7 @@ var BilibiliFetcherMethods = {
9940
10015
  COMMENT_REPLIES: "fetchCommentReplies",
9941
10016
  USER_CARD: "fetchUserCard",
9942
10017
  USER_DYNAMICS: "fetchUserDynamicList",
10018
+ USER_LIVE_STATUS: "fetchUserLiveStatus",
9943
10019
  USER_SPACE_INFO: "fetchUserSpaceInfo",
9944
10020
  USER_TOTAL_VIEWS: "fetchUploaderTotalViews",
9945
10021
  DYNAMIC_DETAIL: "fetchDynamicDetail",
@@ -10048,6 +10124,7 @@ var BilibiliMethodToFetcher = {
10048
10124
  [BilibiliInternalMethods.COMMENT_REPLIES]: BilibiliFetcherMethods.COMMENT_REPLIES,
10049
10125
  [BilibiliInternalMethods.USER_CARD]: BilibiliFetcherMethods.USER_CARD,
10050
10126
  [BilibiliInternalMethods.USER_DYNAMICS]: BilibiliFetcherMethods.USER_DYNAMICS,
10127
+ [BilibiliInternalMethods.USER_LIVE_STATUS]: BilibiliFetcherMethods.USER_LIVE_STATUS,
10051
10128
  [BilibiliInternalMethods.USER_SPACE_INFO]: BilibiliFetcherMethods.USER_SPACE_INFO,
10052
10129
  [BilibiliInternalMethods.USER_TOTAL_VIEWS]: BilibiliFetcherMethods.USER_TOTAL_VIEWS,
10053
10130
  [BilibiliInternalMethods.DYNAMIC_DETAIL]: BilibiliFetcherMethods.DYNAMIC_DETAIL,
@@ -10179,6 +10256,7 @@ var BilibiliMethodMapping = {
10179
10256
  指定评论的回复: "fetchCommentReplies",
10180
10257
  用户主页数据: "fetchUserCard",
10181
10258
  用户主页动态列表数据: "fetchUserDynamicList",
10259
+ 用户直播状态: "fetchUserLiveStatus",
10182
10260
  用户空间详细信息: "fetchUserSpaceInfo",
10183
10261
  获取UP主总播放量: "fetchUploaderTotalViews",
10184
10262
  动态详情数据: "fetchDynamicDetail",
@@ -10261,6 +10339,7 @@ var BilibiliApiRoutes = {
10261
10339
  commentReplies: "/comment-replies",
10262
10340
  userCard: "/user",
10263
10341
  userDynamicList: "/user/dynamics",
10342
+ userLiveStatus: "/user/live-status",
10264
10343
  userSpaceInfo: "/user/space",
10265
10344
  uploaderTotalViews: "/user/total-views",
10266
10345
  dynamicDetail: "/dynamic",
@@ -10334,7 +10413,7 @@ function getApiRoute(platform, methodType) {
10334
10413
  * 构建后使用 __VERSION__,开发环境从 package.json 读取
10335
10414
  */
10336
10415
  var getVersion = () => {
10337
- return "6.2.0";
10416
+ return "6.4.0";
10338
10417
  };
10339
10418
  var VERSION = getVersion();
10340
10419
  /**
@@ -19565,7 +19644,7 @@ var DouyinPosterHeader$2 = ({ data }) => {
19565
19644
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
19566
19645
  className: "min-w-0",
19567
19646
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
19568
- className: "max-w-[660px] truncate text-[44px] font-black leading-tight text-foreground select-text",
19647
+ className: "max-w-165 truncate text-[44px] font-black leading-tight text-foreground select-text",
19569
19648
  children: username
19570
19649
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
19571
19650
  className: "mt-3 flex flex-wrap items-center gap-x-5 gap-y-2 text-[30px] text-muted",
@@ -19591,7 +19670,7 @@ var DouyinPosterHeader$2 = ({ data }) => {
19591
19670
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
19592
19671
  src: useDarkTheme ? "/image/douyin/dylogo-light.svg" : "/image/douyin/dylogo-dark.svg",
19593
19672
  alt: "抖音",
19594
- className: "mt-2 h-[68px] w-auto shrink-0 object-contain opacity-90"
19673
+ className: "mt-2 h-17 w-auto shrink-0 object-contain opacity-90"
19595
19674
  })]
19596
19675
  });
19597
19676
  };
@@ -19738,7 +19817,7 @@ var DouyinSignalLine$2 = ({ data }) => {
19738
19817
  ].map((stat) => {
19739
19818
  const Icon = stat.icon;
19740
19819
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
19741
- className: "min-w-[150px]",
19820
+ className: "min-w-37.5",
19742
19821
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
19743
19822
  className: "flex items-center gap-3 text-[28px] font-semibold text-muted",
19744
19823
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, {
@@ -19778,7 +19857,7 @@ var DouyinPosterFooter$2 = ({ data }) => {
19778
19857
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
19779
19858
  className: "min-w-0",
19780
19859
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
19781
- className: "max-w-[650px] truncate text-[48px] font-black leading-tight text-foreground select-text",
19860
+ className: "max-w-162.5 truncate text-[48px] font-black leading-tight text-foreground select-text",
19782
19861
  children: username
19783
19862
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
19784
19863
  className: "mt-3 flex items-center gap-2 text-[30px] text-muted",
@@ -19812,7 +19891,7 @@ var DouyinPosterFooter$2 = ({ data }) => {
19812
19891
  ].map((stat) => {
19813
19892
  const Icon = stat.icon;
19814
19893
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
19815
- className: "min-w-[150px]",
19894
+ className: "min-w-37.5",
19816
19895
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
19817
19896
  className: "flex items-center gap-3 text-[25px] font-semibold text-muted",
19818
19897
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, {
@@ -19836,7 +19915,7 @@ var DouyinPosterFooter$2 = ({ data }) => {
19836
19915
  avatarUrl: avater_url,
19837
19916
  useDarkTheme,
19838
19917
  alt: "二维码",
19839
- className: "h-[300px] w-[300px]"
19918
+ className: "h-75 w-75"
19840
19919
  })
19841
19920
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
19842
19921
  className: "mt-2 text-[28px] font-black text-foreground/80",
@@ -21135,7 +21214,7 @@ var DouyinPosterHeader$1 = ({ data }) => {
21135
21214
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21136
21215
  className: "min-w-0",
21137
21216
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
21138
- className: "max-w-[660px] truncate text-[44px] font-black leading-tight text-foreground select-text",
21217
+ className: "max-w-165 truncate text-[44px] font-black leading-tight text-foreground select-text",
21139
21218
  children: username
21140
21219
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21141
21220
  className: "mt-3 flex flex-wrap items-center gap-x-5 gap-y-2 text-[30px] text-muted",
@@ -21160,7 +21239,7 @@ var DouyinPosterHeader$1 = ({ data }) => {
21160
21239
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
21161
21240
  src: useDarkTheme ? "/image/douyin/dylogo-light.svg" : "/image/douyin/dylogo-dark.svg",
21162
21241
  alt: "抖音",
21163
- className: "mt-2 h-[68px] w-auto shrink-0 object-contain opacity-90"
21242
+ className: "mt-2 h-17 w-auto shrink-0 object-contain opacity-90"
21164
21243
  })]
21165
21244
  });
21166
21245
  };
@@ -21187,7 +21266,7 @@ var DouyinPosterTitle$1 = ({ data }) => {
21187
21266
  },
21188
21267
  children: renderRichTextToReact(title, richTextOptions)
21189
21268
  }), hasDesc && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
21190
- className: cn$1("mt-7 whitespace-pre-wrap select-text", !hasTitle ? "text-6xl font-bold leading-tight" : "text-5xl font-medium"),
21269
+ className: cn$1("mt-7 whitespace-pre-wrap select-text", !hasTitle ? "text-6xl font-bold" : "text-5xl font-medium", "leading-tight"),
21191
21270
  style: {
21192
21271
  wordBreak: "break-word",
21193
21272
  overflowWrap: "break-word"
@@ -21270,7 +21349,7 @@ var DouyinImageCover = ({ data }) => {
21270
21349
  })
21271
21350
  }),
21272
21351
  music && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21273
- className: "absolute bottom-12 left-24 z-30 flex max-w-[850px] items-center gap-5 text-white drop-shadow-xl",
21352
+ className: "absolute bottom-12 left-24 z-30 flex max-w-212.5 items-center gap-5 text-white drop-shadow-xl",
21274
21353
  children: [music.cover ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
21275
21354
  className: "relative h-20 w-20 shrink-0",
21276
21355
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GlowImage, {
@@ -21333,7 +21412,7 @@ var DouyinSignalLine$1 = ({ data }) => {
21333
21412
  ].map((stat) => {
21334
21413
  const Icon = stat.icon;
21335
21414
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21336
- className: "min-w-[150px]",
21415
+ className: "min-w-37.5",
21337
21416
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21338
21417
  className: "flex items-center gap-3 text-[28px] font-semibold text-muted",
21339
21418
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, {
@@ -21388,11 +21467,11 @@ var DouyinCoCreatorList$1 = ({ data, coCreatorCount }) => {
21388
21467
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21389
21468
  className: "mt-6 flex min-w-0 flex-wrap items-center gap-x-10 gap-y-6 overflow-hidden",
21390
21469
  children: [visibleCreators.map((creator, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21391
- className: "flex min-w-0 max-w-[310px] items-center gap-4",
21470
+ className: "flex min-w-0 max-w-77.5 items-center gap-4",
21392
21471
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
21393
21472
  src: creator.avatar_url || data.avater_url,
21394
21473
  alt: "共创者头像",
21395
- className: "h-[72px] w-[72px] shrink-0 rounded-full object-cover shadow-xl",
21474
+ className: "h-18 w-18 shrink-0 rounded-full object-cover shadow-xl",
21396
21475
  referrerPolicy: "no-referrer",
21397
21476
  crossOrigin: "anonymous"
21398
21477
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -21433,7 +21512,7 @@ var DouyinPosterFooter$1 = ({ data }) => {
21433
21512
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21434
21513
  className: "min-w-0",
21435
21514
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
21436
- className: "max-w-[650px] truncate text-[48px] font-black leading-tight text-foreground select-text",
21515
+ className: "max-w-162.5 truncate text-[48px] font-black leading-tight text-foreground select-text",
21437
21516
  children: username
21438
21517
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21439
21518
  className: "mt-3 flex items-center gap-2 text-[30px] text-muted",
@@ -21467,7 +21546,7 @@ var DouyinPosterFooter$1 = ({ data }) => {
21467
21546
  ].map((stat) => {
21468
21547
  const Icon = stat.icon;
21469
21548
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21470
- className: "min-w-[150px]",
21549
+ className: "min-w-37.5",
21471
21550
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
21472
21551
  className: "flex items-center gap-3 text-[25px] font-semibold text-muted",
21473
21552
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, {
@@ -21491,7 +21570,7 @@ var DouyinPosterFooter$1 = ({ data }) => {
21491
21570
  avatarUrl: avater_url,
21492
21571
  useDarkTheme,
21493
21572
  alt: "二维码",
21494
- className: "h-[300px] w-[300px]"
21573
+ className: "h-75 w-75"
21495
21574
  })
21496
21575
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
21497
21576
  className: "mt-2 text-[28px] font-black text-foreground/80",
@@ -23250,7 +23329,7 @@ var DouyinPosterHeader = ({ data }) => {
23250
23329
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23251
23330
  className: "min-w-0",
23252
23331
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
23253
- className: "max-w-[660px] truncate text-[44px] font-black leading-tight text-foreground select-text",
23332
+ className: "max-w-165 truncate text-[44px] font-black leading-tight text-foreground select-text",
23254
23333
  children: username
23255
23334
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23256
23335
  className: "mt-3 flex flex-wrap items-center gap-x-5 gap-y-2 text-[30px] text-muted",
@@ -23275,7 +23354,7 @@ var DouyinPosterHeader = ({ data }) => {
23275
23354
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
23276
23355
  src: useDarkTheme ? "/image/douyin/dylogo-light.svg" : "/image/douyin/dylogo-dark.svg",
23277
23356
  alt: "抖音",
23278
- className: "mt-2 h-[68px] w-auto shrink-0 object-contain opacity-90"
23357
+ className: "mt-2 h-17 w-auto shrink-0 object-contain opacity-90"
23279
23358
  })]
23280
23359
  });
23281
23360
  };
@@ -23325,7 +23404,7 @@ var DouyinVideoCover = ({ data }) => {
23325
23404
  className: "absolute bottom-12 right-24 z-30 text-white opacity-90 drop-shadow-2xl"
23326
23405
  }),
23327
23406
  music && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23328
- className: "absolute bottom-12 left-24 z-30 flex max-w-[850px] items-center gap-5 text-white drop-shadow-xl",
23407
+ className: "absolute bottom-12 left-24 z-30 flex max-w-212.5 items-center gap-5 text-white drop-shadow-xl",
23329
23408
  children: [music.cover ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
23330
23409
  className: "relative h-20 w-20 shrink-0",
23331
23410
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GlowImage, {
@@ -23380,7 +23459,7 @@ var DouyinPosterTitle = ({ data }) => {
23380
23459
  },
23381
23460
  children: renderRichTextToReact(title, richTextOptions)
23382
23461
  }), hasDesc && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
23383
- className: "mt-7 max-w-[1160px] whitespace-pre-wrap text-[42px] font-medium leading-[1.48] text-muted select-text",
23462
+ className: "mt-7 max-w-290 whitespace-pre-wrap text-[42px] font-medium leading-tight text-muted select-text",
23384
23463
  style: {
23385
23464
  wordBreak: "break-word",
23386
23465
  overflowWrap: "break-word"
@@ -23420,7 +23499,7 @@ var DouyinSignalLine = ({ data }) => {
23420
23499
  ].map((stat) => {
23421
23500
  const Icon = stat.icon;
23422
23501
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23423
- className: "min-w-[150px]",
23502
+ className: "min-w-37.5",
23424
23503
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23425
23504
  className: "flex items-center gap-3 text-[28px] font-semibold text-muted",
23426
23505
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, {
@@ -23474,11 +23553,11 @@ var DouyinCoCreatorList = ({ data, coCreatorCount }) => {
23474
23553
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23475
23554
  className: "mt-6 flex min-w-0 flex-wrap items-center gap-x-10 gap-y-6 overflow-hidden",
23476
23555
  children: [visibleCreators.map((creator, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23477
- className: "flex min-w-0 max-w-[310px] items-center gap-4",
23556
+ className: "flex min-w-0 max-w-77.5 items-center gap-4",
23478
23557
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
23479
23558
  src: creator.avatar_url || data.avater_url,
23480
23559
  alt: "共创者头像",
23481
- className: "h-[72px] w-[72px] shrink-0 rounded-full object-cover shadow-xl",
23560
+ className: "h-18 w-18 shrink-0 rounded-full object-cover shadow-xl",
23482
23561
  referrerPolicy: "no-referrer",
23483
23562
  crossOrigin: "anonymous"
23484
23563
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -23519,7 +23598,7 @@ var DouyinPosterFooter = ({ data }) => {
23519
23598
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23520
23599
  className: "min-w-0",
23521
23600
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
23522
- className: "max-w-[650px] truncate text-[48px] font-black leading-tight text-foreground select-text",
23601
+ className: "max-w-162.5 truncate text-[48px] font-black leading-tight text-foreground select-text",
23523
23602
  children: username
23524
23603
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23525
23604
  className: "mt-3 flex items-center gap-2 text-[30px] text-muted",
@@ -23553,7 +23632,7 @@ var DouyinPosterFooter = ({ data }) => {
23553
23632
  ].map((stat) => {
23554
23633
  const Icon = stat.icon;
23555
23634
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23556
- className: "min-w-[150px]",
23635
+ className: "min-w-37.5",
23557
23636
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
23558
23637
  className: "flex items-center gap-3 text-[25px] font-semibold text-muted",
23559
23638
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, {
@@ -23577,7 +23656,7 @@ var DouyinPosterFooter = ({ data }) => {
23577
23656
  avatarUrl: avater_url,
23578
23657
  useDarkTheme,
23579
23658
  alt: "二维码",
23580
- className: "h-[300px] w-[300px]"
23659
+ className: "h-75 w-75"
23581
23660
  })
23582
23661
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
23583
23662
  className: "mt-2 text-[28px] font-black text-foreground/80",
@@ -35035,6 +35114,8 @@ var buildBilibiliRichTextForwardMessage = async (document, options = {}) => {
35035
35114
  //#endregion
35036
35115
  //#region src/platform/bilibili/bilibili.ts
35037
35116
  var img$1;
35117
+ /** 评论请求统一使用匿名态,避免账号 Cookie 改变评论热度池结果。 */
35118
+ var bilibiliAnonymousRequestConfig = { headers: { Cookie: "" } };
35038
35119
  var Bilibili = class extends Base {
35039
35120
  e;
35040
35121
  type;
@@ -35158,7 +35239,7 @@ var Bilibili = class extends Base {
35158
35239
  type: 1,
35159
35240
  oid: infoData.data.data.aid.toString(),
35160
35241
  typeMode: "strict"
35161
- }), [SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED]);
35242
+ }, bilibiliAnonymousRequestConfig), [SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED]);
35162
35243
  if (commentsData.code === SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED) this.e.reply("UP主已关闭评论区,无法获取评论");
35163
35244
  else {
35164
35245
  const { comments: commentsdata, image_urls } = bilibiliComments(commentsData.data, infoData.data.data.owner.mid.toString());
@@ -35786,7 +35867,7 @@ var Bilibili = class extends Base {
35786
35867
  oid: oid(dynamicInfo.data.data.item.type, dynamicInfo.data),
35787
35868
  number: Config.bilibili.numcomment,
35788
35869
  typeMode: "strict"
35789
- }), [SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED]);
35870
+ }, bilibiliAnonymousRequestConfig), [SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED]);
35790
35871
  if (commentsData.code === SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED) this.e.reply("UP主已关闭评论区,无法获取评论");
35791
35872
  else {
35792
35873
  const { comments: commentsdata, image_urls } = bilibiliComments(commentsData.data, dynamicInfo.data.data.item.modules.module_author.mid.toString());
@@ -36822,6 +36903,43 @@ var bilibiliLogin = async (e) => {
36822
36903
  }
36823
36904
  };
36824
36905
  //#endregion
36906
+ //#region src/platform/bilibili/live-status.ts
36907
+ var invalidLiveTimes = /* @__PURE__ */ new Set([
36908
+ "",
36909
+ "-62170012800",
36910
+ "0000-00-00 00:00:00"
36911
+ ]);
36912
+ /**
36913
+ * 将B站返回的东八区开播时间转换为数据库可比较的 ISO 时间。
36914
+ *
36915
+ * @param liveTime B站直播间详情返回的开播时间。
36916
+ * @returns 有效的 UTC ISO 时间;无法解析时返回 `null`。
36917
+ */
36918
+ var parseBilibiliLiveStartedAt = (liveTime) => {
36919
+ const normalizedLiveTime = liveTime.trim();
36920
+ if (invalidLiveTimes.has(normalizedLiveTime)) return null;
36921
+ const zonedLiveTime = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(normalizedLiveTime) ? `${normalizedLiveTime.replace(" ", "T")}+08:00` : normalizedLiveTime;
36922
+ const timestamp = Date.parse(zonedLiveTime);
36923
+ return Number.isNaN(timestamp) ? null : new Date(timestamp).toISOString();
36924
+ };
36925
+ /**
36926
+ * 使用直播间和开播时间构造跨检测源稳定的场次缓存键。
36927
+ *
36928
+ * @remarks
36929
+ * 定时推送可能先从 UID 直播状态接口发现开播,也可能在接口异常时回退到动态列表。
36930
+ * 两条路径必须使用同一个场次键,才能避免同一场直播被重复推送。
36931
+ *
36932
+ * @param hostMid UP 主 UID。
36933
+ * @param roomId 直播间长号。
36934
+ * @param liveTime B站直播间详情返回的本场开播时间。
36935
+ * @returns 可用于 `DynamicCaches` 的场次键;开播时间无效时返回 `null`。
36936
+ */
36937
+ var buildBilibiliLiveSessionId = (hostMid, roomId, liveTime) => {
36938
+ const normalizedLiveTime = liveTime.trim();
36939
+ if (!parseBilibiliLiveStartedAt(normalizedLiveTime)) return null;
36940
+ return `bilibili-live:${hostMid}:${roomId}:${normalizedLiveTime}`;
36941
+ };
36942
+ //#endregion
36825
36943
  //#region src/platform/bilibili/push.ts
36826
36944
  /** BilibiliPushType 到 DynamicType 的映射 */
36827
36945
  var pushTypeToDynamicType = {
@@ -36929,6 +37047,88 @@ var Bilibilipush = class extends Base {
36929
37047
  }
36930
37048
  return filteredList;
36931
37049
  }
37050
+ /** 将 UID 直播状态接口的结果接入原有动态推送列表。 */
37051
+ async getDirectLivePushItems(userList) {
37052
+ const handledUids = /* @__PURE__ */ new Set();
37053
+ const willBePushList = {};
37054
+ const liveSubscriptions = userList.filter((item) => item.switch !== false && (item.pushTypes || allBilibiliPushTypes).includes("live"));
37055
+ for (const item of liveSubscriptions) {
37056
+ let liveStatus;
37057
+ try {
37058
+ const liveStatusResult = await this.amagi.bilibili.fetcher.fetchUserLiveStatus({
37059
+ host_mid: item.host_mid,
37060
+ typeMode: "strict"
37061
+ });
37062
+ if (!liveStatusResult.success) throw new Error(`code=${liveStatusResult.code}:${liveStatusResult.message}`);
37063
+ liveStatus = liveStatusResult.data.data;
37064
+ } catch (error) {
37065
+ logger.warn(`[Bilibili 推送] UP主 ${item.remark}(${item.host_mid})直播状态直查失败,本轮停止直查并让剩余订阅回退到直播动态检测:${formatErrorMessage(error)}`);
37066
+ break;
37067
+ }
37068
+ if (liveStatus.roomStatus !== 1 || liveStatus.liveStatus !== 1 || liveStatus.roomid <= 0) {
37069
+ handledUids.add(item.host_mid);
37070
+ continue;
37071
+ }
37072
+ try {
37073
+ const liveInfo = (await this.amagi.bilibili.fetcher.fetchLiveRoomInfo({
37074
+ room_id: String(liveStatus.roomid),
37075
+ typeMode: "strict"
37076
+ })).data.data;
37077
+ /** 两个直播接口状态不一致时,以直播间详情为准。 */
37078
+ if (liveInfo.live_status !== 1) {
37079
+ handledUids.add(item.host_mid);
37080
+ continue;
37081
+ }
37082
+ const sessionId = buildBilibiliLiveSessionId(item.host_mid, liveInfo.room_id, liveInfo.live_time);
37083
+ const liveStartedAt = parseBilibiliLiveStartedAt(liveInfo.live_time);
37084
+ if (!sessionId || !liveStartedAt) throw new Error(`直播间 ${liveInfo.room_id} 未返回可用于场次去重的开播时间`);
37085
+ const dynamic = createLiveDynamicItem(sessionId, liveStartedAt, liveInfo, liveStatus);
37086
+ willBePushList[sessionId] = {
37087
+ remark: item.remark,
37088
+ host_mid: item.host_mid,
37089
+ create_time: dynamic.modules.module_author.pub_ts,
37090
+ targets: item.group_id.map((groupWithBot) => {
37091
+ const [groupId, botId] = groupWithBot.split(":");
37092
+ return {
37093
+ groupId,
37094
+ botId
37095
+ };
37096
+ }),
37097
+ Dynamic_Data: dynamic,
37098
+ avatar_img: "",
37099
+ dynamic_type: DynamicType.LIVE_RCMD
37100
+ };
37101
+ handledUids.add(item.host_mid);
37102
+ } catch (error) {
37103
+ logger.warn(`[Bilibili 推送] UP主 ${item.remark}(${item.host_mid})直播场次信息不完整,本轮回退到直播动态检测:${formatErrorMessage(error)}`);
37104
+ }
37105
+ }
37106
+ return {
37107
+ handledUids,
37108
+ willBePushList
37109
+ };
37110
+ }
37111
+ /**
37112
+ * 为降级路径中的直播动态解析与直查路径一致的场次缓存键。
37113
+ *
37114
+ * @param dynamic B站空间动态中的直播推荐项。
37115
+ * @param hostMid UP 主 UID。
37116
+ * @returns 可用时返回直播场次键,否则退回原始动态ID。
37117
+ */
37118
+ async resolveLiveDynamicCacheId(dynamic, hostMid) {
37119
+ try {
37120
+ const liveData = JSON.parse(dynamic.modules.module_dynamic.major.live_rcmd.content);
37121
+ const roomId = Number(liveData.live_play_info.room_id);
37122
+ const liveInfo = await this.amagi.bilibili.fetcher.fetchLiveRoomInfo({
37123
+ room_id: String(roomId),
37124
+ typeMode: "strict"
37125
+ });
37126
+ return buildBilibiliLiveSessionId(hostMid, liveInfo.data.data.room_id, liveInfo.data.data.live_time) || dynamic.id_str;
37127
+ } catch (error) {
37128
+ logger.warn(`[Bilibili 推送] 直播动态 ${dynamic.id_str} 无法解析统一场次键,将使用动态ID去重:${formatErrorMessage(error)}`);
37129
+ return dynamic.id_str;
37130
+ }
37131
+ }
36932
37132
  /**
36933
37133
  * 同步配置文件中的订阅信息到数据库
36934
37134
  */
@@ -37580,18 +37780,22 @@ var Bilibilipush = class extends Base {
37580
37780
  }
37581
37781
  /**
37582
37782
  * 根据配置文件获取UP当天的动态列表。
37783
+ * @param userList B站订阅列表。
37583
37784
  * @returns
37584
37785
  */
37585
37786
  async getDynamicList(userList) {
37586
- const willbepushlist = {};
37787
+ const directLiveItems = await this.getDirectLivePushItems(userList);
37788
+ const willbepushlist = { ...directLiveItems.willBePushList };
37587
37789
  try {
37588
37790
  /** 过滤掉不启用的订阅项 */
37589
37791
  const filteredUserList = userList.filter((item) => item.switch !== false);
37590
37792
  for (const item of filteredUserList) {
37591
- await common.sleep(2e3);
37592
- logger.debug(`[Bilibili 推送] 开始获取UP: ${item.remark}(${item.host_mid}) 的动态列表`);
37593
37793
  const pushTypes = item.pushTypes || allBilibiliPushTypes;
37594
37794
  const allowedDynamicTypes = new Set(pushTypes.map((pt) => pushTypeToDynamicType[pt]));
37795
+ if (directLiveItems.handledUids.has(item.host_mid)) allowedDynamicTypes.delete(DynamicType.LIVE_RCMD);
37796
+ if (allowedDynamicTypes.size === 0) continue;
37797
+ await common.sleep(2e3);
37798
+ logger.debug(`[Bilibili 推送] 开始获取UP: ${item.remark}(${item.host_mid}) 的动态列表`);
37595
37799
  const dynamic_list = await this.amagi.bilibili.fetcher.fetchUserDynamicList({
37596
37800
  host_mid: item.host_mid,
37597
37801
  typeMode: "strict"
@@ -37630,7 +37834,8 @@ var Bilibilipush = class extends Base {
37630
37834
  botId
37631
37835
  };
37632
37836
  });
37633
- if (!willbepushlist[dynamic.id_str]) willbepushlist[dynamic.id_str] = {
37837
+ const pushId = dynamic.type === DynamicType.LIVE_RCMD ? await this.resolveLiveDynamicCacheId(dynamic, item.host_mid) : dynamic.id_str;
37838
+ if (!willbepushlist[pushId]) willbepushlist[pushId] = {
37634
37839
  remark: item.remark,
37635
37840
  host_mid: item.host_mid,
37636
37841
  create_time: dynamic.modules.module_author.pub_ts,
@@ -37812,6 +38017,44 @@ var Bilibilipush = class extends Base {
37812
38017
  }
37813
38018
  };
37814
38019
  /**
38020
+ * 把直播状态接口的数据适配为现有直播动态分支实际读取的字段。
38021
+ *
38022
+ * 后续过滤、渲染、发送和缓存均继续使用统一的动态推送链路。
38023
+ */
38024
+ var createLiveDynamicItem = (sessionId, liveStartedAt, liveInfo, liveStatus) => {
38025
+ const content = JSON.stringify({ live_play_info: {
38026
+ area_name: liveInfo.area_name,
38027
+ cover: liveInfo.user_cover || liveStatus.cover,
38028
+ room_id: liveInfo.room_id,
38029
+ title: liveInfo.title || liveStatus.title
38030
+ } });
38031
+ return {
38032
+ id_str: sessionId,
38033
+ type: DynamicType.LIVE_RCMD,
38034
+ modules: {
38035
+ module_author: {
38036
+ face: "",
38037
+ pendant: { image: "" },
38038
+ pub_ts: Math.floor(Date.parse(liveStartedAt) / 1e3)
38039
+ },
38040
+ module_dynamic: {
38041
+ additional: null,
38042
+ desc: null,
38043
+ major: {
38044
+ live_rcmd: {
38045
+ content,
38046
+ reserve_type: 0
38047
+ },
38048
+ type: MajorType.LIVE_RCMD
38049
+ },
38050
+ topic: null
38051
+ }
38052
+ }
38053
+ };
38054
+ };
38055
+ /** 将未知异常转换为适合业务日志展示的文本。 */
38056
+ var formatErrorMessage = (error) => error instanceof Error ? error.message : String(error);
38057
+ /**
37815
38058
  * 将换行符替换为HTML的<br>标签。
37816
38059
  * @param data 需要进行换行符替换的字符串。
37817
38060
  * @returns 替换后的字符串,其中的换行符\n被<br>替换。