koishi-plugin-cfmrmod 1.0.5 → 1.0.7

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/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # koishi-plugin-cfmrmod
2
2
 
3
3
  Koishi 插件:搜索 CurseForge / Modrinth / MCMod,并渲染图片卡片。
4
+ 哥给个star吧
5
+ Star就是我维护的动力🤤
4
6
 
5
7
  ## 使用方法
6
8
 
@@ -41,6 +43,7 @@ Koishi 插件:搜索 CurseForge / Modrinth / MCMod,并渲染图片卡片。
41
43
  - `notify.interval`: 全局轮询间隔(毫秒)
42
44
  - `notify.adminAuthority`: 权限等级(1=全部,2=管理员+群主,3=仅群主)
43
45
  - `notify.stateFile`: 状态文件路径(JSON)
46
+ - `notify.configFile`: 订阅配置文件路径(JSON,指令修改会写入)
44
47
  - `notify.groups`: 通知群组列表
45
48
  - `channelId`: 群/频道 ID
46
49
  - `enabled`: 是否启用本群通知
package/dist/index.js CHANGED
@@ -52,6 +52,7 @@ exports.Config = koishi_1.Schema.object({
52
52
  interval: koishi_1.Schema.number().default(30 * 60 * 1000).description('轮询间隔(ms),默认 30 分钟'),
53
53
  adminAuthority: koishi_1.Schema.number().default(3).description('机器人管理员权限等级(默认 3)'),
54
54
  stateFile: koishi_1.Schema.string().default('data/cfmrmod_notify_state.json').description('状态存储 JSON 路径(数据库不可用时使用)'),
55
+ configFile: koishi_1.Schema.string().default('data/cfmrmod_notify_config.json').description('订阅配置存储 JSON 路径(指令修改会写入)'),
55
56
  groups: koishi_1.Schema.array(koishi_1.Schema.object({
56
57
  channelId: koishi_1.Schema.string().description('群号/频道 ID'),
57
58
  enabled: koishi_1.Schema.boolean().default(true).description('是否启用本群通知'),
@@ -564,7 +564,7 @@ async function drawModCard(url) {
564
564
  versions.forEach(v => {
565
565
  dummy.font = `14px "${font}"`;
566
566
  const lw = dummy.measureText(v.l).width + 10;
567
- const lines = wrapText(dummy, v.v, 0, 0, contentW - lw, 20, 100, false) / 20;
567
+ const lines = wrapText(dummy, v.v, 0, 0, contentW - lw, 20, 500, false) / 20;
568
568
  extraH += lines * 20 + 10;
569
569
  });
570
570
  }
@@ -578,7 +578,7 @@ async function drawModCard(url) {
578
578
  const isHeader = node.tag === 'h';
579
579
  dummy.font = `${isHeader ? 'bold' : ''} ${isHeader ? 22 : 16}px "${font}"`;
580
580
  const lh = isHeader ? 32 : 26;
581
- const lines = wrapText(dummy, node.val, 0, 0, contentW, lh, 100, false) / lh;
581
+ const lines = wrapText(dummy, node.val, 0, 0, contentW, lh, 5000, false) / lh;
582
582
  descH += lines * lh + (isHeader ? 15 : 10);
583
583
  }
584
584
  else if (node.type === 'i') {
package/dist/notify.js CHANGED
@@ -183,6 +183,7 @@ function apply(ctx, config, options) {
183
183
  let stateLoaded = false;
184
184
  let saving = false;
185
185
  let dbWarned = false;
186
+ let configLoaded = false;
186
187
  const getStateKey = (channelId, platform, projectId) => {
187
188
  return `${channelId}|${platform}|${projectId}`;
188
189
  };
@@ -190,6 +191,48 @@ function apply(ctx, config, options) {
190
191
  const p = String(config.stateFile || 'data/cfmrmod_notify_state.json');
191
192
  return path_1.default.isAbsolute(p) ? p : path_1.default.resolve(process.cwd(), p);
192
193
  };
194
+ const resolveConfigFile = () => {
195
+ const p = String(config.configFile || 'data/cfmrmod_notify_config.json');
196
+ return path_1.default.isAbsolute(p) ? p : path_1.default.resolve(process.cwd(), p);
197
+ };
198
+ const loadConfigFromFile = async () => {
199
+ if (configLoaded)
200
+ return;
201
+ configLoaded = true;
202
+ try {
203
+ const filePath = resolveConfigFile();
204
+ const content = await fs_1.promises.readFile(filePath, 'utf8');
205
+ const json = JSON.parse(content);
206
+ if (json && typeof json === 'object') {
207
+ if (typeof json.enabled === 'boolean')
208
+ config.enabled = json.enabled;
209
+ if (Array.isArray(json.groups))
210
+ config.groups = json.groups;
211
+ }
212
+ if (!Array.isArray(config.groups))
213
+ config.groups = [];
214
+ }
215
+ catch {
216
+ if (!Array.isArray(config.groups))
217
+ config.groups = [];
218
+ if (config.groups.length)
219
+ await saveConfigToFile();
220
+ }
221
+ };
222
+ const saveConfigToFile = async () => {
223
+ try {
224
+ const filePath = resolveConfigFile();
225
+ await fs_1.promises.mkdir(path_1.default.dirname(filePath), { recursive: true });
226
+ const obj = {
227
+ enabled: !!config.enabled,
228
+ groups: Array.isArray(config.groups) ? config.groups : [],
229
+ };
230
+ await fs_1.promises.writeFile(filePath, JSON.stringify(obj, null, 2), 'utf8');
231
+ }
232
+ catch (e) {
233
+ logger.warn(`配置文件写入失败:${e.message}`);
234
+ }
235
+ };
193
236
  const loadStateFromFile = async () => {
194
237
  if (stateLoaded)
195
238
  return;
@@ -387,6 +430,7 @@ function apply(ctx, config, options) {
387
430
  }
388
431
  async function checkOnce(channelId, force = false) {
389
432
  var _a;
433
+ await loadConfigFromFile();
390
434
  if (!config.enabled)
391
435
  return;
392
436
  const subs = getConfigSubs(channelId);
@@ -437,6 +481,7 @@ function apply(ctx, config, options) {
437
481
  }
438
482
  const checkOne = async (sub, forceSendAll) => {
439
483
  var _a;
484
+ await loadConfigFromFile();
440
485
  const timeout = ((_a = options === null || options === void 0 ? void 0 : options.cfmr) === null || _a === void 0 ? void 0 : _a.requestTimeout) || 15000;
441
486
  const latest = sub.platform === 'mr'
442
487
  ? await getLatestModrinth(sub.projectId, timeout)
@@ -474,6 +519,7 @@ function apply(ctx, config, options) {
474
519
  }
475
520
  ctx.command('notify.add <platform> <projectId>', '添加更新订阅')
476
521
  .action(async ({ session }, platform, projectId) => {
522
+ await loadConfigFromFile();
477
523
  if (!platform || !projectId)
478
524
  return '参数不足。';
479
525
  const platformKey = normalizePlatform(platform);
@@ -495,10 +541,12 @@ function apply(ctx, config, options) {
495
541
  const interval = Math.max(60 * 1000, Number(config.interval) || 30 * 60 * 1000);
496
542
  list.push({ platform: platformKey, projectId: pid, interval });
497
543
  group.subs = list;
544
+ await saveConfigToFile();
498
545
  return `已添加订阅:${platformKey}:${pid}`;
499
546
  });
500
547
  ctx.command('notify.remove <platform> <projectId>', '删除更新订阅')
501
548
  .action(async ({ session }, platform, projectId) => {
549
+ await loadConfigFromFile();
502
550
  if (!platform || !projectId)
503
551
  return '参数不足。';
504
552
  const platformKey = normalizePlatform(platform);
@@ -519,10 +567,12 @@ function apply(ctx, config, options) {
519
567
  group.subs = group.subs.filter((s) => !(normalizePlatform(s === null || s === void 0 ? void 0 : s.platform) === platformKey && String((s === null || s === void 0 ? void 0 : s.projectId) || '').trim() === pid));
520
568
  if (group.subs.length === before)
521
569
  return '未找到订阅。';
570
+ await saveConfigToFile();
522
571
  return `已删除订阅:${platformKey}:${pid}`;
523
572
  });
524
573
  ctx.command('notify.list', '列出订阅')
525
574
  .action(async ({ session }) => {
575
+ await loadConfigFromFile();
526
576
  const targetChannel = session.channelId;
527
577
  if (!targetChannel)
528
578
  return '只能在群聊使用或指定 channelId。';
@@ -546,6 +596,7 @@ function apply(ctx, config, options) {
546
596
  });
547
597
  ctx.command('notify.enable <onoff>', '启用/禁用本群通知')
548
598
  .action(async ({ session }, onoff) => {
599
+ await loadConfigFromFile();
549
600
  const targetChannel = session.channelId;
550
601
  if (!targetChannel)
551
602
  return '只能在群聊使用或指定 channelId。';
@@ -556,6 +607,7 @@ function apply(ctx, config, options) {
556
607
  return 'onoff 参数错误,请使用 on/off 或 true/false。';
557
608
  const group = ensureGroup(targetChannel);
558
609
  group.enabled = flag;
610
+ await saveConfigToFile();
559
611
  return flag ? '已启用本群通知。' : '已禁用本群通知。';
560
612
  });
561
613
  ctx.command('notify.helpme', '查看通知系统帮助')
@@ -579,6 +631,7 @@ function apply(ctx, config, options) {
579
631
  ctx.command('notify.check [arg]', '手动检查更新')
580
632
  .option('broadcast', '-b 直接发送最新版卡片(忽略是否更新)')
581
633
  .action(async ({ session, options }, arg) => {
634
+ await loadConfigFromFile();
582
635
  const targetChannel = session.channelId;
583
636
  if (!targetChannel)
584
637
  return '只能在群聊使用或指定 channelId。';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-cfmrmod",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Koishi 插件:搜索 CurseForge/Modrinth/MCMod 并渲染图片卡片",
5
5
  "main": "dist/index.js",
6
6
  "files": [