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.
- package/lib/HashManager.d.ts +7 -1
- package/lib/index.js +23 -16
- package/package.json +1 -1
package/lib/HashManager.d.ts
CHANGED
|
@@ -63,7 +63,13 @@ export declare class HashManager {
|
|
|
63
63
|
* @returns {Promise<string>} 一个包含操作结果的报告字符串。
|
|
64
64
|
*/
|
|
65
65
|
checkForSimilarCaves(): Promise<string>;
|
|
66
|
-
|
|
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
|
-
|
|
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
|
-
|
|
810
|
-
|
|
811
|
-
|
|
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
|
|
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
|
|
830
|
-
|
|
831
|
-
|
|
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
|
-
|
|
1041
|
-
|
|
1042
|
-
const
|
|
1043
|
-
|
|
1044
|
-
|
|
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;
|