koishi-plugin-ets2-tools-tmp 2.5.91 → 3.0.0

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 (31) hide show
  1. package/lib/command/ets-app/addMember/addMemberV2.js +93 -0
  2. package/lib/command/ets-app/changePoint/changePoint.js +14 -0
  3. package/lib/command/ets-app/changePoint/changePointV1.js +3 -0
  4. package/lib/command/ets-app/changePoint/changePointV2.js +91 -0
  5. package/lib/command/ets-app/queryPoint/queryPoint.js +38 -0
  6. package/lib/command/ets-app/queryPoint/queryPointV1.js +51 -0
  7. package/lib/command/ets-app/queryPoint/queryPointV2.js +51 -0
  8. package/lib/command/ets-app/resetPassword/resetPassword.js +20 -0
  9. package/lib/command/ets-app/resetPassword/resetPasswordV1.js +115 -0
  10. package/lib/command/ets-app/resetPassword/resetPasswordV2.js +71 -0
  11. package/lib/command/tmpActivityService/tmpActivityServiceV1.js +71 -0
  12. package/lib/command/tmpActivityService/tmpActivityServiceV2.js +85 -0
  13. package/lib/command/tmpActivityService.js +13 -120
  14. package/lib/command/tmpDlcMap.js +1 -1
  15. package/lib/command/tmpFootprint.js +1 -1
  16. package/lib/command/tmpMileageRanking.js +1 -1
  17. package/lib/command/tmpPosition.js +1 -1
  18. package/lib/command/tmpServer/tmpServer.d.ts +2 -0
  19. package/lib/command/tmpServer/tmpServer.js +15 -0
  20. package/lib/command/tmpServer/tmpServerImg.d.ts +3 -0
  21. package/lib/command/tmpServer/tmpServerImg.js +35 -0
  22. package/lib/command/tmpServer/tmpServerText.d.ts +2 -0
  23. package/lib/command/tmpServer/tmpServerText.js +33 -0
  24. package/lib/command/tmpTraffic/tmpTrafficMap.js +1 -1
  25. package/lib/index.js +50 -15
  26. package/lib/resource/dlc.html +1 -1
  27. package/lib/resource/footprint.html +2 -2
  28. package/lib/resource/position.html +1 -1
  29. package/lib/resource/server-list.html +298 -0
  30. package/lib/resource/traffic.html +1 -1
  31. package/package.json +1 -1
