koishi-plugin-best-cave 2.2.4 → 2.2.6

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.
@@ -63,7 +63,13 @@ export declare class HashManager {
63
63
  * @returns {Promise<string>} 一个包含操作结果的报告字符串。
64
64
  */
65
65
  checkForSimilarCaves(): Promise<string>;
66
- private _generateSingleChannelPHash;
66
+ /**
67
+ * @description 从单通道原始像素数据计算pHash。
68
+ * @param channelData - 单通道的像素值数组。
69
+ * @param size - 图像的边长(例如16)。
70
+ * @returns {string} 该通道的二进制哈希字符串。
71
+ */
72
+ private _calculateHashFromRawChannel;
67
73
  /**
68
74
  * @description 生成768位颜色感知哈希(Color pHash)。
69
75
  * @param imageBuffer - 图片的 Buffer 数据。
package/lib/index.js CHANGED
@@ -697,7 +697,9 @@ var HashManager = class {
697
697
  const combinedText = cave.elements.filter((el) => el.type === "text" && el.content).map((el) => el.content).join(" ");
698
698
  if (combinedText) {
699
699
  const textHash = this.generateTextSimhash(combinedText);
700
- allHashes.push({ cave: cave.id, hash: textHash, type: "simhash" });
700
+ if (textHash) {
701
+ allHashes.push({ cave: cave.id, hash: textHash, type: "simhash" });
702
+ }
701
703
  }
702
704
  for (const el of cave.elements.filter((el2) => el2.type === "image" && el2.file)) {
703
705
  try {
@@ -806,11 +808,16 @@ var HashManager = class {
806
808
  if (subHashDuplicates.length > 0) report += "\n图片局部重复:\n" + [...new Set(subHashDuplicates)].join("\n");
807
809
  return report.trim();
808
810
  }
809
- async _generateSingleChannelPHash(channelBuffer, size) {
810
- const pixelData = await (0, import_sharp.default)(channelBuffer).resize(size, size, { fit: "fill" }).raw().toBuffer();
811
- const totalLuminance = pixelData.reduce((acc, val) => acc + val, 0);
811
+ /**
812
+ * @description 从单通道原始像素数据计算pHash。
813
+ * @param channelData - 单通道的像素值数组。
814
+ * @param size - 图像的边长(例如16)。
815
+ * @returns {string} 该通道的二进制哈希字符串。
816
+ */
817
+ _calculateHashFromRawChannel(channelData, size) {
818
+ const totalLuminance = channelData.reduce((acc, val) => acc + val, 0);
812
819
  const avgLuminance = totalLuminance / (size * size);
813
- return Array.from(pixelData).map((lum) => lum > avgLuminance ? "1" : "0").join("");
820
+ return channelData.map((lum) => lum > avgLuminance ? "1" : "0").join("");
814
821
  }
815
822
  /**
816
823
  * @description 生成768位颜色感知哈希(Color pHash)。
@@ -826,11 +833,9 @@ var HashManager = class {
826
833
  g.push(data[i + 1]);
827
834
  b.push(data[i + 2]);
828
835
  }
829
- const [rHash, gHash, bHash] = await Promise.all([
830
- this._generateSingleChannelPHash(Buffer.from(r), 16),
831
- this._generateSingleChannelPHash(Buffer.from(g), 16),
832
- this._generateSingleChannelPHash(Buffer.from(b), 16)
833
- ]);
836
+ const rHash = this._calculateHashFromRawChannel(r, 16);
837
+ const gHash = this._calculateHashFromRawChannel(g, 16);
838
+ const bHash = this._calculateHashFromRawChannel(b, 16);
834
839
  const combinedHash = rHash + gHash + bHash;
835
840
  let hex = "";
836
841
  for (let i = 0; i < combinedHash.length; i += 4) {
@@ -1037,14 +1042,16 @@ function apply(ctx, config) {
1037
1042
  const combinedText = finalElementsForDb.filter((el) => el.type === "text" && el.content).map((el) => el.content).join(" ");
1038
1043
  if (combinedText) {
1039
1044
  const newSimhash = hashManager.generateTextSimhash(combinedText);
1040
- const existingTextHashes = await ctx.database.get("cave_hash", { type: "simhash" });
1041
- for (const existing of existingTextHashes) {
1042
- const similarity = hashManager.calculateSimilarity(newSimhash, existing.hash);
1043
- if (similarity >= config.textThreshold) {
1044
- return `文本与回声洞(${existing.cave})的相似度为 ${(similarity * 100).toFixed(2)}%,超过阈值`;
1045
+ if (newSimhash) {
1046
+ const existingTextHashes = await ctx.database.get("cave_hash", { type: "simhash" });
1047
+ for (const existing of existingTextHashes) {
1048
+ const similarity = hashManager.calculateSimilarity(newSimhash, existing.hash);
1049
+ if (similarity >= config.textThreshold) {
1050
+ return `文本与回声洞(${existing.cave})的相似度为 ${(similarity * 100).toFixed(2)}%,超过阈值`;
1051
+ }
1045
1052
  }
1053
+ textHashesToStore.push({ hash: newSimhash, type: "simhash" });
1046
1054
  }
1047
- textHashesToStore.push({ hash: newSimhash, type: "simhash" });
1048
1055
  }
1049
1056
  }
1050
1057
  const userName = (config.enableProfile ? await profileManager.getNickname(session.userId) : null) || session.username;
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.4",
4
+ "version": "2.2.6",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],