koishi-plugin-best-cave 1.5.8 → 1.5.10
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 +42 -11
- package/lib/index.js +84 -21
- package/lib/utils/AuditHandler.d.ts +72 -0
- package/lib/utils/MediaHandler.d.ts +42 -0
- package/lib/utils/ProcessHandle.d.ts +38 -0
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -1,14 +1,37 @@
|
|
|
1
1
|
import { Context, Schema } from 'koishi';
|
|
2
2
|
export declare const name = "best-cave";
|
|
3
3
|
export declare const inject: string[];
|
|
4
|
+
/**
|
|
5
|
+
* 基础元素类型
|
|
6
|
+
* @interface BaseElement
|
|
7
|
+
* @property {('text'|'img'|'video')} type - 元素类型
|
|
8
|
+
* @property {number} index - 排序索引
|
|
9
|
+
*/
|
|
4
10
|
export interface BaseElement {
|
|
5
11
|
type: 'text' | 'img' | 'video';
|
|
6
12
|
index: number;
|
|
7
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 文本元素类型
|
|
16
|
+
* @interface TextElement
|
|
17
|
+
* @extends {BaseElement}
|
|
18
|
+
* @property {'text'} type - 文本类型
|
|
19
|
+
* @property {string} content - 文本内容
|
|
20
|
+
*/
|
|
8
21
|
export interface TextElement extends BaseElement {
|
|
9
22
|
type: 'text';
|
|
10
23
|
content: string;
|
|
11
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* 媒体元素类型
|
|
27
|
+
* @interface MediaElement
|
|
28
|
+
* @extends {BaseElement}
|
|
29
|
+
* @property {('img'|'video')} type - 媒体类型
|
|
30
|
+
* @property {string} [file] - 文件名
|
|
31
|
+
* @property {string} [fileName] - 原始文件名
|
|
32
|
+
* @property {string} [fileSize] - 文件大小
|
|
33
|
+
* @property {string} [filePath] - 文件路径
|
|
34
|
+
*/
|
|
12
35
|
export interface MediaElement extends BaseElement {
|
|
13
36
|
type: 'img' | 'video';
|
|
14
37
|
file?: string;
|
|
@@ -17,6 +40,14 @@ export interface MediaElement extends BaseElement {
|
|
|
17
40
|
filePath?: string;
|
|
18
41
|
}
|
|
19
42
|
export type Element = TextElement | MediaElement;
|
|
43
|
+
/**
|
|
44
|
+
* 回声洞对象
|
|
45
|
+
* @interface CaveObject
|
|
46
|
+
* @property {number} cave_id - 回声洞ID
|
|
47
|
+
* @property {Element[]} elements - 元素列表
|
|
48
|
+
* @property {string} contributor_number - 投稿者ID
|
|
49
|
+
* @property {string} contributor_name - 投稿者名称
|
|
50
|
+
*/
|
|
20
51
|
export interface CaveObject {
|
|
21
52
|
cave_id: number;
|
|
22
53
|
elements: Element[];
|
|
@@ -25,17 +56,6 @@ export interface CaveObject {
|
|
|
25
56
|
}
|
|
26
57
|
export interface PendingCave extends CaveObject {
|
|
27
58
|
}
|
|
28
|
-
/**
|
|
29
|
-
* 插件配置项
|
|
30
|
-
* @type {Schema}
|
|
31
|
-
*/
|
|
32
|
-
export declare const Config: Schema<Config>;
|
|
33
|
-
/**
|
|
34
|
-
* 插件主入口
|
|
35
|
-
* @param {Context} ctx - Koishi上下文
|
|
36
|
-
* @param {Config} config - 插件配置
|
|
37
|
-
*/
|
|
38
|
-
export declare function apply(ctx: Context, config: Config): Promise<void>;
|
|
39
59
|
export interface Config {
|
|
40
60
|
manager: string[];
|
|
41
61
|
number: number;
|
|
@@ -52,3 +72,14 @@ export interface Config {
|
|
|
52
72
|
textDuplicateThreshold: number;
|
|
53
73
|
enableTextDuplicate: boolean;
|
|
54
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* 插件配置项
|
|
77
|
+
* @type {Schema}
|
|
78
|
+
*/
|
|
79
|
+
export declare const Config: Schema<Config>;
|
|
80
|
+
/**
|
|
81
|
+
* 插件主入口
|
|
82
|
+
* @param {Context} ctx - Koishi上下文
|
|
83
|
+
* @param {Config} config - 插件配置
|
|
84
|
+
*/
|
|
85
|
+
export declare function apply(ctx: Context, config: Config): Promise<void>;
|
package/lib/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
33
33
|
// src/locales/zh-CN.yml
|
|
34
34
|
var require_zh_CN = __commonJS({
|
|
35
35
|
"src/locales/zh-CN.yml"(exports2, module2) {
|
|
36
|
-
module2.exports = { _config: { manager: "管理员", number: "冷却时间(秒)", enableAudit: "启用审核", enableTextDuplicate: "启用文本查重", textDuplicateThreshold: "文本相似度阈值(0-1)", enableImageDuplicate: "启用图片查重", imageDuplicateThreshold: "图片相似度阈值(0-1)", imageMaxSize: "图片最大大小(MB)", allowVideo: "允许视频上传", videoMaxSize: "视频最大大小(MB)", enablePagination: "启用统计分页", itemsPerPage: "每页显示数目", blacklist: "黑名单(用户)", whitelist: "审核白名单(用户/群组/频道)" }, commands: { cave: { description: "回声洞", usage: "支持添加、抽取、查看、管理回声洞", examples: "使用 cave 随机抽取回声洞\n使用 -a 直接添加或引用添加\n使用 -g 查看指定回声洞\n使用 -r 删除指定回声洞", options: { a: "添加回声洞", g: "查看回声洞", r: "删除回声洞", l: "查询投稿统计" }, pass: { description: "通过回声洞审核", usage: "通过指定ID的回声洞审核\ncave.pass <ID> - 通过审核\ncave.pass all - 通过所有待审核内容\n" }, reject: { description: "拒绝回声洞审核", usage: "拒绝指定ID的回声洞审核\ncave.reject <ID> - 拒绝审核\ncave.reject all - 拒绝所有待审核内容\n" }, add: { noContent: "请在一分钟内发送内容", operationTimeout: "操作超时,添加取消", videoDisabled: "不允许上传视频", submitPending: "提交成功,序号为({0})", addSuccess: "添加成功,序号为({0})", mediaSizeExceeded: "{0}文件大小超过限制", localFileNotAllowed: "检测到本地文件路径,无法保存" }, remove: { noPermission: "你无权删除他人添加的回声洞", deletePending: "删除(待审核)", deleted: "已删除" }, list: { pageInfo: "第 {0} / {1} 页", header: "当前共有 {0} 项回声洞:", totalItems: "用户 {0} 共计投稿 {1} 项:", idsLine: "{0}" }, audit: { noPending: "暂无待审核回声洞", pendingNotFound: "未找到待审核回声洞", pendingResult: "{0},剩余 {1} 个待审核回声洞:[{2}]", auditPassed: "已通过", auditRejected: "已拒绝", batchAuditResult: "已{0} {1}/{2} 项回声洞", title: "待审核回声洞:", from: "投稿人:", sendFailed: "发送审核消息失败,无法联系管理员 {0}" }, error: { noContent: "回声洞内容为空", getCave: "获取回声洞失败", noCave: "
|
|
36
|
+
module2.exports = { _config: { manager: "管理员", number: "冷却时间(秒)", enableAudit: "启用审核", enableTextDuplicate: "启用文本查重", textDuplicateThreshold: "文本相似度阈值(0-1)", enableImageDuplicate: "启用图片查重", imageDuplicateThreshold: "图片相似度阈值(0-1)", imageMaxSize: "图片最大大小(MB)", allowVideo: "允许视频上传", videoMaxSize: "视频最大大小(MB)", enablePagination: "启用统计分页", itemsPerPage: "每页显示数目", blacklist: "黑名单(用户)", whitelist: "审核白名单(用户/群组/频道)" }, commands: { cave: { description: "回声洞", usage: "支持添加、抽取、查看、管理回声洞", examples: "使用 cave 随机抽取回声洞\n使用 -a 直接添加或引用添加\n使用 -g 查看指定回声洞\n使用 -r 删除指定回声洞", options: { a: "添加回声洞", g: "查看回声洞", r: "删除回声洞", l: "查询投稿统计" }, pass: { description: "通过回声洞审核", usage: "通过指定ID的回声洞审核\ncave.pass <ID> - 通过审核\ncave.pass all - 通过所有待审核内容\n" }, reject: { description: "拒绝回声洞审核", usage: "拒绝指定ID的回声洞审核\ncave.reject <ID> - 拒绝审核\ncave.reject all - 拒绝所有待审核内容\n" }, add: { noContent: "请在一分钟内发送内容", operationTimeout: "操作超时,添加取消", videoDisabled: "不允许上传视频", submitPending: "提交成功,序号为({0})", addSuccess: "添加成功,序号为({0})", mediaSizeExceeded: "{0}文件大小超过限制", localFileNotAllowed: "检测到本地文件路径,无法保存" }, remove: { noPermission: "你无权删除他人添加的回声洞", deletePending: "删除(待审核)", deleted: "已删除" }, list: { pageInfo: "第 {0} / {1} 页", header: "当前共有 {0} 项回声洞:", totalItems: "用户 {0} 共计投稿 {1} 项:", idsLine: "{0}" }, audit: { noPending: "暂无待审核回声洞", pendingNotFound: "未找到待审核回声洞", pendingResult: "{0},剩余 {1} 个待审核回声洞:[{2}]", auditPassed: "已通过", auditRejected: "已拒绝", batchAuditResult: "已{0} {1}/{2} 项回声洞", title: "待审核回声洞:", from: "投稿人:", sendFailed: "发送审核消息失败,无法联系管理员 {0}" }, error: { noContent: "回声洞内容为空", getCave: "获取回声洞失败", noCave: "当前无回声洞", invalidId: "请输入有效的回声洞ID", notFound: "未找到该回声洞", exactDuplicateFound: "发现完全相同的", similarDuplicateFound: "发现相似度为 {0}% 的", addFailed: "添加失败,请稍后重试。" }, message: { blacklisted: "你已被列入黑名单", managerOnly: "此操作仅限管理员可用", cooldown: "群聊冷却中...请在 {0} 秒后重试", caveTitle: "回声洞 —— ({0})", contributorSuffix: "—— {0}", mediaSizeExceeded: "{0}文件大小超过限制" } } } };
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
39
|
|
|
@@ -622,16 +622,11 @@ var HashManager = class _HashManager {
|
|
|
622
622
|
static {
|
|
623
623
|
__name(this, "HashManager");
|
|
624
624
|
}
|
|
625
|
-
// 哈希数据文件名
|
|
626
625
|
static HASH_FILE = "hash.json";
|
|
627
|
-
// 回声洞数据文件名
|
|
628
626
|
static CAVE_FILE = "cave.json";
|
|
629
|
-
// 批处理大小
|
|
630
627
|
static BATCH_SIZE = 50;
|
|
631
|
-
// 存储回声洞ID到图片哈希值的映射
|
|
632
628
|
imageHashes = /* @__PURE__ */ new Map();
|
|
633
629
|
textHashes = /* @__PURE__ */ new Map();
|
|
634
|
-
// 初始化状态标志
|
|
635
630
|
initialized = false;
|
|
636
631
|
get filePath() {
|
|
637
632
|
return path3.join(this.caveDir, _HashManager.HASH_FILE);
|
|
@@ -824,7 +819,6 @@ var HashManager = class _HashManager {
|
|
|
824
819
|
}
|
|
825
820
|
return matches / length;
|
|
826
821
|
}
|
|
827
|
-
// 重命名原有的图片哈希相关方法
|
|
828
822
|
async findImageDuplicates(images, threshold) {
|
|
829
823
|
if (!this.initialized) await this.initialize();
|
|
830
824
|
const inputHashes = await Promise.all(
|
|
@@ -985,6 +979,12 @@ var import_koishi4 = require("koishi");
|
|
|
985
979
|
var fs4 = __toESM(require("fs"));
|
|
986
980
|
var path4 = __toESM(require("path"));
|
|
987
981
|
var AuditManager = class {
|
|
982
|
+
/**
|
|
983
|
+
* 创建审核管理器实例
|
|
984
|
+
* @param ctx - Koishi 上下文
|
|
985
|
+
* @param config - 配置对象
|
|
986
|
+
* @param idManager - ID 管理器实例
|
|
987
|
+
*/
|
|
988
988
|
constructor(ctx, config, idManager) {
|
|
989
989
|
this.ctx = ctx;
|
|
990
990
|
this.config = config;
|
|
@@ -994,6 +994,17 @@ var AuditManager = class {
|
|
|
994
994
|
__name(this, "AuditManager");
|
|
995
995
|
}
|
|
996
996
|
logger = new import_koishi4.Logger("AuditManager");
|
|
997
|
+
/**
|
|
998
|
+
* 处理审核操作
|
|
999
|
+
* @param pendingData - 待审核的洞数据数组
|
|
1000
|
+
* @param isApprove - 是否通过审核
|
|
1001
|
+
* @param caveFilePath - 洞数据文件路径
|
|
1002
|
+
* @param resourceDir - 资源目录路径
|
|
1003
|
+
* @param pendingFilePath - 待审核数据文件路径
|
|
1004
|
+
* @param session - 会话对象
|
|
1005
|
+
* @param targetId - 目标洞ID(可选)
|
|
1006
|
+
* @returns 处理结果消息
|
|
1007
|
+
*/
|
|
997
1008
|
async processAudit(pendingData, isApprove, caveFilePath, resourceDir, pendingFilePath, session, targetId) {
|
|
998
1009
|
if (pendingData.length === 0) {
|
|
999
1010
|
return this.sendMessage(session, "commands.cave.audit.noPending", [], true);
|
|
@@ -1018,6 +1029,18 @@ var AuditManager = class {
|
|
|
1018
1029
|
session
|
|
1019
1030
|
);
|
|
1020
1031
|
}
|
|
1032
|
+
/**
|
|
1033
|
+
* 处理单条审核
|
|
1034
|
+
* @param pendingData - 待审核的洞数据数组
|
|
1035
|
+
* @param isApprove - 是否通过审核
|
|
1036
|
+
* @param caveFilePath - 洞数据文件路径
|
|
1037
|
+
* @param resourceDir - 资源目录路径
|
|
1038
|
+
* @param pendingFilePath - 待审核数据文件路径
|
|
1039
|
+
* @param targetId - 目标洞ID
|
|
1040
|
+
* @param session - 会话对象
|
|
1041
|
+
* @returns 处理结果消息
|
|
1042
|
+
* @private
|
|
1043
|
+
*/
|
|
1021
1044
|
async handleSingleAudit(pendingData, isApprove, caveFilePath, resourceDir, pendingFilePath, targetId, session) {
|
|
1022
1045
|
const targetCave = pendingData.find((item) => item.cave_id === targetId);
|
|
1023
1046
|
if (!targetCave) {
|
|
@@ -1066,6 +1089,17 @@ var AuditManager = class {
|
|
|
1066
1089
|
false
|
|
1067
1090
|
);
|
|
1068
1091
|
}
|
|
1092
|
+
/**
|
|
1093
|
+
* 处理批量审核
|
|
1094
|
+
* @param pendingData - 待审核的洞数据数组
|
|
1095
|
+
* @param isApprove - 是否通过审核
|
|
1096
|
+
* @param caveFilePath - 洞数据文件路径
|
|
1097
|
+
* @param resourceDir - 资源目录路径
|
|
1098
|
+
* @param pendingFilePath - 待审核数据文件路径
|
|
1099
|
+
* @param session - 会话对象
|
|
1100
|
+
* @returns 处理结果消息
|
|
1101
|
+
* @private
|
|
1102
|
+
*/
|
|
1069
1103
|
async handleBatchAudit(pendingData, isApprove, caveFilePath, resourceDir, pendingFilePath, session) {
|
|
1070
1104
|
const data = isApprove ? await FileHandler.readJsonData(caveFilePath) : null;
|
|
1071
1105
|
let processedCount = 0;
|
|
@@ -1109,6 +1143,12 @@ var AuditManager = class {
|
|
|
1109
1143
|
pendingData.length
|
|
1110
1144
|
], false);
|
|
1111
1145
|
}
|
|
1146
|
+
/**
|
|
1147
|
+
* 发送审核消息给管理员
|
|
1148
|
+
* @param cave - 待审核的洞数据
|
|
1149
|
+
* @param content - 消息内容
|
|
1150
|
+
* @param session - 会话对象
|
|
1151
|
+
*/
|
|
1112
1152
|
async sendAuditMessage(cave, content, session) {
|
|
1113
1153
|
const auditMessage = `${session.text("commands.cave.audit.title")}
|
|
1114
1154
|
${content}
|
|
@@ -1124,6 +1164,12 @@ ${session.text("commands.cave.audit.from")}${cave.contributor_number}`;
|
|
|
1124
1164
|
}
|
|
1125
1165
|
}
|
|
1126
1166
|
}
|
|
1167
|
+
/**
|
|
1168
|
+
* 删除媒体文件
|
|
1169
|
+
* @param cave - 洞数据
|
|
1170
|
+
* @param resourceDir - 资源目录路径
|
|
1171
|
+
* @private
|
|
1172
|
+
*/
|
|
1127
1173
|
async deleteMediaFiles(cave, resourceDir) {
|
|
1128
1174
|
if (cave.elements) {
|
|
1129
1175
|
for (const element of cave.elements) {
|
|
@@ -1136,6 +1182,13 @@ ${session.text("commands.cave.audit.from")}${cave.contributor_number}`;
|
|
|
1136
1182
|
}
|
|
1137
1183
|
}
|
|
1138
1184
|
}
|
|
1185
|
+
/**
|
|
1186
|
+
* 清理元素数据用于保存
|
|
1187
|
+
* @param elements - 元素数组
|
|
1188
|
+
* @param keepIndex - 是否保留索引
|
|
1189
|
+
* @returns 清理后的元素数组
|
|
1190
|
+
* @private
|
|
1191
|
+
*/
|
|
1139
1192
|
cleanElementsForSave(elements, keepIndex = false) {
|
|
1140
1193
|
if (!elements?.length) return [];
|
|
1141
1194
|
const cleanedElements = elements.map((element) => {
|
|
@@ -1159,6 +1212,16 @@ ${session.text("commands.cave.audit.from")}${cave.contributor_number}`;
|
|
|
1159
1212
|
});
|
|
1160
1213
|
return keepIndex ? cleanedElements.sort((a, b) => (a.index || 0) - (b.index || 0)) : cleanedElements;
|
|
1161
1214
|
}
|
|
1215
|
+
/**
|
|
1216
|
+
* 发送消息
|
|
1217
|
+
* @param session - 会话对象
|
|
1218
|
+
* @param key - 消息key
|
|
1219
|
+
* @param params - 消息参数
|
|
1220
|
+
* @param isTemp - 是否为临时消息
|
|
1221
|
+
* @param timeout - 临时消息超时时间
|
|
1222
|
+
* @returns 空字符串
|
|
1223
|
+
* @private
|
|
1224
|
+
*/
|
|
1162
1225
|
async sendMessage(session, key, params = [], isTemp = true, timeout = 1e4) {
|
|
1163
1226
|
try {
|
|
1164
1227
|
const msg = await session.send(session.text(key, params));
|
|
@@ -1208,10 +1271,7 @@ async function buildMessage(cave, resourceDir, session) {
|
|
|
1208
1271
|
lines.push(element.content);
|
|
1209
1272
|
} else if (element.type === "img" && element.file) {
|
|
1210
1273
|
const filePath = path5.join(resourceDir, element.file);
|
|
1211
|
-
|
|
1212
|
-
if (base64Data) {
|
|
1213
|
-
lines.push((0, import_koishi5.h)("image", { src: base64Data }));
|
|
1214
|
-
}
|
|
1274
|
+
lines.push(import_koishi5.h.image(filePath));
|
|
1215
1275
|
}
|
|
1216
1276
|
}
|
|
1217
1277
|
lines.push(session.text("commands.cave.message.contributorSuffix", [cave.contributor_name]));
|
|
@@ -1237,9 +1297,17 @@ async function sendMessage(session, key, params = [], isTemp = true, timeout = 1
|
|
|
1237
1297
|
}
|
|
1238
1298
|
__name(sendMessage, "sendMessage");
|
|
1239
1299
|
async function processMediaFile(filePath, type) {
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1300
|
+
try {
|
|
1301
|
+
await fs5.promises.access(filePath);
|
|
1302
|
+
if (type === "image") {
|
|
1303
|
+
return filePath;
|
|
1304
|
+
} else {
|
|
1305
|
+
const data = await fs5.promises.readFile(filePath);
|
|
1306
|
+
return `data:${type}/mp4;base64,${data.toString("base64")}`;
|
|
1307
|
+
}
|
|
1308
|
+
} catch {
|
|
1309
|
+
return null;
|
|
1310
|
+
}
|
|
1243
1311
|
}
|
|
1244
1312
|
__name(processMediaFile, "processMediaFile");
|
|
1245
1313
|
async function extractMediaContent(originalContent, config, session) {
|
|
@@ -1463,6 +1531,7 @@ __name(processDelete, "processDelete");
|
|
|
1463
1531
|
// src/index.ts
|
|
1464
1532
|
var name = "best-cave";
|
|
1465
1533
|
var inject = ["database"];
|
|
1534
|
+
var logger5 = new import_koishi6.Logger("cave");
|
|
1466
1535
|
var Config = import_koishi6.Schema.object({
|
|
1467
1536
|
manager: import_koishi6.Schema.array(import_koishi6.Schema.string()).required(),
|
|
1468
1537
|
// 管理员用户ID
|
|
@@ -1553,7 +1622,6 @@ async function apply(ctx, config) {
|
|
|
1553
1622
|
ctx2,
|
|
1554
1623
|
session,
|
|
1555
1624
|
imageBuffers
|
|
1556
|
-
// 添加参数用于收集buffer
|
|
1557
1625
|
) : [],
|
|
1558
1626
|
videoUrls.length > 0 ? saveMedia(
|
|
1559
1627
|
videoUrls,
|
|
@@ -1568,20 +1636,16 @@ async function apply(ctx, config) {
|
|
|
1568
1636
|
]);
|
|
1569
1637
|
const newCave = {
|
|
1570
1638
|
cave_id: caveId,
|
|
1571
|
-
// 确保使用有效的数字ID
|
|
1572
1639
|
elements: [
|
|
1573
1640
|
...textParts,
|
|
1574
1641
|
...imageElements.map((el, idx) => ({
|
|
1575
1642
|
...el,
|
|
1576
1643
|
file: savedImages[idx],
|
|
1577
|
-
// 保持原始文本和图片的相对位置
|
|
1578
1644
|
index: el.index
|
|
1579
1645
|
}))
|
|
1580
1646
|
].sort((a, b) => a.index - b.index),
|
|
1581
1647
|
contributor_number: session.userId || "100000",
|
|
1582
|
-
// 添加默认值
|
|
1583
1648
|
contributor_name: session.username || "User"
|
|
1584
|
-
// 添加默认值
|
|
1585
1649
|
};
|
|
1586
1650
|
if (videoUrls.length > 0 && savedVideos.length > 0) {
|
|
1587
1651
|
newCave.elements.push({
|
|
@@ -1658,7 +1722,7 @@ async function apply(ctx, config) {
|
|
|
1658
1722
|
}
|
|
1659
1723
|
}
|
|
1660
1724
|
__name(processAdd, "processAdd");
|
|
1661
|
-
const caveCommand = ctx.command("cave [message]").option("a", "添加回声洞").option("g", "查看回声洞", { type: "string" }).option("r", "删除回声洞", { type: "string" }).option("l", "查询投稿统计", { type: "string" }).before(async ({ session
|
|
1725
|
+
const caveCommand = ctx.command("cave [message]").option("a", "添加回声洞").option("g", "查看回声洞", { type: "string" }).option("r", "删除回声洞", { type: "string" }).option("l", "查询投稿统计", { type: "string" }).before(async ({ session }) => {
|
|
1662
1726
|
if (config.blacklist.includes(session.userId)) {
|
|
1663
1727
|
return sendMessage(session, "commands.cave.message.blacklisted", [], true);
|
|
1664
1728
|
}
|
|
@@ -1737,7 +1801,6 @@ async function apply(ctx, config) {
|
|
|
1737
1801
|
});
|
|
1738
1802
|
}
|
|
1739
1803
|
__name(apply, "apply");
|
|
1740
|
-
var logger5 = new import_koishi6.Logger("cave");
|
|
1741
1804
|
function cleanElementsForSave(elements, keepIndex = false) {
|
|
1742
1805
|
if (!elements?.length) return [];
|
|
1743
1806
|
const cleanedElements = elements.map((element) => {
|
|
@@ -1,17 +1,89 @@
|
|
|
1
1
|
import { Context } from 'koishi';
|
|
2
2
|
import { Config, PendingCave } from '..';
|
|
3
3
|
import { IdManager } from './IdManager';
|
|
4
|
+
/**
|
|
5
|
+
* 管理洞审核相关操作的类
|
|
6
|
+
*/
|
|
4
7
|
export declare class AuditManager {
|
|
5
8
|
private ctx;
|
|
6
9
|
private config;
|
|
7
10
|
private idManager;
|
|
8
11
|
private logger;
|
|
12
|
+
/**
|
|
13
|
+
* 创建审核管理器实例
|
|
14
|
+
* @param ctx - Koishi 上下文
|
|
15
|
+
* @param config - 配置对象
|
|
16
|
+
* @param idManager - ID 管理器实例
|
|
17
|
+
*/
|
|
9
18
|
constructor(ctx: Context, config: Config, idManager: IdManager);
|
|
19
|
+
/**
|
|
20
|
+
* 处理审核操作
|
|
21
|
+
* @param pendingData - 待审核的洞数据数组
|
|
22
|
+
* @param isApprove - 是否通过审核
|
|
23
|
+
* @param caveFilePath - 洞数据文件路径
|
|
24
|
+
* @param resourceDir - 资源目录路径
|
|
25
|
+
* @param pendingFilePath - 待审核数据文件路径
|
|
26
|
+
* @param session - 会话对象
|
|
27
|
+
* @param targetId - 目标洞ID(可选)
|
|
28
|
+
* @returns 处理结果消息
|
|
29
|
+
*/
|
|
10
30
|
processAudit(pendingData: PendingCave[], isApprove: boolean, caveFilePath: string, resourceDir: string, pendingFilePath: string, session: any, targetId?: number): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* 处理单条审核
|
|
33
|
+
* @param pendingData - 待审核的洞数据数组
|
|
34
|
+
* @param isApprove - 是否通过审核
|
|
35
|
+
* @param caveFilePath - 洞数据文件路径
|
|
36
|
+
* @param resourceDir - 资源目录路径
|
|
37
|
+
* @param pendingFilePath - 待审核数据文件路径
|
|
38
|
+
* @param targetId - 目标洞ID
|
|
39
|
+
* @param session - 会话对象
|
|
40
|
+
* @returns 处理结果消息
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
11
43
|
private handleSingleAudit;
|
|
44
|
+
/**
|
|
45
|
+
* 处理批量审核
|
|
46
|
+
* @param pendingData - 待审核的洞数据数组
|
|
47
|
+
* @param isApprove - 是否通过审核
|
|
48
|
+
* @param caveFilePath - 洞数据文件路径
|
|
49
|
+
* @param resourceDir - 资源目录路径
|
|
50
|
+
* @param pendingFilePath - 待审核数据文件路径
|
|
51
|
+
* @param session - 会话对象
|
|
52
|
+
* @returns 处理结果消息
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
12
55
|
private handleBatchAudit;
|
|
56
|
+
/**
|
|
57
|
+
* 发送审核消息给管理员
|
|
58
|
+
* @param cave - 待审核的洞数据
|
|
59
|
+
* @param content - 消息内容
|
|
60
|
+
* @param session - 会话对象
|
|
61
|
+
*/
|
|
13
62
|
sendAuditMessage(cave: PendingCave, content: string, session: any): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* 删除媒体文件
|
|
65
|
+
* @param cave - 洞数据
|
|
66
|
+
* @param resourceDir - 资源目录路径
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
14
69
|
private deleteMediaFiles;
|
|
70
|
+
/**
|
|
71
|
+
* 清理元素数据用于保存
|
|
72
|
+
* @param elements - 元素数组
|
|
73
|
+
* @param keepIndex - 是否保留索引
|
|
74
|
+
* @returns 清理后的元素数组
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
15
77
|
private cleanElementsForSave;
|
|
78
|
+
/**
|
|
79
|
+
* 发送消息
|
|
80
|
+
* @param session - 会话对象
|
|
81
|
+
* @param key - 消息key
|
|
82
|
+
* @param params - 消息参数
|
|
83
|
+
* @param isTemp - 是否为临时消息
|
|
84
|
+
* @param timeout - 临时消息超时时间
|
|
85
|
+
* @returns 空字符串
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
16
88
|
private sendMessage;
|
|
17
89
|
}
|
|
@@ -1,8 +1,37 @@
|
|
|
1
1
|
import { Context } from 'koishi';
|
|
2
2
|
import { Element, CaveObject } from '..';
|
|
3
|
+
/**
|
|
4
|
+
* 构建并返回洞窟消息内容
|
|
5
|
+
* @param cave - 洞窟对象
|
|
6
|
+
* @param resourceDir - 资源目录路径
|
|
7
|
+
* @param session - 会话对象
|
|
8
|
+
* @returns 格式化后的消息字符串
|
|
9
|
+
*/
|
|
3
10
|
export declare function buildMessage(cave: CaveObject, resourceDir: string, session?: any): Promise<string>;
|
|
11
|
+
/**
|
|
12
|
+
* 发送临时或永久消息
|
|
13
|
+
* @param session - 会话对象
|
|
14
|
+
* @param key - 消息key
|
|
15
|
+
* @param params - 消息参数数组
|
|
16
|
+
* @param isTemp - 是否为临时消息
|
|
17
|
+
* @param timeout - 临时消息超时时间(ms)
|
|
18
|
+
* @returns 空字符串
|
|
19
|
+
*/
|
|
4
20
|
export declare function sendMessage(session: any, key: string, params?: any[], isTemp?: boolean, timeout?: number): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* 处理媒体文件,返回文件路径或base64编码
|
|
23
|
+
* @param filePath - 文件路径
|
|
24
|
+
* @param type - 媒体类型('image' | 'video')
|
|
25
|
+
* @returns 图片路径或视频base64编码
|
|
26
|
+
*/
|
|
5
27
|
export declare function processMediaFile(filePath: string, type: 'image' | 'video'): Promise<string | null>;
|
|
28
|
+
/**
|
|
29
|
+
* 从内容中提取媒体元素
|
|
30
|
+
* @param originalContent - 原始内容字符串
|
|
31
|
+
* @param config - 配置对象,包含图片和视频大小限制
|
|
32
|
+
* @param session - 会话对象
|
|
33
|
+
* @returns 包含图片、视频URL和元素的对象
|
|
34
|
+
*/
|
|
6
35
|
export declare function extractMediaContent(originalContent: string, config: {
|
|
7
36
|
imageMaxSize: number;
|
|
8
37
|
videoMaxSize: number;
|
|
@@ -23,6 +52,19 @@ export declare function extractMediaContent(originalContent: string, config: {
|
|
|
23
52
|
}>;
|
|
24
53
|
textParts: Element[];
|
|
25
54
|
}>;
|
|
55
|
+
/**
|
|
56
|
+
* 保存媒体文件
|
|
57
|
+
* @param urls - 媒体URL数组
|
|
58
|
+
* @param fileNames - 文件名数组
|
|
59
|
+
* @param resourceDir - 资源目录路径
|
|
60
|
+
* @param caveId - 洞窟ID
|
|
61
|
+
* @param mediaType - 媒体类型('img' | 'video')
|
|
62
|
+
* @param config - 配置对象,包含重复检查相关设置
|
|
63
|
+
* @param ctx - Koishi上下文
|
|
64
|
+
* @param session - 会话对象
|
|
65
|
+
* @param buffers - 可选的buffer数组,用于收集图片buffer
|
|
66
|
+
* @returns 保存后的文件名数组
|
|
67
|
+
*/
|
|
26
68
|
export declare function saveMedia(urls: string[], fileNames: (string | undefined)[], resourceDir: string, caveId: number, mediaType: 'img' | 'video', config: {
|
|
27
69
|
enableImageDuplicate: boolean;
|
|
28
70
|
imageDuplicateThreshold: number;
|
|
@@ -1,7 +1,45 @@
|
|
|
1
1
|
import { Config } from '..';
|
|
2
2
|
import { IdManager } from './IdManager';
|
|
3
3
|
import { HashManager } from './HashManager';
|
|
4
|
+
/**
|
|
5
|
+
* 处理回声洞列表查询
|
|
6
|
+
* @param session - 会话对象
|
|
7
|
+
* @param config - 配置对象
|
|
8
|
+
* @param idManager - ID管理器实例
|
|
9
|
+
* @param userId - 可选的用户ID,用于筛选特定用户的回声洞
|
|
10
|
+
* @param pageNum - 页码,默认为1
|
|
11
|
+
* @returns 格式化后的回声洞列表字符串
|
|
12
|
+
*/
|
|
4
13
|
export declare function processList(session: any, config: Config, idManager: IdManager, userId?: string, pageNum?: number): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* 查看指定ID的回声洞内容
|
|
16
|
+
* @param caveFilePath - 回声洞数据文件路径
|
|
17
|
+
* @param resourceDir - 资源文件目录路径
|
|
18
|
+
* @param session - 会话对象
|
|
19
|
+
* @param options - 命令选项
|
|
20
|
+
* @param content - 命令内容数组
|
|
21
|
+
* @returns 回声洞内容的格式化字符串
|
|
22
|
+
*/
|
|
5
23
|
export declare function processView(caveFilePath: string, resourceDir: string, session: any, options: any, content: string[]): Promise<string>;
|
|
24
|
+
/**
|
|
25
|
+
* 随机获取一个回声洞
|
|
26
|
+
* @param caveFilePath - 回声洞数据文件路径
|
|
27
|
+
* @param resourceDir - 资源文件目录路径
|
|
28
|
+
* @param session - 会话对象
|
|
29
|
+
* @returns 随机回声洞的格式化字符串,如果没有可用的回声洞则返回错误消息
|
|
30
|
+
*/
|
|
6
31
|
export declare function processRandom(caveFilePath: string, resourceDir: string, session: any): Promise<string | void>;
|
|
32
|
+
/**
|
|
33
|
+
* 删除指定ID的回声洞
|
|
34
|
+
* @param caveFilePath - 回声洞数据文件路径
|
|
35
|
+
* @param resourceDir - 资源文件目录路径
|
|
36
|
+
* @param pendingFilePath - 待审核回声洞数据文件路径
|
|
37
|
+
* @param session - 会话对象
|
|
38
|
+
* @param config - 配置对象
|
|
39
|
+
* @param options - 命令选项
|
|
40
|
+
* @param content - 命令内容数组
|
|
41
|
+
* @param idManager - ID管理器实例
|
|
42
|
+
* @param HashManager - 哈希管理器实例
|
|
43
|
+
* @returns 删除操作的结果消息
|
|
44
|
+
*/
|
|
7
45
|
export declare function processDelete(caveFilePath: string, resourceDir: string, pendingFilePath: string, session: any, config: Config, options: any, content: string[], idManager: IdManager, HashManager: HashManager): Promise<string>;
|