koishi-plugin-ets2-tools-tmp 1.1.0 → 1.1.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 (3) hide show
  1. package/lib/index.js +75 -24
  2. package/package.json +1 -1
  3. package/readme.md +54 -47
package/lib/index.js CHANGED
@@ -300,13 +300,15 @@ class ActivityService {
300
300
  const previousActivityCount = this.todayActivities.length;
301
301
  const previousTMPCount = this.todayTMPEvents.length;
302
302
  const previousReminderCount = this.sentReminders.size;
303
-
304
303
  this.todayActivities = [];
305
304
  this.todayTMPEvents = [];
306
305
  this.sentReminders.clear();
307
-
308
- this.logger.debug(`每日数据已重置: 活动${previousActivityCount}→0, TMP${previousTMPCount}→0, 提醒${previousReminderCount}→0`);
309
- this.updateActivityData();
306
+ this.logger.info(`[数据重置] 每日数据已重置: 活动${previousActivityCount}→0, TMP${previousTMPCount}→0, 提醒${previousReminderCount}→0`);
307
+ this.updateActivityData().then(() => {
308
+ this.logger.info(`[数据重置] 重置后数据更新完成: 活动${this.todayActivities.length}个, TMP${this.todayTMPEvents.length}个`);
309
+ }).catch(error => {
310
+ this.logger.error(`[数据重置] 重置后数据更新失败:`, error.message);
311
+ });
310
312
  }
311
313
 
