koishi-plugin-tmp-bot 1.15.1 → 1.16.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.
package/lib/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.apply = exports.Config = exports.inject = exports.name = void 0;
3
+ exports.Config = exports.inject = exports.name = void 0;
4
+ exports.apply = apply;
4
5
  const koishi_1 = require("koishi");
5
6
  const model = require('./database/model');
6
- const tmpQuery = require('./command/tmpQuery');
7
+ const tmpQuery = require('./command/tmpQuery/tmpQuery');
7
8
  const tmpServer = require('./command/tmpServer');
8
9
  const tmpBind = require('./command/tmpBind');
9
10
  const tmpTraffic = require('./command/tmpTraffic/tmpTraffic');
@@ -28,6 +29,10 @@ exports.Config = koishi_1.Schema.intersect([
28
29
  koishi_1.Schema.const(1).description('文字'),
29
30
  koishi_1.Schema.const(2).description('热力图')
30
31
  ]).default(1).description('路况信息展示方式'),
32
+ tmpQueryType: koishi_1.Schema.union([
33
+ koishi_1.Schema.const(1).description('文字'),
34
+ koishi_1.Schema.const(2).description('图片')
35
+ ]).default(1).description('玩家信息展示方式'),
31
36
  }).description('指令配置'),
32
37
  ]);
