koishi-plugin-best-cave 2.2.1 → 2.2.2

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.
@@ -24,10 +24,15 @@ export declare class HashManager {
24
24
  */
25
25
  registerCommands(cave: any): void;
26
26
  /**
27
- * @description 检查数据库中所有回声洞,为没有哈希记录的历史数据生成哈希,并在此之后对所有内容进行相似度检查。
27
+ * @description 检查数据库中所有回声洞,为没有哈希记录的历史数据生成哈希。
28
28
  * @returns {Promise<string>} 一个包含操作结果的报告字符串。
29
29
  */
30
- validateAllCaves(): Promise<string>;
30
+ generateHashesForHistoricalCaves(): Promise<string>;
31
+ /**
32
+ * @description 对所有已存在哈希的回声洞进行相似度检查。
33
+ * @returns {Promise<string>} 一个包含操作结果的报告字符串。
34
+ */
35
+ checkForSimilarCaves(): Promise<string>;
31
36
  /**
32
37
  * @description 将图片切割为4个象限并为每个象限生成pHash。
33
38
  * @param imageBuffer - 图片的 Buffer 数据。
package/lib/index.js CHANGED
@@ -597,25 +597,40 @@ var HashManager = class {
597
597
  * @param cave - 主 `cave` 命令实例。
598
598
  */
599
599
  registerCommands(cave) {
600
- cave.subcommand(".hash", "校验回声洞").usage("校验所有回声洞,为历史数据生成哈希,并检查现有内容的相似度。").action(async ({ session }) => {
600
+ const adminCheck = /* @__PURE__ */ __name(({ session }) => {
601
601
  const adminChannelId = this.config.adminChannel?.split(":")[1];
602
602
  if (session.channelId !== adminChannelId) {
603
603
  return "此指令仅限在管理群组中使用";
604
604
  }
605
- await session.send("正在处理,请稍候...");
605
+ }, "adminCheck");
606
+ cave.subcommand(".hash", "校验回声洞").usage("校验所有回声洞,补全所有哈希记录。").action(async (argv) => {
607
+ const checkResult = adminCheck(argv);
608
+ if (checkResult) return checkResult;
609
+ await argv.session.send("正在处理,请稍候...");
606
610
  try {
607
- return await this.validateAllCaves();
611
+ return await this.generateHashesForHistoricalCaves();
608
612
  } catch (error) {
609
- this.logger.error("校验哈希失败:", error);
610
- return `校验失败: ${error.message}`;
613
+ this.logger.error("生成历史哈希失败:", error);
614
+ return `操作失败: ${error.message}`;
615
+ }
616
+ });
617
+ cave.subcommand(".check", "检查回声洞").usage("检查所有已存在哈希的回声洞的相似度。").action(async (argv) => {
618
+ const checkResult = adminCheck(argv);
619
+ if (checkResult) return checkResult;
620
+ await argv.session.send("正在检查,请稍候...");
621
+ try {
622
+ return await this.checkForSimilarCaves();
623
+ } catch (error) {
624
+ this.logger.error("检查相似度失败:", error);
625
+ return `检查失败: ${error.message}`;
611
626
  }
612
627
  });
613
628
  }
614
629
  /**
615
- * @description 检查数据库中所有回声洞,为没有哈希记录的历史数据生成哈希,并在此之后对所有内容进行相似度检查。
630
+ * @description 检查数据库中所有回声洞,为没有哈希记录的历史数据生成哈希。
616
631
  * @returns {Promise<string>} 一个包含操作结果的报告字符串。
617
632
  */
618
- async validateAllCaves() {
633
+ async generateHashesForHistoricalCaves() {
619
634
  const allCaves = await this.ctx.database.get("cave", { status: "active" });
620
635
  const existingHashedCaveIds = new Set((await this.ctx.database.get("cave_hash", {}, { fields: ["cave"] })).map((h4) => h4.cave));
621
636
  let hashesToInsert = [];
@@ -664,8 +679,13 @@ var HashManager = class {
664
679
  if (hashesToInsert.length >= 100) await flushHashes();
665
680
  }
666
681
  await flushHashes();
667
- const generationReport = totalHashesGenerated > 0 ? `已补全 ${historicalCount} 个回声洞的 ${totalHashesGenerated} 条哈希
668
- ` : "无需补全回声洞的哈希\n";
682
+ return totalHashesGenerated > 0 ? `已补全 ${historicalCount} 个回声洞的 ${totalHashesGenerated} 条哈希` : "无需补全回声洞哈希";
683
+ }
684
+ /**
685
+ * @description 对所有已存在哈希的回声洞进行相似度检查。
686
+ * @returns {Promise<string>} 一个包含操作结果的报告字符串。
687
+ */
688
+ async checkForSimilarCaves() {
669
689
  const allHashes = await this.ctx.database.get("cave_hash", {});
670
690
  const caveTextHashes = /* @__PURE__ */ new Map();
671
691
  const caveImagePHashes = /* @__PURE__ */ new Map();
@@ -677,7 +697,7 @@ var HashManager = class {
677
697
  caveImagePHashes.get(hash.cave).push(hash.hash);
678
698
  }
679
699
  }
680
- const caveIds = allCaves.map((c) => c.id);
700
+ const caveIds = Array.from(/* @__PURE__ */ new Set([...caveTextHashes.keys(), ...caveImagePHashes.keys()]));
681
701
  const similarPairs = /* @__PURE__ */ new Set();
682
702
  for (let i = 0; i < caveIds.length; i++) {
683
703
  for (let j = i + 1; j < caveIds.length; j++) {
@@ -688,7 +708,7 @@ var HashManager = class {
688
708
  if (textHash1 && textHash2) {
689
709
  const textSim = this.calculateSimilarity(textHash1, textHash2);
690
710
  if (textSim >= this.config.textThreshold) {
691
- similarPairs.add(`文本:(${id1},${id2}),相似度:${(textSim * 100).toFixed(2)}%`);
711
+ similarPairs.add(`文本${id1}&${id2}=${(textSim * 100).toFixed(2)}%`);
692
712
  }
693
713
  }
694
714
  const imageHashes1 = caveImagePHashes.get(id1) || [];
@@ -698,17 +718,15 @@ var HashManager = class {
698
718
  for (const imgHash2 of imageHashes2) {
699
719
  const imgSim = this.calculateSimilarity(imgHash1, imgHash2);
700
720
  if (imgSim >= this.config.imageThreshold) {
701
- similarPairs.add(`图片:(${id1},${id2}),相似度:${(imgSim * 100).toFixed(2)}%`);
721
+ similarPairs.add(`图片${id1}&${id2}=${(imgSim * 100).toFixed(2)}%`);
702
722
  }
703
723
  }
704
724
  }
705
725
  }
706
726
  }
707
727
  }
708
- const similarityReport = similarPairs.size > 0 ? `发现 ${similarPairs.size} 对高相似度内容:
728
+ return similarPairs.size > 0 ? `已发现 ${similarPairs.size} 对高相似度内容:
709
729
  ` + [...similarPairs].join("\n") : "未发现高相似度内容";
710
- return `校验完成:
711
- ${generationReport}${similarityReport}`;
712
730
  }
713
731
  /**
714
732
  * @description 将图片切割为4个象限并为每个象限生成pHash。
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-best-cave",
3
3
  "description": "功能强大、高度可定制的回声洞。支持丰富的媒体类型、内容查重、人工审核、用户昵称、数据迁移以及本地/S3 双重文件存储后端。",
4
- "version": "2.2.1",
4
+ "version": "2.2.2",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],