koishi-plugin-dew-bot 1.0.254 → 1.0.255
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/assets/item-card/special-item-placeholder.png +0 -0
- package/assets/item-card/special-item-placeholder.prompt.txt +7 -0
- package/lib/index.js +21 -5
- package/lib/shared/face/index.d.ts +3 -1
- package/package.json +1 -1
- package/src/plugin/serverHandel/qqPageMessage.ts +15 -4
- package/src/shared/bot/serviceProto.ts +9 -1
- package/src/shared/face/index.ts +3 -1
|
Binary file
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Generation tool: built-in image_gen
|
|
2
|
+
|
|
3
|
+
Use case: stylized-concept.
|
|
4
|
+
Asset type: one square raster placeholder icon for a Chinese fantasy RPG inventory, shared by bloodline items, pet eggs and follower contracts until their own artwork is available.
|
|
5
|
+
Primary request: create exactly ONE neutral placeholder illustration, a single mysterious life seal: a simple rounded jade-gray magical core with an abstract curled life-flame motif, subtly enclosed by a soft ink halo. It should suggest unrevealed life and a sealed bond without depicting a specific bloodline, creature or character.
|
|
6
|
+
Style/medium: elegant Chinese ink and pale watercolor on warm off-white rice paper, matching refined fantasy game item artwork. Calm, restrained light; strong, simple silhouette. One centered subject, occupying about 65–70% of the square, large clear forms, clean low-contrast background and generous safe margins.
|
|
7
|
+
Constraints: opaque square background; remains legible at 24×24 pixels; one standalone icon, not an icon sheet or UI screenshot. No text, no letters, no numbers, no question mark, no watermark, no UI frame, no quality badge, no character, no weapon, no armor, no detailed scene, no tiny intricate decorations.
|
package/lib/index.js
CHANGED
|
@@ -980,6 +980,12 @@ function compactListLabel(value) {
|
|
|
980
980
|
return /[📖📚]/u.test(label) ? label.replace(/技能书(?=$|×\d+(?:\.\d+)?(?:||$)||)/g, "") : label;
|
|
981
981
|
}
|
|
982
982
|
__name(compactListLabel, "compactListLabel");
|
|
983
|
+
function renderEntryArtwork(address) {
|
|
984
|
+
if (!artworkIdentity(address)) return "";
|
|
985
|
+
const url = new URL(address).href.replace(/[()]/g, (character) => "%" + character.charCodeAt(0).toString(16).toUpperCase());
|
|
986
|
+
return ` `;
|
|
987
|
+
}
|
|
988
|
+
__name(renderEntryArtwork, "renderEntryArtwork");
|
|
983
989
|
function inlineCommandUrl(command) {
|
|
984
990
|
const encoded = encodeURIComponent(command).replace(/[!'()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
985
991
|
return `mqqapi://aio/inlinecmd?command=${encoded}&enter=true&reply=false`;
|
|
@@ -1106,6 +1112,7 @@ __name(renderInventoryFilters, "renderInventoryFilters");
|
|
|
1106
1112
|
function renderQQInventoryMarkdown(data, showGreeting) {
|
|
1107
1113
|
const nav = data.pageNav;
|
|
1108
1114
|
const entryCommands = new Map(nav.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
1115
|
+
const entryArtwork = new Map(nav.entries?.map((entry) => [entry.lineIndex, renderEntryArtwork(entry.artworkUrl)]) ?? []);
|
|
1109
1116
|
const sections = [];
|
|
1110
1117
|
const items = [];
|
|
1111
1118
|
const flushItems = /* @__PURE__ */ __name(() => {
|
|
@@ -1116,7 +1123,7 @@ function renderQQInventoryMarkdown(data, showGreeting) {
|
|
|
1116
1123
|
const command = entryCommands.get(lineIndex);
|
|
1117
1124
|
if (item.type === 1 /* line */ && command) {
|
|
1118
1125
|
const label = compactListLabel(item.content.replace(/^\[\d+\]\s*/, ""));
|
|
1119
|
-
items.push(`[${escapeMarkdown(label)}](${inlineCommandUrl(command)})`);
|
|
1126
|
+
items.push((entryArtwork.get(lineIndex) ?? "") + `[${escapeMarkdown(label)}](${inlineCommandUrl(command)})`);
|
|
1120
1127
|
continue;
|
|
1121
1128
|
}
|
|
1122
1129
|
flushItems();
|
|
@@ -1144,6 +1151,7 @@ function renderQQPageMarkdown(data, showGreeting) {
|
|
|
1144
1151
|
const nav = data.pageNav;
|
|
1145
1152
|
const entryCommands = new Map(nav?.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
1146
1153
|
const labeledEntries = new Map(nav?.entries?.filter((entry) => entry.label !== void 0).map((entry) => [entry.lineIndex, entry]) ?? []);
|
|
1154
|
+
const entryArtwork = new Map(nav?.entries?.map((entry) => [entry.lineIndex, renderEntryArtwork(entry.artworkUrl)]) ?? []);
|
|
1147
1155
|
const listPattern = /^\[(\d+)\]\s*([^\r\n]+)$/;
|
|
1148
1156
|
const pagePattern = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/;
|
|
1149
1157
|
const title = data.line.find((item) => item.type === 0 /* title */);
|
|
@@ -1183,7 +1191,7 @@ function renderQQPageMarkdown(data, showGreeting) {
|
|
|
1183
1191
|
if (labeledEntry) {
|
|
1184
1192
|
flushList();
|
|
1185
1193
|
flushRewards();
|
|
1186
|
-
bodyLines.push(`[${escapeMarkdown(labeledEntry.label)}](${inlineCommandUrl(labeledEntry.viewCommand)})` + (labeledEntry.description ? " " + escapeMarkdown(labeledEntry.description) : ""));
|
|
1194
|
+
bodyLines.push((entryArtwork.get(lineIndex) ?? "") + `[${escapeMarkdown(labeledEntry.label)}](${inlineCommandUrl(labeledEntry.viewCommand)})` + (labeledEntry.description ? " " + escapeMarkdown(labeledEntry.description) : ""));
|
|
1187
1195
|
break;
|
|
1188
1196
|
}
|
|
1189
1197
|
if (item.reward) {
|
|
@@ -1201,7 +1209,7 @@ function renderQQPageMarkdown(data, showGreeting) {
|
|
|
1201
1209
|
const content = compactListLabel(listEntry[2]);
|
|
1202
1210
|
const label = escapeMarkdown(content);
|
|
1203
1211
|
const name2 = command2 ? `[${label}](${inlineCommandUrl(command2)})` : renderInlineCommands(content);
|
|
1204
|
-
listLines.push(`${listEntry[1]}. ${name2}`);
|
|
1212
|
+
listLines.push(`${listEntry[1]}. ${entryArtwork.get(lineIndex) ?? ""}${name2}`);
|
|
1205
1213
|
break;
|
|
1206
1214
|
}
|
|
1207
1215
|
flushList();
|
|
@@ -1222,7 +1230,7 @@ function renderQQPageMarkdown(data, showGreeting) {
|
|
|
1222
1230
|
break;
|
|
1223
1231
|
}
|
|
1224
1232
|
const command = entryCommands.get(lineIndex);
|
|
1225
|
-
bodyLines.push(command ? `[${escapeMarkdown(compactListLabel(item.content))}](${inlineCommandUrl(command)})` : renderInlineCommands(item.content));
|
|
1233
|
+
bodyLines.push(command ? (entryArtwork.get(lineIndex) ?? "") + `[${escapeMarkdown(compactListLabel(item.content))}](${inlineCommandUrl(command)})` : renderInlineCommands(item.content));
|
|
1226
1234
|
break;
|
|
1227
1235
|
}
|
|
1228
1236
|
case 2 /* error */:
|
|
@@ -1632,7 +1640,7 @@ var import_tsrpc = require("tsrpc");
|
|
|
1632
1640
|
|
|
1633
1641
|
// src/shared/bot/serviceProto.ts
|
|
1634
1642
|
var serviceProto = {
|
|
1635
|
-
"version":
|
|
1643
|
+
"version": 22,
|
|
1636
1644
|
"services": [
|
|
1637
1645
|
{
|
|
1638
1646
|
"id": 0,
|
|
@@ -2534,6 +2542,14 @@ var serviceProto = {
|
|
|
2534
2542
|
"type": "String"
|
|
2535
2543
|
},
|
|
2536
2544
|
"optional": true
|
|
2545
|
+
},
|
|
2546
|
+
{
|
|
2547
|
+
"id": 4,
|
|
2548
|
+
"name": "artworkUrl",
|
|
2549
|
+
"type": {
|
|
2550
|
+
"type": "String"
|
|
2551
|
+
},
|
|
2552
|
+
"optional": true
|
|
2537
2553
|
}
|
|
2538
2554
|
]
|
|
2539
2555
|
}
|
|
@@ -134,9 +134,11 @@ export interface PageNavData {
|
|
|
134
134
|
entries?: Array<{
|
|
135
135
|
lineIndex: number;
|
|
136
136
|
viewCommand: string;
|
|
137
|
-
/**
|
|
137
|
+
/** 菜单入口名称;提供时仅此文字可点击,说明作为普通文本显示。 */
|
|
138
138
|
label?: string;
|
|
139
139
|
description?: string;
|
|
140
|
+
/** 列表名称前的小图;使用已保存插画的临时 HTTPS 链接。 */
|
|
141
|
+
artworkUrl?: string;
|
|
140
142
|
}>;
|
|
141
143
|
/** 按完整实时列表提供筛选入口;空数组表示没有可用类型。 */
|
|
142
144
|
filters?: Array<{
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import { MessageType, type IMessage, type PageNavData } from '../../shared/face'
|
|
|
3
3
|
import type { MsgMessage } from '../../shared/bot/MsgMessage'
|
|
4
4
|
import { compactDisplayText, escapeMarkdown, renderQQTitle } from './qqMarkdownHelpers'
|
|
5
5
|
import { isRewardMessage, renderRewardLine, renderRewardTitle } from './qqRewardMessage'
|
|
6
|
+
import { artworkIdentity } from '../skillArtwork'
|
|
6
7
|
|
|
7
8
|
export { escapeMarkdown, renderQQTitle } from './qqMarkdownHelpers'
|
|
8
9
|
|
|
@@ -35,6 +36,14 @@ function compactListLabel(value: string): string {
|
|
|
35
36
|
: label
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
/** QQ Markdown uses dimensions in the image label; keep the existing COS URL policy. */
|
|
40
|
+
function renderEntryArtwork(address?: string): string {
|
|
41
|
+
if (!artworkIdentity(address)) return ''
|
|
42
|
+
const url = new URL(address!).href.replace(/[()]/g, character =>
|
|
43
|
+
'%' + character.charCodeAt(0).toString(16).toUpperCase())
|
|
44
|
+
return ` `
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
export function inlineCommandUrl(command: string): string {
|
|
39
48
|
// encodeURIComponent leaves parentheses unescaped, which would close the
|
|
40
49
|
// surrounding Markdown link if an item ID ever contained one.
|
|
@@ -179,6 +188,7 @@ function renderInventoryFilters(nav: PageNavData): string {
|
|
|
179
188
|
function renderQQInventoryMarkdown(data: IMessage, showGreeting: boolean): string {
|
|
180
189
|
const nav = data.pageNav!
|
|
181
190
|
const entryCommands = new Map(nav.entries?.map(entry => [entry.lineIndex, entry.viewCommand]) ?? [])
|
|
191
|
+
const entryArtwork = new Map(nav.entries?.map(entry => [entry.lineIndex, renderEntryArtwork(entry.artworkUrl)]) ?? [])
|
|
182
192
|
const sections: string[] = []
|
|
183
193
|
const items: string[] = []
|
|
184
194
|
const flushItems = () => {
|
|
@@ -189,7 +199,7 @@ function renderQQInventoryMarkdown(data: IMessage, showGreeting: boolean): strin
|
|
|
189
199
|
const command = entryCommands.get(lineIndex)
|
|
190
200
|
if (item.type === MessageType.line && command) {
|
|
191
201
|
const label = compactListLabel(item.content.replace(/^\[\d+\]\s*/, ''))
|
|
192
|
-
items.push(`[${escapeMarkdown(label)}](${inlineCommandUrl(command)})`)
|
|
202
|
+
items.push((entryArtwork.get(lineIndex) ?? '') + `[${escapeMarkdown(label)}](${inlineCommandUrl(command)})`)
|
|
193
203
|
continue
|
|
194
204
|
}
|
|
195
205
|
flushItems()
|
|
@@ -225,6 +235,7 @@ export function renderQQPageMarkdown(data: IMessage, showGreeting: boolean): str
|
|
|
225
235
|
const entryCommands = new Map(nav?.entries?.map(entry => [entry.lineIndex, entry.viewCommand]) ?? [])
|
|
226
236
|
const labeledEntries = new Map(nav?.entries?.filter(entry => entry.label !== undefined)
|
|
227
237
|
.map(entry => [entry.lineIndex, entry]) ?? [])
|
|
238
|
+
const entryArtwork = new Map(nav?.entries?.map(entry => [entry.lineIndex, renderEntryArtwork(entry.artworkUrl)]) ?? [])
|
|
228
239
|
const listPattern = /^\[(\d+)\]\s*([^\r\n]+)$/
|
|
229
240
|
const pagePattern = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/
|
|
230
241
|
const title = data.line.find(item => item.type === MessageType.title)
|
|
@@ -261,7 +272,7 @@ export function renderQQPageMarkdown(data: IMessage, showGreeting: boolean): str
|
|
|
261
272
|
if (labeledEntry) {
|
|
262
273
|
flushList()
|
|
263
274
|
flushRewards()
|
|
264
|
-
bodyLines.push(`[${escapeMarkdown(labeledEntry.label!)}](${inlineCommandUrl(labeledEntry.viewCommand)})`
|
|
275
|
+
bodyLines.push((entryArtwork.get(lineIndex) ?? '') + `[${escapeMarkdown(labeledEntry.label!)}](${inlineCommandUrl(labeledEntry.viewCommand)})`
|
|
265
276
|
+ (labeledEntry.description ? ' ' + escapeMarkdown(labeledEntry.description) : ''))
|
|
266
277
|
break
|
|
267
278
|
}
|
|
@@ -283,7 +294,7 @@ export function renderQQPageMarkdown(data: IMessage, showGreeting: boolean): str
|
|
|
283
294
|
? `[${label}](${inlineCommandUrl(command)})`
|
|
284
295
|
: renderInlineCommands(content)
|
|
285
296
|
// Keep the numeric marker as Markdown syntax; escape only the item text.
|
|
286
|
-
listLines.push(`${listEntry[1]}. ${name}`)
|
|
297
|
+
listLines.push(`${listEntry[1]}. ${entryArtwork.get(lineIndex) ?? ''}${name}`)
|
|
287
298
|
break
|
|
288
299
|
}
|
|
289
300
|
flushList()
|
|
@@ -307,7 +318,7 @@ export function renderQQPageMarkdown(data: IMessage, showGreeting: boolean): str
|
|
|
307
318
|
}
|
|
308
319
|
const command = entryCommands.get(lineIndex)
|
|
309
320
|
bodyLines.push(command
|
|
310
|
-
? `[${escapeMarkdown(compactListLabel(item.content))}](${inlineCommandUrl(command)})`
|
|
321
|
+
? (entryArtwork.get(lineIndex) ?? '') + `[${escapeMarkdown(compactListLabel(item.content))}](${inlineCommandUrl(command)})`
|
|
311
322
|
: renderInlineCommands(item.content))
|
|
312
323
|
break
|
|
313
324
|
}
|
|
@@ -20,7 +20,7 @@ export interface ServiceType {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const serviceProto: ServiceProto<ServiceType> = {
|
|
23
|
-
"version":
|
|
23
|
+
"version": 22,
|
|
24
24
|
"services": [
|
|
25
25
|
{
|
|
26
26
|
"id": 0,
|
|
@@ -922,6 +922,14 @@ export const serviceProto: ServiceProto<ServiceType> = {
|
|
|
922
922
|
"type": "String"
|
|
923
923
|
},
|
|
924
924
|
"optional": true
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
"id": 4,
|
|
928
|
+
"name": "artworkUrl",
|
|
929
|
+
"type": {
|
|
930
|
+
"type": "String"
|
|
931
|
+
},
|
|
932
|
+
"optional": true
|
|
925
933
|
}
|
|
926
934
|
]
|
|
927
935
|
}
|
package/src/shared/face/index.ts
CHANGED
|
@@ -111,9 +111,11 @@ export interface PageNavData {
|
|
|
111
111
|
entries?: Array<{
|
|
112
112
|
lineIndex: number;
|
|
113
113
|
viewCommand: string;
|
|
114
|
-
/**
|
|
114
|
+
/** 菜单入口名称;提供时仅此文字可点击,说明作为普通文本显示。 */
|
|
115
115
|
label?: string;
|
|
116
116
|
description?: string;
|
|
117
|
+
/** 列表名称前的小图;使用已保存插画的临时 HTTPS 链接。 */
|
|
118
|
+
artworkUrl?: string;
|
|
117
119
|
}>;
|
|
118
120
|
/** 按完整实时列表提供筛选入口;空数组表示没有可用类型。 */
|
|
119
121
|
filters?: Array<{ name: string; emoji?: string; command: string }>;
|