koishi-plugin-dew-bot 1.0.261 → 1.0.263
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 +316 -105
- package/lib/plugin/characterCardAssets.d.ts +3 -1
- package/lib/plugin/characterCardStyles.d.ts +1 -1
- package/lib/plugin/serverHandel/imageMessageFollowup.d.ts +9 -0
- package/lib/plugin/serverHandel/qqMessageButtons.d.ts +27 -0
- package/lib/plugin/serverHandel/qqMessagePreview.d.ts +3 -0
- package/lib/plugin/serverHandel/qqPageMessage.d.ts +2 -1
- package/lib/shared/bot/analysisMsg.d.ts +5 -0
- package/lib/shared/bot/inlineCommands.d.ts +11 -0
- package/lib/shared/face/index.d.ts +16 -1
- package/package.json +1 -1
- package/src/plugin/bloodlineCardTemplate.ts +2 -4
- package/src/plugin/cardLayout.ts +15 -1
- package/src/plugin/characterCardAssets.ts +9 -1
- package/src/plugin/characterCardStyles.ts +6 -4
- package/src/plugin/characterCardTemplate.ts +9 -8
- package/src/plugin/serverHandel/image.ts +5 -5
- package/src/plugin/serverHandel/imageMessageFollowup.ts +23 -0
- package/src/plugin/serverHandel/qqCommandMessage.ts +10 -3
- package/src/plugin/serverHandel/qqMessageButtons.ts +38 -0
- package/src/plugin/serverHandel/qqMessagePreview.ts +19 -8
- package/src/plugin/serverHandel/qqPageMessage.ts +9 -21
- package/src/plugin/serverHandel/qqRewardMessage.ts +2 -0
- package/src/plugin/serverHandel/qqStoryMessage.ts +4 -1
- package/src/plugin/serverHandel/qqTransactionMessage.ts +4 -1
- package/src/plugin/serverHandel/text.ts +1 -1
- package/src/shared/bot/analysisMsg.ts +38 -1
- package/src/shared/bot/inlineCommands.ts +39 -0
- package/src/shared/bot/serviceProto.ts +80 -1
- package/src/shared/face/index.ts +18 -1
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": 39,
|
|
71
71
|
"services": [
|
|
72
72
|
{
|
|
73
73
|
"id": 0,
|
|
@@ -295,6 +295,18 @@ var init_serviceProto = __esm({
|
|
|
295
295
|
"target": "messageFace/TitleCardData"
|
|
296
296
|
},
|
|
297
297
|
"optional": true
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"id": 17,
|
|
301
|
+
"name": "buttons",
|
|
302
|
+
"type": {
|
|
303
|
+
"type": "Array",
|
|
304
|
+
"elementType": {
|
|
305
|
+
"type": "Reference",
|
|
306
|
+
"target": "messageFace/MessageButtonRow"
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
"optional": true
|
|
298
310
|
}
|
|
299
311
|
]
|
|
300
312
|
},
|
|
@@ -751,6 +763,14 @@ var init_serviceProto = __esm({
|
|
|
751
763
|
}
|
|
752
764
|
},
|
|
753
765
|
"optional": true
|
|
766
|
+
},
|
|
767
|
+
{
|
|
768
|
+
"id": 14,
|
|
769
|
+
"name": "explorationRank",
|
|
770
|
+
"type": {
|
|
771
|
+
"type": "String"
|
|
772
|
+
},
|
|
773
|
+
"optional": true
|
|
754
774
|
}
|
|
755
775
|
]
|
|
756
776
|
},
|
|
@@ -1891,6 +1911,65 @@ var init_serviceProto = __esm({
|
|
|
1891
1911
|
}
|
|
1892
1912
|
]
|
|
1893
1913
|
},
|
|
1914
|
+
"messageFace/MessageButtonRow": {
|
|
1915
|
+
"type": "Interface",
|
|
1916
|
+
"properties": [
|
|
1917
|
+
{
|
|
1918
|
+
"id": 0,
|
|
1919
|
+
"name": "buttons",
|
|
1920
|
+
"type": {
|
|
1921
|
+
"type": "Array",
|
|
1922
|
+
"elementType": {
|
|
1923
|
+
"type": "Reference",
|
|
1924
|
+
"target": "messageFace/MessageButton"
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
]
|
|
1929
|
+
},
|
|
1930
|
+
"messageFace/MessageButton": {
|
|
1931
|
+
"type": "Interface",
|
|
1932
|
+
"properties": [
|
|
1933
|
+
{
|
|
1934
|
+
"id": 0,
|
|
1935
|
+
"name": "label",
|
|
1936
|
+
"type": {
|
|
1937
|
+
"type": "String"
|
|
1938
|
+
}
|
|
1939
|
+
},
|
|
1940
|
+
{
|
|
1941
|
+
"id": 1,
|
|
1942
|
+
"name": "command",
|
|
1943
|
+
"type": {
|
|
1944
|
+
"type": "String"
|
|
1945
|
+
}
|
|
1946
|
+
},
|
|
1947
|
+
{
|
|
1948
|
+
"id": 2,
|
|
1949
|
+
"name": "style",
|
|
1950
|
+
"type": {
|
|
1951
|
+
"type": "Union",
|
|
1952
|
+
"members": [
|
|
1953
|
+
{
|
|
1954
|
+
"id": 0,
|
|
1955
|
+
"type": {
|
|
1956
|
+
"type": "Literal",
|
|
1957
|
+
"literal": "primary"
|
|
1958
|
+
}
|
|
1959
|
+
},
|
|
1960
|
+
{
|
|
1961
|
+
"id": 1,
|
|
1962
|
+
"type": {
|
|
1963
|
+
"type": "Literal",
|
|
1964
|
+
"literal": "secondary"
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
]
|
|
1968
|
+
},
|
|
1969
|
+
"optional": true
|
|
1970
|
+
}
|
|
1971
|
+
]
|
|
1972
|
+
},
|
|
1894
1973
|
"PtlMessage/ReqMessage": {
|
|
1895
1974
|
"type": "Interface",
|
|
1896
1975
|
"extends": [
|
|
@@ -2660,15 +2739,17 @@ var characterCardStyles = `
|
|
|
2660
2739
|
.character-sheet .companion-portrait{padding:10px;border-radius:18px;flex:0 0 auto;background:linear-gradient(135deg,#fffefa 2%,var(--edge) 18%,#ffffff 30%,var(--accent) 41%,#fffdf2 51%,var(--edge) 71%,#ffffff 82%,var(--metal-shadow) 100%);box-shadow:inset 0 0 0 1px #ffffffd9,0 3px 9px #51628038}
|
|
2661
2740
|
.character-sheet .companion-portrait:before{inset:5px;border-radius:12px;border-color:#fffdf1cf;box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 43%,transparent)}.character-sheet .companion-portrait:after{inset:2px;border-radius:15px;border-color:#fffefa9c}.character-sheet .companion-portrait .panel-corner{width:var(--portrait-ornament-size);height:var(--portrait-ornament-size)}
|
|
2662
2741
|
.character-sheet .portrait-window{height:auto;border:2px solid var(--edge);border-radius:6px;overflow:hidden;background:var(--paper)}.character-artwork{display:block;width:100%;height:auto;object-fit:contain}.character-sheet .portrait-placeholder,.character-sheet .placeholder{height:100%;width:100%;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;color:var(--subtle);font:21px/1.5 "Microsoft YaHei",sans-serif}.character-sheet .placeholder small{font-size:16px}.character-sheet .portrait-window>.placeholder{height:448px}
|
|
2663
|
-
.character-stats{padding:17px 18px 15px;display:flex;flex-direction:column}.character-stats>.character-identity,.character-stats>.
|
|
2742
|
+
.character-stats{padding:17px 18px 15px;display:flex;flex-direction:column}.character-stats>.character-identity,.character-stats>.resource,.character-stats>.attribute-panel{position:relative;z-index:4}
|
|
2664
2743
|
.character-identity{text-align:center;min-width:0}.title-image-slot{position:absolute;inset:12px;display:flex;align-items:center;justify-content:center;min-width:0;z-index:4;pointer-events:none}.title-artwork{display:block;width:auto;height:auto;max-width:100%;max-height:min(110px,100%);object-fit:contain;filter:drop-shadow(0 2px 3px #17213a70)}.title-artwork[alt="称号图片占位"]{max-width:min(244px,100%);max-height:min(44px,100%)}
|
|
2665
2744
|
.character-name{font-size:43px;line-height:1.17;font-weight:700;letter-spacing:3px;margin:0 0 3px;overflow-wrap:anywhere;color:var(--ink);text-shadow:0 1px 0 #ffffff}.character-level{font:27px/1.25 Georgia,"Microsoft YaHei",serif;margin:0;color:var(--subtle);display:flex;align-items:baseline;justify-content:center;gap:7px;min-width:0}.character-level strong{font-size:28px;font-weight:500;overflow-wrap:anywhere;min-width:0}
|
|
2666
2745
|
.gene-panel{position:relative;margin:8px auto 0;padding:4px 12px 4px 7px;display:flex;align-items:center;justify-content:center;gap:6px;width:fit-content;max-width:100%;border:1px solid color-mix(in srgb,var(--edge) 80%,#ffffff);border-radius:7px;background:linear-gradient(#ffffffd6,color-mix(in srgb,var(--paper) 75%,#ffffff));box-shadow:inset 0 0 0 2px #ffffffaa,0 1px 2px #54628210}
|
|
2667
2746
|
.gene-panel:before,.gene-panel:after{content:"";position:absolute;top:50%;width:6px;height:6px;background:var(--light-edge);border:1px solid var(--edge);transform:translateY(-50%) rotate(45deg)}.gene-panel:before{left:-4px}.gene-panel:after{right:-4px}.gene-crest{flex:0 0 26px;height:29px;color:var(--accent)}.gene-crest svg{display:block;width:100%;height:100%}.gene-rank{font-size:18px;line-height:1.35;letter-spacing:1px;overflow-wrap:anywhere;font-weight:700;text-align:center;min-width:0;color:var(--ink)}
|
|
2668
|
-
.
|
|
2747
|
+
.exploration-rank-row{display:flex;align-items:center;justify-content:center;gap:7px;margin:10px 0 0;font:16px/1.4 "KaiTi","STKaiti","Microsoft YaHei",sans-serif;letter-spacing:1px;color:var(--subtle)}.exploration-rank-row>svg{width:17px;height:17px;flex-shrink:0;fill:none;stroke:var(--accent);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}.exploration-rank-row>span{white-space:nowrap}.exploration-rank-row strong{font-size:18px;font-weight:700;color:var(--ink);overflow-wrap:anywhere;min-width:0}
|
|
2748
|
+
.combat-row{display:flex;align-items:center;justify-content:center;gap:8px;margin:12px 0 0;padding:0 6px;min-width:0;font:28px/1.2 "KaiTi","STKaiti","Microsoft YaHei",sans-serif;position:relative;z-index:4}.power-icon{flex:0 0 34px;height:34px;display:grid;place-items:center;color:var(--accent)}.power-icon svg{display:block;width:34px;height:34px;overflow:visible}.power-label{font:inherit;white-space:nowrap}.power-value{min-width:0;flex:0 1 auto;text-align:center;overflow-wrap:anywhere;font:inherit;color:var(--accent);letter-spacing:0}
|
|
2669
2749
|
.companion-resource{font-family:"Microsoft YaHei",sans-serif;margin-bottom:12px}.resource-heading{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:17px;color:var(--subtle);line-height:1.35}.resource-label{display:flex;align-items:center;gap:6px;font-weight:600;flex-shrink:0}.resource-label svg{width:18px;height:18px;fill:var(--health)}.resource-number{text-align:right;overflow-wrap:anywhere;min-width:0;font-size:15px}
|
|
2670
|
-
.resource-track{height:18px;position:relative;margin-top:5px;border:1px solid var(--track-edge);border-radius:10px;overflow:hidden;background:linear-gradient(var(--track),#f2f5ed);box-shadow:inset 0 1px 2px #6e805825}.resource-fill{display:block;position:absolute;top:0;bottom:0;left:0;border-radius:9px;background:linear-gradient(var(--health-light),var(--health) 55%,color-mix(in srgb,var(--health) 80%,var(--health-light)));border-right:1px solid #fff9}.resource-percent{position:absolute;inset:0;display:grid;place-items:center;font:11px/1 "Microsoft YaHei",sans-serif;color:#fffef7;text-shadow:0 1px 2px #435443}.exp-resource
|
|
2671
|
-
.
|
|
2750
|
+
.resource-track{height:18px;position:relative;margin-top:5px;border:1px solid var(--track-edge);border-radius:10px;overflow:hidden;background:linear-gradient(var(--track),#f2f5ed);box-shadow:inset 0 1px 2px #6e805825}.resource-fill{display:block;position:absolute;top:0;bottom:0;left:0;border-radius:9px;background:linear-gradient(var(--health-light),var(--health) 55%,color-mix(in srgb,var(--health) 80%,var(--health-light)));border-right:1px solid #fff9}.resource-percent{position:absolute;inset:0;display:grid;place-items:center;font:11px/1 "Microsoft YaHei",sans-serif;color:#fffef7;text-shadow:0 1px 2px #435443}.exp-resource{width:calc(100% - 20px);align-self:center;margin:0 0 14px}.exp-resource .resource-track{height:6px;margin-top:0;border-color:#d5c48b;border-radius:4px;background:#eee9d7;box-shadow:inset 0 1px 1px #9d82351a}.exp-resource .resource-fill{border-radius:3px;border-right:0;background:linear-gradient(#fff0a0,#e8bd48 60%,#d6a934)}
|
|
2751
|
+
.hp-resource{display:flex;align-items:center;margin-top:16px;margin-bottom:0}.hp-resource .resource-track{flex:1;min-width:0;height:20px;margin-top:0}.hp-bar-value{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:0 8px;white-space:nowrap;font:12px/1 "Microsoft YaHei",sans-serif;color:#fffef7;text-shadow:0 1px 2px #435443,0 0 2px #435443}
|
|
2752
|
+
.companion-attributes{margin-top:5px;min-width:0;flex:1;display:flex;flex-direction:column;justify-content:center}.attribute-divider{height:28px;margin:0 0 3px;display:flex;align-items:center;justify-content:center}.attribute-divider svg{display:block;width:100%;height:36px}.companion-radar{width:100%;height:260px;display:block;overflow:visible}
|
|
2672
2753
|
.radar-grid{fill:none;stroke:var(--radar-grid);stroke-width:1.1}.radar-axis{stroke:var(--radar-grid);stroke-width:1;opacity:.8}.radar-area{fill:var(--radar-fill);stroke:var(--radar);stroke-width:2.3;stroke-linejoin:round}.radar-dot{fill:#fffefa;stroke:var(--radar);stroke-width:2}.radar-label{font:19px "KaiTi","STKaiti","Microsoft YaHei",sans-serif;fill:var(--ink)}.radar-value{font:20px Georgia,"Microsoft YaHei",serif;fill:var(--ink)}.radar-scale{font:11px Georgia,serif;fill:var(--subtle)}.empty-attributes{padding:45px 10px;color:var(--subtle);font:18px/1.6 "Microsoft YaHei",sans-serif;text-align:center}.custom-attributes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px 10px;margin:6px 0 0;font:15px/1.5 "Microsoft YaHei",sans-serif;color:var(--subtle)}.custom-attributes span{overflow-wrap:anywhere}.custom-attributes b{font-weight:500;color:var(--ink)}
|
|
2673
2754
|
`;
|
|
2674
2755
|
|
|
@@ -2721,6 +2802,12 @@ function characterGeneCrest(tier) {
|
|
|
2721
2802
|
return `<svg viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="m30 4 20 10v20L30 55 10 34V14Z" fill="var(--paper)" stroke="currentColor" stroke-width="1.6"/><path d="m30 9 15 8v16L30 49 15 33V17Z" fill="none" stroke="var(--light-edge)" stroke-width="1"/><path d="M23 27v-6a7 7 0 0 1 14 0v6" fill="none" stroke="currentColor" stroke-width="2.5"/><rect x="20" y="26" width="20" height="15" rx="3" fill="currentColor"/><circle cx="30" cy="32" r="2" fill="var(--light-edge)"/><path d="M30 33v4" stroke="var(--light-edge)" stroke-width="1.8"/>${tier >= 3 ? '<path d="m30 2 3 4-3 4-3-4Z" fill="var(--gem)" stroke="var(--light-edge)"/>' : ""}${tier >= 5 ? '<path d="m18 12 1-7 6 4 5-7 5 7 6-4 1 7Z" fill="var(--accent)" stroke="var(--light-edge)" stroke-width=".7"/>' : ""}</svg>`;
|
|
2722
2803
|
}
|
|
2723
2804
|
__name(characterGeneCrest, "characterGeneCrest");
|
|
2805
|
+
var characterAttributeDivider = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 310 36">
|
|
2806
|
+
${ornamentPaint}
|
|
2807
|
+
<g fill="none" stroke="var(--edge)" stroke-width=".8"><path d="M5 18h91m118 0h91"/><path d="M75 18c18 0 29-8 47-8m66 0c18 0 29 8 47 8"/><path d="M102 18c12 0 21 6 31 6m44 0c10 0 19-6 31-6"/></g>
|
|
2808
|
+
<g fill="url(#character-leaf)" stroke="var(--light-edge)" stroke-width=".6"><path d="M120 11c-10-1-14-6-16-10 10 0 17 3 16 10Zm14 12c-10 2-18-1-22-6 10-2 18-1 22 6Zm56-12c10-1 14-6 16-10-10 0-17 3-16 10Zm-14 12c10 2 18-1 22-6-10-2-18-1-22 6Z"/></g>
|
|
2809
|
+
${flower(155, 18, 0.5)}<g fill="var(--accent)"><path d="m94 18 3-3 3 3-3 3Zm116 0 3-3 3 3-3 3Z"/></g>
|
|
2810
|
+
</svg>`;
|
|
2724
2811
|
|
|
2725
2812
|
// src/plugin/characterCardTemplate.ts
|
|
2726
2813
|
var finite = /* @__PURE__ */ __name((value) => Number.isFinite(value) ? value : 0, "finite");
|
|
@@ -2735,7 +2822,6 @@ var primaryAttributes = [
|
|
|
2735
2822
|
["resistance", "抗性"]
|
|
2736
2823
|
];
|
|
2737
2824
|
var primaryIds = new Set(primaryAttributes.map(([id]) => id));
|
|
2738
|
-
var heading = /* @__PURE__ */ __name((label) => `<h2 class="ornament-heading"><span class="heading-star" aria-hidden="true">✦</span>${cardEscape(label)}<span class="heading-star" aria-hidden="true">✦</span></h2>`, "heading");
|
|
2739
2825
|
var corners = /* @__PURE__ */ __name((tier, positions = ["tl", "tr", "bl", "br"]) => positions.map((position) => `<span class="panel-corner corner-${position}" data-decoration-level="${tier}">${characterTierOrnament(tier)}</span>`).join(""), "corners");
|
|
2740
2826
|
function radar(attributes) {
|
|
2741
2827
|
if (!attributes.length) return '<p class="empty-attributes">暂无一级属性</p>';
|
|
@@ -2781,14 +2867,16 @@ function characterCardHtml(card, artwork, _frame, defaultArtwork, titleArtwork,
|
|
|
2781
2867
|
const hpPercent = ratio(card.hp, card.maxHp) * 100;
|
|
2782
2868
|
const experience = Math.max(0, Math.min(100, finite(card.experiencePercent)));
|
|
2783
2869
|
const geneRank = card.geneLockRankName || "基因锁未开启";
|
|
2870
|
+
const explorationRank = card.explorationRank?.trim();
|
|
2784
2871
|
return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><style>${characterCardStyles}</style></head><body><main id="capture" class="companion-sheet character-adventure character-sheet gene-tier-${tier}" data-gene-lock-tier="${tier}" data-decoration-level="${tier}"><span class="character-ambient" aria-hidden="true">${characterFloralWatermark}</span><div class="character-card companion-main">
|
|
2785
2872
|
<div class="portrait-column"><div class="companion-panel companion-portrait character-portrait">${corners(tier)}<div class="portrait-window portrait">${portrait ? `<img id="character-image" class="character-artwork" src="${cardEscape(portrait)}" data-fallback="${cardEscape(defaultArtwork ?? "")}" alt="${cardEscape(card.name)}的形象图">` : '<div class="placeholder"><span>形象尚未生成</span><small>角色形象</small></div>'}</div>
|
|
2786
|
-
|
|
2787
|
-
<
|
|
2788
|
-
|
|
2789
|
-
<
|
|
2790
|
-
<div class="resource companion-resource
|
|
2791
|
-
<
|
|
2873
|
+
${titleArtwork || card.titleImageUrl ? `<div class="title-image-slot character-title-centered"><img id="title-image" class="title-artwork" src="${cardEscape(titleArtwork || characterTitlePlaceholder)}" data-fallback="${cardEscape(characterTitlePlaceholder)}" alt="${titleArtwork ? "称号图片" : "称号图片占位"}"></div>` : ""}</div>
|
|
2874
|
+
<div class="combat-row companion-power-row"><span class="power-emblem power-icon" aria-hidden="true"><svg class="crossed-weapons" viewBox="0 0 42 42"><g fill="currentColor" stroke="var(--panel)" stroke-width=".9" stroke-linejoin="round"><g transform="rotate(-45 21 21)"><path d="M21 2 26 9v14l-5 4-5-4V9Z"/><path d="M12 26h18l-1 4H13Zm7 4h4v8h-4Zm-1 8h6v3h-6Z"/><path d="M21 7v15" fill="none" stroke="var(--light-edge)" stroke-width="1.1"/></g><g transform="rotate(45 21 21)"><path d="M21 2 26 9v14l-5 4-5-4V9Z"/><path d="M12 26h18l-1 4H13Zm7 4h4v8h-4Zm-1 8h6v3h-6Z"/><path d="M21 7v15" fill="none" stroke="var(--light-edge)" stroke-width="1.1"/></g></g></svg></span><span class="power-label companion-power-label">战力</span><strong id="combat-power" class="power-value companion-power">${number2(card.power)}</strong></div>
|
|
2875
|
+
</div>
|
|
2876
|
+
<section class="companion-panel companion-stats character-stats" aria-label="角色属性"><span class="character-paper-pattern" aria-hidden="true">${characterFloralWatermark}</span>${corners(tier, ["tr", "br"])}<div class="identity character-identity"><h1 id="character-name" class="character-name" title="${cardEscape(card.name)}">${cardEscape(card.name)}</h1><p class="level character-level"><span>Lv.</span><strong id="character-level">${number2(card.level)}</strong></p><div class="gene-panel"><span class="gene-crest" aria-hidden="true">${characterGeneCrest(tier)}</span><div id="gene-rank" class="gene-rank" title="${cardEscape(geneRank)}">${cardEscape(geneRank)}</div></div><p class="exploration-rank-row"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M19.8 7.7A8 8 0 1 0 20 16M20 3v5h-5M15.8 12a3.8 3.8 0 1 1-3.8-3.8"/></svg><span>轮回等级</span> <strong id="exploration-rank">${cardEscape(explorationRank ? explorationRank + "级" : "—")}</strong></p></div>
|
|
2877
|
+
<div class="resource companion-resource hp-resource"><div class="resource-track" role="progressbar" aria-label="生命值" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${hpPercent}" aria-valuetext="${number2(card.hp)} / ${number2(card.maxHp)}"><span class="resource-fill fill" style="width:${hpPercent}%"></span><span id="hp-numbers" class="hp-bar-value">${number2(card.hp)} / ${number2(card.maxHp)}</span></div></div>
|
|
2878
|
+
<div class="resource companion-resource exp-resource"><div id="experience-track" class="resource-track" role="progressbar" aria-label="经验进度" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${experience}"><span class="resource-fill" style="width:${experience}%"></span></div></div>
|
|
2879
|
+
<section class="attribute-panel companion-attributes" aria-label="一级属性"><div class="attribute-divider" aria-hidden="true">${characterAttributeDivider}</div>${radar(card.attributes)}</section></section>
|
|
2792
2880
|
</div></main></body></html>`;
|
|
2793
2881
|
}
|
|
2794
2882
|
__name(characterCardHtml, "characterCardHtml");
|
|
@@ -2854,7 +2942,7 @@ var primaryAttributes2 = [
|
|
|
2854
2942
|
];
|
|
2855
2943
|
var primaryIds2 = new Set(primaryAttributes2.map(([id]) => id));
|
|
2856
2944
|
var corners2 = /* @__PURE__ */ __name((positions = ["tl", "tr", "bl", "br"]) => positions.map((position) => `<span class="panel-corner corner-${position}">${companionCornerDecoration}</span>`).join(""), "corners");
|
|
2857
|
-
var
|
|
2945
|
+
var heading = /* @__PURE__ */ __name((title) => `<h2 class="ornament-heading"><span class="heading-star" aria-hidden="true">✦</span>${cardEscape(title)}<span class="heading-star" aria-hidden="true">✦</span></h2>`, "heading");
|
|
2858
2946
|
var paw = '<svg viewBox="0 0 28 28" aria-hidden="true"><ellipse cx="5" cy="10" rx="3" ry="4"/><ellipse cx="11" cy="5" rx="3" ry="4"/><ellipse cx="18" cy="5" rx="3" ry="4"/><ellipse cx="24" cy="10" rx="3" ry="4"/><path d="M5 21c0-5 4-4 6-9 1-3 5-3 6 0 2 5 6 4 6 9 0 5-6 4-9 2-3 2-9 3-9-2Z"/></svg>';
|
|
2859
2947
|
var crest = '<svg viewBox="0 0 32 32" aria-hidden="true" fill="currentColor"><path d="M15 28C5 24 3 16 4 7c8 0 11 9 11 21ZM17 28c10-4 12-12 11-21-8 0-11 9-11 21ZM16 18C9 13 10 7 16 2c6 5 7 11 0 16Z"/></svg>';
|
|
2860
2948
|
var sword = '<svg viewBox="0 0 42 42" aria-hidden="true"><path d="m9 5 5 1 16 21-4 4L9 11Zm24 0-5 1L12 27l4 4L33 11ZM14 27l14 10m0-10L14 37M9 35l4-4m20 4-4-4"/></svg>';
|
|
@@ -2898,13 +2986,13 @@ function radar2(card) {
|
|
|
2898
2986
|
}
|
|
2899
2987
|
__name(radar2, "radar");
|
|
2900
2988
|
function bloodlines(card, icons) {
|
|
2901
|
-
return `<section class="companion-panel bloodline-panel" aria-label="血统">${
|
|
2989
|
+
return `<section class="companion-panel bloodline-panel" aria-label="血统">${heading("血统")}${card.bloodlines.length ? `<div class="bloodline-list">${card.bloodlines.map((bloodline, index) => `<div class="bloodline-row"><span class="bloodline-crest${icons?.bloodlines?.[index] ? " has-entry-artwork" : ""}" aria-hidden="true">${bloodline.emoji ? cardEscape(bloodline.emoji) : crest}${icons?.bloodlines?.[index] ? `<img class="bloodline-entry-artwork" data-entry-index="${index}" src="${cardEscape(icons.bloodlines[index])}" alt="">` : ""}</span><span class="bloodline-name">${cardEscape(bloodline.name)}</span><span class="bloodline-quality">${cardEscape(bloodline.quality)}</span></div>`).join("")}</div>` : '<p class="empty-list">暂无血统</p>'}</section>`;
|
|
2902
2990
|
}
|
|
2903
2991
|
__name(bloodlines, "bloodlines");
|
|
2904
2992
|
function skills(card, icons) {
|
|
2905
2993
|
const active = '<path d="m8 24 16-16 2-3 4 4-3 2-16 16M7 21l9 9M7 31l5-5M5 33l2-2"/>';
|
|
2906
2994
|
const passive = '<path d="M17 30V14M17 24C7 22 4 14 5 8c9 1 13 7 12 16ZM17 19c1-9 5-14 13-15 0 8-4 14-13 15Z"/>';
|
|
2907
|
-
return `<section class="companion-panel companion-skills" aria-label="技能">${corners2()}${
|
|
2995
|
+
return `<section class="companion-panel companion-skills" aria-label="技能">${corners2()}${heading("技能")}${card.skills.length ? `<div class="skill-grid">${card.skills.map((skill, index) => `<div class="companion-skill" data-skill-id="${cardEscape(skill.id)}"><span class="skill-icon" aria-hidden="true"><svg viewBox="0 0 36 36">${skill.type === "passive" ? passive : active}</svg>${icons?.skills?.[index] ? `<img class="skill-entry-artwork" data-entry-index="${index}" src="${cardEscape(icons.skills[index])}" alt="">` : ""}</span><span class="skill-name">${cardEscape(skill.name)}</span><span class="skill-level">Lv.${number3(skill.rank)}</span></div>`).join("")}</div>` : '<p class="empty-list">暂无技能</p>'}</section>`;
|
|
2908
2996
|
}
|
|
2909
2997
|
__name(skills, "skills");
|
|
2910
2998
|
function companionCardHtml(card, artwork, icons) {
|
|
@@ -2920,7 +3008,7 @@ function companionCardHtml(card, artwork, icons) {
|
|
|
2920
3008
|
<div class="companion-power-row"><span class="power-icon" aria-hidden="true">${sword}</span><span class="companion-power-label">战力</span><strong id="companion-power" class="companion-power">${number3(card.power)}</strong></div>
|
|
2921
3009
|
<div class="companion-resource hp-resource"><div class="resource-heading"><span class="resource-label"><svg viewBox="0 0 32 32" aria-hidden="true"><path d="M16 28C6 21 2 17 2 10a7 7 0 0 1 14-2 7 7 0 0 1 14 2c0 7-4 11-14 18Z"/></svg>生命值</span><span id="companion-hp" class="resource-number">${number3(card.hp)} / ${number3(card.maxHp)}</span></div><div class="resource-track" role="progressbar" aria-label="生命值" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${healthPercent}"><span class="resource-fill" style="width:${healthPercent}%"></span><span class="resource-percent">${number3(healthPercent)}%</span></div></div>
|
|
2922
3010
|
${pet ? `<div class="companion-resource exp-resource"><div class="resource-heading"><span class="resource-label"><svg viewBox="0 0 32 32" aria-hidden="true"><path d="m16 2 4.5 9.1 10 1.4-7.3 7.1 1.7 10-8.9-4.7-8.9 4.7 1.7-10-7.3-7.1 10-1.4Z"/></svg>经验进度</span><span class="resource-number">${number3(experience)}%</span></div><div class="resource-track" role="progressbar" aria-label="经验进度" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${experience}"><span class="resource-fill" style="width:${experience}%"></span><span class="resource-percent">${number3(experience)}%</span></div></div>` : ""}
|
|
2923
|
-
<section class="companion-attributes" aria-label="一级属性">${
|
|
3011
|
+
<section class="companion-attributes" aria-label="一级属性">${heading("一级属性")}${radar2(card)}</section></section>
|
|
2924
3012
|
</div>${skills(card, icons)}</main></body></html>`;
|
|
2925
3013
|
}
|
|
2926
3014
|
__name(companionCardHtml, "companionCardHtml");
|
|
@@ -3134,6 +3222,18 @@ var import_node_crypto = require("node:crypto");
|
|
|
3134
3222
|
// src/plugin/cardLayout.ts
|
|
3135
3223
|
async function layoutCard(document2 = globalThis.document) {
|
|
3136
3224
|
await document2.fonts.ready;
|
|
3225
|
+
for (const name3 of document2.querySelectorAll("#character-name,#companion-name")) {
|
|
3226
|
+
const style = document2.defaultView.getComputedStyle(name3);
|
|
3227
|
+
const maximum = parseFloat(style.fontSize);
|
|
3228
|
+
const spacing = parseFloat(style.letterSpacing) || 0;
|
|
3229
|
+
name3.style.whiteSpace = "nowrap";
|
|
3230
|
+
for (let size = maximum; size >= 18; size--) {
|
|
3231
|
+
name3.style.fontSize = size + "px";
|
|
3232
|
+
name3.style.letterSpacing = spacing * size / maximum + "px";
|
|
3233
|
+
if (name3.scrollWidth <= name3.clientWidth) break;
|
|
3234
|
+
}
|
|
3235
|
+
if (name3.scrollWidth > name3.clientWidth) name3.style.whiteSpace = "normal";
|
|
3236
|
+
}
|
|
3137
3237
|
const titleBanner = document2.querySelector(".title-banner-artwork");
|
|
3138
3238
|
if (titleBanner) {
|
|
3139
3239
|
try {
|
|
@@ -3419,15 +3519,13 @@ function radar4(card) {
|
|
|
3419
3519
|
const attribute = card.attributes.find((value) => value.id === id);
|
|
3420
3520
|
return { name: attribute?.name?.trim() || name2, value: finite4(attribute?.value ?? 0) };
|
|
3421
3521
|
});
|
|
3422
|
-
const
|
|
3423
|
-
const magnitude = 10 ** Math.floor(Math.log10(max));
|
|
3424
|
-
const ceiling = Math.ceil(max / magnitude) * magnitude;
|
|
3522
|
+
const ceiling = Math.max(0, ...attributes.map((attribute) => attribute.value));
|
|
3425
3523
|
const point = /* @__PURE__ */ __name((index, radius) => {
|
|
3426
3524
|
const angle = -Math.PI / 2 + index * Math.PI / 3;
|
|
3427
3525
|
return [320 + Math.cos(angle) * radius, 190 + Math.sin(angle) * radius];
|
|
3428
3526
|
}, "point");
|
|
3429
3527
|
const polygon = /* @__PURE__ */ __name((radius) => attributes.map((_, index) => point(index, radius).join(",")).join(" "), "polygon");
|
|
3430
|
-
const data = attributes.map((attribute, index) => point(index, 122 *
|
|
3528
|
+
const data = attributes.map((attribute, index) => point(index, 122 * (ceiling > 0 ? Math.max(0, attribute.value / ceiling) : 0)));
|
|
3431
3529
|
return `<div class="radar-panel"><svg class="bloodline-radar" viewBox="0 0 640 396" role="img" aria-label="血统六维属性加成雷达图" xmlns="http://www.w3.org/2000/svg">
|
|
3432
3530
|
<defs><linearGradient id="bloodline-radar-fill" x1="0" y1="0" x2="1" y2="1"><stop stop-color="var(--quality-accent)" stop-opacity=".35"/><stop offset="1" stop-color="var(--quality-accent)" stop-opacity=".12"/></linearGradient></defs>
|
|
3433
3531
|
${[0.2, 0.4, 0.6, 0.8, 1].map((scale) => `<polygon points="${polygon(122 * scale)}" fill="none" stroke="#b9bdad" stroke-width="1.2"/>`).join("")}
|
|
@@ -3929,6 +4027,143 @@ var handel_base = class {
|
|
|
3929
4027
|
// src/plugin/serverHandel/text.ts
|
|
3930
4028
|
init_sessions();
|
|
3931
4029
|
|
|
4030
|
+
// src/shared/bot/inlineCommands.ts
|
|
4031
|
+
function inlineCommandSpans(content) {
|
|
4032
|
+
const spans = [];
|
|
4033
|
+
let depth = 0, start = 0, labelStart = 0;
|
|
4034
|
+
for (let index = 0; index < content.length; index++) {
|
|
4035
|
+
if (content[index] === "[") {
|
|
4036
|
+
if (depth === 0) {
|
|
4037
|
+
start = index > 0 && content[index - 1] === "\\" ? index - 1 : index;
|
|
4038
|
+
labelStart = index + 1;
|
|
4039
|
+
}
|
|
4040
|
+
depth++;
|
|
4041
|
+
} else if (content[index] === "]" && depth > 0 && --depth === 0) {
|
|
4042
|
+
const label = content.slice(labelStart, index).replace(/\\$/, "");
|
|
4043
|
+
if (!label.trim() || /[\[\]\r\n]/.test(label) || /^\d+$/.test(label.trim())) continue;
|
|
4044
|
+
const alias = /^\(command:([^()[\]\r\n]+)\)/.exec(content.slice(index + 1));
|
|
4045
|
+
const command = alias ? alias[1].trim() : label.split(/[++]/, 1)[0].trim().replace(/^🔄\s*/u, "");
|
|
4046
|
+
if (!command) continue;
|
|
4047
|
+
const end = index + 1 + (alias?.[0].length ?? 0);
|
|
4048
|
+
spans.push({ start, end, label, command, ...alias ? { aliased: true } : {} });
|
|
4049
|
+
if (alias) index = end - 1;
|
|
4050
|
+
}
|
|
4051
|
+
}
|
|
4052
|
+
return spans;
|
|
4053
|
+
}
|
|
4054
|
+
__name(inlineCommandSpans, "inlineCommandSpans");
|
|
4055
|
+
function renderPlainInlineCommandAliases(content) {
|
|
4056
|
+
let result = "", offset = 0;
|
|
4057
|
+
for (const span of inlineCommandSpans(content)) {
|
|
4058
|
+
if (!span.aliased) continue;
|
|
4059
|
+
result += content.slice(offset, span.start) + (span.label.trim() === span.command ? `[${span.command}]` : `${span.label}[${span.command}]`);
|
|
4060
|
+
offset = span.end;
|
|
4061
|
+
}
|
|
4062
|
+
return result + content.slice(offset);
|
|
4063
|
+
}
|
|
4064
|
+
__name(renderPlainInlineCommandAliases, "renderPlainInlineCommandAliases");
|
|
4065
|
+
|
|
4066
|
+
// src/shared/bot/analysisMsg.ts
|
|
4067
|
+
function messageButtonFallbackLines(data) {
|
|
4068
|
+
return [...new Set((data.buttons ?? []).flatMap((row) => row.buttons.map((button) => "[" + button.command + "]" + button.label)))];
|
|
4069
|
+
}
|
|
4070
|
+
__name(messageButtonFallbackLines, "messageButtonFallbackLines");
|
|
4071
|
+
function matchesButtonFallback(content, fallback) {
|
|
4072
|
+
const bracket = fallback.indexOf("]");
|
|
4073
|
+
const prefix = fallback.slice(0, bracket + 1);
|
|
4074
|
+
const line = content.trim();
|
|
4075
|
+
return line.startsWith(prefix) && line.slice(prefix.length).trim() === fallback.slice(prefix.length).trim();
|
|
4076
|
+
}
|
|
4077
|
+
__name(matchesButtonFallback, "matchesButtonFallback");
|
|
4078
|
+
function appendMessageButtonFallbacks(content, data) {
|
|
4079
|
+
const lines = content.replace(/\r\n?/g, "\n").split("\n");
|
|
4080
|
+
const missing = messageButtonFallbackLines(data).filter((fallback) => !lines.some((line) => matchesButtonFallback(line, fallback)));
|
|
4081
|
+
if (!missing.length) return content;
|
|
4082
|
+
return content + (content && !content.endsWith("\n") ? "\n" : "") + missing.join("\n") + "\n";
|
|
4083
|
+
}
|
|
4084
|
+
__name(appendMessageButtonFallbacks, "appendMessageButtonFallbacks");
|
|
4085
|
+
function withoutMessageButtonFallbacks(data) {
|
|
4086
|
+
const fallbacks = messageButtonFallbackLines(data);
|
|
4087
|
+
if (!fallbacks.length) return data;
|
|
4088
|
+
return { ...data, line: data.line.map((item) => {
|
|
4089
|
+
if (item.type !== 1 /* line */ || item.codeBlock || item.reward || item.mailPart !== void 0) return item;
|
|
4090
|
+
const lines = item.content.replace(/\r\n?/g, "\n").split("\n");
|
|
4091
|
+
const kept = lines.filter((line) => !fallbacks.some((fallback) => matchesButtonFallback(line, fallback)));
|
|
4092
|
+
return kept.length === lines.length ? item : { ...item, content: kept.join("\n") };
|
|
4093
|
+
}) };
|
|
4094
|
+
}
|
|
4095
|
+
__name(withoutMessageButtonFallbacks, "withoutMessageButtonFallbacks");
|
|
4096
|
+
var AnalysisMsg = class {
|
|
4097
|
+
static {
|
|
4098
|
+
__name(this, "AnalysisMsg");
|
|
4099
|
+
}
|
|
4100
|
+
parse(data) {
|
|
4101
|
+
let msg = "";
|
|
4102
|
+
let haveTitle = false;
|
|
4103
|
+
const commands = new Map(data.pageNav?.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
4104
|
+
const labeledEntries = /* @__PURE__ */ new Map();
|
|
4105
|
+
for (const entry of data.pageNav?.entries ?? []) {
|
|
4106
|
+
if (entry.label === void 0) continue;
|
|
4107
|
+
const row = labeledEntries.get(entry.lineIndex) ?? [];
|
|
4108
|
+
row.push(entry);
|
|
4109
|
+
labeledEntries.set(entry.lineIndex, row);
|
|
4110
|
+
}
|
|
4111
|
+
const withCommandHint = /* @__PURE__ */ __name((content, command) => {
|
|
4112
|
+
const hint = command && !content.includes(`[${command}]`) && content.trim() !== command ? ` [${command}]` : "";
|
|
4113
|
+
return content + hint;
|
|
4114
|
+
}, "withCommandHint");
|
|
4115
|
+
for (const [lineIndex, item] of data.line.entries()) {
|
|
4116
|
+
switch (item.type) {
|
|
4117
|
+
case 0 /* title */:
|
|
4118
|
+
haveTitle = true;
|
|
4119
|
+
msg += `┄━═${item.content}═━┄
|
|
4120
|
+
`;
|
|
4121
|
+
break;
|
|
4122
|
+
case 1 /* line */:
|
|
4123
|
+
const labeledRow = labeledEntries.get(lineIndex);
|
|
4124
|
+
const content = labeledRow ? labeledRow.map((entry) => entry.label + (entry.description ? " · " + entry.description : "") + ` [${entry.viewCommand}]`).join("") : withCommandHint(item.content, commands.get(lineIndex));
|
|
4125
|
+
const plainContent = item.codeBlock || item.mailPart === "body" || labeledRow ? content : renderPlainInlineCommandAliases(content);
|
|
4126
|
+
msg += `${plainContent}
|
|
4127
|
+
`;
|
|
4128
|
+
break;
|
|
4129
|
+
case 2 /* error */:
|
|
4130
|
+
msg += `❌出错了!错误原因:${item.content},请反馈至联系开发者
|
|
4131
|
+
`;
|
|
4132
|
+
break;
|
|
4133
|
+
default:
|
|
4134
|
+
break;
|
|
4135
|
+
}
|
|
4136
|
+
}
|
|
4137
|
+
msg = appendMessageButtonFallbacks(msg, data);
|
|
4138
|
+
if (haveTitle) {
|
|
4139
|
+
msg += "┄━════════━┄";
|
|
4140
|
+
}
|
|
4141
|
+
return msg;
|
|
4142
|
+
}
|
|
4143
|
+
};
|
|
4144
|
+
|
|
4145
|
+
// src/plugin/serverHandel/qqMessageButtons.ts
|
|
4146
|
+
function renderQQKeyboard(data) {
|
|
4147
|
+
const rows = data.buttons;
|
|
4148
|
+
if (!rows?.length) return void 0;
|
|
4149
|
+
if (rows.length > 5 || rows.some((row) => !row.buttons.length || row.buttons.length > 5)) {
|
|
4150
|
+
throw new Error("QQ 按钮最多 5 行,每行必须有 1–5 个按钮");
|
|
4151
|
+
}
|
|
4152
|
+
return { content: { rows: rows.map((row, rowIndex) => ({
|
|
4153
|
+
buttons: row.buttons.map((button, buttonIndex) => {
|
|
4154
|
+
if (!button.label.trim() || !button.command.trim() || /[\r\n\0]/.test(button.label + button.command) || button.command.length > 4e3 || button.style !== void 0 && button.style !== "primary" && button.style !== "secondary") {
|
|
4155
|
+
throw new Error("QQ 按钮文案和指令必须是非空单行文本,样式必须为 primary 或 secondary");
|
|
4156
|
+
}
|
|
4157
|
+
return {
|
|
4158
|
+
id: "action-" + rowIndex + "-" + buttonIndex,
|
|
4159
|
+
render_data: { label: button.label, visited_label: button.label, style: button.style === "primary" ? 1 : 0 },
|
|
4160
|
+
action: { type: 2, permission: { type: 2 }, data: button.command, enter: true, reply: false, unsupport_tips: "请发送:" + button.command }
|
|
4161
|
+
};
|
|
4162
|
+
})
|
|
4163
|
+
})) } };
|
|
4164
|
+
}
|
|
4165
|
+
__name(renderQQKeyboard, "renderQQKeyboard");
|
|
4166
|
+
|
|
3932
4167
|
// src/plugin/serverHandel/qqMarkdownHelpers.ts
|
|
3933
4168
|
function escapeMarkdown(value) {
|
|
3934
4169
|
return value.replace(/[\\`*_{}\[\]()#+\-.!|>~<&]/g, "\\$&");
|
|
@@ -4051,6 +4286,7 @@ function renderQQMailMarkdown(data) {
|
|
|
4051
4286
|
}
|
|
4052
4287
|
__name(renderQQMailMarkdown, "renderQQMailMarkdown");
|
|
4053
4288
|
function renderQQRewardMarkdown(data, showGreeting) {
|
|
4289
|
+
data = withoutMessageButtonFallbacks(data);
|
|
4054
4290
|
if (data.mail) return appendMissingBattleLogLinks(renderQQMailMarkdown(data), data);
|
|
4055
4291
|
const rewards = data.line.filter((item) => item.type === 1 /* line */ && item.reward).map((item) => renderRewardLine(item.content)).filter(Boolean);
|
|
4056
4292
|
if (rewards.length && !data.mail) return appendMissingBattleLogLinks("🎁获得奖励\n\n" + rewards.join(" \n"), data);
|
|
@@ -4099,36 +4335,21 @@ function inlineCommandUrl(command) {
|
|
|
4099
4335
|
return `mqqapi://aio/inlinecmd?command=${encoded}&enter=true&reply=false`;
|
|
4100
4336
|
}
|
|
4101
4337
|
__name(inlineCommandUrl, "inlineCommandUrl");
|
|
4102
|
-
function
|
|
4103
|
-
const spans =
|
|
4104
|
-
let depth = 0, start = 0, labelStart = 0;
|
|
4105
|
-
for (let index = 0; index < content.length; index++) {
|
|
4106
|
-
if (content[index] === "[") {
|
|
4107
|
-
if (depth === 0) {
|
|
4108
|
-
start = index > 0 && content[index - 1] === "\\" ? index - 1 : index;
|
|
4109
|
-
labelStart = index + 1;
|
|
4110
|
-
}
|
|
4111
|
-
depth++;
|
|
4112
|
-
} else if (content[index] === "]" && depth > 0 && --depth === 0) {
|
|
4113
|
-
const label = content.slice(labelStart, index).replace(/\\$/, "");
|
|
4114
|
-
if (!label.trim() || /[\[\]\r\n]/.test(label) || /^\d+$/.test(label.trim())) continue;
|
|
4115
|
-
const command = label.split(/[++]/, 1)[0].trim().replace(/^🔄\s*/u, "");
|
|
4116
|
-
if (command) spans.push({ start, end: index + 1, label, command });
|
|
4117
|
-
}
|
|
4118
|
-
}
|
|
4338
|
+
function inlineCommandSpans2(content) {
|
|
4339
|
+
const spans = inlineCommandSpans(content);
|
|
4119
4340
|
const logLinks = battleLogLinkSpans(content);
|
|
4120
4341
|
return spans.filter((span) => !logLinks.some((link) => span.start < link.end && span.end > link.start));
|
|
4121
4342
|
}
|
|
4122
|
-
__name(
|
|
4343
|
+
__name(inlineCommandSpans2, "inlineCommandSpans");
|
|
4123
4344
|
function hasInlineCommands(content) {
|
|
4124
|
-
return
|
|
4345
|
+
return inlineCommandSpans2(content).length > 0;
|
|
4125
4346
|
}
|
|
4126
4347
|
__name(hasInlineCommands, "hasInlineCommands");
|
|
4127
4348
|
function renderInlineCommands(content) {
|
|
4128
4349
|
const parts = [];
|
|
4129
4350
|
let offset = 0;
|
|
4130
4351
|
const spans = [
|
|
4131
|
-
...
|
|
4352
|
+
...inlineCommandSpans2(content).map((span) => ({ ...span, rendered: "[" + escapeMarkdown(span.label) + "](" + inlineCommandUrl(span.command) + ")" })),
|
|
4132
4353
|
...battleLogLinkSpans(content).map((span) => ({ ...span, rendered: renderBattleLogLink(span) }))
|
|
4133
4354
|
].sort((a, b) => a.start - b.start);
|
|
4134
4355
|
for (const span of spans) {
|
|
@@ -4255,6 +4476,7 @@ function renderQQInventoryMarkdown(data, showGreeting) {
|
|
|
4255
4476
|
}
|
|
4256
4477
|
__name(renderQQInventoryMarkdown, "renderQQInventoryMarkdown");
|
|
4257
4478
|
function renderQQPageMarkdown(data, showGreeting) {
|
|
4479
|
+
data = withoutMessageButtonFallbacks(data);
|
|
4258
4480
|
const hasEntryLabels = data.pageNav?.entries?.some((entry) => entry.label !== void 0) ?? false;
|
|
4259
4481
|
if (data.task && !hasEntryLabels) return renderQQTaskMarkdown(data);
|
|
4260
4482
|
if (!hasEntryLabels && data.pageNav && data.line.some((item) => item.type === 0 /* title */ && /^(?:💼)?我的背包$/u.test(compactDisplayText(item.content))))
|
|
@@ -4380,7 +4602,7 @@ function canSendQQPage(session, data) {
|
|
|
4380
4602
|
return !!internal?.sendMessage && !!internal.sendPrivateMessage;
|
|
4381
4603
|
}
|
|
4382
4604
|
__name(canSendQQPage, "canSendQQPage");
|
|
4383
|
-
async function sendQQMarkdown(session, markdown) {
|
|
4605
|
+
async function sendQQMarkdown(session, markdown, keyboard) {
|
|
4384
4606
|
const internal = session.bot.internal;
|
|
4385
4607
|
const request = {
|
|
4386
4608
|
// With msg_type=2, QQ requires the ordinary content field to be empty.
|
|
@@ -4388,6 +4610,7 @@ async function sendQQMarkdown(session, markdown) {
|
|
|
4388
4610
|
msg_type: 2,
|
|
4389
4611
|
markdown: { content: markdown }
|
|
4390
4612
|
};
|
|
4613
|
+
if (keyboard) request.keyboard = keyboard;
|
|
4391
4614
|
const age = Date.now() - session.timestamp;
|
|
4392
4615
|
if (session.messageId && Number.isFinite(age) && age >= 0 && age < 5 * 60 * 1e3 - 2e3) {
|
|
4393
4616
|
const sequenced = session;
|
|
@@ -4401,68 +4624,21 @@ async function sendQQMarkdown(session, markdown) {
|
|
|
4401
4624
|
}
|
|
4402
4625
|
__name(sendQQMarkdown, "sendQQMarkdown");
|
|
4403
4626
|
|
|
4404
|
-
// src/shared/bot/analysisMsg.ts
|
|
4405
|
-
var AnalysisMsg = class {
|
|
4406
|
-
static {
|
|
4407
|
-
__name(this, "AnalysisMsg");
|
|
4408
|
-
}
|
|
4409
|
-
parse(data) {
|
|
4410
|
-
let msg = "";
|
|
4411
|
-
let haveTitle = false;
|
|
4412
|
-
const commands = new Map(data.pageNav?.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
4413
|
-
const labeledEntries = /* @__PURE__ */ new Map();
|
|
4414
|
-
for (const entry of data.pageNav?.entries ?? []) {
|
|
4415
|
-
if (entry.label === void 0) continue;
|
|
4416
|
-
const row = labeledEntries.get(entry.lineIndex) ?? [];
|
|
4417
|
-
row.push(entry);
|
|
4418
|
-
labeledEntries.set(entry.lineIndex, row);
|
|
4419
|
-
}
|
|
4420
|
-
const withCommandHint = /* @__PURE__ */ __name((content, command) => {
|
|
4421
|
-
const hint = command && !content.includes(`[${command}]`) && content.trim() !== command ? ` [${command}]` : "";
|
|
4422
|
-
return content + hint;
|
|
4423
|
-
}, "withCommandHint");
|
|
4424
|
-
for (const [lineIndex, item] of data.line.entries()) {
|
|
4425
|
-
switch (item.type) {
|
|
4426
|
-
case 0 /* title */:
|
|
4427
|
-
haveTitle = true;
|
|
4428
|
-
msg += `┄━═${item.content}═━┄
|
|
4429
|
-
`;
|
|
4430
|
-
break;
|
|
4431
|
-
case 1 /* line */:
|
|
4432
|
-
const labeledRow = labeledEntries.get(lineIndex);
|
|
4433
|
-
const content = labeledRow ? labeledRow.map((entry) => entry.label + (entry.description ? " · " + entry.description : "") + ` [${entry.viewCommand}]`).join("") : withCommandHint(item.content, commands.get(lineIndex));
|
|
4434
|
-
msg += `${content}
|
|
4435
|
-
`;
|
|
4436
|
-
break;
|
|
4437
|
-
case 2 /* error */:
|
|
4438
|
-
msg += `❌出错了!错误原因:${item.content},请反馈至联系开发者
|
|
4439
|
-
`;
|
|
4440
|
-
break;
|
|
4441
|
-
default:
|
|
4442
|
-
break;
|
|
4443
|
-
}
|
|
4444
|
-
}
|
|
4445
|
-
if (haveTitle) {
|
|
4446
|
-
msg += "┄━════════━┄";
|
|
4447
|
-
}
|
|
4448
|
-
return msg;
|
|
4449
|
-
}
|
|
4450
|
-
};
|
|
4451
|
-
|
|
4452
4627
|
// src/plugin/serverHandel/qqCommandMessage.ts
|
|
4453
4628
|
function renderQQCommandMarkdown(data, showGreeting) {
|
|
4629
|
+
data = withoutMessageButtonFallbacks(data);
|
|
4454
4630
|
if (data.notification) {
|
|
4455
4631
|
const onlyLine = data.line.length === 1 ? data.line[0] : void 0;
|
|
4456
4632
|
if (onlyLine?.type === 1 /* line */ && /^🔔系统提示:[^\r\n]+$/.test(onlyLine.content)) {
|
|
4457
4633
|
return renderInlineCommands(onlyLine.content);
|
|
4458
4634
|
}
|
|
4459
4635
|
const title = data.line.find((item) => item.type === 0 /* title */)?.content;
|
|
4460
|
-
const
|
|
4636
|
+
const heading2 = title === void 0 ? "**🔔** 系统提示" : `**${escapeMarkdown(title)}**`;
|
|
4461
4637
|
const body = data.line.filter((item) => item.type !== 0 /* title */).flatMap((item) => {
|
|
4462
4638
|
const content = item.type === 2 /* error */ ? `❌ ${item.content}` : item.content;
|
|
4463
4639
|
return content.replace(/\r\n?/g, "\n").split("\n").map((line) => "> " + renderInlineCommands(line));
|
|
4464
4640
|
}).join(" \n");
|
|
4465
|
-
return
|
|
4641
|
+
return heading2 + (body ? "\n\n" + body : "");
|
|
4466
4642
|
}
|
|
4467
4643
|
const rewardMessage = isRewardMessage(data);
|
|
4468
4644
|
if (!data.commandHelp && !data.pageNav && data.line.some((item) => item.type === 1 /* line */ && !item.reward && /^\[\d+\]\s*[^\r\n]+$/.test(item.content))) {
|
|
@@ -4494,8 +4670,10 @@ function renderQQCommandMarkdown(data, showGreeting) {
|
|
|
4494
4670
|
break;
|
|
4495
4671
|
}
|
|
4496
4672
|
flushRewards();
|
|
4497
|
-
|
|
4498
|
-
|
|
4673
|
+
for (const line of item.content.replace(/\r\n?/g, "\n").split("\n")) {
|
|
4674
|
+
if (!line.trim()) flushBody();
|
|
4675
|
+
else bodyLines.push(renderInlineCommands(line));
|
|
4676
|
+
}
|
|
4499
4677
|
break;
|
|
4500
4678
|
case 2 /* error */:
|
|
4501
4679
|
flushBody();
|
|
@@ -4512,6 +4690,7 @@ __name(renderQQCommandMarkdown, "renderQQCommandMarkdown");
|
|
|
4512
4690
|
|
|
4513
4691
|
// src/plugin/serverHandel/qqTransactionMessage.ts
|
|
4514
4692
|
function renderQQTransactionMarkdown(data, showGreeting) {
|
|
4693
|
+
data = withoutMessageButtonFallbacks(data);
|
|
4515
4694
|
const rewardMessage = isRewardMessage(data);
|
|
4516
4695
|
const shortageMessage = data.transaction === true && data.line.some((item) => item.type === 0 /* title */ && item.content === "❌材料不足");
|
|
4517
4696
|
const sections = [];
|
|
@@ -4605,6 +4784,7 @@ function fencedStory(content) {
|
|
|
4605
4784
|
}
|
|
4606
4785
|
__name(fencedStory, "fencedStory");
|
|
4607
4786
|
function renderQQStoryMarkdown(data, showGreeting) {
|
|
4787
|
+
data = withoutMessageButtonFallbacks(data);
|
|
4608
4788
|
if (data.reward === true && data.line.some((item) => item.type === 1 /* line */ && item.reward === true && item.content.trim())) {
|
|
4609
4789
|
const stories = data.line.filter((item) => item.type === 1 /* line */ && item.codeBlock === true).map((item) => fencedStory(item.content));
|
|
4610
4790
|
return [...stories, renderQQRewardMarkdown(data, false)].join("\n\n");
|
|
@@ -4663,15 +4843,29 @@ __name(renderQQStoryMarkdown, "renderQQStoryMarkdown");
|
|
|
4663
4843
|
function renderQQMessagePreview(data, showGreeting = false) {
|
|
4664
4844
|
const plain = new AnalysisMsg().parse(data);
|
|
4665
4845
|
const text = data.notification ? plain.trimEnd() : plain;
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4846
|
+
let keyboard;
|
|
4847
|
+
try {
|
|
4848
|
+
keyboard = renderQQKeyboard(data);
|
|
4849
|
+
} catch {
|
|
4850
|
+
return { kind: "text", text };
|
|
4851
|
+
}
|
|
4852
|
+
data = withoutMessageButtonFallbacks(data);
|
|
4853
|
+
const native = /* @__PURE__ */ __name((kind, markdown) => ({
|
|
4854
|
+
kind,
|
|
4855
|
+
markdown,
|
|
4856
|
+
text,
|
|
4857
|
+
...keyboard ? { keyboard } : {}
|
|
4858
|
+
}), "native");
|
|
4859
|
+
if (data.notification) return native("command", renderQQCommandMarkdown(data, false));
|
|
4860
|
+
if (hasStoryCodeBlock(data)) return native("story", renderQQStoryMarkdown(data, showGreeting));
|
|
4861
|
+
if (data.commandHelp) return native("command", renderQQCommandMarkdown(data, showGreeting));
|
|
4862
|
+
if (data.transaction) return native("transaction", renderQQTransactionMarkdown(data, showGreeting));
|
|
4863
|
+
if (data.pageNav) return native("page", renderQQPageMarkdown(data, showGreeting));
|
|
4864
|
+
if (isRewardMessage(data)) return native("reward", renderQQRewardMarkdown(data, showGreeting));
|
|
4672
4865
|
if (battleLogMessageLinks(data).length || data.line.some((item) => (item.type === 1 /* line */ || item.type === 2 /* error */) && hasInlineCommands(item.content))) {
|
|
4673
|
-
return
|
|
4866
|
+
return native("command", renderQQCommandMarkdown(data, showGreeting));
|
|
4674
4867
|
}
|
|
4868
|
+
if (keyboard) return native("command", renderQQCommandMarkdown(data, showGreeting));
|
|
4675
4869
|
return { kind: "text", text };
|
|
4676
4870
|
}
|
|
4677
4871
|
__name(renderQQMessagePreview, "renderQQMessagePreview");
|
|
@@ -4688,7 +4882,7 @@ var handelr_text = class extends handel_base {
|
|
|
4688
4882
|
if (preview.markdown !== void 0 && canSendQQPage(session, data)) {
|
|
4689
4883
|
const sendStartedAt = this.timing ? performance.now() : 0;
|
|
4690
4884
|
try {
|
|
4691
|
-
await sendQQMarkdown(session, preview.markdown);
|
|
4885
|
+
await sendQQMarkdown(session, preview.markdown, preview.keyboard);
|
|
4692
4886
|
if (this.timing) {
|
|
4693
4887
|
this.timing.delivery = "qq-markdown";
|
|
4694
4888
|
this.timing.sendMs = performance.now() - sendStartedAt;
|
|
@@ -4733,6 +4927,23 @@ function titleCardFollowup(data) {
|
|
|
4733
4927
|
}
|
|
4734
4928
|
__name(titleCardFollowup, "titleCardFollowup");
|
|
4735
4929
|
|
|
4930
|
+
// src/plugin/serverHandel/imageMessageFollowup.ts
|
|
4931
|
+
function renderQQImageFollowup(data) {
|
|
4932
|
+
const title = titleCardFollowup(data);
|
|
4933
|
+
const actionLines = messageButtonFallbackLines(data);
|
|
4934
|
+
if (!title && !actionLines.length) return void 0;
|
|
4935
|
+
const text = appendMessageButtonFallbacks(title?.text ?? "", data).trimEnd();
|
|
4936
|
+
let keyboard;
|
|
4937
|
+
try {
|
|
4938
|
+
keyboard = renderQQKeyboard(data);
|
|
4939
|
+
} catch {
|
|
4940
|
+
return { text };
|
|
4941
|
+
}
|
|
4942
|
+
const markdown = titleCardFollowup(withoutMessageButtonFallbacks(data))?.markdown ?? " ";
|
|
4943
|
+
return { text, markdown, ...keyboard ? { keyboard } : {} };
|
|
4944
|
+
}
|
|
4945
|
+
__name(renderQQImageFollowup, "renderQQImageFollowup");
|
|
4946
|
+
|
|
4736
4947
|
// src/plugin/serverHandel/image.ts
|
|
4737
4948
|
var ImageHandler = class extends handel_base {
|
|
4738
4949
|
static {
|
|
@@ -4763,16 +4974,16 @@ var ImageHandler = class extends handel_base {
|
|
|
4763
4974
|
}
|
|
4764
4975
|
const sendStartedAt = this.timing ? performance.now() : 0;
|
|
4765
4976
|
await this.send(data, content, "image");
|
|
4766
|
-
const followup =
|
|
4977
|
+
const followup = renderQQImageFollowup(data);
|
|
4767
4978
|
if (!followup) return;
|
|
4768
4979
|
const session = sessions_default.get(sessionKey(data.botId, data.userId, data.channelId));
|
|
4769
4980
|
let sentMarkdown = false;
|
|
4770
|
-
if (canSendQQPage(session, data)) {
|
|
4981
|
+
if (followup.markdown !== void 0 && canSendQQPage(session, data)) {
|
|
4771
4982
|
try {
|
|
4772
|
-
await sendQQMarkdown(session, followup.markdown);
|
|
4983
|
+
await sendQQMarkdown(session, followup.markdown, followup.keyboard);
|
|
4773
4984
|
sentMarkdown = true;
|
|
4774
4985
|
} catch (error) {
|
|
4775
|
-
this.ctx.logger.warn("
|
|
4986
|
+
this.ctx.logger.warn("图片操作 Markdown 发送失败,改用普通文字", error instanceof Error ? error.message : error);
|
|
4776
4987
|
}
|
|
4777
4988
|
}
|
|
4778
4989
|
if (!sentMarkdown) await this.send({ ...data, notification: true }, followup.text);
|