33
38
  function apply(ctx, cfg) {
@@ -42,4 +47,3 @@ function apply(ctx, cfg) {
42
47
  ctx.command('tmpversion').action(async () => await tmpVersion(ctx));
43
48
  ctx.command('tmpdlcmap').action(async ({ session }) => await tmpDlcMap(ctx, session));
44
49
  }
45
- exports.apply = apply;
@@ -1,180 +1,360 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>Title</title>
6
- <style>
7
- .border {
8
- border: 1px solid red;
9
- }
10
-
11
- .form-box {
12
- display: flex;
13
- flex-wrap: wrap;
14
- }
15
- .form-box .form-item {
16
- width: 50%;
17
- }
18
- .form-box .form-item.full {
19
- width: 100%;
20
- }
21
-
22
- #container {
23
- width: 400px;
24
- background: linear-gradient(135deg, #1f2f54, #0f2c2a);
25
- overflow: hidden;
26
- }
27
-
28
- .header {
29
- height: 100px;
30
- background-color: rgba(0, 0, 0, .1);
31
- display: flex;
32
- align-items: center;
33
- padding: 0 26px;
34
- box-shadow: 0 0 16px rgba(0, 0, 0, .4);
35
- }
36
- .header .avatar {
37
- width: 64px;
38
- height: 64px;
39
- }
40
- .header .info {
41
- flex: 1;
42
- padding-left: 16px;
43
- }
44
- .header .info .name {
45
- color: #b0c7ff;
46
- font-size: 18px;
47
- font-weight: 600;
48
- }
49
- .header .info .tmp-id {
50
- color: #aaaaaa;
51
- font-size: 14px;
52
- margin-top: 4px;
53
- }
54
-
55
- .details-container {
56
- padding: 12px 26px;
57
- }
58
- .details-container .form-item {
59
- margin-top: 12px;
60
- }
61
- .details-container .form-item:nth-child(1) {
62
- margin-top: 0;
63
- }
64
- .details-container .form-item .label {
65
- color: #dddddd;
66
- }
67
- .details-container .form-item .value {
68
- color: #ffffff;
69
- }
70
-
71
- .ban-container {
72
- margin: 16px 26px;
73
- background-color: rgba(227, 92, 92, 0.3);
74
- }
75
- .ban-header {
76
- width: 100%;
77
- height: 30px;
78
- box-sizing: border-box;
79
- padding: 0 12px;
80
- color: #ffffff;
81
- font-size: 16px;
82
- line-height: 30px;
83
- background-color: rgba(227, 92, 92, 0.6);
84
- }
85
- .ban-body {
86
- padding: 12px 16px;
87
- }
88
- .ban-body .ban-hidden {
89
- color: #cccccc;
90
- font-size: 14px;
91
- font-style: italic;
92
- text-align: center;
93
- }
94
- .ban-body .form-item {
95
- margin-top: 8px;
96
- }
97
- .ban-body .form-item:nth-child(1),
98
- .ban-body .form-item:nth-child(2){
99
- margin-top: 0;
100
- }
101
- .ban-body .form-item .label {
102
- color: #cccccc;
103
- font-size: 12px;
104
- }
105
- .ban-body .form-item .value {
106
- color: #eeeeee;
107
- font-size: 14px;
108
- word-wrap: break-word;
109
- word-break: break-all;
110
- }
111
- </style>
112
- </head>
113
- <body>
114
- <!--
115
- 🆔TMP编号: 5672599
116
- 😀玩家名称: MakeKazakh
117
- 🎮SteamID: 76561199225329400
118
- 📑注册日期: 2024年11月03日 (186天)
119
- 💼所属分组: 玩家
120
- 🚚所属车队: Kazakhstan-Taraz Truckers
121
- 🚚车队角色: Owner
122
- 🚫是否封禁:
123
- 🚫封禁次数: 0
124
- 📶在线状态: 在线🟢 (Simulation 1)
125
- 🌍线上位置: 法国 - 加莱-杜伊斯堡 -->
126
- <div id="container">
127
- <div class="header">
128
- <img class="avatar" src="https://static.truckersmp.com/avatarsN/4763167.1710207515.jpg" alt="avatar"/>
129
- <div class="info">
130
- <div class="name">*ACC* 014 kuroneko</div>
131
- <div class="tmp-id">TMP#4763167</div>
132
- </div>
133
- </div>
134
- <div class="details-container">
135
- <div class="form-box">
136
- <div class="form-item">
137
- <div class="label">🎮SteamID</div>
138
- <div class="value">76561198354836885</div>
139
- </div>
140
- <div class="form-item full">
141
- <div class="label">📑注册日期</div>
142
- <div class="value">2024年12月18日 (141天)</div>
143
- </div>
144
- <div class="form-item full">
145
- <div class="label">💼所属分组</div>
146
- <div class="value">玩家</div>
147
- </div>
148
- <div class="form-item full">
149
- <div class="label">🚚所属车队</div>
150
- <div class="value">Kazakhstan-Taraz Truckers</div>
151
- </div>
152
- <div class="form-item full">
153
- <div class="label">🚚车队角色</div>
154
- <div class="value">Owner</div>
155
- </div>
156
- </div>
157
- </div>
158
- <div class="ban-container">
159
- <div class="ban-header">封禁中</div>
160
- <div class="ban-body">
161
- <div class="ban-hidden">玩家隐藏</div>
162
- <!-- <div class="form-box">-->
163
- <!-- <div class="form-item">-->
164
- <!-- <div class="label">截止时间</div>-->
165
- <!-- <div class="value">2020-09-09 09:09:09</div>-->
166
- <!-- </div>-->
167
- <!-- <div class="form-item">-->
168
- <!-- <div class="label">封禁次数</div>-->
169
- <!-- <div class="value">5次</div>-->
170
- <!-- </div>-->
171
- <!-- <div class="form-item full">-->
172
- <!-- <div class="label">原因</div>-->
173
- <!-- <div class="value">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</div>-->
174
- <!-- </div>-->
175
- <!-- </div>-->
176
- </div>
177
- </div>
178
- </div>
179
- </body>
180
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Title</title>
6
+ <link href="./package/leaflet/leaflet.min.css" rel="stylesheet">
7
+ <script src="./package/leaflet/leaflet.min.js"></script>
8
+ <style>
9
+ .border {
10
+ border: 1px solid red;
11
+ }
12
+
13
+ #container {
14
+ padding-bottom: 16px;
15
+ }
16
+
17
+ .form-box {
18
+ display: flex;
19
+ flex-wrap: wrap;
20
+ }
21
+ .form-box .form-item {
22
+ width: 50%;
23
+ }
24
+ .form-box .form-item.full {
25
+ width: 100%;
26
+ }
27
+
28
+ #container {
29
+ width: 400px;
30
+ background: linear-gradient(135deg, #1f2f54, #0f2c2a);
31
+ overflow: hidden;
32
+ }
33
+
34
+ .header {
35
+ height: 100px;
36
+ background-color: rgba(0, 0, 0, .1);
37
+ display: flex;
38
+ align-items: center;
39
+ padding: 0 26px;
40
+ box-shadow: 0 0 16px rgba(0, 0, 0, .4);
41
+ }
42
+ .header .avatar {
43
+ width: 64px;
44
+ height: 64px;
45
+ }
46
+ .header .info {
47
+ flex: 1;
48
+ padding-left: 16px;
49
+ }
50
+ .header .info .name {
51
+ color: #b0c7ff;
52
+ font-size: 18px;
53
+ font-weight: 600;
54
+ }
55
+ .header .info .tmp-id {
56
+ color: #aaaaaa;
57
+ font-size: 14px;
58
+ margin-top: 4px;
59
+ }
60
+ .header .info .group {
61
+ color: #ffffff;
62
+ font-size: 12px;
63
+ padding: 2px 4px;
64
+ margin-left: 6px;
65
+ border-radius: 4px;
66
+ }
67
+
68
+ .details-container {
69
+ padding: 16px 20px 0 20px;
70
+ }
71
+ .details-container .form-item {
72
+ background-color: rgba(0, 0, 0, 0.2);
73
+ box-sizing: border-box;
74
+ }
75
+ .details-container .form-item:nth-child(1) {
76
+ margin-top: 0;
77
+ }
78
+ .details-container .form-item .label {
79
+ color: #dddddd;
80
+ background-color: rgba(0, 0, 0, 0.2);
81
+ padding: 4px 8px;
82
+ }
83
+ .details-container .form-item .value {
84
+ color: #ffffff;
85
+ padding: 4px 8px;
86
+ }
87
+
88
+ .ban-container {
89
+ margin: 16px 20px 0 20px;
90
+ background-color: rgba(227, 92, 92, 0.3);
91
+ }
92
+ .ban-header {
93
+ width: 100%;
94
+ height: 30px;
95
+ box-sizing: border-box;
96
+ padding: 0 12px;
97
+ color: #ffffff;
98
+ font-size: 14px;
99
+ line-height: 30px;
100
+ background-color: rgba(227, 92, 92, 0.6);
101
+ }
102
+ .ban-body {
103
+ padding: 12px 16px;
104
+ }
105
+ .ban-body .ban-hidden {
106
+ color: #cccccc;
107
+ font-size: 14px;
108
+ font-style: italic;
109
+ text-align: center;
110
+ }
111
+ .ban-body .form-item {
112
+ margin-top: 8px;
113
+ }
114
+ .ban-body .form-item:nth-child(1),
115
+ .ban-body .form-item:nth-child(2) {
116
+ margin-top: 0;
117
+ }
118
+ .ban-body .form-item .label {
119
+ color: #f3f3f3;
120
+ font-size: 12px;
121
+ }
122
+ .ban-body .form-item .value {
123
+ color: #eeeeee;
124
+ font-size: 14px;
125
+ word-wrap: break-word;
126
+ word-break: break-all;
127
+ }
128
+
129
+ .position-container {
130
+ margin: 16px 20px;
131
+ }
132
+ .position-container .position-header {
133
+ width: 100%;
134
+ height: 30px;
135
+ box-sizing: border-box;
136
+ padding: 0 12px;
137
+ color: #ffffff;
138
+ font-size: 14px;
139
+ line-height: 30px;
140
+ background-color: rgba(0, 0, 0, 0.4);
141
+ }
142
+ .position-container #map {
143
+ width: 100%;
144
+ height: 150px;
145
+ background-color: rgba(0, 0, 0, 0.25);
146
+ }
147
+
148
+ .footer {
149
+ color: rgba(255, 255, 255, .5);
150
+ font-size: 14px;
151
+ text-align: center;
152
+ font-weight: 100;
153
+ margin-top: 16px;
154
+ }
155
+ </style>
156
+ </head>
157
+ <body>
158
+ <div id="container">
159
+ <div class="header">
160
+ <img class="avatar" id="tmp-avatar" src="" alt="avatar"/>
161
+ <div class="info">
162
+ <div class="name" id="tmp-name">-</div>
163
+ <div class="tmp-id" id="tmp-id"></div>
164
+ </div>
165
+ </div>
166
+ <div class="details-container">
167
+ <div class="form-box">
168
+ <div class="form-item full">
169
+ <div class="label">🎮SteamID</div>
170
+ <div class="value" id="tmp-steam-id"></div>
171
+ </div>
172
+ <div class="form-item full">
173
+ <div class="label">📑注册日期</div>
174
+ <div class="value" id="tmp-register-date"></div>
175
+ </div>
176
+ <div class="form-item full" id="tmp-vtc-box">
177
+ <div class="label">🚚所属车队</div>
178
+ <div class="value" id="tmp-vtc-name"></div>
179
+ </div>
180
+ <div class="form-item full" id="tmp-vtc-role-box">
181
+ <div class="label">🚚车队角色</div>
182
+ <div class="value" id="tmp-vtc-role"></div>
183
+ </div>
184
+ <div class="form-item" id="tmp-sponsor-box">
185
+ <div class="label">🎁赞助用户</div>
186
+ <div class="value" id="tmp-sponsor-amount"></div>
187
+ </div>
188
+ <div class="form-item" id="tmp-sponsor-cumulative-box">
189
+ <div class="label">🎁累计赞助</div>
190
+ <div class="value" id="tmp-sponsor-cumulative"></div>
191
+ </div>
192
+ </div>
193
+ </div>
194
+ <div class="position-container" id="position-box">
195
+ <div class="position-header" id="position-title"></div>
196
+ <div id="map"></div>
197
+ </div>
198
+ <div class="ban-container" id="ban-box">
199
+ <div class="ban-header">封禁中</div>
200
+ <div class="ban-body">
201
+ <div class="ban-hidden" id="ban-hidden-box">玩家隐藏信息</div>
202
+ <div class="form-box" id="ban-info-box">
203
+ <div class="form-item">
204
+ <div class="label">截止时间</div>
205
+ <div class="value" id="ban-until"></div>
206
+ </div>
207
+ <div class="form-item">
208
+ <div class="label">封禁次数</div>
209
+ <div class="value" id="ban-count"></div>
210
+ </div>
211
+ <div class="form-item full">
212
+ <div class="label">原因</div>
213
+ <div class="value" id="ban-reason"></div>
214
+ </div>
215
+ </div>
216
+ </div>
217
+ </div>
218
+ <div class="footer">如需更换为文本展示方式,请联系QQ79887143</div>
219
+ </div>
220
+ <script>
221
+ let mapConfig = {
222
+ ets: {
223
+ tileUrl: 'https://ets-map.oss-cn-beijing.aliyuncs.com/ets2/05102019/{z}/{x}/{y}.png',
224
+ multipliers: {
225
+ x: 71282,
226
+ y: 56532
227
+ },
228
+ breakpoints: {
229
+ uk: {
230
+ x: -31056.8,
231
+ y: -5832.867
232
+ }
233
+ },
234
+ bounds: {
235
+ y: 131072,
236
+ x: 131072
237
+ },
238
+ maxZoom: 8,
239
+ minZoom: 2,
240
+ // 游戏地转地图坐标
241
+ calculateMapCoordinate (x, y) {
242
+ return [
243
+ x / 1.325928 + mapConfig.ets.multipliers.x,
244
+ y / 1.325928 + mapConfig.ets.multipliers.y
245
+ ];
246
+ }
247
+ },
248
+ promods: {
249
+ tileUrl: 'https://ets-map.oss-cn-beijing.aliyuncs.com/promods/05102019/{z}/{x}/{y}.png',
250
+ multipliers: {
251
+ x: 51953,
252
+ y: 76024
253
+ },
254
+ breakpoints: {
255
+ uk: {
256
+ x: -31056.8,
257
+ y: -5832.867
258
+ }
259
+ },
260
+ bounds: {
261
+ y: 131072,
262
+ x: 131072
263
+ },
264
+ maxZoom: 8,
265
+ minZoom: 2,
266
+ // 游戏地转地图坐标
267
+ calculateMapCoordinate (x, y) {
268
+ return [
269
+ x / 2.598541 + mapConfig.promods.multipliers.x,
270
+ y / 2.598541 + mapConfig.promods.multipliers.y
271
+ ]
272
+ }
273
+ }
274
+ }
275
+
276
+ function init(data) {
277
+ document.getElementById('tmp-name').innerText = data.name
278
+ document.getElementById('tmp-avatar').src = data.avatarUrl
279
+ document.getElementById('tmp-id').innerHTML = `TMP#${data.tmpId} <span class="group" style="background-color: #${data.groupColor}">${data.groupName}</span>`
280
+ document.getElementById('tmp-steam-id').innerText = data.steamId
281
+ document.getElementById('tmp-register-date').innerText = data.registerDate
282
+ if (data.isJoinVtc) {
283
+ document.getElementById('tmp-vtc-name').innerText = data.vtcName
284
+ document.getElementById('tmp-vtc-role').innerText = data.vtcRole
285
+ } else {
286
+ document.getElementById('tmp-vtc-box').remove()
287
+ document.getElementById('tmp-vtc-role-box').remove()
288
+ }
289
+ if (data.isSponsor && !data.sponsorHide) {
290
+ document.getElementById('tmp-sponsor-amount').innerText = '$' + Math.floor(data.sponsorAmount / 100)
291
+ document.getElementById('tmp-sponsor-cumulative').innerText = '$' + Math.floor(data.sponsorCumulativeAmount / 100)
292
+ } else {
293
+ document.getElementById('tmp-sponsor-box').remove()
294
+ document.getElementById('tmp-sponsor-cumulative-box').remove()
295
+ }
296
+ if (data.isOnline) {
297
+ document.getElementById('position-title').innerText = `${data.onlineServerName} · ${data.onlineCountry}-${data.onlineCity}`
298
+ map('ets', data.onlineX, data.onlineY)
299
+ } else {
300
+ document.getElementById('position-box').remove()
301
+ }
302
+ if (data.isBan) {
303
+ if (data.banHide) {
304
+ document.getElementById('ban-info-box').remove()
305
+ } else {
306
+ document.getElementById('ban-hidden-box').remove()
307
+ document.getElementById('ban-until').innerText = (data.banUntil || '永久')
308
+ document.getElementById('ban-count').innerText = (data.banCount || 0) + '次'
309
+ document.getElementById('ban-reason').innerText = data.banReasonZh || data.banReason
310
+ }
311
+ } else {
312
+ document.getElementById('ban-box').remove()
313
+ }
314
+ }
315
+
316
+ function map(mapType, x, y) {
317
+ // 定义地图
318
+ let map = L.map('map', {
319
+ attributionControl: false,
320
+ crs: L.CRS.Simple,
321
+ zoomControl: false
322
+ });
323
+
324
+ // 边界
325
+ let bounds = L.latLngBounds(
326
+ map.unproject([0, mapConfig[mapType].bounds.y], mapConfig[mapType].maxZoom),
327
+ map.unproject([mapConfig[mapType].bounds.x, 0], mapConfig[mapType].maxZoom)
328
+ );
329
+
330
+ // 瓦片地图
331
+ L.tileLayer(mapConfig[mapType].tileUrl, {
332
+ minZoom: 2,
333
+ maxZoom: 10,
334
+ maxNativeZoom: 8,
335
+ tileSize: 512,
336
+ bounds: bounds,
337
+ reuseTiles: true
338
+ }).addTo(map);
339
+ map.setMaxBounds(
340
+ new L.LatLngBounds(
341
+ map.unproject([0, mapConfig[mapType].bounds.y], mapConfig[mapType].maxZoom),
342
+ map.unproject([mapConfig[mapType].bounds.x, 0], mapConfig[mapType].maxZoom)
343
+ )
344
+ );
345
+
346
+ L.circleMarker(map.unproject(mapConfig[mapType].calculateMapCoordinate(x, y), 8), {
347
+ color: '#2f2f2f', // 标记点边框颜色
348
+ weight: 2, // 标记点边框大小
349
+ fillColor: '#1cb715', // 标记点填充颜色
350
+ fillOpacity: 1, // 标记点填充不透明度(0到1之间的值)
351
+ radius: 5, // 标记点半径(以像素为单位)
352
+ zIndex: 1000
353
+ }).addTo(map);
354
+
355
+ // 设置中心点
356
+ map.setView(map.unproject(mapConfig[mapType].calculateMapCoordinate(x, y), 8), 5);
357
+ }
358
+ </script>
359
+ </body>
360
+ </html>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-tmp-bot",
3
3
  "description": "欧洲卡车模拟2 TMP查询插件,不会部署的可以直接使用此机器人->QQ:3523283907",