312
314
  async updateActivityData() {
@@ -328,6 +330,8 @@ class ActivityService {
328
330
 
329
331
  async updateTodayActivities() {
330
332
  try {
333
+ this.todayActivities = [];
334
+
331
335
  const protocol = this.cfg.adminUseHttps ? "https://" : "http://";
332
336
  const fullUrl = `${protocol}${this.cfg.adminApiUrl}/api/activity/info/list?token=${this.cfg.adminApiToken}&page=1&limit=50&themeName=`;
333
337
  this.logger.api(`请求车队平台API: ${fullUrl.replace(this.cfg.adminApiToken, "***")}`);
@@ -347,53 +351,88 @@ class ActivityService {
347
351
 
348
352
  if (response.code === 0 && response.data?.list) {
349
353
  const today = new Date().toISOString().split("T")[0];
354
+ this.logger.debug(`[活动更新] 当前日期: ${today}`);
355
+
350
356
  const originalCount = response.data.list.length;
357
+ this.logger.debug(`[活动更新] API返回活动总数: ${originalCount}`);
358
+ if (this.cfg.debugMode && originalCount > 0) {
359
+ const activityDates = response.data.list.map(a => `${a.themeName}: ${a.startTime?.split(" ")[0]}`);
360
+ this.logger.debug(`[活动更新] 所有活动日期:`, activityDates);
361
+ }
362
+
351
363
  this.todayActivities = response.data.list.filter((activity) => {
352
364
  const activityDate = activity.startTime?.split(" ")[0];
353
- return activityDate === today;
365
+ const isToday = activityDate === today;
366
+ if (!isToday && this.cfg.debugMode) {
367
+ this.logger.debug(`[活动更新] 跳过非今日活动: ${activity.themeName}, 日期: ${activityDate}`);
368
+ }
369
+ return isToday;
354
370
  });
355
- this.logger.info(`从车队平台找到 ${this.todayActivities.length}/${originalCount} 个今日活动`);
371
+
372
+ this.logger.info(`[活动更新] 从车队平台找到 ${this.todayActivities.length}/${originalCount} 个今日活动`);
373
+ if (this.cfg.debugMode && this.todayActivities.length > 0) {
374
+ const todayActivityNames = this.todayActivities.map(a => `${a.themeName}: ${a.startTime}`);
375
+ this.logger.debug(`[活动更新] 今日活动详情:`, todayActivityNames);
376
+ }
356
377
  } else {
357
- this.logger.error(`车队平台API返回错误: ${response.msg || '未知错误'} (代码: ${response.code || '无'})`);
378
+ this.logger.error(`[活动更新] 车队平台API返回错误: ${response.msg || '未知错误'} (代码: ${response.code || '无'})`);
358
379
  this.todayActivities = [];
359
380
  }
360
381
  } catch (error) {
361
- this.logger.error("获取车队平台活动列表失败:", error.message);
382
+ this.logger.error("[活动更新] 获取车队平台活动列表失败:", error.message);
362
383
  this.todayActivities = [];
363
384
  }
364
385
  }
365
386
 
366
387
  async updateTodayTMPEvents() {
367
388
  try {
389
+ this.todayTMPEvents = [];
390
+
368
391
  if (!this.cfg.adminVtcId) {
369
- this.logger.warn("TMP API请求失败:未配置adminVtcId");
370
- this.todayTMPEvents = [];
392
+ this.logger.warn("[TMP活动更新] TMP API请求失败:未配置adminVtcId");
371
393
  return;
372
394
  }
373
395
 
374
396
  const tmpApiUrl = `https://api.truckersmp.com/v2/vtc/${this.cfg.adminVtcId}/events/attending/`;
375
- this.logger.api(`请求TMP API: ${tmpApiUrl}`);
397
+ this.logger.api(`[TMP活动更新] 请求TMP API: ${tmpApiUrl}`);
376
398
 
377
399
  const startTime = Date.now();
378
400
  const response = await this.ctx.http.get(tmpApiUrl, { timeout: 10000 });
379
401
  const duration = Date.now() - startTime;
380
- this.logger.api(`TMP API响应耗时: ${duration}ms, 错误状态: ${response.error}`);
402
+ this.logger.api(`[TMP活动更新] TMP API响应耗时: ${duration}ms, 错误状态: ${response.error}`);
381
403
 
382
404
  if (!response.error && Array.isArray(response.response)) {
383
405
  const today = new Date().toISOString().split("T")[0];
406
+ this.logger.debug(`[TMP活动更新] 当前日期: ${today}`);
407
+
384
408
  const originalCount = response.response.length;
409
+ this.logger.debug(`[TMP活动更新] API返回活动总数: ${originalCount}`);
410
+
411
+ if (this.cfg.debugMode && originalCount > 0) {
412
+ const eventDates = response.response.map(e => `${e.name}: ${e.start_at?.split(" ")[0]}`);
413
+ this.logger.debug(`[TMP活动更新] 所有活动日期:`, eventDates);
414
+ }
415
+
385
416
  this.todayTMPEvents = response.response.filter((event) => {
386
417
  const eventDate = event.start_at?.split(" ")[0];
387
- return eventDate === today;
418
+ const isToday = eventDate === today;
419
+ if (!isToday && this.cfg.debugMode) {
420
+ this.logger.debug(`[TMP活动更新] 跳过非今日活动: ${event.name}, 日期: ${eventDate}`);
421
+ }
422
+ return isToday;
388
423
  });
389
- this.logger.info(`从TMP找到 ${this.todayTMPEvents.length}/${originalCount} 个今日活动`);
424
+
425
+ this.logger.info(`[TMP活动更新] 从TMP找到 ${this.todayTMPEvents.length}/${originalCount} 个今日活动`);
426
+
427
+ if (this.cfg.debugMode && this.todayTMPEvents.length > 0) {
428
+ const todayEventNames = this.todayTMPEvents.map(e => `${e.name}: ${e.start_at}`);
429
+ this.logger.debug(`[TMP活动更新] 今日活动详情:`, todayEventNames);
430
+ }
390
431
  } else {
391
- this.logger.error(`TMP API返回错误: ${response.message || '未知错误'}`);
392
- this.todayTMPEvents = [];
432
+ this.logger.error(`[TMP活动更新] TMP API返回错误: ${response.message || '未知错误'}`);
393
433
  }
394
434
  } catch (error) {
395
- this.logger.error("获取TMP活动失败:", error.message);
396
- this.todayTMPEvents = [];
435
+ this.logger.error("[TMP活动更新] 获取TMP活动失败:", error.message);
397
436
  }
398
437
  }
399
438
 
@@ -424,11 +463,18 @@ class ActivityService {
424
463
 
425
464
  async checkAndSendActivityReminders() {
426
465
  const now = new Date();
466
+ const today = now.toISOString().split("T")[0];
427
467
  let remindersSent = 0;
428
- this.logger.debug(`检查 ${this.todayActivities.length} 个活动的提醒时间`);
468
+ this.logger.debug(`检查 ${this.todayActivities.length} 个活动的提醒时间,当前日期: ${today}`);
429
469
 
430
470
  for (const activity of this.todayActivities) {
431
471
  try {
472
+ const activityDate = activity.startTime?.split(" ")[0];
473
+ if (activityDate !== today) {
474
+ this.logger.debug(`跳过非今日活动 "${activity.themeName}",活动日期: ${activityDate},当前日期: ${today}`);
475
+ continue;
476
+ }
477
+
432
478
  const activityStartTime = new Date(activity.startTime);
433
479
  if (isNaN(activityStartTime.getTime())) {
434
480
  this.logger.warn(`活动 "${activity.themeName}" 开始时间格式错误,跳过提醒`);
@@ -436,10 +482,13 @@ class ActivityService {
436
482
  }
437
483
 
438
484
  const timeDiff = activityStartTime.getTime() - now.getTime();
439
- const minutesLeft = Math.floor(timeDiff / (1e3 * 60));
440
- this.logger.debug(`活动 "${activity.themeName}" 剩余时间: ${minutesLeft} 分钟`);
485
+ const totalSecondsLeft = Math.floor(timeDiff / 1000);
486
+ const minutesLeft = Math.floor(totalSecondsLeft / 60);
487
+ const secondsLeft = totalSecondsLeft % 60;
488
+ this.logger.debug(`活动 "${activity.themeName}" 剩余时间: ${minutesLeft} 分 ${secondsLeft} 秒`);
441
489
 
442
- if (minutesLeft <= 0 && minutesLeft > -1) {
490
+ // 活动开始提醒:只在活动开始时间点触发(允许30秒误差)
491
+ if (totalSecondsLeft >= -30 && totalSecondsLeft <= 0) {
443
492
  const startReminderKey = `${activity.id}_started`;
444
493
  if (!this.sentReminders.has(startReminderKey)) {
445
494
  this.logger.debug(`触发活动开始提醒: ${activity.themeName}`);
@@ -449,9 +498,11 @@ class ActivityService {
449
498
  }
450
499
  }
451
500
 
452
- if (minutesLeft < 0) continue;
501
+ // 活动前提醒:只在精确时间点触发(允许30秒误差)
502
+ if (totalSecondsLeft < 0) continue;
453
503
  for (const reminderTime of this.cfg.mainActivityReminderTimes) {
454
- if (minutesLeft <= reminderTime && minutesLeft > reminderTime - 1) {
504
+ const reminderTimeSeconds = reminderTime * 60;
505
+ if (totalSecondsLeft <= reminderTimeSeconds && totalSecondsLeft > reminderTimeSeconds - 30) {
455
506
  const reminderKey = `${activity.id}_${reminderTime}`;
456
507
  if (!this.sentReminders.has(reminderKey)) {
457
508
  this.logger.debug(`触发提醒: ${activity.themeName} - ${reminderTime} 分钟前`);
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.1.0",
4
+ "version": "1.1.2",
5
5
  "contributors": [
6
6
  "opwop <slhp1013@qq.com>",
7
7
  "bot_actions <168329908@qq.com>"
package/readme.md CHANGED
@@ -2,63 +2,63 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/koishi-plugin-ets2-tools-tmp?style=flat-square)](https://www.npmjs.com/package/koishi-plugin-tmp-bot)
4
4
 
5
- ## 插件介绍
5
+ ## 🚛 插件介绍
6
6
 
7
- 一款集欧洲卡车模拟2 (ETS2) / 美国卡车模拟 (ATS) TMP数据查询与车队活动管理于一体的多功能插件,支持自动获取活动信息、发送智能提醒,同时提供丰富的游戏数据查询功能,适配QQ等主流聊天平台。
7
+ 一款专为欧洲卡车模拟2 (ETS2) / 美国卡车模拟 (ATS) 玩家打造的多功能插件,集成TMP数据查询与车队活动管理功能。支持自动获取活动信息、智能提醒推送,提供丰富的游戏数据查询服务,完美适配QQ等主流聊天平台。
8
8
 
9
- ## 功能特性
9
+ ## 功能特性
10
10
 
11
11
  ### 🎮 核心查询功能
12
- - **玩家数据查询**: 支持TMP玩家信息、位置查询,绑定ID后操作更便捷
13
- - **服务器与路况**: 查询欧卡/美卡服务器状态、热门地点路况(支持服务器简称)
14
- - **游戏资源查询**: 地图DLC价格、TMP版本信息查询
15
- - **排行与积分**: 总里程/今日里程排行榜、车队平台积分查询
16
- - **VTC与规则**: 支持指定VTC ID查询,提供TruckersMP官方规则链接
12
+ - **玩家数据查询**:支持TMP玩家信息、实时位置查询,绑定ID后操作更便捷
13
+ - **服务器与路况**:查询欧卡/美卡服务器状态、热门地点路况(支持服务器简称速查)
14
+ - **游戏资源查询**:地图DLC价格、TMP版本信息一键获取
15
+ - **排行与积分**:总里程/今日里程排行榜、车队平台积分查询
16
+ - **VTC与规则**:支持指定VTC ID查询,提供TruckersMP官方规则快速链接
17
17
 
18
18
  ### 🚚 车队活动管理
19
- - **双数据源支持**: 同时从车队平台(V1.0)和TruckersMP API获取活动数据
20
- - **智能提醒机制**: 活动开始前按配置时间发送提醒,支持多时间点设置
21
- - **档位状态检查**: 自动检测活动档上传状态,向管理群发送提醒
22
- - **多群组适配**: 区分管理群与主群,按需发送不同类型消息
19
+ - **双数据源支持**:同时对接车队平台(V1.0)和TruckersMP API获取活动数据
20
+ - **智能提醒机制**:活动开始前按配置时间自动发送提醒,支持多时间点精准设置
21
+ - **档位状态检查**:自动检测活动档上传状态,及时向管理群发送提醒
22
+ - **多群组适配**:区分管理群与主群,按需发送不同类型通知消息
23
23
 
24
24
  ### ⚙️ 灵活配置选项
25
- - **数据源自定义**: 独立选择服务器、起点、终点信息来源(车队平台/ TMP API)
26
- - **定时任务配置**: 自定义活动检查、消息发送的时间节点
27
- - **消息模板编辑**: 支持变量替换的个性化提醒模板
28
- - **权限与适配**: 管理员专用功能(密码重置),兼容主流聊天平台
25
+ - **数据源自定义**:独立选择服务器、起点、终点信息来源(车队平台/ TMP API)
26
+ - **定时任务配置**:自定义活动检查、消息发送的时间节点
27
+ - **消息模板编辑**:支持变量替换的个性化提醒模板,打造专属通知风格
28
+ - **权限与适配**:管理员专用功能(密码重置),兼容主流聊天平台
29
29
 
30
30
  ### 🔧 开发者支持
31
- - **多级日志记录**: 调试模式、API监控、定时任务记录等细分日志选项
32
- - **详细调试信息**: 插件运行状态、数据统计一键查看
33
- - **接口文档支持**: 提供TMP数据接口文档,便于二次开发
31
+ - **多级日志记录**:调试模式、API监控、定时任务记录等细分日志选项
32
+ - **详细调试信息**:插件运行状态、数据统计一键查看
33
+ - **接口文档支持**:提供TMP数据接口文档,便于二次开发扩展
34
34
 
35
- ## 安装配置
35
+ ## 📦 安装配置
36
36
 
37
37
  ### 1. 基础配置
38
38
 
39
39
  #### API配置
40
- - **使用HTTPS协议**: 选择是否启用HTTPS协议
41
- - **车队平台URL**: 自行部署的车队平台地址(不含协议,仅支持V1.0版本)
42
- - **车队平台TOKEN**: API访问认证令牌
43
- - **VTC ID**: 您在TruckersMP的VTC ID
40
+ - **使用HTTPS协议**:选择是否启用HTTPS协议
41
+ - **车队平台URL**:自行部署的车队平台地址(不含协议,仅支持V1.0版本)
42
+ - **车队平台TOKEN**:API访问认证令牌
43
+ - **VTC ID**:您在TruckersMP的VTC ID
44
44
 
45
45
  #### 翻译配置(可选)
46
- - **启用百度翻译**: 开启/关闭翻译功能
47
- - **百度翻译APP ID**: 翻译服务认证ID
48
- - **百度翻译秘钥**: 翻译服务认证密钥
49
- - **启用翻译缓存**: 减少重复翻译请求,提升效率
46
+ - **启用百度翻译**:开启/关闭翻译功能
47
+ - **百度翻译APP ID**:翻译服务认证ID
48
+ - **百度翻译秘钥**:翻译服务认证密钥
49
+ - **启用翻译缓存**:减少重复翻译请求,提升效率
50
50
 
51
51
  ### 2. 群组配置
52
52
 
53
53
  #### 管理群设置
54
- - **活动检查时间**: 检查活动档位状态的时间(HH:mm格式)
55
- - **信息发送时间**: 发送档位提醒的时间(HH:mm格式)
56
- - **管理群组ID**: 接收管理提醒(档位状态、异常通知)的群组ID列表
54
+ - **活动检查时间**:检查活动档位状态的时间(HH:mm格式)
55
+ - **信息发送时间**:发送档位提醒的时间(HH:mm格式)
56
+ - **管理群组ID**:接收管理提醒(档位状态、异常通知)的群组ID列表
57
57
 
58
58
  #### 主群设置
59
- - **主群群号**: 接收活动开始提醒的群组ID列表
60
- - **活动提醒消息模板**: 支持变量替换的自定义模板
61
- - **活动提醒时间**: 活动开始前的提醒时间点(分钟)
59
+ - **主群群号**:接收活动开始提醒的群组ID列表
60
+ - **活动提醒消息模板**:支持变量替换的自定义模板
61
+ - **活动提醒时间**:活动开始前的提醒时间点(分钟)
62
62
 
63
63
  ### 3. 数据源与消息配置
64
64
 
@@ -69,18 +69,25 @@
69
69
  - 活动横幅显示开关
70
70
 
71
71
  #### 消息内容配置
72
- - **档位已上传消息**: 活动档上传完成时的提示文案
73
- - **档位未上传消息**: 活动档未上传时的提醒文案
74
- - **活动提醒模板变量**: `{name}`(活动名)、`{server}`(服务器)、`{startingPoint}`(起点)、`{terminalPoint}`(终点)、`{distance}`(距离)、`{banner}`(横幅)、`{timeLeft}`(剩余时间)
72
+ - **档位已上传消息**:活动档上传完成时的提示文案
73
+ - **档位未上传消息**:活动档未上传时的提醒文案
74
+ - **活动提醒模板变量**:
75
+ - `{name}`(活动名)
76
+ - `{server}`(服务器)
77
+ - `{startingPoint}`(起点)
78
+ - `{terminalPoint}`(终点)
79
+ - `{distance}`(距离)
80
+ - `{banner}`(横幅)
81
+ - `{timeLeft}`(剩余时间)
75
82
 
76
83
  ### 4. 开发者选项
77
- - **调试模式**: 启用后输出详细运行日志
78
- - **记录API响应**: 记录API请求参数与响应详情
79
- - **记录定时任务**: 记录定时任务执行时间、结果
80
- - **记录活动匹配**: 记录活动数据跨源匹配过程
81
- - **记录消息发送**: 记录消息发送状态、接收群组
84
+ - **调试模式**:启用后输出详细运行日志
85
+ - **记录API响应**:记录API请求参数与响应详情
86
+ - **记录定时任务**:记录定时任务执行时间、结果
87
+ - **记录活动匹配**:记录活动数据跨源匹配过程
88
+ - **记录消息发送**:记录消息发送状态、接收群组
82
89
 
83
- ## 指令说明
90
+ ## 📋 指令说明
84
91
 
85
92
  | 指令名称 | 指令介绍 | 使用示例 |
86
93
  |------------------|---------------------------------------------------------------------------------------------------------------------------------------------|------------------------|
@@ -102,7 +109,7 @@
102
109
  | 活动DEBUG | 查看插件运行状态、数据统计等调试信息 | 活动DEBUG |
103
110
  | 重置数据 | 手动重置今日活动数据与提醒记录 | 重置数据 |
104
111
 
105
- ## 使用方法
112
+ ## 📝 使用方法
106
113
 
107
114
  ### 自动功能
108
115
  - 每日凌晨2点自动重置活动数据
@@ -113,9 +120,9 @@
113
120
  ### 注意事项
114
121
  - 车队平台仅支持V1.0版本,V2.0版本适配将在后续更新
115
122
  - 路况查询仅支持指定服务器简称,需按规则输入(s1/s2/p/a)
116
- - 管理员专用功能(如批量重置密码)需提前配置管理员权限
123
+ - 管理员专用功能(如重置密码)需提前配置管理员权限
117
124
 
118
- ## 技术支持
125
+ ## 🔍 技术支持
119
126
 
120
127
  ### 接口文档
121
128
  TMP数据接口文档:https://apifox.com/apidoc/shared/38508a88-5ff4-4b29-b724-41f9d3d3336a
@@ -126,7 +133,7 @@ TMP数据接口文档:https://apifox.com/apidoc/shared/38508a88-5ff4-4b29-b724
126
133
  3. 确认群组ID格式正确,机器人拥有发送消息权限
127
134
  4. 定时任务未执行可检查服务器时间与配置时间是否匹配
128
135
 
129
- ## 鸣谢
136
+ ## 致谢
130
137
  特别感谢 [79887143](https://github.com/79887143) 提供的API接口与开发思路,基于其开源项目 [koishi-plugin-tmp-bot](https://github.com/79887143/koishi-plugin-tmp-bot?tab=readme-ov-file#koishi-plugin-tmp-bot) 扩展开发。
131
138
 
132
139
  ## 版本信息