koishi-plugin-best-cave 1.2.0 → 1.3.0
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.d.ts +6 -30
- package/lib/index.js +834 -425
- package/lib/utils/HashStorage.d.ts +34 -0
- package/lib/utils/ImageHasher.d.ts +27 -0
- package/lib/utils/fileHandler.d.ts +19 -0
- package/lib/utils/idManager.d.ts +17 -0
- package/package.json +8 -2
- package/readme.md +29 -8
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
interface HashStatus {
|
|
2
|
+
lastUpdated: string;
|
|
3
|
+
entries: Array<{
|
|
4
|
+
caveId: number;
|
|
5
|
+
hashes: string[];
|
|
6
|
+
}>;
|
|
7
|
+
}
|
|
8
|
+
export declare class HashStorage {
|
|
9
|
+
private readonly caveDir;
|
|
10
|
+
private static readonly HASH_FILE;
|
|
11
|
+
private static readonly CAVE_FILE;
|
|
12
|
+
private static readonly BATCH_SIZE;
|
|
13
|
+
private hashes;
|
|
14
|
+
private initialized;
|
|
15
|
+
constructor(caveDir: string);
|
|
16
|
+
private get filePath();
|
|
17
|
+
private get resourceDir();
|
|
18
|
+
private get caveFilePath();
|
|
19
|
+
initialize(): Promise<void>;
|
|
20
|
+
getStatus(): Promise<HashStatus>;
|
|
21
|
+
updateCaveHash(caveId: number, imgBuffers?: Buffer[]): Promise<void>;
|
|
22
|
+
updateAllCaves(isInitialBuild?: boolean): Promise<void>;
|
|
23
|
+
findDuplicates(imgBuffers: Buffer[], threshold: number): Promise<Array<{
|
|
24
|
+
index: number;
|
|
25
|
+
caveId: number;
|
|
26
|
+
similarity: number;
|
|
27
|
+
} | null>>;
|
|
28
|
+
private loadCaveData;
|
|
29
|
+
private saveHashes;
|
|
30
|
+
private buildInitialHashes;
|
|
31
|
+
private updateMissingHashes;
|
|
32
|
+
private processBatch;
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
/**
|
|
3
|
+
* 图片哈希计算
|
|
4
|
+
*/
|
|
5
|
+
export declare class ImageHasher {
|
|
6
|
+
/**
|
|
7
|
+
* 计算图片哈希值
|
|
8
|
+
*/
|
|
9
|
+
static calculateHash(imageBuffer: Buffer): Promise<string>;
|
|
10
|
+
private static binaryToHex;
|
|
11
|
+
private static hexToBinary;
|
|
12
|
+
private static haarWaveletTransform;
|
|
13
|
+
private static haarTransform1D;
|
|
14
|
+
private static extractFeatures;
|
|
15
|
+
/**
|
|
16
|
+
* 计算两个hash值的汉明距离
|
|
17
|
+
*/
|
|
18
|
+
static calculateDistance(hash1: string, hash2: string): number;
|
|
19
|
+
/**
|
|
20
|
+
* 计算图片相似度(0-1)
|
|
21
|
+
*/
|
|
22
|
+
static calculateSimilarity(hash1: string, hash2: string): number;
|
|
23
|
+
/**
|
|
24
|
+
* 批量比较图片相似度
|
|
25
|
+
*/
|
|
26
|
+
static batchCompareSimilarity(newHash: string, existingHashes: string[]): number[];
|
|
27
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare class FileHandler {
|
|
2
|
+
private static locks;
|
|
3
|
+
private static readonly RETRY_COUNT;
|
|
4
|
+
private static readonly RETRY_DELAY;
|
|
5
|
+
private static readonly CONCURRENCY_LIMIT;
|
|
6
|
+
private static withConcurrencyLimit;
|
|
7
|
+
private static withFileOp;
|
|
8
|
+
static withTransaction<T>(operations: Array<{
|
|
9
|
+
filePath: string;
|
|
10
|
+
operation: () => Promise<T>;
|
|
11
|
+
rollback?: () => Promise<void>;
|
|
12
|
+
}>): Promise<T[]>;
|
|
13
|
+
static readJsonData<T>(filePath: string): Promise<T[]>;
|
|
14
|
+
static writeJsonData<T>(filePath: string, data: T[]): Promise<void>;
|
|
15
|
+
static ensureDirectory(dir: string): Promise<void>;
|
|
16
|
+
static ensureJsonFile(filePath: string): Promise<void>;
|
|
17
|
+
static saveMediaFile(filePath: string, data: Buffer | string): Promise<void>;
|
|
18
|
+
static deleteMediaFile(filePath: string): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class IdManager {
|
|
2
|
+
private deletedIds;
|
|
3
|
+
private maxId;
|
|
4
|
+
private initialized;
|
|
5
|
+
private readonly statusFilePath;
|
|
6
|
+
private stats;
|
|
7
|
+
private usedIds;
|
|
8
|
+
constructor(baseDir: string);
|
|
9
|
+
initialize(caveFilePath: string, pendingFilePath: string): Promise<void>;
|
|
10
|
+
private handleConflicts;
|
|
11
|
+
getNextId(): number;
|
|
12
|
+
markDeleted(id: number): Promise<void>;
|
|
13
|
+
addStat(contributorNumber: string, caveId: number): Promise<void>;
|
|
14
|
+
removeStat(contributorNumber: string, caveId: number): Promise<void>;
|
|
15
|
+
getStats(): Record<string, number[]>;
|
|
16
|
+
private saveStatus;
|
|
17
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-best-cave",
|
|
3
3
|
"description": "最好的 cave 插件,可开关的审核系统,可引用添加,支持图文混合内容,可查阅投稿列表,完美复刻你的 .cave 体验!",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"contributors": [
|
|
6
6
|
"Yis_Rime <yis_rime@outlook.com>"
|
|
7
7
|
],
|
|
@@ -25,6 +25,12 @@
|
|
|
25
25
|
],
|
|
26
26
|
"devDependencies": {},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"koishi": "^4.18.3"
|
|
28
|
+
"koishi": "^4.18.3",
|
|
29
|
+
"sharp": "^0.32.6",
|
|
30
|
+
"koishi-plugin-adapter-onebot": "^6.1.3"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"sharp": "^0.32.6",
|
|
34
|
+
"koishi-plugin-adapter-onebot": "^6.1.3"
|
|
29
35
|
}
|
|
30
36
|
}
|
package/readme.md
CHANGED
|
@@ -9,11 +9,14 @@
|
|
|
9
9
|
### 核心功能
|
|
10
10
|
|
|
11
11
|
- 支持文字与图片混合保存
|
|
12
|
-
-
|
|
13
|
-
-
|
|
12
|
+
- 智能处理各类图片与视频链接
|
|
13
|
+
- 内容智能排序,保持原始布局
|
|
14
14
|
- 完整的权限管理系统
|
|
15
15
|
- 可选的内容审核流程
|
|
16
16
|
- 群组调用冷却机制
|
|
17
|
+
- 重复内容智能检测
|
|
18
|
+
- 黑白名单系统
|
|
19
|
+
- 分页显示支持
|
|
17
20
|
|
|
18
21
|
### 指令
|
|
19
22
|
|
|
@@ -23,19 +26,37 @@
|
|
|
23
26
|
| `cave -a <内容>` | 添加新回声洞(支持文字、图片与视频) | 所有人 |
|
|
24
27
|
| `cave -g <编号>` | 查看指定回声洞 | 所有人 |
|
|
25
28
|
| `cave -r <编号>` | 删除指定回声洞 | 内容贡献者/管理员 |
|
|
29
|
+
| `cave -l [页码/用户ID]` | 查看投稿统计 | 所有人(仅自己)/管理员(全部) |
|
|
26
30
|
|
|
27
31
|
#### 管理指令
|
|
28
32
|
|
|
29
33
|
| 指令 | 说明 | 权限 |
|
|
30
34
|
|------|------|------|
|
|
31
|
-
| `cave -l [用户ID]` | 查看投稿统计 | 管理员 |
|
|
32
35
|
| `cave -p <编号/all>` | 通过待审核内容 | 管理员 |
|
|
33
36
|
| `cave -d <编号/all>` | 拒绝待审核内容 | 管理员 |
|
|
34
37
|
|
|
38
|
+
### 配置项
|
|
39
|
+
|
|
40
|
+
| 配置项 | 类型 | 默认值 | 说明 |
|
|
41
|
+
|--------|------|--------|------|
|
|
42
|
+
| manager | string[] | [] | 管理员用户ID列表 |
|
|
43
|
+
| number | number | 60 | 冷却时间(秒) |
|
|
44
|
+
| enableAudit | boolean | false | 是否启用审核 |
|
|
45
|
+
| imageMaxSize | number | 4 | 图片大小限制(MB) |
|
|
46
|
+
| duplicateThreshold | number | 0.8 | 图片查重阈值(0-1) |
|
|
47
|
+
| allowVideo | boolean | true | 是否允许视频 |
|
|
48
|
+
| videoMaxSize | number | 16 | 视频大小限制(MB) |
|
|
49
|
+
| enablePagination | boolean | false | 是否启用分页 |
|
|
50
|
+
| itemsPerPage | number | 10 | 每页显示条数 |
|
|
51
|
+
| blacklist | string[] | [] | 黑名单用户/群组ID |
|
|
52
|
+
| whitelist | string[] | [] | 白名单用户/群组ID |
|
|
53
|
+
|
|
35
54
|
### 注意事项
|
|
36
55
|
|
|
37
|
-
1.
|
|
38
|
-
2.
|
|
39
|
-
3.
|
|
40
|
-
4.
|
|
41
|
-
5.
|
|
56
|
+
1. 图片和视频会自动保存到本地,请确保存储空间充足
|
|
57
|
+
2. 管理员不受群组冷却时间限制
|
|
58
|
+
3. 开启审核模式后,白名单内的用户可直接投稿
|
|
59
|
+
4. 引用消息添加时会保留原消息的格式与布局
|
|
60
|
+
5. 支持自动检测重复图片内容,可通过阈值调整严格程度
|
|
61
|
+
6. 黑名单中的用户无法使用任何功能
|
|
62
|
+
7. 支持按页码查看投稿统计,提升大量数据的浏览体验
|