koishi-plugin-maple-drift-bottle 0.0.1

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 ADDED
@@ -0,0 +1,23 @@
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
+ created: Date;
11
+ }
12
+ declare module 'koishi' {
13
+ interface Tables {
14
+ 'maple-drift-bottles': DriftBottle;
15
+ }
16
+ }
17
+ export interface Config {
18
+ anonymousByDefault: boolean;
19
+ maxContentLength: number;
20
+ }
21
+ export declare const Config: Schema<Config>;
22
+ export declare function apply(ctx: Context, config: Config): void;
23
+ export {};
package/lib/index.js ADDED
@@ -0,0 +1,281 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+ var __export = (target, all) => {
7
+ for (var name2 in all)
8
+ __defProp(target, name2, { get: all[name2], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ Config: () => Config,
24
+ apply: () => apply,
25
+ name: () => name,
26
+ using: () => using
27
+ });
28
+ module.exports = __toCommonJS(src_exports);
29
+ var import_koishi = require("koishi");
30
+ var name = "maple-drift-bottle";
31
+ var using = ["database"];
32
+ var Config = import_koishi.Schema.object({
33
+ anonymousByDefault: import_koishi.Schema.boolean().default(false).description("默认是否匿名(true: 匿名,false: 不匿名)"),
34
+ maxContentLength: import_koishi.Schema.number().default(500).min(50).max(2e3).description("漂流瓶内容最大长度(字)(50-2000)")
35
+ });
36
+ function getAuthorDisplay(bottle) {
37
+ return bottle.anonymous ? "匿名" : bottle.authorName;
38
+ }
39
+ __name(getAuthorDisplay, "getAuthorDisplay");
40
+ function formatTime(date) {
41
+ return date.toLocaleString("zh-CN", {
42
+ year: "numeric",
43
+ month: "2-digit",
44
+ day: "2-digit",
45
+ hour: "2-digit",
46
+ minute: "2-digit",
47
+ second: "2-digit"
48
+ });
49
+ }
50
+ __name(formatTime, "formatTime");
51
+ function apply(ctx, config) {
52
+ console.log("maple-drift-bottle 漂流瓶插件加载中...");
53
+ ctx.model.extend("maple-drift-bottles", {
54
+ id: "unsigned",
55
+ author: "string",
56
+ // 用户ID
57
+ authorName: "string",
58
+ // 用户昵称
59
+ anonymous: "boolean",
60
+ // 是否匿名
61
+ content: "text",
62
+ // 漂流瓶内容(text类型,支持长文本)
63
+ created: "timestamp"
64
+ // 创建时间
65
+ }, {
66
+ primary: "id",
67
+ autoInc: true
68
+ });
69
+ ctx.command("漂流瓶", "漂流瓶相关指令").action(({ session }) => {
70
+ return session.execute("help 漂流瓶");
71
+ });
72
+ ctx.command("漂流瓶/捞漂流瓶", "捞取一个随机漂流瓶").alias("捞漂流瓶").alias("随机漂流瓶").example("捞漂流瓶").action(async ({ session }) => {
73
+ try {
74
+ const allBottles = await ctx.database.get("maple-drift-bottles", {});
75
+ if (allBottles.length === 0) {
76
+ return "海里还没有漂流瓶哦,快扔一个吧!";
77
+ }
78
+ const randomIndex = Math.floor(Math.random() * allBottles.length);
79
+ const bottle = allBottles[randomIndex];
80
+ const authorDisplay = getAuthorDisplay(bottle);
81
+ const timeDisplay = formatTime(bottle.created);
82
+ return `【漂流瓶 #${bottle.id}】
83
+ 作者:${authorDisplay}
84
+ 时间:${timeDisplay}
85
+ 内容:
86
+ ${bottle.content}`;
87
+ } catch (error) {
88
+ ctx.logger("maple-drift-bottle").error("捞漂流瓶时出错:", error);
89
+ return "捞取漂流瓶时出错了,请稍后再试。";
90
+ }
91
+ });
92
+ ctx.command("漂流瓶/扔漂流瓶 <content:text>", "扔一个漂流瓶到海里").alias("扔漂流瓶").alias("丢漂流瓶").option("invisible", "-i 匿名发送(不显示发送者)").option("visible", "-v 公开发送(显示发送者)").example("扔漂流瓶 这是一条漂流瓶内容").example("扔漂流瓶 -i 这是一条匿名漂流瓶内容").action(async ({ session, options }, content) => {
93
+ try {
94
+ if (!content || content.trim().length === 0) {
95
+ return "漂流瓶内容不能为空!\n格式:扔漂流瓶 [-i|-v] 内容\n示例:扔漂流瓶 -i 这是一条匿名漂流瓶";
96
+ }
97
+ const trimmedContent = content.trim();
98
+ if (trimmedContent.length > config.maxContentLength) {
99
+ return `漂流瓶内容太长了!最多只能输入${config.maxContentLength}个字(当前: ${trimmedContent.length})。`;
100
+ }
101
+ if (options.invisible && options.visible) {
102
+ return "选项冲突:-i(匿名)和-v(公开)不能同时使用";
103
+ }
104
+ let anonymous = config.anonymousByDefault;
105
+ if (options.invisible) {
106
+ anonymous = true;
107
+ } else if (options.visible) {
108
+ anonymous = false;
109
+ }
110
+ const userInfo = await session.getUser(session.userId);
111
+ const authorName = userInfo?.name || session.username || `用户${session.userId}`;
112
+ const newBottle = await ctx.database.create("maple-drift-bottles", {
113
+ author: session.userId,
114
+ authorName,
115
+ anonymous,
116
+ content: trimmedContent,
117
+ created: /* @__PURE__ */ new Date()
118
+ });
119
+ const anonymousText = anonymous ? "匿名" : "不匿名";
120
+ return `成功扔出一个漂流瓶!
121
+ ID: #${newBottle.id}
122
+ 状态: ${anonymousText}
123
+ 内容已保存到海中,等待有缘人捞取。`;
124
+ } catch (error) {
125
+ ctx.logger("maple-drift-bottle").error("扔漂流瓶时出错:", error);
126
+ return "扔漂流瓶时出错了,请稍后再试。";
127
+ }
128
+ });
129
+ ctx.command("漂流瓶/我的漂流瓶 [page:number]", "查看我发送的所有漂流瓶").alias("我的漂流瓶").alias("我的瓶子").example("我的漂流瓶").example("我的漂流瓶 2").action(async ({ session }, page = 1) => {
130
+ try {
131
+ if (page < 1) {
132
+ return "页码必须是正整数!";
133
+ }
134
+ const userBottles = await ctx.database.get("maple-drift-bottles", {
135
+ author: session.userId
136
+ });
137
+ if (userBottles.length === 0) {
138
+ return '你还没有扔过任何漂流瓶哦!\n使用"扔漂流瓶"指令扔一个吧。';
139
+ }
140
+ userBottles.sort((a, b) => b.created.getTime() - a.created.getTime());
141
+ const pageSize = 10;
142
+ const totalPages = Math.ceil(userBottles.length / pageSize);
143
+ if (page > totalPages) {
144
+ return `你只有 ${totalPages} 页漂流瓶记录,请输入 1-${totalPages} 之间的页码。`;
145
+ }
146
+ const startIndex = (page - 1) * pageSize;
147
+ const endIndex = Math.min(startIndex + pageSize, userBottles.length);
148
+ const currentPageBottles = userBottles.slice(startIndex, endIndex);
149
+ let output = `【我的漂流瓶】第 ${page}/${totalPages} 页(共 ${userBottles.length} 条)
150
+
151
+ `;
152
+ currentPageBottles.forEach((bottle, index) => {
153
+ const displayIndex = startIndex + index + 1;
154
+ const timeDisplay = formatTime(bottle.created);
155
+ const anonymousText = bottle.anonymous ? "(匿名)" : "";
156
+ output += `${displayIndex}. 漂流瓶 #${bottle.id} ${anonymousText} - ${timeDisplay}
157
+ `;
158
+ });
159
+ output += "\n──────────────\n";
160
+ if (page > 1) {
161
+ output += `输入"我的漂流瓶 ${page - 1}"查看上一页
162
+ `;
163
+ }
164
+ if (page < totalPages) {
165
+ output += `输入"我的漂流瓶 ${page + 1}"查看下一页
166
+ `;
167
+ }
168
+ output += `输入"查看漂流瓶 序号"查看具体内容`;
169
+ return output.trim();
170
+ } catch (error) {
171
+ ctx.logger("maple-drift-bottle").error("查看我的漂流瓶时出错:", error);
172
+ return "查看漂流瓶时出错了,请稍后再试。";
173
+ }
174
+ });
175
+ ctx.command("漂流瓶/查看漂流瓶 [id:number]", "查看特定的漂流瓶内容").alias("查看漂流瓶").alias("查看瓶子").option("all", "-a 查看任意漂流瓶(不受作者限制)").example("查看漂流瓶 1").example("查看漂流瓶 -a 1").action(async ({ session, options }, id) => {
176
+ try {
177
+ if (!id) {
178
+ return '请提供漂流瓶序号!\n格式:查看漂流瓶 序号\n可以发送"我的漂流瓶"查看你发送的所有漂流瓶序号。';
179
+ }
180
+ const bottles = await ctx.database.get("maple-drift-bottles", { id });
181
+ if (bottles.length === 0) {
182
+ return `没有找到ID为 #${id} 的漂流瓶。
183
+ 可以发送"我的漂流瓶"查看你发送的所有漂流瓶序号。`;
184
+ }
185
+ const bottle = bottles[0];
186
+ if (!options.all && bottle.author !== session.userId) {
187
+ return `仅可查看由你自己发送的漂流瓶。
188
+ 可以发送"我的漂流瓶"查看你发送的所有漂流瓶序号。`;
189
+ }
190
+ const authorDisplay = getAuthorDisplay(bottle);
191
+ const timeDisplay = formatTime(bottle.created);
192
+ return `【漂流瓶 #${bottle.id}】
193
+ 作者:${authorDisplay}
194
+ 时间:${timeDisplay}
195
+ 状态:${bottle.anonymous ? "匿名" : "公开"}
196
+ 内容:
197
+ ${bottle.content}`;
198
+ } catch (error) {
199
+ ctx.logger("maple-drift-bottle").error("查看漂流瓶时出错:", error);
200
+ return "查看漂流瓶时出错了,请稍后再试。";
201
+ }
202
+ });
203
+ ctx.command("漂流瓶/删除漂流瓶 [id:number]", "删除漂流瓶").alias("删除漂流瓶").alias("删除瓶子").option("all", "-a 删除任意漂流瓶(不受作者限制)").example("删除漂流瓶 1").example("删除漂流瓶 -a 1").action(async ({ session, options }, id) => {
204
+ try {
205
+ if (!id) {
206
+ return '请提供漂流瓶序号!\n格式:删除漂流瓶 序号\n可以发送"我的漂流瓶"查看你发送的所有漂流瓶序号。';
207
+ }
208
+ const bottles = await ctx.database.get("maple-drift-bottles", { id });
209
+ if (bottles.length === 0) {
210
+ return `没有找到ID为 #${id} 的漂流瓶。
211
+ 可以发送"我的漂流瓶"查看你发送的所有漂流瓶序号。`;
212
+ }
213
+ const bottle = bottles[0];
214
+ if (!options.all && bottle.author !== session.userId) {
215
+ return `仅可删除由你自己发送的漂流瓶。
216
+ 可以发送"我的漂流瓶"查看你发送的所有漂流瓶序号。`;
217
+ }
218
+ const authorDisplay = getAuthorDisplay(bottle);
219
+ const timeDisplay = formatTime(bottle.created);
220
+ const contentPreview = bottle.content.length > 50 ? bottle.content.substring(0, 50) + "..." : bottle.content;
221
+ await ctx.database.remove("maple-drift-bottles", { id });
222
+ return `已成功删除漂流瓶 #${id}
223
+ 作者:${authorDisplay}
224
+ 时间:${timeDisplay}
225
+ 内容预览:${contentPreview}`;
226
+ } catch (error) {
227
+ ctx.logger("maple-drift-bottle").error("删除漂流瓶时出错:", error);
228
+ return "删除漂流瓶时出错了,请稍后再试。";
229
+ }
230
+ });
231
+ ctx.command("漂流瓶/清空漂流瓶 [options]", "清空漂流瓶").alias("清空漂流瓶").alias("清空瓶子").option("all", "-a 清空所有漂流瓶(默认)").option("user", "-u <userId:string> 清空指定用户的所有漂流瓶").option("date", "-d <date:string> 清空指定日期之前的漂流瓶(格式: yyyy-mm-dd)").example("清空漂流瓶").example("清空漂流瓶 -u 123456").action(async ({ session, options }) => {
232
+ try {
233
+ const query = {};
234
+ let description = "";
235
+ if (options.user) {
236
+ query.author = options.user;
237
+ description += `用户 ${options.user} 的`;
238
+ }
239
+ if (options.date) {
240
+ const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
241
+ if (!dateRegex.test(options.date)) {
242
+ return "日期格式不正确,请使用 yyyy-mm-dd 格式,例如:2023-12-31";
243
+ }
244
+ const targetDate = new Date(options.date);
245
+ if (isNaN(targetDate.getTime())) {
246
+ return "日期格式不正确,请使用有效的日期,例如:2023-12-31";
247
+ }
248
+ query.created = { $lt: targetDate };
249
+ description += `${options.date} 之前的`;
250
+ }
251
+ if (!options.user && !options.date) {
252
+ description = "所有";
253
+ } else if (!description) {
254
+ description = "符合条件的";
255
+ }
256
+ const bottles = await ctx.database.get("maple-drift-bottles", query);
257
+ const count = bottles.length;
258
+ if (count === 0) {
259
+ return `没有找到${description}漂流瓶。`;
260
+ }
261
+ await ctx.database.remove("maple-drift-bottles", query);
262
+ return `已成功清空 ${count} 条${description}漂流瓶记录。`;
263
+ } catch (error) {
264
+ ctx.logger("maple-drift-bottle").error("清空漂流瓶时出错:", error);
265
+ return "清空漂流瓶时出错了,请稍后再试。";
266
+ }
267
+ });
268
+ ctx.on("ready", () => {
269
+ console.log("maple-drift-bottle 漂流瓶插件已加载完成");
270
+ ctx.logger("maple-drift-bottle").info(`默认匿名设置: ${config.anonymousByDefault ? "是" : "否"}`);
271
+ ctx.logger("maple-drift-bottle").info(`内容最大长度: ${config.maxContentLength} 字`);
272
+ });
273
+ }
274
+ __name(apply, "apply");
275
+ // Annotate the CommonJS export names for ESM import in node:
276
+ 0 && (module.exports = {
277
+ Config,
278
+ apply,
279
+ name,
280
+ using
281
+ });
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "koishi-plugin-maple-drift-bottle",
3
+ "description": "-",
4
+ "version": "0.0.1",
5
+ "main": "lib/index.js",
6
+ "typings": "lib/index.d.ts",
7
+ "files": [
8
+ "lib",
9
+ "dist"
10
+ ],
11
+ "koishi": {
12
+ "service": {
13
+ "required": ["database"]
14
+ }
15
+ },
16
+ "license": "MIT",
17
+ "keywords": [
18
+ "maple"
19
+ ],
20
+ "peerDependencies": {
21
+ "koishi": "^4.18.7"
22
+ }
23
+ }
package/readme.md ADDED
@@ -0,0 +1,5 @@
1
+ # koishi-plugin-maple-drift-bottle
2
+
3
+ [![npm](https://img.shields.io/npm/v/koishi-plugin-maple-drift-bottle?style=flat-square)](https://www.npmjs.com/package/koishi-plugin-maple-drift-bottle)
4
+
5
+ -