koishi-plugin-noah 2.4.0 → 2.4.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.
@@ -0,0 +1,6 @@
1
+ import { Context } from 'koishi';
2
+ /**
3
+ * 注册 poke 命令:主动戳一戳目标用户
4
+ * @param ctx - koishi 上下文
5
+ */
6
+ export declare function registerPokeCommand(ctx: Context): void;
@@ -0,0 +1,6 @@
1
+ import { Context } from 'koishi';
2
+ /**
3
+ * 注册 stamp 命令:手动发送随机贴纸
4
+ * @param ctx - koishi 上下文
5
+ */
6
+ export declare function registerStampCommand(ctx: Context): void;
@@ -0,0 +1,10 @@
1
+ /** 支持的图片扩展名 */
2
+ export declare const IMAGE_EXTENSIONS: readonly [".png", ".jpg", ".jpeg", ".gif", ".webp"];
3
+ /** 扩展名到 MIME 类型的映射 */
4
+ export declare const MIME_MAP: Record<string, string>;
5
+ /** MIME 类型兜底值 */
6
+ export declare const DEFAULT_MIME = "image/png";
7
+ /** tip 缺省语言(用户无匹配偏好时使用) */
8
+ export declare const DEFAULT_LOCALE = "zh-CN";
9
+ /** 被戳时 text 类型随机抽取的提示池(按语言区分) */
10
+ export declare const TIP_POOL: Record<string, string[]>;
@@ -0,0 +1,9 @@
1
+ import { Context } from 'koishi';
2
+ import { PokeConfig } from '../../../types/config';
3
+ /**
4
+ * 注册被戳事件处理:命中冷却发警告,否则按权重分发文本/贴纸
5
+ * @param ctx - koishi 上下文
6
+ * @param config - 戳一戳配置
7
+ * @param cache - 用户 -> 上次触发时间戳的冷却缓存
8
+ */
9
+ export declare function registerPokeNotice(ctx: Context, config: PokeConfig, cache: Map<string, number>): void;
@@ -1,4 +1,5 @@
1
- import { Context } from 'koishi';
1
+ import { Context, Logger } from 'koishi';
2
2
  import { AppConfig } from '../../types/config';
3
3
  export declare const name = "Noah-Poke";
4
+ export declare const logger: Logger;
4
5
  export declare function apply(ctx: Context, config: AppConfig): void;
@@ -6,7 +6,12 @@ declare module 'koishi' {
6
6
  targetId: string;
7
7
  }
8
8
  }
9
+ export type MessageReplyType = 'text' | 'noah' | 'chat';
9
10
  export interface MessageReply {
11
+ type: MessageReplyType;
12
+ weight: number;
13
+ }
14
+ export interface PromptReply {
10
15
  content: string;
11
16
  weight: number;
12
17
  }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 判断文件是否为图片
3
+ * @param filename - 文件名
4
+ * @returns 是否为支持的图片格式
5
+ */
6
+ export declare function isImageFile(filename: string): boolean;
7
+ /**
8
+ * 根据文件名获取 MIME 类型
9
+ * @param filename - 文件名
10
+ * @returns MIME 类型,未匹配时返回兜底值
11
+ */
12
+ export declare function getMimeType(filename: string): string;
13
+ /**
14
+ * 查找贴纸图片对应的语音文件
15
+ * @param imagePath - 贴纸图片完整路径(如 .../stamp_0384_01.png)
16
+ * @returns 匹配的音频文件路径(如 .../xxx-1.mp3),未找到返回 null
17
+ */
18
+ export declare function findMatchingAudio(imagePath: string): string | null;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 按权重随机选取一项
3
+ * @param items - 带 weight 字段的数组
4
+ * @returns 命中的元素,空数组时返回 undefined
5
+ */
6
+ export declare function randomMessage<T extends {
7
+ weight: number;
8
+ }>(items: T[]): T | undefined;
9
+ /**
10
+ * 从数组中等概率随机取一项
11
+ * @param items - 任意数组
12
+ * @returns 随机元素,空数组时返回 undefined
13
+ */
14
+ export declare function pickRandom<T>(items: T[]): T | undefined;
@@ -0,0 +1,14 @@
1
+ import { Context, h, Session } from 'koishi';
2
+ /**
3
+ * 随机发送一个 noah 贴纸(文件夹形式,可附带语音)
4
+ * @param ctx - koishi 上下文
5
+ * @param session - 当前会话
6
+ * @param voiceOnly - 是否仅选取带语音的贴纸
7
+ */
8
+ export declare function sendRandomNoahStamp(ctx: Context, session: Session, voiceOnly?: boolean): Promise<void>;
9
+ /**
10
+ * 随机选取一个 chat 贴纸(直接图片形式)
11
+ * @param ctx - koishi 上下文
12
+ * @returns 图片消息元素,失败时返回错误文本
13
+ */
14
+ export declare function getRandomChatStamp(ctx: Context): h | string;
@@ -0,0 +1,10 @@
1
+ import { Session } from 'koishi';
2
+ /**
3
+ * 根据用户偏好语言随机选取一条 tip
4
+ *
5
+ * 按用户的 locales(偏好语言顺序)依次匹配 TIP_POOL,
6
+ * 命中首个有内容的语言;都不匹配时回退到默认语言。
7
+ * @param session - 当前会话
8
+ * @returns 随机 tip 文本,无可用 tip 时返回 undefined
9
+ */
10
+ export declare function pickTip(session: Session): Promise<string | undefined>;
package/lib/index.cjs CHANGED
@@ -1115,8 +1115,8 @@ function registerApiRoutes(ctx, apiCtx) {
1115
1115
  "/noah/api/resolve",
1116
1116
  "/noah/api/health"
1117
1117
  ];