@@ -0,0 +1,85 @@
1
+ module.exports = {
2
+ async updateTodayActivities() {
3
+ try {
4
+ this.todayActivities = [];
5
+
6
+ const baseUrl = this.cfg.mainSettings?.url || "open.vtcm.link";
7
+ const token = this.cfg.mainSettings?.token || "";
8
+ const fullUrl = `https://${baseUrl}/events`;
9
+ this.logger.api(`请求V2车队平台API: ${fullUrl}`);
10
+
11
+ const startTime = Date.now();
12
+ const response = await this.ctx.http.get(fullUrl, {
13
+ timeout: 10000,
14
+ headers: { token }
15
+ });
16
+ const duration = Date.now() - startTime;
17
+ this.logger.api(`V2车队平台API响应耗时: ${duration}ms, 状态码: ${response.code}`);
18
+
19
+ if (this.cfg.debug?.logApiResponses) {
20
+ this.logger.api("V2车队平台API响应详情:", {
21
+ code: response.code,
22
+ totalCount: response.total,
23
+ listCount: response.rows?.length
24
+ });
25
+ }
26
+
27
+ if (response.code === 200 && response.rows) {
28
+ const now = new Date();
29
+ const today = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
30
+ this.logger.debug(`[V2活动更新] 当前本地日期: ${today}, UTC日期: ${new Date().toISOString().split("T")[0]}`);
31
+
32
+ const originalCount = response.rows.length;
33
+ this.logger.debug(`[V2活动更新] API返回活动总数: ${originalCount}`);
34
+
35
+ this.todayActivities = response.rows.filter((activity) => {
36
+ return activity.eventDate === today;
37
+ }).map((activity) => ({
38
+ ...activity,
39
+ themeName: activity.eventName,
40
+ startTime: activity.eventDate,
41
+ profileFile: activity.saveFileId
42
+ }));
43
+
44
+ this.logger.info(`[V2活动更新] 从车队平台找到 ${this.todayActivities.length}/${originalCount} 个今日活动`);
45
+ if (this.cfg.debug?.debugMode && this.todayActivities.length > 0) {
46
+ const todayActivityNames = this.todayActivities.map(a => `${a.themeName}: ${a.startTime}`);
47
+ this.logger.debug(`[V2活动更新] 今日活动详情:`, todayActivityNames);
48
+ }
49
+ } else {
50
+ this.logger.error(`[V2活动更新] 车队平台API返回错误: ${response.msg || '未知错误'} (代码: ${response.code || '无'})`);
51
+ this.todayActivities = [];
52
+ }
53
+ } catch (error) {
54
+ this.logger.error("[V2活动更新] 获取车队平台活动列表失败:", error.message);
55
+ this.todayActivities = [];
56
+ }
57
+ },
58
+
59
+ async checkAutoClock(activity) {
60
+ try {
61
+ const baseUrl = this.cfg.mainSettings?.url || "open.vtcm.link";
62
+ const token = this.cfg.mainSettings?.token || "";
63
+ const fullUrl = `https://${baseUrl}/events/${activity.id}`;
64
+ this.logger.api(`请求V2活动详情API: ${fullUrl}`);
65
+
66
+ const response = await this.ctx.http.get(fullUrl, {
67
+ timeout: 10000,
68
+ headers: { token }
69
+ });
70
+ this.logger.api(`V2活动详情API响应:`, response);
71
+
72
+ if (response.code === 200 && response.data) {
73
+ const autoCheckInEnable = response.data.autoCheckInEnable;
74
+ this.logger.debug(`活动 "${activity.themeName}" V2自动打卡状态: ${autoCheckInEnable}`);
75
+ return autoCheckInEnable === 1;
76
+ } else {
77
+ this.logger.error(`V2活动详情API返回错误: ${response.msg || '未知错误'} (代码: ${response.code || '无'})`);
78
+ return false;
79
+ }
80
+ } catch (error) {
81
+ this.logger.error(`检查V2活动 "${activity.themeName}" 自动打卡状态失败:`, error.message);
82
+ return false;
83
+ }
84
+ }
85
+ };
@@ -4,6 +4,9 @@ exports.ActivityService = void 0;
4
4
 
5
5
  const koishi_1 = require("koishi");
6
6
 
