koishi-plugin-bilibili-notify 3.6.5 → 3.6.6

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.
Files changed (3) hide show
  1. package/lib/index.cjs +928 -1429
  2. package/lib/index.mjs +928 -1429
  3. package/package.json +4 -4
package/lib/index.cjs CHANGED
@@ -758,9 +758,9 @@ var ComRegister = class ComRegister {
758
758
  preInitConfig(subs) {
759
759
  for (const sub of Object.values(subs)) {
760
760
  if (sub.customLiveMsg.enable) {
761
- if (!sub.customLiveMsg.customLiveStart.trim()) sub.customLiveMsg.customLiveStart = this.config.customLiveStart;
762
- if (!sub.customLiveMsg.customLiveEnd.trim()) sub.customLiveMsg.customLiveEnd = this.config.customLiveEnd;
763
- if (!sub.customLiveMsg.customLive.trim()) sub.customLiveMsg.customLive = this.config.customLive;
761
+ if (sub.customLiveMsg.customLiveStart && !sub.customLiveMsg.customLiveStart.trim()) sub.customLiveMsg.customLiveStart = this.config.customLiveStart;
762
+ if (sub.customLiveMsg.customLiveEnd && !sub.customLiveMsg.customLiveEnd.trim()) sub.customLiveMsg.customLiveEnd = this.config.customLiveEnd;
763
+ if (sub.customLiveMsg.customLive && !sub.customLiveMsg.customLive.trim()) sub.customLiveMsg.customLive = this.config.customLive;
764
764
  } else {
765
765
  sub.customLiveMsg.enable = false;
766
766
  sub.customLiveMsg.customLiveStart = this.config.customLiveStart;
@@ -768,10 +768,10 @@ var ComRegister = class ComRegister {
768
768
  sub.customLiveMsg.customLive = this.config.customLive;
769
769
  }
770
770
  if (sub.customGuardBuy.enable) {
771
- if (!sub.customGuardBuy.guardBuyMsg.trim()) sub.customGuardBuy.guardBuyMsg = this.config.customGuardBuy.guardBuyMsg;
772
- if (!sub.customGuardBuy.captainImgUrl.trim()) sub.customGuardBuy.captainImgUrl = this.config.customGuardBuy.captainImgUrl;
773
- if (!sub.customGuardBuy.supervisorImgUrl.trim()) sub.customGuardBuy.supervisorImgUrl = this.config.customGuardBuy.supervisorImgUrl;
774
- if (!sub.customGuardBuy.governorImgUrl.trim()) sub.customGuardBuy.governorImgUrl = this.config.customGuardBuy.governorImgUrl;
771
+ if (sub.customGuardBuy.guardBuyMsg && !sub.customGuardBuy.guardBuyMsg.trim()) sub.customGuardBuy.guardBuyMsg = this.config.customGuardBuy.guardBuyMsg;
772
+ if (sub.customGuardBuy.captainImgUrl && !sub.customGuardBuy.captainImgUrl.trim()) sub.customGuardBuy.captainImgUrl = this.config.customGuardBuy.captainImgUrl;
773
+ if (sub.customGuardBuy.supervisorImgUrl && !sub.customGuardBuy.supervisorImgUrl.trim()) sub.customGuardBuy.supervisorImgUrl = this.config.customGuardBuy.supervisorImgUrl;
774
+ if (sub.customGuardBuy.governorImgUrl && !sub.customGuardBuy.governorImgUrl.trim()) sub.customGuardBuy.governorImgUrl = this.config.customGuardBuy.governorImgUrl;
775
775
  } else if (this.config.customGuardBuy.enable) {
776
776
  sub.customGuardBuy.enable = true;
777
777
  sub.customGuardBuy.guardBuyMsg = this.config.customGuardBuy.guardBuyMsg;
@@ -2064,830 +2064,234 @@ var GenerateImg = class GenerateImg extends koishi.Service {
2064
2064
  numberToStr(num) {
2065
2065
  return num > 1e4 ? `${(num / 1e4).toFixed(1)}万` : num.toString();
2066
2066
  }
2067
- async imgHandler(html) {
2068
- const htmlPath = `file://${__dirname.replaceAll("\\", "/")}/page/0.html`;
2069
- const page = await this.ctx.puppeteer.page();
2070
- await page.goto(htmlPath);
2071
- await page.setContent(html, { waitUntil: "networkidle0" });
2072
- const elementHandle = await page.$("html");
2073
- const boundingBox = await elementHandle.boundingBox();
2074
- const buffer = await page.screenshot({
2075
- type: "jpeg",
2076
- clip: {
2077
- x: boundingBox.x,
2078
- y: boundingBox.y,
2079
- width: boundingBox.width,
2080
- height: boundingBox.height
2081
- }
2082
- });
2083
- await elementHandle.dispose();
2084
- await page.close();
2085
- return buffer;
2086
- }
2087
- async generateLiveImg(data, username, userface, liveData, liveStatus, { cardColorStart = this.giConfig.cardColorStart, cardColorEnd = this.giConfig.cardColorEnd, cardBasePlateColor = this.giConfig.cardBasePlateColor, cardBasePlateBorder = this.giConfig.cardBasePlateBorder } = {}) {
2088
- const [titleStatus, liveTime, cover] = await this.getLiveStatus(data.live_time, liveStatus);
2089
- const html = `
2090
- <!DOCTYPE html>
2091
- <html>
2092
- <head>
2093
- <title>直播通知</title>
2094
- <style>
2095
- * {
2096
- margin: 0;
2097
- padding: 0;
2098
- box-sizing: border-box;
2099
- font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
2100
- }
2101
-
2102
- html {
2103
- width: 800px;
2104
- height: auto;
2105
- }
2106
-
2107
- .background {
2108
- width: 100%;
2109
- height: auto;
2110
- padding: 15px;
2111
- background: linear-gradient(to right bottom, ${cardColorStart}, ${cardColorEnd});
2112
- overflow: hidden;
2113
- }
2114
-
2115
- .base-plate {
2116
- width: 100%;
2117
- height: auto;
2118
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
2119
- padding: ${cardBasePlateBorder};
2120
- border-radius: 10px;
2121
- background-color: ${cardBasePlateColor};
2122
- }
2067
+ CARD_STYLES = {
2068
+ large: {
2069
+ avatarSize: "70px",
2070
+ upNameFont: "27px",
2071
+ pubTimeFont: "20px",
2072
+ dressUpFont: "17px",
2073
+ cardDetailsFont: "22px",
2074
+ forwardUserinfoHeight: "35px",
2075
+ forwardUsernameFont: "20px",
2076
+ forwardAvatarSize: "25px",
2077
+ videoCardHeight: "147px",
2078
+ dynTitleFont: "20px",
2079
+ upInfoHeight: "70px",
2080
+ dynamicCardRight: "67px",
2081
+ dynamicCardTop: "24px"
2082
+ },
2083
+ normal: {
2084
+ avatarSize: "50px",
2085
+ upNameFont: "20px",
2086
+ pubTimeFont: "12px",
2087
+ dressUpFont: "12px",
2088
+ cardDetailsFont: "14px",
2089
+ forwardUserinfoHeight: "30px",
2090
+ forwardUsernameFont: "15px",
2091
+ forwardAvatarSize: "20px",
2092
+ videoCardHeight: "132px",
2093
+ dynTitleFont: "20px",
2094
+ upInfoHeight: "50px",
2095
+ dynamicCardRight: "37px",
2096
+ dynamicCardTop: "5px"
2097
+ }
2098
+ };
2099
+ generateCardStyle(isLargeFont, cardColorStart, cardColorEnd, cardBasePlateBorder, cardBasePlateColor, dynamicCardColor) {
2100
+ const style = isLargeFont ? this.CARD_STYLES.large : this.CARD_STYLES.normal;
2101
+ return `
2102
+ * {
2103
+ margin: 0;
2104
+ padding: 0;
2105
+ box-sizing: border-box;
2106
+ font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
2107
+ }
2123
2108
 
2124
- .card {
2125
- width: 100%;
2126
- height: auto;
2127
- border-radius: 5px;
2128
- padding: 15px;
2129
- overflow: hidden;
2130
- background-color: #fff;
2131
- }
2109
+ html {
2110
+ width: 800px;
2111
+ height: auto;
2112
+ }
2132
2113
 
2133
- .card img {
2134
- border-radius: 5px 5px 0 0;
2135
- max-width: 100%;
2136
- /* 设置最大宽度为容器宽度的100% */
2137
- max-height: 80%;
2138
- /* 设置最大高度为容器高度的90% */
2139
- }
2114
+ .background {
2115
+ width: 100%;
2116
+ height: auto;
2117
+ padding: 15px;
2118
+ background: linear-gradient(to right bottom, ${cardColorStart}, ${cardColorEnd});
2119
+ overflow: hidden;
2120
+ }
2140
2121
 
2141
- .card-header {
2142
- display: flex;
2143
- justify-content: space-between;
2144
- align-items: center;
2145
- margin-top: 5px;
2146
- margin-bottom: 10px;
2147
- }
2122
+ .base-plate {
2123
+ width: 100%;
2124
+ height: auto;
2125
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
2126
+ padding: ${cardBasePlateBorder};
2127
+ border-radius: 10px;
2128
+ background-color: ${cardBasePlateColor};
2129
+ }
2148
2130
 
2149
- .card-title {
2150
- line-height: 50px;
2151
- }
2131
+ .card {
2132
+ width: 100%;
2133
+ height: auto;
2134
+ border-radius: 5px;
2135
+ padding: 15px;
2136
+ overflow: hidden;
2137
+ background-color: #fff;
2138
+ }
2152
2139
 
2153
- .card-body {
2154
- padding: 2px 16px;
2155
- margin-bottom: 10px;
2156
- }
2140
+ .card-body {
2141
+ display: flex;
2142
+ padding: 15px;
2143
+ }
2157
2144
 
2158
- .live-broadcast-info {
2159
- display: flex;
2160
- align-items: center;
2161
- margin-bottom: 10px;
2162
- }
2145
+ .card .anchor-avatar {
2146
+ max-width: ${style.avatarSize};
2147
+ max-height: ${style.avatarSize};
2148
+ margin-right: 20px;
2149
+ border-radius: 10px;
2150
+ }
2163
2151
 
2164
- .anchor-avatar {
2165
- width: 50px;
2166
- /* 主播头像大小 */
2167
- height: auto;
2168
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
2169
- }
2152
+ .card .card-body .card-content {
2153
+ width: 100%;
2154
+ }
2170
2155
 
2171
- .broadcast-message {
2172
- display: inline-block;
2173
- margin-left: 10px;
2174
- font-size: 20px;
2175
- color: #333;
2176
- }
2156
+ .card .card-body .card-content .card-header {
2157
+ width: 100%;
2158
+ display: flex;
2159
+ justify-content: space-between;
2160
+ }
2177
2161
 
2178
- .card-text {
2179
- color: grey;
2180
- font-size: 20px;
2181
- }
2162
+ .card .up-info {
2163
+ display: flex;
2164
+ flex-direction: column;
2165
+ justify-content: space-between;
2166
+ height: ${style.upInfoHeight};
2167
+ }
2182
2168
 
2183
- .card-link {
2184
- display: flex;
2185
- justify-content: space-between;
2186
- text-decoration: none;
2187
- font-size: 20px;
2188
- margin-top: 10px;
2189
- margin-bottom: 10px;
2190
- }
2191
- </style>
2192
- </head>
2193
- <body>
2194
- <div class="background">
2195
- <div ${this.giConfig.removeBorder ? "" : "class=\"base-plate\""}>
2196
- <div class="card">
2197
- <img src="${cover ? data.user_cover : data.keyframe}"
2198
- alt="封面">
2199
- <div class="card-body">
2200
- <div class="card-header">
2201
- <h1 class="card-title">${data.title}</h1>
2202
- <div class="live-broadcast-info">
2203
- <!-- 主播头像 -->
2204
- <img style="border-radius: 10px; margin-left: 10px" class="anchor-avatar"
2205
- src="${userface}" alt="主播头像">
2206
- <span class="broadcast-message">${username}${titleStatus}</span>
2207
- </div>
2208
- </div>
2209
- ${this.giConfig.hideDesc ? "" : `<p class="card-text">${data.description ? data.description : "这个主播很懒,什么简介都没写"}</p>`}
2210
- <p class="card-link">
2211
- <span>${liveStatus === 3 ? `本场直播点赞数:${this.numberToStr(+liveData.likedNum)}` : `人气:${this.numberToStr(data.online)}`}</span>
2212
- <span>分区名称:${data.area_name}</span>
2213
- </p>
2214
- <p class="card-link">
2215
- <span>${liveTime}</span>
2216
- ${this.giConfig.followerDisplay ? `
2217
- <span>
2218
- ${liveStatus === 1 ? `当前粉丝数:${liveData.fansNum || "暂未获取到"}` : liveStatus === 2 ? `${liveData.watchedNum !== "API" ? `累计观看人数:${liveData.watchedNum}` : ""}` : liveStatus === 3 ? `粉丝数变化:${liveData.fansChanged}` : ""}
2219
- </span>` : ""}
2220
- </p>
2221
- </div>
2222
- </div>
2223
- </div>
2224
- </div>
2225
- </body>
2226
- </html>
2227
- `;
2228
- return await withRetry(() => this.imgHandler(html)).catch((e) => {
2229
- throw new Error(`生成图片失败!错误: ${e.toString()}`);
2230
- });
2231
- }
2232
- static BG_COLOR = {
2233
- [blive_message_listener.GuardLevel.None]: ["#4ebcec", "#F9CCDF"],
2234
- [blive_message_listener.GuardLevel.Jianzhang]: ["#4ebcec", "#b494e5"],
2235
- [blive_message_listener.GuardLevel.Tidu]: ["#d8a0e6", "#b494e5"],
2236
- [blive_message_listener.GuardLevel.Zongdu]: ["#f2a053", "#ef5f5f"]
2237
- };
2238
- async generateBoardingImg(captainImgUrl, { guardLevel, uname, face, isAdmin }, { masterAvatarUrl, masterName }) {
2239
- const bgColor = GenerateImg.BG_COLOR[guardLevel];
2240
- const desc = {
2241
- [blive_message_listener.GuardLevel.Jianzhang]: () => {
2242
- return `"${uname}号"加入<br/>"${masterName}"大航海舰队!`;
2243
- },
2244
- [blive_message_listener.GuardLevel.Tidu]: () => {
2245
- return `"${uname}"就任<br/>"${masterName}"大航海舰队提督!`;
2246
- },
2247
- [blive_message_listener.GuardLevel.Zongdu]: () => {
2248
- return `"${uname}"上任<br/>"${masterName}"大航海舰队总督!`;
2249
- }
2250
- };
2251
- const html = `
2252
- <!DOCTYPE html>
2253
- <html>
2169
+ .card .up-info .up-name {
2170
+ font-size: ${style.upNameFont};
2171
+ }
2254
2172
 
2255
- <head>
2256
- <title>上舰通知</title>
2257
- <style>
2258
- * {
2259
- margin: 0;
2260
- padding: 0;
2261
- box-sizing: border-box;
2262
- font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
2263
- }
2173
+ .card .pub-time {
2174
+ font-size: ${style.pubTimeFont};
2175
+ color: grey;
2176
+ }
2264
2177
 
2265
- html {
2266
- width: 430px;
2267
- height: auto;
2268
- }
2178
+ .card .card-header img {
2179
+ height: 50px;
2180
+ }
2269
2181
 
2270
- .bg {
2271
- display: flex;
2272
- justify-content: center;
2273
- align-items: center;
2274
- width: 430px;
2275
- height: 220px;
2276
- background: linear-gradient(to right bottom, ${bgColor[0]}, ${bgColor[1]});
2277
- }
2182
+ .card .dress-up {
2183
+ position: relative;
2184
+ font-size: ${style.dressUpFont};
2185
+ }
2278
2186
 
2279
- .baseplate {
2280
- display: flex;
2281
- justify-content: space-between;
2282
- align-items: center;
2283
- border-radius: 10px;
2284
- width: 410px;
2285
- height: 200px;
2286
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
2287
- background-color: rgba(255, 255, 255, 0.65);
2288
- backdrop-filter: blur(10px);
2289
- }
2187
+ .card .dress-up img {
2188
+ max-width: 100%;
2189
+ max-height: 100%;
2190
+ }
2290
2191
 
2291
- .info {
2292
- flex: 1;
2293
- height: 100%;
2294
- display: flex;
2295
- flex-direction: column;
2296
- justify-content: space-between;
2297
- padding: 10px 0 10px 10px;
2298
- }
2192
+ .card .dress-up span {
2193
+ position: absolute;
2194
+ color: ${dynamicCardColor};
2195
+ right: ${style.dynamicCardRight};
2196
+ top: ${style.dynamicCardTop};
2197
+ }
2299
2198
 
2300
- .user {
2301
- display: flex;
2302
- gap: 10px;
2303
- }
2199
+ .card .dyn-title {
2200
+ font-size: ${style.dynTitleFont};
2201
+ margin-bottom: 10px;
2202
+ }
2304
2203
 
2305
- .avatar {
2306
- height: 90px;
2307
- width: 90px;
2308
- border-radius: 50%;
2309
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
2310
- }
2204
+ .card .card-topic {
2205
+ display: flex;
2206
+ align-items: center;
2207
+ margin-top: 10px;
2208
+ font-size: 20px;
2209
+ color: #008AC5;
2210
+ gap: 3px;
2211
+ }
2311
2212
 
2312
- .avatar img {
2313
- width: 100%;
2314
- height: 100%;
2315
- border-radius: 50%;
2316
- border: 3px solid white;
2317
- }
2213
+ .card .card-details {
2214
+ margin-top: 5px;
2215
+ margin-bottom: 15px;
2216
+ font-size: ${style.cardDetailsFont};
2217
+ width: 90%;
2218
+ }
2318
2219
 
2319
- .user-info {
2320
- display: flex;
2321
- flex-direction: column;
2322
- align-items: flex-start;
2323
- gap: 7px;
2324
- margin-top: 10px;
2325
- }
2220
+ .card .card-major {
2221
+ display: flex;
2222
+ flex-wrap: wrap;
2223
+ gap: 5px;
2224
+ }
2326
2225
 
2327
- .name-badge {
2328
- display: flex;
2329
- align-items: center;
2330
- height: 30px;
2331
- background-color: ${bgColor[0]};
2332
- border-radius: 25px;
2333
- color: white;
2334
- padding: 0 10px;
2335
- border: solid 2px white;
2336
- overflow: hidden;
2337
- }
2226
+ .card .card-major .photo-item {
2227
+ border-radius: 10px;
2228
+ overflow: hidden;
2229
+ width: 170px;
2230
+ height: 170px;
2231
+ object-fit: cover;
2232
+ }
2338
2233
 
2339
- .name-badge span {
2340
- max-width: 100px;
2341
- white-space: nowrap;
2342
- text-overflow: ellipsis;
2343
- overflow: hidden;
2344
- font-weight: bold;
2345
- font-size: 12px;
2346
- }
2234
+ .card .card-major .single-photo-mask {
2235
+ position: absolute;
2236
+ text-align: center;
2237
+ width: 100%;
2238
+ height: 100%;
2239
+ top: 0;
2240
+ left: 0;
2241
+ background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, transparent 30%);
2242
+ }
2347
2243
 
2348
- .accompany {
2349
- display: flex;
2350
- gap: 5px;
2351
- align-items: center;
2352
- height: 25px;
2353
- background-color: ${bgColor[0]};
2354
- border-radius: 25px;
2355
- border: solid 2px white;
2356
- overflow: hidden;
2357
- }
2244
+ .card .card-major .single-photo-mask-text {
2245
+ position: absolute;
2246
+ color: #fff;
2247
+ font-size: 24px;
2248
+ right: 0;
2249
+ bottom: 66px;
2250
+ left: 0;
2251
+ text-align: center;
2252
+ }
2358
2253
 
2359
- .master-avatar {
2360
- width: 25px;
2361
- height: 25px;
2362
- border-radius: 50%;
2363
- background: url("${masterAvatarUrl}") no-repeat center;
2364
- background-size: cover;
2365
- }
2254
+ .card .card-major .single-photo-mask-arrow {
2255
+ position: absolute;
2256
+ width: 70px;
2257
+ height: 70px;
2258
+ bottom: 7px;
2259
+ left: 50%;
2260
+ transform: translateX(-50%);
2261
+ }
2366
2262
 
2367
- .accompany span {
2368
- max-width: 85px;
2369
- white-space: nowrap;
2370
- text-overflow: ellipsis;
2371
- overflow: hidden;
2372
- color: white;
2373
- font-size: 10px;
2374
- font-weight: bold;
2375
- margin-right: 5px;
2376
- }
2263
+ .card .card-major .single-photo-container {
2264
+ position: relative;
2265
+ max-width: 500px;
2266
+ max-height: 1000px;
2267
+ border-radius: 10px;
2268
+ overflow: hidden;
2269
+ }
2377
2270
 
2378
- .desc {
2379
- margin-bottom: 10px;
2380
- font-size: 16px;
2381
- font-weight: bold;
2382
- font-style: italic;
2383
- color: #333;
2384
- }
2271
+ .card .card-major .single-photo-item {
2272
+ max-width: 500px;
2273
+ border-radius: 10px;
2274
+ overflow: hidden;
2275
+ }
2385
2276
 
2386
- .captain {
2387
- width: 175px;
2388
- height: 175px;
2389
- background: url("${captainImgUrl}") no-repeat center;
2390
- background-size: cover;
2391
- }
2392
- </style>
2393
- </head>
2277
+ .card .card-major .four-photo-item {
2278
+ width: 170px;
2279
+ height: 170px;
2280
+ object-fit: cover;
2281
+ border-radius: 10px;
2282
+ overflow: hidden;
2283
+ flex-basis: 20%;
2284
+ }
2394
2285
 
2395
- <body>
2396
- <div class="bg">
2397
- <div class="baseplate">
2398
- <div class="info">
2399
- <div class="user">
2400
- <div class="avatar">
2401
- <img src="${face}" alt="用户头像">
2402
- </div>
2403
- <div class="user-info">
2404
- <div class="name-badge">
2405
- <span>${uname}</span>
2406
- </div>
2407
- <div class="accompany">
2408
- <div class="master-avatar"></div><span>${isAdmin ? "房管" : masterName}</span>
2409
- </div>
2410
- </div>
2411
- </div>
2412
- <div class="desc">
2413
- ${desc[guardLevel]()}
2414
- </div>
2415
- </div>
2416
- <div class="captain"></div>
2417
- </div>
2418
- </div>
2419
- </body>
2286
+ .card .card-stat {
2287
+ display: flex;
2288
+ justify-content: space-between;
2289
+ width: 90%;
2290
+ margin-top: 15px;
2291
+ color: gray;
2292
+ font-size: 14px;
2293
+ }
2420
2294
 
2421
- </html>
2422
- `;
2423
- return await withRetry(() => this.imgHandler(html)).catch((e) => {
2424
- throw new Error(`生成图片失败!错误: ${e.toString()}`);
2425
- });
2426
- }
2427
- richTextParser(rt, title) {
2428
- const richText = rt.reduce((accumulator, currentValue) => {
2429
- if (currentValue.emoji) return `${accumulator}<img style="width:28px; height:28px;" src="${currentValue.emoji.icon_url}"/>`;
2430
- return accumulator + currentValue.text;
2431
- }, "");
2432
- if (this.giConfig.filter.enable) {
2433
- if (this.giConfig.filter.regex) {
2434
- if (new RegExp(this.giConfig.filter.regex).test(richText)) throw new Error("出现关键词,屏蔽该动态");
2435
- }
2436
- if (this.giConfig.filter.keywords.length !== 0 && this.giConfig.filter.keywords.some((keyword) => richText.includes(keyword))) throw new Error("出现关键词,屏蔽该动态");
2437
- }
2438
- const text = richText.replace(/\n/g, "<br>");
2439
- return `
2440
- <div class="card-details">
2441
- ${title ? `<h1 class="dyn-title">${title}</h1>` : ""}
2442
- ${text}
2443
- </div>
2444
- `;
2445
- }
2446
- async generateDynamicImg(data, { cardColorStart = this.giConfig.cardColorStart, cardColorEnd = this.giConfig.cardColorEnd, cardBasePlateColor = this.giConfig.cardBasePlateColor, cardBasePlateBorder = this.giConfig.cardBasePlateBorder } = {}) {
2447
- const module_author = data.modules.module_author;
2448
- const avatarUrl = module_author.face;
2449
- const upName = module_author.name;
2450
- let pubTime = this.unixTimestampToString(module_author.pub_ts);
2451
- let dynamicCardUrl;
2452
- let dynamicCardId;
2453
- let dynamicCardColor;
2454
- if (module_author.decorate) {
2455
- dynamicCardUrl = module_author.decorate.card_url;
2456
- dynamicCardId = module_author.decorate.fan.num_str;
2457
- dynamicCardColor = module_author.decorate.fan.color;
2458
- }
2459
- const module_stat = data.modules.module_stat;
2460
- const comment = module_stat.comment.count;
2461
- const forward = module_stat.forward.count;
2462
- const like = module_stat.like.count;
2463
- const topic = data.modules.module_dynamic.topic ? data.modules.module_dynamic.topic.name : "";
2464
- const getDynamicMajor = async (dynamic, forward$1) => {
2465
- let main$1 = "";
2466
- let forwardInfo;
2467
- const basicDynamic = () => {
2468
- const module_dynamic = dynamic.modules.module_dynamic;
2469
- if (module_dynamic?.desc?.rich_text_nodes) {
2470
- const content = this.richTextParser(module_dynamic.desc.rich_text_nodes);
2471
- main$1 += content;
2472
- }
2473
- if (module_dynamic?.major?.opus?.summary?.rich_text_nodes) {
2474
- const content = this.richTextParser(module_dynamic.major.opus.summary.rich_text_nodes, module_dynamic.major.opus.title);
2475
- main$1 += content;
2476
- }
2477
- let major = "";
2478
- const arrowImg = (0, node_url.pathToFileURL)((0, node_path.resolve)(__dirname, "img/arrow.png"));
2479
- if (module_dynamic?.major?.opus?.pics) {
2480
- if (module_dynamic.major.opus.pics.length === 1) if (module_dynamic.major.opus.pics[0].height > 3e3) major += `
2481
- <div class="single-photo-container">
2482
- <img class="single-photo-item" src="${module_dynamic.major.opus.pics[0].url}"/>
2483
- <div class="single-photo-mask">
2484
- <span class="single-photo-mask-text">点击链接浏览全部</span>
2485
- </div>
2486
- <img class="single-photo-mask-arrow" src="${arrowImg}"/>
2487
- </div>
2488
- `;
2489
- else major += `
2490
- <div class="single-photo-container">
2491
- <img class="single-photo-item" src="${module_dynamic.major.opus.pics[0].url}"/>
2492
- </div>
2493
- `;
2494
- else if (module_dynamic.major.opus.pics.length === 4) major += module_dynamic.major.opus.pics.reduce((acc, cV) => {
2495
- return `${acc}<img class="four-photo-item" src="${cV.url}"/>`;
2496
- }, "");
2497
- else major += module_dynamic.major.opus.pics.reduce((acc, cV) => {
2498
- return `${acc}<img class="photo-item" src="${cV.url}"/>`;
2499
- }, "");
2500
- main$1 += `
2501
- <div class="card-major">
2502
- ${major}
2503
- </div>
2504
- `;
2505
- }
2506
- };
2507
- switch (dynamic.type) {
2508
- case DYNAMIC_TYPE_WORD:
2509
- case DYNAMIC_TYPE_DRAW:
2510
- case DYNAMIC_TYPE_FORWARD:
2511
- basicDynamic();
2512
- if (dynamic.type === DYNAMIC_TYPE_FORWARD) {
2513
- if (this.giConfig.filter.enable && this.giConfig.filter.forward) throw new Error("已屏蔽转发动态");
2514
- const forward_module_author = dynamic.orig.modules.module_author;
2515
- const forwardUserAvatarUrl = forward_module_author.face;
2516
- const forwardUserName = forward_module_author.name;
2517
- const [forwardMain, forwardInfo$1] = await getDynamicMajor(dynamic.orig, true);
2518
- main$1 += `
2519
- <div class="card-forward">
2520
- <div class="forward-userinfo">
2521
- <img class="forward-avatar" src="${forwardUserAvatarUrl}" alt="avatar">
2522
- <span class="forward-username">${forwardUserName} ${forwardInfo$1 ? forwardInfo$1 : ""}</span>
2523
- </div>
2524
- <div class="forward-main">
2525
- ${forwardMain}
2526
- </div>
2527
- </div>
2528
- `;
2529
- }
2530
- if (dynamic.modules.module_dynamic.additional) {
2531
- const additional = dynamic.modules.module_dynamic.additional;
2532
- switch (additional.type) {
2533
- case ADDITIONAL_TYPE_RESERVE: {
2534
- const reserve = additional.reserve;
2535
- let button;
2536
- if (reserve.button.uncheck.text === "已结束") button = `
2537
- <button class="reserve-button-end">
2538
- <span>${reserve.button.uncheck.text}</span>
2539
- </button>
2540
- `;
2541
- else button = `
2542
- <button class="reserve-button-ing">
2543
- <svg class="bili-dyn-card-reserve__action__icon" style="width: 16px; height: 16px;"
2544
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
2545
- viewBox="0 0 16 16" width="16" height="16">
2546
- <path
2547
- d="M3.0000133333333334 6.999199999999999C3.0000133333333334 4.23776 5.2385866666666665 1.9991866666666667 8 1.9991866666666667C10.761433333333333 1.9991866666666667 13 4.23776 13 6.999199999999999L13 9.860933333333332C13 9.923533333333333 13.024899999999999 9.983633333333334 13.069199999999999 10.027933333333333L13.588366666666666 10.5471C14.389533333333333 11.348299999999998 13.914133333333334 12.734533333333333 12.754199999999999 12.8183C11.535999999999998 12.906233333333333 9.818933333333334 12.999199999999998 8 12.999199999999998C6.181073333333334 12.999199999999998 4.464026666666666 12.906233333333333 3.2458266666666664 12.8183C2.0859066666666664 12.734533333333333 1.61046 11.348299999999998 2.4116466666666665 10.547133333333333L2.93084 10.027933333333333C2.975133333333333 9.983633333333334 3.0000133333333334 9.923533333333333 3.0000133333333334 9.860933333333332L3.0000133333333334 6.999199999999999zM8 2.9991866666666667C5.790873333333334 2.9991866666666667 4.000013333333333 4.790046666666666 4.000013333333333 6.999199999999999L4.000013333333333 9.860933333333332C4.000013333333333 10.1888 3.8697733333333333 10.5032 3.6379466666666667 10.735033333333334L3.1187466666666666 11.254233333333334C2.911966666666667 11.461 3.0317600000000002 11.800199999999998 3.317833333333333 11.820899999999998C4.5211266666666665 11.907766666666667 6.212726666666666 11.999199999999998 8 11.999199999999998C9.787266666666666 11.999199999999998 11.4789 11.907733333333333 12.682199999999998 11.820899999999998C12.968233333333332 11.800199999999998 13.088033333333332 11.461 12.881266666666665 11.254233333333334L12.362066666666665 10.735033333333334C12.130233333333333 10.5032 12 10.1888 12 9.860933333333332L12 6.999199999999999C12 4.790046666666666 10.209166666666667 2.9991866666666667 8 2.9991866666666667z"
2548
- fill="currentColor"></path>
2549
- <path
2550
- d="M8.720066666666666 2.0260466666666668C8.720066666666666 2.42372 8.397666666666666 2.746093333333333 8 2.746093333333333C7.602333333333332 2.746093333333333 7.279933333333333 2.42372 7.279933333333333 2.0260466666666668C7.279933333333333 1.6283666666666667 7.602333333333332 1.3059866666666666 8 1.3059866666666666C8.397666666666666 1.3059866666666666 8.720066666666666 1.6283666666666667 8.720066666666666 2.0260466666666668z"
2551
- fill="currentColor"></path>
2552
- <path
2553
- d="M6.791266666666666 12.499199999999998C6.791266666666666 13.173966666666667 7.335266666666667 13.715866666666665 8 13.715866666666665C8.664766666666665 13.715866666666665 9.208733333333333 13.173966666666667 9.208733333333333 12.499199999999998L10.208733333333333 12.499199999999998C10.208733333333333 13.720566666666667 9.2227 14.715866666666665 8 14.715866666666665C6.777346666666666 14.715866666666665 5.791273333333333 13.720566666666667 5.791273333333333 12.499199999999998L6.791266666666666 12.499199999999998z"
2554
- fill="currentColor"></path>
2555
- </svg>
2556
- <span>${reserve.button.uncheck.text}</span>
2557
- </button>
2558
- `;
2559
- main$1 += `
2560
- <div class="card-reserve">
2561
- <div class="reserve-main">
2562
- <div class="reserve-title">
2563
- ${reserve.title}
2564
- </div>
2565
- <div class="reserve-desc">
2566
- <div class="reserve-info">
2567
- <span class="reserve-time">${reserve.desc1.text}</span>
2568
- <span class="reserve-num">${reserve.desc2.text}</span>
2569
- </div>
2570
- ${reserve.desc3 ? `<div class="reserve-prize">
2571
- <svg class="bili-dyn-card-reserve__lottery__icon"
2572
- style="width: 16px; height: 16px;" xmlns="http://www.w3.org/2000/svg"
2573
- xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" width="16"
2574
- height="16">
2575
- <path
2576
- d="M2.99998 7.785666666666666C3.2761266666666664 7.785666666666666 3.49998 8.0095 3.49998 8.285666666666666L3.49998 12.285666666666666C3.49998 12.719566666666667 3.8517599999999996 13.071333333333332 4.285693333333333 13.071333333333332L11.714266666666667 13.071333333333332C12.1482 13.071333333333332 12.5 12.719566666666667 12.5 12.285666666666666L12.5 8.285666666666666C12.5 8.0095 12.723833333333333 7.785666666666666 13 7.785666666666666C13.276133333333334 7.785666666666666 13.5 8.0095 13.5 8.285666666666666L13.5 12.285666666666666C13.5 13.271866666666668 12.7005 14.071333333333332 11.714266666666667 14.071333333333332L4.285693333333333 14.071333333333332C3.2994733333333333 14.071333333333332 2.49998 13.271866666666668 2.49998 12.285666666666666L2.49998 8.285666666666666C2.49998 8.0095 2.7238399999999996 7.785666666666666 2.99998 7.785666666666666z"
2577
- fill="currentColor"></path>
2578
- <path
2579
- d="M1.9285533333333333 5.857139999999999C1.9285533333333333 5.107613333333333 2.5361666666666665 4.5 3.285693333333333 4.5L12.714266666666667 4.5C13.463799999999999 4.5 14.071399999999999 5.107613333333333 14.071399999999999 5.857139999999999L14.071399999999999 7.134066666666667C14.071399999999999 7.793799999999999 13.590066666666667 8.373766666666667 12.905000000000001 8.4432C12.058933333333332 8.528966666666665 10.470166666666666 8.642866666666666 8 8.642866666666666C5.529819999999999 8.642866666666666 3.9410399999999997 8.528966666666665 3.09498 8.4432C2.4099066666666666 8.373766666666667 1.9285533333333333 7.793799999999999 1.9285533333333333 7.134066666666667L1.9285533333333333 5.857139999999999zM3.285693333333333 5.5C3.088453333333333 5.5 2.9285533333333333 5.6599 2.9285533333333333 5.857139999999999L2.9285533333333333 7.134066666666667C2.9285533333333333 7.3082 3.0432666666666663 7.432833333333333 3.1958066666666665 7.4483C4.00544 7.530366666666667 5.560420000000001 7.6428666666666665 8 7.6428666666666665C10.439566666666666 7.6428666666666665 11.994533333333333 7.530366666666667 12.804133333333333 7.4483C12.9567 7.432833333333333 13.071399999999999 7.3082 13.071399999999999 7.134066666666667L13.071399999999999 5.857139999999999C13.071399999999999 5.6599 12.911499999999998 5.5 12.714266666666667 5.5L3.285693333333333 5.5z"
2580
- fill="currentColor"></path>
2581
- <path
2582
- d="M4.357126666666666 3.5714733333333335C4.357126666666666 2.506353333333333 5.220573333333333 1.6429066666666667 6.285693333333333 1.6429066666666667C7.350833333333332 1.6429066666666667 8.214266666666667 2.506353333333333 8.214266666666667 3.5714733333333335L8.214266666666667 5.500046666666666L6.285693333333333 5.500046666666666C5.220573333333333 5.500046666666666 4.357126666666666 4.636593333333333 4.357126666666666 3.5714733333333335zM6.285693333333333 2.6429066666666667C5.77286 2.6429066666666667 5.357126666666667 3.0586399999999996 5.357126666666667 3.5714733333333335C5.357126666666667 4.084313333333333 5.77286 4.500046666666666 6.285693333333333 4.500046666666666L7.214266666666667 4.500046666666666L7.214266666666667 3.5714733333333335C7.214266666666667 3.0586399999999996 6.798533333333333 2.6429066666666667 6.285693333333333 2.6429066666666667z"
2583
- fill="currentColor"></path>
2584
- <path
2585
- d="M7.785666666666666 3.5714733333333335C7.785666666666666 2.506353333333333 8.649133333333332 1.6429066666666667 9.714266666666667 1.6429066666666667C10.779399999999999 1.6429066666666667 11.642866666666666 2.506353333333333 11.642866666666666 3.5714733333333335C11.642866666666666 4.636593333333333 10.779399999999999 5.500046666666666 9.714266666666667 5.500046666666666L7.785666666666666 5.500046666666666L7.785666666666666 3.5714733333333335zM9.714266666666667 2.6429066666666667C9.201433333333332 2.6429066666666667 8.785666666666666 3.0586399999999996 8.785666666666666 3.5714733333333335L8.785666666666666 4.500046666666666L9.714266666666667 4.500046666666666C10.2271 4.500046666666666 10.642866666666666 4.084313333333333 10.642866666666666 3.5714733333333335C10.642866666666666 3.0586399999999996 10.2271 2.6429066666666667 9.714266666666667 2.6429066666666667z"
2586
- fill="currentColor"></path>
2587
- <path
2588
- d="M8 3.7856466666666666C8.276133333333332 3.7856466666666666 8.5 4.009499999999999 8.5 4.285646666666667L8.5 13.142800000000001C8.5 13.418933333333332 8.276133333333332 13.642800000000001 8 13.642800000000001C7.723833333333333 13.642800000000001 7.5 13.418933333333332 7.5 13.142800000000001L7.5 4.285646666666667C7.5 4.009499999999999 7.723833333333333 3.7856466666666666 8 3.7856466666666666z"
2589
- fill="currentColor"></path>
2590
- </svg>
2591
- <span>${reserve.desc3.text}</span>
2592
- <svg style="width: 12px; height: 12px;" xmlns="http://www.w3.org/2000/svg"
2593
- xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 12 12" width="12"
2594
- height="12">
2595
- <path
2596
- d="M4.359835 1.609835C4.21339 1.756285 4.21339 1.99372 4.359835 2.140165L8.0429 5.823225C8.140525 5.920875 8.140525 6.079125 8.0429 6.176775L4.359835 9.859825C4.21339 10.006275 4.21339 10.243725 4.359835 10.390175C4.506285 10.5366 4.743725 10.5366 4.89017 10.390175L8.573225 6.7071C8.96375 6.316575 8.96375 5.683425 8.573225 5.2929L4.89017 1.609835C4.743725 1.46339 4.506285 1.46339 4.359835 1.609835z"
2597
- fill="currentColor"></path>
2598
- </svg>
2599
- </div>` : ""}
2600
- </div>
2601
- </div>
2602
- <div class="reserve-button">
2603
- ${button}
2604
- </div>
2605
- </div>
2606
- `;
2607
- }
2608
- }
2609
- }
2610
- break;
2611
- case DYNAMIC_TYPE_AV: {
2612
- basicDynamic();
2613
- const archive = dynamic.modules.module_dynamic.major.archive;
2614
- if (archive.badge.text === "投稿视频") if (forward$1) forwardInfo = "投稿了视频";
2615
- else pubTime = `${pubTime} · 投稿了视频`;
2616
- main$1 += `
2617
- <div class="card-video">
2618
- <div class="video-cover">
2619
- <img src="${archive.cover}"
2620
- alt="">
2621
- <div class="cover-mask"></div>
2622
- <span>${archive.duration_text}</span>
2623
- </div>
2624
- <div class="video-info">
2625
- <div class="video-info-header">
2626
- <div class="video-title">
2627
- ${archive.title}
2628
- </div>
2629
- <div class="video-introduction">
2630
- ${archive.desc}
2631
- </div>
2632
- </div>
2633
- <div class="video-stat">
2634
- <div class="video-stat-item">
2635
- <svg style="width: 16px; height: 16px;" xmlns="http://www.w3.org/2000/svg"
2636
- xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" width="16"
2637
- height="16">
2638
- <path
2639
- d="M8 3.3320333333333334C6.321186666666667 3.3320333333333334 4.855333333333333 3.4174399999999996 3.820593333333333 3.5013466666666666C3.1014733333333333 3.5596599999999996 2.5440733333333334 4.109013333333333 2.48 4.821693333333333C2.4040466666666664 5.666533333333334 2.333333333333333 6.780666666666666 2.333333333333333 7.998666666666666C2.333333333333333 9.216733333333334 2.4040466666666664 10.330866666666665 2.48 11.175699999999999C2.5440733333333334 11.888366666666666 3.1014733333333333 12.437733333333334 3.820593333333333 12.496066666666666C4.855333333333333 12.579933333333333 6.321186666666667 12.665333333333333 8 12.665333333333333C9.678999999999998 12.665333333333333 11.144933333333334 12.579933333333333 12.179733333333333 12.496033333333333C12.898733333333332 12.4377 13.456 11.888533333333331 13.520066666666667 11.176033333333333C13.595999999999998 10.331533333333333 13.666666666666666 9.217633333333332 13.666666666666666 7.998666666666666C13.666666666666666 6.779766666666667 13.595999999999998 5.665846666666667 13.520066666666667 4.821366666666666C13.456 4.108866666666666 12.898733333333332 3.55968 12.179733333333333 3.5013666666666663C11.144933333333334 3.417453333333333 9.678999999999998 3.3320333333333334 8 3.3320333333333334zM3.7397666666666667 2.50462C4.794879999999999 2.41906 6.288386666666666 2.3320333333333334 8 2.3320333333333334C9.7118 2.3320333333333334 11.2054 2.4190733333333334 12.260533333333331 2.5046399999999998C13.458733333333331 2.6018133333333333 14.407866666666665 3.5285199999999994 14.516066666666667 4.73182C14.593933333333332 5.597933333333334 14.666666666666666 6.7427 14.666666666666666 7.998666666666666C14.666666666666666 9.2547 14.593933333333332 10.399466666666665 14.516066666666667 11.2656C14.407866666666665 12.468866666666665 13.458733333333331 13.395566666666667 12.260533333333331 13.492766666666665C11.2054 13.578333333333333 9.7118 13.665333333333333 8 13.665333333333333C6.288386666666666 13.665333333333333 4.794879999999999 13.578333333333333 3.7397666666666667 13.492799999999999C2.541373333333333 13.395599999999998 1.5922066666666668 12.468633333333333 1.4840200000000001 11.265266666666665C1.4061199999999998 10.3988 1.3333333333333333 9.253866666666667 1.3333333333333333 7.998666666666666C1.3333333333333333 6.743533333333333 1.4061199999999998 5.598579999999999 1.4840200000000001 4.732153333333333C1.5922066666666668 3.5287466666666667 2.541373333333333 2.601793333333333 3.7397666666666667 2.50462z"
2640
- fill="currentColor"></path>
2641
- <path
2642
- d="M9.8092 7.3125C10.338433333333333 7.618066666666666 10.338433333333333 8.382 9.809166666666666 8.687533333333333L7.690799999999999 9.910599999999999C7.161566666666666 10.216133333333332 6.5 9.8342 6.500006666666666 9.223066666666666L6.500006666666666 6.776999999999999C6.500006666666666 6.165873333333334 7.161566666666666 5.783913333333333 7.690799999999999 6.089479999999999L9.8092 7.3125z"
2643
- fill="currentColor"></path>
2644
- </svg>
2645
- <span>${archive.stat.play}</span>
2646
- </div>
2647
- <div class="video-stat-item">
2648
- <svg style="width: 16px; height: 16px;" xmlns="http://www.w3.org/2000/svg"
2649
- xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" width="16"
2650
- height="16">
2651
- <path
2652
- d="M8 3.3320333333333334C6.321186666666667 3.3320333333333334 4.855333333333333 3.4174399999999996 3.820593333333333 3.5013466666666666C3.1014733333333333 3.5596599999999996 2.5440733333333334 4.109013333333333 2.48 4.821693333333333C2.4040466666666664 5.666533333333334 2.333333333333333 6.780666666666666 2.333333333333333 7.998666666666666C2.333333333333333 9.216733333333334 2.4040466666666664 10.330866666666665 2.48 11.175699999999999C2.5440733333333334 11.888366666666666 3.1014733333333333 12.437733333333334 3.820593333333333 12.496066666666666C4.855333333333333 12.579933333333333 6.321186666666667 12.665333333333333 8 12.665333333333333C9.678999999999998 12.665333333333333 11.144933333333334 12.579933333333333 12.179733333333333 12.496033333333333C12.898733333333332 12.4377 13.456 11.888533333333331 13.520066666666667 11.176033333333333C13.595999999999998 10.331533333333333 13.666666666666666 9.217633333333332 13.666666666666666 7.998666666666666C13.666666666666666 6.779766666666667 13.595999999999998 5.665846666666667 13.520066666666667 4.821366666666666C13.456 4.108866666666666 12.898733333333332 3.55968 12.179733333333333 3.5013666666666663C11.144933333333334 3.417453333333333 9.678999999999998 3.3320333333333334 8 3.3320333333333334zM3.7397666666666667 2.50462C4.794879999999999 2.41906 6.288386666666666 2.3320333333333334 8 2.3320333333333334C9.7118 2.3320333333333334 11.2054 2.4190733333333334 12.260533333333331 2.5046399999999998C13.458733333333331 2.6018133333333333 14.407866666666665 3.5285199999999994 14.516066666666667 4.73182C14.593933333333332 5.597933333333334 14.666666666666666 6.7427 14.666666666666666 7.998666666666666C14.666666666666666 9.2547 14.593933333333332 10.399466666666665 14.516066666666667 11.2656C14.407866666666665 12.468866666666665 13.458733333333331 13.395566666666667 12.260533333333331 13.492766666666665C11.2054 13.578333333333333 9.7118 13.665333333333333 8 13.665333333333333C6.288386666666666 13.665333333333333 4.794879999999999 13.578333333333333 3.7397666666666667 13.492799999999999C2.541373333333333 13.395599999999998 1.5922066666666668 12.468633333333333 1.4840200000000001 11.265266666666665C1.4061199999999998 10.3988 1.3333333333333333 9.253866666666667 1.3333333333333333 7.998666666666666C1.3333333333333333 6.743533333333333 1.4061199999999998 5.598579999999999 1.4840200000000001 4.732153333333333C1.5922066666666668 3.5287466666666667 2.541373333333333 2.601793333333333 3.7397666666666667 2.50462z"
2653
- fill="currentColor"></path>
2654
- <path
2655
- d="M10.583333333333332 7.166666666666666L6.583333333333333 7.166666666666666C6.307193333333332 7.166666666666666 6.083333333333333 6.942799999999999 6.083333333333333 6.666666666666666C6.083333333333333 6.390526666666666 6.307193333333332 6.166666666666666 6.583333333333333 6.166666666666666L10.583333333333332 6.166666666666666C10.859466666666666 6.166666666666666 11.083333333333332 6.390526666666666 11.083333333333332 6.666666666666666C11.083333333333332 6.942799999999999 10.859466666666666 7.166666666666666 10.583333333333332 7.166666666666666z"
2656
- fill="currentColor"></path>
2657
- <path
2658
- d="M11.583333333333332 9.833333333333332L7.583333333333333 9.833333333333332C7.3072 9.833333333333332 7.083333333333333 9.609466666666666 7.083333333333333 9.333333333333332C7.083333333333333 9.0572 7.3072 8.833333333333332 7.583333333333333 8.833333333333332L11.583333333333332 8.833333333333332C11.859466666666666 8.833333333333332 12.083333333333332 9.0572 12.083333333333332 9.333333333333332C12.083333333333332 9.609466666666666 11.859466666666666 9.833333333333332 11.583333333333332 9.833333333333332z"
2659
- fill="currentColor"></path>
2660
- <path
2661
- d="M5.25 6.666666666666666C5.25 6.942799999999999 5.02614 7.166666666666666 4.75 7.166666666666666L4.416666666666666 7.166666666666666C4.140526666666666 7.166666666666666 3.9166666666666665 6.942799999999999 3.9166666666666665 6.666666666666666C3.9166666666666665 6.390526666666666 4.140526666666666 6.166666666666666 4.416666666666666 6.166666666666666L4.75 6.166666666666666C5.02614 6.166666666666666 5.25 6.390526666666666 5.25 6.666666666666666z"
2662
- fill="currentColor"></path>
2663
- <path
2664
- d="M6.25 9.333333333333332C6.25 9.609466666666666 6.02614 9.833333333333332 5.75 9.833333333333332L5.416666666666666 9.833333333333332C5.140526666666666 9.833333333333332 4.916666666666666 9.609466666666666 4.916666666666666 9.333333333333332C4.916666666666666 9.0572 5.140526666666666 8.833333333333332 5.416666666666666 8.833333333333332L5.75 8.833333333333332C6.02614 8.833333333333332 6.25 9.0572 6.25 9.333333333333332z"
2665
- fill="currentColor"></path>
2666
- </svg>
2667
- <span>${archive.stat.danmaku}</span>
2668
- </div>
2669
- </div>
2670
- </div>
2671
- </div>
2672
- `;
2673
- break;
2674
- }
2675
- case DYNAMIC_TYPE_LIVE: return [`${upName}发起了直播预约,我暂时无法渲染,请自行查看`];
2676
- case DYNAMIC_TYPE_MEDIALIST: return [`${upName}分享了收藏夹,我暂时无法渲染,请自行查看`];
2677
- case DYNAMIC_TYPE_PGC: return [`${upName}发布了剧集(番剧、电影、纪录片),我暂时无法渲染,请自行查看`];
2678
- case DYNAMIC_TYPE_ARTICLE:
2679
- if (this.giConfig.filter.enable && this.giConfig.filter.article) throw new Error("已屏蔽专栏动态");
2680
- return [`${upName}投稿了新专栏,我暂时无法渲染,请自行查看`];
2681
- case DYNAMIC_TYPE_MUSIC: return [`${upName}发行了新歌,我暂时无法渲染,请自行查看`];
2682
- case DYNAMIC_TYPE_COMMON_SQUARE: return [`${upName}发布了装扮|剧集|点评|普通分享,我暂时无法渲染,请自行查看`];
2683
- case DYNAMIC_TYPE_COURSES_SEASON: return [`${upName}发布了新课程,我暂时无法渲染,请自行查看`];
2684
- case DYNAMIC_TYPE_UGC_SEASON: return [`${upName}更新了合集,我暂时无法渲染,请自行查看`];
2685
- case DYNAMIC_TYPE_NONE: return [`${upName}发布了一条无效动态`];
2686
- case DYNAMIC_TYPE_LIVE_RCMD: throw new Error("直播开播动态,不做处理");
2687
- default: return [`${upName}发布了一条我无法识别的动态,请自行查看`];
2688
- }
2689
- return [main$1, forwardInfo];
2690
- };
2691
- const [main] = await getDynamicMajor(data, false);
2692
- let style;
2693
- if (this.giConfig.enableLargeFont) style = `
2694
- * {
2695
- margin: 0;
2696
- padding: 0;
2697
- box-sizing: border-box;
2698
- font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
2699
- }
2700
-
2701
- html {
2702
- width: 800px;
2703
- height: auto;
2704
- }
2705
-
2706
- .background {
2707
- width: 100%;
2708
- height: auto;
2709
- padding: 15px;
2710
- background: linear-gradient(to right bottom, ${cardColorStart}, ${cardColorEnd});
2711
- overflow: hidden;
2712
- }
2713
-
2714
- .base-plate {
2715
- width: 100%;
2716
- height: auto;
2717
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
2718
- padding: ${cardBasePlateBorder};
2719
- border-radius: 10px;
2720
- background-color: ${cardBasePlateColor};
2721
- }
2722
-
2723
- .card {
2724
- width: 100%;
2725
- height: auto;
2726
- border-radius: 5px;
2727
- padding: 15px;
2728
- overflow: hidden;
2729
- background-color: #fff;
2730
- }
2731
-
2732
- .card-body {
2733
- display: flex;
2734
- padding: 15px;
2735
- }
2736
-
2737
- .card .anchor-avatar {
2738
- max-width: 70px;
2739
- /* 设置最大宽度为容器宽度的100% */
2740
- max-height: 70px;
2741
- /* 设置最大高度为容器高度的90% */
2742
- margin-right: 20px;
2743
- border-radius: 10px;
2744
- }
2745
-
2746
- .card .card-body .card-content {
2747
- width: 100%;
2748
- }
2749
-
2750
- .card .card-body .card-content .card-header {
2751
- width: 100%;
2752
- display: flex;
2753
- justify-content: space-between;
2754
- }
2755
-
2756
- .card .up-info {
2757
- display: flex;
2758
- flex-direction: column;
2759
- justify-content: space-between;
2760
- height: 70px;
2761
- }
2762
-
2763
- .card .up-info .up-name {
2764
- font-size: 27px;
2765
- }
2766
-
2767
- .card .pub-time {
2768
- font-size: 20px;
2769
- color: grey;
2770
- }
2771
-
2772
- .card .card-header img {
2773
- height: 50px;
2774
- }
2775
-
2776
- .card .dress-up {
2777
- position: relative;
2778
- /* background-image: url('${dynamicCardUrl}');
2779
- background-size: cover; */
2780
- font-size: 17px;
2781
- }
2782
-
2783
- .card .dress-up img {
2784
- max-width: 100%;
2785
- max-height: 100%;
2786
- }
2787
-
2788
- .card .dress-up span {
2789
- position: absolute;
2790
- color: ${dynamicCardColor};
2791
- right: 67px;
2792
- top: 24px;
2793
- }
2794
-
2795
- .card .dyn-title {
2796
- font-size: 20px;
2797
- margin-bottom: 10px;
2798
- }
2799
-
2800
- .card .card-topic {
2801
- display: flex;
2802
- align-items: center;
2803
- margin-top: 10px;
2804
- font-size: 20px;
2805
- color: #008AC5;
2806
- gap: 3px;
2807
- }
2808
-
2809
- .card .card-details {
2810
- margin-top: 5px;
2811
- margin-bottom: 15px;
2812
- font-size: 22px;
2813
- width: 90%;
2814
- }
2815
-
2816
- .card .card-major {
2817
- display: flex;
2818
- flex-wrap: wrap;
2819
- gap: 5px;
2820
- }
2821
-
2822
- .card .card-major .photo-item {
2823
- border-radius: 10px;
2824
- overflow: hidden;
2825
- width: 170px;
2826
- height: 170px;
2827
- object-fit: cover;
2828
- }
2829
-
2830
- .card .card-major .single-photo-mask {
2831
- position: absolute;
2832
- text-align: center;
2833
- width: 100%;
2834
- height: 100%;
2835
- top: 0;
2836
- left: 0;
2837
- background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, transparent 30%);
2838
- }
2839
-
2840
- .card .card-major .single-photo-mask-text {
2841
- position: absolute;
2842
- color: #fff;
2843
- font-size: 24px;
2844
- right: 0;
2845
- bottom: 66px;
2846
- left: 0;
2847
- text-align: center;
2848
- }
2849
-
2850
- .card .card-major .single-photo-mask-arrow {
2851
- position: absolute;
2852
- width: 70px;
2853
- height: 70px;
2854
- bottom: 7px;
2855
- left: 50%;
2856
- transform: translateX(-50%);
2857
- }
2858
-
2859
- .card .card-major .single-photo-container {
2860
- position: relative;
2861
- max-width: 500px;
2862
- max-height: 1000px;
2863
- border-radius: 10px;
2864
- overflow: hidden;
2865
- }
2866
-
2867
- .card .card-major .single-photo-item {
2868
- max-width: 500px;
2869
- border-radius: 10px;
2870
- overflow: hidden;
2871
- }
2872
-
2873
- .card .card-major .four-photo-item {
2874
- width: 170px;
2875
- height: 170px;
2876
- object-fit: cover;
2877
- border-radius: 10px;
2878
- overflow: hidden;
2879
- flex-basis: 20%; /* or any value less than 50% */
2880
- }
2881
-
2882
- .card .card-stat {
2883
- display: flex;
2884
- justify-content: space-between;
2885
- width: 90%;
2886
- margin-top: 15px;
2887
- color: gray;
2888
- font-size: 14px;
2889
- }
2890
-
2891
2295
  .card .card-stat .stat-item {
2892
2296
  display: flex;
2893
2297
  align-items: center;
@@ -2899,15 +2303,15 @@ var GenerateImg = class GenerateImg extends koishi.Service {
2899
2303
  overflow: hidden;
2900
2304
  border-radius: 5px 0 0 5px;
2901
2305
  margin-top: 10px;
2902
- height: 147px;
2306
+ height: ${style.videoCardHeight};
2903
2307
  }
2904
-
2308
+
2905
2309
  .card .video-cover {
2906
2310
  position: relative;
2907
2311
  flex: 2;
2908
2312
  overflow: hidden;
2909
2313
  }
2910
-
2314
+
2911
2315
  .card .video-cover img {
2912
2316
  width: 236px;
2913
2317
  }
@@ -2920,7 +2324,7 @@ var GenerateImg = class GenerateImg extends koishi.Service {
2920
2324
  left: 0;
2921
2325
  background: linear-gradient(to top, rgba(0, 0, 0, 0.5) 0%, transparent 30%);
2922
2326
  }
2923
-
2327
+
2924
2328
  .card .video-cover span {
2925
2329
  position: absolute;
2926
2330
  color: #fff;
@@ -2928,7 +2332,7 @@ var GenerateImg = class GenerateImg extends koishi.Service {
2928
2332
  right: 10px;
2929
2333
  bottom: 8px;
2930
2334
  }
2931
-
2335
+
2932
2336
  .card .video-info {
2933
2337
  display: flex;
2934
2338
  justify-content: space-between;
@@ -2940,32 +2344,28 @@ var GenerateImg = class GenerateImg extends koishi.Service {
2940
2344
  padding: 12px 16px 10px;
2941
2345
  background-color: #fff;
2942
2346
  }
2943
-
2347
+
2944
2348
  .card .video-info-header .video-title {
2945
2349
  font-size: 16px;
2946
2350
  }
2947
-
2351
+
2948
2352
  .card .video-info-header .video-introduction {
2949
2353
  margin-top: 5px;
2950
2354
  font-size: 12px;
2951
2355
  color: #AAA;
2952
2356
  display: -webkit-box;
2953
- /* 必须设置为 -webkit-box 或 -webkit-inline-box */
2954
2357
  -webkit-box-orient: vertical;
2955
- /* 必须设置为 vertical */
2956
2358
  -webkit-line-clamp: 2;
2957
- /* 显示的文本行数 */
2958
2359
  overflow: hidden;
2959
- /* 必须设置为 hidden */
2960
2360
  }
2961
-
2361
+
2962
2362
  .card .video-stat {
2963
2363
  font-size: 12px;
2964
2364
  color: #AAA;
2965
2365
  display: flex;
2966
2366
  gap: 35px
2967
2367
  }
2968
-
2368
+
2969
2369
  .card .video-stat .video-stat-item {
2970
2370
  display: flex;
2971
2371
  align-items: center;
@@ -2977,23 +2377,23 @@ var GenerateImg = class GenerateImg extends koishi.Service {
2977
2377
  padding: 12px 10px 14px 10px;
2978
2378
  background-color: #F6F7F8;
2979
2379
  }
2980
-
2380
+
2981
2381
  .card-forward .forward-userinfo {
2982
2382
  display: flex;
2983
2383
  align-items: center;
2984
2384
  gap: 5px;
2985
- height: 35px;
2385
+ height: ${style.forwardUserinfoHeight};
2986
2386
  }
2987
-
2387
+
2988
2388
  .forward-userinfo img {
2989
- width: 25px;
2990
- height: 25px;
2389
+ width: ${style.forwardAvatarSize};
2390
+ height: ${style.forwardAvatarSize};
2991
2391
  border-radius: 50%;
2992
2392
  }
2993
-
2393
+
2994
2394
  .forward-userinfo span {
2995
2395
  color: #61666D;
2996
- font-size: 20px;
2396
+ font-size: ${style.forwardUsernameFont};
2997
2397
  }
2998
2398
 
2999
2399
  .card .card-reserve {
@@ -3005,22 +2405,22 @@ var GenerateImg = class GenerateImg extends koishi.Service {
3005
2405
  border-radius: 10px;
3006
2406
  background-color: #F6F7F8;
3007
2407
  }
3008
-
2408
+
3009
2409
  .card-reserve .reserve-title {
3010
2410
  font-size: 14px;
3011
2411
  color: #18191C;
3012
2412
  }
3013
-
2413
+
3014
2414
  .card-reserve .reserve-desc {
3015
2415
  margin-top: 7px;
3016
2416
  font-size: 12px;
3017
2417
  color: #9499A0;
3018
2418
  }
3019
-
2419
+
3020
2420
  .reserve-info .reserve-time {
3021
2421
  margin-right: 7px;
3022
2422
  }
3023
-
2423
+
3024
2424
  .card-reserve .reserve-prize {
3025
2425
  display: flex;
3026
2426
  align-items: center;
@@ -3028,7 +2428,7 @@ var GenerateImg = class GenerateImg extends koishi.Service {
3028
2428
  gap: 3px;
3029
2429
  color: #00AEEC;
3030
2430
  }
3031
-
2431
+
3032
2432
  .card .card-reserve .reserve-button button {
3033
2433
  border: none;
3034
2434
  height: 30px;
@@ -3036,7 +2436,7 @@ var GenerateImg = class GenerateImg extends koishi.Service {
3036
2436
  font-size: 13px;
3037
2437
  border-radius: 7px;
3038
2438
  }
3039
-
2439
+
3040
2440
  .card .card-reserve .reserve-button .reserve-button-end {
3041
2441
  display: flex;
3042
2442
  align-items: center;
@@ -3044,7 +2444,7 @@ var GenerateImg = class GenerateImg extends koishi.Service {
3044
2444
  color: #9499A0;
3045
2445
  background-color: #E3E5E7;
3046
2446
  }
3047
-
2447
+
3048
2448
  .card .card-reserve .reserve-button .reserve-button-ing {
3049
2449
  display: flex;
3050
2450
  align-items: center;
@@ -3052,378 +2452,640 @@ var GenerateImg = class GenerateImg extends koishi.Service {
3052
2452
  color: #FFF;
3053
2453
  background-color: #00A0D8;
3054
2454
  }
3055
- `;
3056
- else style = `
3057
- * {
3058
- margin: 0;
3059
- padding: 0;
3060
- box-sizing: border-box;
3061
- font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
3062
- }
3063
-
3064
- html {
3065
- width: 800px;
3066
- height: auto;
3067
- }
3068
-
3069
- .background {
3070
- width: 100%;
3071
- height: auto;
3072
- padding: 15px;
3073
- background: linear-gradient(to right bottom, ${cardColorStart}, ${cardColorEnd});
3074
- overflow: hidden;
3075
- }
2455
+ `;
2456
+ }
2457
+ async imgHandler(html) {
2458
+ const htmlPath = `file://${__dirname.replaceAll("\\", "/")}/page/0.html`;
2459
+ const page = await this.ctx.puppeteer.page();
2460
+ await page.goto(htmlPath);
2461
+ await page.setContent(html, { waitUntil: "networkidle0" });
2462
+ const elementHandle = await page.$("html");
2463
+ const boundingBox = await elementHandle.boundingBox();
2464
+ const buffer = await page.screenshot({
2465
+ type: "jpeg",
2466
+ clip: {
2467
+ x: boundingBox.x,
2468
+ y: boundingBox.y,
2469
+ width: boundingBox.width,
2470
+ height: boundingBox.height
2471
+ }
2472
+ });
2473
+ await elementHandle.dispose();
2474
+ await page.close();
2475
+ return buffer;
2476
+ }
2477
+ async generateLiveImg(data, username, userface, liveData, liveStatus, { cardColorStart = this.giConfig.cardColorStart, cardColorEnd = this.giConfig.cardColorEnd, cardBasePlateColor = this.giConfig.cardBasePlateColor, cardBasePlateBorder = this.giConfig.cardBasePlateBorder } = {}) {
2478
+ const [titleStatus, liveTime, cover] = await this.getLiveStatus(data.live_time, liveStatus);
2479
+ const html = `
2480
+ <!DOCTYPE html>
2481
+ <html>
2482
+ <head>
2483
+ <title>直播通知</title>
2484
+ <style>
2485
+ * {
2486
+ margin: 0;
2487
+ padding: 0;
2488
+ box-sizing: border-box;
2489
+ font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
2490
+ }
2491
+
2492
+ html {
2493
+ width: 800px;
2494
+ height: auto;
2495
+ }
2496
+
2497
+ .background {
2498
+ width: 100%;
2499
+ height: auto;
2500
+ padding: 15px;
2501
+ background: linear-gradient(to right bottom, ${cardColorStart}, ${cardColorEnd});
2502
+ overflow: hidden;
2503
+ }
2504
+
2505
+ .base-plate {
2506
+ width: 100%;
2507
+ height: auto;
2508
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
2509
+ padding: ${cardBasePlateBorder};
2510
+ border-radius: 10px;
2511
+ background-color: ${cardBasePlateColor};
2512
+ }
3076
2513
 
3077
- .base-plate {
3078
- width: 100%;
3079
- height: auto;
3080
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
3081
- padding: ${cardBasePlateBorder};
3082
- border-radius: 10px;
3083
- background-color: ${cardBasePlateColor};
3084
- }
3085
-
3086
- .card {
3087
- width: 100%;
3088
- height: auto;
3089
- border-radius: 5px;
3090
- padding: 15px;
3091
- overflow: hidden;
3092
- background-color: #fff;
3093
- }
3094
-
3095
- .card-body {
3096
- display: flex;
3097
- padding: 15px;
3098
- }
3099
-
3100
- .card .anchor-avatar {
3101
- border-radius: 5px 5px 0 0;
3102
- max-width: 50px;
3103
- /* 设置最大宽度为容器宽度的100% */
3104
- max-height: 50px;
3105
- /* 设置最大高度为容器高度的90% */
3106
- margin-right: 20px;
3107
- border-radius: 10px;
3108
- }
3109
-
3110
- .card .card-body .card-content {
3111
- width: 100%;
3112
- }
3113
-
3114
- .card .card-body .card-content .card-header {
3115
- width: 100%;
3116
- display: flex;
3117
- justify-content: space-between;
3118
- }
3119
-
3120
- .card .up-info {
3121
- display: flex;
3122
- flex-direction: column;
3123
- justify-content: space-between;
3124
- height: 50px;
3125
- }
3126
-
3127
- .card .up-info .up-name {
3128
- font-size: 20px;
3129
- }
3130
-
3131
- .card .pub-time {
3132
- font-size: 12px;
3133
- color: grey;
3134
- }
3135
-
3136
- .card .card-header img {
3137
- height: 50px;
3138
- }
2514
+ .card {
2515
+ width: 100%;
2516
+ height: auto;
2517
+ border-radius: 5px;
2518
+ padding: 15px;
2519
+ overflow: hidden;
2520
+ background-color: #fff;
2521
+ }
3139
2522
 
3140
- .card .dress-up {
3141
- position: relative;
3142
- max-width: 110px;
3143
- max-height: 34px;
3144
- /* background-image: url('${dynamicCardUrl}');
3145
- background-size: cover; */
3146
- font-size: 12px;
3147
- line-height: 33px;
3148
- }
2523
+ .card img {
2524
+ border-radius: 5px 5px 0 0;
2525
+ max-width: 100%;
2526
+ /* 设置最大宽度为容器宽度的100% */
2527
+ max-height: 80%;
2528
+ /* 设置最大高度为容器高度的90% */
2529
+ }
2530
+
2531
+ .card-header {
2532
+ display: flex;
2533
+ justify-content: space-between;
2534
+ align-items: center;
2535
+ margin-top: 5px;
2536
+ margin-bottom: 10px;
2537
+ }
2538
+
2539
+ .card-title {
2540
+ line-height: 50px;
2541
+ }
2542
+
2543
+ .card-body {
2544
+ padding: 2px 16px;
2545
+ margin-bottom: 10px;
2546
+ }
2547
+
2548
+ .live-broadcast-info {
2549
+ display: flex;
2550
+ align-items: center;
2551
+ margin-bottom: 10px;
2552
+ }
2553
+
2554
+ .anchor-avatar {
2555
+ width: 50px;
2556
+ /* 主播头像大小 */
2557
+ height: auto;
2558
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
2559
+ }
2560
+
2561
+ .broadcast-message {
2562
+ display: inline-block;
2563
+ margin-left: 10px;
2564
+ font-size: 20px;
2565
+ color: #333;
2566
+ }
2567
+
2568
+ .card-text {
2569
+ color: grey;
2570
+ font-size: 20px;
2571
+ }
2572
+
2573
+ .card-link {
2574
+ display: flex;
2575
+ justify-content: space-between;
2576
+ text-decoration: none;
2577
+ font-size: 20px;
2578
+ margin-top: 10px;
2579
+ margin-bottom: 10px;
2580
+ }
2581
+ </style>
2582
+ </head>
2583
+ <body>
2584
+ <div class="background">
2585
+ <div ${this.giConfig.removeBorder ? "" : "class=\"base-plate\""}>
2586
+ <div class="card">
2587
+ <img src="${cover ? data.user_cover : data.keyframe}"
2588
+ alt="封面">
2589
+ <div class="card-body">
2590
+ <div class="card-header">
2591
+ <h1 class="card-title">${data.title}</h1>
2592
+ <div class="live-broadcast-info">
2593
+ <!-- 主播头像 -->
2594
+ <img style="border-radius: 10px; margin-left: 10px" class="anchor-avatar"
2595
+ src="${userface}" alt="主播头像">
2596
+ <span class="broadcast-message">${username}${titleStatus}</span>
2597
+ </div>
2598
+ </div>
2599
+ ${this.giConfig.hideDesc ? "" : `<p class="card-text">${data.description ? data.description : "这个主播很懒,什么简介都没写"}</p>`}
2600
+ <p class="card-link">
2601
+ <span>${liveStatus === 3 ? `本场直播点赞数:${this.numberToStr(+liveData.likedNum)}` : `人气:${this.numberToStr(data.online)}`}</span>
2602
+ <span>分区名称:${data.area_name}</span>
2603
+ </p>
2604
+ <p class="card-link">
2605
+ <span>${liveTime}</span>
2606
+ ${this.giConfig.followerDisplay ? `
2607
+ <span>
2608
+ ${liveStatus === 1 ? `当前粉丝数:${liveData.fansNum || "暂未获取到"}` : liveStatus === 2 ? `${liveData.watchedNum !== "API" ? `累计观看人数:${liveData.watchedNum}` : ""}` : liveStatus === 3 ? `粉丝数变化:${liveData.fansChanged}` : ""}
2609
+ </span>` : ""}
2610
+ </p>
2611
+ </div>
2612
+ </div>
2613
+ </div>
2614
+ </div>
2615
+ </body>
2616
+ </html>
2617
+ `;
2618
+ return await withRetry(() => this.imgHandler(html)).catch((e) => {
2619
+ throw new Error(`生成图片失败!错误: ${e.toString()}`);
2620
+ });
2621
+ }
2622
+ static BG_COLOR = {
2623
+ [blive_message_listener.GuardLevel.None]: ["#4ebcec", "#F9CCDF"],
2624
+ [blive_message_listener.GuardLevel.Jianzhang]: ["#4ebcec", "#b494e5"],
2625
+ [blive_message_listener.GuardLevel.Tidu]: ["#d8a0e6", "#b494e5"],
2626
+ [blive_message_listener.GuardLevel.Zongdu]: ["#f2a053", "#ef5f5f"]
2627
+ };
2628
+ async generateBoardingImg(captainImgUrl, { guardLevel, uname, face, isAdmin }, { masterAvatarUrl, masterName }) {
2629
+ const bgColor = GenerateImg.BG_COLOR[guardLevel];
2630
+ const desc = {
2631
+ [blive_message_listener.GuardLevel.Jianzhang]: () => {
2632
+ return `"${uname}号"加入<br/>"${masterName}"大航海舰队!`;
2633
+ },
2634
+ [blive_message_listener.GuardLevel.Tidu]: () => {
2635
+ return `"${uname}"就任<br/>"${masterName}"大航海舰队提督!`;
2636
+ },
2637
+ [blive_message_listener.GuardLevel.Zongdu]: () => {
2638
+ return `"${uname}"上任<br/>"${masterName}"大航海舰队总督!`;
2639
+ }
2640
+ };
2641
+ const html = `
2642
+ <!DOCTYPE html>
2643
+ <html>
3149
2644
 
3150
- .card .dress-up img {
3151
- max-width: 100%;
3152
- max-height: 100%;
3153
- }
2645
+ <head>
2646
+ <title>上舰通知</title>
2647
+ <style>
2648
+ * {
2649
+ margin: 0;
2650
+ padding: 0;
2651
+ box-sizing: border-box;
2652
+ font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
2653
+ }
3154
2654
 
3155
- .card .dress-up span {
3156
- position: absolute;
3157
- color: ${dynamicCardColor};
3158
- right: 37px;
3159
- top: 5px;
3160
- }
2655
+ html {
2656
+ width: 430px;
2657
+ height: auto;
2658
+ }
3161
2659
 
3162
- .card .dyn-title {
3163
- font-size: 20px;
3164
- margin-bottom: 10px;
3165
- }
2660
+ .bg {
2661
+ display: flex;
2662
+ justify-content: center;
2663
+ align-items: center;
2664
+ width: 430px;
2665
+ height: 220px;
2666
+ background: linear-gradient(to right bottom, ${bgColor[0]}, ${bgColor[1]});
2667
+ }
3166
2668
 
3167
- .card .card-topic {
3168
- display: flex;
3169
- align-items: center;
3170
- margin-top: 10px;
3171
- color: #008AC5;
3172
- gap: 3px;
3173
- }
3174
-
3175
- .card .card-details {
3176
- margin-bottom: 15px;
3177
- width: 90%;
3178
- }
3179
-
3180
- .card .card-major {
3181
- display: flex;
3182
- flex-wrap: wrap;
3183
- gap: 5px;
3184
- }
3185
-
3186
- .card .card-major .photo-item {
3187
- border-radius: 10px;
3188
- overflow: hidden;
3189
- width: 170px;
3190
- height: 170px;
3191
- object-fit: cover;
3192
- }
2669
+ .baseplate {
2670
+ display: flex;
2671
+ justify-content: space-between;
2672
+ align-items: center;
2673
+ border-radius: 10px;
2674
+ width: 410px;
2675
+ height: 200px;
2676
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
2677
+ background-color: rgba(255, 255, 255, 0.65);
2678
+ backdrop-filter: blur(10px);
2679
+ }
3193
2680
 
3194
- .card .card-major .single-photo-mask {
3195
- position: absolute;
3196
- text-align: center;
3197
- width: 100%;
3198
- height: 100%;
3199
- top: 0;
3200
- left: 0;
3201
- background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, transparent 30%);
3202
- }
2681
+ .info {
2682
+ flex: 1;
2683
+ height: 100%;
2684
+ display: flex;
2685
+ flex-direction: column;
2686
+ justify-content: space-between;
2687
+ padding: 10px 0 10px 10px;
2688
+ }
3203
2689
 
3204
- .card .card-major .single-photo-mask-text {
3205
- position: absolute;
3206
- color: #fff;
3207
- font-size: 24px;
3208
- right: 0;
3209
- bottom: 66px;
3210
- left: 0;
3211
- text-align: center;
3212
- }
2690
+ .user {
2691
+ display: flex;
2692
+ gap: 10px;
2693
+ }
3213
2694
 
3214
- .card .card-major .single-photo-mask-arrow {
3215
- position: absolute;
3216
- width: 70px;
3217
- height: 70px;
3218
- bottom: 7px;
3219
- left: 50%;
3220
- transform: translateX(-50%);
3221
- }
2695
+ .avatar {
2696
+ height: 90px;
2697
+ width: 90px;
2698
+ border-radius: 50%;
2699
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
2700
+ }
3222
2701
 
3223
- .card .card-major .single-photo-container {
3224
- position: relative;
3225
- max-width: 500px;
3226
- max-height: 1000px;
3227
- border-radius: 10px;
3228
- overflow: hidden;
3229
- }
2702
+ .avatar img {
2703
+ width: 100%;
2704
+ height: 100%;
2705
+ border-radius: 50%;
2706
+ border: 3px solid white;
2707
+ }
3230
2708
 
3231
- .card .card-major .single-photo-item {
3232
- max-width: 500px;
3233
- border-radius: 10px;
3234
- overflow: hidden;
3235
- }
2709
+ .user-info {
2710
+ display: flex;
2711
+ flex-direction: column;
2712
+ align-items: flex-start;
2713
+ gap: 7px;
2714
+ margin-top: 10px;
2715
+ }
3236
2716
 
3237
- .card .card-major .four-photo-item {
3238
- width: 170px;
3239
- height: 170px;
3240
- object-fit: cover;
3241
- border-radius: 10px;
3242
- overflow: hidden;
3243
- flex-basis: 20%; /* or any value less than 50% */
3244
- }
3245
-
3246
- .card .card-stat {
3247
- display: flex;
3248
- justify-content: space-between;
3249
- width: 90%;
3250
- margin-top: 15px;
3251
- color: gray;
3252
- font-size: 14px;
3253
- }
3254
-
3255
- .card .card-stat .stat-item {
3256
- display: flex;
3257
- align-items: center;
3258
- gap: 3px;
3259
- }
2717
+ .name-badge {
2718
+ display: flex;
2719
+ align-items: center;
2720
+ height: 30px;
2721
+ background-color: ${bgColor[0]};
2722
+ border-radius: 25px;
2723
+ color: white;
2724
+ padding: 0 10px;
2725
+ border: solid 2px white;
2726
+ overflow: hidden;
2727
+ }
3260
2728
 
3261
- .card .card-video {
3262
- display: flex;
3263
- overflow: hidden;
3264
- border-radius: 5px 0 0 5px;
3265
- margin-top: 10px;
3266
- height: 132px;
3267
- }
3268
-
3269
- .card .video-cover {
3270
- position: relative;
3271
- flex: 2;
3272
- overflow: hidden;
3273
- }
3274
-
3275
- .card .video-cover img {
3276
- width: 236px;
3277
- }
2729
+ .name-badge span {
2730
+ max-width: 100px;
2731
+ white-space: nowrap;
2732
+ text-overflow: ellipsis;
2733
+ overflow: hidden;
2734
+ font-weight: bold;
2735
+ font-size: 12px;
2736
+ }
3278
2737
 
3279
- .card .cover-mask {
3280
- position: absolute;
3281
- width: 100%;
3282
- height: 100%;
3283
- top: 0;
3284
- left: 0;
3285
- background: linear-gradient(to top, rgba(0, 0, 0, 0.5) 0%, transparent 30%);
3286
- }
3287
-
3288
- .card .video-cover span {
3289
- position: absolute;
3290
- color: #fff;
3291
- font-size: 14px;
3292
- right: 10px;
3293
- bottom: 8px;
3294
- }
3295
-
3296
- .card .video-info {
3297
- display: flex;
3298
- justify-content: space-between;
3299
- flex-direction: column;
3300
- flex: 3;
3301
- border: #e5e7e9 1px solid;
3302
- border-left: none;
3303
- border-radius: 0 5px 5px 0;
3304
- padding: 12px 16px 10px;
3305
- background-color: #fff;
3306
- }
3307
-
3308
- .card .video-info-header .video-title {
3309
- font-size: 16px;
3310
- }
3311
-
3312
- .card .video-info-header .video-introduction {
3313
- margin-top: 5px;
3314
- font-size: 12px;
3315
- color: #AAA;
3316
- display: -webkit-box;
3317
- /* 必须设置为 -webkit-box 或 -webkit-inline-box */
3318
- -webkit-box-orient: vertical;
3319
- /* 必须设置为 vertical */
3320
- -webkit-line-clamp: 2;
3321
- /* 显示的文本行数 */
3322
- overflow: hidden;
3323
- /* 必须设置为 hidden */
3324
- }
3325
-
3326
- .card .video-stat {
3327
- font-size: 12px;
3328
- color: #AAA;
3329
- display: flex;
3330
- gap: 35px
3331
- }
3332
-
3333
- .card .video-stat .video-stat-item {
3334
- display: flex;
3335
- align-items: center;
3336
- gap: 3px;
3337
- }
2738
+ .accompany {
2739
+ display: flex;
2740
+ gap: 5px;
2741
+ align-items: center;
2742
+ height: 25px;
2743
+ background-color: ${bgColor[0]};
2744
+ border-radius: 25px;
2745
+ border: solid 2px white;
2746
+ overflow: hidden;
2747
+ }
3338
2748
 
3339
- .card .card-forward {
3340
- border-radius: 5px;
3341
- padding: 12px 10px 14px 10px;
3342
- background-color: #F6F7F8;
3343
- }
3344
-
3345
- .card-forward .forward-userinfo {
3346
- display: flex;
3347
- align-items: center;
3348
- gap: 5px;
3349
- height: 30px;
3350
- }
3351
-
3352
- .forward-userinfo img {
3353
- width: 20px;
3354
- height: 20px;
3355
- border-radius: 50%;
3356
- }
3357
-
3358
- .forward-userinfo span {
3359
- color: #61666D;
3360
- font-size: 15px;
3361
- }
2749
+ .master-avatar {
2750
+ width: 25px;
2751
+ height: 25px;
2752
+ border-radius: 50%;
2753
+ background: url("${masterAvatarUrl}") no-repeat center;
2754
+ background-size: cover;
2755
+ }
3362
2756
 
3363
- .card .card-reserve {
3364
- display: flex;
3365
- justify-content: space-between;
3366
- align-items: center;
3367
- padding: 10px 20px 10px 20px;
3368
- margin-top: 10px;
3369
- border-radius: 10px;
3370
- background-color: #F6F7F8;
3371
- }
3372
-
3373
- .card-reserve .reserve-title {
3374
- font-size: 14px;
3375
- color: #18191C;
3376
- }
3377
-
3378
- .card-reserve .reserve-desc {
3379
- margin-top: 7px;
3380
- font-size: 12px;
3381
- color: #9499A0;
3382
- }
3383
-
3384
- .reserve-info .reserve-time {
3385
- margin-right: 7px;
3386
- }
3387
-
3388
- .card-reserve .reserve-prize {
3389
- display: flex;
3390
- align-items: center;
3391
- margin-top: 3px;
3392
- gap: 3px;
3393
- color: #00AEEC;
3394
- }
3395
-
3396
- .card .card-reserve .reserve-button button {
3397
- border: none;
3398
- height: 30px;
3399
- width: 72px;
3400
- font-size: 13px;
3401
- border-radius: 7px;
3402
- }
3403
-
3404
- .card .card-reserve .reserve-button .reserve-button-end {
3405
- display: flex;
3406
- align-items: center;
3407
- justify-content: center;
3408
- color: #9499A0;
3409
- background-color: #E3E5E7;
3410
- }
3411
-
3412
- .card .card-reserve .reserve-button .reserve-button-ing {
3413
- display: flex;
3414
- align-items: center;
3415
- justify-content: center;
3416
- color: #FFF;
3417
- background-color: #00A0D8;
3418
- }
3419
- `;
2757
+ .accompany span {
2758
+ max-width: 85px;
2759
+ white-space: nowrap;
2760
+ text-overflow: ellipsis;
2761
+ overflow: hidden;
2762
+ color: white;
2763
+ font-size: 10px;
2764
+ font-weight: bold;
2765
+ margin-right: 5px;
2766
+ }
2767
+
2768
+ .desc {
2769
+ margin-bottom: 10px;
2770
+ font-size: 16px;
2771
+ font-weight: bold;
2772
+ font-style: italic;
2773
+ color: #333;
2774
+ }
2775
+
2776
+ .captain {
2777
+ width: 175px;
2778
+ height: 175px;
2779
+ background: url("${captainImgUrl}") no-repeat center;
2780
+ background-size: cover;
2781
+ }
2782
+ </style>
2783
+ </head>
2784
+
2785
+ <body>
2786
+ <div class="bg">
2787
+ <div class="baseplate">
2788
+ <div class="info">
2789
+ <div class="user">
2790
+ <div class="avatar">
2791
+ <img src="${face}" alt="用户头像">
2792
+ </div>
2793
+ <div class="user-info">
2794
+ <div class="name-badge">
2795
+ <span>${uname}</span>
2796
+ </div>
2797
+ <div class="accompany">
2798
+ <div class="master-avatar"></div><span>${isAdmin ? "房管" : masterName}</span>
2799
+ </div>
2800
+ </div>
2801
+ </div>
2802
+ <div class="desc">
2803
+ ${desc[guardLevel]()}
2804
+ </div>
2805
+ </div>
2806
+ <div class="captain"></div>
2807
+ </div>
2808
+ </div>
2809
+ </body>
2810
+
2811
+ </html>
2812
+ `;
2813
+ return await withRetry(() => this.imgHandler(html)).catch((e) => {
2814
+ throw new Error(`生成图片失败!错误: ${e.toString()}`);
2815
+ });
2816
+ }
2817
+ richTextParser(rt, title) {
2818
+ const richText = rt.reduce((accumulator, currentValue) => {
2819
+ if (currentValue.emoji) return `${accumulator}<img style="width:17px; height:17px;" src="${currentValue.emoji.icon_url}"/>`;
2820
+ return accumulator + currentValue.text;
2821
+ }, "");
2822
+ if (this.giConfig.filter.enable) {
2823
+ if (this.giConfig.filter.regex) {
2824
+ if (new RegExp(this.giConfig.filter.regex).test(richText)) throw new Error("出现关键词,屏蔽该动态");
2825
+ }
2826
+ if (this.giConfig.filter.keywords.length !== 0 && this.giConfig.filter.keywords.some((keyword) => richText.includes(keyword))) throw new Error("出现关键词,屏蔽该动态");
2827
+ }
2828
+ const text = richText.replace(/\n/g, "<br>");
2829
+ return `
2830
+ <div class="card-details">
2831
+ ${title ? `<h1 class="dyn-title">${title}</h1>` : ""}
2832
+ ${text}
2833
+ </div>
2834
+ `;
2835
+ }
2836
+ async generateDynamicImg(data, { cardColorStart = this.giConfig.cardColorStart, cardColorEnd = this.giConfig.cardColorEnd, cardBasePlateColor = this.giConfig.cardBasePlateColor, cardBasePlateBorder = this.giConfig.cardBasePlateBorder } = {}) {
2837
+ const module_author = data.modules.module_author;
2838
+ const avatarUrl = module_author.face;
2839
+ const upName = module_author.name;
2840
+ let pubTime = this.unixTimestampToString(module_author.pub_ts);
2841
+ let dynamicCardUrl;
2842
+ let dynamicCardId;
2843
+ let dynamicCardColor;
2844
+ if (module_author.decorate) {
2845
+ dynamicCardUrl = module_author.decorate.card_url;
2846
+ dynamicCardId = module_author.decorate.fan.num_str;
2847
+ dynamicCardColor = module_author.decorate.fan.color;
2848
+ }
2849
+ const module_stat = data.modules.module_stat;
2850
+ const comment = module_stat.comment.count;
2851
+ const forward = module_stat.forward.count;
2852
+ const like = module_stat.like.count;
2853
+ const topic = data.modules.module_dynamic.topic ? data.modules.module_dynamic.topic.name : "";
2854
+ const getDynamicMajor = async (dynamic, forward$1) => {
2855
+ let main$1 = "";
2856
+ let forwardInfo;
2857
+ const basicDynamic = () => {
2858
+ const module_dynamic = dynamic.modules.module_dynamic;
2859
+ if (module_dynamic?.desc?.rich_text_nodes) {
2860
+ const content = this.richTextParser(module_dynamic.desc.rich_text_nodes);
2861
+ main$1 += content;
2862
+ }
2863
+ if (module_dynamic?.major?.opus?.summary?.rich_text_nodes) {
2864
+ const content = this.richTextParser(module_dynamic.major.opus.summary.rich_text_nodes, module_dynamic.major.opus.title);
2865
+ main$1 += content;
2866
+ }
2867
+ let major = "";
2868
+ const arrowImg = (0, node_url.pathToFileURL)((0, node_path.resolve)(__dirname, "img/arrow.png"));
2869
+ if (module_dynamic?.major?.opus?.pics) {
2870
+ if (module_dynamic.major.opus.pics.length === 1) if (module_dynamic.major.opus.pics[0].height > 3e3) major += `
2871
+ <div class="single-photo-container">
2872
+ <img class="single-photo-item" src="${module_dynamic.major.opus.pics[0].url}"/>
2873
+ <div class="single-photo-mask">
2874
+ <span class="single-photo-mask-text">点击链接浏览全部</span>
2875
+ </div>
2876
+ <img class="single-photo-mask-arrow" src="${arrowImg}"/>
2877
+ </div>
2878
+ `;
2879
+ else major += `
2880
+ <div class="single-photo-container">
2881
+ <img class="single-photo-item" src="${module_dynamic.major.opus.pics[0].url}"/>
2882
+ </div>
2883
+ `;
2884
+ else if (module_dynamic.major.opus.pics.length === 4) major += module_dynamic.major.opus.pics.reduce((acc, cV) => {
2885
+ return `${acc}<img class="four-photo-item" src="${cV.url}"/>`;
2886
+ }, "");
2887
+ else major += module_dynamic.major.opus.pics.reduce((acc, cV) => {
2888
+ return `${acc}<img class="photo-item" src="${cV.url}"/>`;
2889
+ }, "");
2890
+ main$1 += `
2891
+ <div class="card-major">
2892
+ ${major}
2893
+ </div>
2894
+ `;
2895
+ }
2896
+ };
2897
+ switch (dynamic.type) {
2898
+ case DYNAMIC_TYPE_WORD:
2899
+ case DYNAMIC_TYPE_DRAW:
2900
+ case DYNAMIC_TYPE_FORWARD:
2901
+ basicDynamic();
2902
+ if (dynamic.type === DYNAMIC_TYPE_FORWARD) {
2903
+ if (this.giConfig.filter.enable && this.giConfig.filter.forward) throw new Error("已屏蔽转发动态");
2904
+ const forward_module_author = dynamic.orig.modules.module_author;
2905
+ const forwardUserAvatarUrl = forward_module_author.face;
2906
+ const forwardUserName = forward_module_author.name;
2907
+ const [forwardMain, forwardInfo$1] = await getDynamicMajor(dynamic.orig, true);
2908
+ main$1 += `
2909
+ <div class="card-forward">
2910
+ <div class="forward-userinfo">
2911
+ <img class="forward-avatar" src="${forwardUserAvatarUrl}" alt="avatar">
2912
+ <span class="forward-username">${forwardUserName} ${forwardInfo$1 ? forwardInfo$1 : ""}</span>
2913
+ </div>
2914
+ <div class="forward-main">
2915
+ ${forwardMain}
2916
+ </div>
2917
+ </div>
2918
+ `;
2919
+ }
2920
+ if (dynamic.modules.module_dynamic.additional) {
2921
+ const additional = dynamic.modules.module_dynamic.additional;
2922
+ switch (additional.type) {
2923
+ case ADDITIONAL_TYPE_RESERVE: {
2924
+ const reserve = additional.reserve;
2925
+ let button;
2926
+ if (reserve.button.uncheck.text === "已结束") button = `
2927
+ <button class="reserve-button-end">
2928
+ <span>${reserve.button.uncheck.text}</span>
2929
+ </button>
2930
+ `;
2931
+ else button = `
2932
+ <button class="reserve-button-ing">
2933
+ <svg class="bili-dyn-card-reserve__action__icon" style="width: 16px; height: 16px;"
2934
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
2935
+ viewBox="0 0 16 16" width="16" height="16">
2936
+ <path
2937
+ d="M3.0000133333333334 6.999199999999999C3.0000133333333334 4.23776 5.2385866666666665 1.9991866666666667 8 1.9991866666666667C10.761433333333333 1.9991866666666667 13 4.23776 13 6.999199999999999L13 9.860933333333332C13 9.923533333333333 13.024899999999999 9.983633333333334 13.069199999999999 10.027933333333333L13.588366666666666 10.5471C14.389533333333333 11.348299999999998 13.914133333333334 12.734533333333333 12.754199999999999 12.8183C11.535999999999998 12.906233333333333 9.818933333333334 12.999199999999998 8 12.999199999999998C6.181073333333334 12.999199999999998 4.464026666666666 12.906233333333333 3.2458266666666664 12.8183C2.0859066666666664 12.734533333333333 1.61046 11.348299999999998 2.4116466666666665 10.547133333333333L2.93084 10.027933333333333C2.975133333333333 9.983633333333334 3.0000133333333334 9.923533333333333 3.0000133333333334 9.860933333333332L3.0000133333333334 6.999199999999999zM8 2.9991866666666667C5.790873333333334 2.9991866666666667 4.000013333333333 4.790046666666666 4.000013333333333 6.999199999999999L4.000013333333333 9.860933333333332C4.000013333333333 10.1888 3.8697733333333333 10.5032 3.6379466666666667 10.735033333333334L3.1187466666666666 11.254233333333334C2.911966666666667 11.461 3.0317600000000002 11.800199999999998 3.317833333333333 11.820899999999998C4.5211266666666665 11.907766666666667 6.212726666666666 11.999199999999998 8 11.999199999999998C9.787266666666666 11.999199999999998 11.4789 11.907733333333333 12.682199999999998 11.820899999999998C12.968233333333332 11.800199999999998 13.088033333333332 11.461 12.881266666666665 11.254233333333334L12.362066666666665 10.735033333333334C12.130233333333333 10.5032 12 10.1888 12 9.860933333333332L12 6.999199999999999C12 4.790046666666666 10.209166666666667 2.9991866666666667 8 2.9991866666666667z"
2938
+ fill="currentColor"></path>
2939
+ <path
2940
+ d="M8.720066666666666 2.0260466666666668C8.720066666666666 2.42372 8.397666666666666 2.746093333333333 8 2.746093333333333C7.602333333333332 2.746093333333333 7.279933333333333 2.42372 7.279933333333333 2.0260466666666668C7.279933333333333 1.6283666666666667 7.602333333333332 1.3059866666666666 8 1.3059866666666666C8.397666666666666 1.3059866666666666 8.720066666666666 1.6283666666666667 8.720066666666666 2.0260466666666668z"
2941
+ fill="currentColor"></path>
2942
+ <path
2943
+ d="M6.791266666666666 12.499199999999998C6.791266666666666 13.173966666666667 7.335266666666667 13.715866666666665 8 13.715866666666665C8.664766666666665 13.715866666666665 9.208733333333333 13.173966666666667 9.208733333333333 12.499199999999998L10.208733333333333 12.499199999999998C10.208733333333333 13.720566666666667 9.2227 14.715866666666665 8 14.715866666666665C6.777346666666666 14.715866666666665 5.791273333333333 13.720566666666667 5.791273333333333 12.499199999999998L6.791266666666666 12.499199999999998z"
2944
+ fill="currentColor"></path>
2945
+ </svg>
2946
+ <span>${reserve.button.uncheck.text}</span>
2947
+ </button>
2948
+ `;
2949
+ main$1 += `
2950
+ <div class="card-reserve">
2951
+ <div class="reserve-main">
2952
+ <div class="reserve-title">
2953
+ ${reserve.title}
2954
+ </div>
2955
+ <div class="reserve-desc">
2956
+ <div class="reserve-info">
2957
+ <span class="reserve-time">${reserve.desc1.text}</span>
2958
+ <span class="reserve-num">${reserve.desc2.text}</span>
2959
+ </div>
2960
+ ${reserve.desc3 ? `<div class="reserve-prize">
2961
+ <svg class="bili-dyn-card-reserve__lottery__icon"
2962
+ style="width: 16px; height: 16px;" xmlns="http://www.w3.org/2000/svg"
2963
+ xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" width="16"
2964
+ height="16">
2965
+ <path
2966
+ d="M2.99998 7.785666666666666C3.2761266666666664 7.785666666666666 3.49998 8.0095 3.49998 8.285666666666666L3.49998 12.285666666666666C3.49998 12.719566666666667 3.8517599999999996 13.071333333333332 4.285693333333333 13.071333333333332L11.714266666666667 13.071333333333332C12.1482 13.071333333333332 12.5 12.719566666666667 12.5 12.285666666666666L12.5 8.285666666666666C12.5 8.0095 12.723833333333333 7.785666666666666 13 7.785666666666666C13.276133333333334 7.785666666666666 13.5 8.0095 13.5 8.285666666666666L13.5 12.285666666666666C13.5 13.271866666666668 12.7005 14.071333333333332 11.714266666666667 14.071333333333332L4.285693333333333 14.071333333333332C3.2994733333333333 14.071333333333332 2.49998 13.271866666666668 2.49998 12.285666666666666L2.49998 8.285666666666666C2.49998 8.0095 2.7238399999999996 7.785666666666666 2.99998 7.785666666666666z"
2967
+ fill="currentColor"></path>
2968
+ <path
2969
+ d="M1.9285533333333333 5.857139999999999C1.9285533333333333 5.107613333333333 2.5361666666666665 4.5 3.285693333333333 4.5L12.714266666666667 4.5C13.463799999999999 4.5 14.071399999999999 5.107613333333333 14.071399999999999 5.857139999999999L14.071399999999999 7.134066666666667C14.071399999999999 7.793799999999999 13.590066666666667 8.373766666666667 12.905000000000001 8.4432C12.058933333333332 8.528966666666665 10.470166666666666 8.642866666666666 8 8.642866666666666C5.529819999999999 8.642866666666666 3.9410399999999997 8.528966666666665 3.09498 8.4432C2.4099066666666666 8.373766666666667 1.9285533333333333 7.793799999999999 1.9285533333333333 7.134066666666667L1.9285533333333333 5.857139999999999zM3.285693333333333 5.5C3.088453333333333 5.5 2.9285533333333333 5.6599 2.9285533333333333 5.857139999999999L2.9285533333333333 7.134066666666667C2.9285533333333333 7.3082 3.0432666666666663 7.432833333333333 3.1958066666666665 7.4483C4.00544 7.530366666666667 5.560420000000001 7.6428666666666665 8 7.6428666666666665C10.439566666666666 7.6428666666666665 11.994533333333333 7.530366666666667 12.804133333333333 7.4483C12.9567 7.432833333333333 13.071399999999999 7.3082 13.071399999999999 7.134066666666667L13.071399999999999 5.857139999999999C13.071399999999999 5.6599 12.911499999999998 5.5 12.714266666666667 5.5L3.285693333333333 5.5z"
2970
+ fill="currentColor"></path>
2971
+ <path
2972
+ d="M4.357126666666666 3.5714733333333335C4.357126666666666 2.506353333333333 5.220573333333333 1.6429066666666667 6.285693333333333 1.6429066666666667C7.350833333333332 1.6429066666666667 8.214266666666667 2.506353333333333 8.214266666666667 3.5714733333333335L8.214266666666667 5.500046666666666L6.285693333333333 5.500046666666666C5.220573333333333 5.500046666666666 4.357126666666666 4.636593333333333 4.357126666666666 3.5714733333333335zM6.285693333333333 2.6429066666666667C5.77286 2.6429066666666667 5.357126666666667 3.0586399999999996 5.357126666666667 3.5714733333333335C5.357126666666667 4.084313333333333 5.77286 4.500046666666666 6.285693333333333 4.500046666666666L7.214266666666667 4.500046666666666L7.214266666666667 3.5714733333333335C7.214266666666667 3.0586399999999996 6.798533333333333 2.6429066666666667 6.285693333333333 2.6429066666666667z"
2973
+ fill="currentColor"></path>
2974
+ <path
2975
+ d="M7.785666666666666 3.5714733333333335C7.785666666666666 2.506353333333333 8.649133333333332 1.6429066666666667 9.714266666666667 1.6429066666666667C10.779399999999999 1.6429066666666667 11.642866666666666 2.506353333333333 11.642866666666666 3.5714733333333335C11.642866666666666 4.636593333333333 10.779399999999999 5.500046666666666 9.714266666666667 5.500046666666666L7.785666666666666 5.500046666666666L7.785666666666666 3.5714733333333335zM9.714266666666667 2.6429066666666667C9.201433333333332 2.6429066666666667 8.785666666666666 3.0586399999999996 8.785666666666666 3.5714733333333335L8.785666666666666 4.500046666666666L9.714266666666667 4.500046666666666C10.2271 4.500046666666666 10.642866666666666 4.084313333333333 10.642866666666666 3.5714733333333335C10.642866666666666 3.0586399999999996 10.2271 2.6429066666666667 9.714266666666667 2.6429066666666667z"
2976
+ fill="currentColor"></path>
2977
+ <path
2978
+ d="M8 3.7856466666666666C8.276133333333332 3.7856466666666666 8.5 4.009499999999999 8.5 4.285646666666667L8.5 13.142800000000001C8.5 13.418933333333332 8.276133333333332 13.642800000000001 8 13.642800000000001C7.723833333333333 13.642800000000001 7.5 13.418933333333332 7.5 13.142800000000001L7.5 4.285646666666667C7.5 4.009499999999999 7.723833333333333 3.7856466666666666 8 3.7856466666666666z"
2979
+ fill="currentColor"></path>
2980
+ </svg>
2981
+ <span>${reserve.desc3.text}</span>
2982
+ <svg style="width: 12px; height: 12px;" xmlns="http://www.w3.org/2000/svg"
2983
+ xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 12 12" width="12"
2984
+ height="12">
2985
+ <path
2986
+ d="M4.359835 1.609835C4.21339 1.756285 4.21339 1.99372 4.359835 2.140165L8.0429 5.823225C8.140525 5.920875 8.140525 6.079125 8.0429 6.176775L4.359835 9.859825C4.21339 10.006275 4.21339 10.243725 4.359835 10.390175C4.506285 10.5366 4.743725 10.5366 4.89017 10.390175L8.573225 6.7071C8.96375 6.316575 8.96375 5.683425 8.573225 5.2929L4.89017 1.609835C4.743725 1.46339 4.506285 1.46339 4.359835 1.609835z"
2987
+ fill="currentColor"></path>
2988
+ </svg>
2989
+ </div>` : ""}
2990
+ </div>
2991
+ </div>
2992
+ <div class="reserve-button">
2993
+ ${button}
2994
+ </div>
2995
+ </div>
2996
+ `;
2997
+ }
2998
+ }
2999
+ }
3000
+ break;
3001
+ case DYNAMIC_TYPE_AV: {
3002
+ basicDynamic();
3003
+ const archive = dynamic.modules.module_dynamic.major.archive;
3004
+ if (archive.badge.text === "投稿视频") if (forward$1) forwardInfo = "投稿了视频";
3005
+ else pubTime = `${pubTime} · 投稿了视频`;
3006
+ main$1 += `
3007
+ <div class="card-video">
3008
+ <div class="video-cover">
3009
+ <img src="${archive.cover}"
3010
+ alt="">
3011
+ <div class="cover-mask"></div>
3012
+ <span>${archive.duration_text}</span>
3013
+ </div>
3014
+ <div class="video-info">
3015
+ <div class="video-info-header">
3016
+ <div class="video-title">
3017
+ ${archive.title}
3018
+ </div>
3019
+ <div class="video-introduction">
3020
+ ${archive.desc}
3021
+ </div>
3022
+ </div>
3023
+ <div class="video-stat">
3024
+ <div class="video-stat-item">
3025
+ <svg style="width: 16px; height: 16px;" xmlns="http://www.w3.org/2000/svg"
3026
+ xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" width="16"
3027
+ height="16">
3028
+ <path
3029
+ d="M8 3.3320333333333334C6.321186666666667 3.3320333333333334 4.855333333333333 3.4174399999999996 3.820593333333333 3.5013466666666666C3.1014733333333333 3.5596599999999996 2.5440733333333334 4.109013333333333 2.48 4.821693333333333C2.4040466666666664 5.666533333333334 2.333333333333333 6.780666666666666 2.333333333333333 7.998666666666666C2.333333333333333 9.216733333333334 2.4040466666666664 10.330866666666665 2.48 11.175699999999999C2.5440733333333334 11.888366666666666 3.1014733333333333 12.437733333333334 3.820593333333333 12.496066666666666C4.855333333333333 12.579933333333333 6.321186666666667 12.665333333333333 8 12.665333333333333C9.678999999999998 12.665333333333333 11.144933333333334 12.579933333333333 12.179733333333333 12.496033333333333C12.898733333333332 12.4377 13.456 11.888533333333331 13.520066666666667 11.176033333333333C13.595999999999998 10.331533333333333 13.666666666666666 9.217633333333332 13.666666666666666 7.998666666666666C13.666666666666666 6.779766666666667 13.595999999999998 5.665846666666667 13.520066666666667 4.821366666666666C13.456 4.108866666666666 12.898733333333332 3.55968 12.179733333333333 3.5013666666666663C11.144933333333334 3.417453333333333 9.678999999999998 3.3320333333333334 8 3.3320333333333334zM3.7397666666666667 2.50462C4.794879999999999 2.41906 6.288386666666666 2.3320333333333334 8 2.3320333333333334C9.7118 2.3320333333333334 11.2054 2.4190733333333334 12.260533333333331 2.5046399999999998C13.458733333333331 2.6018133333333333 14.407866666666665 3.5285199999999994 14.516066666666667 4.73182C14.593933333333332 5.597933333333334 14.666666666666666 6.7427 14.666666666666666 7.998666666666666C14.666666666666666 9.2547 14.593933333333332 10.399466666666665 14.516066666666667 11.2656C14.407866666666665 12.468866666666665 13.458733333333331 13.395566666666667 12.260533333333331 13.492766666666665C11.2054 13.578333333333333 9.7118 13.665333333333333 8 13.665333333333333C6.288386666666666 13.665333333333333 4.794879999999999 13.578333333333333 3.7397666666666667 13.492799999999999C2.541373333333333 13.395599999999998 1.5922066666666668 12.468633333333333 1.4840200000000001 11.265266666666665C1.4061199999999998 10.3988 1.3333333333333333 9.253866666666667 1.3333333333333333 7.998666666666666C1.3333333333333333 6.743533333333333 1.4061199999999998 5.598579999999999 1.4840200000000001 4.732153333333333C1.5922066666666668 3.5287466666666667 2.541373333333333 2.601793333333333 3.7397666666666667 2.50462z"
3030
+ fill="currentColor"></path>
3031
+ <path
3032
+ d="M9.8092 7.3125C10.338433333333333 7.618066666666666 10.338433333333333 8.382 9.809166666666666 8.687533333333333L7.690799999999999 9.910599999999999C7.161566666666666 10.216133333333332 6.5 9.8342 6.500006666666666 9.223066666666666L6.500006666666666 6.776999999999999C6.500006666666666 6.165873333333334 7.161566666666666 5.783913333333333 7.690799999999999 6.089479999999999L9.8092 7.3125z"
3033
+ fill="currentColor"></path>
3034
+ </svg>
3035
+ <span>${archive.stat.play}</span>
3036
+ </div>
3037
+ <div class="video-stat-item">
3038
+ <svg style="width: 16px; height: 16px;" xmlns="http://www.w3.org/2000/svg"
3039
+ xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" width="16"
3040
+ height="16">
3041
+ <path
3042
+ d="M8 3.3320333333333334C6.321186666666667 3.3320333333333334 4.855333333333333 3.4174399999999996 3.820593333333333 3.5013466666666666C3.1014733333333333 3.5596599999999996 2.5440733333333334 4.109013333333333 2.48 4.821693333333333C2.4040466666666664 5.666533333333334 2.333333333333333 6.780666666666666 2.333333333333333 7.998666666666666C2.333333333333333 9.216733333333334 2.4040466666666664 10.330866666666665 2.48 11.175699999999999C2.5440733333333334 11.888366666666666 3.1014733333333333 12.437733333333334 3.820593333333333 12.496066666666666C4.855333333333333 12.579933333333333 6.321186666666667 12.665333333333333 8 12.665333333333333C9.678999999999998 12.665333333333333 11.144933333333334 12.579933333333333 12.179733333333333 12.496033333333333C12.898733333333332 12.4377 13.456 11.888533333333331 13.520066666666667 11.176033333333333C13.595999999999998 10.331533333333333 13.666666666666666 9.217633333333332 13.666666666666666 7.998666666666666C13.666666666666666 6.779766666666667 13.595999999999998 5.665846666666667 13.520066666666667 4.821366666666666C13.456 4.108866666666666 12.898733333333332 3.55968 12.179733333333333 3.5013666666666663C11.144933333333334 3.417453333333333 9.678999999999998 3.3320333333333334 8 3.3320333333333334zM3.7397666666666667 2.50462C4.794879999999999 2.41906 6.288386666666666 2.3320333333333334 8 2.3320333333333334C9.7118 2.3320333333333334 11.2054 2.4190733333333334 12.260533333333331 2.5046399999999998C13.458733333333331 2.6018133333333333 14.407866666666665 3.5285199999999994 14.516066666666667 4.73182C14.593933333333332 5.597933333333334 14.666666666666666 6.7427 14.666666666666666 7.998666666666666C14.666666666666666 9.2547 14.593933333333332 10.399466666666665 14.516066666666667 11.2656C14.407866666666665 12.468866666666665 13.458733333333331 13.395566666666667 12.260533333333331 13.492766666666665C11.2054 13.578333333333333 9.7118 13.665333333333333 8 13.665333333333333C6.288386666666666 13.665333333333333 4.794879999999999 13.578333333333333 3.7397666666666667 13.492799999999999C2.541373333333333 13.395599999999998 1.5922066666666668 12.468633333333333 1.4840200000000001 11.265266666666665C1.4061199999999998 10.3988 1.3333333333333333 9.253866666666667 1.3333333333333333 7.998666666666666C1.3333333333333333 6.743533333333333 1.4061199999999998 5.598579999999999 1.4840200000000001 4.732153333333333C1.5922066666666668 3.5287466666666667 2.541373333333333 2.601793333333333 3.7397666666666667 2.50462z"
3043
+ fill="currentColor"></path>
3044
+ <path
3045
+ d="M10.583333333333332 7.166666666666666L6.583333333333333 7.166666666666666C6.307193333333332 7.166666666666666 6.083333333333333 6.942799999999999 6.083333333333333 6.666666666666666C6.083333333333333 6.390526666666666 6.307193333333332 6.166666666666666 6.583333333333333 6.166666666666666L10.583333333333332 6.166666666666666C10.859466666666666 6.166666666666666 11.083333333333332 6.390526666666666 11.083333333333332 6.666666666666666C11.083333333333332 6.942799999999999 10.859466666666666 7.166666666666666 10.583333333333332 7.166666666666666z"
3046
+ fill="currentColor"></path>
3047
+ <path
3048
+ d="M11.583333333333332 9.833333333333332L7.583333333333333 9.833333333333332C7.3072 9.833333333333332 7.083333333333333 9.609466666666666 7.083333333333333 9.333333333333332C7.083333333333333 9.0572 7.3072 8.833333333333332 7.583333333333333 8.833333333333332L11.583333333333332 8.833333333333332C11.859466666666666 8.833333333333332 12.083333333333332 9.0572 12.083333333333332 9.333333333333332C12.083333333333332 9.609466666666666 11.859466666666666 9.833333333333332 11.583333333333332 9.833333333333332z"
3049
+ fill="currentColor"></path>
3050
+ <path
3051
+ d="M5.25 6.666666666666666C5.25 6.942799999999999 5.02614 7.166666666666666 4.75 7.166666666666666L4.416666666666666 7.166666666666666C4.140526666666666 7.166666666666666 3.9166666666666665 6.942799999999999 3.9166666666666665 6.666666666666666C3.9166666666666665 6.390526666666666 4.140526666666666 6.166666666666666 4.416666666666666 6.166666666666666L4.75 6.166666666666666C5.02614 6.166666666666666 5.25 6.390526666666666 5.25 6.666666666666666z"
3052
+ fill="currentColor"></path>
3053
+ <path
3054
+ d="M6.25 9.333333333333332C6.25 9.609466666666666 6.02614 9.833333333333332 5.75 9.833333333333332L5.416666666666666 9.833333333333332C5.140526666666666 9.833333333333332 4.916666666666666 9.609466666666666 4.916666666666666 9.333333333333332C4.916666666666666 9.0572 5.140526666666666 8.833333333333332 5.416666666666666 8.833333333333332L5.75 8.833333333333332C6.02614 8.833333333333332 6.25 9.0572 6.25 9.333333333333332z"
3055
+ fill="currentColor"></path>
3056
+ </svg>
3057
+ <span>${archive.stat.danmaku}</span>
3058
+ </div>
3059
+ </div>
3060
+ </div>
3061
+ </div>
3062
+ `;
3063
+ break;
3064
+ }
3065
+ case DYNAMIC_TYPE_LIVE: return [`${upName}发起了直播预约,我暂时无法渲染,请自行查看`];
3066
+ case DYNAMIC_TYPE_MEDIALIST: return [`${upName}分享了收藏夹,我暂时无法渲染,请自行查看`];
3067
+ case DYNAMIC_TYPE_PGC: return [`${upName}发布了剧集(番剧、电影、纪录片),我暂时无法渲染,请自行查看`];
3068
+ case DYNAMIC_TYPE_ARTICLE:
3069
+ if (this.giConfig.filter.enable && this.giConfig.filter.article) throw new Error("已屏蔽专栏动态");
3070
+ return [`${upName}投稿了新专栏,我暂时无法渲染,请自行查看`];
3071
+ case DYNAMIC_TYPE_MUSIC: return [`${upName}发行了新歌,我暂时无法渲染,请自行查看`];
3072
+ case DYNAMIC_TYPE_COMMON_SQUARE: return [`${upName}发布了装扮|剧集|点评|普通分享,我暂时无法渲染,请自行查看`];
3073
+ case DYNAMIC_TYPE_COURSES_SEASON: return [`${upName}发布了新课程,我暂时无法渲染,请自行查看`];
3074
+ case DYNAMIC_TYPE_UGC_SEASON: return [`${upName}更新了合集,我暂时无法渲染,请自行查看`];
3075
+ case DYNAMIC_TYPE_NONE: return [`${upName}发布了一条无效动态`];
3076
+ case DYNAMIC_TYPE_LIVE_RCMD: throw new Error("直播开播动态,不做处理");
3077
+ default: return [`${upName}发布了一条我无法识别的动态,请自行查看`];
3078
+ }
3079
+ return [main$1, forwardInfo];
3080
+ };
3081
+ const [main] = await getDynamicMajor(data, false);
3420
3082
  const html = `
3421
3083
  <!DOCTYPE html>
3422
3084
  <html>
3423
3085
  <head>
3424
3086
  <title>动态通知</title>
3425
3087
  <style>
3426
- ${style}
3088
+ ${this.generateCardStyle(this.giConfig.enableLargeFont, cardColorStart, cardColorEnd, cardBasePlateBorder, cardBasePlateColor, dynamicCardColor ?? "#FFFFFF")}
3427
3089
  </style>
3428
3090
  </head>
3429
3091
  <body>
@@ -3800,6 +3462,15 @@ var BiliAPI = class extends koishi.Service {
3800
3462
  updateJob;
3801
3463
  pRetry;
3802
3464
  AbortError;
3465
+ RETRY_CONFIG = { retries: 3 };
3466
+ async retryWithLog(fn, methodName) {
3467
+ return this.pRetry(fn, {
3468
+ onFailedAttempt: (error) => {
3469
+ this.logger.error(`主人呜呜 (;>_<) 女仆在执行 ${methodName}() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
3470
+ },
3471
+ ...this.RETRY_CONFIG
3472
+ });
3473
+ }
3803
3474
  constructor(ctx, config) {
3804
3475
  super(ctx, "bilibili-notify-api");
3805
3476
  this.apiConfig = config;
@@ -3869,82 +3540,46 @@ var BiliAPI = class extends koishi.Service {
3869
3540
  return Buffer.concat([decipher.update(encryptedText), decipher.final()]).toString();
3870
3541
  }
3871
3542
  async getTheUserWhoIsLiveStreaming() {
3872
- const run = async () => {
3543
+ return this.retryWithLog(async () => {
3873
3544
  const { data } = await this.client.get(GET_LATEST_UPDATED_UPS);
3874
3545
  return data;
3875
- };
3876
- return await this.pRetry(run, {
3877
- onFailedAttempt: (error) => {
3878
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getTheUserWhoIsLiveStreaming() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
3879
- },
3880
- retries: 3
3881
- });
3546
+ }, "getTheUserWhoIsLiveStreaming");
3882
3547
  }
3883
3548
  async getLiveRoomInfoStreamKey(roomId) {
3884
- const run = async () => {
3549
+ return this.retryWithLog(async () => {
3885
3550
  const { data } = await this.client.get(`${GET_LIVE_ROOM_INFO_STREAM_KEY}?id=${roomId}`);
3886
3551
  return data;
3887
- };
3888
- return await this.pRetry(run, {
3889
- onFailedAttempt: (error) => {
3890
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getLiveRoomInfoStreamKey() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
3891
- },
3892
- retries: 3
3893
- });
3552
+ }, "getLiveRoomInfoStreamKey");
3894
3553
  }
3895
3554
  async getLiveRoomInfoByUids(uids) {
3896
- const run = async () => {
3555
+ return this.retryWithLog(async () => {
3897
3556
  const params = uids.map((uid) => `uids[]=${uid}`).join("&");
3898
3557
  const { data } = await this.client.get(`${GET_LIVE_ROOMS_INFO}?${params}`);
3899
3558
  return data;
3900
- };
3901
- return await this.pRetry(run, {
3902
- onFailedAttempt: (error) => {
3903
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getLiveRoomInfoByUids() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
3904
- },
3905
- retries: 3
3906
- });
3559
+ }, "getLiveRoomInfoByUids");
3907
3560
  }
3908
3561
  async getServerUTCTime() {
3909
- const run = async () => {
3562
+ return this.retryWithLog(async () => {
3910
3563
  const { data } = await this.client.get(GET_SERVER_UTC_TIME);
3911
3564
  const match = data.match(/Date\.UTC\((.*?)\)/);
3912
3565
  if (match) return new Function(`return Date.UTC(${match[1]})`)() / 1e3;
3913
3566
  throw new this.AbortError("解析服务器时间失败!");
3914
- };
3915
- return await this.pRetry(run, {
3916
- onFailedAttempt: (error) => {
3917
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getServerUTCTime() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
3918
- },
3919
- retries: 3
3920
- });
3567
+ }, "getServerUTCTime");
3921
3568
  }
3922
3569
  async getTimeNow() {
3923
- const run = async () => {
3570
+ return this.retryWithLog(async () => {
3924
3571
  const { data } = await this.client.get(GET_TIME_NOW);
3925
3572
  return data;
3926
- };
3927
- return await this.pRetry(run, {
3928
- onFailedAttempt: (error) => {
3929
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getTimeNow() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
3930
- },
3931
- retries: 3
3932
- });
3573
+ }, "getTimeNow");
3933
3574
  }
3934
3575
  async getAllGroup() {
3935
- const run = async () => {
3576
+ return this.retryWithLog(async () => {
3936
3577
  const { data } = await this.client.get(GET_ALL_GROUP);
3937
3578
  return data;
3938
- };
3939
- return await this.pRetry(run, {
3940
- onFailedAttempt: (error) => {
3941
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getAllGroup() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
3942
- },
3943
- retries: 3
3944
- });
3579
+ }, "getAllGroup");
3945
3580
  }
3946
3581
  async removeUserFromGroup(mid) {
3947
- const run = async () => {
3582
+ return this.retryWithLog(async () => {
3948
3583
  const csrf = this.getCSRF();
3949
3584
  const { data } = await this.client.post(MODIFY_GROUP_MEMBER, {
3950
3585
  fids: mid,
@@ -3952,16 +3587,10 @@ var BiliAPI = class extends koishi.Service {
3952
3587
  csrf
3953
3588
  }, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
3954
3589
  return data;
3955
- };
3956
- return await this.pRetry(run, {
3957
- onFailedAttempt: (error) => {
3958
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 removeUserFromGroup() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
3959
- },
3960
- retries: 3
3961
- });
3590
+ }, "removeUserFromGroup");
3962
3591
  }
3963
3592
  async copyUserToGroup(mid, groupId) {
3964
- const run = async () => {
3593
+ return this.retryWithLog(async () => {
3965
3594
  const csrf = this.getCSRF();
3966
3595
  const { data } = await this.client.post(COPY_USER_TO_GROUP, {
3967
3596
  fids: mid,
@@ -3969,67 +3598,37 @@ var BiliAPI = class extends koishi.Service {
3969
3598
  csrf
3970
3599
  }, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
3971
3600
  return data;
3972
- };
3973
- return await this.pRetry(run, {
3974
- onFailedAttempt: (error) => {
3975
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 copyUserToGroup() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
3976
- },
3977
- retries: 3
3978
- });
3601
+ }, "copyUserToGroup");
3979
3602
  }
3980
3603
  async getUserSpaceDynamic(mid) {
3981
- const run = async () => {
3604
+ return this.retryWithLog(async () => {
3982
3605
  const { data } = await this.client.get(`${GET_USER_SPACE_DYNAMIC_LIST}&host_mid=${mid}`);
3983
3606
  return data;
3984
- };
3985
- return await this.pRetry(run, {
3986
- onFailedAttempt: (error) => {
3987
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getUserSpaceDynamic() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
3988
- },
3989
- retries: 3
3990
- });
3607
+ }, "getUserSpaceDynamic");
3991
3608
  }
3992
3609
  async createGroup(tag) {
3993
- const run = async () => {
3610
+ return this.retryWithLog(async () => {
3994
3611
  const { data } = await this.client.post(CREATE_GROUP, {
3995
3612
  tag,
3996
3613
  csrf: this.getCSRF()
3997
3614
  }, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
3998
3615
  return data;
3999
- };
4000
- return await this.pRetry(run, {
4001
- onFailedAttempt: (error) => {
4002
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 createGroup() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4003
- },
4004
- retries: 3
4005
- });
3616
+ }, "createGroup");
4006
3617
  }
4007
3618
  async getAllDynamic() {
4008
- const run = async () => {
3619
+ return this.retryWithLog(async () => {
4009
3620
  const { data } = await this.client.get(GET_ALL_DYNAMIC_LIST);
4010
3621
  return data;
4011
- };
4012
- return await this.pRetry(run, {
4013
- onFailedAttempt: (error) => {
4014
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getAllDynamic() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4015
- },
4016
- retries: 3
4017
- });
3622
+ }, "getAllDynamic");
4018
3623
  }
4019
3624
  async hasNewDynamic(updateBaseline) {
4020
- const run = async () => {
3625
+ return this.retryWithLog(async () => {
4021
3626
  const { data } = await this.client.get(`${HAS_NEW_DYNAMIC}?update_baseline=${updateBaseline}`);
4022
3627
  return data;
4023
- };
4024
- return await this.pRetry(run, {
4025
- onFailedAttempt: (error) => {
4026
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 hasNewDynamic()时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4027
- },
4028
- retries: 3
4029
- });
3628
+ }, "hasNewDynamic");
4030
3629
  }
4031
3630
  async follow(fid) {
4032
- const run = async () => {
3631
+ return this.retryWithLog(async () => {
4033
3632
  const { data } = await this.client.post(MODIFY_RELATION, {
4034
3633
  fid,
4035
3634
  act: 1,
@@ -4037,43 +3636,25 @@ var BiliAPI = class extends koishi.Service {
4037
3636
  csrf: this.getCSRF()
4038
3637
  }, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
4039
3638
  return data;
4040
- };
4041
- return await this.pRetry(run, {
4042
- onFailedAttempt: (error) => {
4043
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 follow() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4044
- },
4045
- retries: 3
4046
- });
3639
+ }, "follow");
4047
3640
  }
4048
3641
  async getRelationGroupDetail(tagid) {
4049
- const run = async () => {
3642
+ return this.retryWithLog(async () => {
4050
3643
  const { data } = await this.client.get(`${GET_RELATION_GROUP_DETAIL}?tagid=${tagid}`);
4051
3644
  return data;
4052
- };
4053
- return await this.pRetry(run, {
4054
- onFailedAttempt: (error) => {
4055
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getRelationGroupDetail() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4056
- },
4057
- retries: 3
4058
- });
3645
+ }, "getRelationGroupDetail");
4059
3646
  }
4060
3647
  async getCookieInfo(refreshToken) {
4061
- const run = async () => {
3648
+ return this.retryWithLog(async () => {
4062
3649
  const { data } = await this.client.get(`${GET_COOKIES_INFO}?csrf=${refreshToken}`).catch((e) => {
4063
3650
  this.logger.info(e.message);
4064
3651
  return null;
4065
3652
  });
4066
3653
  return data;
4067
- };
4068
- return await this.pRetry(run, {
4069
- onFailedAttempt: (error) => {
4070
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getCookieInfo() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4071
- },
4072
- retries: 3
4073
- });
3654
+ }, "getCookieInfo");
4074
3655
  }
4075
3656
  async getUserInfo(mid, grisk_id) {
4076
- const run = async () => {
3657
+ return this.retryWithLog(async () => {
4077
3658
  if (mid === "11783021") {
4078
3659
  console.log("检测到番剧出差UID,跳过远程用户接口访问");
4079
3660
  return bangumiTripData;
@@ -4083,139 +3664,73 @@ var BiliAPI = class extends koishi.Service {
4083
3664
  const wbi = await this.getWbi(params);
4084
3665
  const { data } = await this.client.get(`${GET_USER_INFO}?${wbi}`);
4085
3666
  return data;
4086
- };
4087
- return await this.pRetry(run, {
4088
- onFailedAttempt: (error) => {
4089
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getUserInfo() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4090
- },
4091
- retries: 3
4092
- });
3667
+ }, "getUserInfo");
4093
3668
  }
4094
3669
  async getWbiKeys() {
4095
- const run = async () => {
3670
+ return this.retryWithLog(async () => {
4096
3671
  const { data } = await this.client.get("https://api.bilibili.com/x/web-interface/nav");
4097
3672
  const { data: { wbi_img: { img_url, sub_url } } } = data;
4098
3673
  return {
4099
3674
  img_key: img_url.slice(img_url.lastIndexOf("/") + 1, img_url.lastIndexOf(".")),
4100
3675
  sub_key: sub_url.slice(sub_url.lastIndexOf("/") + 1, sub_url.lastIndexOf("."))
4101
3676
  };
4102
- };
4103
- return await this.pRetry(run, {
4104
- onFailedAttempt: (error) => {
4105
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getWbiKeys() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4106
- },
4107
- retries: 3
4108
- });
3677
+ }, "getWbiKeys");
4109
3678
  }
4110
3679
  async getMyselfInfo() {
4111
- const run = async () => {
3680
+ return this.retryWithLog(async () => {
4112
3681
  const { data } = await this.client.get(GET_MYSELF_INFO);
4113
3682
  return data;
4114
- };
4115
- return await this.pRetry(run, {
4116
- onFailedAttempt: (error) => {
4117
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getMyselfInfo() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4118
- },
4119
- retries: 3
4120
- });
3683
+ }, "getMyselfInfo");
4121
3684
  }
4122
3685
  async getLoginQRCode() {
4123
- const run = async () => {
3686
+ return this.retryWithLog(async () => {
4124
3687
  const { data } = await this.client.get(GET_LOGIN_QRCODE);
4125
3688
  return data;
4126
- };
4127
- return await this.pRetry(run, {
4128
- onFailedAttempt: (error) => {
4129
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getLoginQRCode() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4130
- },
4131
- retries: 3
4132
- });
3689
+ }, "getLoginQRCode");
4133
3690
  }
4134
3691
  async getLoginStatus(qrcodeKey) {
4135
- const run = async () => {
3692
+ return this.retryWithLog(async () => {
4136
3693
  const { data } = await this.client.get(`${GET_LOGIN_STATUS}?qrcode_key=${qrcodeKey}`);
4137
3694
  return data;
4138
- };
4139
- return await this.pRetry(run, {
4140
- onFailedAttempt: (error) => {
4141
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getLoginStatus() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4142
- },
4143
- retries: 3
4144
- });
3695
+ }, "getLoginStatus");
4145
3696
  }
4146
3697
  async getLiveRoomInfo(roomId) {
4147
- const run = async () => {
3698
+ return this.retryWithLog(async () => {
4148
3699
  const { data } = await this.client.get(`${GET_LIVE_ROOM_INFO}?room_id=${roomId}`);
4149
3700
  return data;
4150
- };
4151
- return await this.pRetry(run, {
4152
- onFailedAttempt: (error) => {
4153
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getLiveRoomInfo() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4154
- },
4155
- retries: 3
4156
- });
3701
+ }, "getLiveRoomInfo");
4157
3702
  }
4158
3703
  async getMasterInfo(mid) {
4159
- const run = async () => {
3704
+ return this.retryWithLog(async () => {
4160
3705
  const { data } = await this.client.get(`${GET_MASTER_INFO}?uid=${mid}`);
4161
3706
  return data;
4162
- };
4163
- return await this.pRetry(run, {
4164
- onFailedAttempt: (error) => {
4165
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getMasterInfo() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4166
- },
4167
- retries: 3
4168
- });
3707
+ }, "getMasterInfo");
4169
3708
  }
4170
3709
  async getOnlineGoldRank(roomId, ruid, page = 1, pageSize = 20) {
4171
- const run = async () => {
3710
+ return this.retryWithLog(async () => {
4172
3711
  const { data } = await this.client.get(`${GET_ONLINE_GOLD_RANK}?room_id=${roomId}&ruid=${ruid}&page=${page}&page_size=${pageSize}`);
4173
3712
  return data;
4174
- };
4175
- return await this.pRetry(run, {
4176
- onFailedAttempt: (error) => {
4177
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getOnlineGoldRank() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4178
- },
4179
- retries: 3
4180
- });
3713
+ }, "getOnlineGoldRank");
4181
3714
  }
4182
3715
  async getUserInfoInLive(uid, ruid) {
4183
- const run = async () => {
3716
+ return this.retryWithLog(async () => {
4184
3717
  const { data } = await this.client.get(`${GET_USER_INFO_IN_LIVE}?uid=${uid}&ruid=${ruid}`);
4185
3718
  return data;
4186
- };
4187
- return await this.pRetry(run, {
4188
- onFailedAttempt: (error) => {
4189
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getUserInfoInLive() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4190
- },
4191
- retries: 3
4192
- });
3719
+ }, "getUserInfoInLive");
4193
3720
  }
4194
3721
  async getUserCardInfo(mid, photo) {
4195
- const run = async () => {
3722
+ return this.retryWithLog(async () => {
4196
3723
  let url = `${GET_USER_CARD_INFO}?mid=${mid}`;
4197
3724
  if (photo) url += "&photo=true";
4198
3725
  const { data } = await this.client.get(url);
4199
3726
  return data;
4200
- };
4201
- return await this.pRetry(run, {
4202
- onFailedAttempt: (error) => {
4203
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getUserInfoInLive() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4204
- },
4205
- retries: 3
4206
- });
3727
+ }, "getUserCardInfo");
4207
3728
  }
4208
3729
  async getCORSContent(url) {
4209
- const run = async () => {
3730
+ return this.retryWithLog(async () => {
4210
3731
  const { data } = await this.client.get(url);
4211
3732
  return data;
4212
- };
4213
- return await this.pRetry(run, {
4214
- onFailedAttempt: (error) => {
4215
- this.logger.error(`主人呜呜 (;>_<) 女仆在执行 getUserInfoInLive() 时第 ${error.attemptNumber} 次失败啦~原因:${error.message},请主人帮女仆看看呀 (>ω<)♡`);
4216
- },
4217
- retries: 3
4218
- });
3733
+ }, "getCORSContent");
4219
3734
  }
4220
3735
  async chatWithAI(content) {
4221
3736
  return await this.aiClient.chat.completions.create({
@@ -4317,6 +3832,10 @@ var BiliAPI = class extends koishi.Service {
4317
3832
  getLoginInfoIsLoaded() {
4318
3833
  return this.loginInfoIsLoaded;
4319
3834
  }
3835
+ parseExpires(expires) {
3836
+ if (!expires || expires === "Infinity") return "Infinity";
3837
+ return luxon.DateTime.fromISO(expires).toJSDate();
3838
+ }
4320
3839
  async getLoginInfoFromDB() {
4321
3840
  const data = (await this.ctx.database.get("loginBili", 1))[0];
4322
3841
  if (data === void 0) {
@@ -4357,32 +3876,13 @@ var BiliAPI = class extends koishi.Service {
4357
3876
  this.loginInfoIsLoaded = true;
4358
3877
  return;
4359
3878
  }
4360
- let csrf;
4361
- let expires;
4362
- let domain;
4363
- let path;
4364
- let secure;
4365
- let httpOnly;
4366
- let sameSite;
3879
+ const biliJctCookie = cookies.find((c) => c.key === "bili_jct");
3880
+ let csrf = biliJctCookie?.value ?? "";
4367
3881
  for (const cookieData of cookies) {
4368
- if (cookieData.key === "bili_jct") {
4369
- csrf = cookieData.value;
4370
- expires = cookieData.expires ? luxon.DateTime.fromISO(cookieData.expires).toJSDate() : "Infinity";
4371
- domain = cookieData.domain;
4372
- path = cookieData.path;
4373
- secure = cookieData.secure;
4374
- httpOnly = cookieData.httpOnly;
4375
- sameSite = cookieData.sameSite;
4376
- }
4377
- const cdExpires = (() => {
4378
- if (!cookieData.expires) return "Infinity";
4379
- if (cookieData.expires !== "Infinity") return luxon.DateTime.fromISO(cookieData.expires).toJSDate();
4380
- return cookieData.expires;
4381
- })();
4382
3882
  const cookie = new tough_cookie.Cookie({
4383
3883
  key: cookieData.key,
4384
3884
  value: cookieData.value,
4385
- expires: cdExpires,
3885
+ expires: this.parseExpires(cookieData.expires),
4386
3886
  domain: cookieData.domain,
4387
3887
  path: cookieData.path,
4388
3888
  secure: cookieData.secure,
@@ -4391,17 +3891,20 @@ var BiliAPI = class extends koishi.Service {
4391
3891
  });
4392
3892
  this.jar.setCookieSync(cookie, `http${cookie.secure ? "s" : ""}://${cookie.domain}${cookie.path}`);
4393
3893
  }
4394
- const buvid3Cookie = new tough_cookie.Cookie({
4395
- key: "buvid3",
4396
- value: "some_non_empty_value",
4397
- expires,
4398
- domain,
4399
- path,
4400
- secure,
4401
- httpOnly,
4402
- sameSite
4403
- });
4404
- this.jar.setCookieSync(buvid3Cookie, `http${buvid3Cookie.secure ? "s" : ""}://${buvid3Cookie.domain}${buvid3Cookie.path}`);
3894
+ if (biliJctCookie) {
3895
+ csrf = biliJctCookie.value;
3896
+ const buvid3Cookie = new tough_cookie.Cookie({
3897
+ key: "buvid3",
3898
+ value: "some_non_empty_value",
3899
+ expires: this.parseExpires(biliJctCookie.expires),
3900
+ domain: biliJctCookie.domain,
3901
+ path: biliJctCookie.path,
3902
+ secure: biliJctCookie.secure,
3903
+ httpOnly: biliJctCookie.httpOnly,
3904
+ sameSite: biliJctCookie.sameSite
3905
+ });
3906
+ this.jar.setCookieSync(buvid3Cookie, `http${buvid3Cookie.secure ? "s" : ""}://${buvid3Cookie.domain}${buvid3Cookie.path}`);
3907
+ }
4405
3908
  this.loginInfoIsLoaded = true;
4406
3909
  this.checkIfTokenNeedRefresh(refresh_token, csrf);
4407
3910
  this.enableRefreshCookiesDetect();
@@ -4411,10 +3914,8 @@ var BiliAPI = class extends koishi.Service {
4411
3914
  this.refreshCookieTimer = this.ctx.setInterval(async () => {
4412
3915
  const { cookies, refresh_token } = await this.getLoginInfoFromDB();
4413
3916
  if (!cookies || !refresh_token) return;
4414
- const csrf = cookies.find((cookie) => {
4415
- if (cookie.key === "bili_jct") return true;
4416
- return false;
4417
- }).value;
3917
+ const csrf = cookies.find((cookie) => cookie.key === "bili_jct")?.value;
3918
+ if (!csrf) return;
4418
3919
  this.checkIfTokenNeedRefresh(refresh_token, csrf);
4419
3920
  }, 36e5);
4420
3921
  }
@@ -4472,10 +3973,8 @@ var BiliAPI = class extends koishi.Service {
4472
3973
  bili_cookies: encryptedCookies,
4473
3974
  bili_refresh_token: encryptedRefreshToken
4474
3975
  }]);
4475
- const newCsrf = this.jar.serializeSync().cookies.find((cookie) => {
4476
- if (cookie.key === "bili_jct") return true;
4477
- return false;
4478
- }).value;
3976
+ const newCsrf = this.jar.serializeSync().cookies.find((cookie) => cookie.key === "bili_jct")?.value;
3977
+ if (!newCsrf) throw new Error("未找到 bili_jct cookie");
4479
3978
  const { data: aceeptData } = await this.client.post("https://passport.bilibili.com/x/passport-login/web/confirm/refresh", {
4480
3979
  csrf: newCsrf,
4481
3980
  refresh_token: refreshToken