1118
- for (const path3 of apiPaths) {
1119
- ctx.server.all(path3, async (kctx, next) => {
1118
+ for (const path4 of apiPaths) {
1119
+ ctx.server.all(path4, async (kctx, next) => {
1120
1120
  setCors(kctx);
1121
1121
  if (kctx.method === "OPTIONS") {
1122
1122
  kctx.status = 204;
@@ -3331,8 +3331,8 @@ var SDVXDrawer = class extends BaseDrawer {
3331
3331
  ["Fredoka One", "fonts/FredokaOne.ttf"]
3332
3332
  ];
3333
3333
  for (const [name15, file] of fonts) {
3334
- const path3 = getAssetPath(this.ctx, file);
3335
- if (fs2.existsSync(path3)) FontLibrary.use(name15, path3);
3334
+ const path4 = getAssetPath(this.ctx, file);
3335
+ if (fs2.existsSync(path4)) FontLibrary.use(name15, path4);
3336
3336
  }
3337
3337
  this.fontsLoaded = true;
3338
3338
  }
@@ -3438,20 +3438,20 @@ var SDVXDrawer = class extends BaseDrawer {
3438
3438
  ctx.save();
3439
3439
  ctx.translate(556, 17);
3440
3440
  ctx.beginPath();
3441
- const r = 16, w = 100, h11 = 200, x0 = 0, y0 = 0;
3441
+ const r = 16, w = 100, h12 = 200, x0 = 0, y0 = 0;
3442
3442
  ctx.moveTo(x0 + r, y0);
3443
3443
  ctx.lineTo(x0 + w - r, y0);
3444
3444
  ctx.arcTo(x0 + w, y0, x0 + w, y0 + r, r);
3445
- ctx.lineTo(x0 + w, y0 + h11 - r);
3446
- ctx.arcTo(x0 + w, y0 + h11, x0 + w - r, y0 + h11, r);
3447
- ctx.lineTo(x0 + r, y0 + h11);
3448
- ctx.arcTo(x0, y0 + h11, x0, y0 + h11 - r, r);
3445
+ ctx.lineTo(x0 + w, y0 + h12 - r);
3446
+ ctx.arcTo(x0 + w, y0 + h12, x0 + w - r, y0 + h12, r);
3447
+ ctx.lineTo(x0 + r, y0 + h12);
3448
+ ctx.arcTo(x0, y0 + h12, x0, y0 + h12 - r, r);
3449
3449
  ctx.lineTo(x0, y0 + r);
3450
3450
  ctx.arcTo(x0, y0, x0 + r, y0, r);
3451
3451
  ctx.closePath();
3452
3452
  const circleRadius = 14;
3453
3453
  const circleX = x0 + w;
3454
- const circleY = y0 + h11 / 2;
3454
+ const circleY = y0 + h12 / 2;
3455
3455
  ctx.moveTo(circleX + circleRadius, circleY);
3456
3456
  ctx.arc(circleX, circleY, circleRadius, 0, Math.PI * 2, true);
3457
3457
  ctx.clip();
@@ -4280,154 +4280,20 @@ __name(apply6, "apply");
4280
4280
  var poke_exports = {};
4281
4281
  __export(poke_exports, {
4282
4282
  apply: () => apply7,
4283
+ logger: () => logger3,
4283
4284
  name: () => name7
4284
4285
  });
4285
- var fs3 = __toESM(require("fs"), 1);
4286
- var path2 = __toESM(require("path"), 1);
4287
- var import_koishi8 = require("koishi");
4288
-
4289
- // src/fun/poke/locales/en-US.yml
4290
- var en_US_default3 = { _config: { $desc: "Poke Module Settings", interval: "最小触发间隔(毫秒)", warning: "频繁触发是否发送警告", prompt: "警告内容", messages: { $desc: "消息内容", content: "消息内容", weight: "权重" } }, commands: { poke: { description: "poke" } } };
4291
-
4292
- // src/fun/poke/locales/zh-CN.yml
4293
- var zh_CN_default3 = { _config: { $desc: "Poke 模块设置", interval: "最小触发间隔(毫秒)", warning: "频繁触发是否发送警告", prompt: { $desc: "警告内容", content: "消息", weight: "权重" }, messages: { $desc: "消息内容", content: "消息", weight: "权重" } }, commands: { poke: { description: "戳一戳" } } };
4286
+ var import_koishi10 = require("koishi");
4294
4287
 
4295
- // src/fun/poke/index.ts
4296
- var name7 = "Noah-Poke";
4297
- function apply7(ctx, config) {
4298
- ;
4299
- [
4300
- ["en-US", en_US_default3],
4301
- ["zh-CN", zh_CN_default3]
4302
- ].forEach(([lang, file]) => ctx.i18n.define(lang, file));
4303
- const cache = /* @__PURE__ */ new Map();
4304
- const pokeConfig2 = config.poke;
4305
- const IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".gif", ".webp"];
4306
- function isImageFile(filename) {
4307
- const ext = path2.extname(filename).toLowerCase();
4308
- return IMAGE_EXTENSIONS.includes(ext);
4309
- }
4310
- __name(isImageFile, "isImageFile");
4311
- function getMimeType(filename) {
4312
- const ext = path2.extname(filename).toLowerCase();
4313
- switch (ext) {
4314
- case ".png":
4315
- return "image/png";
4316
- case ".jpg":
4317
- case ".jpeg":
4318
- return "image/jpeg";
4319
- case ".gif":
4320
- return "image/gif";
4321
- case ".webp":
4322
- return "image/webp";
4323
- default:
4324
- return "image/png";
4325
- }
4326
- }
4327
- __name(getMimeType, "getMimeType");
4328
- function findMatchingAudio(imagePath) {
4329
- try {
4330
- const dir = path2.dirname(imagePath);
4331
- const filename = path2.basename(imagePath);
4332
- const match = filename.match(/_(\d+)\.(png|jpg|jpeg|gif|webp)$/i);
4333
- if (!match) {
4334
- return null;
4335
- }
4336
- const imageNumber = match[1];
4337
- const audioNumber = parseInt(imageNumber, 10).toString();
4338
- const files = fs3.readdirSync(dir);
4339
- const audioFile = files.find((file) => {
4340
- return file.endsWith(`-${audioNumber}.mp3`);
4341
- });
4342
- return audioFile ? path2.join(dir, audioFile) : null;
4343
- } catch {
4344
- return null;
4345
- }
4346
- }
4347
- __name(findMatchingAudio, "findMatchingAudio");
4348
- async function sendRandomNoahStamp(ctx2, session, voiceOnly = false) {
4349
- try {
4350
- const stampsPath = getAssetPath(ctx2, "stamps/noah_stamp");
4351
- const stampDirs = fs3.readdirSync(stampsPath).filter((dir) => dir.startsWith("stamp_"));
4352
- if (stampDirs.length === 0) {
4353
- await session.sendQueued("No stamps found!");
4354
- return;
4355
- }
4356
- const allStamps = [];
4357
- for (const dir of stampDirs) {
4358
- const stampDirPath = path2.join(stampsPath, dir);
4359
- const stampFiles = fs3.readdirSync(stampDirPath).filter((file) => file.startsWith(dir) && isImageFile(file));
4360
- stampFiles.forEach((file) => {
4361
- allStamps.push({
4362
- path: path2.join(stampDirPath, file),
4363
- dirName: dir
4364
- });
4365
- });
4366
- }
4367
- if (allStamps.length === 0) {
4368
- await session.sendQueued("No stamps found in any directory!");
4369
- return;
4370
- }
4371
- let availableStamps = allStamps;
4372
- if (voiceOnly) {
4373
- availableStamps = allStamps.filter((stamp) => {
4374
- const audioPath2 = findMatchingAudio(stamp.path);
4375
- return audioPath2 && fs3.existsSync(audioPath2);
4376
- });
4377
- if (availableStamps.length === 0) {
4378
- await session.sendQueued("No stamps with voice found!");
4379
- return;
4380
- }
4381
- }
4382
- const randomStamp = availableStamps[Math.floor(Math.random() * availableStamps.length)];
4383
- ctx2.logger("Noah-Poke").debug(`Selected stamp from ${randomStamp.dirName}`);
4384
- if (!fs3.existsSync(randomStamp.path)) {
4385
- await session.sendQueued("Selected stamp not found!");
4386
- return;
4387
- }
4388
- const imageBuffer = fs3.readFileSync(randomStamp.path);
4389
- const audioPath = findMatchingAudio(randomStamp.path);
4390
- await session.sendQueued(import_koishi8.h.image(imageBuffer, getMimeType(randomStamp.path)));
4391
- if (audioPath && fs3.existsSync(audioPath)) {
4392
- ctx2.logger("Noah-Poke").debug(`Found matching audio: ${path2.basename(audioPath)}`);
4393
- const audioBuffer = fs3.readFileSync(audioPath);
4394
- await session.sendQueued(import_koishi8.h.audio(audioBuffer, "audio/mpeg"));
4395
- }
4396
- } catch (error) {
4397
- ctx2.logger("Noah-Poke").error(`Error sending noah stamp: ${error.message}`);
4398
- await session.sendQueued("Failed to send noah stamp.");
4399
- }
4400
- }
4401
- __name(sendRandomNoahStamp, "sendRandomNoahStamp");
4402
- async function sendRandomChatStamp(ctx2) {
4403
- try {
4404
- const stampsPath = getAssetPath(ctx2, "stamps/chat_stamp");
4405
- const stampFiles = fs3.readdirSync(stampsPath).filter((file) => isImageFile(file));
4406
- if (stampFiles.length === 0) {
4407
- return "No chat stamps found!";
4408
- }
4409
- const randomStamp = stampFiles[Math.floor(Math.random() * stampFiles.length)];
4410
- const stampPath = path2.join(stampsPath, randomStamp);
4411
- if (!fs3.existsSync(stampPath)) {
4412
- return "Selected stamp not found!";
4413
- }
4414
- const imageBuffer = fs3.readFileSync(stampPath);
4415
- return import_koishi8.h.image(imageBuffer, getMimeType(stampPath));
4416
- } catch (error) {
4417
- ctx2.logger("Noah-Poke").error(`Error sending chat stamp: ${error.message}`);
4418
- return "Failed to send chat stamp.";
4419
- }
4420
- }
4421
- __name(sendRandomChatStamp, "sendRandomChatStamp");
4422
- ctx.command("stamp").option("type", "-t [type]").option("voice", "-v", { fallback: false }).action(async ({ session, options }) => {
4423
- if (options.type == "noah") {
4424
- await sendRandomNoahStamp(ctx, session, options.voice);
4425
- } else if (options.type == "chat") {
4426
- return sendRandomChatStamp(ctx);
4427
- } else {
4428
- return sendRandomChatStamp(ctx);
4429
- }
4430
- });
4288
+ // src/fun/poke/commands/poke.ts
4289
+ function parsePlatform(target) {
4290
+ const index = target.indexOf(":");
4291
+ const platform = target.slice(0, index);
4292
+ const id = target.slice(index + 1);
4293
+ return [platform, id];
4294
+ }
4295
+ __name(parsePlatform, "parsePlatform");
4296
+ function registerPokeCommand(ctx) {
4431
4297
  ctx.platform("onebot").command("poke [target:user]").action(async ({ session }, target) => {
4432
4298
  if (!session.onebot) {
4433
4299
  return;
@@ -4435,7 +4301,7 @@ function apply7(ctx, config) {
4435
4301
  const params = { user_id: session.userId };
4436
4302
  if (target) {
4437
4303
  const [platform, id] = parsePlatform(target);
4438
- if (platform != "onebot") {
4304
+ if (platform !== "onebot") {
4439
4305
  return;
4440
4306
  }
4441
4307
  params.user_id = id;
@@ -4443,66 +4309,292 @@ function apply7(ctx, config) {
4443
4309
  if (session.isDirect) {
4444
4310
  await session.onebot._request("friend_poke", params);
4445
4311
  } else {
4446
- params["group_id"] = session.guildId;
4312
+ params.group_id = session.guildId;
4447
4313
  await session.onebot._request("group_poke", params);
4448
4314
  }
4449
4315
  });
4450
- ctx.platform("onebot").on("notice", async (session) => {
4451
- if (session.subtype != "poke") {
4316
+ }
4317
+ __name(registerPokeCommand, "registerPokeCommand");
4318
+
4319
+ // src/fun/poke/utils/stamp.ts
4320
+ var fs4 = __toESM(require("fs"), 1);
4321
+ var path3 = __toESM(require("path"), 1);
4322
+ var import_koishi8 = require("koishi");
4323
+
4324
+ // src/fun/poke/utils/file.ts
4325
+ var fs3 = __toESM(require("fs"), 1);
4326
+ var path2 = __toESM(require("path"), 1);
4327
+
4328
+ // src/fun/poke/constants.ts
4329
+ var IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".gif", ".webp"];
4330
+ var MIME_MAP = {
4331
+ ".png": "image/png",
4332
+ ".jpg": "image/jpeg",
4333
+ ".jpeg": "image/jpeg",
4334
+ ".gif": "image/gif",
4335
+ ".webp": "image/webp"
4336
+ };
4337
+ var DEFAULT_MIME = "image/png";
4338
+ var DEFAULT_LOCALE = "zh-CN";
4339
+ var TIP_POOL = {
4340
+ "zh-CN": [
4341
+ "你知道吗: 《FIN4LE ~終止線の彼方へ~》在发布 337 天后才出现首个 PUC。",
4342
+ "你知道吗: Near 是双子中的姐姐哟~",
4343
+ "你知道吗: Noah 是双子中的妹妹哟~",
4344
+ "你知道吗: 可以看刘海方向来区分 Near 和 Noah。",
4345
+ "你知道吗: Near 和 Noah 就读于ボルテ学園初等部。",
4346
+ "你知道吗: 元气满满的是姐姐 Near,文静的是妹妹 Noah。",
4347
+ "你知道吗: Near 和 Noah 的兔子鞋是烈风刀送给她们的。",
4348
+ "你知道吗: Near 和 Noah 都会飞哟~",
4349
+ "你知道吗: Near 和 Noah 初登场于 BOOTH 代歌曲《freaky freak》。",
4350
+ "你知道吗: Near 和 Noah 的 CV 为 日高里菜。",
4351
+ "你知道吗: Near 和 Noah 的身高是 140 cm。",
4352
+ "你知道吗: Near 和 Noah 的生日是 6 月 10 日。"
4353
+ ],
4354
+ "en-US": [
4355
+ "Do you know: FIN4LE ~終止線の彼方へ~ took 337 days to get its first PUC.",
4356
+ "Do you know: Near is the older sister of the twin.",
4357
+ "Do you know: Noah is the younger sister of the twin.",
4358
+ "Do you know: You can tell Near and Noah apart by their hair direction.",
4359
+ "Do you know: Near and Noah attend ボルテ学園初等部.",
4360
+ "Do you know: The energetic Near is the older sister, while the quiet Noah is the younger sister.",
4361
+ "Do you know: Near and Noah received their rabbit shoes from 烈风刀.",
4362
+ "Do you know: Near and Noah can fly.",
4363
+ 'Do you know: Near and Noah made their debut in the BOOTH song "freaky freak".',
4364
+ "Do you know: Near and Noah's CV is 日高里菜.",
4365
+ "Do you know: Near and Noah's height is 140 cm.",
4366
+ "Do you know: Near and Noah's birthday is June 10th."
4367
+ ]
4368
+ };
4369
+
4370
+ // src/fun/poke/utils/file.ts
4371
+ function isImageFile(filename) {
4372
+ const ext = path2.extname(filename).toLowerCase();
4373
+ return IMAGE_EXTENSIONS.includes(ext);
4374
+ }
4375
+ __name(isImageFile, "isImageFile");
4376
+ function getMimeType(filename) {
4377
+ const ext = path2.extname(filename).toLowerCase();
4378
+ return MIME_MAP[ext] ?? DEFAULT_MIME;
4379
+ }
4380
+ __name(getMimeType, "getMimeType");
4381
+ function findMatchingAudio(imagePath) {
4382
+ try {
4383
+ const dir = path2.dirname(imagePath);
4384
+ const filename = path2.basename(imagePath);
4385
+ const match = filename.match(/_(\d+)\.(png|jpg|jpeg|gif|webp)$/i);
4386
+ if (!match) {
4387
+ return null;
4388
+ }
4389
+ const audioNumber = parseInt(match[1], 10).toString();
4390
+ const files = fs3.readdirSync(dir);
4391
+ const audioFile = files.find((file) => file.endsWith(`-${audioNumber}.mp3`));
4392
+ return audioFile ? path2.join(dir, audioFile) : null;
4393
+ } catch {
4394
+ return null;
4395
+ }
4396
+ }
4397
+ __name(findMatchingAudio, "findMatchingAudio");
4398
+
4399
+ // src/fun/poke/utils/random.ts
4400
+ function randomMessage(items) {
4401
+ if (items.length === 0) {
4402
+ return void 0;
4403
+ }
4404
+ const totalWeight = items.reduce((sum2, cur) => sum2 + cur.weight, 0);
4405
+ const random = Math.random() * totalWeight;
4406
+ let sum = 0;
4407
+ for (const item of items) {
4408
+ sum += item.weight;
4409
+ if (random < sum) return item;
4410
+ }
4411
+ return items[items.length - 1];
4412
+ }
4413
+ __name(randomMessage, "randomMessage");
4414
+ function pickRandom(items) {
4415
+ if (items.length === 0) {
4416
+ return void 0;
4417
+ }
4418
+ return items[Math.floor(Math.random() * items.length)];
4419
+ }
4420
+ __name(pickRandom, "pickRandom");
4421
+
4422
+ // src/fun/poke/utils/stamp.ts
4423
+ var LOGGER_NAME = "Noah-Poke";
4424
+ function collectNoahStamps(stampsPath) {
4425
+ const stampDirs = fs4.readdirSync(stampsPath).filter((dir) => dir.startsWith("stamp_"));
4426
+ const allStamps = [];
4427
+ for (const dir of stampDirs) {
4428
+ const stampDirPath = path3.join(stampsPath, dir);
4429
+ const stampFiles = fs4.readdirSync(stampDirPath).filter((file) => file.startsWith(dir) && isImageFile(file));
4430
+ stampFiles.forEach((file) => {
4431
+ allStamps.push({ path: path3.join(stampDirPath, file), dirName: dir });
4432
+ });
4433
+ }
4434
+ return allStamps;
4435
+ }
4436
+ __name(collectNoahStamps, "collectNoahStamps");
4437
+ async function sendRandomNoahStamp(ctx, session, voiceOnly = false) {
4438
+ const logger6 = ctx.logger(LOGGER_NAME);
4439
+ try {
4440
+ const stampsPath = getAssetPath(ctx, "stamps/noah_stamp");
4441
+ const allStamps = collectNoahStamps(stampsPath);
4442
+ if (allStamps.length === 0) {
4443
+ await session.sendQueued("No stamps found!");
4444
+ return;
4445
+ }
4446
+ const availableStamps = voiceOnly ? allStamps.filter((stamp) => {
4447
+ const audioPath2 = findMatchingAudio(stamp.path);
4448
+ return audioPath2 && fs4.existsSync(audioPath2);
4449
+ }) : allStamps;
4450
+ if (availableStamps.length === 0) {
4451
+ await session.sendQueued("No stamps with voice found!");
4452
+ return;
4453
+ }
4454
+ const randomStamp = pickRandom(availableStamps);
4455
+ logger6.debug(`Selected stamp from ${randomStamp.dirName}`);
4456
+ if (!fs4.existsSync(randomStamp.path)) {
4457
+ await session.sendQueued("Selected stamp not found!");
4452
4458
  return;
4453
4459
  }
4454
- if (session.targetId != session.selfId) {
4460
+ const imageBuffer = fs4.readFileSync(randomStamp.path);
4461
+ await session.sendQueued(import_koishi8.h.image(imageBuffer, getMimeType(randomStamp.path)));
4462
+ const audioPath = findMatchingAudio(randomStamp.path);
4463
+ if (audioPath && fs4.existsSync(audioPath)) {
4464
+ logger6.debug(`Found matching audio: ${path3.basename(audioPath)}`);
4465
+ const audioBuffer = fs4.readFileSync(audioPath);
4466
+ await session.sendQueued(import_koishi8.h.audio(audioBuffer, "audio/mpeg"));
4467
+ }
4468
+ } catch (error) {
4469
+ logger6.error(`Error sending noah stamp: ${error.message}`);
4470
+ await session.sendQueued("Failed to send noah stamp.");
4471
+ }
4472
+ }
4473
+ __name(sendRandomNoahStamp, "sendRandomNoahStamp");
4474
+ function getRandomChatStamp(ctx) {
4475
+ const logger6 = ctx.logger(LOGGER_NAME);
4476
+ try {
4477
+ const stampsPath = getAssetPath(ctx, "stamps/chat_stamp");
4478
+ const stampFiles = fs4.readdirSync(stampsPath).filter((file) => isImageFile(file));
4479
+ if (stampFiles.length === 0) {
4480
+ return "No chat stamps found!";
4481
+ }
4482
+ const randomStamp = pickRandom(stampFiles);
4483
+ const stampPath = path3.join(stampsPath, randomStamp);
4484
+ if (!fs4.existsSync(stampPath)) {
4485
+ return "Selected stamp not found!";
4486
+ }
4487
+ const imageBuffer = fs4.readFileSync(stampPath);
4488
+ return import_koishi8.h.image(imageBuffer, getMimeType(stampPath));
4489
+ } catch (error) {
4490
+ logger6.error(`Error sending chat stamp: ${error.message}`);
4491
+ return "Failed to send chat stamp.";
4492
+ }
4493
+ }
4494
+ __name(getRandomChatStamp, "getRandomChatStamp");
4495
+
4496
+ // src/fun/poke/commands/stamp.ts
4497
+ function registerStampCommand(ctx) {
4498
+ ctx.command("stamp").option("type", "-t [type]").option("voice", "-v", { fallback: false }).action(async ({ session, options }) => {
4499
+ if (options.type === "noah") {
4500
+ await sendRandomNoahStamp(ctx, session, options.voice);
4501
+ return;
4502
+ }
4503
+ return getRandomChatStamp(ctx);
4504
+ });
4505
+ }
4506
+ __name(registerStampCommand, "registerStampCommand");
4507
+
4508
+ // src/fun/poke/events/notice.ts
4509
+ var import_koishi9 = require("koishi");
4510
+
4511
+ // src/fun/poke/utils/tip.ts
4512
+ async function pickTip(session) {
4513
+ const user = await session.observeUser(["locales"]);
4514
+ const locales = user.locales ?? [];
4515
+ for (const locale2 of locales) {
4516
+ const tips = TIP_POOL[locale2];
4517
+ if (tips && tips.length > 0) {
4518
+ return pickRandom(tips);
4519
+ }
4520
+ }
4521
+ return pickRandom(TIP_POOL[DEFAULT_LOCALE] ?? []);
4522
+ }
4523
+ __name(pickTip, "pickTip");
4524
+
4525
+ // src/fun/poke/events/notice.ts
4526
+ function registerPokeNotice(ctx, config, cache) {
4527
+ ctx.platform("onebot").on("notice", async (session) => {
4528
+ if (session.subtype !== "poke" || session.targetId !== session.selfId) {
4455
4529
  return;
4456
4530
  }
4457
- if (pokeConfig2.interval > 0 && cache.has(session.userId)) {
4531
+ if (config.interval > 0 && cache.has(session.userId)) {
4458
4532
  const ts = cache.get(session.userId);
4459
- if (session.timestamp - ts < pokeConfig2.interval) {
4460
- if (pokeConfig2.warning) {
4461
- const msg = randomMessage(pokeConfig2.prompt);
4462
- const content = import_koishi8.h.parse(msg, session);
4463
- session.sendQueued(content);
4533
+ if (session.timestamp - ts < config.interval) {
4534
+ if (config.warning) {
4535
+ const msg2 = randomMessage(config.prompt);
4536
+ if (msg2) {
4537
+ await session.sendQueued(import_koishi9.h.parse(msg2.content, session));
4538
+ }
4464
4539
  }
4465
4540
  return;
4466
4541
  }
4467
4542
  }
4468
4543
  cache.set(session.userId, session.timestamp);
4469
- if (pokeConfig2.messages.length > 0) {
4470
- const msg = randomMessage(pokeConfig2.messages);
4471
- const content = import_koishi8.h.parse(msg, session);
4472
- await session.sendQueued(content);
4544
+ if (config.messages.length === 0) {
4545
+ return;
4546
+ }
4547
+ const msg = randomMessage(config.messages);
4548
+ if (!msg) {
4549
+ return;
4550
+ }
4551
+ if (msg.type === "noah") {
4552
+ await sendRandomNoahStamp(ctx, session);
4553
+ } else if (msg.type === "chat") {
4554
+ await session.sendQueued(getRandomChatStamp(ctx));
4555
+ } else {
4556
+ const tip = await pickTip(session);
4557
+ if (tip) {
4558
+ await session.sendQueued(import_koishi9.h.parse(tip, session));
4559
+ }
4473
4560
  }
4474
4561
  });
4475
4562
  }
4476
- __name(apply7, "apply");
4477
- function randomMessage(messages) {
4478
- const totalWeight = messages.reduce((sum2, cur) => sum2 + cur.weight, 0);
4479
- const random = Math.random() * totalWeight;
4480
- let sum = 0;
4481
- for (const message of messages) {
4482
- sum += message.weight;
4483
- if (random < sum) return message.content;
4484
- }
4485
- }
4486
- __name(randomMessage, "randomMessage");
4487
- function parsePlatform(target) {
4488
- const index = target.indexOf(":");
4489
- const platform = target.slice(0, index);
4490
- const id = target.slice(index + 1);
4491
- return [platform, id];
4563
+ __name(registerPokeNotice, "registerPokeNotice");
4564
+
4565
+ // src/fun/poke/locales/en-US.yml
4566
+ var en_US_default3 = { _config: { $desc: "Poke Module Settings", interval: "最小触发间隔(毫秒)", warning: "频繁触发是否发送警告", prompt: "警告内容", messages: { $desc: "消息内容", type: "Type (text=random tip / noah=voice stamp / chat=chat stamp)", weight: "权重" } }, commands: { poke: { description: "poke" } } };
4567
+
4568
+ // src/fun/poke/locales/zh-CN.yml
4569
+ var zh_CN_default3 = { _config: { $desc: "Poke 模块设置", interval: "最小触发间隔(毫秒)", warning: "频繁触发是否发送警告", prompt: { $desc: "警告内容", content: "消息", weight: "权重" }, messages: { $desc: "消息内容", type: "类型(text=随机提示 / noah=语音表情 / chat=聊天表情)", weight: "权重" } }, commands: { poke: { description: "戳一戳" } } };
4570
+
4571
+ // src/fun/poke/index.ts
4572
+ var name7 = "Noah-Poke";
4573
+ var logger3 = new import_koishi10.Logger("Noah-Poke");
4574
+ function apply7(ctx, config) {
4575
+ ;
4576
+ [
4577
+ ["en-US", en_US_default3],
4578
+ ["zh-CN", zh_CN_default3]
4579
+ ].forEach(([lang, file]) => ctx.i18n.define(lang, file));
4580
+ const cache = /* @__PURE__ */ new Map();
4581
+ registerStampCommand(ctx);
4582
+ registerPokeCommand(ctx);
4583
+ registerPokeNotice(ctx, config.poke, cache);
4492
4584
  }
4493
- __name(parsePlatform, "parsePlatform");
4585
+ __name(apply7, "apply");
4494
4586
 
4495
4587
  // src/games/general/index.ts
4496
4588
  var general_exports = {};
4497
4589
  __export(general_exports, {
4498
4590
  apply: () => apply8,
4499
- logger: () => logger3,
4591
+ logger: () => logger4,
4500
4592
  name: () => name8
4501
4593
  });
4502
- var import_koishi10 = require("koishi");
4594
+ var import_koishi12 = require("koishi");
4503
4595
 
4504
4596
  // src/games/general/events/quote.ts
4505
- var import_koishi9 = require("koishi");
4597
+ var import_koishi11 = require("koishi");
4506
4598
 
4507
4599
  // src/games/general/utils/codeReader.ts
4508
4600
  async function readCode128(ctx, barcodeApiUrl, imageUrl) {
@@ -4528,8 +4620,8 @@ __name(readCode128, "readCode128");
4528
4620
  function quote(ctx, config) {
4529
4621
  ctx.on("message", async (session) => {
4530
4622
  if (session.quote && session.quote.user.id === session.selfId) {
4531
- const images = await import_koishi9.h.select(session.quote.elements, "img");
4532
- const textElements = await import_koishi9.h.select(session.elements, "text");
4623
+ const images = await import_koishi11.h.select(session.quote.elements, "img");
4624
+ const textElements = await import_koishi11.h.select(session.elements, "text");
4533
4625
  const allText = textElements.map((el) => el.attrs?.content || "").join(" ");
4534
4626
  if (images.length === 1) {
4535
4627
  const imageUrl = images[0].attrs.src;
@@ -4555,7 +4647,7 @@ __name(quote, "quote");
4555
4647
 
4556
4648
  // src/games/general/index.ts
4557
4649
  var name8 = "Noah-General";
4558
- var logger3 = new import_koishi10.Logger("Noah-General");
4650
+ var logger4 = new import_koishi12.Logger("Noah-General");
4559
4651
  async function apply8(ctx, config) {
4560
4652
  quote(ctx, config.general);
4561
4653
  }
@@ -4566,10 +4658,10 @@ var sdvx_exports = {};
4566
4658
  __export(sdvx_exports, {
4567
4659
  apply: () => apply13,
4568
4660
  inject: () => inject3,
4569
- logger: () => logger4,
4661
+ logger: () => logger5,
4570
4662
  name: () => name13
4571
4663
  });
4572
- var import_koishi19 = require("koishi");
4664
+ var import_koishi21 = require("koishi");
4573
4665
 
4574
4666
  // src/servers/index.ts
4575
4667
  var servers_exports = {};
@@ -4581,7 +4673,7 @@ __export(servers_exports, {
4581
4673
  });
4582
4674
 
4583
4675
  // src/servers/Asphyxia/index.ts
4584
- var import_koishi11 = require("koishi");
4676
+ var import_koishi13 = require("koishi");
4585
4677
  var Asphyxia = class {
4586
4678
  static {
4587
4679
  __name(this, "Asphyxia");
@@ -4589,11 +4681,11 @@ var Asphyxia = class {
4589
4681
  name = "asphyxia";
4590
4682
  supportedGames = ["sdvx", "iidx"];
4591
4683
  gameServices = {};
4592
- logger = new import_koishi11.Logger("Noah-Asphyxia");
4684
+ logger = new import_koishi13.Logger("Noah-Asphyxia");
4593
4685
  };
4594
4686
 
4595
4687
  // src/servers/Mao/index.ts
4596
- var import_koishi12 = require("koishi");
4688
+ var import_koishi14 = require("koishi");
4597
4689
  var Mao = class {
4598
4690
  static {
4599
4691
  __name(this, "Mao");
@@ -4601,11 +4693,11 @@ var Mao = class {
4601
4693
  name = "mao";
4602
4694
  supportedGames = ["sdvx"];
4603
4695
  gameServices = {};
4604
- logger = new import_koishi12.Logger("Noah-Mao");
4696
+ logger = new import_koishi14.Logger("Noah-Mao");
4605
4697
  };
4606
4698
 
4607
4699
  // src/servers/Official/index.ts
4608
- var import_koishi13 = require("koishi");
4700
+ var import_koishi15 = require("koishi");
4609
4701
  var Official = class {
4610
4702
  static {
4611
4703
  __name(this, "Official");
@@ -4613,7 +4705,7 @@ var Official = class {
4613
4705
  name = "official";
4614
4706
  supportedGames = ["sdvx"];
4615
4707
  gameServices = {};
4616
- logger = new import_koishi13.Logger("Noah-Official");
4708
+ logger = new import_koishi15.Logger("Noah-Official");
4617
4709
  };
4618
4710
 
4619
4711
  // src/servers/ServerFactory.ts
@@ -4981,13 +5073,13 @@ var AsphyxiaSDVXService = class _AsphyxiaSDVXService {
4981
5073
  logger;
4982
5074
  config;
4983
5075
  cachedModel = null;
4984
- constructor(logger5, config) {
4985
- this.logger = logger5;
5076
+ constructor(logger6, config) {
5077
+ this.logger = logger6;
4986
5078
  this.config = config;
4987
5079
  }
4988
- static getInstance(logger5, config) {
5080
+ static getInstance(logger6, config) {
4989
5081
  if (!_AsphyxiaSDVXService.instance) {
4990
- _AsphyxiaSDVXService.instance = new _AsphyxiaSDVXService(logger5, config);
5082
+ _AsphyxiaSDVXService.instance = new _AsphyxiaSDVXService(logger6, config);
4991
5083
  }
4992
5084
  return _AsphyxiaSDVXService.instance;
4993
5085
  }
@@ -5134,12 +5226,12 @@ var MaoSDVXService = class _MaoSDVXService {
5134
5226
  }
5135
5227
  static instance;
5136
5228
  logger;
5137
- constructor(logger5) {
5138
- this.logger = logger5;
5229
+ constructor(logger6) {
5230
+ this.logger = logger6;
5139
5231
  }
5140
- static getInstance(logger5) {
5232
+ static getInstance(logger6) {
5141
5233
  if (!_MaoSDVXService.instance) {
5142
- _MaoSDVXService.instance = new _MaoSDVXService(logger5);
5234
+ _MaoSDVXService.instance = new _MaoSDVXService(logger6);
5143
5235
  }
5144
5236
  return _MaoSDVXService.instance;
5145
5237
  }
@@ -5484,12 +5576,12 @@ var OfficialSDVXService = class _OfficialSDVXService {
5484
5576
  }
5485
5577
  static instance;
5486
5578
  logger;
5487
- constructor(logger5) {
5488
- this.logger = logger5;
5579
+ constructor(logger6) {
5580
+ this.logger = logger6;
5489
5581
  }
5490
- static getInstance(logger5) {
5582
+ static getInstance(logger6) {
5491
5583
  if (!_OfficialSDVXService.instance) {
5492
- _OfficialSDVXService.instance = new _OfficialSDVXService(logger5);
5584
+ _OfficialSDVXService.instance = new _OfficialSDVXService(logger6);
5493
5585
  }
5494
5586
  return _OfficialSDVXService.instance;
5495
5587
  }
@@ -5594,15 +5686,15 @@ var OfficialSDVXService = class _OfficialSDVXService {
5594
5686
  };
5595
5687
 
5596
5688
  // src/games/sdvx/adapters/index.ts
5597
- function registerSDVXAdapters(logger5, config) {
5689
+ function registerSDVXAdapters(logger6, config) {
5598
5690
  const serverManager = ServerManager.getInstance();
5599
5691
  serverManager.registerGameService(
5600
5692
  "asphyxia",
5601
5693
  "sdvx",
5602
- AsphyxiaSDVXService.getInstance(logger5, config)
5694
+ AsphyxiaSDVXService.getInstance(logger6, config)
5603
5695
  );
5604
- serverManager.registerGameService("mao", "sdvx", MaoSDVXService.getInstance(logger5));
5605
- serverManager.registerGameService("official", "sdvx", OfficialSDVXService.getInstance(logger5));
5696
+ serverManager.registerGameService("mao", "sdvx", MaoSDVXService.getInstance(logger6));
5697
+ serverManager.registerGameService("official", "sdvx", OfficialSDVXService.getInstance(logger6));
5606
5698
  }
5607
5699
  __name(registerSDVXAdapters, "registerSDVXAdapters");
5608
5700
 
@@ -5614,7 +5706,7 @@ __export(command_exports2, {
5614
5706
  });
5615
5707
 
5616
5708
  // src/games/sdvx/commands/calculate.ts
5617
- var import_koishi14 = require("koishi");
5709
+ var import_koishi16 = require("koishi");
5618
5710
 
5619
5711
  // src/games/sdvx/utils/param-parser.ts
5620
5712
  function parseNumberWithSuffix(str) {
@@ -6133,7 +6225,7 @@ function parseQueryInput(input) {
6133
6225
  __name(parseQueryInput, "parseQueryInput");
6134
6226
 
6135
6227
  // src/games/sdvx/commands/calculate.ts
6136
- function calculate(ctx, config, logger5) {
6228
+ function calculate(ctx, config, logger6) {
6137
6229
  ctx.command("sdvx.calculate <query:text>").alias("sdvx.cal").action(async ({ session, options }, query) => {
6138
6230
  try {
6139
6231
  let queryInput = query;
@@ -6167,7 +6259,7 @@ function calculate(ctx, config, logger5) {
6167
6259
  lossless: true
6168
6260
  }
6169
6261
  );
6170
- return import_koishi14.h.image(imageBuffer, "image/png");
6262
+ return import_koishi16.h.image(imageBuffer, "image/png");
6171
6263
  } catch (error) {
6172
6264
  ctx.logger("SDVX-Calculate").warn(error);
6173
6265
  return session.text(".error");
@@ -6177,7 +6269,7 @@ function calculate(ctx, config, logger5) {
6177
6269
  __name(calculate, "calculate");
6178
6270
 
6179
6271
  // src/games/sdvx/commands/chart.ts
6180
- var import_koishi15 = require("koishi");
6272
+ var import_koishi17 = require("koishi");
6181
6273
  function mapArrangementToken(tok) {
6182
6274
  const t = tok.toLowerCase();
6183
6275
  if (t === "ran" || t === "random") return "random";
@@ -6260,7 +6352,7 @@ function getHighestDifstr(diffs) {
6260
6352
  return diffs[diffs.length - 1].difstr;
6261
6353
  }
6262
6354
  __name(getHighestDifstr, "getHighestDifstr");
6263
- function chart(ctx, config, logger5) {
6355
+ function chart(ctx, config, logger6) {
6264
6356
  ctx.command("sdvx.chart [query:text]").alias("sdvx.c").action(async ({ session }, query) => {
6265
6357
  if (!query) {
6266
6358
  await session.send(session.text(".prompt"));
@@ -6323,7 +6415,7 @@ function chart(ctx, config, logger5) {
6323
6415
  const res = await ctx.http.post(`${config.sdvx_data_url}/chart`, payload, {
6324
6416
  headers: { "Content-Type": "application/json" }
6325
6417
  });
6326
- return import_koishi15.h.image(res, "image/png");
6418
+ return import_koishi17.h.image(res, "image/png");
6327
6419
  } else {
6328
6420
  const {
6329
6421
  diffStr: parsedDiff,
@@ -6339,7 +6431,7 @@ function chart(ctx, config, logger5) {
6339
6431
  const picked = musicInfo[0];
6340
6432
  const music_id = Number(picked?.id);
6341
6433
  if (!Number.isFinite(music_id)) {
6342
- logger5.warn("search result missing id", picked);
6434
+ logger6.warn("search result missing id", picked);
6343
6435
  return session.text(".error");
6344
6436
  }
6345
6437
  let difstr = null;
@@ -6373,10 +6465,10 @@ function chart(ctx, config, logger5) {
6373
6465
  const res = await ctx.http.post(`${config.sdvx_data_url}/chart`, payload, {
6374
6466
  headers: { "Content-Type": "application/json" }
6375
6467
  });
6376
- return import_koishi15.h.image(res, "image/png");
6468
+ return import_koishi17.h.image(res, "image/png");
6377
6469
  }
6378
6470
  } catch (err) {
6379
- logger5.warn(err);
6471
+ logger6.warn(err);
6380
6472
  return session.text(".error");
6381
6473
  }
6382
6474
  });
@@ -6384,7 +6476,7 @@ function chart(ctx, config, logger5) {
6384
6476
  __name(chart, "chart");
6385
6477
 
6386
6478
  // src/core/utils/selector.ts
6387
- var import_koishi16 = require("koishi");
6479
+ var import_koishi18 = require("koishi");
6388
6480
  async function selectCard(session, cardService, uid) {
6389
6481
  const userCards = await cardService.getCardsByUid(uid);
6390
6482
  if (userCards.length === 0) {
@@ -6400,7 +6492,7 @@ async function selectCard(session, cardService, uid) {
6400
6492
  cardListMsg += `<p>${i + 1}. ${userCards[i].name}</p>`;
6401
6493
  }
6402
6494
  }
6403
- const msg = import_koishi16.h.unescape(session.text("selector.menu-select", { card_list: cardListMsg }));
6495
+ const msg = import_koishi18.h.unescape(session.text("selector.menu-select", { card_list: cardListMsg }));
6404
6496
  await session.send(msg);
6405
6497
  const select = await session.prompt();
6406
6498
  if (!select) return { ok: false, message: session.text("commands.timeout") };
@@ -6428,7 +6520,7 @@ async function selectServer(session, serverService, uid, channelId) {
6428
6520
  serverListMsg += `<p>${i + 1}. ${servers[i].name} (${servers[i].type})</p>`;
6429
6521
  }
6430
6522
  }
6431
- const msg = import_koishi16.h.unescape(
6523
+ const msg = import_koishi18.h.unescape(
6432
6524
  session.text("selector.server-menu-select", { server_list: serverListMsg })
6433
6525
  );
6434
6526
  await session.send(msg);
@@ -6565,7 +6657,7 @@ var ScoreService = class _ScoreService {
6565
6657
  };
6566
6658
 
6567
6659
  // src/games/sdvx/commands/radar.ts
6568
- function radar(ctx, config, logger5) {
6660
+ function radar(ctx, config, logger6) {
6569
6661
  ctx.command("sdvx.radar").userFields(["defaultCardId", "defaultServerId", "id"]).channelFields(["defaultServerId", "id"]).option("card", "-c").option("server", "-s").action(async ({ session, options }) => {
6570
6662
  const atGuild = session.guildId != null;
6571
6663
  const cardService = new CardService(ctx);
@@ -6631,7 +6723,7 @@ function radar(ctx, config, logger5) {
6631
6723
  one_hand: radarResult.one_hand.toFixed(2)
6632
6724
  });
6633
6725
  } catch (error) {
6634
- logger5.warn(error);
6726
+ logger6.warn(error);
6635
6727
  return session.text(".error");
6636
6728
  }
6637
6729
  });
@@ -6639,8 +6731,8 @@ function radar(ctx, config, logger5) {
6639
6731
  __name(radar, "radar");
6640
6732
 
6641
6733
  // src/games/sdvx/commands/recent.ts
6642
- var import_koishi17 = require("koishi");
6643
- function recent(ctx, config, logger5) {
6734
+ var import_koishi19 = require("koishi");
6735
+ function recent(ctx, config, logger6) {
6644
6736
  ctx.command("sdvx.recent [count:number]").alias("sdvx.r").userFields(["defaultCardId", "defaultServerId", "id"]).channelFields(["defaultServerId", "id"]).option("lossless", "-l").option("card", "-c").option("server", "-s").action(async ({ session, options }, count) => {
6645
6737
  const atGuild = session.guildId != null;
6646
6738
  if (!count) count = 1;
@@ -6710,11 +6802,11 @@ function recent(ctx, config, logger5) {
6710
6802
  }
6711
6803
  );
6712
6804
  if (options.lossless) {
6713
- return import_koishi17.h.image(imageBuffer, "image/png");
6805
+ return import_koishi19.h.image(imageBuffer, "image/png");
6714
6806
  }
6715
- return import_koishi17.h.image(imageBuffer, "image/jpg");
6807
+ return import_koishi19.h.image(imageBuffer, "image/jpg");
6716
6808
  } catch (error) {
6717
- logger5.warn(error);
6809
+ logger6.warn(error);
6718
6810
  return session.text(".error");
6719
6811
  }
6720
6812
  });
@@ -6722,7 +6814,7 @@ function recent(ctx, config, logger5) {
6722
6814
  __name(recent, "recent");
6723
6815
 
6724
6816
  // src/games/sdvx/commands/sync.ts
6725
- function sync(ctx, config, logger5) {
6817
+ function sync(ctx, config, logger6) {
6726
6818
  ctx.command("sdvx.sync").userFields(["id"]).channelFields(["id"]).action(async ({ session }) => {
6727
6819
  const serverService = new ServerService(ctx);
6728
6820
  const cardService = new CardService(ctx);
@@ -6797,7 +6889,7 @@ function sync(ctx, config, logger5) {
6797
6889
  const maoSdvxService = serverManager.getGameService("mao", "sdvx");
6798
6890
  const maoVerifyUrl = "https://maomani.cn";
6799
6891
  if (!maoSdvxService || typeof maoSdvxService.verifyPin !== "function") {
6800
- logger5.warn("Mao SDVX service does not support PIN verification");
6892
+ logger6.warn("Mao SDVX service does not support PIN verification");
6801
6893
  return session.text(".pin-verify-error");
6802
6894
  }
6803
6895
  const existingPin = await ctx.database.get("sdvx_pin_verified", {
@@ -6818,7 +6910,7 @@ function sync(ctx, config, logger5) {
6818
6910
  pinVerified = true;
6819
6911
  }
6820
6912
  } catch (error) {
6821
- logger5.warn(error);
6913
+ logger6.warn(error);
6822
6914
  }
6823
6915
  }
6824
6916
  if (!pinVerified) {
@@ -6854,7 +6946,7 @@ function sync(ctx, config, logger5) {
6854
6946
  })
6855
6947
  );
6856
6948
  } catch (error) {
6857
- logger5.warn(error);
6949
+ logger6.warn(error);
6858
6950
  await session.send(session.text(".pin-verify-error"));
6859
6951
  }
6860
6952
  }
@@ -6876,7 +6968,7 @@ function sync(ctx, config, logger5) {
6876
6968
  config
6877
6969
  );
6878
6970
  } catch (error) {
6879
- logger5.warn(error);
6971
+ logger6.warn(error);
6880
6972
  return session.text(".fetch-error");
6881
6973
  }
6882
6974
  if (!scoreList || scoreList.length === 0) {
@@ -6898,11 +6990,11 @@ function sync(ctx, config, logger5) {
6898
6990
  scoreList
6899
6991
  );
6900
6992
  if (!ok) {
6901
- logger5.warn("Mao SDVX uploadScore returned falsy result");
6993
+ logger6.warn("Mao SDVX uploadScore returned falsy result");
6902
6994
  return session.text(".sync-failed");
6903
6995
  }
6904
6996
  } catch (error) {
6905
- logger5.warn(error);
6997
+ logger6.warn(error);
6906
6998
  return session.text(".sync-error");
6907
6999
  }
6908
7000
  return session.text(".selected-summary", {
@@ -6917,8 +7009,8 @@ function sync(ctx, config, logger5) {
6917
7009
  __name(sync, "sync");
6918
7010
 
6919
7011
  // src/games/sdvx/commands/vf.ts
6920
- var fs4 = __toESM(require("fs"), 1);
6921
- var import_koishi18 = require("koishi");
7012
+ var fs5 = __toESM(require("fs"), 1);
7013
+ var import_koishi20 = require("koishi");
6922
7014
 
6923
7015
  // src/games/sdvx/utils/filter.ts
6924
7016
  function parseFilterQuery(query) {
@@ -6971,7 +7063,7 @@ function parseFilterQuery(query) {
6971
7063
  __name(parseFilterQuery, "parseFilterQuery");
6972
7064
 
6973
7065
  // src/games/sdvx/commands/vf.ts
6974
- function vf(ctx, config, logger5) {
7066
+ function vf(ctx, config, logger6) {
6975
7067
  ctx.command("vf").userFields(["defaultCardId", "defaultServerId", "id"]).channelFields(["defaultServerId", "id"]).option("lossless", "-l").option("card", "-c").option("server", "-s").option("filter", "-f <query:text>").action(async ({ session, options }) => {
6976
7068
  const atGuild = session.guildId != null;
6977
7069
  const cardService = new CardService(ctx);
@@ -7046,9 +7138,9 @@ function vf(ctx, config, logger5) {
7046
7138
  }
7047
7139
  );
7048
7140
  if (options.lossless) {
7049
- session.send(import_koishi18.h.file(imageBuffer, "image/png"));
7141
+ session.send(import_koishi20.h.file(imageBuffer, "image/png"));
7050
7142
  } else {
7051
- session.send(import_koishi18.h.image(imageBuffer, "image/jpg"));
7143
+ session.send(import_koishi20.h.image(imageBuffer, "image/jpg"));
7052
7144
  }
7053
7145
  const sortedScores = [...best50ScoreList].sort((a, b) => b.extra.volforce - a.extra.volforce).slice(0, 50);
7054
7146
  const total = sortedScores.reduce((sum, score) => sum + score.extra.volforce, 0);
@@ -7075,20 +7167,20 @@ function vf(ctx, config, logger5) {
7075
7167
  ctx,
7076
7168
  "stamps/noah_stamp/stamp_0385/stamp_0385_02.png"
7077
7169
  );
7078
- if (fs4.existsSync(audioPath)) {
7079
- const audioBuffer = fs4.readFileSync(audioPath);
7080
- session.send(import_koishi18.h.audio(audioBuffer, "audio/mpeg"));
7170
+ if (fs5.existsSync(audioPath)) {
7171
+ const audioBuffer = fs5.readFileSync(audioPath);
7172
+ session.send(import_koishi20.h.audio(audioBuffer, "audio/mpeg"));
7081
7173
  }
7082
- if (fs4.existsSync(imagePath)) {
7083
- const imageBuffer2 = fs4.readFileSync(imagePath);
7084
- session.send(import_koishi18.h.image(imageBuffer2, "image/png"));
7174
+ if (fs5.existsSync(imagePath)) {
7175
+ const imageBuffer2 = fs5.readFileSync(imagePath);
7176
+ session.send(import_koishi20.h.image(imageBuffer2, "image/png"));
7085
7177
  }
7086
7178
  } catch (error) {
7087
- logger5.warn(`Failed to send celebration files: ${error.message}`);
7179
+ logger6.warn(`Failed to send celebration files: ${error.message}`);
7088
7180
  }
7089
7181
  }
7090
7182
  } catch (error) {
7091
- logger5.warn(error);
7183
+ logger6.warn(error);
7092
7184
  return session.text(".error");
7093
7185
  }
7094
7186
  return;
@@ -7100,12 +7192,12 @@ __name(vf, "vf");
7100
7192
  var name10 = "command";
7101
7193
  function apply10(ctx, config) {
7102
7194
  ctx.command("sdvx").alias("s");
7103
- vf(ctx, config, logger4);
7104
- recent(ctx, config, logger4);
7105
- chart(ctx, config, logger4);
7106
- calculate(ctx, config, logger4);
7107
- sync(ctx, config, logger4);
7108
- radar(ctx, config, logger4);
7195
+ vf(ctx, config, logger5);
7196
+ recent(ctx, config, logger5);
7197
+ chart(ctx, config, logger5);
7198
+ calculate(ctx, config, logger5);
7199
+ sync(ctx, config, logger5);
7200
+ radar(ctx, config, logger5);
7109
7201
  }
7110
7202
  __name(apply10, "apply");
7111
7203
 
@@ -7153,14 +7245,14 @@ var zh_CN_default4 = { _config: { $desc: "SDVX 模块设置", sdvx_data_url: "<p
7153
7245
  // src/games/sdvx/index.ts
7154
7246
  var name13 = "Noah-SDVX";
7155
7247
  var inject3 = ["database", "globalConfig"];
7156
- var logger4 = new import_koishi19.Logger("Noah-SDVX");
7248
+ var logger5 = new import_koishi21.Logger("Noah-SDVX");
7157
7249
  async function apply13(ctx, config) {
7158
7250
  ;
7159
7251
  [
7160
7252
  ["en-US", en_US_default4],
7161
7253
  ["zh-CN", zh_CN_default4]
7162
7254
  ].forEach(([lang, file]) => ctx.i18n.define(lang, file));
7163
- registerSDVXAdapters(logger4, config.sdvx);
7255
+ registerSDVXAdapters(logger5, config.sdvx);
7164
7256
  ctx.plugin(database_exports2, config.sdvx);
7165
7257
  ctx.plugin(command_exports2, config.sdvx);
7166
7258
  ctx.plugin(event_exports2, config.sdvx);
@@ -7168,50 +7260,50 @@ async function apply13(ctx, config) {
7168
7260
  __name(apply13, "apply");
7169
7261
 
7170
7262
  // src/config.ts
7171
- var import_koishi27 = require("koishi");
7263
+ var import_koishi29 = require("koishi");
7172
7264
 
7173
7265
  // src/asset/config.ts
7174
- var import_koishi20 = require("koishi");
7175
- var assetConfig = import_koishi20.Schema.object({
7176
- data_path: import_koishi20.Schema.string().default("noah_assets"),
7177
- auto_update: import_koishi20.Schema.boolean().default(true),
7178
- update_url: import_koishi20.Schema.string().default("https://github.com/logthm/noah/releases/latest/download/"),
7179
- update_interval: import_koishi20.Schema.number().default(24 * 60 * 60 * 1e3),
7266
+ var import_koishi22 = require("koishi");
7267
+ var assetConfig = import_koishi22.Schema.object({
7268
+ data_path: import_koishi22.Schema.string().default("noah_assets"),
7269
+ auto_update: import_koishi22.Schema.boolean().default(true),
7270
+ update_url: import_koishi22.Schema.string().default("https://github.com/logthm/noah/releases/latest/download/"),
7271
+ update_interval: import_koishi22.Schema.number().default(24 * 60 * 60 * 1e3),
7180
7272
  // 24 hours in milliseconds
7181
- github_token: import_koishi20.Schema.string().description("GitHub token for accessing private repositories").role("secret")
7273
+ github_token: import_koishi22.Schema.string().description("GitHub token for accessing private repositories").role("secret")
7182
7274
  }).i18n({
7183
7275
  "en-US": en_US_default._config,
7184
7276
  "zh-CN": zh_CN_default._config
7185
7277
  });
7186
7278
 
7187
7279
  // src/core/config.ts
7188
- var import_koishi21 = require("koishi");
7189
- var coreConfig = import_koishi21.Schema.object({
7190
- adminUsers: import_koishi21.Schema.array(String).role("table"),
7191
- guildNameCards: import_koishi21.Schema.array(String).role("table").default(["Noah | /help 获取食用指南"]),
7192
- tokenTtl: import_koishi21.Schema.number().default(1800),
7193
- frontendUrl: import_koishi21.Schema.string().default(""),
7194
- corsOrigin: import_koishi21.Schema.string().default("*")
7280
+ var import_koishi23 = require("koishi");
7281
+ var coreConfig = import_koishi23.Schema.object({
7282
+ adminUsers: import_koishi23.Schema.array(String).role("table"),
7283
+ guildNameCards: import_koishi23.Schema.array(String).role("table").default(["Noah | /help 获取食用指南"]),
7284
+ tokenTtl: import_koishi23.Schema.number().default(1800),
7285
+ frontendUrl: import_koishi23.Schema.string().default(""),
7286
+ corsOrigin: import_koishi23.Schema.string().default("*")
7195
7287
  }).i18n({
7196
7288
  "en-US": en_US_default2._config,
7197
7289
  "zh-CN": zh_CN_default2._config
7198
7290
  });
7199
7291
 
7200
7292
  // src/fun/poke/config.ts
7201
- var import_koishi22 = require("koishi");
7202
- var pokeConfig = import_koishi22.Schema.object({
7203
- interval: import_koishi22.Schema.number().default(1e3).step(100),
7204
- warning: import_koishi22.Schema.boolean().default(false),
7205
- prompt: import_koishi22.Schema.array(
7206
- import_koishi22.Schema.object({
7207
- content: import_koishi22.Schema.string().required(),
7208
- weight: import_koishi22.Schema.number().min(0).max(100).default(50)
7293
+ var import_koishi24 = require("koishi");
7294
+ var pokeConfig = import_koishi24.Schema.object({
7295
+ interval: import_koishi24.Schema.number().default(1e3).step(100),
7296
+ warning: import_koishi24.Schema.boolean().default(false),
7297
+ prompt: import_koishi24.Schema.array(
7298
+ import_koishi24.Schema.object({
7299
+ content: import_koishi24.Schema.string().required(),
7300
+ weight: import_koishi24.Schema.number().min(0).max(100).default(50)
7209
7301
  })
7210
7302
  ).role("table"),
7211
- messages: import_koishi22.Schema.array(
7212
- import_koishi22.Schema.object({
7213
- content: import_koishi22.Schema.string().required(),
7214
- weight: import_koishi22.Schema.number().min(0).max(100).default(50)
7303
+ messages: import_koishi24.Schema.array(
7304
+ import_koishi24.Schema.object({
7305
+ type: import_koishi24.Schema.union(["text", "noah", "chat"]).default("text"),
7306
+ weight: import_koishi24.Schema.number().min(0).max(100).default(50)
7215
7307
  })
7216
7308
  ).role("table")
7217
7309
  }).i18n({
@@ -7220,7 +7312,7 @@ var pokeConfig = import_koishi22.Schema.object({
7220
7312
  });
7221
7313
 
7222
7314
  // src/games/general/config.ts
7223
- var import_koishi23 = require("koishi");
7315
+ var import_koishi25 = require("koishi");
7224
7316
 
7225
7317
  // src/games/general/locales/en-US.yml
7226
7318
  var en_US_default5 = { _config: { $desc: "General Module Settings", barcode_api_url: "<p>The URL of the barcode API</p>" } };
@@ -7229,33 +7321,33 @@ var en_US_default5 = { _config: { $desc: "General Module Settings", barcode_api_
7229
7321
  var zh_CN_default5 = { _config: { $desc: "通用工具模块设置", barcode_api_url: "<p>条形码 API 地址</p>" } };
7230
7322
 
7231
7323
  // src/games/general/config.ts
7232
- var generalConfig = import_koishi23.Schema.object({
7233
- barcode_api_url: import_koishi23.Schema.string().required()
7324
+ var generalConfig = import_koishi25.Schema.object({
7325
+ barcode_api_url: import_koishi25.Schema.string().required()
7234
7326
  }).i18n({
7235
7327
  "en-US": en_US_default5._config,
7236
7328
  "zh-CN": zh_CN_default5._config
7237
7329
  });
7238
7330
 
7239
7331
  // src/games/sdvx/config.ts
7240
- var import_koishi24 = require("koishi");
7241
- var sdvxConfig = import_koishi24.Schema.object({
7242
- sdvx_data_url: import_koishi24.Schema.string().required(),
7243
- sdvx_search_url: import_koishi24.Schema.string().required()
7332
+ var import_koishi26 = require("koishi");
7333
+ var sdvxConfig = import_koishi26.Schema.object({
7334
+ sdvx_data_url: import_koishi26.Schema.string().required(),
7335
+ sdvx_search_url: import_koishi26.Schema.string().required()
7244
7336
  }).i18n({
7245
7337
  "en-US": en_US_default4._config,
7246
7338
  "zh-CN": zh_CN_default4._config
7247
7339
  });
7248
7340
 
7249
7341
  // src/global/config.ts
7250
- var import_koishi25 = require("koishi");
7251
- var globalConfig = import_koishi25.Schema.object({
7252
- official_support_url: import_koishi25.Schema.string().default("https://noah.logthm.com"),
7253
- maoServerUrl: import_koishi25.Schema.string().default("http://maomani.cn:577"),
7254
- maoApiKey: import_koishi25.Schema.string().role("secret").default("")
7342
+ var import_koishi27 = require("koishi");
7343
+ var globalConfig = import_koishi27.Schema.object({
7344
+ official_support_url: import_koishi27.Schema.string().default("https://noah.logthm.com"),
7345
+ maoServerUrl: import_koishi27.Schema.string().default("http://maomani.cn:577"),
7346
+ maoApiKey: import_koishi27.Schema.string().role("secret").default("")
7255
7347
  });
7256
7348
 
7257
7349
  // src/slash/config.ts
7258
- var import_koishi26 = require("koishi");
7350
+ var import_koishi28 = require("koishi");
7259
7351
 
7260
7352
  // src/slash/locales/en-US.yml
7261
7353
  var en_US_default6 = { _config: { $desc: "Slash Module Settings", test_guilds: "**Guilds To Sync**", auto_sync_on_start: "**Auto Sync on Connect**" } };
@@ -7264,16 +7356,16 @@ var en_US_default6 = { _config: { $desc: "Slash Module Settings", test_guilds: "
7264
7356
  var zh_CN_default6 = { _config: { $desc: "Slash 模块设置", test_guilds: "**默认同步 Guild 列表**", auto_sync_on_start: "**连接后自动同步**" } };
7265
7357
 
7266
7358
  // src/slash/config.ts
7267
- var slashConfig = import_koishi26.Schema.object({
7268
- test_guilds: import_koishi26.Schema.array(String).default([]),
7269
- auto_sync_on_start: import_koishi26.Schema.boolean().default(true)
7359
+ var slashConfig = import_koishi28.Schema.object({
7360
+ test_guilds: import_koishi28.Schema.array(String).default([]),
7361
+ auto_sync_on_start: import_koishi28.Schema.boolean().default(true)
7270
7362
  }).i18n({
7271
7363
  "en-US": en_US_default6._config,
7272
7364
  "zh-CN": zh_CN_default6._config
7273
7365
  });
7274
7366
 
7275
7367
  // src/config.ts
7276
- var Config = import_koishi27.Schema.object({
7368
+ var Config = import_koishi29.Schema.object({
7277
7369
  global: globalConfig,
7278
7370
  core: coreConfig,
7279
7371
  sdvx: sdvxConfig,
@@ -1,4 +1,4 @@
1
- import { MessageReply } from '../fun/poke/types';
1
+ import { MessageReply, PromptReply } from '../fun/poke/types';
2
2
  import { SDVXConfig } from '../games/sdvx/types/config';
3
3
  export { SDVXConfig };
4
4
  /**
@@ -55,7 +55,7 @@ export interface PokeConfig extends BaseConfig {
55
55
  /** 是否启用警告功能 */
56
56
  warning?: boolean;
57
57
  /** 提示消息列表 */
58
- prompt?: MessageReply[];
58
+ prompt?: PromptReply[];
59
59
  /** 消息回复列表 */
60
60
  messages?: MessageReply[];
61
61
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-noah",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "contributors": [
5
5
  "Logthm <logthm@outlook.com>"
6
6
  ],