7
+ const v1Methods = require('./tmpActivityService/tmpActivityServiceV1');
8
+ const v2Methods = require('./tmpActivityService/tmpActivityServiceV2');
9
+
7
10
  class ActivityService {
8
11
  constructor(ctx, config) {
9
12
  this.ctx = ctx;
@@ -14,6 +17,13 @@ class ActivityService {
14
17
  this.sentNoActivityNotification = false;
15
18
  this.timers = [];
16
19
  this.logger = this.initLogger();
20
+
21
+ const platformVersion = (this.cfg.mainSettings?.platformVersion || "v1").toLowerCase();
22
+ if (platformVersion === "v2") {
23
+ Object.assign(this, v2Methods);
24
+ } else {
25
+ Object.assign(this, v1Methods);
26
+ }
17
27
  }
18
28
 
19
29
  initLogger() {
@@ -215,63 +225,6 @@ class ActivityService {
215
225
  }
216
226
  }
217
227
 
218
- async updateTodayActivities() {
219
- try {
220
- this.todayActivities = [];
221
-
222
- const protocol = this.cfg.api.useHttps ? "https://" : "http://";
223
- const fullUrl = `${protocol}${this.cfg.api.url}/api/activity/info/list?token=${this.cfg.api.token}&page=1&limit=100&themeName=`;
224
- this.logger.api(`请求车队平台API: ${fullUrl.replace(this.cfg.api.token, "***")}`);
225
-
226
- const startTime = Date.now();
227
- const response = await this.ctx.http.get(fullUrl, { timeout: 10000 });
228
- const duration = Date.now() - startTime;
229
- this.logger.api(`车队平台API响应耗时: ${duration}ms, 状态码: ${response.code}`);
230
-
231
- if (this.cfg.debug?.logApiResponses) {
232
- this.logger.api("车队平台API响应详情:", {
233
- code: response.code,
234
- totalCount: response.data?.totalCount,
235
- listCount: response.data?.list?.length
236
- });
237
- }
238
-
239
- if (response.code === 0 && response.data?.list) {
240
- const now = new Date();
241
- const today = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
242
- this.logger.debug(`[活动更新] 当前本地日期: ${today}, UTC日期: ${new Date().toISOString().split("T")[0]}`);
243
-
244
- const originalCount = response.data.list.length;
245
- this.logger.debug(`[活动更新] API返回活动总数: ${originalCount}`);
246
- if (this.cfg.debug?.debugMode && originalCount > 0) {
247
- const activityDates = response.data.list.map(a => `${a.themeName}: ${a.startTime?.split(" ")[0]}`);
248
- this.logger.debug(`[活动更新] 所有活动日期:`, activityDates);
249
- }
250
-
251
- this.todayActivities = response.data.list.filter((activity) => {
252
- const activityDate = activity.startTime?.split(" ")[0];
253
- const isToday = activityDate === today;
254
- if (!isToday && this.cfg.debug?.debugMode) {
255
- this.logger.debug(`[活动更新] 跳过非今日活动: ${activity.themeName}, 日期: ${activityDate}, 当前日期: ${today}`);
256
- }
257
- return isToday;
258
- });
259
-
260
- this.logger.info(`[活动更新] 从车队平台找到 ${this.todayActivities.length}/${originalCount} 个今日活动`);
261
- if (this.cfg.debug?.debugMode && this.todayActivities.length > 0) {
262
- const todayActivityNames = this.todayActivities.map(a => `${a.themeName}: ${a.startTime}`);
263
- this.logger.debug(`[活动更新] 今日活动详情:`, todayActivityNames);
264
- }
265
- } else {
266
- this.logger.error(`[活动更新] 车队平台API返回错误: ${response.msg || '未知错误'} (代码: ${response.code || '无'})`);
267
- this.todayActivities = [];
268
- }
269
- } catch (error) {
270
- this.logger.error("[活动更新] 获取车队平台活动列表失败:", error.message);
271
- this.todayActivities = [];
272
- }
273
- }
274
-
275
228
  async updateTodayTMPEvents() {
276
229
  try {
277
230
  this.todayTMPEvents = [];
@@ -603,19 +556,11 @@ class ActivityService {
603
556
 
604
557
  this.logger.debug(`开始检查 ${this.todayActivities.length} 个活动的自动打卡状态`);
605
558
 
606
- const platformVersion = (this.cfg.mainSettings?.platformVersion || "v1").toLowerCase();
607
-
608
559
  for (const activity of this.todayActivities) {
609
560
  try {
610
- let autoClockEnabled = false;
561
+ const autoClockEnabled = await this.checkAutoClock(activity);
611
562
 
612
- if (platformVersion === "v1") {
613
- autoClockEnabled = await this.checkV1AutoClock(activity);
614
- } else if (platformVersion === "v2") {
615
- autoClockEnabled = await this.checkV2AutoClock(activity);
616
- }
617
-
618
- const message = autoClockEnabled
563
+ const message = autoClockEnabled
619
564
  ? `今日活动自动打卡已设置`
620
565
  : `请注意,今日活动打卡未设置。\n 活动名称: ${activity.themeName || '未知活动'}`;
621
566
 
@@ -635,58 +580,6 @@ class ActivityService {
635
580
  }
636
581
  }
637
582
 
638
- async checkV1AutoClock(activity) {
639
- try {
640
- const protocol = this.cfg.api.useHttps ? "https://" : "http://";
641
- const fullUrl = `${protocol}${this.cfg.api.url}/api/activity/info/info/${activity.id}?token=${this.cfg.api.token}`;
642
- this.logger.api(`请求V1活动详情API: ${fullUrl.replace(this.cfg.api.token, "***")}`);
643
-
644
- const response = await this.ctx.http.get(fullUrl, { timeout: 10000 });
645
- this.logger.api(`V1活动详情API响应:`, response);
646
-
647
- if (response.code === 0 && response.data) {
648
- const enableAutoClock = response.data.enableAutoClock;
649
- this.logger.debug(`活动 "${activity.themeName}" V1自动打卡状态: ${enableAutoClock}`);
650
- return enableAutoClock === 1;
651
- } else {
652
- this.logger.error(`V1活动详情API返回错误: ${response.msg || '未知错误'} (代码: ${response.code || '无'})`);
653
- return false;
654
- }
655
- } catch (error) {
656
- this.logger.error(`检查V1活动 "${activity.themeName}" 自动打卡状态失败:`, error.message);
657
- return false;
658
- }
659
- }
660
-
661
- async checkV2AutoClock(activity) {
662
- try {
663
- const protocol = this.cfg.api.useHttps ? "https://" : "http://";
664
- const fullUrl = `${protocol}${this.cfg.api.url}/activity/list?token=${this.cfg.api.token}`;
665
- this.logger.api(`请求V2活动列表API: ${fullUrl.replace(this.cfg.api.token, "***")}`);
666
-
667
- const response = await this.ctx.http.get(fullUrl, { timeout: 10000 });
668
- this.logger.api(`V2活动列表API响应:`, response);
669
-
670
- if (response.code === 200 && response.data?.rows) {
671
- const activityDetail = response.data.rows.find(row => row.id === activity.id);
672
- if (activityDetail) {
673
- const autoCheckInEnable = activityDetail.autoCheckInEnable;
674
- this.logger.debug(`活动 "${activity.themeName}" V2自动打卡状态: ${autoCheckInEnable}`);
675
- return autoCheckInEnable === 1;
676
- } else {
677
- this.logger.warn(`在V2活动列表中未找到活动ID: ${activity.id}`);
678
- return false;
679
- }
680
- } else {
681
- this.logger.error(`V2活动列表API返回错误: ${response.msg || '未知错误'} (代码: ${response.code || '无'})`);
682
- return false;
683
- }
684
- } catch (error) {
685
- this.logger.error(`检查V2活动 "${activity.themeName}" 自动打卡状态失败:`, error.message);
686
- return false;
687
- }
688
- }
689
-
690
583
  cleanup() {
691
584
  this.logger.debug("插件卸载,开始清理资源");
692
585
  this.todayActivities = [];
@@ -701,4 +594,4 @@ class ActivityService {
701
594
  }
702
595
  }
703
596
 
704
- exports.ActivityService = ActivityService;
597
+ exports.ActivityService = ActivityService;
@@ -11,7 +11,7 @@ module.exports = async (ctx, session) => {
11
11
  let page;
12
12
  try {
13
13
  page = await ctx.puppeteer.page();
14
- await page.setViewport({ width: 1000, height: 1000 });
14
+ await page.setViewport({ width: 1000, height: 1000, deviceScaleFactor: 2 });
15
15
  await page.goto(`file:///${resolve(__dirname, '../resource/dlc.html')}`);
16
16
  await page.evaluate(`setData(${JSON.stringify(dlcData.data)})`);
17
17
  await page.waitForNetworkIdle();
@@ -122,7 +122,7 @@ module.exports = async (ctx, session, serverType, tmpId, date) => {
122
122
  let page
123
123
  try {
124
124
  page = await ctx.puppeteer.page()
125
- await page.setViewport({ width: 1000, height: 1000 })
125
+ await page.setViewport({ width: 1000, height: 1000, deviceScaleFactor: 2 })
126
126
  await page.goto(`file:///${resolve(__dirname, '../resource/footprint.html')}`)
127
127
  await page.evaluate(`init(${JSON.stringify(data)})`)
128
128
  await common.sleep(100)
@@ -33,7 +33,7 @@ module.exports = async (ctx, session, rankingType) => {
33
33
  let page;
34
34
  try {
35
35
  page = await ctx.puppeteer.page();
36
- await page.setViewport({ width: 1000, height: 1000 });
36
+ await page.setViewport({ width: 1000, height: 1000, deviceScaleFactor: 2 });
37
37
  await page.goto(`file:///${resolve(__dirname, '../resource/mileage-leaderboard.html')}`);
38
38
  await page.evaluate(`setData(${JSON.stringify(data)})`);
39
39
  await page.waitForNetworkIdle();
@@ -98,7 +98,7 @@ module.exports = async (ctx, cfg, session, tmpId) => {
98
98
  let page
99
99
  try {
100
100
  page = await ctx.puppeteer.page()
101
- await page.setViewport({ width: 1000, height: 1000 })
101
+ await page.setViewport({ width: 1000, height: 1000, deviceScaleFactor: 2 })
102
102
  await page.goto(`file:///${resolve(__dirname, '../resource/position.html')}`)
103
103
  await page.evaluate(`setData(${JSON.stringify(data)})`)
104
104
  await common.sleep(100)
@@ -0,0 +1,2 @@
1
+ declare function _exports(ctx: any, cfg: any): Promise<string | import("koishi").Element>;
2
+ export = _exports;
@@ -0,0 +1,15 @@
1
+ const tmpServerText = require("./tmpServerText");
2
+ const tmpServerImg = require("./tmpServerImg");
3
+ /**
4
+ * 查询服务器列表
5
+ */
6
+ module.exports = async (ctx, cfg) => {
7
+ switch (cfg.tmpServer?.type) {
8
+ case 1:
9
+ return await tmpServerText(ctx);
10
+ case 2:
11
+ return await tmpServerImg(ctx);
12
+ default:
13
+ return '指令配置错误';
14
+ }
15
+ };
@@ -0,0 +1,3 @@
1
+ declare function _exports(ctx: any): Promise<segment | "渲染异常,请重试" | "未启用 puppeteer 服务" | "查询服务器失败,请稍后重试">;
2
+ export = _exports;
3
+ import { segment } from "@koishijs/core";
@@ -0,0 +1,35 @@
1
+ const evmOpenApi = require('../../api/evmOpenApi');
2
+ const { resolve } = require("path");
3
+ const common = require("../../util/common");
4
+ const { segment } = require("koishi");
5
+ module.exports = async (ctx) => {
6
+ if (!ctx.puppeteer) {
7
+ return '未启用 puppeteer 服务';
8
+ }
9
+ // 查询服务器信息
10
+ let serverData = await evmOpenApi.serverList(ctx.http);
11
+ if (serverData.error) {
12
+ return '查询服务器失败,请稍后重试';
13
+ }
14
+ let page;
15
+ try {
16
+ page = await ctx.puppeteer.page();
17
+ await page.setViewport({ width: 380, height: 1000, deviceScaleFactor: 1.5 });
18
+ await page.goto(`file:///${resolve(__dirname, '../../resource/server-list.html')}`);
19
+ await page.evaluate(`setData(${JSON.stringify(serverData)})`);
20
+ await common.sleep(100);
21
+ await page.waitForNetworkIdle();
22
+ const element = await page.$("#container");
23
+ return (segment.image(await element.screenshot({
24
+ encoding: "binary"
25
+ }), "image/jpg"));
26
+ }
27
+ catch {
28
+ return '渲染异常,请重试';
29
+ }
30
+ finally {
31
+ if (page) {
32
+ await page.close();
33
+ }
34
+ }
35
+ };
@@ -0,0 +1,2 @@
1
+ declare function _exports(ctx: any): Promise<string>;
2
+ export = _exports;
@@ -0,0 +1,33 @@
1
+ const evmOpenApi = require('../../api/evmOpenApi');
2
+ module.exports = async (ctx) => {
3
+ // 查询服务器信息
4
+ let serverData = await evmOpenApi.serverList(ctx.http);
5
+ if (serverData.error) {
6
+ return '查询服务器失败,请稍后重试';
7
+ }
8
+ // 构建消息
9
+ let message = '';
10
+ for (let server of serverData.data) {
11
+ // 如果前面有内容,换行
12
+ if (message) {
13
+ message += '\n\n';
14
+ }
15
+ message += '服务器: ' + (server.isOnline === 1 ? '🟢' : '⚫') + server.serverName;
16
+ message += `\n玩家人数: ${server.playerCount}/${server.maxPlayer}`;
17
+ if (server.queue) {
18
+ message += ` (队列: ${server.queueCount})`;
19
+ }
20
+ // 服务器特性
21
+ let characteristicList = [];
22
+ if (!(server.afkEnable === 1)) {
23
+ characteristicList.push('⏱挂机');
24
+ }
25
+ if (server.collisionsEnable === 1) {
26
+ characteristicList.push('💥碰撞');
27
+ }
28
+ if (characteristicList && characteristicList.length > 0) {
29
+ message += '\n服务器特性: ' + characteristicList.join(' ');
30
+ }
31
+ }
32
+ return message;
33
+ };
@@ -102,7 +102,7 @@ module.exports = async (ctx, cfg, serverName) => {
102
102
  let page;
103
103
  try {
104
104
  page = await ctx.puppeteer.page();
105
- await page.setViewport({ width: 1000, height: 1000 });
105
+ await page.setViewport({ width: 1000, height: 1000, deviceScaleFactor: 2 });
106
106
  await page.goto(`file:///${resolve(__dirname, '../../resource/traffic.html')}`);
107
107
  await page.evaluate(`setData(${JSON.stringify(data)})`);
108
108
  await common.sleep(100);
package/lib/index.js CHANGED
@@ -10,15 +10,17 @@ const { MileageRankingType } = require('./util/constant');
10
10
 
11
11
  const commands = {
12
12
  tmpQuery: require('./command/tmpQuery/tmpQuery'),
13
- tmpServer: require('./command/tmpServer'),
13
+ tmpServer: require('./command/tmpServer/tmpServer'),
14
14
  tmpBind: require('./command/tmpBind'),
15
15
  tmpTraffic: require('./command/tmpTraffic/tmpTraffic'),
16
16
  tmpPosition: require('./command/tmpPosition'),
17
17
  tmpVersion: require('./command/tmpVersion'),
18
18
  tmpDlcMap: require('./command/tmpDlcMap'),
19
19
  tmpMileageRanking: require('./command/tmpMileageRanking'),
20
- resetPassword: require('./command/ets-app/resetPassword'),
21
- queryPoint: require('./command/ets-app/queryPoint'),
20
+ resetPassword: require('./command/ets-app/resetPassword/resetPassword'),
21
+ queryPoint: require('./command/ets-app/queryPoint/queryPoint'),
22
+ changePoint: require('./command/ets-app/changePoint/changePoint'),
23
+ addMember: require('./command/ets-app/addMember/addMemberV2'),
22
24
  tmpVtc: require('./command/tmpVtc'),
23
25
  tmpFootprint: require('./command/tmpFootprint')
24
26
  };
@@ -77,6 +79,8 @@ exports.Config = koishi_1.Schema.intersect([
77
79
  tmpFootprint: koishi_1.Schema.boolean().default(true).description('是否启用足迹查询'),
78
80
  mainSettings: koishi_1.Schema.boolean().default(false).description('是否启用车队平台积分查询功能'),
79
81
  resetPassword: koishi_1.Schema.boolean().default(false).description('是否启用车队平台重置密码功能'),
82
+ changePoint: koishi_1.Schema.boolean().default(false).description('是否启用车队平台积分修改功能'),
83
+ addMember: koishi_1.Schema.boolean().default(false).description('是否启用车队平台新增成员功能'),
80
84
  tmpActivityService: koishi_1.Schema.boolean().default(false).description('是否启用车队活动查询'),
81
85
  tmpVersionCheck: koishi_1.Schema.boolean().default(false).description('是否启用TMP版本更新查询'),
82
86
  tmpQueryGameTime: koishi_1.Schema.boolean().default(true).description('是否启用游戏时长查询功能'),
@@ -101,6 +105,13 @@ exports.Config = koishi_1.Schema.intersect([
101
105
  koishi_1.Schema.const(2).description('热力图')
102
106
  ]).default(1).description('路况信息展示方式'),
103
107
  }).description('路况查询配置'),
108
+ tmpServer: koishi_1.Schema.object({
109
+ type: koishi_1.Schema.union([
110
+ koishi_1.Schema.const(1).description('文字'),
111
+ koishi_1.Schema.const(2).description('图片')
112
+ ]).default(1).description('服务器信息展示方式'),
113
+ }).description('服务器查询配置'),
114
+
104
115
  tmpVersionCheck: koishi_1.Schema.object({
105
116
  checkInterval: koishi_1.Schema.number().description("版本检查间隔(分钟)").default(30),
106
117
  groups: koishi_1.Schema.array(koishi_1.Schema.string()).role("table").description("接收版本更新通知的群组ID列表").default([])
@@ -115,26 +126,34 @@ exports.Config = koishi_1.Schema.intersect([
115
126
  koishi_1.Schema.const("v1").description("车队平台V1.0"),
116
127
  koishi_1.Schema.const("v2").description("车队平台V2.0")
117
128
  ]).default("v1").description("车队平台版本"),
118
- url: koishi_1.Schema.string().description("API服务器地址(V1平台地址 / V2 OpenAPI地址,不含协议)"),
119
- token: koishi_1.Schema.string().description("API认证令牌(V1平台Token / V2 OpenAPI Token)"),
120
- mailEnabled: koishi_1.Schema.boolean().description("V2.0重置密码后发送邮件(需启用 adapter-mail)").default(false),
121
- mailTo: koishi_1.Schema.string().description("V2.0重置密码通知邮箱(自定义邮箱地址)").default(""),
122
- mailSubject: koishi_1.Schema.string().description("V2.0重置密码邮件标题").default("重置密码通知"),
123
- mailTemplate: koishi_1.Schema.string().description("V2.0重置密码邮件内容模板,支持变量:{uid} {qq} {password} {psw}").default("我们已将您平台的密码进行重置,您的账号:{uid},新的密码为:{psw} 请妥善保管好您的密码,以防泄露"),
124
- mailFromName: koishi_1.Schema.string().description("V2.0重置密码邮件发件人名字(覆盖 adapter-mail name)").default(""),
125
- logOutput: koishi_1.Schema.boolean().description("是否输出日志").default(true)
126
- }).description("通用配置")
129
+ url: koishi_1.Schema.string().description("API服务器地址(不含协议)"),
130
+ token: koishi_1.Schema.string().description("API认证令牌"),
131
+ logOutput: koishi_1.Schema.boolean().description("是否输出日志").default(true),
132
+ mailEnabled: koishi_1.Schema.boolean().description("V2.0】重置密码后发送邮件(需启用 adapter-mail)").default(false),
133
+ mailTo: koishi_1.Schema.string().description("V2.0】重置密码通知邮箱(自定义邮箱地址)").default(""),
134
+ mailSubject: koishi_1.Schema.string().description("V2.0】重置密码邮件标题").default("重置密码通知"),
135
+ mailTemplate: koishi_1.Schema.string().description("V2.0】重置密码邮件内容模板,支持变量:{uid} {qq} {password} {psw}").default("我们已将您平台的密码进行重置,您的账号:{uid},新的密码为:{psw} 请妥善保管好您的密码,以防泄露"),
136
+ mailFromName: koishi_1.Schema.string().description("【V2.0】重置密码邮件发件人名字(覆盖 adapter-mail 的 name)").default(""),
137
+ }).description("车队平台配置")
127
138
  }).description("车队平台配置"),
128
139
  resetPassword: koishi_1.Schema.object({
129
140
  settings: koishi_1.Schema.object({
130
141
  adminUsers: koishi_1.Schema.array(koishi_1.Schema.string()).description("管理员用户ID(拥有重置任意teamId权限)").default([])
131
142
  })
132
143
  }).description("重置密码功能配置"),
144
+ changePoint: koishi_1.Schema.object({
145
+ settings: koishi_1.Schema.object({
146
+ adminUsers: koishi_1.Schema.array(koishi_1.Schema.string()).description("管理员用户ID(拥有积分修改权限)").default([])
147
+ })
148
+ }).description("积分修改功能配置"),
149
+ addMember: koishi_1.Schema.object({
150
+ settings: koishi_1.Schema.object({
151
+ adminUsers: koishi_1.Schema.array(koishi_1.Schema.string()).description("管理员用户ID(拥有新增成员权限)").default([]),
152
+ teamNumberGenerateEnable: koishi_1.Schema.boolean().default(true).description("自动生成车队编号(关闭后需手动输入车队编号)")
153
+ })
154
+ }).description("新增成员功能配置"),
133
155
  tmpActivityService: koishi_1.Schema.object({
134
156
  api: koishi_1.Schema.object({
135
- useHttps: koishi_1.Schema.boolean().description("使用HTTPS协议").default(true),
136
- url: koishi_1.Schema.string().description("车队平台URL(不包含协议)").default(""),
137
- token: koishi_1.Schema.string().description("车队平台TOKEN").default(""),
138
157
  vtcId: koishi_1.Schema.string().description("VTC ID(用于TMP API)").default("")
139
158
  }).description("API配置"),
140
159
  admin: koishi_1.Schema.object({
@@ -331,6 +350,22 @@ function registerBaseCommands(ctx, cfg) {
331
350
  .action(async ({ session }, targetQQ) => await commands.queryPoint(ctx, cfg, session, targetQQ));
332
351
  }
333
352
 
353
+ if (cfg.commands?.changePoint) {
354
+ ctx.command(`积分修改 <target:string> <changeType:string> <quantity:string>`, "修改欧卡车队平台积分")
355
+ .usage("管理员专用。changeType: 增加 或 减少。target可输入UID或@群成员")
356
+ .example(`积分修改 @某人 增加 10 - 增加@某人10积分`)
357
+ .example(`积分修改 10000 减少 5 - 减少UID为10000的用户5积分`)
358
+ .action(async ({ session }, target, changeType, quantity) => await commands.changePoint(ctx, cfg, session, target, changeType, quantity));
359
+ }
360
+
361
+ if (cfg.commands?.addMember) {
362
+ ctx.command(`新增成员 <tmpId:string> <qq:string> [teamNumber:string]`, "新增车队平台成员")
363
+ .usage("管理员专用。qq可输入QQ号或@群成员。若关闭自动生成车队编号则需手动输入teamNumber")
364
+ .example(`新增成员 12345 79887143 - 自动生成车队编号`)
365
+ .example(`新增成员 12345 @某人 5 - 手动指定车队编号为5`)
366
+ .action(async ({ session }, tmpId, qq, teamNumber) => await commands.addMember(ctx, cfg, session, tmpId, qq, teamNumber));
367
+ }
368
+
334
369
  ctx.command('规则查询')
335
370
  .action(async () => 'TruckersMP官方规则链接:https://truckersmp.com/knowledge-base/article/746');
336
371
  }
@@ -112,4 +112,4 @@
112
112
  }
113
113
  </script>
114
114
  </body>
115
- </html>
115
+ </html>
@@ -150,7 +150,7 @@
150
150
 
151
151
  let dist = calculateDistance(prev, curr);
152
152
  dist = dist * 19;
153
- const isDistJump = dist > 50000; // > 50km
153
+ const isDistJump = dist > 30000; // > 30km
154
154
 
155
155
  let timeDiff = 0;
156
156
  try {
@@ -238,4 +238,4 @@
238
238
  }
239
239
  </script>
240
240
  </body>
241
- </html>
241
+ </html>
@@ -226,4 +226,4 @@
226
226
  }
227
227
  </script>
228
228
  </body>
229
- </html>
229
+ </html>