koishi-plugin-best-cave 2.4.5 → 2.4.7

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.
Files changed (2) hide show
  1. package/lib/index.js +61 -29
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -297,10 +297,22 @@ async function buildCaveMessage(cave, config, fileManager, logger2, platform, pr
297
297
  const forwardNodes = Array.isArray(el.content) ? el.content : [];
298
298
  const messageNodes = await Promise.all(forwardNodes.map(async (node) => {
299
299
  const author = (0, import_koishi.h)("author", { id: node.userId, name: node.userName });
300
- const content = await transformToH(node.elements);
301
- return (0, import_koishi.h)("message", {}, [author, ...content]);
300
+ const contentElements = await transformToH(node.elements);
301
+ const unwrappedContent = [];
302
+ const nestedMessageNodes = [];
303
+ for (const contentEl of contentElements) {
304
+ if (contentEl.type === "message" && contentEl.attrs.forward) {
305
+ nestedMessageNodes.push(...contentEl.children);
306
+ } else {
307
+ unwrappedContent.push(contentEl);
308
+ }
309
+ }
310
+ const resultNodes = [];
311
+ if (unwrappedContent.length > 0) resultNodes.push((0, import_koishi.h)("message", {}, [author, ...unwrappedContent]));
312
+ resultNodes.push(...nestedMessageNodes);
313
+ return resultNodes;
302
314
  }));
303
- return (0, import_koishi.h)("message", { forward: true }, messageNodes);
315
+ return (0, import_koishi.h)("message", { forward: true }, messageNodes.flat());
304
316
  } catch (error) {
305
317
  logger2.warn(`解析回声洞(${cave.id})合并转发内容失败:`, error);
306
318
  return import_koishi.h.text("[合并转发]");
@@ -321,7 +333,7 @@ async function buildCaveMessage(cave, config, fileManager, logger2, platform, pr
321
333
  }
322
334
  }
323
335
  return null;
324
- })).then((hElements) => hElements.filter(Boolean));
336
+ })).then((hElements) => hElements.flat().filter(Boolean));
325
337
  }
326
338
  __name(transformToH, "transformToH");
327
339
  const caveHElements = await transformToH(cave.elements);
