koishi-plugin-dew-bot 1.0.263 → 1.0.264
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.
- package/README.md +7 -1
- package/assets/official-qq-group.jpg +0 -0
- package/assets/signin-portraits/01-bunny-hostess.webp +0 -0
- package/assets/signin-portraits/02-forest-mage.webp +0 -0
- package/assets/signin-portraits/03-silver-goddess.webp +0 -0
- package/assets/signin-portraits/04-blue-knight.webp +0 -0
- package/assets/signin-portraits/05-steampunk-engineer.webp +0 -0
- package/assets/signin-portraits/06-naval-officer.webp +0 -0
- package/assets/signin-portraits/07-jade-qipao.webp +0 -0
- package/assets/signin-portraits/08-violet-mage.webp +0 -0
- package/assets/signin-portraits/09-ivory-adventurer.webp +0 -0
- package/assets/signin-portraits/10-sakura-kimono.webp +0 -0
- package/assets/signin-portraits/11-red-velvet-lady.webp +0 -0
- package/assets/signin-portraits/12-elven-ranger.webp +0 -0
- package/assets/signin-portraits/13-black-tuxedo.webp +0 -0
- package/assets/signin-portraits/14-ocean-blue-lady.webp +0 -0
- package/assets/signin-portraits/15-amber-witch.webp +0 -0
- package/assets/signin-portraits/16-classic-maid.webp +0 -0
- package/assets/signin-portraits/17-ice-blue-winter.webp +0 -0
- package/assets/signin-portraits/18-violet-office.webp +0 -0
- package/assets/signin-portraits/19-sapphire-gown.webp +0 -0
- package/assets/signin-portraits/20-silver-tech-jacket.webp +0 -0
- package/assets/signin-portraits/21-desert-linen.webp +0 -0
- package/assets/signin-portraits/22-forest-ranger.webp +0 -0
- package/assets/signin-portraits/23-moonlight-hanfu.webp +0 -0
- package/assets/signin-portraits/24-white-uniform.webp +0 -0
- package/assets/signin-portraits/25-gothic-lace.webp +0 -0
- package/assets/signin-portraits/26-orange-racer.webp +0 -0
- package/assets/signin-portraits/27-blue-alchemist.webp +0 -0
- package/assets/signin-portraits/28-rose-leather.webp +0 -0
- package/assets/signin-portraits/29-lilac-elf.webp +0 -0
- package/assets/signin-portraits/30-sun-gown.webp +0 -0
- package/assets/signin-portraits/31-pirate-captain.webp +0 -0
- package/assets/signin-portraits/32-green-scholar.webp +0 -0
- package/assets/signin-portraits/33-blue-streetwear.webp +0 -0
- package/assets/signin-portraits/34-cream-ballgown.webp +0 -0
- package/assets/signin-portraits/35-white-coat.webp +0 -0
- package/assets/signin-portraits/36-emerald-priestess.webp +0 -0
- package/assets/signin-portraits/37-peach-floral.webp +0 -0
- package/assets/signin-portraits/38-casino-hostess.webp +0 -0
- package/assets/signin-portraits/39-red-gold-armor.webp +0 -0
- package/assets/signin-portraits/40-opera-gown.webp +0 -0
- package/assets/signin-portraits/41-teal-officer.webp +0 -0
- package/assets/signin-portraits/42-guild-uniform.webp +0 -0
- package/assets/signin-portraits/43-charcoal-qipao.webp +0 -0
- package/assets/signin-portraits/44-sci-fi-pilot.webp +0 -0
- package/assets/signin-portraits/45-athlete-jacket.webp +0 -0
- package/assets/signin-portraits/46-teal-traditional.webp +0 -0
- package/assets/signin-portraits/47-violet-queen.webp +0 -0
- package/assets/signin-portraits/48-magic-explorer.webp +0 -0
- package/assets/signin-portraits/49-red-floral-qipao.webp +0 -0
- package/assets/signin-portraits/50-summer-dress.webp +0 -0
- package/lib/index.js +605 -27
- package/lib/plugin/signinCardAssets.d.ts +9 -0
- package/lib/plugin/signinCardStyles.d.ts +2 -0
- package/lib/plugin/signinCardTemplate.d.ts +9 -0
- package/lib/plugin/signinPortraits.d.ts +8 -0
- package/lib/plugin/skillCard.d.ts +2 -1
- package/lib/shared/face/index.d.ts +17 -0
- package/package.json +1 -1
- package/src/plugin/cardLayout.ts +22 -0
- package/src/plugin/equipmentCardTemplate.ts +1 -1
- package/src/plugin/serverHandel/handel_base.ts +2 -2
- package/src/plugin/serverHandel/image.ts +2 -2
- package/src/plugin/serverHandel/qqMessagePreview.ts +1 -0
- package/src/plugin/signinCardAssets.ts +63 -0
- package/src/plugin/signinCardStyles.ts +48 -0
- package/src/plugin/signinCardTemplate.ts +42 -0
- package/src/plugin/signinPortraits.ts +310 -0
- package/src/plugin/skillCard.ts +27 -12
- package/src/plugin/skillCardTemplate.ts +0 -1
- package/src/shared/bot/serviceProto.ts +92 -1
- package/src/shared/face/index.ts +18 -0
package/lib/index.js
CHANGED
|
@@ -67,7 +67,7 @@ var serviceProto;
|
|
|
67
67
|
var init_serviceProto = __esm({
|
|
68
68
|
"src/shared/bot/serviceProto.ts"() {
|
|
69
69
|
serviceProto = {
|
|
70
|
-
"version":
|
|
70
|
+
"version": 41,
|
|
71
71
|
"services": [
|
|
72
72
|
{
|
|
73
73
|
"id": 0,
|
|
@@ -307,6 +307,23 @@ var init_serviceProto = __esm({
|
|
|
307
307
|
}
|
|
308
308
|
},
|
|
309
309
|
"optional": true
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"id": 18,
|
|
313
|
+
"name": "plainText",
|
|
314
|
+
"type": {
|
|
315
|
+
"type": "Boolean"
|
|
316
|
+
},
|
|
317
|
+
"optional": true
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"id": 19,
|
|
321
|
+
"name": "signinCard",
|
|
322
|
+
"type": {
|
|
323
|
+
"type": "Reference",
|
|
324
|
+
"target": "messageFace/SigninCardData"
|
|
325
|
+
},
|
|
326
|
+
"optional": true
|
|
310
327
|
}
|
|
311
328
|
]
|
|
312
329
|
},
|
|
@@ -1970,6 +1987,80 @@ var init_serviceProto = __esm({
|
|
|
1970
1987
|
}
|
|
1971
1988
|
]
|
|
1972
1989
|
},
|
|
1990
|
+
"messageFace/SigninCardData": {
|
|
1991
|
+
"type": "Interface",
|
|
1992
|
+
"properties": [
|
|
1993
|
+
{
|
|
1994
|
+
"id": 0,
|
|
1995
|
+
"name": "cycleDays",
|
|
1996
|
+
"type": {
|
|
1997
|
+
"type": "Number"
|
|
1998
|
+
}
|
|
1999
|
+
},
|
|
2000
|
+
{
|
|
2001
|
+
"id": 1,
|
|
2002
|
+
"name": "completedDays",
|
|
2003
|
+
"type": {
|
|
2004
|
+
"type": "Number"
|
|
2005
|
+
}
|
|
2006
|
+
},
|
|
2007
|
+
{
|
|
2008
|
+
"id": 2,
|
|
2009
|
+
"name": "portraitId",
|
|
2010
|
+
"type": {
|
|
2011
|
+
"type": "Number"
|
|
2012
|
+
}
|
|
2013
|
+
},
|
|
2014
|
+
{
|
|
2015
|
+
"id": 3,
|
|
2016
|
+
"name": "days",
|
|
2017
|
+
"type": {
|
|
2018
|
+
"type": "Array",
|
|
2019
|
+
"elementType": {
|
|
2020
|
+
"type": "Interface",
|
|
2021
|
+
"properties": [
|
|
2022
|
+
{
|
|
2023
|
+
"id": 0,
|
|
2024
|
+
"name": "day",
|
|
2025
|
+
"type": {
|
|
2026
|
+
"type": "Number"
|
|
2027
|
+
}
|
|
2028
|
+
},
|
|
2029
|
+
{
|
|
2030
|
+
"id": 1,
|
|
2031
|
+
"name": "itemId",
|
|
2032
|
+
"type": {
|
|
2033
|
+
"type": "String"
|
|
2034
|
+
}
|
|
2035
|
+
},
|
|
2036
|
+
{
|
|
2037
|
+
"id": 2,
|
|
2038
|
+
"name": "name",
|
|
2039
|
+
"type": {
|
|
2040
|
+
"type": "String"
|
|
2041
|
+
}
|
|
2042
|
+
},
|
|
2043
|
+
{
|
|
2044
|
+
"id": 3,
|
|
2045
|
+
"name": "count",
|
|
2046
|
+
"type": {
|
|
2047
|
+
"type": "Number"
|
|
2048
|
+
}
|
|
2049
|
+
},
|
|
2050
|
+
{
|
|
2051
|
+
"id": 4,
|
|
2052
|
+
"name": "artworkUrl",
|
|
2053
|
+
"type": {
|
|
2054
|
+
"type": "String"
|
|
2055
|
+
},
|
|
2056
|
+
"optional": true
|
|
2057
|
+
}
|
|
2058
|
+
]
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
]
|
|
2063
|
+
},
|
|
1973
2064
|
"PtlMessage/ReqMessage": {
|
|
1974
2065
|
"type": "Interface",
|
|
1975
2066
|
"extends": [
|
|
@@ -2777,7 +2868,7 @@ function flower(x, y, scale) {
|
|
|
2777
2868
|
return `<g transform="translate(${x} ${y}) scale(${scale})">${petals}${inner}<circle r="3.4" fill="var(--accent)" stroke="#fffefa" stroke-width=".8"/>${stamens}</g>`;
|
|
2778
2869
|
}
|
|
2779
2870
|
__name(flower, "flower");
|
|
2780
|
-
var slimLeaf = /* @__PURE__ */ __name((
|
|
2871
|
+
var slimLeaf = /* @__PURE__ */ __name((path3, vein) => `<path d="${path3}" fill="url(#character-leaf)" stroke="var(--light-edge)" stroke-width="1.15"/><path d="${vein}" fill="none" stroke="var(--leaf-light)" stroke-width=".65"/>`, "slimLeaf");
|
|
2781
2872
|
function characterTierOrnament(tier) {
|
|
2782
2873
|
const leaves = `<g class="ornament-leaves"><path d="M13 151C7 105 10 51 39 25c25-20 66-15 103-17" fill="none" stroke="url(#character-metal)" stroke-width="3.6"/><path d="M13 150C10 90 17 42 48 24s69-13 97-15" fill="none" stroke="#fffefa" stroke-width=".65"/>${slimLeaf("M23 86C1 74 4 52 7 40c12 14 24 22 16 46Z", "M23 85 9 45")}${slimLeaf("M58 23C67 5 85 5 99 7 90 19 78 33 58 23Z", "M59 23 96 9")}</g>`;
|
|
2783
2874
|
const flowers = `<g class="ornament-flowers">${flower(34, 34, 0.87)}${slimLeaf("M33 68C34 47 50 44 60 39 57 57 46 69 33 68Z", "M34 67 57 43")}</g>`;
|
|
@@ -3222,6 +3313,31 @@ var import_node_crypto = require("node:crypto");
|
|
|
3222
3313
|
// src/plugin/cardLayout.ts
|
|
3223
3314
|
async function layoutCard(document2 = globalThis.document) {
|
|
3224
3315
|
await document2.fonts.ready;
|
|
3316
|
+
if (document2.getElementById("capture")?.classList.contains("signin-sheet")) {
|
|
3317
|
+
await Promise.all([...document2.querySelectorAll(".signin-item-art,.signin-item-glow,.signin-portrait-art")].map(async (image2) => {
|
|
3318
|
+
try {
|
|
3319
|
+
await image2.decode();
|
|
3320
|
+
} catch {
|
|
3321
|
+
image2.remove();
|
|
3322
|
+
}
|
|
3323
|
+
}));
|
|
3324
|
+
for (const label of document2.querySelectorAll(".signin-reward-label")) {
|
|
3325
|
+
const container = label.parentElement;
|
|
3326
|
+
const style = document2.defaultView.getComputedStyle(container);
|
|
3327
|
+
const available = container.clientWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight) - 1;
|
|
3328
|
+
const maximum = parseFloat(document2.defaultView.getComputedStyle(label).fontSize);
|
|
3329
|
+
let size = maximum;
|
|
3330
|
+
for (let attempt = 0; attempt < 6; attempt++) {
|
|
3331
|
+
const width = label.getBoundingClientRect().width;
|
|
3332
|
+
if (width <= available) break;
|
|
3333
|
+
size = Math.max(1, size * available / width * 0.98);
|
|
3334
|
+
label.style.fontSize = size + "px";
|
|
3335
|
+
label.style.gap = 3.79 * size / maximum + "px";
|
|
3336
|
+
label.style.webkitTextStrokeWidth = 1.14 * size / maximum + "px";
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3339
|
+
return;
|
|
3340
|
+
}
|
|
3225
3341
|
for (const name3 of document2.querySelectorAll("#character-name,#companion-name")) {
|
|
3226
3342
|
const style = document2.defaultView.getComputedStyle(name3);
|
|
3227
3343
|
const maximum = parseFloat(style.fontSize);
|
|
@@ -3415,8 +3531,8 @@ function leaderboardHtml(data, _headerImage, backgroundImage) {
|
|
|
3415
3531
|
__name(leaderboardHtml, "leaderboardHtml");
|
|
3416
3532
|
|
|
3417
3533
|
// src/plugin/skillCard.ts
|
|
3418
|
-
var
|
|
3419
|
-
var
|
|
3534
|
+
var import_promises2 = __toESM(require("node:fs/promises"));
|
|
3535
|
+
var import_node_path2 = __toESM(require("node:path"));
|
|
3420
3536
|
|
|
3421
3537
|
// src/plugin/skillCardTemplate.ts
|
|
3422
3538
|
var escape2 = /* @__PURE__ */ __name((value) => String(value ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]), "escape");
|
|
@@ -3457,7 +3573,6 @@ function skillCardHtml(card, _frame = "", artwork) {
|
|
|
3457
3573
|
<div class="card-inner"><header class="card-titlebar"><span class="title-glyph" aria-hidden="true">◇</span><h1>${escape2(card.name)}</h1><span class="title-star" aria-hidden="true">✦</span></header>
|
|
3458
3574
|
<div class="card-hero"><div class="hero-copy"><div class="hero-meta"><span class="skill-type">${card.passive ? "被动技能" : "主动技能"}</span><span class="quality-badge"><b>${quality}</b> 级</span></div><div class="tags">${tags.map((tag) => `<span class="tag ${tagClass(tag)}">${escape2(tag)}</span>`).join("")}</div></div><div class="hero-icon-wrap">${qualityMagicCircle(quality)}<div class="art-fallback" aria-hidden="true">${card.passive ? "静" : "势"}</div>${artwork ? `<img class="skill-artwork" alt="${escape2(card.name)}图标" src="${escape2(artwork)}">` : ""}${qualityIconFrame(quality)}</div></div>
|
|
3459
3575
|
<div class="card-body"><div class="effect-stats">
|
|
3460
|
-
${row("技能等级", `${escape2(card.level)} <small class="param-unit">/ ${escape2(card.maxLevel)}</small>`, true)}
|
|
3461
3576
|
${row("消耗", escape2(card.cost || "无消耗"), true)}
|
|
3462
3577
|
${row("冷却", cooldownValue, true)}
|
|
3463
3578
|
${power ? row("战力", escape2(power.replace(/^(?:🔥\s*)?战力\s*[::]\s*/, "")), true) : ""}
|
|
@@ -3481,7 +3596,7 @@ function equipmentCardHtml(card, artwork, unknownFallback = false) {
|
|
|
3481
3596
|
...card.referencePrice ? [cardStatRow("参考价格", card.referencePrice)] : []
|
|
3482
3597
|
].join("");
|
|
3483
3598
|
const affixes = card.affixes?.length ? '<div class="detail-list">' + card.affixes.map((affix) => cardStatRow(affix.name, affix.value)).join("") + "</div>" : '<p class="description">暂无附加属性</p>';
|
|
3484
|
-
const skills2 = card.skills?.length ? cardSection("附带技能", '<div class="detail-list">' + card.skills.map((skill) => cardStatRow(skill.name,
|
|
3599
|
+
const skills2 = card.skills?.length ? cardSection("附带技能", '<div class="detail-list">' + card.skills.map((skill) => cardStatRow(skill.name, "")).join("") + "</div>") : "";
|
|
3485
3600
|
const description = card.description?.trim() ? cardSection("装备描述", '<p class="description">' + cardEscape(card.description.trim()) + "</p>") : "";
|
|
3486
3601
|
const notes = card.notes?.filter((note) => note?.trim()).length ? cardSection("附加信息", '<p class="description">' + card.notes.filter((note) => note?.trim()).map((note) => cardEscape(note)).join("\n") + "</p>") : "";
|
|
3487
3602
|
return detailCardHtml({
|
|
@@ -3745,6 +3860,458 @@ async function loadCardEntryArtwork(card) {
|
|
|
3745
3860
|
}
|
|
3746
3861
|
__name(loadCardEntryArtwork, "loadCardEntryArtwork");
|
|
3747
3862
|
|
|
3863
|
+
// src/plugin/signinCardStyles.ts
|
|
3864
|
+
var signinCardStyles = `
|
|
3865
|
+
body { margin: 0; background: #edf0e4; }
|
|
3866
|
+
|
|
3867
|
+
#capture.signin-sheet { font-family: "Microsoft YaHei", "PingFang SC", sans-serif; padding: 22.72px 20.2px 30.3px; }
|
|
3868
|
+
#capture.signin-sheet * { box-sizing: border-box; }
|
|
3869
|
+
#capture.signin-sheet .signin-poster { width: 100%; max-width: 719.6px; margin: 0 auto; padding-top: 111.1px; color: #4b493f; }
|
|
3870
|
+
#capture.signin-sheet .signin-banner { position: relative; isolation: isolate; z-index: 1; height: 218.41px; padding: 35.35px 35.35px 27.77px; border-radius: 30.3px 30.3px 0 0; background: linear-gradient(108deg, #b5cb65, #c6d879 54%, #8daa5f); box-shadow: 0 -2.52px 0 #dbe6ab inset; }
|
|
3871
|
+
#capture.signin-sheet .signin-banner::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: radial-gradient(ellipse at 16% 0%, #e0eba778, transparent 48%), repeating-linear-gradient(45deg, #6b852c06 0 5.05px, transparent 5.05px 15.15px); }
|
|
3872
|
+
#capture.signin-sheet .signin-eyebrow { position: relative; z-index: 2; color: #47612e; font-size: 12.62px; font-weight: 700; letter-spacing: 4.42px; margin-bottom: 10.1px; }
|
|
3873
|
+
#capture.signin-sheet .signin-title { position: relative; z-index: 2; width: fit-content; margin: 0; font-size: 54.29px; font-weight: 900; letter-spacing: 2.52px; line-height: 1.2; color: #fffde8; -webkit-text-stroke: 1.39px #4a5c2e; paint-order: stroke fill; text-shadow: 0 3.79px 0 #566632, 0 6.31px 7.57px #71803c25; }
|
|
3874
|
+
#capture.signin-sheet .signin-progress { position: relative; z-index: 2; display: inline-flex; align-items: center; gap: 10.1px; margin-top: 20.2px; padding: 5.05px 15.15px 5.05px 10.1px; color: #fbf7d3; background: #4d642bcc; border-radius: 10.1px; font-size: 21.46px; font-weight: 700; line-height: 1.25; font-variant-numeric: tabular-nums; }
|
|
3875
|
+
#capture.signin-sheet .signin-progress svg { width: 22.72px; height: 22.72px; }
|
|
3876
|
+
#capture.signin-sheet .signin-progress small { font-size: 13.89px; font-weight: 400; opacity: .85; padding-left: 5.05px; }
|
|
3877
|
+
#capture.signin-sheet .signin-portrait { position: absolute; z-index: 0; inset: -107.31px -3.79px 0 auto; width: 366.11px; overflow: hidden; border: 0; padding: 0; background: none; }
|
|
3878
|
+
#capture.signin-sheet .signin-portrait::before { content: ""; position: absolute; width: 277.74px; height: 277.74px; right: 10.1px; bottom: -42.92px; border-radius: 50%; background: radial-gradient(circle, #e3e8b88c 0%, #9fba6e36 65%, transparent 70%); }
|
|
3879
|
+
#capture.signin-sheet .signin-portrait img { position: absolute; top: 0; left: -38%; width: 170%; max-width: none; height: auto; filter: drop-shadow(0 3.79px 3.79px #3f542415); }
|
|
3880
|
+
#capture.signin-sheet .signin-leaf { position: absolute; z-index: 1; width: 37.87px; height: 15.15px; border-radius: 100% 0 100% 0; background: #eff2ae70; transform: rotate(-32deg); }
|
|
3881
|
+
#capture.signin-sheet .leaf-a { top: 25.25px; left: 44%; }
|
|
3882
|
+
#capture.signin-sheet .leaf-b { top: 87.11px; left: 51%; width: 23.99px; height: 10.1px; transform: rotate(22deg); }
|
|
3883
|
+
#capture.signin-sheet .leaf-c { bottom: 40.4px; left: 46%; width: 55.55px; height: 22.72px; transform: rotate(-50deg); opacity: .6; }
|
|
3884
|
+
#capture.signin-sheet .signin-refresh { position: absolute; bottom: 21.46px; right: 25.25px; z-index: 2; display: flex; align-items: center; gap: 6.31px; padding: 5.05px 10.1px; border-radius: 6.31px; color: #35472f; background: #f8f8dddc; font-size: 13.89px; }
|
|
3885
|
+
#capture.signin-sheet .signin-refresh svg { width: 16.41px; height: 16.41px; }
|
|
3886
|
+
#capture.signin-sheet .signin-eyebrow, #capture.signin-sheet .signin-title, #capture.signin-sheet .signin-progress, #capture.signin-sheet .signin-refresh, #capture.signin-sheet .signin-leaf { pointer-events: none; }
|
|
3887
|
+
#capture.signin-sheet .signin-board { position: relative; z-index: 3; background: #f8f5ec; border-radius: 20.2px; padding: 18.94px; margin-top: -2.52px; box-shadow: 0 11.36px 35.35px #474c3220, 0 0 0 1.26px #d9d8cc; }
|
|
3888
|
+
#capture.signin-sheet .signin-seam { height: 0; border-top: 2.52px dashed #6d78555a; margin: -17.67px 5.05px 16.41px; }
|
|
3889
|
+
#capture.signin-sheet .signin-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 11.36px; }
|
|
3890
|
+
#capture.signin-sheet .signin-day { position: relative; display: flex; flex-direction: column; align-items: center; min-width: 0; aspect-ratio: .72; padding: 0; overflow: hidden; border: 0; border-radius: 11.36px; color: #615346; background: linear-gradient(158deg, #ead1a3, #f4e2c4 62%, #efe0ca); box-shadow: inset 0 0 0 1.26px #dfc49b70; font-family: inherit; transition: transform .15s ease, box-shadow .15s ease; }
|
|
3891
|
+
#capture.signin-sheet .signin-day::after { content: ""; position: absolute; inset: auto 0 0; height: 5.05px; background: linear-gradient(to right, #daa04d, #f0bc6c); }
|
|
3892
|
+
#capture.signin-sheet .signin-number { position: absolute; top: 6.31px; left: 8.84px; color: #fff9e5ce; font-size: 31.56px; font-weight: 400; letter-spacing: -1.89px; line-height: 1; }
|
|
3893
|
+
#capture.signin-sheet .signin-reward { display: flex; align-items: center; justify-content: center; flex: 1; min-height: 0; width: 100%; padding: 36.61px 6.31px 3.79px; }
|
|
3894
|
+
#capture.signin-sheet .signin-art-wrap { position: relative; isolation: isolate; display: block; width: 90.9px; height: 90.9px; max-width: 100%; flex-shrink: 0; }
|
|
3895
|
+
#capture.signin-sheet .signin-item-art { display: block; position: relative; width: 100%; height: 100%; max-width: 100%; object-fit: contain; border-radius: 24%; box-shadow: 0 3.79px 11.36px #68533416, inset 0 0 0 1.26px #fff9e936; }
|
|
3896
|
+
#capture.signin-sheet .signin-reward-info { display: flex; align-items: flex-end; justify-content: center; flex-shrink: 0; width: 100%; height: 37.87px; padding: 0 2.52px 11.36px; background: none; text-align: center; }
|
|
3897
|
+
#capture.signin-sheet .signin-reward-label { display: inline-flex; align-items: baseline; gap: 3.79px; flex-shrink: 0; color: #fff; font-size: 16.41px; font-weight: 600; line-height: 1; white-space: nowrap; -webkit-text-stroke: 1.14px #26231f; paint-order: stroke fill; text-shadow: 0 1.26px 1.26px #0004; }
|
|
3898
|
+
#capture.signin-sheet .signin-item-name { display: inline; color: inherit; font-size: inherit; font-weight: inherit; line-height: inherit; }
|
|
3899
|
+
#capture.signin-sheet .signin-quantity { display: inline; color: inherit; font-size: inherit; font-weight: inherit; line-height: inherit; font-variant-numeric: tabular-nums; }
|
|
3900
|
+
#capture.signin-sheet .signin-claimed-overlay { position: absolute; z-index: 4; inset: 0; background: #211e187d; pointer-events: none; }
|
|
3901
|
+
#capture.signin-sheet .signin-check { position: absolute; z-index: 5; inset: 0; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; color: #fff; opacity: .82; background: none; border: 0; box-shadow: none; pointer-events: none; }
|
|
3902
|
+
#capture.signin-sheet .signin-check svg { width: 52% !important; height: 52% !important; max-width: 68.17px; max-height: 68.17px; stroke-width: 3px; }
|
|
3903
|
+
|
|
3904
|
+
#capture.signin-sheet { box-sizing: border-box; width: 760px; background: linear-gradient(160deg, #edf1e5, #e8e9e0); }
|
|
3905
|
+
#capture.signin-sheet .signin-portrait.full-body img { width: 170%; left: -38%; top: 0; }
|
|
3906
|
+
#capture.signin-sheet .signin-portrait.waist-up img { width: 100%; left: 0; top: 10px; }
|
|
3907
|
+
#capture.signin-sheet .signin-item-glow { position: absolute; z-index: -1; inset: -4px; width: calc(100% + 8px); height: calc(100% + 8px); object-fit: cover; border-radius: 26%; filter: blur(9px); opacity: .42; transform: translateY(4px) scale(1.03); }
|
|
3908
|
+
#capture.signin-sheet .signin-day { cursor: default; }
|
|
3909
|
+
#capture.signin-sheet .signin-day::after { z-index: 1; }
|
|
3910
|
+
`;
|
|
3911
|
+
|
|
3912
|
+
// src/plugin/signinCardTemplate.ts
|
|
3913
|
+
var check = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg>';
|
|
3914
|
+
var progressCheck = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 11 3 3L22 4"/><path d="M21 12v1a9 9 0 1 1-5.34-8.23"/></svg>';
|
|
3915
|
+
var clock = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 6v6h4"/></svg>';
|
|
3916
|
+
function signinCardHtml(card, artwork = [], portrait) {
|
|
3917
|
+
if (card.cycleDays !== 30 || card.days.length !== 30 || card.days.some((day, index) => day.day !== index + 1)) throw new Error("签到卡片必须包含固定 30 天奖励");
|
|
3918
|
+
const completed = Math.min(30, Math.max(0, Math.trunc(card.completedDays)));
|
|
3919
|
+
const days = card.days.map((day, index) => {
|
|
3920
|
+
const image2 = artwork[index];
|
|
3921
|
+
const claimed = day.day <= completed;
|
|
3922
|
+
return `<div class="signin-day${claimed ? " is-claimed" : ""}" data-day="${day.day}" aria-label="第 ${day.day} 天,${cardEscape(day.name)} ×${cardEscape(day.count)}${claimed ? ",已签到" : ""}">
|
|
3923
|
+
<span class="signin-number">${String(day.day).padStart(2, "0")}</span>
|
|
3924
|
+
<div class="signin-reward"><span class="signin-art-wrap">${image2 ? `<img class="signin-item-glow" src="${cardEscape(image2)}" alt="" aria-hidden="true"><img class="signin-item-art" src="${cardEscape(image2)}" alt="${cardEscape(day.name)}">` : ""}</span></div>
|
|
3925
|
+
<div class="signin-reward-info"><span class="signin-reward-label"><span class="signin-item-name">${cardEscape(day.name)}</span><span class="signin-quantity">×${cardEscape(day.count)}</span></span></div>
|
|
3926
|
+
${claimed ? `<span class="signin-claimed-overlay" aria-hidden="true"></span><span class="signin-check">${check}</span>` : ""}
|
|
3927
|
+
</div>`;
|
|
3928
|
+
}).join("");
|
|
3929
|
+
return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><style>${signinCardStyles}</style></head><body><main id="capture" class="signin-sheet" data-portrait-id="${cardEscape(card.portraitId)}">
|
|
3930
|
+
<article class="signin-poster" aria-label="每日签到,固定 30 天周期">
|
|
3931
|
+
<header class="signin-banner">
|
|
3932
|
+
${portrait ? `<div class="signin-portrait ${portrait.framing === "full-body" ? "full-body" : "waist-up"}"><img class="signin-portrait-art" src="${cardEscape(portrait.src)}" alt="${cardEscape(portrait.name)}"></div>` : ""}
|
|
3933
|
+
<span class="signin-leaf leaf-a" aria-hidden="true"></span><span class="signin-leaf leaf-b" aria-hidden="true"></span><span class="signin-leaf leaf-c" aria-hidden="true"></span>
|
|
3934
|
+
<div class="signin-eyebrow">DAILY CHECK-IN</div><h1 class="signin-title">每日签到</h1>
|
|
3935
|
+
<div class="signin-progress">${progressCheck}<span>${completed} / 30</span><small>本轮签到</small></div>
|
|
3936
|
+
<div class="signin-refresh">${clock}每日 00:00 刷新</div>
|
|
3937
|
+
</header>
|
|
3938
|
+
<section class="signin-board" aria-label="30 天奖励日历"><div class="signin-seam" aria-hidden="true"></div><div class="signin-grid">${days}</div></section>
|
|
3939
|
+
</article>
|
|
3940
|
+
</main></body></html>`;
|
|
3941
|
+
}
|
|
3942
|
+
__name(signinCardHtml, "signinCardHtml");
|
|
3943
|
+
|
|
3944
|
+
// src/plugin/signinCardAssets.ts
|
|
3945
|
+
var import_promises = __toESM(require("node:fs/promises"));
|
|
3946
|
+
var import_node_path = __toESM(require("node:path"));
|
|
3947
|
+
|
|
3948
|
+
// src/plugin/signinPortraits.ts
|
|
3949
|
+
var SIGNIN_PORTRAITS = [
|
|
3950
|
+
{
|
|
3951
|
+
"id": 1,
|
|
3952
|
+
"name": "银发兔女郎",
|
|
3953
|
+
"file": "01-bunny-hostess.webp",
|
|
3954
|
+
"framing": "full-body"
|
|
3955
|
+
},
|
|
3956
|
+
{
|
|
3957
|
+
"id": 2,
|
|
3958
|
+
"name": "森林法师",
|
|
3959
|
+
"file": "02-forest-mage.webp",
|
|
3960
|
+
"framing": "waist-up"
|
|
3961
|
+
},
|
|
3962
|
+
{
|
|
3963
|
+
"id": 3,
|
|
3964
|
+
"name": "银发女神",
|
|
3965
|
+
"file": "03-silver-goddess.webp",
|
|
3966
|
+
"framing": "waist-up"
|
|
3967
|
+
},
|
|
3968
|
+
{
|
|
3969
|
+
"id": 4,
|
|
3970
|
+
"name": "蓝甲女骑士",
|
|
3971
|
+
"file": "04-blue-knight.webp",
|
|
3972
|
+
"framing": "waist-up"
|
|
3973
|
+
},
|
|
3974
|
+
{
|
|
3975
|
+
"id": 5,
|
|
3976
|
+
"name": "蒸汽朋克工程师",
|
|
3977
|
+
"file": "05-steampunk-engineer.webp",
|
|
3978
|
+
"framing": "waist-up"
|
|
3979
|
+
},
|
|
3980
|
+
{
|
|
3981
|
+
"id": 6,
|
|
3982
|
+
"name": "海军礼服军官",
|
|
3983
|
+
"file": "06-naval-officer.webp",
|
|
3984
|
+
"framing": "waist-up"
|
|
3985
|
+
},
|
|
3986
|
+
{
|
|
3987
|
+
"id": 7,
|
|
3988
|
+
"name": "翡翠旗袍佳人",
|
|
3989
|
+
"file": "07-jade-qipao.webp",
|
|
3990
|
+
"framing": "waist-up"
|
|
3991
|
+
},
|
|
3992
|
+
{
|
|
3993
|
+
"id": 8,
|
|
3994
|
+
"name": "紫罗兰女法师",
|
|
3995
|
+
"file": "08-violet-mage.webp",
|
|
3996
|
+
"framing": "waist-up"
|
|
3997
|
+
},
|
|
3998
|
+
{
|
|
3999
|
+
"id": 9,
|
|
4000
|
+
"name": "米白衬衫冒险家",
|
|
4001
|
+
"file": "09-ivory-adventurer.webp",
|
|
4002
|
+
"framing": "waist-up"
|
|
4003
|
+
},
|
|
4004
|
+
{
|
|
4005
|
+
"id": 10,
|
|
4006
|
+
"name": "樱花和服佳人",
|
|
4007
|
+
"file": "10-sakura-kimono.webp",
|
|
4008
|
+
"framing": "waist-up"
|
|
4009
|
+
},
|
|
4010
|
+
{
|
|
4011
|
+
"id": 11,
|
|
4012
|
+
"name": "红丝绒礼裙淑女",
|
|
4013
|
+
"file": "11-red-velvet-lady.webp",
|
|
4014
|
+
"framing": "waist-up"
|
|
4015
|
+
},
|
|
4016
|
+
{
|
|
4017
|
+
"id": 12,
|
|
4018
|
+
"name": "精灵绿裙游侠",
|
|
4019
|
+
"file": "12-elven-ranger.webp",
|
|
4020
|
+
"framing": "waist-up"
|
|
4021
|
+
},
|
|
4022
|
+
{
|
|
4023
|
+
"id": 13,
|
|
4024
|
+
"name": "黑礼服西装佳人",
|
|
4025
|
+
"file": "13-black-tuxedo.webp",
|
|
4026
|
+
"framing": "waist-up"
|
|
4027
|
+
},
|
|
4028
|
+
{
|
|
4029
|
+
"id": 14,
|
|
4030
|
+
"name": "海蓝披肩佳人",
|
|
4031
|
+
"file": "14-ocean-blue-lady.webp",
|
|
4032
|
+
"framing": "waist-up"
|
|
4033
|
+
},
|
|
4034
|
+
{
|
|
4035
|
+
"id": 15,
|
|
4036
|
+
"name": "琥珀女巫",
|
|
4037
|
+
"file": "15-amber-witch.webp",
|
|
4038
|
+
"framing": "waist-up"
|
|
4039
|
+
},
|
|
4040
|
+
{
|
|
4041
|
+
"id": 16,
|
|
4042
|
+
"name": "经典黑白女仆",
|
|
4043
|
+
"file": "16-classic-maid.webp",
|
|
4044
|
+
"framing": "waist-up"
|
|
4045
|
+
},
|
|
4046
|
+
{
|
|
4047
|
+
"id": 17,
|
|
4048
|
+
"name": "冰蓝冬装佳人",
|
|
4049
|
+
"file": "17-ice-blue-winter.webp",
|
|
4050
|
+
"framing": "waist-up"
|
|
4051
|
+
},
|
|
4052
|
+
{
|
|
4053
|
+
"id": 18,
|
|
4054
|
+
"name": "紫色职场西装佳人",
|
|
4055
|
+
"file": "18-violet-office.webp",
|
|
4056
|
+
"framing": "waist-up"
|
|
4057
|
+
},
|
|
4058
|
+
{
|
|
4059
|
+
"id": 19,
|
|
4060
|
+
"name": "红发蓝宝石礼裙",
|
|
4061
|
+
"file": "19-sapphire-gown.webp",
|
|
4062
|
+
"framing": "waist-up"
|
|
4063
|
+
},
|
|
4064
|
+
{
|
|
4065
|
+
"id": 20,
|
|
4066
|
+
"name": "银发科技夹克",
|
|
4067
|
+
"file": "20-silver-tech-jacket.webp",
|
|
4068
|
+
"framing": "waist-up"
|
|
4069
|
+
},
|
|
4070
|
+
{
|
|
4071
|
+
"id": 21,
|
|
4072
|
+
"name": "沙漠旅者",
|
|
4073
|
+
"file": "21-desert-linen.webp",
|
|
4074
|
+
"framing": "waist-up"
|
|
4075
|
+
},
|
|
4076
|
+
{
|
|
4077
|
+
"id": 22,
|
|
4078
|
+
"name": "森林游侠",
|
|
4079
|
+
"file": "22-forest-ranger.webp",
|
|
4080
|
+
"framing": "waist-up"
|
|
4081
|
+
},
|
|
4082
|
+
{
|
|
4083
|
+
"id": 23,
|
|
4084
|
+
"name": "月白汉服",
|
|
4085
|
+
"file": "23-moonlight-hanfu.webp",
|
|
4086
|
+
"framing": "waist-up"
|
|
4087
|
+
},
|
|
4088
|
+
{
|
|
4089
|
+
"id": 24,
|
|
4090
|
+
"name": "白色军装",
|
|
4091
|
+
"file": "24-white-uniform.webp",
|
|
4092
|
+
"framing": "waist-up"
|
|
4093
|
+
},
|
|
4094
|
+
{
|
|
4095
|
+
"id": 25,
|
|
4096
|
+
"name": "紫发哥特礼裙",
|
|
4097
|
+
"file": "25-gothic-lace.webp",
|
|
4098
|
+
"framing": "waist-up"
|
|
4099
|
+
},
|
|
4100
|
+
{
|
|
4101
|
+
"id": 26,
|
|
4102
|
+
"name": "赛车夹克",
|
|
4103
|
+
"file": "26-orange-racer.webp",
|
|
4104
|
+
"framing": "waist-up"
|
|
4105
|
+
},
|
|
4106
|
+
{
|
|
4107
|
+
"id": 27,
|
|
4108
|
+
"name": "蓝发炼金师",
|
|
4109
|
+
"file": "27-blue-alchemist.webp",
|
|
4110
|
+
"framing": "waist-up"
|
|
4111
|
+
},
|
|
4112
|
+
{
|
|
4113
|
+
"id": 28,
|
|
4114
|
+
"name": "玫瑰短发皮夹克",
|
|
4115
|
+
"file": "28-rose-leather.webp",
|
|
4116
|
+
"framing": "waist-up"
|
|
4117
|
+
},
|
|
4118
|
+
{
|
|
4119
|
+
"id": 29,
|
|
4120
|
+
"name": "淡紫成人精灵",
|
|
4121
|
+
"file": "29-lilac-elf.webp",
|
|
4122
|
+
"framing": "waist-up"
|
|
4123
|
+
},
|
|
4124
|
+
{
|
|
4125
|
+
"id": 30,
|
|
4126
|
+
"name": "太阳纹礼裙",
|
|
4127
|
+
"file": "30-sun-gown.webp",
|
|
4128
|
+
"framing": "waist-up"
|
|
4129
|
+
},
|
|
4130
|
+
{
|
|
4131
|
+
"id": 31,
|
|
4132
|
+
"name": "海盗船长",
|
|
4133
|
+
"file": "31-pirate-captain.webp",
|
|
4134
|
+
"framing": "waist-up"
|
|
4135
|
+
},
|
|
4136
|
+
{
|
|
4137
|
+
"id": 32,
|
|
4138
|
+
"name": "墨绿学院学者",
|
|
4139
|
+
"file": "32-green-scholar.webp",
|
|
4140
|
+
"framing": "waist-up"
|
|
4141
|
+
},
|
|
4142
|
+
{
|
|
4143
|
+
"id": 33,
|
|
4144
|
+
"name": "街头拉链外套",
|
|
4145
|
+
"file": "33-blue-streetwear.webp",
|
|
4146
|
+
"framing": "waist-up"
|
|
4147
|
+
},
|
|
4148
|
+
{
|
|
4149
|
+
"id": 34,
|
|
4150
|
+
"name": "奶油色舞会礼裙",
|
|
4151
|
+
"file": "34-cream-ballgown.webp",
|
|
4152
|
+
"framing": "waist-up"
|
|
4153
|
+
},
|
|
4154
|
+
{
|
|
4155
|
+
"id": 35,
|
|
4156
|
+
"name": "赤褐马尾医师",
|
|
4157
|
+
"file": "35-white-coat.webp",
|
|
4158
|
+
"framing": "waist-up"
|
|
4159
|
+
},
|
|
4160
|
+
{
|
|
4161
|
+
"id": 36,
|
|
4162
|
+
"name": "铂金圣职祭司",
|
|
4163
|
+
"file": "36-emerald-priestess.webp",
|
|
4164
|
+
"framing": "waist-up"
|
|
4165
|
+
},
|
|
4166
|
+
{
|
|
4167
|
+
"id": 37,
|
|
4168
|
+
"name": "桃色复古花裙",
|
|
4169
|
+
"file": "37-peach-floral.webp",
|
|
4170
|
+
"framing": "waist-up"
|
|
4171
|
+
},
|
|
4172
|
+
{
|
|
4173
|
+
"id": 38,
|
|
4174
|
+
"name": "紫发赌场主持",
|
|
4175
|
+
"file": "38-casino-hostess.webp",
|
|
4176
|
+
"framing": "waist-up"
|
|
4177
|
+
},
|
|
4178
|
+
{
|
|
4179
|
+
"id": 39,
|
|
4180
|
+
"name": "红金轻甲骑士",
|
|
4181
|
+
"file": "39-red-gold-armor.webp",
|
|
4182
|
+
"framing": "waist-up"
|
|
4183
|
+
},
|
|
4184
|
+
{
|
|
4185
|
+
"id": 40,
|
|
4186
|
+
"name": "玫瑰歌剧女伶",
|
|
4187
|
+
"file": "40-opera-gown.webp",
|
|
4188
|
+
"framing": "waist-up"
|
|
4189
|
+
},
|
|
4190
|
+
{
|
|
4191
|
+
"id": 41,
|
|
4192
|
+
"name": "青发军官",
|
|
4193
|
+
"file": "41-teal-officer.webp",
|
|
4194
|
+
"framing": "waist-up"
|
|
4195
|
+
},
|
|
4196
|
+
{
|
|
4197
|
+
"id": 42,
|
|
4198
|
+
"name": "金棕公会接待",
|
|
4199
|
+
"file": "42-guild-uniform.webp",
|
|
4200
|
+
"framing": "waist-up"
|
|
4201
|
+
},
|
|
4202
|
+
{
|
|
4203
|
+
"id": 43,
|
|
4204
|
+
"name": "炭灰旗袍佳人",
|
|
4205
|
+
"file": "43-charcoal-qipao.webp",
|
|
4206
|
+
"framing": "waist-up"
|
|
4207
|
+
},
|
|
4208
|
+
{
|
|
4209
|
+
"id": 44,
|
|
4210
|
+
"name": "银蓝飞行员",
|
|
4211
|
+
"file": "44-sci-fi-pilot.webp",
|
|
4212
|
+
"framing": "waist-up"
|
|
4213
|
+
},
|
|
4214
|
+
{
|
|
4215
|
+
"id": 45,
|
|
4216
|
+
"name": "小麦肤运动员",
|
|
4217
|
+
"file": "45-athlete-jacket.webp",
|
|
4218
|
+
"framing": "waist-up"
|
|
4219
|
+
},
|
|
4220
|
+
{
|
|
4221
|
+
"id": 46,
|
|
4222
|
+
"name": "青裙盘髻佳人",
|
|
4223
|
+
"file": "46-teal-traditional.webp",
|
|
4224
|
+
"framing": "waist-up"
|
|
4225
|
+
},
|
|
4226
|
+
{
|
|
4227
|
+
"id": 47,
|
|
4228
|
+
"name": "紫披肩女王",
|
|
4229
|
+
"file": "47-violet-queen.webp",
|
|
4230
|
+
"framing": "waist-up"
|
|
4231
|
+
},
|
|
4232
|
+
{
|
|
4233
|
+
"id": 48,
|
|
4234
|
+
"name": "魔法探险者",
|
|
4235
|
+
"file": "48-magic-explorer.webp",
|
|
4236
|
+
"framing": "waist-up"
|
|
4237
|
+
},
|
|
4238
|
+
{
|
|
4239
|
+
"id": 49,
|
|
4240
|
+
"name": "白发红花旗袍",
|
|
4241
|
+
"file": "49-red-floral-qipao.webp",
|
|
4242
|
+
"framing": "waist-up"
|
|
4243
|
+
},
|
|
4244
|
+
{
|
|
4245
|
+
"id": 50,
|
|
4246
|
+
"name": "草莓金夏日裙",
|
|
4247
|
+
"file": "50-summer-dress.webp",
|
|
4248
|
+
"framing": "waist-up"
|
|
4249
|
+
}
|
|
4250
|
+
];
|
|
4251
|
+
|
|
4252
|
+
// src/plugin/signinCardAssets.ts
|
|
4253
|
+
var portraits = /* @__PURE__ */ new Map();
|
|
4254
|
+
var ICON_CONCURRENCY2 = 8;
|
|
4255
|
+
var ICON_BUDGET_MS2 = 6e3;
|
|
4256
|
+
async function loadSigninPortrait(id) {
|
|
4257
|
+
const entry = SIGNIN_PORTRAITS.find((portrait) => portrait.id === id);
|
|
4258
|
+
if (!entry) throw new Error("签到立绘编号无效");
|
|
4259
|
+
if (!portraits.has(id)) portraits.set(id, (async () => {
|
|
4260
|
+
for (const base2 of ["../assets/signin-portraits", "../../assets/signin-portraits"]) {
|
|
4261
|
+
try {
|
|
4262
|
+
const bytes = await import_promises.default.readFile(import_node_path.default.resolve(__dirname, base2, entry.file));
|
|
4263
|
+
return { src: "data:image/webp;base64," + bytes.toString("base64"), name: entry.name, framing: entry.framing };
|
|
4264
|
+
} catch (error) {
|
|
4265
|
+
if (error.code !== "ENOENT") throw error;
|
|
4266
|
+
}
|
|
4267
|
+
}
|
|
4268
|
+
return void 0;
|
|
4269
|
+
})().then((value) => {
|
|
4270
|
+
if (!value) portraits.delete(id);
|
|
4271
|
+
return value;
|
|
4272
|
+
}, (error) => {
|
|
4273
|
+
portraits.delete(id);
|
|
4274
|
+
throw error;
|
|
4275
|
+
}));
|
|
4276
|
+
return portraits.get(id);
|
|
4277
|
+
}
|
|
4278
|
+
__name(loadSigninPortrait, "loadSigninPortrait");
|
|
4279
|
+
async function loadSigninCardAssets(card) {
|
|
4280
|
+
const portraitPromise = loadSigninPortrait(card.portraitId);
|
|
4281
|
+
const addresses = [...new Set(card.days.map((day) => day.artworkUrl).filter((address) => Boolean(address)))];
|
|
4282
|
+
const loaded = /* @__PURE__ */ new Map();
|
|
4283
|
+
let cursor = 0;
|
|
4284
|
+
let stopped = false;
|
|
4285
|
+
let timer;
|
|
4286
|
+
const work = Promise.all(Array.from({ length: Math.min(ICON_CONCURRENCY2, addresses.length) }, async () => {
|
|
4287
|
+
while (!stopped && cursor < addresses.length) {
|
|
4288
|
+
const address = addresses[cursor++];
|
|
4289
|
+
let image2;
|
|
4290
|
+
try {
|
|
4291
|
+
image2 = await loadSkillArtwork(address);
|
|
4292
|
+
} catch {
|
|
4293
|
+
}
|
|
4294
|
+
if (!stopped && image2) loaded.set(address, image2);
|
|
4295
|
+
}
|
|
4296
|
+
}));
|
|
4297
|
+
let portrait;
|
|
4298
|
+
try {
|
|
4299
|
+
;
|
|
4300
|
+
[portrait] = await Promise.all([portraitPromise, Promise.race([work, new Promise((resolve2) => {
|
|
4301
|
+
timer = setTimeout(() => {
|
|
4302
|
+
stopped = true;
|
|
4303
|
+
resolve2();
|
|
4304
|
+
}, ICON_BUDGET_MS2);
|
|
4305
|
+
})])]);
|
|
4306
|
+
} finally {
|
|
4307
|
+
if (timer) clearTimeout(timer);
|
|
4308
|
+
stopped = true;
|
|
4309
|
+
}
|
|
4310
|
+
if (!portrait) throw new Error("签到立绘素材缺失");
|
|
4311
|
+
return { portrait, artwork: card.days.map((day) => day.artworkUrl ? loaded.get(day.artworkUrl) : void 0) };
|
|
4312
|
+
}
|
|
4313
|
+
__name(loadSigninCardAssets, "loadSigninCardAssets");
|
|
4314
|
+
|
|
3748
4315
|
// src/plugin/skillCard.ts
|
|
3749
4316
|
var running = 0;
|
|
3750
4317
|
var waiting = [];
|
|
@@ -3754,7 +4321,7 @@ async function staticAsset(folder, file) {
|
|
|
3754
4321
|
if (!staticAssets.has(key)) staticAssets.set(key, (async () => {
|
|
3755
4322
|
for (const base2 of [`../assets/${folder}`, `../../assets/${folder}`]) {
|
|
3756
4323
|
try {
|
|
3757
|
-
return "data:image/webp;base64," + (await
|
|
4324
|
+
return "data:image/webp;base64," + (await import_promises2.default.readFile(import_node_path2.default.resolve(__dirname, base2, file))).toString("base64");
|
|
3758
4325
|
} catch {
|
|
3759
4326
|
}
|
|
3760
4327
|
}
|
|
@@ -3772,7 +4339,7 @@ async function leaderboardHeader() {
|
|
|
3772
4339
|
for (const base2 of ["../assets/leaderboard", "../../assets/leaderboard"]) {
|
|
3773
4340
|
for (const [file, mime] of [["header.png", "image/png"], ["header.jpg", "image/jpeg"], ["header.webp", "image/webp"], ["header.svg", "image/svg+xml"]]) {
|
|
3774
4341
|
try {
|
|
3775
|
-
return "data:" + mime + ";base64," + (await
|
|
4342
|
+
return "data:" + mime + ";base64," + (await import_promises2.default.readFile(import_node_path2.default.resolve(__dirname, base2, file))).toString("base64");
|
|
3776
4343
|
} catch (error) {
|
|
3777
4344
|
if (error.code !== "ENOENT") throw error;
|
|
3778
4345
|
}
|
|
@@ -3833,9 +4400,10 @@ function rememberRender(key, image2) {
|
|
|
3833
4400
|
}
|
|
3834
4401
|
}
|
|
3835
4402
|
__name(rememberRender, "rememberRender");
|
|
3836
|
-
async function renderSkillCard(ctx, card, leaderboard, itemCard, characterCard, equipmentCard, bloodlineCard, companionCard, titleCard) {
|
|
4403
|
+
async function renderSkillCard(ctx, card, leaderboard, itemCard, characterCard, equipmentCard, bloodlineCard, companionCard, titleCard, signinCard) {
|
|
3837
4404
|
if (!ctx.puppeteer) throw new Error("Puppeteer 未启用");
|
|
3838
|
-
if (JSON.stringify(titleCard ?? bloodlineCard ?? equipmentCard ?? companionCard ?? characterCard ?? itemCard ?? card ?? leaderboard ?? {}).length > 24e3) throw new Error("卡片内容过长");
|
|
4405
|
+
if (JSON.stringify(signinCard ?? titleCard ?? bloodlineCard ?? equipmentCard ?? companionCard ?? characterCard ?? itemCard ?? card ?? leaderboard ?? {}).length > 24e3) throw new Error("卡片内容过长");
|
|
4406
|
+
if (signinCard) return (await renderUncached(ctx, card, leaderboard, itemCard, characterCard, equipmentCard, bloodlineCard, companionCard, titleCard, signinCard)).image;
|
|
3839
4407
|
const key = leaderboard && !titleCard && !bloodlineCard && !equipmentCard && !companionCard ? void 0 : renderKey(card, itemCard, characterCard, equipmentCard, bloodlineCard, companionCard, titleCard);
|
|
3840
4408
|
if (!key) return (await renderUncached(ctx, card, leaderboard, itemCard, characterCard, equipmentCard, bloodlineCard, companionCard, titleCard)).image;
|
|
3841
4409
|
const hit = cachedRender(key);
|
|
@@ -3853,7 +4421,7 @@ async function renderSkillCard(ctx, card, leaderboard, itemCard, characterCard,
|
|
|
3853
4421
|
return work;
|
|
3854
4422
|
}
|
|
3855
4423
|
__name(renderSkillCard, "renderSkillCard");
|
|
3856
|
-
async function renderUncached(ctx, card, leaderboard, itemCard, characterCard, equipmentCard, bloodlineCard, companionCard, titleCard) {
|
|
4424
|
+
async function renderUncached(ctx, card, leaderboard, itemCard, characterCard, equipmentCard, bloodlineCard, companionCard, titleCard, signinCard) {
|
|
3857
4425
|
if (running >= 2) {
|
|
3858
4426
|
if (waiting.length >= 16) throw new Error("绘图繁忙");
|
|
3859
4427
|
await new Promise((resolve2) => waiting.push(resolve2));
|
|
@@ -3870,15 +4438,16 @@ async function renderUncached(ctx, card, leaderboard, itemCard, characterCard, e
|
|
|
3870
4438
|
}, "release");
|
|
3871
4439
|
try {
|
|
3872
4440
|
const work = /* @__PURE__ */ __name(async () => {
|
|
3873
|
-
const remoteAddress = titleCard ? titleCard.artworkUrl : bloodlineCard ? bloodlineCard.artworkUrl : equipmentCard ? equipmentCard.artworkUrl : companionCard ? companionCard.artworkUrl : characterCard ? characterCard.artworkUrl : itemCard ? itemCard.artworkUrl : leaderboard ? leaderboard.backgroundUrl : card?.artworkUrl;
|
|
3874
|
-
const isEquipment = !titleCard && !bloodlineCard && Boolean(equipmentCard);
|
|
3875
|
-
const isCharacter = !titleCard && !bloodlineCard && !equipmentCard && !companionCard && Boolean(characterCard);
|
|
3876
|
-
const [remoteArt, fallbackArt, entryArtwork, characterAssets, header] = await Promise.all([
|
|
4441
|
+
const remoteAddress = signinCard ? void 0 : titleCard ? titleCard.artworkUrl : bloodlineCard ? bloodlineCard.artworkUrl : equipmentCard ? equipmentCard.artworkUrl : companionCard ? companionCard.artworkUrl : characterCard ? characterCard.artworkUrl : itemCard ? itemCard.artworkUrl : leaderboard ? leaderboard.backgroundUrl : card?.artworkUrl;
|
|
4442
|
+
const isEquipment = !signinCard && !titleCard && !bloodlineCard && Boolean(equipmentCard);
|
|
4443
|
+
const isCharacter = !signinCard && !titleCard && !bloodlineCard && !equipmentCard && !companionCard && Boolean(characterCard);
|
|
4444
|
+
const [remoteArt, fallbackArt, entryArtwork, characterAssets, header, signinAssets] = await Promise.all([
|
|
3877
4445
|
loadSkillArtwork(remoteAddress),
|
|
3878
4446
|
isEquipment ? equipmentFallback() : void 0,
|
|
3879
|
-
loadCardEntryArtwork(!titleCard && !bloodlineCard && !equipmentCard ? companionCard : void 0),
|
|
4447
|
+
loadCardEntryArtwork(!signinCard && !titleCard && !bloodlineCard && !equipmentCard ? companionCard : void 0),
|
|
3880
4448
|
isCharacter ? Promise.all([characterAsset(), loadSkillArtwork(characterCard.titleImageUrl)]) : void 0,
|
|
3881
|
-
!titleCard && !bloodlineCard && !equipmentCard && !companionCard && !characterCard && !itemCard && leaderboard ? leaderboardHeader() : void 0,
|
|
4449
|
+
!signinCard && !titleCard && !bloodlineCard && !equipmentCard && !companionCard && !characterCard && !itemCard && leaderboard ? leaderboardHeader() : void 0,
|
|
4450
|
+
signinCard ? loadSigninCardAssets(signinCard) : void 0,
|
|
3882
4451
|
ctx.puppeteer.page().then(async (created) => {
|
|
3883
4452
|
if (expired || finished) {
|
|
3884
4453
|
await created.close();
|
|
@@ -3893,7 +4462,9 @@ async function renderUncached(ctx, card, leaderboard, itemCard, characterCard, e
|
|
|
3893
4462
|
let html;
|
|
3894
4463
|
let loadedCharacterTitle;
|
|
3895
4464
|
let localAssetsReady = true;
|
|
3896
|
-
if (
|
|
4465
|
+
if (signinCard) {
|
|
4466
|
+
html = signinCardHtml(signinCard, signinAssets.artwork, signinAssets.portrait);
|
|
4467
|
+
} else if (titleCard) {
|
|
3897
4468
|
html = titleCardHtml(titleCard, art);
|
|
3898
4469
|
} else if (bloodlineCard) {
|
|
3899
4470
|
html = bloodlineCardHtml(bloodlineCard, art);
|
|
@@ -3916,7 +4487,7 @@ async function renderUncached(ctx, card, leaderboard, itemCard, characterCard, e
|
|
|
3916
4487
|
}
|
|
3917
4488
|
if (expired) throw new Error("绘图超时");
|
|
3918
4489
|
if (!page) throw new Error("卡片页面缺失");
|
|
3919
|
-
await page.setViewport({ width: 760, height: 1107, deviceScaleFactor: titleCard || (companionCard || characterCard) && !bloodlineCard && !equipmentCard ? 2 : 1 });
|
|
4490
|
+
await page.setViewport({ width: 760, height: 1107, deviceScaleFactor: signinCard ? 1.5 : titleCard || (companionCard || characterCard) && !bloodlineCard && !equipmentCard ? 2 : 1 });
|
|
3920
4491
|
await page.setJavaScriptEnabled(false);
|
|
3921
4492
|
await page.setRequestInterception(true);
|
|
3922
4493
|
page.on("request", (req) => {
|
|
@@ -3925,6 +4496,12 @@ async function renderUncached(ctx, card, leaderboard, itemCard, characterCard, e
|
|
|
3925
4496
|
});
|
|
3926
4497
|
await page.setContent(html, { waitUntil: "load", timeout: 1e4 });
|
|
3927
4498
|
await page.evaluate(layoutCard);
|
|
4499
|
+
if (signinCard && signinAssets) {
|
|
4500
|
+
const decodedDays = await page.evaluate(() => [...document.querySelectorAll(".signin-item-art")].map((image2) => Number(image2.closest(".signin-day")?.dataset.day)));
|
|
4501
|
+
signinAssets.artwork.forEach((image2, index) => {
|
|
4502
|
+
if (image2 && !decodedDays.includes(signinCard.days[index].day)) discardSkillArtwork(signinCard.days[index].artworkUrl, image2);
|
|
4503
|
+
});
|
|
4504
|
+
}
|
|
3928
4505
|
let titleDecoded = true;
|
|
3929
4506
|
if (titleCard && art) {
|
|
3930
4507
|
titleDecoded = await page.evaluate((expected) => {
|
|
@@ -3955,7 +4532,7 @@ async function renderUncached(ctx, card, leaderboard, itemCard, characterCard, e
|
|
|
3955
4532
|
if (!target) throw new Error("卡片元素缺失");
|
|
3956
4533
|
const bounds = await target.boundingBox();
|
|
3957
4534
|
if (!bounds || bounds.height > 1e4) throw new Error("卡片内容过长");
|
|
3958
|
-
return { image: Buffer.from(await target.screenshot({ type: "jpeg", quality: 90 })), cacheable: localAssetsReady && titleDecoded && entryArtwork.complete && decodedIcons === expectedIcons && (!remoteAddress || Boolean(!titleCard && !bloodlineCard && equipmentCard ? dedicatedArt : art)) };
|
|
4535
|
+
return { image: Buffer.from(await target.screenshot({ type: "jpeg", quality: signinCard ? 82 : 90 })), cacheable: !signinCard && localAssetsReady && titleDecoded && entryArtwork.complete && decodedIcons === expectedIcons && (!remoteAddress || Boolean(!titleCard && !bloodlineCard && equipmentCard ? dedicatedArt : art)) };
|
|
3959
4536
|
}, "work");
|
|
3960
4537
|
workPromise = work();
|
|
3961
4538
|
return await Promise.race([workPromise, new Promise((_, reject) => {
|
|
@@ -4008,8 +4585,8 @@ var handel_base = class {
|
|
|
4008
4585
|
this.ctx.logger.info("session not found", data.userId, data.channelId);
|
|
4009
4586
|
return;
|
|
4010
4587
|
}
|
|
4011
|
-
let finalContent = data.notification ? content.trimEnd() : content;
|
|
4012
|
-
if (messageType === "text" && !data.notification && session.event?.platform === "qq" && session.event?.channel?.type === 0) {
|
|
4588
|
+
let finalContent = data.notification || data.plainText ? content.trimEnd() : content;
|
|
4589
|
+
if (messageType === "text" && !data.notification && !data.plainText && session.event?.platform === "qq" && session.event?.channel?.type === 0) {
|
|
4013
4590
|
finalContent = "Ciallo~(∠・ω< )\n" + content;
|
|
4014
4591
|
}
|
|
4015
4592
|
const sendStartedAt = this.timing ? performance.now() : 0;
|
|
@@ -4841,6 +5418,7 @@ __name(renderQQStoryMarkdown, "renderQQStoryMarkdown");
|
|
|
4841
5418
|
|
|
4842
5419
|
// src/plugin/serverHandel/qqMessagePreview.ts
|
|
4843
5420
|
function renderQQMessagePreview(data, showGreeting = false) {
|
|
5421
|
+
if (data.plainText) return { kind: "text", text: data.line.map((item) => item.content).join("\n").trimEnd() };
|
|
4844
5422
|
const plain = new AnalysisMsg().parse(data);
|
|
4845
5423
|
const text = data.notification ? plain.trimEnd() : plain;
|
|
4846
5424
|
let keyboard;
|
|
@@ -4954,8 +5532,8 @@ var ImageHandler = class extends handel_base {
|
|
|
4954
5532
|
let rendered = false;
|
|
4955
5533
|
const renderStartedAt = this.timing ? performance.now() : 0;
|
|
4956
5534
|
try {
|
|
4957
|
-
if (!data.titleCard && !data.companionCard && !data.characterCard && !data.itemCard && !data.card && !data.leaderboard && !data.equipmentCard && !data.bloodlineCard) throw new Error("缺少卡片数据");
|
|
4958
|
-
const image2 = await renderSkillCard(this.ctx, data.card, data.leaderboard, data.itemCard, data.characterCard, data.equipmentCard, data.bloodlineCard, data.companionCard, data.titleCard);
|
|
5535
|
+
if (!data.signinCard && !data.titleCard && !data.companionCard && !data.characterCard && !data.itemCard && !data.card && !data.leaderboard && !data.equipmentCard && !data.bloodlineCard) throw new Error("缺少卡片数据");
|
|
5536
|
+
const image2 = await renderSkillCard(this.ctx, data.card, data.leaderboard, data.itemCard, data.characterCard, data.equipmentCard, data.bloodlineCard, data.companionCard, data.titleCard, data.signinCard);
|
|
4959
5537
|
if (this.timing) this.timing.imageBytes = image2.length;
|
|
4960
5538
|
content = import_koishi.h.image(image2, "image/jpeg").toString();
|
|
4961
5539
|
rendered = true;
|
|
@@ -5072,7 +5650,7 @@ function apply(ctx, config) {
|
|
|
5072
5650
|
__name(apply, "apply");
|
|
5073
5651
|
|
|
5074
5652
|
// src/index.ts
|
|
5075
|
-
var
|
|
5653
|
+
var import_node_path3 = require("node:path");
|
|
5076
5654
|
var inject = { optional: ["puppeteer", "console"] };
|
|
5077
5655
|
var name = "dew-bot";
|
|
5078
5656
|
var filter = false;
|
|
@@ -5084,8 +5662,8 @@ function apply2(ctx, config) {
|
|
|
5084
5662
|
ctx.inject(["console"], async (consoleCtx) => {
|
|
5085
5663
|
const { default: StatisticsProvider2 } = await Promise.resolve().then(() => (init_statistics(), statistics_exports));
|
|
5086
5664
|
consoleCtx.plugin(StatisticsProvider2, {
|
|
5087
|
-
dev: (0,
|
|
5088
|
-
prod: (0,
|
|
5665
|
+
dev: (0, import_node_path3.resolve)(__dirname, "../client/index.ts"),
|
|
5666
|
+
prod: (0, import_node_path3.resolve)(__dirname, "../dist")
|
|
5089
5667
|
});
|
|
5090
5668
|
});
|
|
5091
5669
|
}
|