koishi-plugin-ets2-tools-tmp 1.2.0 → 1.2.2

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.
Files changed (2) hide show
  1. package/lib/index.js +81 -70
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -34,9 +34,9 @@ const __copyProps = (to, from, except, desc) => {
34
34
  if (from && (typeof from === "object" || typeof from === "function")) {
35
35
  for (const key of __getOwnPropNames(from))
36
36
  if (!__hasOwnProp.call(to, key) && key !== except)
37
- __defProp(to, key, {
38
- get: () => from[key],
39
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
37
+ __defProp(to, key, {
38
+ get: () => from[key],
39
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
40
40
  });
41
41
  }
42
42
  return to;
@@ -212,33 +212,14 @@ class ActivityService {
212
212
  });
213
213
  }
214
214
 
215
- getDebugInfo() {
216
- let startRemindersSent = 0;
217
- for (const reminderKey of this.sentReminders) {
218
- if (reminderKey.endsWith('_started')) {
219
- startRemindersSent++;
220
- }
221
- }
222
-
223
- return `📊 TMP-BOT 插件调试信息:\n` +
224
- `• 今日活动: ${this.todayActivities.length} 个\n` +
225
- `• TMP活动: ${this.todayTMPEvents.length} 个\n` +
226
- `• 已发送提醒: ${this.sentReminders.size} 个\n` +
227
- ` - 活动开始提醒: ${startRemindersSent} 个\n` +
228
- `• 无活动通知: ${this.sentNoActivityNotification ? "已发送" : "未发送"}\n` +
229
- `• 活跃定时器: ${this.timers.length} 个\n` +
230
- `• 调试模式: ${this.cfg.debugMode ? "✅ 开启" : "❌ 关闭"}\n` +
231
- `• 日志选项: API=${this.cfg.logApiResponses ? "✅" : "❌"}, 定时=${this.cfg.logTimingDetails ? "✅" : "❌"}, 匹配=${this.cfg.logActivityMatching ? "✅" : "❌"}, 消息=${this.cfg.logMessageSending ? "✅" : "❌"}`;
232
- }
233
-
234
215
  setupDailyTasks() {
235
216
  const now = new Date();
236
217
  const localTime = now.toLocaleString();
237
218
  const localDate = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
238
219
  const utcDate = now.toISOString().split("T")[0];
239
-
220
+
240
221
  this.logger.timing(`开始设置每日定时任务,本地时间: ${localTime}, 本地日期: ${localDate}, UTC日期: ${utcDate}`);
241
-
222
+
242
223
  const resetHour = 2;
243
224
  const resetMinute = 0;
244
225
  const resetDelay = this.getNextTime(resetHour, resetMinute);
@@ -253,7 +234,7 @@ class ActivityService {
253
234
  }, resetDelay);
254
235
  this.timers.push(resetTimer);
255
236
  this.logger.timing(`设置数据重置定时器: ${resetHour}:${resetMinute.toString().padStart(2, "0")}, 延迟: ${resetDelay}ms`);
256
-
237
+
257
238
  this.cfg.adminCheckTimes.forEach((timeStr, index) => {
258
239
  const [hours, minutes] = timeStr.split(":").map(Number);
259
240
  this.setupTimer(hours, minutes, async () => {
@@ -321,22 +302,22 @@ class ActivityService {
321
302
  const localTime = now.toLocaleString();
322
303
  const localDate = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
323
304
  const utcDate = now.toISOString().split("T")[0];
324
-
305
+
325
306
  const previousActivityCount = this.todayActivities.length;
326
307
  const previousTMPCount = this.todayTMPEvents.length;
327
308
  const previousReminderCount = this.sentReminders.size;
328
309
  const previousNoActivityNotification = this.sentNoActivityNotification;
329
-
310
+
330
311
  this.logger.info(`[数据重置] 开始重置数据,本地时间: ${localTime}, 本地日期: ${localDate}, UTC日期: ${utcDate}`);
331
312
  this.logger.info(`[数据重置] 重置前数据: 活动${previousActivityCount}个, TMP${previousTMPCount}个, 提醒${previousReminderCount}个, 无活动通知${previousNoActivityNotification ? "已发送" : "未发送"}`);
332
-
313
+
333
314
  this.todayActivities = [];
334
315
  this.todayTMPEvents = [];
335
316
  this.sentReminders.clear();
336
317
  this.sentNoActivityNotification = false;
337
-
318
+
338
319
  this.logger.info(`[数据重置] 每日数据已重置: 活动${previousActivityCount}→0, TMP${previousTMPCount}→0, 提醒${previousReminderCount}→0, 无活动通知${previousNoActivityNotification ? "已发送" : "未发送"}→未发送`);
339
-
320
+
340
321
  this.updateActivityData().then(() => {
341
322
  this.logger.info(`[数据重置] 重置后数据更新完成: 活动${this.todayActivities.length}个, TMP${this.todayTMPEvents.length}个`);
342
323
  }).catch(error => {
@@ -352,7 +333,7 @@ class ActivityService {
352
333
  this.updateTodayActivities(),
353
334
  this.updateTodayTMPEvents()
354
335
  ]);
355
-
336
+
356
337
  const duration = Date.now() - startTime;
357
338
  this.logger.info(`活动数据更新完成,耗时: ${duration}ms`);
358
339
  this.logger.debug(`今日活动数量: ${this.todayActivities.length}, TMP活动数量: ${this.todayTMPEvents.length}`);
@@ -364,7 +345,7 @@ class ActivityService {
364
345
  async updateTodayActivities() {
365
346
  try {
366
347
  this.todayActivities = [];
367
-
348
+
368
349
  const protocol = this.cfg.adminUseHttps ? "https://" : "http://";
369
350
  const fullUrl = `${protocol}${this.cfg.adminApiUrl}/api/activity/info/list?token=${this.cfg.adminApiToken}&page=1&limit=50&themeName=`;
370
351
  this.logger.api(`请求车队平台API: ${fullUrl.replace(this.cfg.adminApiToken, "***")}`);
@@ -386,14 +367,14 @@ class ActivityService {
386
367
  const now = new Date();
387
368
  const today = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
388
369
  this.logger.debug(`[活动更新] 当前本地日期: ${today}, UTC日期: ${new Date().toISOString().split("T")[0]}`);
389
-
370
+
390
371
  const originalCount = response.data.list.length;
391
372
  this.logger.debug(`[活动更新] API返回活动总数: ${originalCount}`);
392
373
  if (this.cfg.debugMode && originalCount > 0) {
393
374
  const activityDates = response.data.list.map(a => `${a.themeName}: ${a.startTime?.split(" ")[0]}`);
394
375
  this.logger.debug(`[活动更新] 所有活动日期:`, activityDates);
395
376
  }
396
-
377
+
397
378
  this.todayActivities = response.data.list.filter((activity) => {
398
379
  const activityDate = activity.startTime?.split(" ")[0];
399
380
  const isToday = activityDate === today;
@@ -402,7 +383,7 @@ class ActivityService {
402
383
  }
403
384
  return isToday;
404
385
  });
405
-
386
+
406
387
  this.logger.info(`[活动更新] 从车队平台找到 ${this.todayActivities.length}/${originalCount} 个今日活动`);
407
388
  if (this.cfg.debugMode && this.todayActivities.length > 0) {
408
389
  const todayActivityNames = this.todayActivities.map(a => `${a.themeName}: ${a.startTime}`);
@@ -421,12 +402,12 @@ class ActivityService {
421
402
  async updateTodayTMPEvents() {
422
403
  try {
423
404
  this.todayTMPEvents = [];
424
-
405
+
425
406
  if (!this.cfg.adminVtcId) {
426
407
  this.logger.warn("[TMP活动更新] TMP API请求失败:未配置adminVtcId");
427
408
  return;
428
409
  }
429
-
410
+
430
411
  const tmpApiUrl = `https://api.truckersmp.com/v2/vtc/${this.cfg.adminVtcId}/events/attending/`;
431
412
  this.logger.api(`[TMP活动更新] 请求TMP API: ${tmpApiUrl}`);
432
413
 
@@ -439,15 +420,15 @@ class ActivityService {
439
420
  const now = new Date();
440
421
  const today = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
441
422
  this.logger.debug(`[TMP活动更新] 当前本地日期: ${today}, UTC日期: ${new Date().toISOString().split("T")[0]}`);
442
-
423
+
443
424
  const originalCount = response.response.length;
444
425
  this.logger.debug(`[TMP活动更新] API返回活动总数: ${originalCount}`);
445
-
426
+
446
427
  if (this.cfg.debugMode && originalCount > 0) {
447
428
  const eventDates = response.response.map(e => `${e.name}: ${e.start_at?.split(" ")[0]}`);
448
429
  this.logger.debug(`[TMP活动更新] 所有活动日期:`, eventDates);
449
430
  }
450
-
431
+
451
432
  this.todayTMPEvents = response.response.filter((event) => {
452
433
  const eventDate = event.start_at?.split(" ")[0];
453
434
  const isToday = eventDate === today;
@@ -456,9 +437,9 @@ class ActivityService {
456
437
  }
457
438
  return isToday;
458
439
  });
459
-
440
+
460
441
  this.logger.info(`[TMP活动更新] 从TMP找到 ${this.todayTMPEvents.length}/${originalCount} 个今日活动`);
461
-
442
+
462
443
  if (this.cfg.debugMode && this.todayTMPEvents.length > 0) {
463
444
  const todayEventNames = this.todayTMPEvents.map(e => `${e.name}: ${e.start_at}`);
464
445
  this.logger.debug(`[TMP活动更新] 今日活动详情:`, todayEventNames);
@@ -473,12 +454,12 @@ class ActivityService {
473
454
 
474
455
  async checkAndSendProfileReminders() {
475
456
  await this.updateActivityData();
476
-
457
+
477
458
  if (this.todayActivities.length === 0) {
478
459
  this.logger.debug("今日没有活动,跳过档位检查");
479
460
  return;
480
461
  }
481
-
462
+
482
463
  this.logger.debug(`开始检查 ${this.todayActivities.length} 个活动的档位状态`);
483
464
 
484
465
  for (const activity of this.todayActivities) {
@@ -510,7 +491,7 @@ class ActivityService {
510
491
  }
511
492
 
512
493
  this.logger.info(`${manualTest ? "手动测试" : "自动"}今日无活动,发送通知到管理群`);
513
-
494
+
514
495
  for (const groupId of this.cfg.adminGroups) {
515
496
  try {
516
497
  await this.sendToGroup(groupId, this.cfg.adminNoActivityMessage, "管理群组");
@@ -542,6 +523,12 @@ class ActivityService {
542
523
  let remindersSent = 0;
543
524
  this.logger.debug(`检查 ${this.todayActivities.length} 个活动的提醒时间,当前本地日期: ${today}, UTC日期: ${todayUTC}`);
544
525
 
526
+ if (this.cfg.mainGroups.length === 0) {
527
+ this.logger.warn(`未配置主群组ID (mainGroups为空),活动提醒将无法发送`);
528
+ } else {
529
+ this.logger.debug(`已配置 ${this.cfg.mainGroups.length} 个主群组: ${this.cfg.mainGroups.join(', ')}`);
530
+ }
531
+
545
532
  for (const activity of this.todayActivities) {
546
533
  try {
547
534
  const activityDate = activity.startTime?.split(" ")[0];
@@ -561,25 +548,35 @@ class ActivityService {
561
548
  const minutesLeft = Math.floor(totalSecondsLeft / 60);
562
549
  const secondsLeft = totalSecondsLeft % 60;
563
550
  this.logger.debug(`活动 "${activity.themeName}" 剩余时间: ${minutesLeft} 分 ${secondsLeft} 秒`);
564
- if (totalSecondsLeft >= -30 && totalSecondsLeft <= 0) {
551
+ this.logger.debug(`活动 "${activity.themeName}" 时间检查: totalSecondsLeft=${totalSecondsLeft}, 触发条件: -300 <= ${totalSecondsLeft} <= 0`);
552
+
553
+ if (totalSecondsLeft >= -300 && totalSecondsLeft <= 0) {
565
554
  const startReminderKey = `${activity.id}_started`;
566
555
  if (!this.sentReminders.has(startReminderKey)) {
567
- this.logger.debug(`触发活动开始提醒: ${activity.themeName}`);
556
+ this.logger.info(`触发活动开始提醒: ${activity.themeName}`);
568
557
  await this.sendActivityStartReminder(activity);
569
558
  this.sentReminders.add(startReminderKey);
570
559
  remindersSent++;
560
+ } else {
561
+ this.logger.debug(`活动 "${activity.themeName}" 开始提醒已发送过,跳过`);
571
562
  }
563
+ } else {
564
+ this.logger.debug(`活动 "${activity.themeName}" 未满足开始提醒条件,当前剩余 ${totalSecondsLeft} 秒`);
572
565
  }
566
+
573
567
  if (totalSecondsLeft < 0) continue;
574
568
  for (const reminderTime of this.cfg.mainActivityReminderTimes) {
575
569
  const reminderTimeSeconds = reminderTime * 60;
576
- if (totalSecondsLeft <= reminderTimeSeconds && totalSecondsLeft > reminderTimeSeconds - 30) {
570
+ this.logger.debug(`活动 "${activity.themeName}" ${reminderTime}分钟前提醒检查: totalSecondsLeft=${totalSecondsLeft}, reminderTimeSeconds=${reminderTimeSeconds}, 条件: ${reminderTimeSeconds - 60} <= ${totalSecondsLeft} <= ${reminderTimeSeconds}`);
571
+ if (totalSecondsLeft <= reminderTimeSeconds && totalSecondsLeft > reminderTimeSeconds - 60) {
577
572
  const reminderKey = `${activity.id}_${reminderTime}`;
578
573
  if (!this.sentReminders.has(reminderKey)) {
579
- this.logger.debug(`触发提醒: ${activity.themeName} - ${reminderTime} 分钟前`);
580
- await this.sendActivityReminder(activity, minutesLeft);
574
+ this.logger.info(`触发活动前提醒: ${activity.themeName} - ${reminderTime} 分钟前`);
575
+ await this.sendActivityReminder(activity, reminderTime);
581
576
  this.sentReminders.add(reminderKey);
582
577
  remindersSent++;
578
+ } else {
579
+ this.logger.debug(`活动 "${activity.themeName}" ${reminderTime}分钟前提醒已发送过,跳过`);
583
580
  }
584
581
  }
585
582
  }
@@ -589,7 +586,9 @@ class ActivityService {
589
586
  }
590
587
 
591
588
  if (remindersSent > 0) {
592
- this.logger.debug(`本轮发送了 ${remindersSent} 个活动提醒`);
589
+ this.logger.info(`本轮发送了 ${remindersSent} 个活动提醒`);
590
+ } else {
591
+ this.logger.debug(`本轮未发送任何活动提醒`);
593
592
  }
594
593
  }
595
594
 
@@ -638,7 +637,7 @@ class ActivityService {
638
637
  this.logger.matching(`活动匹配: "${activity.themeName}" - 找到TMP匹配: ${!!tmpEvent}`);
639
638
 
640
639
  const replacements = this.createActivityReplacements(activity, tmpEvent);
641
-
640
+
642
641
  let message = this.cfg.mainActivityStartReminderMessage;
643
642
  for (const [key, value] of Object.entries(replacements)) {
644
643
  message = message.replace(new RegExp(`{${key}}`, "g"), value);
@@ -650,7 +649,7 @@ class ActivityService {
650
649
 
651
650
  message = message.replace(/\\n/g, "\n").trim();
652
651
  const fullMessage = `@全体成员\n${message}`;
653
-
652
+
654
653
  await this.sendToMainGroups(fullMessage, activity.themeName, "开始提醒");
655
654
  } catch (error) {
656
655
  this.logger.error(`发送活动开始提醒失败:`, error.message);
@@ -665,7 +664,7 @@ class ActivityService {
665
664
  this.logger.matching(`活动匹配: "${activity.themeName}" - 找到TMP匹配: ${!!tmpEvent}`);
666
665
 
667
666
  const replacements = this.createActivityReplacements(activity, tmpEvent, minutesLeft);
668
-
667
+
669
668
  let message = this.cfg.mainActivityReminderMessage;
670
669
  for (const [key, value] of Object.entries(replacements)) {
671
670
  message = message.replace(new RegExp(`{${key}}`, "g"), value);
@@ -677,7 +676,7 @@ class ActivityService {
677
676
 
678
677
  message = message.replace(/\\n/g, "\n").trim();
679
678
  const fullMessage = `@全体成员\n${message}`;
680
-
679
+
681
680
  await this.sendToMainGroups(fullMessage, activity.themeName, `${minutesLeft}分钟前提醒`);
682
681
  } catch (error) {
683
682
  this.logger.error(`发送活动提醒失败:`, error.message);
@@ -738,50 +737,62 @@ class ActivityService {
738
737
 
739
738
  function registerBaseCommands(ctx, cfg) {
740
739
  ctx.command('查询 <tmpId>')
740
+ .usage("查询TMP玩家信息")
741
741
  .action(async ({ session }, tmpId) => await commands.tmpQuery(ctx, cfg, session, tmpId));
742
-
742
+
743
743
  ctx.command('美卡服务器')
744
+ .usage("查询美国卡车模拟器TMP服务器信息")
744
745
  .action(async () => await commands.tmpServer(ctx, cfg, 'ATS'));
745
-
746
+
746
747
  ctx.command('欧卡服务器')
748
+ .usage("查询欧洲卡车模拟2TMP服务器信息")
747
749
  .action(async () => await commands.tmpServer(ctx, cfg, 'ETS2'));
748
-
750
+
749
751
  ctx.command('绑定 <tmpId>')
752
+ .usage("绑定TmpId")
750
753
  .action(async ({ session }, tmpId) => await commands.tmpBind(ctx, cfg, session, tmpId));
751
-
754
+
752
755
  ctx.command('路况 <serverName>')
756
+ .usage("查询欧洲卡车模拟2服务器路况")
757
+ .example("路况 - s1")
753
758
  .action(async ({ session }, serverName) => await commands.tmpTraffic(ctx, cfg, serverName));
754
-
759
+
755
760
  ctx.command('定位 <tmpId>')
761
+ .usage("定位玩家线上位置")
756
762
  .action(async ({ session }, tmpId) => await commands.tmpPosition(ctx, cfg, session, tmpId));
757
-
763
+
758
764
  ctx.command('tmp版本')
765
+ .usage("查询TruckersMP支持的游戏版本")
759
766
  .action(async () => await commands.tmpVersion(ctx));
760
-
767
+
761
768
  ctx.command('地图dlc价格')
769
+ .usage("查询欧洲卡车模拟2地图dlc价格")
762
770
  .action(async ({ session }) => await commands.tmpDlcMap(ctx, session));
763
-
771
+
764
772
  ctx.command('里程排行榜')
773
+ .usage("查询欧洲卡车模拟2里程排行榜")
765
774
  .action(async ({ session }) => await commands.tmpMileageRanking(ctx, session, MileageRankingType.total));
766
-
775
+
767
776
  ctx.command('今日里程排行榜')
777
+ .usage("查询欧洲卡车模拟2今日里程排行榜")
768
778
  .action(async ({ session }) => await commands.tmpMileageRanking(ctx, session, MileageRankingType.today));
769
-
779
+
770
780
  ctx.command('vtc查询 <vtcid>')
781
+ .usage("查询TruckersMP VTC信息")
771
782
  .action(async ({ session }, vtcid) => await commands.tmpVtc(ctx, cfg, session, vtcid));
772
-
783
+
773
784
  ctx.command(`重置密码 [targetTeamId:string]`, "重置欧卡车队平台密码")
774
785
  .usage("重置自己的密码,或管理员重置指定teamId的密码")
775
- .example(`重置密码new - 重置自己的密码`)
776
- .example(`重置密码new 123 - 管理员重置指定teamId的密码`)
786
+ .example(`重置密码 - 重置自己的密码`)
787
+ .example(`重置密码 - 管理员重置指定teamId的密码`)
777
788
  .action(async ({ session }, targetTeamId) => await commands.resetPassword(ctx, cfg, session, targetTeamId));
778
-
789
+
779
790
  ctx.command(`查询积分 [targetQQ:string]`, "查询欧卡车队平台积分")
780
791
  .usage("查询自己或指定QQ号的积分,在群聊中可@他人查询")
781
792
  .example(`查询积分 - 查询自己的积分`)
782
793
  .example(`查询积分 123456 - 查询指定QQ号的积分`)
783
794
  .action(async ({ session }, targetQQ) => await commands.queryPoint(ctx, cfg, session, targetQQ));
784
-
795
+
785
796
  ctx.command('规则查询')
786
797
  .action(async () => 'TruckersMP官方规则链接:https://truckersmp.com/knowledge-base/article/746');
787
798
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ets2-tools-tmp",
3
3
  "description": "欧卡2 TMP在线查询、车队平台查询及活动提醒",
4
- "version": "1.2.0",
4
+ "version": "1.2.2",
5
5
  "contributors": [
6
6
  "opwop <slhp1013@qq.com>",
7
7
  "bot_actions <168329908@qq.com>"