koishi-plugin-ets2-tools-tmp 3.0.3 → 3.0.5

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.
@@ -1,4 +1,17 @@
1
- const BASE_API = 'https://da.vtcm.link'
1
+ const BASE_APIS = ['https://da.vtcm.link', 'https://evmapi.114512.xyz']
2
+
3
+ async function requestWithFallback(http, path) {
4
+ let lastError = null
5
+ for (const baseUrl of BASE_APIS) {
6
+ try {
7
+ const result = await http.get(`${baseUrl}${path}`)
8
+ return result
9
+ } catch (e) {
10
+ lastError = e
11
+ }
12
+ }
13
+ throw lastError
14
+ }
2
15
 
3
16
  module.exports = {
4
17
  /**
@@ -7,7 +20,7 @@ module.exports = {
7
20
  async serverList(http) {
8
21
  let result = null
9
22
  try {
10
- result = await http.get(`${BASE_API}/server/list`)
23
+ result = await requestWithFallback(http, '/server/list')
11
24
  } catch {
12
25
  return {
13
26
  error: true
@@ -30,7 +43,7 @@ module.exports = {
30
43
  async mapPlayerList(http, serverId, ax, ay, bx, by) {
31
44
  let result = null
32
45
  try {
33
- result = await http.get(`${BASE_API}/map/playerList?aAxisX=${ax}&aAxisY=${ay}&bAxisX=${bx}&bAxisY=${by}&serverId=${serverId}`)
46
+ result = await requestWithFallback(http, `/map/playerList?aAxisX=${ax}&aAxisY=${ay}&bAxisX=${bx}&bAxisY=${by}&serverId=${serverId}`)
34
47
  } catch {
35
48
  return {
36
49
  error: true
@@ -52,7 +65,7 @@ module.exports = {
52
65
  async playerInfo(http, tmpId) {
53
66
  let result = null
54
67
  try {
55
- result = await http.get(`${BASE_API}/player/info?tmpId=${tmpId}`)
68
+ result = await requestWithFallback(http, `/player/info?tmpId=${tmpId}`)
56
69
  } catch {
57
70
  return {
58
71
  error: true
@@ -75,7 +88,7 @@ module.exports = {
75
88
  async dlcList(http, type) {
76
89
  let result = null
77
90
  try {
78
- result = await http.get(`${BASE_API}/dlc/list?type=${type}`)
91
+ result = await requestWithFallback(http, `/dlc/list?type=${type}`)
79
92
  } catch (e) {
80
93
  return {
81
94
  error: true
@@ -97,7 +110,7 @@ module.exports = {
97
110
  async mileageRankingList(http, rankingType, tmpId) {
98
111
  let result = null
99
112
  try {
100
- result = await http.get(`${BASE_API}/statistics/mileageRankingList?rankingType=${rankingType}&tmpId=${tmpId || ''}&rankingCount=10`)
113
+ result = await requestWithFallback(http, `/statistics/mileageRankingList?rankingType=${rankingType}&tmpId=${tmpId || ''}&rankingCount=10`)
101
114
  } catch (e) {
102
115
  return {
103
116
  error: true
@@ -119,7 +132,7 @@ module.exports = {
119
132
  async mapPlayerHistory(http, tmpId, serverId, startTime, endTime) {
120
133
  let result = null
121
134
  try {
122
- result = await http.get(`${BASE_API}/map/playerHistory?tmpId=${tmpId || ''}&serverId=${serverId || ''}&startTime=${startTime || ''}&endTime=${endTime || ''}`)
135
+ result = await requestWithFallback(http, `/map/playerHistory?tmpId=${tmpId || ''}&serverId=${serverId || ''}&startTime=${startTime || ''}&endTime=${endTime || ''}`)
123
136
  } catch {
124
137
  return {
125
138
  error: true
@@ -135,4 +148,4 @@ module.exports = {
135
148
  }
136
149
  return data
137
150
  }
138
- }
151
+ }
@@ -143,6 +143,14 @@ class ActivityService {
143
143
  }, `无活动通知定时器: ${this.cfg.noActivity.time}`);
144
144
  }
145
145
 
146
+ if (this.cfg.onlineCheck?.enable) {
147
+ const [onlineHours, onlineMinutes] = this.cfg.onlineCheck.time.split(":").map(Number);
148
+ this.setupTimer(onlineHours, onlineMinutes, () => {
149
+ this.logger.timing(`执行在线成员检查任务 (${this.cfg.onlineCheck.time})`);
150
+ this.checkAndSendOnlineMemberReport();
151
+ }, `在线成员检查定时器: ${this.cfg.onlineCheck.time}`);
152
+ }
153
+
146
154
  const minuteTimer = setInterval(async () => {
147
155
  await this.checkAndSendActivityReminders();
148
156
  }, koishi_1.Time.minute);
@@ -342,6 +350,60 @@ class ActivityService {
342
350
  }
343
351
  }
344
352
 
353
+ async checkAndSendOnlineMemberReport(manualTest = false) {
354
+ try {
355
+ if (this.todayActivities.length === 0 && this.todayTMPEvents.length === 0) {
356
+ this.logger.info(`[在线成员检查] 今日无活动,跳过在线成员检查`);
357
+ return;
358
+ }
359
+
360
+ const apiUrl = this.cfg.onlineCheck?.apiUrl;
361
+ if (!apiUrl) {
362
+ this.logger.error(`[在线成员检查] 未配置API地址`);
363
+ return;
364
+ }
365
+
366
+ this.logger.api(`[在线成员检查] 请求在线成员API: ${apiUrl}`);
367
+ const startTime = Date.now();
368
+ const response = await this.ctx.http.get(apiUrl, { timeout: 10000 });
369
+ const duration = Date.now() - startTime;
370
+ this.logger.api(`[在线成员检查] API响应耗时: ${duration}ms, code: ${response.code}`);
371
+
372
+ if (response.code !== 200 || !Array.isArray(response.data)) {
373
+ this.logger.error(`[在线成员检查] API返回错误: ${response.msg || '未知错误'} (code: ${response.code})`);
374
+ return;
375
+ }
376
+
377
+ const onlineMembers = response.data.filter(member => member.isOnline === true);
378
+ this.logger.info(`[在线成员检查] 总成员数: ${response.data.length}, 在线成员数: ${onlineMembers.length}`);
379
+
380
+ if (onlineMembers.length === 0) {
381
+ this.logger.info(`[在线成员检查] 当前无在线成员`);
382
+ return;
383
+ }
384
+
385
+ let message = `🎮 今日活动在线成员 (${onlineMembers.length}人)\n`;
386
+ message += `━━━━━━━━━━━━━━━━\n`;
387
+ onlineMembers.forEach((member, index) => {
388
+ message += `${index + 1}. ${member.name}\n`;
389
+ message += ` TMP ID: ${member.tmpId}\n`;
390
+ message += ` 服务器: ${member.serverName || '未知'}\n`;
391
+ message += ` 更新时间: ${member.updateTime || '未知'}\n`;
392
+ });
393
+
394
+ for (const groupId of this.cfg.admin.groups) {
395
+ try {
396
+ await this.sendToGroup(groupId, message, "管理群组");
397
+ this.logger.message(`[在线成员检查] 已发送在线成员报告到管理群组 ${groupId}`);
398
+ } catch (error) {
399
+ this.logger.error(`[在线成员检查] 发送到管理群组 ${groupId} 失败:`, error.message);
400
+ }
401
+ }
402
+ } catch (error) {
403
+ this.logger.error(`[在线成员检查] 失败:`, error.message);
404
+ }
405
+ }
406
+
345
407
  async checkAndSendActivityReminders() {
346
408
  const now = new Date();
347
409
  const today = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
package/lib/index.js CHANGED
@@ -186,6 +186,11 @@ exports.Config = koishi_1.Schema.intersect([
186
186
  time: koishi_1.Schema.string().description("今日无活动通知发送时间(HH:mm格式)").default("09:00"),
187
187
  message: koishi_1.Schema.string().description("今日无活动通知消息").default("今日没活动")
188
188
  }).description("无活动通知配置"),
189
+ onlineCheck: koishi_1.Schema.object({
190
+ enable: koishi_1.Schema.boolean().description("启用今日有活动时的在线成员检查").default(false),
191
+ time: koishi_1.Schema.string().description("在线成员检查发送时间(HH:mm格式)").default("20:30"),
192
+ apiUrl: koishi_1.Schema.string().description("在线成员查询API地址(含vtcId参数)").default("https://www.cnly.top/api/player_online/api?vtcId=89225")
193
+ }).description("在线成员检查配置"),
189
194
  mainGroup: koishi_1.Schema.object({
190
195
  groups: koishi_1.Schema.array(koishi_1.Schema.string()).role("table").description("主群群号列表").default([]),
191
196
  activityReminderMessage: koishi_1.Schema.string().description("活动提醒消息模板,支持变量:{name}, {server}, {startingPoint}, {terminalPoint}, {distance}, {banner}, {timeLeft}").default("活动 {name} 还有 {timeLeft} 分钟就要开始啦!\n服务器: {server}\n起点: {startingPoint}\n终点: {terminalPoint}\n距离: {distance}KM"),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ets2-tools-tmp",
3
3
  "description": "欧卡2 TruckersMP信息查询、车队平台查询及活动提醒",
4
- "version": "3.0.3",
4
+ "version": "3.0.5",
5
5
  "contributors": [
6
6
  "opwop <slhp1013@qq.com>",
7
7
  "bot_actions <168329908@qq.com>"
package/readme.md CHANGED
@@ -39,7 +39,7 @@
39
39
 
40
40
  #### API配置
41
41
  - **使用HTTPS协议**:选择是否启用HTTPS协议
42
- - **车队平台URL**:自行部署的车队平台地址(不含协议,仅支持V1.0版本)
42
+ - **车队平台URL**:自行部署的车队平台地址(不含协议)
43
43
  - **车队平台TOKEN**:API访问认证令牌
44
44
  - **VTC ID**:您在TruckersMP的VTC ID
45
45