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.
- package/lib/api/evmOpenApi.js +21 -8
- package/lib/command/tmpActivityService.js +62 -0
- package/lib/index.js +5 -0
- package/package.json +1 -1
- package/readme.md +1 -1
package/lib/api/evmOpenApi.js
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
const
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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