4
- "version": "1.15.1",
4
+ "version": "1.16.0",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "homepage": "https://github.com/79887143/koishi-plugin-tmp-bot",
package/readme.md CHANGED
@@ -16,9 +16,8 @@
16
16
  | tmpversion | 查询版本信息 | tmpversion |
17
17
  | tmpdlcmap | 地图DLC列表 | tmpdlcmap |
18
18
 
19
- ### 已部署的机器人
20
- 如不会部署,可直接使用下方已经部署好的机器人
19
+ ### TMP数据接口文档
20
+ https://apifox.com/apidoc/shared/38508a88-5ff4-4b29-b724-41f9d3d3336a
21
21
 
22
- | QQ机器人,添加好友拉群(需要等待我同意请求) | 官方机器人 |
23
- |----------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|
24
- | <img src="https://www.helloimg.com/i/2025/01/20/678da69e7a4da.jpg" width="380" alt="QQ机器人"/> | <img src="https://www.helloimg.com/i/2025/01/20/678da69ecfe34.jpg" width="380" alt="官方机器人"/> |
22
+ ### 已部署的机器人
23
+ 如不会部署,可直接使用此机器人 => QQ:3523283907
@@ -1,71 +0,0 @@
1
- const BASE_API = 'https://open-api.vtcm.link'
2
-
3
- module.exports = {
4
- /**
5
- * 查询服务器列表
6
- */
7
- async serverList (http) {
8
- let result = null
9
- try {
10
- result = await http.get(`${BASE_API}/server/list`)
11
- } catch {
12
- return {
13
- error: true
14
- }
15
- }
16
-
17
- // 拼接返回数据
18
- let data = {
19
- error: result.code !== 200
20
- }
21
- if (!data.error) {
22
- data.data = result.data
23
- }
24
-
25
- return data
26
- },
27
- /**
28
- * 查询在线玩家
29
- */
30
- async mapPlayerList(http, serverId, ax, ay, bx, by) {
31
- let result = null
32
- try {
33
- result = await http.get(`${BASE_API}/map/playerList?aAxisX=${ax}&aAxisY=${ay}&bAxisX=${bx}&bAxisY=${by}&serverId=${serverId}`)
34
- } catch {
35
- return {
36
- error: true
37
- }
38
- }
39
-
40
- // 拼接返回数据
41
- let data = {
42
- error: result.code !== 200
43
- }
44
- if (!data.error) {
45
- data.data = result.data
46
- }
47
- return data
48
- },
49
- /**
50
- * 查询玩家信息
51
- */
52
- async playerInfo (http, tmpId) {
53
- let result = null
54
- try {
55
- result = await http.get(`${BASE_API}/player/info?tmpId=${tmpId}`)
56
- } catch {
57
- return {
58
- error: true
59
- }
60
- }
61
-
62
- // 拼接返回数据
63
- let data = {
64
- error: result.code !== 200
65
- }
66
- if (!data.error) {
67
- data.data = result.data
68
- }
69
- return data
70
- }
71
- }