koishi-plugin-maple-drift-bottle 0.0.3 → 0.1.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 +33 -0
- package/lib/index.js +249 -27
- package/package.json +4 -1
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Context, Schema } from 'koishi';
|
|
2
|
+
export declare const name = "maple-drift-bottle";
|
|
3
|
+
export declare const using: readonly ["database"];
|
|
4
|
+
interface DriftBottle {
|
|
5
|
+
id: number;
|
|
6
|
+
author: string;
|
|
7
|
+
authorName: string;
|
|
8
|
+
anonymous: boolean;
|
|
9
|
+
content: string;
|
|
10
|
+
images: string[];
|
|
11
|
+
created: Date;
|
|
12
|
+
}
|
|
13
|
+
declare module 'koishi' {
|
|
14
|
+
interface Tables {
|
|
15
|
+
'maple-drift-bottles': DriftBottle;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export interface Config {
|
|
19
|
+
anonymousByDefault: boolean;
|
|
20
|
+
maxContentLength: number;
|
|
21
|
+
maxPreviewLength: number;
|
|
22
|
+
maxImages: number;
|
|
23
|
+
saveImagesLocally: boolean;
|
|
24
|
+
imageSavePath: string;
|
|
25
|
+
compressImages: boolean;
|
|
26
|
+
maxImageWidth: number;
|
|
27
|
+
maxImageHeight: number;
|
|
28
|
+
imageQuality: number;
|
|
29
|
+
adminQQ: string[];
|
|
30
|
+
}
|
|
31
|
+
export declare const Config: Schema<Config>;
|
|
32
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
33
|
+
export {};
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
2
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
7
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
8
|
var __export = (target, all) => {
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -27,12 +37,24 @@ __export(src_exports, {
|
|
|
27
37
|
});
|
|
28
38
|
module.exports = __toCommonJS(src_exports);
|
|
29
39
|
var import_koishi = require("koishi");
|
|
40
|
+
var import_promises = require("fs/promises");
|
|
41
|
+
var import_path = require("path");
|
|
42
|
+
var import_crypto = require("crypto");
|
|
43
|
+
var import_fs = require("fs");
|
|
44
|
+
var import_sharp = __toESM(require("sharp"));
|
|
30
45
|
var name = "maple-drift-bottle";
|
|
31
46
|
var using = ["database"];
|
|
32
47
|
var Config = import_koishi.Schema.object({
|
|
33
48
|
anonymousByDefault: import_koishi.Schema.boolean().default(false).description("默认是否匿名(true: 匿名,false: 不匿名)"),
|
|
34
|
-
maxContentLength: import_koishi.Schema.number().default(500).min(50).max(2e3).description("
|
|
35
|
-
maxPreviewLength: import_koishi.Schema.number().default(8).min(3).max(50).description('指令"我的漂流瓶"
|
|
49
|
+
maxContentLength: import_koishi.Schema.number().default(500).min(50).max(2e3).description("漂流瓶文本内容最大长度(字符)"),
|
|
50
|
+
maxPreviewLength: import_koishi.Schema.number().default(8).min(3).max(50).description('指令"我的漂流瓶"最大预览字数'),
|
|
51
|
+
maxImages: import_koishi.Schema.number().default(3).min(0).max(10).description("每一条漂流瓶最多可包含的图片数量(0为不允许发送图片)"),
|
|
52
|
+
saveImagesLocally: import_koishi.Schema.boolean().default(true).description("是否本地保存图片(启用后图片永久保存,不依赖外部URL)"),
|
|
53
|
+
imageSavePath: import_koishi.Schema.string().default("./data/maple-drift-bottle/images").description("图片本地保存路径(相对Koishi根目录)"),
|
|
54
|
+
compressImages: import_koishi.Schema.boolean().default(true).description("是否压缩图片以节省空间"),
|
|
55
|
+
maxImageWidth: import_koishi.Schema.number().default(1200).min(100).max(3840).description("图片最大宽度(像素)"),
|
|
56
|
+
maxImageHeight: import_koishi.Schema.number().default(1200).min(100).max(3840).description("图片最大高度(像素)"),
|
|
57
|
+
imageQuality: import_koishi.Schema.number().default(85).min(10).max(100).description("图片质量 (0-100,越高图片质量越好但文件越大)"),
|
|
36
58
|
adminQQ: import_koishi.Schema.array(String).role("table").default([]).description("管理人QQ号(可添加多个)")
|
|
37
59
|
});
|
|
38
60
|
function getSenderDisplay(bottle) {
|
|
@@ -55,12 +77,90 @@ function formatTime(date) {
|
|
|
55
77
|
}
|
|
56
78
|
__name(formatTime, "formatTime");
|
|
57
79
|
function getContentPreview(content, maxLength) {
|
|
80
|
+
if (!content || content.length === 0) {
|
|
81
|
+
return "[无文本内容]";
|
|
82
|
+
}
|
|
58
83
|
if (content.length <= maxLength) {
|
|
59
84
|
return content;
|
|
60
85
|
}
|
|
61
86
|
return content.substring(0, maxLength) + "...";
|
|
62
87
|
}
|
|
63
88
|
__name(getContentPreview, "getContentPreview");
|
|
89
|
+
function extractContentAndImages(elements) {
|
|
90
|
+
let text = "";
|
|
91
|
+
const images = [];
|
|
92
|
+
for (const element of elements) {
|
|
93
|
+
if (element.type === "text") {
|
|
94
|
+
text += element.attrs?.content || "";
|
|
95
|
+
} else if (element.type === "image" || element.type === "img") {
|
|
96
|
+
const url = element.attrs?.url || element.attrs?.src;
|
|
97
|
+
if (url) {
|
|
98
|
+
images.push(url);
|
|
99
|
+
}
|
|
100
|
+
} else if (element.type === "at") {
|
|
101
|
+
continue;
|
|
102
|
+
} else if (element.type === "face") {
|
|
103
|
+
continue;
|
|
104
|
+
} else {
|
|
105
|
+
text += `[${element.type}]`;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return { text: text.trim(), images };
|
|
109
|
+
}
|
|
110
|
+
__name(extractContentAndImages, "extractContentAndImages");
|
|
111
|
+
async function downloadAndSaveImage(ctx, url, savePath, compress, maxWidth, maxHeight, quality) {
|
|
112
|
+
try {
|
|
113
|
+
if (!(0, import_fs.existsSync)(savePath)) {
|
|
114
|
+
await (0, import_promises.mkdir)(savePath, { recursive: true });
|
|
115
|
+
}
|
|
116
|
+
const hash = (0, import_crypto.createHash)("md5").update(url + Date.now()).digest("hex");
|
|
117
|
+
const originalExt = (0, import_path.extname)(new URL(url).pathname) || ".jpg";
|
|
118
|
+
const fileName = `${hash}${originalExt}`;
|
|
119
|
+
const filePath = (0, import_path.join)(savePath, fileName);
|
|
120
|
+
const response = await ctx.http.get(url, { responseType: "arraybuffer" });
|
|
121
|
+
const imageBuffer = Buffer.from(response);
|
|
122
|
+
if (compress) {
|
|
123
|
+
try {
|
|
124
|
+
let sharpInstance = (0, import_sharp.default)(imageBuffer);
|
|
125
|
+
const metadata = await sharpInstance.metadata();
|
|
126
|
+
if (metadata.width > maxWidth || metadata.height > maxHeight) {
|
|
127
|
+
sharpInstance = sharpInstance.resize({
|
|
128
|
+
width: maxWidth,
|
|
129
|
+
height: maxHeight,
|
|
130
|
+
fit: "inside",
|
|
131
|
+
// 保持宽高比,不超过指定尺寸
|
|
132
|
+
withoutEnlargement: true
|
|
133
|
+
// 不放大比指定尺寸小的图片
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
await sharpInstance.jpeg({ quality }).toFile(filePath);
|
|
137
|
+
ctx.logger("maple-drift-bottle").info(`图片压缩保存: ${fileName} (${imageBuffer.length}字节 -> ${(await (0, import_promises.readFile)(filePath)).length}字节)`);
|
|
138
|
+
} catch (sharpError) {
|
|
139
|
+
ctx.logger("maple-drift-bottle").warn("sharp压缩失败,保存原始图片:", sharpError);
|
|
140
|
+
await (0, import_promises.writeFile)(filePath, imageBuffer);
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
await (0, import_promises.writeFile)(filePath, imageBuffer);
|
|
144
|
+
}
|
|
145
|
+
return fileName;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
ctx.logger("maple-drift-bottle").error("下载或保存图片失败:", error);
|
|
148
|
+
throw new Error(`图片保存失败: ${error.message}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
__name(downloadAndSaveImage, "downloadAndSaveImage");
|
|
152
|
+
function getLocalImagePath(fileName, ctx, config) {
|
|
153
|
+
if (!fileName || !config.saveImagesLocally) {
|
|
154
|
+
return fileName;
|
|
155
|
+
}
|
|
156
|
+
const fullPath = (0, import_path.join)(config.imageSavePath, fileName);
|
|
157
|
+
if (!(0, import_fs.existsSync)(fullPath)) {
|
|
158
|
+
ctx.logger("maple-drift-bottle").warn(`图片文件不存在: ${fullPath}`);
|
|
159
|
+
return fileName;
|
|
160
|
+
}
|
|
161
|
+
return fullPath;
|
|
162
|
+
}
|
|
163
|
+
__name(getLocalImagePath, "getLocalImagePath");
|
|
64
164
|
function apply(ctx, config) {
|
|
65
165
|
console.log("maple-drift-bottle 漂流瓶插件加载中...");
|
|
66
166
|
ctx.model.extend("maple-drift-bottles", {
|
|
@@ -72,7 +172,9 @@ function apply(ctx, config) {
|
|
|
72
172
|
anonymous: "boolean",
|
|
73
173
|
// 是否匿名
|
|
74
174
|
content: "text",
|
|
75
|
-
//
|
|
175
|
+
// 文本内容
|
|
176
|
+
images: "json",
|
|
177
|
+
// 图片本地文件名数组(JSON格式存储)
|
|
76
178
|
created: "timestamp"
|
|
77
179
|
// 创建时间
|
|
78
180
|
}, {
|
|
@@ -92,24 +194,50 @@ function apply(ctx, config) {
|
|
|
92
194
|
const bottle = allBottles[randomIndex];
|
|
93
195
|
const senderDisplay = getSenderDisplay(bottle);
|
|
94
196
|
const timeDisplay = formatTime(bottle.created);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
197
|
+
const message = [
|
|
198
|
+
`【漂流瓶 #${bottle.id}】`,
|
|
199
|
+
`发送者:${senderDisplay}`,
|
|
200
|
+
`时间:${timeDisplay}`
|
|
201
|
+
];
|
|
202
|
+
if (bottle.content) {
|
|
203
|
+
message.push(`内容:
|
|
204
|
+
${bottle.content}`);
|
|
205
|
+
}
|
|
206
|
+
if (bottle.images && bottle.images.length > 0) {
|
|
207
|
+
await session.send(message.join("\n"));
|
|
208
|
+
for (const imageName of bottle.images) {
|
|
209
|
+
try {
|
|
210
|
+
const imagePath = getLocalImagePath(imageName, ctx, config);
|
|
211
|
+
await session.send(import_koishi.h.image(imagePath));
|
|
212
|
+
} catch (error) {
|
|
213
|
+
ctx.logger("maple-drift-bottle").warn(`发送图片失败: ${imageName}`, error);
|
|
214
|
+
await session.send(`[图片加载失败]`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return "";
|
|
218
|
+
} else {
|
|
219
|
+
return message.join("\n");
|
|
220
|
+
}
|
|
100
221
|
} catch (error) {
|
|
101
222
|
ctx.logger("maple-drift-bottle").error("捞漂流瓶时出错:", error);
|
|
102
223
|
return "捞取漂流瓶时出错了,请稍后再试。";
|
|
103
224
|
}
|
|
104
225
|
});
|
|
105
|
-
ctx.command("漂流瓶/扔漂流瓶
|
|
226
|
+
ctx.command("漂流瓶/扔漂流瓶", "扔一个漂流瓶到海里(支持文本和图片)").alias("扔漂流瓶").alias("丢漂流瓶").option("invisible", "-i 匿名发送(不显示发送者)").option("visible", "-v 公开发送(显示发送者)").example("扔漂流瓶 这是一条漂流瓶内容").example("扔漂流瓶 -i 这是一条匿名漂流瓶内容").action(async ({ session, options }) => {
|
|
106
227
|
try {
|
|
107
|
-
|
|
108
|
-
|
|
228
|
+
const elements = session.elements;
|
|
229
|
+
if (elements.length === 0) {
|
|
230
|
+
return "漂流瓶内容不能为空!请发送文本或图片。";
|
|
231
|
+
}
|
|
232
|
+
const { text, images: imageUrls } = extractContentAndImages(elements);
|
|
233
|
+
if (!text && imageUrls.length === 0) {
|
|
234
|
+
return "漂流瓶内容不能为空!请发送文本或图片。";
|
|
235
|
+
}
|
|
236
|
+
if (text.length > config.maxContentLength) {
|
|
237
|
+
return `漂流瓶文本内容太长了!最多只能输入${config.maxContentLength}个字符(当前: ${text.length})。`;
|
|
109
238
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return `漂流瓶内容太长了!最多只能输入${config.maxContentLength}个字(当前: ${trimmedContent.length})。`;
|
|
239
|
+
if (imageUrls.length > config.maxImages) {
|
|
240
|
+
return `图片数量太多了!最多只能发送${config.maxImages}张图片(当前: ${imageUrls.length})。`;
|
|
113
241
|
}
|
|
114
242
|
if (options.invisible && options.visible) {
|
|
115
243
|
return "选项冲突:-i(匿名)和-v(公开)不能同时使用";
|
|
@@ -122,17 +250,40 @@ ${bottle.content}`;
|
|
|
122
250
|
}
|
|
123
251
|
const userInfo = await session.getUser(session.userId);
|
|
124
252
|
const authorName = userInfo?.name || session.username || `用户${session.userId}`;
|
|
253
|
+
const savedImageNames = [];
|
|
254
|
+
if (config.saveImagesLocally && imageUrls.length > 0) {
|
|
255
|
+
for (const imageUrl of imageUrls) {
|
|
256
|
+
try {
|
|
257
|
+
const savedName = await downloadAndSaveImage(
|
|
258
|
+
ctx,
|
|
259
|
+
imageUrl,
|
|
260
|
+
config.imageSavePath,
|
|
261
|
+
config.compressImages,
|
|
262
|
+
config.maxImageWidth,
|
|
263
|
+
config.maxImageHeight,
|
|
264
|
+
config.imageQuality
|
|
265
|
+
);
|
|
266
|
+
savedImageNames.push(savedName);
|
|
267
|
+
} catch (error) {
|
|
268
|
+
ctx.logger("maple-drift-bottle").error("图片处理失败:", error);
|
|
269
|
+
return `图片处理失败: ${error.message}`;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
125
273
|
const newBottle = await ctx.database.create("maple-drift-bottles", {
|
|
126
274
|
author: session.userId,
|
|
127
275
|
authorName,
|
|
128
276
|
anonymous,
|
|
129
|
-
content:
|
|
277
|
+
content: text,
|
|
278
|
+
images: config.saveImagesLocally ? savedImageNames : imageUrls,
|
|
130
279
|
created: /* @__PURE__ */ new Date()
|
|
131
280
|
});
|
|
132
281
|
const anonymousText = anonymous ? "匿名" : "不匿名";
|
|
282
|
+
const imageText = savedImageNames.length > 0 ? `,包含${savedImageNames.length}张图片` : "";
|
|
283
|
+
const saveText = config.saveImagesLocally ? "(已本地保存)" : "";
|
|
133
284
|
return `成功扔出一个漂流瓶!
|
|
134
285
|
ID: #${newBottle.id}
|
|
135
|
-
状态: ${anonymousText}
|
|
286
|
+
状态: ${anonymousText}${imageText}${saveText}
|
|
136
287
|
内容已保存到海中,等待有缘人捞取。`;
|
|
137
288
|
} catch (error) {
|
|
138
289
|
ctx.logger("maple-drift-bottle").error("扔漂流瓶时出错:", error);
|
|
@@ -167,8 +318,9 @@ ID: #${newBottle.id}
|
|
|
167
318
|
const timeDisplay = formatTime(bottle.created);
|
|
168
319
|
const anonymousText = bottle.anonymous ? "(匿名)" : "";
|
|
169
320
|
const contentPreview = getContentPreview(bottle.content, config.maxPreviewLength);
|
|
321
|
+
const imageText = bottle.images && bottle.images.length > 0 ? ` [${bottle.images.length}图]` : "";
|
|
170
322
|
output += `${displayIndex}. 漂流瓶 #${bottle.id} ${anonymousText} - ${timeDisplay}
|
|
171
|
-
预览: ${contentPreview}
|
|
323
|
+
预览: ${contentPreview}${imageText}
|
|
172
324
|
`;
|
|
173
325
|
});
|
|
174
326
|
output += "\n──────────\n";
|
|
@@ -204,12 +356,31 @@ ID: #${newBottle.id}
|
|
|
204
356
|
}
|
|
205
357
|
const senderDisplay = getSenderDisplay(bottle);
|
|
206
358
|
const timeDisplay = formatTime(bottle.created);
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
359
|
+
const message = [
|
|
360
|
+
`【漂流瓶 #${bottle.id}】`,
|
|
361
|
+
`发送者:${senderDisplay}`,
|
|
362
|
+
`时间:${timeDisplay}`,
|
|
363
|
+
`状态:${bottle.anonymous ? "匿名" : "公开"}`
|
|
364
|
+
];
|
|
365
|
+
if (bottle.content) {
|
|
366
|
+
message.push(`内容:
|
|
367
|
+
${bottle.content}`);
|
|
368
|
+
}
|
|
369
|
+
if (bottle.images && bottle.images.length > 0) {
|
|
370
|
+
await session.send(message.join("\n"));
|
|
371
|
+
for (const imageName of bottle.images) {
|
|
372
|
+
try {
|
|
373
|
+
const imagePath = getLocalImagePath(imageName, ctx, config);
|
|
374
|
+
await session.send(import_koishi.h.image(imagePath));
|
|
375
|
+
} catch (error) {
|
|
376
|
+
ctx.logger("maple-drift-bottle").warn(`发送图片失败: ${imageName}`, error);
|
|
377
|
+
await session.send(`[图片加载失败]`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return "";
|
|
381
|
+
} else {
|
|
382
|
+
return message.join("\n");
|
|
383
|
+
}
|
|
213
384
|
} catch (error) {
|
|
214
385
|
ctx.logger("maple-drift-bottle").error("查看漂流瓶时出错:", error);
|
|
215
386
|
return "查看漂流瓶时出错了,请稍后再试。";
|
|
@@ -232,12 +403,26 @@ ${bottle.content}`;
|
|
|
232
403
|
}
|
|
233
404
|
const senderDisplay = getSenderDisplay(bottle);
|
|
234
405
|
const timeDisplay = formatTime(bottle.created);
|
|
235
|
-
const contentPreview = bottle.content.length > 50 ? bottle.content.substring(0, 50) + "..." : bottle.content;
|
|
406
|
+
const contentPreview = bottle.content ? bottle.content.length > 50 ? bottle.content.substring(0, 50) + "..." : bottle.content : "[无文本内容]";
|
|
407
|
+
const imageText = bottle.images && bottle.images.length > 0 ? ` (${bottle.images.length}张图片)` : "";
|
|
408
|
+
if (config.saveImagesLocally && bottle.images && bottle.images.length > 0) {
|
|
409
|
+
for (const imageName of bottle.images) {
|
|
410
|
+
try {
|
|
411
|
+
const imagePath = (0, import_path.join)(config.imageSavePath, imageName);
|
|
412
|
+
if ((0, import_fs.existsSync)(imagePath)) {
|
|
413
|
+
await (0, import_promises.rm)(imagePath);
|
|
414
|
+
ctx.logger("maple-drift-bottle").info(`删除图片文件: ${imagePath}`);
|
|
415
|
+
}
|
|
416
|
+
} catch (error) {
|
|
417
|
+
ctx.logger("maple-drift-bottle").warn(`删除图片文件失败: ${imageName}`, error);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
236
421
|
await ctx.database.remove("maple-drift-bottles", { id });
|
|
237
422
|
return `已成功删除漂流瓶 #${id}
|
|
238
423
|
发送者:${senderDisplay}
|
|
239
424
|
时间:${timeDisplay}
|
|
240
|
-
预览:${contentPreview}`;
|
|
425
|
+
预览:${contentPreview}${imageText}`;
|
|
241
426
|
} catch (error) {
|
|
242
427
|
ctx.logger("maple-drift-bottle").error("删除漂流瓶时出错:", error);
|
|
243
428
|
return "删除漂流瓶时出错了,请稍后再试。";
|
|
@@ -273,6 +458,27 @@ ${bottle.content}`;
|
|
|
273
458
|
if (count === 0) {
|
|
274
459
|
return `没有找到${description}漂流瓶。`;
|
|
275
460
|
}
|
|
461
|
+
if (config.saveImagesLocally) {
|
|
462
|
+
let deletedImages = 0;
|
|
463
|
+
for (const bottle of bottles) {
|
|
464
|
+
if (bottle.images && bottle.images.length > 0) {
|
|
465
|
+
for (const imageName of bottle.images) {
|
|
466
|
+
try {
|
|
467
|
+
const imagePath = (0, import_path.join)(config.imageSavePath, imageName);
|
|
468
|
+
if ((0, import_fs.existsSync)(imagePath)) {
|
|
469
|
+
await (0, import_promises.rm)(imagePath);
|
|
470
|
+
deletedImages++;
|
|
471
|
+
}
|
|
472
|
+
} catch (error) {
|
|
473
|
+
ctx.logger("maple-drift-bottle").warn(`删除图片文件失败: ${imageName}`, error);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if (deletedImages > 0) {
|
|
479
|
+
ctx.logger("maple-drift-bottle").info(`清空漂流瓶时删除了 ${deletedImages} 张图片文件`);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
276
482
|
await ctx.database.remove("maple-drift-bottles", query);
|
|
277
483
|
return `已成功清空 ${count} 条${description}漂流瓶记录。`;
|
|
278
484
|
} catch (error) {
|
|
@@ -327,11 +533,27 @@ ${failDetails.join("\n")}`;
|
|
|
327
533
|
return "联系漂流瓶管理人时出错了,请稍后再试。";
|
|
328
534
|
}
|
|
329
535
|
});
|
|
330
|
-
ctx.on("ready", () => {
|
|
536
|
+
ctx.on("ready", async () => {
|
|
331
537
|
console.log("maple-drift-bottle 漂流瓶插件已加载完成");
|
|
538
|
+
if (config.saveImagesLocally) {
|
|
539
|
+
if (!(0, import_fs.existsSync)(config.imageSavePath)) {
|
|
540
|
+
await (0, import_promises.mkdir)(config.imageSavePath, { recursive: true });
|
|
541
|
+
ctx.logger("maple-drift-bottle").info(`创建图片保存目录: ${config.imageSavePath}`);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
332
544
|
ctx.logger("maple-drift-bottle").info(`默认匿名设置: ${config.anonymousByDefault ? "是" : "否"}`);
|
|
333
|
-
ctx.logger("maple-drift-bottle").info(`内容最大长度: ${config.maxContentLength}
|
|
545
|
+
ctx.logger("maple-drift-bottle").info(`内容最大长度: ${config.maxContentLength} 字符`);
|
|
334
546
|
ctx.logger("maple-drift-bottle").info(`我的漂流瓶最大预览字数: ${config.maxPreviewLength} 字`);
|
|
547
|
+
ctx.logger("maple-drift-bottle").info(`最大图片数量: ${config.maxImages} 张`);
|
|
548
|
+
ctx.logger("maple-drift-bottle").info(`本地保存图片: ${config.saveImagesLocally ? "是" : "否"}`);
|
|
549
|
+
if (config.saveImagesLocally) {
|
|
550
|
+
ctx.logger("maple-drift-bottle").info(`图片保存路径: ${config.imageSavePath}`);
|
|
551
|
+
ctx.logger("maple-drift-bottle").info(`压缩图片: ${config.compressImages ? "是" : "否"}`);
|
|
552
|
+
if (config.compressImages) {
|
|
553
|
+
ctx.logger("maple-drift-bottle").info(`图片最大尺寸: ${config.maxImageWidth}x${config.maxImageHeight} 像素`);
|
|
554
|
+
ctx.logger("maple-drift-bottle").info(`图片质量: ${config.imageQuality}%`);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
335
557
|
ctx.logger("maple-drift-bottle").info(`管理人QQ: ${config.adminQQ.length > 0 ? config.adminQQ.join(", ") : "未配置"}`);
|
|
336
558
|
});
|
|
337
559
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-maple-drift-bottle",
|
|
3
3
|
"description": "-",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -14,5 +14,8 @@
|
|
|
14
14
|
],
|
|
15
15
|
"peerDependencies": {
|
|
16
16
|
"koishi": "^4.18.7"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"sharp": "^0.33.0"
|
|
17
20
|
}
|
|
18
21
|
}
|