@@ -344,7 +356,8 @@ async function buildCaveMessage(cave, config, fileManager, logger2, platform, pr
344
356
  const followUpMessages = [];
345
357
  for (const el of caveHElements) {
346
358
  if (problematicTypes.includes(el.type) || el.type === "message" && el.attrs.forward) {
347
- initialMessageContent.push(import_koishi.h.text(placeholderMap["forward"]));
359
+ const placeholderKey = el.type === "message" && el.attrs.forward ? "forward" : el.type;
360
+ initialMessageContent.push(import_koishi.h.text(placeholderMap[placeholderKey]));
348
361
  followUpMessages.push([el]);
349
362
  } else {
350
363
  initialMessageContent.push(el);
@@ -402,10 +415,46 @@ __name(getNextCaveId, "getNextCaveId");
402
415
  async function processMessageElements(sourceElements, newId, session, config, logger2) {
403
416
  const mediaToSave = [];
404
417
  let mediaIndex = 0;
418
+ const typeMap = { "img": "image", "image": "image", "video": "video", "audio": "audio", "file": "file", "text": "text", "at": "at", "forward": "forward", "reply": "reply" };
419
+ const defaultExtMap = { "image": ".jpg", "video": ".mp4", "audio": ".mp3", "file": ".dat" };
405
420
  async function transform(elements) {
406
421
  const result = [];
407
- const typeMap = { "img": "image", "image": "image", "video": "video", "audio": "audio", "file": "file", "text": "text", "at": "at", "forward": "forward", "reply": "reply" };
408
- const defaultExtMap = { "image": ".jpg", "video": ".mp4", "audio": ".mp3", "file": ".dat" };
422
+ async function processForwardContent(segments) {
423
+ const innerResult = [];
424
+ for (const segment of segments) {
425
+ const sType = typeMap[segment.type];
426
+ if (!sType) continue;
427
+ if (sType === "text" && segment.data?.text?.trim()) {
428
+ innerResult.push({ type: "text", content: segment.data.text.trim() });
429
+ } else if (sType === "at" && (segment.data?.id || segment.data?.qq)) {
430
+ innerResult.push({ type: "at", content: segment.data.id || segment.data.qq });
431
+ } else if (sType === "reply" && segment.data?.id) {
432
+ innerResult.push({ type: "reply", content: segment.data.id });
433
+ } else if (["image", "video", "audio", "file"].includes(sType) && (segment.data?.src || segment.data?.url)) {
434
+ let fileIdentifier = segment.data.src || segment.data.url;
435
+ if (fileIdentifier.startsWith("http")) {
436
+ const ext = path2.extname(segment.data.file || "") || defaultExtMap[sType];
437
+ const currentMediaIndex = ++mediaIndex;
438
+ const fileName = `${newId}_${currentMediaIndex}_${session.channelId || session.guildId}_${session.userId}${ext}`;
439
+ mediaToSave.push({ sourceUrl: fileIdentifier, fileName });
440
+ fileIdentifier = fileName;
441
+ }
442
+ innerResult.push({ type: sType, file: fileIdentifier });
443
+ } else if (sType === "forward" && Array.isArray(segment.data?.content)) {
444
+ const nestedForwardNodes = [];
445
+ for (const nestedNode of segment.data.content) {
446
+ if (!nestedNode.message || !Array.isArray(nestedNode.message)) continue;
447
+ const nestedContentElements = await processForwardContent(nestedNode.message);
448
+ if (nestedContentElements.length > 0) {
449
+ nestedForwardNodes.push({ userId: nestedNode.sender?.user_id, userName: nestedNode.sender?.nickname, elements: nestedContentElements });
450
+ }
451
+ }
452
+ if (nestedForwardNodes.length > 0) innerResult.push({ type: "forward", content: nestedForwardNodes });
453
+ }
454
+ }
455
+ return innerResult;
456
+ }
457
+ __name(processForwardContent, "processForwardContent");
409
458
  for (const el of elements) {
410
459
  const type = typeMap[el.type];
411
460
  if (!type) {
@@ -422,27 +471,10 @@ async function processMessageElements(sourceElements, newId, session, config, lo
422
471
  const forwardNodes = [];
423
472
  for (const node of el.attrs.content) {
424
473
  if (!node.message || !Array.isArray(node.message)) continue;
425
- const userId = node.sender?.user_id;
426
- const userName = node.sender?.nickname;
427
- const elementsToProcess = node.message.map((segment) => {
428
- const { type: type2, data } = segment;
429
- const attrs = { ...data };
430
- if (type2 === "text" && typeof data.text !== "undefined") {
431
- attrs.content = data.text;
432
- delete attrs.text;
433
- }
434
- if (type2 === "at" && typeof data.qq !== "undefined") {
435
- attrs.id = data.qq;
436
- delete attrs.qq;
437
- }
438
- if (["image", "video", "audio"].includes(type2) && typeof data.url !== "undefined") {
439
- attrs.src = data.url;
440
- delete attrs.url;
441
- }
442
- return (0, import_koishi.h)(type2, attrs);
443
- });
444
- const contentElements = await transform(elementsToProcess);
445
- if (contentElements.length > 0) forwardNodes.push({ userId, userName, elements: contentElements });
474
+ const contentElements = await processForwardContent(node.message);
475
+ if (contentElements.length > 0) {
476
+ forwardNodes.push({ userId: node.sender?.user_id, userName: node.sender?.nickname, elements: contentElements });
477
+ }
446
478
  }
447
479
  if (forwardNodes.length > 0) result.push({ type: "forward", content: forwardNodes });
448
480
  } else if (["image", "video", "audio", "file"].includes(type) && el.attrs.src) {
@@ -1088,7 +1120,7 @@ function apply(ctx, config) {
1088
1120
  if (hashManager && textHashesToStore.length > 0) await ctx.database.upsert("cave_hash", textHashesToStore.map((h4) => ({ ...h4, cave: newCave.id })));
1089
1121
  if (initialStatus === "pending") reviewManager.sendForPend(newCave);
1090
1122
  }
1091
- return initialStatus === "pending" || initialStatus === "preload" && config.enablePend ? `提交成功,序号为(${newCave.id})` : `添加成功,序号为(${newCave.id})`;
1123
+ return needsReview ? `提交成功,序号为(${newCave.id})` : `添加成功,序号为(${newCave.id})`;
1092
1124
  } catch (error) {
1093
1125
  logger.error("添加回声洞失败:", error);
1094
1126
  return "添加失败,请稍后再试";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-best-cave",
3
3
  "description": "功能强大、高度可定制的回声洞。支持丰富的媒体类型、内容查重、人工审核、用户昵称、数据迁移以及本地/S3 双重文件存储后端。",
4
- "version": "2.4.5",
4
+ "version": "2.4.7",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],