koishi-plugin-best-cave 2.5.2 → 2.5.3

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 CHANGED
@@ -324,9 +324,9 @@ async function buildCaveMessage(cave, config, fileManager, logger2, platform, pr
324
324
  if (config.enableS3 && config.publicUrl) return (0, import_koishi.h)(el.type, { ...el, src: new URL(fileName, config.publicUrl).href });
325
325
  if (config.localPath) return (0, import_koishi.h)(el.type, { ...el, src: `file://${path2.join(config.localPath, fileName)}` });
326
326
  try {
327
- const data = await fileManager.readFile(fileName);
327
+ const data2 = await fileManager.readFile(fileName);
328
328
  const mimeType = mimeTypeMap[path2.extname(fileName).toLowerCase()] || "application/octet-stream";
329
- return (0, import_koishi.h)(el.type, { ...el, src: `data:${mimeType};base64,${data.toString("base64")}` });
329
+ return (0, import_koishi.h)(el.type, { ...el, src: `data:${mimeType};base64,${data2.toString("base64")}` });
330
330
  } catch (error) {
331
331
  logger2.warn(`转换文件 ${fileName} 为 Base64 失败:`, error);
332
332
  return (0, import_koishi.h)("p", {}, `[${el.type}]`);
@@ -337,11 +337,37 @@ async function buildCaveMessage(cave, config, fileManager, logger2, platform, pr
337
337
  }
338
338
  __name(transformToH, "transformToH");
339
339
  const caveHElements = await transformToH(cave.elements);
340
- const replacements = { id: cave.id.toString(), name: cave.userName };
340
+ const data = {
341
+ id: cave.id.toString(),
342
+ name: cave.userName,
343
+ user: cave.userId,
344
+ channel: cave.channelId,
345
+ time: cave.time.toLocaleString()
346
+ };
347
+ const placeholderRegex = /\{([^}]+)\}/g;
348
+ const replacer = /* @__PURE__ */ __name((match, content) => {
349
+ const parts = content.split(":");
350
+ if (parts.length === 1) return data[content] ?? match;
351
+ if (parts.length === 4) {
352
+ const [maxStarsStr, key, prefixStr, suffixStr] = parts;
353
+ const originalValue = data[key];
354
+ if (!originalValue) return "";
355
+ const maxStars = parseInt(maxStarsStr, 10);
356
+ const prefixLength = parseInt(prefixStr, 10);
357
+ const suffixLength = parseInt(suffixStr, 10);
358
+ if (isNaN(maxStars) || isNaN(prefixLength) || isNaN(suffixLength)) return match;
359
+ if (prefixLength + suffixLength >= originalValue.length) return originalValue;
360
+ const prefix2 = originalValue.substring(0, prefixLength);
361
+ const suffix = originalValue.substring(originalValue.length - suffixLength);
362
+ const maskedLength = Math.min(maxStars, originalValue.length - prefixLength - suffixLength);
363
+ return `${prefix2}${"*".repeat(maskedLength)}${suffix}`;
364
+ }
365
+ return match;
366
+ }, "replacer");
341
367
  const [rawHeader, rawFooter] = config.caveFormat.split("|", 2);
342
- let header = rawHeader ? rawHeader.replace(/\{id\}|\{name\}/g, (match) => replacements[match.slice(1, -1)]).trim() : "";
368
+ let header = rawHeader ? rawHeader.replace(placeholderRegex, replacer).trim() : "";
343
369
  if (prefix) header = `${prefix}${header}`;
344
- const footer = rawFooter ? rawFooter.replace(/\{id\}|\{name\}/g, (match) => replacements[match.slice(1, -1)]).trim() : "";
370
+ const footer = rawFooter ? rawFooter.replace(placeholderRegex, replacer).trim() : "";
345
371
  const problematicTypes = ["video", "audio", "file", "forward"];
346
372
  const placeholderMap = { video: "[视频]", audio: "[音频]", file: "[文件]", forward: "[合并转发]" };
347
373
  const containsProblematic = platform === "onebot" && caveHElements.some((el) => problematicTypes.includes(el.type) || el.type === "message" && el.attrs.forward);
@@ -1006,7 +1032,7 @@ var Config = import_koishi3.Schema.intersect([
1006
1032
  enableName: import_koishi3.Schema.boolean().default(false).description("启用自定义昵称"),
1007
1033
  enableIO: import_koishi3.Schema.boolean().default(false).description("启用导入导出"),
1008
1034
  adminChannel: import_koishi3.Schema.string().default("onebot:").description("管理群组 ID"),
1009
- caveFormat: import_koishi3.Schema.string().default("回声洞 ——({id})|—— {name}").description("自定义文本")
1035
+ caveFormat: import_koishi3.Schema.string().default("回声洞 ——({id})|—— {name}").description("自定义文本,用“|”分隔。支持{id}|{name}|{time}|{user}|{channel}占位符,可使用{星号数:占位符:前缀:后缀}打码")
1010
1036
  }).description("基础配置"),
1011
1037
  import_koishi3.Schema.object({
1012
1038
  enablePend: import_koishi3.Schema.boolean().default(false).description("启用审核"),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-best-cave",
3
3
  "description": "功能强大、高度可定制的回声洞。支持丰富的媒体类型、内容查重、人工审核、用户昵称、数据迁移以及本地/S3 双重文件存储后端。",
4
- "version": "2.5.2",
4
+ "version": "2.5.3",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],
package/readme.md CHANGED
@@ -62,7 +62,7 @@
62
62
  | `enableName` | `boolean` | `false` | 是否启用自定义昵称功能 (`cave.name` 指令)。 |
63
63
  | `enableIO` | `boolean` | `false` | 是否启用数据导入/导出功能 (`cave.export` / `.import` 指令)。 |
64
64
  | `adminChannel` | `string` | `'onebot:'` | **管理群组ID**。格式为 `平台名:群号`,如 `onebot:12345678`。管理指令仅在此群组生效。若配置无效,审核将自动通过。 |
65
- | `caveFormat` | `string` | `'回声洞 ——({id})\|—— {name}'` | 回声洞消息的显示格式。`{id}`是序号,`{name}`是昵称。`\|` 作为换行符,其前面的部分为页眉,后面的为页脚。 |
65
+ | `caveFormat` | `string` | `'回声洞 ——({id})\|—— {name}'` | 回声洞消息的显示格式。`\|`作为分隔符,前面是页眉,后面是页脚。可用占位符:`{id}`, `{name}`, `{time}`, `{user}` 和 `{channel}` 。支持打码,语法为 `{最大星号数:占位符:保留前缀:保留后缀}`,例如 `{3:user:2:2}`。 |
66
66
 
67
67
  ### 复核配置 (审核与查重)
68
68