koishi-plugin-dew-bot 1.0.253 → 1.0.254
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/lib/index.js +727 -229
- package/lib/plugin/appearanceCardTemplate.d.ts +2 -2
- package/lib/plugin/detailCardTemplate.d.ts +22 -0
- package/lib/plugin/equipmentCardTemplate.d.ts +1 -1
- package/lib/plugin/formatCombatPower.d.ts +2 -0
- package/lib/plugin/itemCardTemplate.d.ts +2 -2
- package/lib/plugin/qualityCardDecorations.d.ts +7 -0
- package/lib/plugin/qualityCardStyles.d.ts +2 -0
- package/lib/plugin/serverHandel/qqCommandMessage.d.ts +2 -1
- package/lib/plugin/serverHandel/qqMessagePreview.d.ts +11 -0
- package/lib/plugin/serverHandel/qqPageMessage.d.ts +2 -2
- package/lib/plugin/serverHandel/qqRewardMessage.d.ts +5 -5
- package/lib/plugin/serverHandel/qqStoryMessage.d.ts +4 -3
- package/lib/plugin/serverHandel/qqTransactionMessage.d.ts +2 -1
- package/lib/plugin/skillCardTemplate.d.ts +2 -2
- package/lib/shared/face/index.d.ts +25 -1
- package/package.json +1 -1
- package/src/plugin/appearanceCardTemplate.ts +7 -16
- package/src/plugin/cardLayout.ts +5 -4
- package/src/plugin/characterCardTemplate.ts +2 -1
- package/src/plugin/detailCardTemplate.ts +69 -0
- package/src/plugin/equipmentCardTemplate.ts +29 -31
- package/src/plugin/formatCombatPower.ts +12 -0
- package/src/plugin/itemCardTemplate.ts +13 -19
- package/src/plugin/leaderboardTemplate.ts +2 -1
- package/src/plugin/qualityCardDecorations.ts +81 -0
- package/src/plugin/qualityCardStyles.ts +65 -0
- package/src/plugin/serverHandel/handel_base.ts +3 -3
- package/src/plugin/serverHandel/qqCommandMessage.ts +2 -2
- package/src/plugin/serverHandel/qqMessagePreview.ts +33 -0
- package/src/plugin/serverHandel/qqPageMessage.ts +141 -3
- package/src/plugin/serverHandel/qqRewardMessage.ts +10 -15
- package/src/plugin/serverHandel/qqStoryMessage.ts +10 -5
- package/src/plugin/serverHandel/qqTransactionMessage.ts +2 -2
- package/src/plugin/serverHandel/text.ts +7 -19
- package/src/plugin/skillCard.ts +2 -13
- package/src/plugin/skillCardTemplate.ts +56 -21
- package/src/shared/bot/analysisMsg.ts +7 -2
- package/src/shared/bot/serviceProto.ts +132 -2
- package/src/shared/face/index.ts +27 -2
package/lib/index.js
CHANGED
|
@@ -42,45 +42,278 @@ var import_koishi2 = require("koishi");
|
|
|
42
42
|
// src/plugin/serverHandel/image.ts
|
|
43
43
|
var import_koishi = require("koishi");
|
|
44
44
|
|
|
45
|
+
// src/plugin/qualityCardDecorations.ts
|
|
46
|
+
var colors = {
|
|
47
|
+
F: ["#8d9690", "#55635b", "#e8ece6", "#77877d", "#aab4ad"],
|
|
48
|
+
E: ["#77a085", "#4f765c", "#e7efe5", "#5d886d", "#9db49a"],
|
|
49
|
+
D: ["#4ba59a", "#327d72", "#e1efea", "#337e79", "#83b6a5"],
|
|
50
|
+
C: ["#69a5dd", "#3975a1", "#e5eff6", "#447ea9", "#88b6db"],
|
|
51
|
+
B: ["#ab82d4", "#8058a4", "#f0e9f5", "#8254a9", "#b28cda"],
|
|
52
|
+
A: ["#dfa263", "#a26b30", "#f7ecde", "#be7734", "#e4ad70"],
|
|
53
|
+
S: ["#d5bc68", "#9b813a", "#f4f0de", "#ac903e", "#dcc67c"],
|
|
54
|
+
SS: ["#d5887e", "#ab5c53", "#f6e8e3", "#ac6259", "#e0a18d"],
|
|
55
|
+
SSS: ["#bd9fb7", "#906f8f", "#f0e8ef", "#7e68a0", "#d3bd8d"]
|
|
56
|
+
};
|
|
57
|
+
var magicSizes = { F: 100, E: 108, D: 118, C: 130, B: 144, A: 160, S: 176, SS: 192, SSS: 208 };
|
|
58
|
+
function normalizeCardQuality(value) {
|
|
59
|
+
const grade = String(value ?? "").trim().toUpperCase().replace(/\s*级$/, "").trim();
|
|
60
|
+
return Object.prototype.hasOwnProperty.call(colors, grade) ? grade : "F";
|
|
61
|
+
}
|
|
62
|
+
__name(normalizeCardQuality, "normalizeCardQuality");
|
|
63
|
+
function qualityStyle(value) {
|
|
64
|
+
const grade = normalizeCardQuality(value);
|
|
65
|
+
const color = colors[grade];
|
|
66
|
+
return ["accent", "ink", "light", "start", "end"].map((key, index) => "--quality-" + key + ":" + color[index]).join(";") + ";--magic-base:" + magicSizes[grade];
|
|
67
|
+
}
|
|
68
|
+
__name(qualityStyle, "qualityStyle");
|
|
69
|
+
var number = /* @__PURE__ */ __name((value) => String(Math.round(value * 1e4) / 1e4), "number");
|
|
70
|
+
function qualityMagicCircle(value) {
|
|
71
|
+
const q = normalizeCardQuality(value);
|
|
72
|
+
const rank = Object.keys(colors).indexOf(q);
|
|
73
|
+
const point = /* @__PURE__ */ __name((r, angle) => {
|
|
74
|
+
const a = angle * Math.PI / 180;
|
|
75
|
+
return [number(Math.cos(a) * r), number(Math.sin(a) * r)];
|
|
76
|
+
}, "point");
|
|
77
|
+
const ring = /* @__PURE__ */ __name((r, dash = "") => `<circle r="${r}"${dash ? ` stroke-dasharray="${dash}"` : ""}/>`, "ring");
|
|
78
|
+
const polygon = /* @__PURE__ */ __name((sides, r, turn = -90) => `<polygon points="${Array.from({ length: sides }, (_, i) => point(r, turn + i * 360 / sides).join(",")).join(" ")}"/>`, "polygon");
|
|
79
|
+
const star = /* @__PURE__ */ __name((tips, outer, inner2, turn = -90) => `<polygon points="${Array.from({ length: tips * 2 }, (_, i) => point(i % 2 ? inner2 : outer, turn + i * 180 / tips).join(",")).join(" ")}"/>`, "star");
|
|
80
|
+
const ticks = /* @__PURE__ */ __name((count, r, length = 5) => Array.from({ length: count }, (_, i) => {
|
|
81
|
+
const a = i * 360 / count - 90;
|
|
82
|
+
const [x1, y1] = point(r, a), [x2, y2] = point(r + length, a);
|
|
83
|
+
return `<path d="M${x1} ${y1} ${x2} ${y2}"/>`;
|
|
84
|
+
}).join(""), "ticks");
|
|
85
|
+
const gems = /* @__PURE__ */ __name((count, r, size = 3, turn = -90) => Array.from({ length: count }, (_, i) => {
|
|
86
|
+
const [x, y] = point(r, turn + i * 360 / count);
|
|
87
|
+
return `<path transform="translate(${x} ${y})" d="M0 ${-size} ${size} 0 0 ${size} ${-size} 0Z"/>`;
|
|
88
|
+
}).join(""), "gems");
|
|
89
|
+
const petals = /* @__PURE__ */ __name((count, r, depth, spread) => Array.from({ length: count }, (_, i) => `<path transform="rotate(${i * 360 / count})" d="M0 ${-r} C${spread} ${-r - depth / 2} ${spread} ${-r - depth} 0 ${-r - depth} C${-spread} ${-r - depth} ${-spread} ${-r - depth / 2} 0 ${-r}Z"/>`).join(""), "petals");
|
|
90
|
+
const inner = number(45 * 240 / magicSizes[q]);
|
|
91
|
+
let orbits = ring(inner), rays = "", marks = "", detail = "";
|
|
92
|
+
switch (q) {
|
|
93
|
+
case "F":
|
|
94
|
+
orbits = ring(106);
|
|
95
|
+
break;
|
|
96
|
+
case "E":
|
|
97
|
+
orbits += ring(110);
|
|
98
|
+
detail = ticks(4, 102, 7);
|
|
99
|
+
marks = gems(4, 112, 2);
|
|
100
|
+
break;
|
|
101
|
+
case "D":
|
|
102
|
+
orbits += ring(106) + polygon(4, 114);
|
|
103
|
+
detail = ticks(8, 98, 5);
|
|
104
|
+
marks = gems(4, 111, 3, 0);
|
|
105
|
+
break;
|
|
106
|
+
case "C":
|
|
107
|
+
orbits += ring(96) + ring(108, "21 5");
|
|
108
|
+
rays = star(4, 117, 82);
|
|
109
|
+
detail = ticks(8, 99, 7);
|
|
110
|
+
marks = gems(4, 109, 3, -45);
|
|
111
|
+
break;
|
|
112
|
+
case "B":
|
|
113
|
+
orbits += ring(91) + ring(109);
|
|
114
|
+
rays = polygon(3, 104) + polygon(3, 104, 90);
|
|
115
|
+
detail = ticks(12, 98, 5);
|
|
116
|
+
marks = gems(6, 111, 3);
|
|
117
|
+
break;
|
|
118
|
+
case "A":
|
|
119
|
+
orbits += ring(86) + ring(103);
|
|
120
|
+
rays = star(8, 115, 80) + polygon(8, 93, -67.5);
|
|
121
|
+
detail = ticks(16, 103, 5);
|
|
122
|
+
marks = gems(8, 111, 3.5);
|
|
123
|
+
break;
|
|
124
|
+
case "S":
|
|
125
|
+
orbits += ring(83) + ring(101) + ring(110, "2 4");
|
|
126
|
+
rays = star(12, 116, 87) + polygon(6, 92);
|
|
127
|
+
detail = ticks(24, 104, 4);
|
|
128
|
+
marks = gems(12, 113, 3);
|
|
129
|
+
break;
|
|
130
|
+
case "SS":
|
|
131
|
+
orbits += ring(80) + ring(98) + ring(108);
|
|
132
|
+
rays = star(8, 115, 77) + star(8, 103, 73, -67.5);
|
|
133
|
+
detail = `<ellipse rx="108" ry="58" transform="rotate(35)"/><ellipse rx="108" ry="58" transform="rotate(-35)"/>` + ticks(24, 106, 5);
|
|
134
|
+
marks = gems(8, 114, 4) + gems(8, 96, 2, -67.5);
|
|
135
|
+
break;
|
|
136
|
+
case "SSS":
|
|
137
|
+
orbits += ring(77) + ring(96) + ring(111, "3 4");
|
|
138
|
+
rays = petals(12, 76, 38, 13) + star(8, 116, 83) + star(8, 101, 77, -67.5);
|
|
139
|
+
detail = ticks(32, 101, 5) + polygon(4, 93, -45) + polygon(4, 93);
|
|
140
|
+
marks = gems(4, 114, 5) + gems(12, 108, 2.5, -75);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
return `<svg class="magic-circle magic-${q.toLowerCase()}" data-rank="${rank}" viewBox="-120 -120 240 240" fill="none" aria-hidden="true"><g class="magic-rays">${rays}</g><g class="magic-orbits">${orbits}</g><g class="magic-detail">${detail}</g><g class="magic-marks">${marks}</g></svg>`;
|
|
144
|
+
}
|
|
145
|
+
__name(qualityMagicCircle, "qualityMagicCircle");
|
|
146
|
+
var circle = /* @__PURE__ */ __name((radius, stroke, width, opacity = 1) => '<circle cx="0" cy="0" r="' + radius + '" fill="none" stroke="' + stroke + '" stroke-width="' + width + '" opacity="' + opacity + '"/>', "circle");
|
|
147
|
+
var metal = /* @__PURE__ */ __name((radius, width, opacity = 1) => circle(radius, "currentColor", width, opacity), "metal");
|
|
148
|
+
var light = /* @__PURE__ */ __name((radius, width, opacity = 0.65) => circle(radius, "#fff5df", width, opacity), "light");
|
|
149
|
+
var shadow = /* @__PURE__ */ __name((radius, width, opacity = 0.7) => circle(radius, "#15191f", width, opacity), "shadow");
|
|
150
|
+
var repeat = /* @__PURE__ */ __name((angles, shape) => angles.map((angle) => '<g transform="rotate(' + angle + ')">' + shape + "</g>").join(""), "repeat");
|
|
151
|
+
var base = /* @__PURE__ */ __name((width = 2) => shadow(46.5, width + 1.8, 0.78) + metal(46.5, width) + light(45.2, 0.5, 0.6), "base");
|
|
152
|
+
var designs = {
|
|
153
|
+
F: shadow(45.7, 1.5, 0.4) + metal(45.7, 0.9, 0.72) + light(46.45, 0.35, 0.5),
|
|
154
|
+
E: base(2.2) + metal(48.4, 0.6, 0.65) + repeat([0, 180], '<path d="M-5-48.5 H5" stroke="#fff5df" stroke-width=".8" opacity=".58"/>'),
|
|
155
|
+
D: base(1.8) + shadow(49.1, 1.8, 0.7) + metal(49.1, 0.95, 0.85) + light(48.5, 0.35, 0.42),
|
|
156
|
+
C: base(2.2) + metal(49.4, 0.85, 0.8) + repeat([90, 270], '<path d="M-3.5-46.3 H3.5 L4.2-51.3 H-4.2 Z" fill="currentColor" stroke="#192332" stroke-width=".7"/><path d="M-2.7-50.5 H2.7" stroke="#f0f5fc" stroke-width=".8" opacity=".8"/><path d="M0-47.2 V-50.6" stroke="#f0f5fc" stroke-width=".45" opacity=".55"/>'),
|
|
157
|
+
B: base(2.6) + metal(49.3, 0.65, 0.7) + repeat([0, 90, 180, 270], '<path d="M0-55 L3.8-50.8 0-46.7-3.8-50.8 Z" fill="currentColor" stroke="#211827" stroke-width=".8"/><path d="M0-54.1 2.8-50.8 0-49.5-2.8-50.8 Z" fill="#fff4f7" opacity=".52"/><path d="M0-49.5 V-47.4" stroke="#161320" stroke-width=".55" opacity=".65"/>'),
|
|
158
|
+
A: base(3.1) + light(48.2, 0.45, 0.65) + repeat([45, 135, 225, 315], '<path d="M-4-46.1 H4 L5.2-50.1 0-54.6-5.2-50.1 Z" fill="currentColor" stroke="#302316" stroke-width=".8"/><path d="M-3.5-49.8 0-53.6 3.5-49.8 0-48.6 Z" fill="#ffe9ba" opacity=".7"/><path d="M-3.5-49.8 0-48.6 0-46.6 H-3.2 Z" fill="#4e3017" opacity=".42"/>'),
|
|
159
|
+
S: base(3.3) + metal(49.4, 0.7, 0.9) + light(48.5, 0.6, 0.75) + repeat([0, 180], '<path d="M-7.6-47.1-5.6-51.1-2.5-50.1 0-55 2.5-50.1 5.6-51.1 7.6-47.1 3.6-48.4 0-50.4-3.6-48.4 Z" fill="currentColor" stroke="#3f3118" stroke-width=".8"/><path d="M-5.6-50.2-2.2-49.4 0-53.5 2.2-49.4 5.6-50.2" fill="none" stroke="#fff2c8" stroke-width=".8" opacity=".92"/><path d="M0-49.8 1.5-48.2 0-46.9-1.5-48.2 Z" fill="#fff3c8" opacity=".9"/>'),
|
|
160
|
+
SS: base(3.7) + metal(49.6, 0.75, 0.8) + light(48.55, 0.55, 0.6) + repeat([0, 90, 180, 270], '<path d="M-5-47.2-5.7-51.3 0-55 5.7-51.3 5-47.2 0-46.1 Z" fill="currentColor" stroke="#34191d" stroke-width=".85"/><path d="M-4.4-50.9 0-53.9 4.4-50.9 0-49.4 Z" fill="#ffddd0" opacity=".66"/><path d="M-4.4-50.9 0-49.4 V-47.1 L-3.9-47.8 Z" fill="#3c151c" opacity=".55"/><path d="M0-53.4 V-50.3" stroke="#fff2db" stroke-width=".65" opacity=".85"/>'),
|
|
161
|
+
SSS: shadow(46.7, 5.2, 0.86) + metal(46.7, 3.5, 1) + light(45.2, 0.6, 0.8) + shadow(50, 2.5, 0.75) + circle(50, "#d7b76f", 1.4, 0.95) + light(49.45, 0.45, 0.85) + repeat([0, 90, 180, 270], '<path d="M0-55 2.2-52.6 5.1-51 2.2-49.4 0-46.8-2.2-49.4-5.1-51-2.2-52.6 Z" fill="#d7b76f" stroke="#31213b" stroke-width=".8"/><path d="M0-54 1.5-52 3.4-51 1.5-50 0-48-1.5-50-3.4-51-1.5-52 Z" fill="currentColor"/><path d="M0-53.1 1.15-51 0-49.4-1.15-51 Z" fill="#fff4e7" opacity=".8"/>')
|
|
162
|
+
};
|
|
163
|
+
function qualityIconFrame(value) {
|
|
164
|
+
const grade = normalizeCardQuality(value);
|
|
165
|
+
return '<svg class="skill-icon-frame" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="-60 -60 120 120" fill="none" stroke-linejoin="round" stroke-linecap="round">' + designs[grade] + "</svg>";
|
|
166
|
+
}
|
|
167
|
+
__name(qualityIconFrame, "qualityIconFrame");
|
|
168
|
+
|
|
169
|
+
// src/plugin/qualityCardStyles.ts
|
|
170
|
+
var qualityCardStyles = `
|
|
171
|
+
*{box-sizing:border-box}
|
|
172
|
+
html,body{margin:0;width:760px;background:#e9e9e2;font-family:'Microsoft YaHei','Noto Sans CJK SC',sans-serif;color:#303735}
|
|
173
|
+
#capture{width:760px;padding:18px;background:radial-gradient(ellipse at 70% 10%,#f9f7efb8,transparent 55%),#e9e9e2}
|
|
174
|
+
h1,h2,h3,p{margin:0}
|
|
175
|
+
.detail-card{position:relative;width:100%;isolation:isolate;border:3px solid color-mix(in srgb,var(--quality-accent) 50%,#454a45);border-radius:18px;box-shadow:0 8px 18px #3f47321c;background:#f5f4ed;overflow:visible;--corner-size:24px;--corner-metal:#dce1d6;--corner-cut:polygon(0 0,100% 13%,75% 50%,100% 100%,50% 75%,13% 100%)}
|
|
176
|
+
.card-inner{overflow:hidden;border-radius:14px}
|
|
177
|
+
.card-corner{position:absolute;width:var(--corner-size);height:var(--corner-size);z-index:5;background:linear-gradient(135deg,#faf9eb,var(--corner-metal));border:1px solid #7b8075;clip-path:var(--corner-cut);filter:drop-shadow(0 1px 2px #0009)}
|
|
178
|
+
.card-corner:after{content:'';position:absolute;inset:6px;background:color-mix(in srgb,var(--quality-accent) 80%,#4e584b);clip-path:var(--corner-cut)}
|
|
179
|
+
.corner-tl{top:-7px;left:-7px}.corner-tr{top:-7px;right:-7px;transform:rotate(90deg)}.corner-br{bottom:-7px;right:-7px;transform:rotate(180deg)}.corner-bl{bottom:-7px;left:-7px;transform:rotate(270deg)}
|
|
180
|
+
.quality-f{--corner-size:13.5px;--corner-metal:#a6afa4;--corner-cut:polygon(0 0,100% 0,100% 30%,30% 30%,30% 100%,0 100%)}
|
|
181
|
+
.quality-f .card-corner:after{display:none}
|
|
182
|
+
.quality-e{--corner-size:18px;--corner-metal:#a6c1a7;--corner-cut:polygon(0 0,100% 0,85% 28%,37% 37%,28% 85%,0 100%)}
|
|
183
|
+
.quality-d{--corner-size:21px;--corner-metal:#87c3b1;--corner-cut:polygon(0 0,70% 10%,100% 45%,45% 100%,10% 70%)}
|
|
184
|
+
.quality-c{--corner-metal:#acd5ed}
|
|
185
|
+
.quality-b{--corner-size:25.5px;--corner-metal:#c2a5dc;--corner-cut:polygon(0 0,58% 14%,100% 4%,86% 47%,100% 100%,47% 86%,4% 100%,14% 58%)}
|
|
186
|
+
.quality-a{--corner-size:27px;--corner-metal:#e2ba7b}
|
|
187
|
+
.quality-s{--corner-size:30px;--corner-metal:#e2ca7c;--corner-cut:polygon(0 0,70% 9%,100% 0,86% 30%,67% 45%,100% 100%,45% 67%,30% 86%,0 100%,9% 70%)}
|
|
188
|
+
.quality-ss{--corner-size:30px;--corner-metal:#dea595;--corner-cut:polygon(0 0,78% 14%,100% 43%,70% 70%,43% 100%,14% 78%)}
|
|
189
|
+
.quality-sss{--corner-size:34.5px;--corner-metal:#d6b575;--corner-cut:polygon(0 0,55% 14%,100% 3%,82% 30%,68% 50%,100% 100%,50% 68%,30% 82%,3% 100%,14% 55%)}
|
|
190
|
+
.quality-sss .card-corner:after{background:#9d79ac}
|
|
191
|
+
.card-titlebar{position:relative;isolation:isolate;display:flex;align-items:center;gap:18px;min-height:98px;padding:27px 35px;background:linear-gradient(112deg,var(--quality-start),var(--quality-end));border-bottom:4px solid var(--quality-accent);color:#fffbee}
|
|
192
|
+
.card-titlebar:before{content:'';position:absolute;inset:0;z-index:-1;background-image:radial-gradient(circle,#fff7 1.5px,transparent 2.2px),linear-gradient(30deg,transparent 65%,#ffffff1a 65.2%,transparent 65.6%);background-size:118px 95px,100% 100%;opacity:.55}
|
|
193
|
+
.card-titlebar h1{min-width:0;flex:1;font-size:35px;line-height:1.4;letter-spacing:1px;font-weight:600;text-shadow:0 1px 2px #2c292348;overflow-wrap:anywhere}
|
|
194
|
+
.title-glyph{font-size:31px;line-height:1;color:#fff6cecc}.title-star{font:38px Georgia;opacity:.75}
|
|
195
|
+
.card-hero{position:relative;isolation:isolate;display:flex;align-items:center;justify-content:space-between;gap:24px;min-height:228px;padding:30px 36px;color:#eeeedd;background:radial-gradient(ellipse at 0 0,color-mix(in srgb,var(--quality-accent) 33%,transparent),transparent 65%),#272f30}
|
|
196
|
+
.card-hero:before{content:'';position:absolute;inset:0;z-index:-1;opacity:.16;background-image:radial-gradient(circle,#d3d4bd 1px,transparent 1.2px);background-size:7.5px 7.5px;mask-image:linear-gradient(to bottom,#000,transparent 74%)}
|
|
197
|
+
.hero-copy{flex:1;min-width:0;align-self:stretch;display:flex;flex-direction:column;justify-content:space-between}
|
|
198
|
+
.hero-meta{display:flex;flex-direction:column;align-items:flex-start;gap:15px;margin-bottom:25px}
|
|
199
|
+
.skill-type{font-size:24px;letter-spacing:3px;color:#cbcdbd}
|
|
200
|
+
.quality-badge{display:inline-flex;align-items:center;gap:9px;padding:6px 14px;color:#fff5de;font-size:18px;font-weight:600;border:1px solid color-mix(in srgb,var(--quality-accent) 70%,transparent);border-radius:6px;background:color-mix(in srgb,var(--quality-accent) 17%,transparent)}
|
|
201
|
+
.quality-badge b{color:var(--quality-end);font:700 24px Georgia,serif}
|
|
202
|
+
.tags{display:flex;gap:7px;flex-wrap:wrap}
|
|
203
|
+
.tag{font-size:20px;line-height:1.3;padding:6px 10px;border-radius:4px;overflow-wrap:anywhere;color:#bfcaed;background:#647bb434;border:1px solid #7d9cc62b}
|
|
204
|
+
.tag.damage{color:#f5ae94;background:#b961433d;border-color:#b4614340}.tag.shield{color:#a3d7b7;background:#5186683d;border-color:#73a48a40}.tag.heal{color:#b5deb0;background:#668e4a3b;border-color:#89a47140}.tag.passive{color:#cebbef;background:#8367a63d;border-color:#9682b540}.tag.growth{color:#ecd291;background:#b1944540;border-color:#ab944e40}
|
|
205
|
+
.hero-icon-wrap{--icon-size:120px;--magic-size:calc(var(--magic-base) * 1.5px);position:relative;flex-shrink:0;width:var(--magic-size);height:var(--magic-size)}
|
|
206
|
+
.magic-circle{position:absolute;width:100%;height:100%;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--quality-end);pointer-events:none;overflow:visible}
|
|
207
|
+
.magic-rays{stroke:currentColor;stroke-width:.9;opacity:.28}.magic-orbits{stroke:currentColor;stroke-width:1.2;opacity:.42}.magic-detail{stroke:currentColor;stroke-width:.9;opacity:.45}.magic-marks{fill:currentColor;opacity:.68}
|
|
208
|
+
.magic-sss .magic-rays{stroke:#ddbc80;opacity:.49}.magic-sss .magic-detail{stroke:#bb9ccc;opacity:.64}.magic-sss .magic-marks{fill:#eed093;opacity:.88}
|
|
209
|
+
.quality-s .magic-circle,.quality-ss .magic-circle,.quality-sss .magic-circle{filter:drop-shadow(0 0 4px color-mix(in srgb,var(--quality-accent) 30%,transparent))}
|
|
210
|
+
.skill-artwork,.art-fallback{position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);width:var(--icon-size);height:var(--icon-size);border:1.5px solid #bfc6b7;border-radius:50%;box-shadow:0 4px 13px #0007;object-fit:cover;object-position:center}
|
|
211
|
+
.art-fallback{display:grid;place-items:center;color:var(--quality-end);font:44px 'KaiTi','SimSun',serif;background:radial-gradient(circle,#53615b,#1f2928)}
|
|
212
|
+
.skill-icon-frame{position:absolute;top:50%;left:50%;width:calc(var(--icon-size) + 45px);height:calc(var(--icon-size) + 45px);transform:translate(-50%,-50%);z-index:2;color:var(--quality-accent);pointer-events:none;filter:drop-shadow(0 1px 1px #10181480)}
|
|
213
|
+
.quality-sss .hero-icon-wrap{background:radial-gradient(ellipse,#ad85d525,transparent 68%)}
|
|
214
|
+
.card-body{padding:32px 36px 34px;background:linear-gradient(145deg,#faf9f3,#eeeee7)}
|
|
215
|
+
.effect-stats{display:grid;gap:9px;margin-bottom:27px}
|
|
216
|
+
.stat-row{display:flex;align-items:center;justify-content:space-between;gap:18px;min-height:54px;padding:13px 18px;background:#e5e7de;border-radius:6px;font-size:24px}
|
|
217
|
+
.stat-row>span{color:#626d57;flex:0 0 auto;max-width:45%;overflow-wrap:anywhere}
|
|
218
|
+
.stat-row b{min-width:0;text-align:right;overflow-wrap:anywhere;font-size:30px;color:var(--quality-ink);font-weight:600}
|
|
219
|
+
.stat-row.detail-stat b{font-size:26px;font-weight:500;color:#4f594b;background:none;-webkit-text-fill-color:currentColor}
|
|
220
|
+
.stat-row .param-unit{font-size:24px;font-weight:400;color:#75816d;-webkit-text-fill-color:currentColor}
|
|
221
|
+
.stat-value{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:flex-end;gap:9px}
|
|
222
|
+
.stat-value .stat-unit{font-size:24px;font-weight:400;color:#737c68;-webkit-text-fill-color:currentColor}
|
|
223
|
+
.section-heading{display:flex;align-items:center;gap:10px;margin:0 0 16px;font-size:24px;font-weight:500;letter-spacing:2px;color:#6f7d60}
|
|
224
|
+
.section-heading:before{content:'◆';font-size:10px;color:var(--quality-accent)}
|
|
225
|
+
.description{font-size:28px;line-height:1.85;color:#515b4c;overflow-wrap:anywhere;white-space:pre-wrap}
|
|
226
|
+
.description .number{color:var(--quality-ink);font-weight:600}.description .keyword{color:#907843;font-weight:500}
|
|
227
|
+
.growth-section,.note-section{border-top:1px solid #d6dacd;margin-top:27px;padding-top:24px}
|
|
228
|
+
.growth-section .description{color:#5c684f}
|
|
229
|
+
.note-section .description{font-size:26px;color:#626d57}
|
|
230
|
+
.quality-sss .card-titlebar{background:linear-gradient(110deg,#7c679e,#a77c95 50%,#cba770)}
|
|
231
|
+
.quality-sss .quality-badge{border-color:#d3c192}
|
|
232
|
+
.quality-sss .stat-number{background:linear-gradient(90deg,#936891,#ab884d);background-clip:text;-webkit-text-fill-color:transparent}
|
|
233
|
+
`;
|
|
234
|
+
|
|
235
|
+
// src/plugin/detailCardTemplate.ts
|
|
236
|
+
var cardEscape = /* @__PURE__ */ __name((value) => String(value ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]), "cardEscape");
|
|
237
|
+
function detailCardQuality(value) {
|
|
238
|
+
const grade = String(value ?? "").trim().toUpperCase().replace(/\s*级$/, "").trim();
|
|
239
|
+
return ["F", "E", "D", "C", "B", "A", "S", "SS", "SSS"].includes(grade) ? normalizeCardQuality(grade) : void 0;
|
|
240
|
+
}
|
|
241
|
+
__name(detailCardQuality, "detailCardQuality");
|
|
242
|
+
function cardStatRow(label, value, primary = false) {
|
|
243
|
+
const match = primary ? value.match(/^([+-]?\d+(?:,\d{3})*(?:\.\d+)?%?)\s*(.*)$/) : void 0;
|
|
244
|
+
const display = match ? `<span class="stat-number">${cardEscape(match[1])}</span>${match[2] ? `<small class="stat-unit">${cardEscape(match[2])}</small>` : ""}` : cardEscape(value);
|
|
245
|
+
return `<div class="stat-row${primary ? "" : " detail-stat"}"><span>${cardEscape(label)}</span><b${primary ? ' class="stat-value"' : ""}>${display}</b></div>`;
|
|
246
|
+
}
|
|
247
|
+
__name(cardStatRow, "cardStatRow");
|
|
248
|
+
function cardSection(title, body) {
|
|
249
|
+
return `<section class="detail-section"><h2 class="section-heading">${cardEscape(title)}</h2>${body}</section>`;
|
|
250
|
+
}
|
|
251
|
+
__name(cardSection, "cardSection");
|
|
252
|
+
function cardBodyText(value) {
|
|
253
|
+
return value.split(/(\d+(?:\.\d+)?%?)/g).map((part) => /^\d+(?:\.\d+)?%?$/.test(part) ? `<span class="number">${cardEscape(part)}</span>` : cardEscape(part)).join("");
|
|
254
|
+
}
|
|
255
|
+
__name(cardBodyText, "cardBodyText");
|
|
256
|
+
var neutralStyle = "--quality-accent:#afb9c1;--quality-ink:#52616c;--quality-light:#ecf0f1;--quality-start:#56616d;--quality-end:#77828a;--magic-base:140";
|
|
257
|
+
var neutralMagic = '<svg class="magic-circle magic-neutral" aria-hidden="true" viewBox="-120 -120 240 240" fill="none"><g class="magic-orbits"><circle r="98"/><circle r="112"/></g><g class="magic-detail"><path d="M0-108V-116 M108 0H116 M0 108V116 M-108 0H-116"/></g></svg>';
|
|
258
|
+
var neutralFrame = '<svg class="skill-icon-frame" aria-hidden="true" viewBox="-60 -60 120 120" fill="none"><circle r="46.5" stroke="#15191f" stroke-width="4"/><circle r="46.5" stroke="#c1cbd0" stroke-width="1.6"/><circle r="49.5" stroke="#afb9c1" stroke-width=".8"/><circle r="45.4" stroke="#f2f4ef" stroke-width=".5"/></svg>';
|
|
259
|
+
function detailCardHtml(options) {
|
|
260
|
+
const quality = detailCardQuality(options.quality);
|
|
261
|
+
const artClass = options.artworkClass ?? "item-artwork";
|
|
262
|
+
const styles = `${qualityCardStyles}
|
|
263
|
+
.detail-section+.detail-section{border-top:1px solid #d6dacd;margin-top:27px;padding-top:24px}
|
|
264
|
+
.item-artwork{position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);width:var(--icon-size);height:var(--icon-size);border:1.5px solid #bfc6b7;border-radius:50%;object-fit:cover;object-position:center;box-shadow:0 4px 13px #0007}
|
|
265
|
+
.quality-none{--corner-size:18px;--corner-metal:#bcc7cd;--corner-cut:polygon(0 0,100% 0,100% 22%,40% 40%,22% 100%,0 100%);border-color:#69777e}
|
|
266
|
+
.quality-none .card-corner:after{background:#596970}
|
|
267
|
+
.quality-none .card-titlebar{border-bottom:2px solid #afb9c1}
|
|
268
|
+
.quality-none .card-hero{background:radial-gradient(ellipse at 0 0,#8799a51c,transparent 65%),#272f30}
|
|
269
|
+
.quality-none .magic-circle{color:#aebcc4}
|
|
270
|
+
.quality-none .hero-meta{margin-bottom:0}
|
|
271
|
+
.quality-none .stat-number{color:#52616c}
|
|
272
|
+
.detail-portrait{display:block;width:100%;height:auto;max-height:900px;object-fit:contain;background:#ebece5;border:1px solid #d0d5c8;border-radius:8px}
|
|
273
|
+
.detail-note{font-size:26px;line-height:1.75;color:#626d57;overflow-wrap:anywhere;white-space:pre-wrap}
|
|
274
|
+
.detail-list{display:grid;gap:9px}
|
|
275
|
+
.empty-line{font-size:26px;line-height:1.75;color:#7a8472;overflow-wrap:anywhere}
|
|
276
|
+
.art-status{color:#c2cbbc;font-size:20px;line-height:1.5;overflow-wrap:anywhere}
|
|
277
|
+
`;
|
|
278
|
+
return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><style>${styles}</style></head><body><div id="capture" class="detail-sheet ${cardEscape(options.sheetClass || "item-sheet")}"><article class="detail-card ${quality ? "quality-" + quality.toLowerCase() : "quality-none"}" style="${quality ? qualityStyle(quality) : neutralStyle}">
|
|
279
|
+
<i class="card-corner corner-tl" aria-hidden="true"></i><i class="card-corner corner-tr" aria-hidden="true"></i><i class="card-corner corner-bl" aria-hidden="true"></i><i class="card-corner corner-br" aria-hidden="true"></i>
|
|
280
|
+
<div class="card-inner"><header class="card-titlebar"><span class="title-glyph" aria-hidden="true">◇</span><h1>${cardEscape(options.name)}</h1><span class="title-star" aria-hidden="true">✦</span></header>
|
|
281
|
+
<div class="card-hero"><div class="hero-copy"><div class="hero-meta"><span class="skill-type">${cardEscape(options.type)}</span>${quality ? `<span class="quality-badge"><b>${quality}</b> 级</span>` : ""}</div><div class="tags">${(options.tags || []).map((tag) => `<span class="tag">${cardEscape(tag)}</span>`).join("")}</div></div>
|
|
282
|
+
<div class="hero-icon-wrap">${quality ? qualityMagicCircle(quality) : neutralMagic}<div class="art-fallback" aria-hidden="true">${cardEscape(options.fallbackGlyph || "物")}</div>${options.artwork ? `<img class="${artClass}" alt="${cardEscape(options.name)}图标" src="${cardEscape(options.artwork)}">` : ""}${quality ? qualityIconFrame(quality) : neutralFrame}</div></div>
|
|
283
|
+
<div class="card-body">${options.body}</div></div></article></div></body></html>`;
|
|
284
|
+
}
|
|
285
|
+
__name(detailCardHtml, "detailCardHtml");
|
|
286
|
+
|
|
287
|
+
// src/plugin/itemCardTemplate.ts
|
|
288
|
+
function itemCardHtml(card, artwork, _paper, fullPortrait = false) {
|
|
289
|
+
const rows = cardStatRow("数量", card.count || "1") + cardStatRow("参考价格", card.referencePrice || "暂无") + (card.rows || []).map((row) => cardStatRow(row.label, row.value)).join("");
|
|
290
|
+
const portrait = fullPortrait && artwork ? cardSection("形象预览", `<img class="detail-portrait" src="${cardEscape(artwork)}" alt="${cardEscape(card.name)}完整形象">`) : "";
|
|
291
|
+
const body = `<div class="effect-stats">${rows}</div>` + cardSection("物品说明", `<p class="description item-description">${cardBodyText(card.description || "暂无描述")}</p>`) + (card.useDescription?.trim() ? cardSection("使用效果", `<p class="description item-use-description">${cardBodyText(card.useDescription.trim())}</p>`) : "") + portrait;
|
|
292
|
+
return detailCardHtml({ name: card.name, quality: card.quality, type: card.type || "道具", artwork, artworkClass: "item-artwork", body, sheetClass: fullPortrait ? "item-sheet appearance-sheet" : "item-sheet", fallbackGlyph: fullPortrait ? "像" : "物" });
|
|
293
|
+
}
|
|
294
|
+
__name(itemCardHtml, "itemCardHtml");
|
|
295
|
+
|
|
45
296
|
// src/plugin/appearanceCardTemplate.ts
|
|
46
|
-
var escape = /* @__PURE__ */ __name((value) => String(value ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]), "escape");
|
|
47
297
|
function appearanceCardHtml(card, artwork, paper) {
|
|
48
|
-
return
|
|
49
|
-
*{box-sizing:border-box}html,body{margin:0;width:760px;background:#ece8df;color:#625a49;font-family:'Microsoft YaHei','Noto Sans CJK SC',sans-serif}
|
|
50
|
-
#capture{width:760px;padding:25px 18px 29px;background:radial-gradient(ellipse at center,#f6f2e9,#e4ded2)}
|
|
51
|
-
.scroll{position:relative;padding:18px 0}.sheet{position:relative;margin:0 29px;padding:0 23px;background:#eee5cf;border-left:1px solid #b8a37b;border-right:1px solid #b8a37b;box-shadow:0 7px 16px #49381c24;overflow:hidden}
|
|
52
|
-
.paper{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.22;pointer-events:none}.sheet:after{content:'';position:absolute;inset:0;pointer-events:none;box-shadow:inset 0 18px 20px -18px #49351cb0,inset 0 -18px 20px -18px #49351c90}
|
|
53
|
-
.title{position:relative;margin:0;padding:29px 0 23px;text-align:center;font-family:'KaiTi','STKaiti','SimSun',serif;font-size:34px;font-weight:400;line-height:1.4;letter-spacing:8px;color:#514630}.portrait{position:relative;padding:5px;border:1px solid #ae9360;background:#e8dec5}.item-artwork{display:block;width:100%;height:auto;aspect-ratio:3/5;object-fit:contain}
|
|
54
|
-
.details{position:relative;display:flex;justify-content:flex-end;gap:24px;padding:24px 8px 29px;font-size:17px;line-height:1.6;letter-spacing:1px}.details span{min-width:0;overflow-wrap:anywhere}.details span:last-child{text-align:right}.details b{font-weight:400;color:#403c31;margin-left:10px}
|
|
55
|
-
.roller{position:absolute;left:12px;right:12px;height:30px;z-index:2;border:1px solid #665033;border-radius:5px;background:linear-gradient(180deg,#695136 0%,#aa8b5f 16%,#dfc89a 38%,#b99a67 56%,#80613c 84%,#503a26 100%);box-shadow:0 4px 6px #44311933}.roller.top{top:0}.roller.bottom{bottom:0;height:34px}.roller:before,.roller:after{content:'';position:absolute;top:-4px;width:22px;height:calc(100% + 8px);border:1px solid #443321;border-radius:5px;background:linear-gradient(180deg,#493727,#987b50 28%,#bda071 42%,#745533 65%,#3d2d20);box-shadow:inset 3px 0 2px #d2b88166,inset -3px 0 2px #2c201c66}.roller:before{left:-14px}.roller:after{right:-14px}
|
|
56
|
-
</style></head><body><article id="capture"><div class="scroll"><div class="roller top" aria-hidden="true"></div><div class="sheet">${paper ? `<img class="paper" src="${escape(paper)}" alt="" aria-hidden="true">` : ""}<h1 class="title">形象卡</h1><div class="portrait"><img class="item-artwork" src="${escape(artwork)}" alt="${escape(card.name)}"></div><div class="details"><span>参考价格<b>${escape(card.referencePrice)}</b></span></div></div><div class="roller bottom" aria-hidden="true"></div></div></article></body></html>`;
|
|
298
|
+
return itemCardHtml(card, artwork, paper, true);
|
|
57
299
|
}
|
|
58
300
|
__name(appearanceCardHtml, "appearanceCardHtml");
|
|
59
301
|
|
|
60
|
-
// src/plugin/
|
|
61
|
-
var
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
.
|
|
68
|
-
.quality{grid-column:3;grid-row:1;justify-self:end;display:flex;align-items:center;gap:8px;flex-shrink:0}.quality-label{writing-mode:vertical-rl;font-size:18px;letter-spacing:4px}.quality-seal{border:3px double #a33f31;padding:8px 5px;min-width:68px;max-width:116px;text-align:center;color:#a33f31;font-family:KaiTi,STKaiti,serif;font-size:33px;font-weight:bold;box-shadow:inset 0 0 0 2px #a33f3126;overflow-wrap:anywhere}
|
|
69
|
-
.item-type{text-align:center;font-size:24px;margin:16px 0 22px;overflow-wrap:anywhere}
|
|
70
|
-
.item-art-frame{width:548px;height:548px;padding:8px;margin:0 auto;border:2px solid #4b473d;outline:1px solid #4b473d88;outline-offset:4px;background:#eee6d5}
|
|
71
|
-
.item-artwork{display:block;width:100%;height:100%;object-fit:cover;background:#ede6d8}
|
|
72
|
-
.item-count{display:flex;gap:20px;justify-content:center;align-items:center;font-size:26px;margin:25px 0 30px;overflow-wrap:anywhere}.item-count:before,.item-count:after{content:'';height:1px;width:85px;background:#77705f88}
|
|
73
|
-
.description-title{display:flex;align-items:center;gap:22px;font-family:KaiTi,STKaiti,serif;font-size:34px;font-weight:bold;margin-bottom:16px}.description-title:after{content:'';height:1px;background:#655e5088;flex:1}
|
|
74
|
-
.item-description{font-size:25px;line-height:1.75;white-space:pre-wrap;overflow-wrap:anywhere;margin:0 0 42px;min-height:88px}
|
|
75
|
-
.item-price{border-top:1px solid #736b5b88;padding-top:22px;font-size:24px;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
76
|
-
</style></head><body><article id="capture"><div class="catalog-label">道具图鉴</div><header class="item-heading"><h1 class="item-title">${escape2(card.name)}</h1><div class="quality"><span class="quality-label">品质</span><span class="quality-seal">${escape2(card.quality)}</span></div></header><div class="item-type">类型:${escape2(card.type)}</div><div class="item-art-frame"><img class="item-artwork" alt="道具插画" src="${escape2(artwork)}"></div><div class="item-count">数量:${escape2(card.count)}</div><div class="description-title">描述</div><p class="item-description">${escape2(card.description)}</p><footer class="item-price">参考价格:${escape2(card.referencePrice)}</footer></article></body></html>`;
|
|
302
|
+
// src/plugin/formatCombatPower.ts
|
|
303
|
+
var compactPower = new Intl.NumberFormat("zh-CN", {
|
|
304
|
+
useGrouping: false,
|
|
305
|
+
minimumFractionDigits: 1,
|
|
306
|
+
maximumFractionDigits: 1
|
|
307
|
+
});
|
|
308
|
+
function formatCombatPower(value) {
|
|
309
|
+
return Number.isFinite(value) && Math.abs(value) >= 1e4 ? compactPower.format(value / 1e4) + "万" : value.toLocaleString("zh-CN", { maximumFractionDigits: 2 });
|
|
77
310
|
}
|
|
78
|
-
__name(
|
|
311
|
+
__name(formatCombatPower, "formatCombatPower");
|
|
79
312
|
|
|
80
313
|
// src/plugin/characterCardTemplate.ts
|
|
81
|
-
var
|
|
314
|
+
var escape = /* @__PURE__ */ __name((value) => String(value ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]), "escape");
|
|
82
315
|
var finite = /* @__PURE__ */ __name((value) => Number.isFinite(value) ? value : 0, "finite");
|
|
83
|
-
var
|
|
316
|
+
var number2 = /* @__PURE__ */ __name((value) => finite(value).toLocaleString("zh-CN", { maximumFractionDigits: 2 }), "number");
|
|
84
317
|
var ratio = /* @__PURE__ */ __name((value, max) => max > 0 ? Math.max(0, Math.min(1, finite(value) / max)) : 0, "ratio");
|
|
85
318
|
var qualityColors = { F: "#99958b", E: "#bac1ab", D: "#75b889", C: "#75a8cb", B: "#ab88cc", A: "#e5bd64", S: "#d8a2f0", SS: "#edb76e", SSS: "#f09783" };
|
|
86
319
|
function radar(attributes) {
|
|
@@ -92,7 +325,7 @@ function radar(attributes) {
|
|
|
92
325
|
}, "rank");
|
|
93
326
|
return rank(a.name) - rank(b.name);
|
|
94
327
|
});
|
|
95
|
-
if (attrs.length < 3) return `<div class="empty">${attrs.map((a) => `${
|
|
328
|
+
if (attrs.length < 3) return `<div class="empty">${attrs.map((a) => `${escape(a.name)} ${number2(a.value)}`).join("<br>") || "暂无一级属性"}</div>`;
|
|
96
329
|
const max = Math.max(1, ...attrs.map((a) => Math.max(0, finite(a.value))));
|
|
97
330
|
const ceiling = Math.ceil(max / Math.pow(10, Math.floor(Math.log10(max)))) * Math.pow(10, Math.floor(Math.log10(max)));
|
|
98
331
|
const point = /* @__PURE__ */ __name((index, radius) => {
|
|
@@ -108,9 +341,9 @@ function radar(attributes) {
|
|
|
108
341
|
${data.map((p) => `<circle cx="${p[0]}" cy="${p[1]}" r="4.5" fill="#174e45"/>`).join("")}
|
|
109
342
|
${attrs.map((a, i) => {
|
|
110
343
|
const [x, y] = point(i, 172);
|
|
111
|
-
return `<g transform="translate(${x} ${y})"><path d="M-44 -18 H44 L49 -6 L44 6 H-44 L-49 -6 Z" fill="#222827" stroke="#ab8b4f"/><text y="0" text-anchor="middle" fill="#f3e7c9" font-size="17">${
|
|
344
|
+
return `<g transform="translate(${x} ${y})"><path d="M-44 -18 H44 L49 -6 L44 6 H-44 L-49 -6 Z" fill="#222827" stroke="#ab8b4f"/><text y="0" text-anchor="middle" fill="#f3e7c9" font-size="17">${escape(a.name)}</text><text y="32" text-anchor="middle" fill="#1c5048" font-size="${number2(a.value).length > 12 ? 17 : 24}" font-weight="bold">${number2(a.value)}</text></g>`;
|
|
112
345
|
}).join("")}
|
|
113
|
-
</svg><div class="scale">各轴同尺度 · 满刻度 ${
|
|
346
|
+
</svg><div class="scale">各轴同尺度 · 满刻度 ${number2(ceiling)}</div>`;
|
|
114
347
|
}
|
|
115
348
|
__name(radar, "radar");
|
|
116
349
|
function characterCardHtml(card, artwork, paper, defaultArtwork) {
|
|
@@ -131,13 +364,13 @@ function characterCardHtml(card, artwork, paper, defaultArtwork) {
|
|
|
131
364
|
.power-label{font-size:19px;letter-spacing:2px}.power-value{font:bold 43px Georgia,serif;margin-top:10px;color:#edd69a;overflow-wrap:anywhere}.power-value.long{font-size:29px}.health{padding:15px 13px}.health-label{font-size:18px;margin-bottom:9px}.bar{position:relative;height:30px;border:1px solid #bea365;background:#101817;box-shadow:inset 0 2px 4px #000}.fill{height:100%;background:linear-gradient(#df4d39,#9a241d);border-right:1px solid #f19b67}.bar b{position:absolute;inset:0;display:grid;place-items:center;color:#fff7e6;font:16px Georgia,serif;text-shadow:0 1px 3px #000}
|
|
132
365
|
.panel{margin-top:22px;border:3px solid #252a27;box-shadow:0 0 0 1px #b19559,inset 0 0 0 1px #b19559;background:#f9f1df65;padding:10px 12px 14px}.heading{display:inline-block;margin:-10px 0 0 -12px;padding:9px 25px 10px 20px;background:#222927;border-right:3px solid #b3975a;border-bottom:1px solid #b3975a;color:#eee1bb;font:25px KaiTi,STKaiti,serif;letter-spacing:4px;clip-path:polygon(0 0,94% 0,100% 50%,94% 100%,0 100%)}
|
|
133
366
|
.radar{display:block;width:100%;height:390px;margin-top:-12px;overflow:visible}.scale{text-align:center;font-size:12px;color:#767565}.bloodlines{display:grid;gap:11px;margin-top:15px}.bloodline{display:flex;align-items:center;gap:14px;padding:12px;background:linear-gradient(100deg,#1e2624,#363b34);border:1px solid #b59961;box-shadow:0 0 0 2px #292f29;color:#f2e5c5;min-height:68px}.blood-icon{width:40px;height:40px;border:1px solid #b79a59;display:grid;place-items:center;color:#ddc180;font:26px KaiTi,serif;flex-shrink:0}.blood-name{font-size:21px;flex:1;overflow-wrap:anywhere}.quality{min-width:54px;padding:6px 9px;text-align:center;border:1px solid currentColor;font:bold 27px Georgia,serif;background:#111916;box-shadow:inset 0 0 10px #ffffff12}.empty{text-align:center;padding:25px;color:#6d7266;font-size:18px}.foot{font-size:13px;text-align:center;margin-top:18px;color:#626454;letter-spacing:1px}
|
|
134
|
-
</style><body><main id="capture">${paper ? `<img class="paper" src="${
|
|
135
|
-
<div class="portrait">${portrait ? `<img class="character-artwork" src="${
|
|
136
|
-
<div class="info"><div class="dark title">✦ 角色档案</div><div class="identity"><div class="eyebrow">轮回者</div><div class="identity-row"><h1 class="character-name">${
|
|
137
|
-
<div class="dark"><div class="power-label">⚔ 综合战力</div><div class="power-value ${
|
|
138
|
-
<div class="dark health"><div class="health-label">✚ 生命</div><div class="bar"><div class="fill" style="width:${hpPercent}%"></div><b>${
|
|
367
|
+
</style><body><main id="capture">${paper ? `<img class="paper" src="${escape(paper)}" alt="">` : ""}<div class="content"><div class="top">
|
|
368
|
+
<div class="portrait">${portrait ? `<img class="character-artwork" src="${escape(portrait)}" data-fallback="${escape(defaultArtwork ?? "")}" alt="角色形象">` : '<div class="placeholder"><div class="seal">轮回</div><small>形象尚未生成</small></div>'}</div>
|
|
369
|
+
<div class="info"><div class="dark title">✦ 角色档案</div><div class="identity"><div class="eyebrow">轮回者</div><div class="identity-row"><h1 class="character-name">${escape(card.name)}</h1><span class="level">Lv. ${number2(card.level)}</span></div><div class="experience-label">升级进度 ${number2(exp)}%</div><div class="experience"><span style="width:${exp}%"></span></div></div>
|
|
370
|
+
<div class="dark"><div class="power-label">⚔ 综合战力</div><div class="power-value ${formatCombatPower(finite(card.power)).length > 11 ? "long" : ""}">${formatCombatPower(finite(card.power))}</div></div>
|
|
371
|
+
<div class="dark health"><div class="health-label">✚ 生命</div><div class="bar"><div class="fill" style="width:${hpPercent}%"></div><b>${number2(card.hp)} / ${number2(card.maxHp)}</b></div></div></div></div>
|
|
139
372
|
<section class="panel"><h2 class="heading">一级属性</h2>${radar(card.attributes)}</section>
|
|
140
|
-
<section class="panel"><h2 class="heading">血统</h2><div class="bloodlines">${card.bloodlines.length ? card.bloodlines.map((b) => `<div class="bloodline"><span class="blood-icon">血</span><span class="blood-name">${
|
|
373
|
+
<section class="panel"><h2 class="heading">血统</h2><div class="bloodlines">${card.bloodlines.length ? card.bloodlines.map((b) => `<div class="bloodline"><span class="blood-icon">血</span><span class="blood-name">${escape(b.name)}</span><span class="quality" style="color:${qualityColors[b.quality] ?? "#bdbbae"}">${escape(b.quality)}</span></div>`).join("") : '<div class="empty">尚未融合血统</div>'}</div></section>
|
|
141
374
|
<div class="foot">[详细属性] 查看二级属性 · [指令] 查看操作</div></div></main></body></html>`;
|
|
142
375
|
}
|
|
143
376
|
__name(characterCardHtml, "characterCardHtml");
|
|
@@ -170,8 +403,13 @@ async function layoutCard(document = globalThis.document) {
|
|
|
170
403
|
}
|
|
171
404
|
}
|
|
172
405
|
}
|
|
173
|
-
const itemArtwork
|
|
174
|
-
|
|
406
|
+
for (const itemArtwork of document.querySelectorAll(".item-artwork,.detail-portrait")) {
|
|
407
|
+
try {
|
|
408
|
+
await itemArtwork.decode();
|
|
409
|
+
} catch {
|
|
410
|
+
itemArtwork.remove();
|
|
411
|
+
}
|
|
412
|
+
}
|
|
175
413
|
const artwork = document.querySelector(".skill-artwork");
|
|
176
414
|
if (artwork) {
|
|
177
415
|
try {
|
|
@@ -195,7 +433,7 @@ async function layoutCard(document = globalThis.document) {
|
|
|
195
433
|
if (avatar.scrollWidth <= avatar.clientWidth) break;
|
|
196
434
|
}
|
|
197
435
|
}
|
|
198
|
-
if (document.getElementById("capture")?.classList.contains("skill-sheet")) return;
|
|
436
|
+
if (document.getElementById("capture")?.classList.contains("skill-sheet") || document.getElementById("capture")?.classList.contains("detail-sheet")) return;
|
|
199
437
|
const name2 = document.getElementById("name");
|
|
200
438
|
if (!name2) return;
|
|
201
439
|
for (let size = 36; size >= 20; size--) {
|
|
@@ -216,10 +454,10 @@ async function layoutCard(document = globalThis.document) {
|
|
|
216
454
|
__name(layoutCard, "layoutCard");
|
|
217
455
|
|
|
218
456
|
// src/plugin/leaderboardTemplate.ts
|
|
219
|
-
var
|
|
457
|
+
var escape2 = /* @__PURE__ */ __name((s) => String(s ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]), "escape");
|
|
220
458
|
function leaderboardHtml(data, _headerImage, backgroundImage) {
|
|
221
459
|
const rows = data.rows.slice(0, 20);
|
|
222
|
-
const row = /* @__PURE__ */ __name((r, mine = false) => `<div class="row rank-${r.rank} ${mine ? "personal" : ""}"><div class="rank">${mine ? "<small>我的排名</small>" : ""}<b>${
|
|
460
|
+
const row = /* @__PURE__ */ __name((r, mine = false) => `<div class="row rank-${r.rank} ${mine ? "personal" : ""}"><div class="rank">${mine ? "<small>我的排名</small>" : ""}<b>${escape2(r.rank)}</b></div><div class="name">${escape2(r.name)}</div><div class="value">${escape2(data.metric === "战力" ? formatCombatPower(r.value) : r.value.toLocaleString("zh-CN", { maximumFractionDigits: 2 }))}</div></div>`, "row");
|
|
223
461
|
const personal = data.mine ? row(data.mine, true) : "";
|
|
224
462
|
return `<!doctype html><html lang="zh-CN"><meta charset="utf-8"><style>
|
|
225
463
|
*{box-sizing:border-box}body{margin:0;width:760px;color:#242725;font-family:"Microsoft YaHei","Noto Sans CJK SC",sans-serif}
|
|
@@ -237,7 +475,7 @@ function leaderboardHtml(data, _headerImage, backgroundImage) {
|
|
|
237
475
|
.value{font-size:23px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
238
476
|
#capture.has-background{padding:90px 80px}.has-background .sheet{background:rgba(250,247,238,.20);border:0}.has-background .row{grid-template-columns:48px minmax(0,1fr) 142px;gap:6px;padding:10px 6px}.has-background .name{font-size:20px}
|
|
239
477
|
.has-background .row{background-color:rgba(255,253,246,.38)}
|
|
240
|
-
</style><body><div id="capture" class="${backgroundImage ? "has-background" : ""}">${backgroundImage ? '<img class="board-background" alt="" src="' +
|
|
478
|
+
</style><body><div id="capture" class="${backgroundImage ? "has-background" : ""}">${backgroundImage ? '<img class="board-background" alt="" src="' + escape2(backgroundImage) + '">' : ""}<h1 class="board-title">${escape2(data.title)}</h1><main class="sheet">${rows.length ? rows.map((r) => row(r)).join("") : '<div class="empty">暂无玩家上榜</div>'}${personal}</main></div></body></html>`;
|
|
241
479
|
}
|
|
242
480
|
__name(leaderboardHtml, "leaderboardHtml");
|
|
243
481
|
|
|
@@ -246,53 +484,82 @@ var import_promises = __toESM(require("node:fs/promises"));
|
|
|
246
484
|
var import_node_path = __toESM(require("node:path"));
|
|
247
485
|
|
|
248
486
|
// src/plugin/skillCardTemplate.ts
|
|
249
|
-
var
|
|
250
|
-
function
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
487
|
+
var escape3 = /* @__PURE__ */ __name((value) => String(value ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]), "escape");
|
|
488
|
+
function effectText(value) {
|
|
489
|
+
return value.split(/(\d+(?:\.\d+)?%?|真实伤害|魔法伤害|物理伤害|全能护盾|魔法护盾|不可闪避|不暴击)/g).map((part) => /^\d+(?:\.\d+)?%?$/.test(part) ? `<span class="number">${escape3(part)}</span>` : /^(真实伤害|魔法伤害|物理伤害|全能护盾|魔法护盾|不可闪避|不暴击)$/.test(part) ? `<span class="keyword">${escape3(part)}</span>` : escape3(part)).join("");
|
|
490
|
+
}
|
|
491
|
+
__name(effectText, "effectText");
|
|
492
|
+
function statValue(value) {
|
|
493
|
+
const match = value.match(/^([+-]?\d+(?:\.\d+)?%?)\s*(.*)$/);
|
|
494
|
+
return match ? `<span class="stat-number">${escape3(match[1])}</span>${match[2] ? `<small class="stat-unit">${escape3(match[2])}</small>` : ""}` : escape3(value);
|
|
495
|
+
}
|
|
496
|
+
__name(statValue, "statValue");
|
|
497
|
+
function tagClass(tag) {
|
|
498
|
+
if (/永久成长/.test(tag)) return "growth";
|
|
499
|
+
if (/护盾|防御/.test(tag)) return "shield";
|
|
500
|
+
if (/治疗|恢复/.test(tag)) return "heal";
|
|
501
|
+
if (/伤害|反击/.test(tag)) return "damage";
|
|
502
|
+
if (/被动/.test(tag)) return "passive";
|
|
503
|
+
return "";
|
|
504
|
+
}
|
|
505
|
+
__name(tagClass, "tagClass");
|
|
506
|
+
function skillCardHtml(card, _frame = "", artwork) {
|
|
507
|
+
const quality = normalizeCardQuality(card.quality);
|
|
508
|
+
const description = card.description?.trim() || "暂无技能效果说明";
|
|
509
|
+
const growthMarker = /永久成长[((]仅玩家[))]\s*[::]/.exec(description);
|
|
510
|
+
const effect = growthMarker ? description.slice(0, growthMarker.index).trim() : description;
|
|
511
|
+
const growth = growthMarker ? description.slice(growthMarker.index + growthMarker[0].length).trim() : "";
|
|
512
|
+
const notes = (card.note || "").split(/\n+/).filter(Boolean);
|
|
513
|
+
const power = notes.find((line) => /^(?:🔥\s*)?战力\s*[::]/.test(line));
|
|
514
|
+
const otherNotes = notes.filter((line) => line !== power).join("\n");
|
|
515
|
+
const tags = [...new Set(card.tags || [])];
|
|
516
|
+
const row = /* @__PURE__ */ __name((label, value, detail = false) => `<div class="stat-row${detail ? " detail-stat" : ""}"><span>${escape3(label)}</span><b${detail ? "" : ' class="stat-value"'}>${value}</b></div>`, "row");
|
|
517
|
+
const cooldown = /^([\d.]+)\s*回合$/.exec(card.cooldown || "");
|
|
518
|
+
const cooldownValue = cooldown ? Number(cooldown[1]) === 0 ? "无冷却" : `${escape3(cooldown[1])} <small class="param-unit">回合</small>` : escape3(card.cooldown || "无冷却");
|
|
519
|
+
return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><style>${qualityCardStyles}</style></head><body>
|
|
520
|
+
<div id="capture" class="skill-sheet"><article class="detail-card skill-card quality-${quality.toLowerCase()}" style="${qualityStyle(quality)}">
|
|
521
|
+
<i class="card-corner corner-tl" aria-hidden="true"></i><i class="card-corner corner-tr" aria-hidden="true"></i><i class="card-corner corner-bl" aria-hidden="true"></i><i class="card-corner corner-br" aria-hidden="true"></i>
|
|
522
|
+
<div class="card-inner"><header class="card-titlebar"><span class="title-glyph" aria-hidden="true">◇</span><h1>${escape3(card.name)}</h1><span class="title-star" aria-hidden="true">✦</span></header>
|
|
523
|
+
<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)}">${escape3(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="${escape3(card.name)}图标" src="${escape3(artwork)}">` : ""}${qualityIconFrame(quality)}</div></div>
|
|
524
|
+
<div class="card-body"><div class="effect-stats">
|
|
525
|
+
${row("技能等级", `${escape3(card.level)} <small class="param-unit">/ ${escape3(card.maxLevel)}</small>`, true)}
|
|
526
|
+
${row("消耗", escape3(card.cost || "无消耗"), true)}
|
|
527
|
+
${row("冷却", cooldownValue, true)}
|
|
528
|
+
${power ? row("战力", escape3(power.replace(/^(?:🔥\s*)?战力\s*[::]\s*/, "")), true) : ""}
|
|
529
|
+
${(card.stats || []).slice(0, 3).map((stat) => row(stat.label, statValue(stat.value))).join("")}
|
|
530
|
+
</div><section class="effect"><h2 class="section-heading">技能效果</h2><p class="description">${effectText(effect)}</p></section>
|
|
531
|
+
${growth ? `<section class="growth-section"><h2 class="section-heading">永久成长 · 仅玩家</h2><p class="description">${effectText(growth)}</p></section>` : ""}
|
|
532
|
+
${otherNotes ? `<section class="note-section"><h2 class="section-heading">附加信息</h2><p class="description">${escape3(otherNotes)}</p></section>` : ""}
|
|
533
|
+
</div></div></article></div></body></html>`;
|
|
265
534
|
}
|
|
266
535
|
__name(skillCardHtml, "skillCardHtml");
|
|
267
536
|
|
|
268
537
|
// src/plugin/equipmentCardTemplate.ts
|
|
269
|
-
var escape6 = /* @__PURE__ */ __name((value) => String(value ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]), "escape");
|
|
270
538
|
function equipmentCardHtml(card, artwork, unknownFallback = false) {
|
|
271
|
-
const
|
|
272
|
-
const
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
</style></head><body><div id="capture" class="equipment-sheet ink-equipment-sheet"><header><div class="heading"><div class="heading-copy"><div class="overline">装 备 图 录</div><h1 class="name">${escape6(card.name)}</h1></div><div class="seal"><strong>${escape6(card.quality)}</strong><span>品阶</span></div></div><div class="meta"><span class="slot">${escape6(card.slot)}</span>${enhancement}${author}</div></header><div class="art"><div class="art-fallback"><span class="glyph">?</span><span class="kind">未知外观</span></div>${artwork ? `<img class="skill-artwork equipment-artwork" alt="" src="${escape6(artwork)}">` : ""}${unknownFallback || !artwork ? '<span class="placeholder-note">外观暂未显现</span>' : ""}</div><div class="power"><span>装 备 战 力</span><strong>${escape6(power)}</strong></div><section class="section attributes"><h2>附加属性</h2><div class="affixes">${affixes}</div></section>${skills}${description}${price}${notes}<div class="edition">露 · 装备录</div></div></body></html>`;
|
|
539
|
+
const power = Number.isFinite(Number(card.power)) ? formatCombatPower(Number(card.power)) : String(card.power ?? "—");
|
|
540
|
+
const enhancement = Number(card.enhancement) > 0 ? "+" + String(card.enhancement) : "未强化";
|
|
541
|
+
const details = [
|
|
542
|
+
cardStatRow("装备战力", power, true),
|
|
543
|
+
cardStatRow("装备部位", card.slot || "未知"),
|
|
544
|
+
cardStatRow("强化等级", enhancement),
|
|
545
|
+
cardStatRow("打造者", card.authorName?.trim() || "未知"),
|
|
546
|
+
...card.referencePrice ? [cardStatRow("参考价格", card.referencePrice)] : []
|
|
547
|
+
].join("");
|
|
548
|
+
const affixes = card.affixes?.length ? '<div class="detail-list">' + card.affixes.map((affix) => cardStatRow(affix.name, affix.value)).join("") + "</div>" : '<p class="description">暂无附加属性</p>';
|
|
549
|
+
const skills = card.skills?.length ? cardSection("附带技能", '<div class="detail-list">' + card.skills.map((skill) => cardStatRow(skill.name, skill.rank)).join("") + "</div>") : "";
|
|
550
|
+
const description = card.description?.trim() ? cardSection("装备描述", '<p class="description">' + cardEscape(card.description.trim()) + "</p>") : "";
|
|
551
|
+
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>") : "";
|
|
552
|
+
return detailCardHtml({
|
|
553
|
+
name: card.name,
|
|
554
|
+
quality: card.quality,
|
|
555
|
+
type: "装备",
|
|
556
|
+
artwork,
|
|
557
|
+
artworkClass: "skill-artwork equipment-artwork",
|
|
558
|
+
fallbackGlyph: "?",
|
|
559
|
+
sheetClass: "equipment-sheet",
|
|
560
|
+
tags: unknownFallback || !artwork ? ["外观暂未显现"] : [],
|
|
561
|
+
body: '<div class="effect-stats">' + details + "</div>" + cardSection("附加属性", affixes) + skills + description + notes
|
|
562
|
+
});
|
|
296
563
|
}
|
|
297
564
|
__name(equipmentCardHtml, "equipmentCardHtml");
|
|
298
565
|
|
|
@@ -401,9 +668,9 @@ var staticAssets = /* @__PURE__ */ new Map();
|
|
|
401
668
|
async function staticAsset(folder, file) {
|
|
402
669
|
const key = `${folder}/${file}`;
|
|
403
670
|
if (!staticAssets.has(key)) staticAssets.set(key, (async () => {
|
|
404
|
-
for (const
|
|
671
|
+
for (const base2 of [`../assets/${folder}`, `../../assets/${folder}`]) {
|
|
405
672
|
try {
|
|
406
|
-
return "data:image/webp;base64," + (await import_promises.default.readFile(import_node_path.default.resolve(__dirname,
|
|
673
|
+
return "data:image/webp;base64," + (await import_promises.default.readFile(import_node_path.default.resolve(__dirname, base2, file))).toString("base64");
|
|
407
674
|
} catch {
|
|
408
675
|
}
|
|
409
676
|
}
|
|
@@ -416,23 +683,12 @@ async function staticAsset(folder, file) {
|
|
|
416
683
|
}
|
|
417
684
|
__name(staticAsset, "staticAsset");
|
|
418
685
|
var characterAsset = /* @__PURE__ */ __name((file) => staticAsset("character-card", file), "characterAsset");
|
|
419
|
-
var itemPaper = /* @__PURE__ */ __name(() => staticAsset("item-card", "paper.webp"), "itemPaper");
|
|
420
686
|
var equipmentFallback = /* @__PURE__ */ __name(() => staticAsset("equipment-card", "unknown.webp"), "equipmentFallback");
|
|
421
|
-
var frames = /* @__PURE__ */ new Map();
|
|
422
|
-
async function frame(passive) {
|
|
423
|
-
const file = passive ? "card-trap.png" : "card-spell.png";
|
|
424
|
-
if (!frames.has(file)) frames.set(file, import_promises.default.readFile(import_node_path.default.resolve(__dirname, "../assets/skill-card", file)).catch(() => import_promises.default.readFile(import_node_path.default.resolve(__dirname, "../../assets/skill-card", file))).then((b) => "data:image/png;base64," + b.toString("base64")).catch((e) => {
|
|
425
|
-
frames.delete(file);
|
|
426
|
-
throw e;
|
|
427
|
-
}));
|
|
428
|
-
return frames.get(file);
|
|
429
|
-
}
|
|
430
|
-
__name(frame, "frame");
|
|
431
687
|
async function leaderboardHeader() {
|
|
432
|
-
for (const
|
|
688
|
+
for (const base2 of ["../assets/leaderboard", "../../assets/leaderboard"]) {
|
|
433
689
|
for (const [file, mime] of [["header.png", "image/png"], ["header.jpg", "image/jpeg"], ["header.webp", "image/webp"], ["header.svg", "image/svg+xml"]]) {
|
|
434
690
|
try {
|
|
435
|
-
return "data:" + mime + ";base64," + (await import_promises.default.readFile(import_node_path.default.resolve(__dirname,
|
|
691
|
+
return "data:" + mime + ";base64," + (await import_promises.default.readFile(import_node_path.default.resolve(__dirname, base2, file))).toString("base64");
|
|
436
692
|
} catch (error) {
|
|
437
693
|
if (error.code !== "ENOENT") throw error;
|
|
438
694
|
}
|
|
@@ -522,7 +778,6 @@ async function renderUncached(ctx, card, leaderboard, itemCard, characterCard, e
|
|
|
522
778
|
const dedicatedArt = equipmentCard ? await loadSkillArtwork(equipmentCard.artworkUrl) : void 0;
|
|
523
779
|
const unknownArt = equipmentCard && !dedicatedArt ? await equipmentFallback() : void 0;
|
|
524
780
|
const art = equipmentCard ? dedicatedArt ?? unknownArt : await loadSkillArtwork(characterCard?.artworkUrl ?? itemCard?.artworkUrl ?? leaderboard?.backgroundUrl ?? card?.artworkUrl);
|
|
525
|
-
if (itemCard && !equipmentCard && !art) throw new Error("道具图片读取失败");
|
|
526
781
|
let html;
|
|
527
782
|
let localAssetsReady = true;
|
|
528
783
|
if (equipmentCard) {
|
|
@@ -533,13 +788,11 @@ async function renderUncached(ctx, card, leaderboard, itemCard, characterCard, e
|
|
|
533
788
|
localAssetsReady = Boolean(paper && (art || defaultArtwork));
|
|
534
789
|
html = characterCardHtml(characterCard, art, paper, defaultArtwork);
|
|
535
790
|
} else if (itemCard) {
|
|
536
|
-
|
|
537
|
-
localAssetsReady = Boolean(paper);
|
|
538
|
-
html = itemCard.type === "形象卡" ? appearanceCardHtml(itemCard, art, paper) : itemCardHtml(itemCard, art, paper);
|
|
791
|
+
html = itemCard.type === "形象卡" ? appearanceCardHtml(itemCard, art) : itemCardHtml(itemCard, art);
|
|
539
792
|
} else if (leaderboard) {
|
|
540
793
|
html = leaderboardHtml(leaderboard, await leaderboardHeader(), art);
|
|
541
794
|
} else {
|
|
542
|
-
html = skillCardHtml(card,
|
|
795
|
+
html = skillCardHtml(card, "", art);
|
|
543
796
|
}
|
|
544
797
|
if (expired) throw new Error("绘图超时");
|
|
545
798
|
page = await ctx.puppeteer.page();
|
|
@@ -639,8 +892,8 @@ var handel_base = class {
|
|
|
639
892
|
this.ctx.logger.info("session not found", data.userId, data.channelId);
|
|
640
893
|
return;
|
|
641
894
|
}
|
|
642
|
-
let finalContent = content;
|
|
643
|
-
if (messageType === "text" && session.event?.platform === "qq" && session.event?.channel?.type === 0) {
|
|
895
|
+
let finalContent = data.notification ? content.trimEnd() : content;
|
|
896
|
+
if (messageType === "text" && !data.notification && session.event?.platform === "qq" && session.event?.channel?.type === 0) {
|
|
644
897
|
finalContent = "Ciallo~(∠・ω< )\n" + content;
|
|
645
898
|
}
|
|
646
899
|
const sendStartedAt = this.timing ? performance.now() : 0;
|
|
@@ -655,40 +908,6 @@ var handel_base = class {
|
|
|
655
908
|
}
|
|
656
909
|
};
|
|
657
910
|
|
|
658
|
-
// src/shared/bot/analysisMsg.ts
|
|
659
|
-
var AnalysisMsg = class {
|
|
660
|
-
static {
|
|
661
|
-
__name(this, "AnalysisMsg");
|
|
662
|
-
}
|
|
663
|
-
parse(data) {
|
|
664
|
-
let msg = "";
|
|
665
|
-
let haveTitle = false;
|
|
666
|
-
for (const item of data.line) {
|
|
667
|
-
switch (item.type) {
|
|
668
|
-
case 0 /* title */:
|
|
669
|
-
haveTitle = true;
|
|
670
|
-
msg += `┄━═${item.content}═━┄
|
|
671
|
-
`;
|
|
672
|
-
break;
|
|
673
|
-
case 1 /* line */:
|
|
674
|
-
msg += `${item.content}
|
|
675
|
-
`;
|
|
676
|
-
break;
|
|
677
|
-
case 2 /* error */:
|
|
678
|
-
msg += `❌出错了!错误原因:${item.content},请反馈至联系开发者
|
|
679
|
-
`;
|
|
680
|
-
break;
|
|
681
|
-
default:
|
|
682
|
-
break;
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
if (haveTitle) {
|
|
686
|
-
msg += "┄━════════━┄";
|
|
687
|
-
}
|
|
688
|
-
return msg;
|
|
689
|
-
}
|
|
690
|
-
};
|
|
691
|
-
|
|
692
911
|
// src/plugin/serverHandel/qqMarkdownHelpers.ts
|
|
693
912
|
function escapeMarkdown(value) {
|
|
694
913
|
return value.replace(/[\\`*_{}\[\]()#+\-.!|>~<&]/g, "\\$&");
|
|
@@ -728,19 +947,16 @@ function renderRewardLine(content) {
|
|
|
728
947
|
}
|
|
729
948
|
__name(renderRewardLine, "renderRewardLine");
|
|
730
949
|
function renderQQRewardMarkdown(data, showGreeting) {
|
|
950
|
+
const rewards = data.line.filter((item) => item.type === 1 /* line */ && item.reward).map((item) => renderRewardLine(item.content)).filter(Boolean);
|
|
951
|
+
if (rewards.length) return "🎁获得奖励\n\n" + rewards.join(" \n");
|
|
731
952
|
const sections = [];
|
|
732
953
|
const bodyLines = [];
|
|
733
|
-
const rewardLines = [];
|
|
734
954
|
const flushBody = /* @__PURE__ */ __name(() => {
|
|
735
955
|
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
736
956
|
}, "flushBody");
|
|
737
957
|
if (showGreeting && !data.reward) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
738
958
|
for (const item of data.line) {
|
|
739
|
-
if (item.type === 1 /* line */ && item.reward)
|
|
740
|
-
const reward = renderRewardLine(item.content);
|
|
741
|
-
if (reward) rewardLines.push(reward);
|
|
742
|
-
continue;
|
|
743
|
-
}
|
|
959
|
+
if (item.type === 1 /* line */ && item.reward) continue;
|
|
744
960
|
if (item.type === 0 /* title */) {
|
|
745
961
|
flushBody();
|
|
746
962
|
bodyLines.push(renderRewardTitle(item.content));
|
|
@@ -754,7 +970,6 @@ function renderQQRewardMarkdown(data, showGreeting) {
|
|
|
754
970
|
}
|
|
755
971
|
}
|
|
756
972
|
flushBody();
|
|
757
|
-
if (rewardLines.length) sections.push(rewardLines.join(" \n"));
|
|
758
973
|
return sections.join("\n\n") || " ";
|
|
759
974
|
}
|
|
760
975
|
__name(renderQQRewardMarkdown, "renderQQRewardMarkdown");
|
|
@@ -813,14 +1028,126 @@ function pageCommandLines(nav) {
|
|
|
813
1028
|
];
|
|
814
1029
|
}
|
|
815
1030
|
__name(pageCommandLines, "pageCommandLines");
|
|
1031
|
+
function renderQQTaskMarkdown(data) {
|
|
1032
|
+
const nav = data.pageNav;
|
|
1033
|
+
const entryCommands = new Map(nav?.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
1034
|
+
const sections = [];
|
|
1035
|
+
const rewards = [];
|
|
1036
|
+
let quote;
|
|
1037
|
+
const renderQuote = /* @__PURE__ */ __name((content) => content.replace(/\r\n?/g, "\n").split("\n").map((line) => "> " + renderInlineCommands(line)).join(" \n"), "renderQuote");
|
|
1038
|
+
const flushRewards = /* @__PURE__ */ __name(() => {
|
|
1039
|
+
if (rewards.length) sections.push(rewards.splice(0).join(" \n"));
|
|
1040
|
+
}, "flushRewards");
|
|
1041
|
+
for (const [lineIndex, item] of data.line.entries()) {
|
|
1042
|
+
if (item.type === 0 /* title */) {
|
|
1043
|
+
flushRewards();
|
|
1044
|
+
sections.push(renderRewardTitle(item.content));
|
|
1045
|
+
} else if (item.type === 2 /* error */) {
|
|
1046
|
+
flushRewards();
|
|
1047
|
+
sections.push("❌ " + renderInlineCommands(item.content));
|
|
1048
|
+
} else if (quote === "description") {
|
|
1049
|
+
sections.push(renderQuote(item.content));
|
|
1050
|
+
quote = void 0;
|
|
1051
|
+
} else if (item.reward) {
|
|
1052
|
+
const reward = renderRewardLine(item.content);
|
|
1053
|
+
if (reward) rewards.push(reward);
|
|
1054
|
+
} else if (item.content === "ℹ️任务说明" || item.content === "🎁任务奖励") {
|
|
1055
|
+
flushRewards();
|
|
1056
|
+
sections.push(renderRewardTitle(item.content));
|
|
1057
|
+
quote = item.content === "ℹ️任务说明" ? "description" : "rewards";
|
|
1058
|
+
} else if (/^(?:⌛任务进度[■□]{10}|✅任务完成)$/.test(item.content)) {
|
|
1059
|
+
flushRewards();
|
|
1060
|
+
sections.push(item.content.startsWith("✅任务完成") ? "**✅** " + escapeMarkdown(item.content.slice("✅".length)) : renderRewardTitle(item.content));
|
|
1061
|
+
quote = void 0;
|
|
1062
|
+
} else if (quote === "rewards") {
|
|
1063
|
+
rewards.push(renderQuote(item.content));
|
|
1064
|
+
} else {
|
|
1065
|
+
flushRewards();
|
|
1066
|
+
const command = entryCommands.get(lineIndex);
|
|
1067
|
+
sections.push(command ? "[" + escapeMarkdown(item.content) + "](" + inlineCommandUrl(command) + ")" : renderInlineCommands(item.content));
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
flushRewards();
|
|
1071
|
+
if (nav && (nav.total > 1 || nav.previousCommand || nav.nextCommand)) {
|
|
1072
|
+
const previous = nav.previousCommand ? "[上一个](" + inlineCommandUrl(nav.previousCommand) + ")" : "";
|
|
1073
|
+
const next = nav.nextCommand ? "[下一个](" + inlineCommandUrl(nav.nextCommand) + ")" : "";
|
|
1074
|
+
sections.push(previous + "**(" + nav.current + "/" + nav.total + ")**" + next);
|
|
1075
|
+
}
|
|
1076
|
+
return sections.join("\n\n") || " ";
|
|
1077
|
+
}
|
|
1078
|
+
__name(renderQQTaskMarkdown, "renderQQTaskMarkdown");
|
|
1079
|
+
var inventoryFilterCategories = [
|
|
1080
|
+
{ name: "装备", emoji: "⚔️" },
|
|
1081
|
+
{ name: "装备图纸", emoji: "📐" },
|
|
1082
|
+
{ name: "技能书", emoji: "📖" },
|
|
1083
|
+
{ name: "消耗品", emoji: "🧪" },
|
|
1084
|
+
{ name: "材料", emoji: "🧱" },
|
|
1085
|
+
{ name: "血统道具", emoji: "🧬" },
|
|
1086
|
+
{ name: "盲盒", emoji: "🎁" },
|
|
1087
|
+
{ name: "宠物蛋", emoji: "🥚" },
|
|
1088
|
+
{ name: "随从契约", emoji: "📜" },
|
|
1089
|
+
{ name: "合成配方", emoji: "📋" },
|
|
1090
|
+
{ name: "形象卡", emoji: "🎨" }
|
|
1091
|
+
];
|
|
1092
|
+
function renderInventoryFilters(nav) {
|
|
1093
|
+
const filters = nav.filters ?? inventoryFilterCategories.map((category) => ({
|
|
1094
|
+
...category,
|
|
1095
|
+
command: "搜索" + category.name
|
|
1096
|
+
}));
|
|
1097
|
+
const lines = [];
|
|
1098
|
+
for (let index = 0; index < filters.length; ) {
|
|
1099
|
+
const count = index === 0 ? 2 : 3;
|
|
1100
|
+
lines.push((index === 0 ? "🔍筛选" : "") + filters.slice(index, index + count).map(({ name: name2, emoji, command }) => `[${escapeMarkdown((emoji ?? "") + name2)}](${inlineCommandUrl(command)})`).join(""));
|
|
1101
|
+
index += count;
|
|
1102
|
+
}
|
|
1103
|
+
return lines.join(" \n");
|
|
1104
|
+
}
|
|
1105
|
+
__name(renderInventoryFilters, "renderInventoryFilters");
|
|
1106
|
+
function renderQQInventoryMarkdown(data, showGreeting) {
|
|
1107
|
+
const nav = data.pageNav;
|
|
1108
|
+
const entryCommands = new Map(nav.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
1109
|
+
const sections = [];
|
|
1110
|
+
const items = [];
|
|
1111
|
+
const flushItems = /* @__PURE__ */ __name(() => {
|
|
1112
|
+
if (items.length) sections.push(items.splice(0).map((line) => "> " + line).join(" \n"));
|
|
1113
|
+
}, "flushItems");
|
|
1114
|
+
if (showGreeting) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
1115
|
+
for (const [lineIndex, item] of data.line.entries()) {
|
|
1116
|
+
const command = entryCommands.get(lineIndex);
|
|
1117
|
+
if (item.type === 1 /* line */ && command) {
|
|
1118
|
+
const label = compactListLabel(item.content.replace(/^\[\d+\]\s*/, ""));
|
|
1119
|
+
items.push(`[${escapeMarkdown(label)}](${inlineCommandUrl(command)})`);
|
|
1120
|
+
continue;
|
|
1121
|
+
}
|
|
1122
|
+
flushItems();
|
|
1123
|
+
if (item.type === 0 /* title */) {
|
|
1124
|
+
sections.push(renderQQTitle(item.content));
|
|
1125
|
+
const filters = renderInventoryFilters(nav);
|
|
1126
|
+
if (filters) sections.push(filters);
|
|
1127
|
+
} else if (item.type === 2 /* error */) {
|
|
1128
|
+
sections.push(`❌ 出错了!错误原因:${renderInlineCommands(item.content)},请反馈至联系开发者`);
|
|
1129
|
+
} else if (!/^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*\d+\s*[项条])?$/.test(item.content) && !/^\[指令\]相关指令$/.test(item.content) && item.content.trim() !== "[上一页] [下一页]") {
|
|
1130
|
+
sections.push(renderInlineCommands(item.content));
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
flushItems();
|
|
1134
|
+
sections.push(`[上一页](${inlineCommandUrl(nav.previousCommand ?? "上一页")})**(${nav.current}/${nav.total})**[下一页](${inlineCommandUrl(nav.nextCommand ?? "下一页")})`);
|
|
1135
|
+
return sections.join("\n\n");
|
|
1136
|
+
}
|
|
1137
|
+
__name(renderQQInventoryMarkdown, "renderQQInventoryMarkdown");
|
|
816
1138
|
function renderQQPageMarkdown(data, showGreeting) {
|
|
1139
|
+
const hasEntryLabels = data.pageNav?.entries?.some((entry) => entry.label !== void 0) ?? false;
|
|
1140
|
+
if (data.task && !hasEntryLabels) return renderQQTaskMarkdown(data);
|
|
1141
|
+
if (!hasEntryLabels && data.pageNav && data.line.some((item) => item.type === 0 /* title */ && /^(?:💼)?我的背包$/u.test(compactDisplayText(item.content))))
|
|
1142
|
+
return renderQQInventoryMarkdown(data, showGreeting);
|
|
817
1143
|
const rewardMessage = isRewardMessage(data);
|
|
818
1144
|
const nav = data.pageNav;
|
|
819
1145
|
const entryCommands = new Map(nav?.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
1146
|
+
const labeledEntries = new Map(nav?.entries?.filter((entry) => entry.label !== void 0).map((entry) => [entry.lineIndex, entry]) ?? []);
|
|
820
1147
|
const listPattern = /^\[(\d+)\]\s*([^\r\n]+)$/;
|
|
821
1148
|
const pagePattern = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/;
|
|
822
1149
|
const title = data.line.find((item) => item.type === 0 /* title */);
|
|
823
|
-
const isLeaderboardDirectory = !!nav?.entries?.length && /^(?:🏆)?排行榜$/u.test(compactDisplayText(title?.content ?? ""));
|
|
1150
|
+
const isLeaderboardDirectory = !hasEntryLabels && !!nav?.entries?.length && /^(?:🏆)?排行榜$/u.test(compactDisplayText(title?.content ?? ""));
|
|
824
1151
|
const sections = [];
|
|
825
1152
|
const bodyLines = [];
|
|
826
1153
|
const listLines = [];
|
|
@@ -852,6 +1179,13 @@ function renderQQPageMarkdown(data, showGreeting) {
|
|
|
852
1179
|
else sections.push(renderQQTitle(titleText));
|
|
853
1180
|
break;
|
|
854
1181
|
case 1 /* line */: {
|
|
1182
|
+
const labeledEntry = labeledEntries.get(lineIndex);
|
|
1183
|
+
if (labeledEntry) {
|
|
1184
|
+
flushList();
|
|
1185
|
+
flushRewards();
|
|
1186
|
+
bodyLines.push(`[${escapeMarkdown(labeledEntry.label)}](${inlineCommandUrl(labeledEntry.viewCommand)})` + (labeledEntry.description ? " " + escapeMarkdown(labeledEntry.description) : ""));
|
|
1187
|
+
break;
|
|
1188
|
+
}
|
|
855
1189
|
if (item.reward) {
|
|
856
1190
|
flushList();
|
|
857
1191
|
flushBody();
|
|
@@ -915,11 +1249,6 @@ function canSendQQPage(session, data) {
|
|
|
915
1249
|
return !!internal?.sendMessage && !!internal.sendPrivateMessage;
|
|
916
1250
|
}
|
|
917
1251
|
__name(canSendQQPage, "canSendQQPage");
|
|
918
|
-
async function sendQQPage(session, data) {
|
|
919
|
-
const markdown = renderQQPageMarkdown(data, session.event?.channel?.type === 0);
|
|
920
|
-
await sendQQMarkdown(session, markdown);
|
|
921
|
-
}
|
|
922
|
-
__name(sendQQPage, "sendQQPage");
|
|
923
1252
|
async function sendQQMarkdown(session, markdown) {
|
|
924
1253
|
const internal = session.bot.internal;
|
|
925
1254
|
const request = {
|
|
@@ -941,6 +1270,91 @@ async function sendQQMarkdown(session, markdown) {
|
|
|
941
1270
|
}
|
|
942
1271
|
__name(sendQQMarkdown, "sendQQMarkdown");
|
|
943
1272
|
|
|
1273
|
+
// src/shared/bot/analysisMsg.ts
|
|
1274
|
+
var AnalysisMsg = class {
|
|
1275
|
+
static {
|
|
1276
|
+
__name(this, "AnalysisMsg");
|
|
1277
|
+
}
|
|
1278
|
+
parse(data) {
|
|
1279
|
+
let msg = "";
|
|
1280
|
+
let haveTitle = false;
|
|
1281
|
+
const commands = new Map(data.pageNav?.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
1282
|
+
for (const [lineIndex, item] of data.line.entries()) {
|
|
1283
|
+
switch (item.type) {
|
|
1284
|
+
case 0 /* title */:
|
|
1285
|
+
haveTitle = true;
|
|
1286
|
+
msg += `┄━═${item.content}═━┄
|
|
1287
|
+
`;
|
|
1288
|
+
break;
|
|
1289
|
+
case 1 /* line */:
|
|
1290
|
+
const command = commands.get(lineIndex);
|
|
1291
|
+
const hint = command && !item.content.includes(`[${command}]`) && item.content.trim() !== command ? ` [${command}]` : "";
|
|
1292
|
+
msg += `${item.content}${hint}
|
|
1293
|
+
`;
|
|
1294
|
+
break;
|
|
1295
|
+
case 2 /* error */:
|
|
1296
|
+
msg += `❌出错了!错误原因:${item.content},请反馈至联系开发者
|
|
1297
|
+
`;
|
|
1298
|
+
break;
|
|
1299
|
+
default:
|
|
1300
|
+
break;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
if (haveTitle) {
|
|
1304
|
+
msg += "┄━════════━┄";
|
|
1305
|
+
}
|
|
1306
|
+
return msg;
|
|
1307
|
+
}
|
|
1308
|
+
};
|
|
1309
|
+
|
|
1310
|
+
// src/plugin/serverHandel/qqCommandMessage.ts
|
|
1311
|
+
function renderQQCommandMarkdown(data, showGreeting) {
|
|
1312
|
+
const rewardMessage = isRewardMessage(data);
|
|
1313
|
+
if (!data.commandHelp && !data.pageNav && data.line.some((item) => item.type === 1 /* line */ && !item.reward && /^\[\d+\]\s*[^\r\n]+$/.test(item.content))) {
|
|
1314
|
+
return renderQQPageMarkdown(data, showGreeting);
|
|
1315
|
+
}
|
|
1316
|
+
const sections = [];
|
|
1317
|
+
const bodyLines = [];
|
|
1318
|
+
const rewardLines = [];
|
|
1319
|
+
const flushBody = /* @__PURE__ */ __name(() => {
|
|
1320
|
+
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
1321
|
+
}, "flushBody");
|
|
1322
|
+
const flushRewards = /* @__PURE__ */ __name(() => {
|
|
1323
|
+
if (rewardLines.length) sections.push(rewardLines.splice(0).join(" \n"));
|
|
1324
|
+
}, "flushRewards");
|
|
1325
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
1326
|
+
for (const item of data.line) {
|
|
1327
|
+
switch (item.type) {
|
|
1328
|
+
case 0 /* title */:
|
|
1329
|
+
flushBody();
|
|
1330
|
+
flushRewards();
|
|
1331
|
+
if (rewardMessage) bodyLines.push(renderRewardTitle(item.content));
|
|
1332
|
+
else sections.push(renderQQTitle(item.content));
|
|
1333
|
+
break;
|
|
1334
|
+
case 1 /* line */:
|
|
1335
|
+
if (item.reward) {
|
|
1336
|
+
flushBody();
|
|
1337
|
+
const reward = renderRewardLine(item.content);
|
|
1338
|
+
if (reward) rewardLines.push(reward);
|
|
1339
|
+
break;
|
|
1340
|
+
}
|
|
1341
|
+
flushRewards();
|
|
1342
|
+
if (!item.content.trim()) flushBody();
|
|
1343
|
+
else bodyLines.push(renderInlineCommands(item.content));
|
|
1344
|
+
break;
|
|
1345
|
+
case 2 /* error */:
|
|
1346
|
+
flushBody();
|
|
1347
|
+
flushRewards();
|
|
1348
|
+
sections.push(`❌ 出错了!错误原因:${renderInlineCommands(item.content)},请反馈至联系开发者`);
|
|
1349
|
+
break;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
flushBody();
|
|
1353
|
+
flushRewards();
|
|
1354
|
+
return sections.join("\n\n") || " ";
|
|
1355
|
+
}
|
|
1356
|
+
__name(renderQQCommandMarkdown, "renderQQCommandMarkdown");
|
|
1357
|
+
|
|
944
1358
|
// src/plugin/serverHandel/qqTransactionMessage.ts
|
|
945
1359
|
function renderQQTransactionMarkdown(data, showGreeting) {
|
|
946
1360
|
const rewardMessage = isRewardMessage(data);
|
|
@@ -1007,62 +1421,6 @@ function renderQQTransactionMarkdown(data, showGreeting) {
|
|
|
1007
1421
|
return sections.join("\n\n") || " ";
|
|
1008
1422
|
}
|
|
1009
1423
|
__name(renderQQTransactionMarkdown, "renderQQTransactionMarkdown");
|
|
1010
|
-
async function sendQQTransaction(session, data) {
|
|
1011
|
-
await sendQQMarkdown(session, renderQQTransactionMarkdown(data, session.event?.channel?.type === 0));
|
|
1012
|
-
}
|
|
1013
|
-
__name(sendQQTransaction, "sendQQTransaction");
|
|
1014
|
-
|
|
1015
|
-
// src/plugin/serverHandel/qqCommandMessage.ts
|
|
1016
|
-
function renderQQCommandMarkdown(data, showGreeting) {
|
|
1017
|
-
const rewardMessage = isRewardMessage(data);
|
|
1018
|
-
if (!data.commandHelp && !data.pageNav && data.line.some((item) => item.type === 1 /* line */ && !item.reward && /^\[\d+\]\s*[^\r\n]+$/.test(item.content))) {
|
|
1019
|
-
return renderQQPageMarkdown(data, showGreeting);
|
|
1020
|
-
}
|
|
1021
|
-
const sections = [];
|
|
1022
|
-
const bodyLines = [];
|
|
1023
|
-
const rewardLines = [];
|
|
1024
|
-
const flushBody = /* @__PURE__ */ __name(() => {
|
|
1025
|
-
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
1026
|
-
}, "flushBody");
|
|
1027
|
-
const flushRewards = /* @__PURE__ */ __name(() => {
|
|
1028
|
-
if (rewardLines.length) sections.push(rewardLines.splice(0).join(" \n"));
|
|
1029
|
-
}, "flushRewards");
|
|
1030
|
-
if (showGreeting && !data.reward) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
1031
|
-
for (const item of data.line) {
|
|
1032
|
-
switch (item.type) {
|
|
1033
|
-
case 0 /* title */:
|
|
1034
|
-
flushBody();
|
|
1035
|
-
flushRewards();
|
|
1036
|
-
if (rewardMessage) bodyLines.push(renderRewardTitle(item.content));
|
|
1037
|
-
else sections.push(renderQQTitle(item.content));
|
|
1038
|
-
break;
|
|
1039
|
-
case 1 /* line */:
|
|
1040
|
-
if (item.reward) {
|
|
1041
|
-
flushBody();
|
|
1042
|
-
const reward = renderRewardLine(item.content);
|
|
1043
|
-
if (reward) rewardLines.push(reward);
|
|
1044
|
-
break;
|
|
1045
|
-
}
|
|
1046
|
-
flushRewards();
|
|
1047
|
-
if (!item.content.trim()) flushBody();
|
|
1048
|
-
else bodyLines.push(renderInlineCommands(item.content));
|
|
1049
|
-
break;
|
|
1050
|
-
case 2 /* error */:
|
|
1051
|
-
flushBody();
|
|
1052
|
-
flushRewards();
|
|
1053
|
-
sections.push(`❌ 出错了!错误原因:${renderInlineCommands(item.content)},请反馈至联系开发者`);
|
|
1054
|
-
break;
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
flushBody();
|
|
1058
|
-
flushRewards();
|
|
1059
|
-
return sections.join("\n\n") || " ";
|
|
1060
|
-
}
|
|
1061
|
-
__name(renderQQCommandMarkdown, "renderQQCommandMarkdown");
|
|
1062
|
-
async function sendQQCommand(session, data) {
|
|
1063
|
-
await sendQQMarkdown(session, renderQQCommandMarkdown(data, session.event?.channel?.type === 0));
|
|
1064
|
-
}
|
|
1065
|
-
__name(sendQQCommand, "sendQQCommand");
|
|
1066
1424
|
|
|
1067
1425
|
// src/plugin/serverHandel/qqStoryMessage.ts
|
|
1068
1426
|
function hasStoryCodeBlock(data) {
|
|
@@ -1077,6 +1435,10 @@ function fencedStory(content) {
|
|
|
1077
1435
|
}
|
|
1078
1436
|
__name(fencedStory, "fencedStory");
|
|
1079
1437
|
function renderQQStoryMarkdown(data, showGreeting) {
|
|
1438
|
+
if (data.reward === true && data.line.some((item) => item.type === 1 /* line */ && item.reward === true && item.content.trim())) {
|
|
1439
|
+
const stories = data.line.filter((item) => item.type === 1 /* line */ && item.codeBlock === true).map((item) => fencedStory(item.content));
|
|
1440
|
+
return [...stories, renderQQRewardMarkdown(data, false)].join("\n\n");
|
|
1441
|
+
}
|
|
1080
1442
|
const rewardMessage = isRewardMessage(data);
|
|
1081
1443
|
const sections = [];
|
|
1082
1444
|
const bodyLines = [];
|
|
@@ -1126,10 +1488,23 @@ function renderQQStoryMarkdown(data, showGreeting) {
|
|
|
1126
1488
|
return sections.join("\n\n") || " ";
|
|
1127
1489
|
}
|
|
1128
1490
|
__name(renderQQStoryMarkdown, "renderQQStoryMarkdown");
|
|
1129
|
-
|
|
1130
|
-
|
|
1491
|
+
|
|
1492
|
+
// src/plugin/serverHandel/qqMessagePreview.ts
|
|
1493
|
+
function renderQQMessagePreview(data, showGreeting = false) {
|
|
1494
|
+
const plain = new AnalysisMsg().parse(data);
|
|
1495
|
+
const text = data.notification ? plain.trimEnd() : plain;
|
|
1496
|
+
if (data.notification) return { kind: "command", markdown: renderQQCommandMarkdown(data, false), text };
|
|
1497
|
+
if (hasStoryCodeBlock(data)) return { kind: "story", markdown: renderQQStoryMarkdown(data, showGreeting), text };
|
|
1498
|
+
if (data.commandHelp) return { kind: "command", markdown: renderQQCommandMarkdown(data, showGreeting), text };
|
|
1499
|
+
if (data.transaction) return { kind: "transaction", markdown: renderQQTransactionMarkdown(data, showGreeting), text };
|
|
1500
|
+
if (data.pageNav) return { kind: "page", markdown: renderQQPageMarkdown(data, showGreeting), text };
|
|
1501
|
+
if (isRewardMessage(data)) return { kind: "reward", markdown: renderQQRewardMarkdown(data, showGreeting), text };
|
|
1502
|
+
if (data.line.some((item) => (item.type === 1 /* line */ || item.type === 2 /* error */) && hasInlineCommands(item.content))) {
|
|
1503
|
+
return { kind: "command", markdown: renderQQCommandMarkdown(data, showGreeting), text };
|
|
1504
|
+
}
|
|
1505
|
+
return { kind: "text", text };
|
|
1131
1506
|
}
|
|
1132
|
-
__name(
|
|
1507
|
+
__name(renderQQMessagePreview, "renderQQMessagePreview");
|
|
1133
1508
|
|
|
1134
1509
|
// src/plugin/serverHandel/text.ts
|
|
1135
1510
|
var handelr_text = class extends handel_base {
|
|
@@ -1137,20 +1512,13 @@ var handelr_text = class extends handel_base {
|
|
|
1137
1512
|
__name(this, "handelr_text");
|
|
1138
1513
|
}
|
|
1139
1514
|
async start(data) {
|
|
1140
|
-
const content = new AnalysisMsg().parse(data);
|
|
1141
1515
|
const session = sessions_default.get(sessionKey(data.botId, data.userId, data.channelId));
|
|
1142
|
-
const
|
|
1143
|
-
const
|
|
1144
|
-
|
|
1145
|
-
if ((story || data.commandHelp || data.transaction || data.pageNav || inlineCommands || reward) && canSendQQPage(session, data)) {
|
|
1516
|
+
const preview = renderQQMessagePreview(data, session?.event?.channel?.type === 0);
|
|
1517
|
+
const content = preview.text;
|
|
1518
|
+
if (preview.markdown !== void 0 && canSendQQPage(session, data)) {
|
|
1146
1519
|
const sendStartedAt = this.timing ? performance.now() : 0;
|
|
1147
1520
|
try {
|
|
1148
|
-
|
|
1149
|
-
else if (data.commandHelp) await sendQQCommand(session, data);
|
|
1150
|
-
else if (data.transaction) await sendQQTransaction(session, data);
|
|
1151
|
-
else if (data.pageNav) await sendQQPage(session, data);
|
|
1152
|
-
else if (reward) await sendQQMarkdown(session, renderQQRewardMarkdown(data, session.event?.channel?.type === 0));
|
|
1153
|
-
else await sendQQCommand(session, data);
|
|
1521
|
+
await sendQQMarkdown(session, preview.markdown);
|
|
1154
1522
|
if (this.timing) {
|
|
1155
1523
|
this.timing.delivery = "qq-markdown";
|
|
1156
1524
|
this.timing.sendMs = performance.now() - sendStartedAt;
|
|
@@ -1159,7 +1527,7 @@ var handelr_text = class extends handel_base {
|
|
|
1159
1527
|
} catch (error) {
|
|
1160
1528
|
this.ctx.logger.warn("QQ Markdown 发送失败,改用普通文字", error instanceof Error ? error.message : error);
|
|
1161
1529
|
}
|
|
1162
|
-
const commands =
|
|
1530
|
+
const commands = preview.kind === "page" && data.pageNav ? pageCommandLines(data.pageNav) : [];
|
|
1163
1531
|
await this.send(data, commands.length ? `${content.trimEnd()}
|
|
1164
1532
|
${commands.join("\n")}` : content);
|
|
1165
1533
|
return;
|
|
@@ -1264,7 +1632,7 @@ var import_tsrpc = require("tsrpc");
|
|
|
1264
1632
|
|
|
1265
1633
|
// src/shared/bot/serviceProto.ts
|
|
1266
1634
|
var serviceProto = {
|
|
1267
|
-
"version":
|
|
1635
|
+
"version": 21,
|
|
1268
1636
|
"services": [
|
|
1269
1637
|
{
|
|
1270
1638
|
"id": 0,
|
|
@@ -1399,6 +1767,14 @@ var serviceProto = {
|
|
|
1399
1767
|
},
|
|
1400
1768
|
"optional": true
|
|
1401
1769
|
},
|
|
1770
|
+
{
|
|
1771
|
+
"id": 11,
|
|
1772
|
+
"name": "task",
|
|
1773
|
+
"type": {
|
|
1774
|
+
"type": "Boolean"
|
|
1775
|
+
},
|
|
1776
|
+
"optional": true
|
|
1777
|
+
},
|
|
1402
1778
|
{
|
|
1403
1779
|
"id": 8,
|
|
1404
1780
|
"name": "transaction",
|
|
@@ -1423,6 +1799,14 @@ var serviceProto = {
|
|
|
1423
1799
|
},
|
|
1424
1800
|
"optional": true
|
|
1425
1801
|
},
|
|
1802
|
+
{
|
|
1803
|
+
"id": 12,
|
|
1804
|
+
"name": "notification",
|
|
1805
|
+
"type": {
|
|
1806
|
+
"type": "Boolean"
|
|
1807
|
+
},
|
|
1808
|
+
"optional": true
|
|
1809
|
+
},
|
|
1426
1810
|
{
|
|
1427
1811
|
"id": 1,
|
|
1428
1812
|
"name": "line",
|
|
@@ -1637,6 +2021,33 @@ var serviceProto = {
|
|
|
1637
2021
|
"type": "String"
|
|
1638
2022
|
}
|
|
1639
2023
|
},
|
|
2024
|
+
{
|
|
2025
|
+
"id": 14,
|
|
2026
|
+
"name": "stats",
|
|
2027
|
+
"type": {
|
|
2028
|
+
"type": "Array",
|
|
2029
|
+
"elementType": {
|
|
2030
|
+
"type": "Interface",
|
|
2031
|
+
"properties": [
|
|
2032
|
+
{
|
|
2033
|
+
"id": 0,
|
|
2034
|
+
"name": "label",
|
|
2035
|
+
"type": {
|
|
2036
|
+
"type": "String"
|
|
2037
|
+
}
|
|
2038
|
+
},
|
|
2039
|
+
{
|
|
2040
|
+
"id": 1,
|
|
2041
|
+
"name": "value",
|
|
2042
|
+
"type": {
|
|
2043
|
+
"type": "String"
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
]
|
|
2047
|
+
}
|
|
2048
|
+
},
|
|
2049
|
+
"optional": true
|
|
2050
|
+
},
|
|
1640
2051
|
{
|
|
1641
2052
|
"id": 10,
|
|
1642
2053
|
"name": "tags",
|
|
@@ -1674,7 +2085,8 @@ var serviceProto = {
|
|
|
1674
2085
|
"name": "artworkUrl",
|
|
1675
2086
|
"type": {
|
|
1676
2087
|
"type": "String"
|
|
1677
|
-
}
|
|
2088
|
+
},
|
|
2089
|
+
"optional": true
|
|
1678
2090
|
},
|
|
1679
2091
|
{
|
|
1680
2092
|
"id": 1,
|
|
@@ -1717,6 +2129,41 @@ var serviceProto = {
|
|
|
1717
2129
|
"type": {
|
|
1718
2130
|
"type": "String"
|
|
1719
2131
|
}
|
|
2132
|
+
},
|
|
2133
|
+
{
|
|
2134
|
+
"id": 7,
|
|
2135
|
+
"name": "rows",
|
|
2136
|
+
"type": {
|
|
2137
|
+
"type": "Array",
|
|
2138
|
+
"elementType": {
|
|
2139
|
+
"type": "Interface",
|
|
2140
|
+
"properties": [
|
|
2141
|
+
{
|
|
2142
|
+
"id": 0,
|
|
2143
|
+
"name": "label",
|
|
2144
|
+
"type": {
|
|
2145
|
+
"type": "String"
|
|
2146
|
+
}
|
|
2147
|
+
},
|
|
2148
|
+
{
|
|
2149
|
+
"id": 1,
|
|
2150
|
+
"name": "value",
|
|
2151
|
+
"type": {
|
|
2152
|
+
"type": "String"
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
]
|
|
2156
|
+
}
|
|
2157
|
+
},
|
|
2158
|
+
"optional": true
|
|
2159
|
+
},
|
|
2160
|
+
{
|
|
2161
|
+
"id": 8,
|
|
2162
|
+
"name": "useDescription",
|
|
2163
|
+
"type": {
|
|
2164
|
+
"type": "String"
|
|
2165
|
+
},
|
|
2166
|
+
"optional": true
|
|
1720
2167
|
}
|
|
1721
2168
|
]
|
|
1722
2169
|
},
|
|
@@ -2071,6 +2518,57 @@ var serviceProto = {
|
|
|
2071
2518
|
"type": {
|
|
2072
2519
|
"type": "String"
|
|
2073
2520
|
}
|
|
2521
|
+
},
|
|
2522
|
+
{
|
|
2523
|
+
"id": 2,
|
|
2524
|
+
"name": "label",
|
|
2525
|
+
"type": {
|
|
2526
|
+
"type": "String"
|
|
2527
|
+
},
|
|
2528
|
+
"optional": true
|
|
2529
|
+
},
|
|
2530
|
+
{
|
|
2531
|
+
"id": 3,
|
|
2532
|
+
"name": "description",
|
|
2533
|
+
"type": {
|
|
2534
|
+
"type": "String"
|
|
2535
|
+
},
|
|
2536
|
+
"optional": true
|
|
2537
|
+
}
|
|
2538
|
+
]
|
|
2539
|
+
}
|
|
2540
|
+
},
|
|
2541
|
+
"optional": true
|
|
2542
|
+
},
|
|
2543
|
+
{
|
|
2544
|
+
"id": 5,
|
|
2545
|
+
"name": "filters",
|
|
2546
|
+
"type": {
|
|
2547
|
+
"type": "Array",
|
|
2548
|
+
"elementType": {
|
|
2549
|
+
"type": "Interface",
|
|
2550
|
+
"properties": [
|
|
2551
|
+
{
|
|
2552
|
+
"id": 0,
|
|
2553
|
+
"name": "name",
|
|
2554
|
+
"type": {
|
|
2555
|
+
"type": "String"
|
|
2556
|
+
}
|
|
2557
|
+
},
|
|
2558
|
+
{
|
|
2559
|
+
"id": 1,
|
|
2560
|
+
"name": "emoji",
|
|
2561
|
+
"type": {
|
|
2562
|
+
"type": "String"
|
|
2563
|
+
},
|
|
2564
|
+
"optional": true
|
|
2565
|
+
},
|
|
2566
|
+
{
|
|
2567
|
+
"id": 2,
|
|
2568
|
+
"name": "command",
|
|
2569
|
+
"type": {
|
|
2570
|
+
"type": "String"
|
|
2571
|
+
}
|
|
2074
2572
|
}
|
|
2075
2573
|
]
|
|
2076
2574
|
}
|