koishi-plugin-best-cave 2.3.7 → 2.3.9
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/Utils.d.ts +3 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +43 -44
- package/package.json +1 -1
package/lib/Utils.d.ts
CHANGED
|
@@ -50,9 +50,11 @@ export declare function updateCooldownTimestamp(session: Session, config: Config
|
|
|
50
50
|
* @param sourceElements 原始的 Koishi 消息元素数组。
|
|
51
51
|
* @param newId 这条回声洞的新 ID。
|
|
52
52
|
* @param session 触发操作的会话。
|
|
53
|
+
* @param config 插件配置。
|
|
54
|
+
* @param logger 日志实例。
|
|
53
55
|
* @returns 包含数据库元素和待保存媒体列表的对象。
|
|
54
56
|
*/
|
|
55
|
-
export declare function processMessageElements(sourceElements: h[], newId: number, session: Session): Promise<{
|
|
57
|
+
export declare function processMessageElements(sourceElements: h[], newId: number, session: Session, config: Config, logger: Logger): Promise<{
|
|
56
58
|
finalElementsForDb: StoredElement[];
|
|
57
59
|
mediaToSave: {
|
|
58
60
|
sourceUrl: string;
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -406,57 +406,46 @@ function updateCooldownTimestamp(session, config, lastUsed) {
|
|
|
406
406
|
}
|
|
407
407
|
}
|
|
408
408
|
__name(updateCooldownTimestamp, "updateCooldownTimestamp");
|
|
409
|
-
async function processMessageElements(sourceElements, newId, session) {
|
|
409
|
+
async function processMessageElements(sourceElements, newId, session, config, logger2) {
|
|
410
410
|
const mediaToSave = [];
|
|
411
411
|
let mediaIndex = 0;
|
|
412
|
-
async function transform(elements
|
|
412
|
+
async function transform(elements) {
|
|
413
413
|
const result = [];
|
|
414
414
|
const typeMap = { "img": "image", "image": "image", "video": "video", "audio": "audio", "file": "file", "text": "text", "at": "at", "forward": "forward" };
|
|
415
415
|
const defaultExtMap = { "image": ".jpg", "video": ".mp4", "audio": ".mp3", "file": ".dat" };
|
|
416
416
|
for (const el of elements) {
|
|
417
417
|
const type = typeMap[el.type];
|
|
418
|
+
if (config.debug) logger2.info(`正在处理元素 <${el.type}>, 映射类型: ${type || "无"}`);
|
|
418
419
|
if (!type) {
|
|
419
|
-
if (el.children) result.push(...await transform(el.children
|
|
420
|
+
if (el.children) result.push(...await transform(el.children));
|
|
420
421
|
continue;
|
|
421
422
|
}
|
|
422
423
|
if (type === "text" && el.attrs.content?.trim()) {
|
|
423
|
-
|
|
424
|
+
const content = el.attrs.content.trim();
|
|
425
|
+
if (config.debug) logger2.info(`发现 [text] 元素,内容: "${content}"`);
|
|
426
|
+
result.push({ type: "text", content });
|
|
424
427
|
} else if (type === "at" && el.attrs.id) {
|
|
428
|
+
if (config.debug) logger2.info(`发现 [at] 元素,ID: "${el.attrs.id}"`);
|
|
425
429
|
result.push({ type: "at", content: el.attrs.id });
|
|
426
|
-
} else if (type === "forward") {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
if (!node) continue;
|
|
431
|
-
const contentToNormalize = node.message;
|
|
432
|
-
if (contentToNormalize) {
|
|
433
|
-
try {
|
|
434
|
-
childrenToProcess.push(...import_koishi.h.normalize(contentToNormalize));
|
|
435
|
-
} catch (error) {
|
|
436
|
-
logger2.warn(`跳过无法解析的转发节点内容: ${error}`);
|
|
437
|
-
childrenToProcess.push(import_koishi.h.text("[内容解析失败]"));
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
if (childrenToProcess.length > 0) {
|
|
443
|
-
const transformedChildren = await transform(childrenToProcess, logger2);
|
|
444
|
-
if (transformedChildren.length > 0) {
|
|
445
|
-
result.push({ type: "forward", content: JSON.stringify(transformedChildren) });
|
|
446
|
-
}
|
|
447
|
-
}
|
|
430
|
+
} else if (type === "forward" && el.children?.length) {
|
|
431
|
+
if (config.debug) logger2.info(`发现 [forward] 元素,开始递归解析子元素...`);
|
|
432
|
+
const transformedChildren = await transform(el.children);
|
|
433
|
+
result.push({ type: "forward", content: JSON.stringify(transformedChildren) });
|
|
448
434
|
} else if (["image", "video", "audio", "file"].includes(type) && el.attrs.src) {
|
|
449
435
|
let fileIdentifier = el.attrs.src;
|
|
436
|
+
if (config.debug) logger2.info(`发现 [${type}] 元素,src: "${fileIdentifier}"`);
|
|
450
437
|
if (fileIdentifier.startsWith("http")) {
|
|
451
438
|
const ext = path2.extname(el.attrs.file || "") || defaultExtMap[type];
|
|
452
439
|
const currentMediaIndex = ++mediaIndex;
|
|
453
440
|
const fileName = `${newId}_${currentMediaIndex}_${session.channelId || "private"}_${session.userId}${ext}`;
|
|
441
|
+
if (config.debug) logger2.info(`[${type}] 是远程文件,文件名: "${fileName}"`);
|
|
454
442
|
mediaToSave.push({ sourceUrl: fileIdentifier, fileName });
|
|
455
443
|
fileIdentifier = fileName;
|
|
456
444
|
}
|
|
457
445
|
result.push({ type, file: fileIdentifier });
|
|
458
446
|
} else if (el.children) {
|
|
459
|
-
|
|
447
|
+
if (config.debug) logger2.info(`元素 <${el.type}> 无直接内容,递归其子元素...`);
|
|
448
|
+
result.push(...await transform(el.children));
|
|
460
449
|
}
|
|
461
450
|
}
|
|
462
451
|
return result;
|
|
@@ -472,7 +461,6 @@ async function handleFileUploads(ctx, config, fileManager, logger2, reviewManage
|
|
|
472
461
|
const imageHashesToStore = [];
|
|
473
462
|
const allExistingImageHashes = hashManager ? await ctx.database.get("cave_hash", { type: { $ne: "simhash" } }) : [];
|
|
474
463
|
const existingGlobalHashes = allExistingImageHashes.filter((h4) => h4.type === "phash_g");
|
|
475
|
-
const existingQuadrantHashes = allExistingImageHashes.filter((h4) => h4.type.startsWith("phash_q"));
|
|
476
464
|
for (const media of mediaToToSave) {
|
|
477
465
|
const buffer = Buffer.from(await ctx.http.get(media.sourceUrl, { responseType: "arraybuffer", timeout: 3e4 }));
|
|
478
466
|
downloadedMedia.push({ fileName: media.fileName, buffer });
|
|
@@ -487,16 +475,6 @@ async function handleFileUploads(ctx, config, fileManager, logger2, reviewManage
|
|
|
487
475
|
return;
|
|
488
476
|
}
|
|
489
477
|
}
|
|
490
|
-
const notifiedPartialCaves = /* @__PURE__ */ new Set();
|
|
491
|
-
for (const newSubHash of Object.values(quadrantHashes)) {
|
|
492
|
-
for (const existing of existingQuadrantHashes) {
|
|
493
|
-
if (notifiedPartialCaves.has(existing.cave)) continue;
|
|
494
|
-
if (newSubHash === existing.hash) {
|
|
495
|
-
await session.send(`图片与回声洞(${existing.cave})局部相同`);
|
|
496
|
-
notifiedPartialCaves.add(existing.cave);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
478
|
imageHashesToStore.push({ hash: globalHash, type: "phash_g" });
|
|
501
479
|
imageHashesToStore.push({ hash: quadrantHashes.q1, type: "phash_q1" });
|
|
502
480
|
imageHashesToStore.push({ hash: quadrantHashes.q2, type: "phash_q2" });
|
|
@@ -1027,7 +1005,10 @@ var Config = import_koishi3.Schema.intersect([
|
|
|
1027
1005
|
region: import_koishi3.Schema.string().default("auto").description("区域 (Region)"),
|
|
1028
1006
|
accessKeyId: import_koishi3.Schema.string().description("Access Key ID").role("secret"),
|
|
1029
1007
|
secretAccessKey: import_koishi3.Schema.string().description("Secret Access Key").role("secret")
|
|
1030
|
-
}).description("存储配置")
|
|
1008
|
+
}).description("存储配置"),
|
|
1009
|
+
import_koishi3.Schema.object({
|
|
1010
|
+
debug: import_koishi3.Schema.boolean().default(false).description("启用调试模式,将在控制台输出详细的操作日志。")
|
|
1011
|
+
}).description("开发配置")
|
|
1031
1012
|
]);
|
|
1032
1013
|
function apply(ctx, config) {
|
|
1033
1014
|
ctx.model.extend("cave", {
|
|
@@ -1070,18 +1051,36 @@ function apply(ctx, config) {
|
|
|
1070
1051
|
});
|
|
1071
1052
|
cave.subcommand(".add [content:text]", "添加回声洞").usage("添加一条回声洞。可直接发送内容,也可回复或引用消息。").action(async ({ session }, content) => {
|
|
1072
1053
|
try {
|
|
1073
|
-
let sourceElements
|
|
1074
|
-
|
|
1054
|
+
let sourceElements;
|
|
1055
|
+
let sourceOrigin = "";
|
|
1056
|
+
if (session.quote?.elements) {
|
|
1057
|
+
sourceElements = session.quote.elements;
|
|
1058
|
+
sourceOrigin = "引用(quote)";
|
|
1059
|
+
} else if (content?.trim()) {
|
|
1075
1060
|
sourceElements = import_koishi3.h.parse(content);
|
|
1076
|
-
|
|
1077
|
-
|
|
1061
|
+
sourceOrigin = `指令参数(content)`;
|
|
1062
|
+
} else {
|
|
1078
1063
|
await session.send("请在一分钟内发送你要添加的内容");
|
|
1079
1064
|
const reply = await session.prompt(6e4);
|
|
1080
1065
|
if (!reply) return "等待操作超时";
|
|
1081
1066
|
sourceElements = import_koishi3.h.parse(reply);
|
|
1067
|
+
sourceOrigin = `用户回复(prompt)`;
|
|
1068
|
+
}
|
|
1069
|
+
if (config.debug) {
|
|
1070
|
+
logger.info(`内容来源: ${sourceOrigin}`);
|
|
1071
|
+
logger.info(`获取到的消息内容 (sourceElements):
|
|
1072
|
+
${JSON.stringify(sourceElements, null, 2)}`);
|
|
1073
|
+
logger.info(`完整的会话对象 (session):
|
|
1074
|
+
${JSON.stringify(session, null, 2)}`);
|
|
1082
1075
|
}
|
|
1083
1076
|
const newId = await getNextCaveId(ctx, getScopeQuery(session, config, false), reusableIds);
|
|
1084
|
-
const { finalElementsForDb, mediaToSave } = await processMessageElements(sourceElements, newId, session);
|
|
1077
|
+
const { finalElementsForDb, mediaToSave } = await processMessageElements(sourceElements, newId, session, config, logger);
|
|
1078
|
+
if (config.debug) {
|
|
1079
|
+
logger.info(`提取后数据库元素(finalElementsForDb):
|
|
1080
|
+
${JSON.stringify(finalElementsForDb, null, 2)}`);
|
|
1081
|
+
logger.info(`提取后待存媒体(mediaToSave):
|
|
1082
|
+
${JSON.stringify(mediaToSave, null, 2)}`);
|
|
1083
|
+
}
|
|
1085
1084
|
if (finalElementsForDb.length === 0) return "无可添加内容";
|
|
1086
1085
|
const textHashesToStore = [];
|
|
1087
1086
|
if (hashManager) {
|