koishi-plugin-ets2-tools-tmp 3.1.2 → 3.1.4
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/command/tmpFootprint.js +1 -1
- package/lib/index.js +1 -1
- package/lib/resource/dlc.html +150 -42
- package/lib/resource/mileage-leaderboard.html +448 -247
- package/lib/resource/query.html +2 -2
- package/lib/resource/server-list.html +264 -112
- package/lib/resource/traffic.html +246 -116
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="
|
|
2
|
+
<html lang="zh-CN">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<title>Mileage Leaderboard</title>
|
|
@@ -10,354 +10,555 @@
|
|
|
10
10
|
font-weight: normal;
|
|
11
11
|
font-style: normal;
|
|
12
12
|
}
|
|
13
|
+
|
|
14
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
15
|
+
|
|
13
16
|
body {
|
|
14
|
-
font-family: 'segui-emj', sans-serif;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
background-color: #000;
|
|
17
|
+
font-family: 'segui-emj', 'Segoe UI', -apple-system, sans-serif;
|
|
18
|
+
background: #0a0a0a;
|
|
19
|
+
-webkit-font-smoothing: antialiased;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
#container {
|
|
21
|
-
width:
|
|
22
|
-
background:
|
|
23
|
+
width: 520px;
|
|
24
|
+
background: #0d0d0d;
|
|
25
|
+
padding-bottom: 20px;
|
|
23
26
|
overflow: hidden;
|
|
24
|
-
|
|
25
|
-
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
|
|
27
|
+
position: relative;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
/* Racing stripe background */
|
|
31
|
+
.racing-stripes {
|
|
32
|
+
position: absolute;
|
|
33
|
+
top: 0;
|
|
34
|
+
left: 0;
|
|
35
|
+
right: 0;
|
|
36
|
+
height: 6px;
|
|
37
|
+
background: repeating-linear-gradient(
|
|
38
|
+
90deg,
|
|
39
|
+
#ff6b00 0px, #ff6b00 20px,
|
|
40
|
+
#0d0d0d 20px, #0d0d0d 40px
|
|
41
|
+
);
|
|
42
|
+
z-index: 10;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Carbon fiber texture overlay */
|
|
46
|
+
.carbon-texture {
|
|
47
|
+
position: absolute;
|
|
48
|
+
inset: 0;
|
|
49
|
+
background:
|
|
50
|
+
radial-gradient(circle at 2px 2px, rgba(255,255,255,0.015) 1px, transparent 0) 0 0 / 4px 4px;
|
|
51
|
+
pointer-events: none;
|
|
52
|
+
z-index: 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Neon glow accents */
|
|
56
|
+
.neon-line-left {
|
|
57
|
+
position: absolute;
|
|
58
|
+
left: 0;
|
|
59
|
+
top: 80px;
|
|
60
|
+
bottom: 40px;
|
|
61
|
+
width: 2px;
|
|
62
|
+
background: linear-gradient(180deg, transparent, #ff6b00, #ff3d00, #ff6b00, transparent);
|
|
63
|
+
box-shadow: 0 0 8px rgba(255, 107, 0, 0.4), 0 0 20px rgba(255, 61, 0, 0.15);
|
|
64
|
+
z-index: 1;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.neon-line-right {
|
|
68
|
+
position: absolute;
|
|
69
|
+
right: 0;
|
|
70
|
+
top: 120px;
|
|
71
|
+
bottom: 80px;
|
|
72
|
+
width: 2px;
|
|
73
|
+
background: linear-gradient(180deg, transparent, #ff3d00, #ff6b00, #ff3d00, transparent);
|
|
74
|
+
box-shadow: 0 0 8px rgba(255, 61, 0, 0.4), 0 0 20px rgba(255, 107, 0, 0.15);
|
|
75
|
+
z-index: 1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* ===== HEADER ===== */
|
|
28
79
|
.header {
|
|
29
|
-
|
|
30
|
-
|
|
80
|
+
padding: 30px 24px 18px;
|
|
81
|
+
text-align: center;
|
|
82
|
+
position: relative;
|
|
83
|
+
z-index: 2;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.header-icon {
|
|
87
|
+
font-size: 42px;
|
|
88
|
+
display: block;
|
|
89
|
+
margin-bottom: 6px;
|
|
90
|
+
filter: drop-shadow(0 0 12px rgba(255, 107, 0, 0.5));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.header .title {
|
|
94
|
+
font-size: 24px;
|
|
95
|
+
font-weight: 900;
|
|
96
|
+
color: #ffffff;
|
|
97
|
+
letter-spacing: 3px;
|
|
98
|
+
text-transform: uppercase;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.header .title-accent {
|
|
102
|
+
display: inline-block;
|
|
103
|
+
width: 60px;
|
|
104
|
+
height: 3px;
|
|
105
|
+
background: linear-gradient(90deg, transparent, #ff6b00, transparent);
|
|
106
|
+
margin: 10px auto 0;
|
|
107
|
+
border-radius: 2px;
|
|
108
|
+
box-shadow: 0 0 10px rgba(255, 107, 0, 0.5);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.header .subtitle {
|
|
112
|
+
font-size: 11px;
|
|
113
|
+
color: #555;
|
|
114
|
+
margin-top: 8px;
|
|
115
|
+
letter-spacing: 2px;
|
|
116
|
+
text-transform: uppercase;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* ===== TOP 1 HERO ===== */
|
|
120
|
+
.hero {
|
|
121
|
+
margin: 16px 20px;
|
|
122
|
+
padding: 20px;
|
|
123
|
+
background: linear-gradient(135deg, rgba(255, 107, 0, 0.1) 0%, rgba(255, 61, 0, 0.05) 100%);
|
|
124
|
+
border: 1px solid rgba(255, 107, 0, 0.2);
|
|
125
|
+
border-radius: 16px;
|
|
126
|
+
position: relative;
|
|
127
|
+
z-index: 2;
|
|
31
128
|
display: flex;
|
|
32
129
|
align-items: center;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
box-shadow: 0 0 16px rgba(0, 0, 0, .4);
|
|
130
|
+
gap: 16px;
|
|
131
|
+
box-shadow: 0 4px 24px rgba(255, 107, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.03);
|
|
36
132
|
}
|
|
37
133
|
|
|
38
|
-
.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
134
|
+
.hero::before {
|
|
135
|
+
content: '';
|
|
136
|
+
position: absolute;
|
|
137
|
+
top: 0;
|
|
138
|
+
left: 20px;
|
|
139
|
+
right: 20px;
|
|
140
|
+
height: 1px;
|
|
141
|
+
background: linear-gradient(90deg, transparent, rgba(255, 107, 0, 0.3), transparent);
|
|
43
142
|
}
|
|
44
143
|
|
|
45
|
-
.
|
|
46
|
-
|
|
144
|
+
.hero-crown {
|
|
145
|
+
font-size: 36px;
|
|
146
|
+
filter: drop-shadow(0 0 8px rgba(255, 215, 0, 0.5));
|
|
147
|
+
flex-shrink: 0;
|
|
47
148
|
}
|
|
48
149
|
|
|
49
|
-
.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
150
|
+
.hero-info {
|
|
151
|
+
flex: 1;
|
|
152
|
+
min-width: 0;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.hero-name {
|
|
156
|
+
font-size: 18px;
|
|
157
|
+
font-weight: 800;
|
|
158
|
+
color: #ff6b00;
|
|
159
|
+
white-space: nowrap;
|
|
53
160
|
overflow: hidden;
|
|
54
|
-
|
|
161
|
+
text-overflow: ellipsis;
|
|
162
|
+
text-shadow: 0 0 12px rgba(255, 107, 0, 0.3);
|
|
55
163
|
}
|
|
56
164
|
|
|
57
|
-
.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
165
|
+
.hero-rank {
|
|
166
|
+
font-size: 11px;
|
|
167
|
+
color: #888;
|
|
168
|
+
letter-spacing: 1px;
|
|
169
|
+
margin-top: 2px;
|
|
61
170
|
}
|
|
62
171
|
|
|
63
|
-
.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
172
|
+
.hero-distance {
|
|
173
|
+
font-size: 20px;
|
|
174
|
+
font-weight: 900;
|
|
175
|
+
color: #fff;
|
|
176
|
+
flex-shrink: 0;
|
|
177
|
+
letter-spacing: 0.5px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.hero-distance-unit {
|
|
181
|
+
font-size: 12px;
|
|
182
|
+
font-weight: 400;
|
|
183
|
+
color: #666;
|
|
184
|
+
margin-left: 4px;
|
|
67
185
|
}
|
|
68
186
|
|
|
69
|
-
|
|
187
|
+
/* ===== 2ND & 3RD PODIUM ===== */
|
|
188
|
+
.podium-row {
|
|
70
189
|
display: flex;
|
|
71
|
-
|
|
72
|
-
|
|
190
|
+
gap: 10px;
|
|
191
|
+
margin: 12px 20px;
|
|
192
|
+
position: relative;
|
|
193
|
+
z-index: 2;
|
|
73
194
|
}
|
|
74
195
|
|
|
75
|
-
.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
196
|
+
.podium-card {
|
|
197
|
+
flex: 1;
|
|
198
|
+
padding: 14px;
|
|
199
|
+
background: rgba(255, 255, 255, 0.03);
|
|
200
|
+
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
201
|
+
border-radius: 12px;
|
|
202
|
+
display: flex;
|
|
203
|
+
align-items: center;
|
|
204
|
+
gap: 10px;
|
|
205
|
+
position: relative;
|
|
206
|
+
overflow: hidden;
|
|
82
207
|
}
|
|
83
208
|
|
|
84
|
-
.
|
|
85
|
-
|
|
86
|
-
|
|
209
|
+
.podium-card::before {
|
|
210
|
+
content: '';
|
|
211
|
+
position: absolute;
|
|
212
|
+
top: 0;
|
|
213
|
+
left: 0;
|
|
214
|
+
right: 0;
|
|
215
|
+
height: 1px;
|
|
216
|
+
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.06), transparent);
|
|
87
217
|
}
|
|
88
218
|
|
|
89
|
-
.
|
|
90
|
-
color:
|
|
91
|
-
|
|
219
|
+
.podium-card.second {
|
|
220
|
+
border-color: rgba(192, 192, 192, 0.15);
|
|
221
|
+
background: linear-gradient(135deg, rgba(192, 192, 192, 0.06), rgba(192, 192, 192, 0.02));
|
|
92
222
|
}
|
|
93
223
|
|
|
94
|
-
.
|
|
95
|
-
color:
|
|
96
|
-
|
|
224
|
+
.podium-card.third {
|
|
225
|
+
border-color: rgba(205, 127, 50, 0.15);
|
|
226
|
+
background: linear-gradient(135deg, rgba(205, 127, 50, 0.06), rgba(205, 127, 50, 0.02));
|
|
97
227
|
}
|
|
98
228
|
|
|
99
|
-
.
|
|
100
|
-
|
|
101
|
-
|
|
229
|
+
.podium-medal {
|
|
230
|
+
font-size: 22px;
|
|
231
|
+
flex-shrink: 0;
|
|
102
232
|
}
|
|
103
233
|
|
|
104
|
-
.
|
|
234
|
+
.podium-card-info {
|
|
105
235
|
flex: 1;
|
|
106
|
-
padding: 0 10px;
|
|
107
236
|
min-width: 0;
|
|
108
237
|
}
|
|
109
238
|
|
|
110
|
-
.
|
|
111
|
-
color: #ffffff;
|
|
239
|
+
.podium-card-name {
|
|
112
240
|
font-size: 13px;
|
|
113
|
-
font-weight:
|
|
241
|
+
font-weight: 700;
|
|
242
|
+
color: #ddd;
|
|
114
243
|
white-space: nowrap;
|
|
115
244
|
overflow: hidden;
|
|
116
245
|
text-overflow: ellipsis;
|
|
117
|
-
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
|
118
|
-
max-width: 160px;
|
|
119
246
|
}
|
|
120
247
|
|
|
121
|
-
.
|
|
122
|
-
|
|
248
|
+
.podium-card.second .podium-card-name { color: #c0c0c0; }
|
|
249
|
+
.podium-card.third .podium-card-name { color: #cd7f32; }
|
|
250
|
+
|
|
251
|
+
.podium-card-dist {
|
|
252
|
+
font-size: 14px;
|
|
253
|
+
font-weight: 800;
|
|
254
|
+
color: #aaa;
|
|
255
|
+
flex-shrink: 0;
|
|
123
256
|
}
|
|
124
257
|
|
|
258
|
+
.podium-card.second .podium-card-dist { color: #c0c0c0; }
|
|
259
|
+
.podium-card.third .podium-card-dist { color: #cd7f32; }
|
|
125
260
|
|
|
126
|
-
|
|
127
|
-
|
|
261
|
+
/* ===== RANK LIST (4-10) ===== */
|
|
262
|
+
.rank-list {
|
|
263
|
+
margin: 8px 20px 0;
|
|
264
|
+
position: relative;
|
|
265
|
+
z-index: 2;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.rank-item {
|
|
269
|
+
display: flex;
|
|
270
|
+
align-items: center;
|
|
271
|
+
padding: 10px 14px;
|
|
272
|
+
margin-bottom: 4px;
|
|
273
|
+
background: rgba(255, 255, 255, 0.02);
|
|
274
|
+
border-left: 3px solid rgba(255, 107, 0, 0.3);
|
|
275
|
+
border-radius: 0 8px 8px 0;
|
|
276
|
+
position: relative;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.rank-item::before {
|
|
280
|
+
content: '';
|
|
281
|
+
position: absolute;
|
|
282
|
+
left: -3px;
|
|
283
|
+
top: 50%;
|
|
284
|
+
transform: translateY(-50%);
|
|
285
|
+
width: 3px;
|
|
286
|
+
height: 0;
|
|
287
|
+
background: #ff6b00;
|
|
288
|
+
border-radius: 2px;
|
|
289
|
+
box-shadow: 0 0 6px rgba(255, 107, 0, 0.5);
|
|
290
|
+
transition: height 0.2s;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.rank-number {
|
|
294
|
+
width: 26px;
|
|
295
|
+
font-size: 14px;
|
|
296
|
+
font-weight: 900;
|
|
297
|
+
color: #444;
|
|
298
|
+
flex-shrink: 0;
|
|
299
|
+
text-align: center;
|
|
300
|
+
margin-right: 12px;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.rank-bar {
|
|
304
|
+
flex: 1;
|
|
305
|
+
height: 4px;
|
|
306
|
+
background: rgba(255, 255, 255, 0.04);
|
|
307
|
+
border-radius: 2px;
|
|
308
|
+
overflow: hidden;
|
|
309
|
+
margin-right: 12px;
|
|
310
|
+
position: relative;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.rank-bar-fill {
|
|
314
|
+
height: 100%;
|
|
315
|
+
background: linear-gradient(90deg, #ff6b00, #ff3d00);
|
|
316
|
+
border-radius: 2px;
|
|
317
|
+
box-shadow: 0 0 6px rgba(255, 107, 0, 0.3);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.rank-name {
|
|
128
321
|
font-size: 13px;
|
|
129
|
-
font-weight:
|
|
130
|
-
|
|
322
|
+
font-weight: 600;
|
|
323
|
+
color: #bbb;
|
|
324
|
+
flex-shrink: 0;
|
|
325
|
+
width: 120px;
|
|
131
326
|
white-space: nowrap;
|
|
132
|
-
|
|
133
|
-
|
|
327
|
+
overflow: hidden;
|
|
328
|
+
text-overflow: ellipsis;
|
|
329
|
+
margin-right: 12px;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.rank-distance {
|
|
333
|
+
font-size: 13px;
|
|
334
|
+
font-weight: 800;
|
|
335
|
+
color: #888;
|
|
336
|
+
flex-shrink: 0;
|
|
337
|
+
text-align: right;
|
|
338
|
+
min-width: 70px;
|
|
134
339
|
}
|
|
135
340
|
|
|
341
|
+
/* ===== DIVIDER ===== */
|
|
136
342
|
.divider {
|
|
137
343
|
height: 1px;
|
|
138
|
-
|
|
139
|
-
|
|
344
|
+
margin: 16px 40px;
|
|
345
|
+
background: linear-gradient(90deg, transparent, rgba(255, 107, 0, 0.3), transparent);
|
|
346
|
+
position: relative;
|
|
347
|
+
z-index: 2;
|
|
140
348
|
}
|
|
141
349
|
|
|
142
|
-
|
|
143
|
-
|
|
350
|
+
/* ===== CURRENT PLAYER ===== */
|
|
351
|
+
.current-section {
|
|
352
|
+
margin: 0 20px;
|
|
353
|
+
position: relative;
|
|
354
|
+
z-index: 2;
|
|
144
355
|
}
|
|
145
356
|
|
|
146
|
-
.current-
|
|
147
|
-
|
|
148
|
-
font-
|
|
357
|
+
.current-title {
|
|
358
|
+
font-size: 10px;
|
|
359
|
+
font-weight: 700;
|
|
360
|
+
color: #555;
|
|
361
|
+
text-transform: uppercase;
|
|
362
|
+
letter-spacing: 2px;
|
|
149
363
|
text-align: center;
|
|
150
364
|
margin-bottom: 8px;
|
|
151
365
|
}
|
|
152
366
|
|
|
153
|
-
.
|
|
154
|
-
|
|
367
|
+
.current-card {
|
|
368
|
+
display: flex;
|
|
369
|
+
align-items: center;
|
|
370
|
+
padding: 12px 16px;
|
|
371
|
+
background: linear-gradient(135deg, rgba(0, 200, 83, 0.1) 0%, rgba(0, 200, 83, 0.03) 100%);
|
|
372
|
+
border: 1px solid rgba(0, 200, 83, 0.2);
|
|
373
|
+
border-left: 3px solid #00c853;
|
|
374
|
+
border-radius: 0 12px 12px 0;
|
|
375
|
+
box-shadow: 0 2px 12px rgba(0, 200, 83, 0.08);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
.current-rank {
|
|
379
|
+
font-size: 18px;
|
|
380
|
+
font-weight: 900;
|
|
381
|
+
color: #00c853;
|
|
382
|
+
flex-shrink: 0;
|
|
383
|
+
margin-right: 12px;
|
|
384
|
+
min-width: 40px;
|
|
385
|
+
text-shadow: 0 0 8px rgba(0, 200, 83, 0.3);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.current-name {
|
|
389
|
+
font-size: 14px;
|
|
390
|
+
font-weight: 700;
|
|
391
|
+
color: #00c853;
|
|
392
|
+
flex: 1;
|
|
393
|
+
min-width: 0;
|
|
394
|
+
white-space: nowrap;
|
|
395
|
+
overflow: hidden;
|
|
396
|
+
text-overflow: ellipsis;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.current-distance {
|
|
400
|
+
font-size: 15px;
|
|
401
|
+
font-weight: 800;
|
|
402
|
+
color: #00c853;
|
|
403
|
+
flex-shrink: 0;
|
|
404
|
+
text-shadow: 0 0 6px rgba(0, 200, 83, 0.3);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/* ===== FOOTER ===== */
|
|
408
|
+
.footer {
|
|
155
409
|
font-size: 10px;
|
|
410
|
+
color: #333;
|
|
156
411
|
text-align: center;
|
|
157
|
-
margin-top:
|
|
158
|
-
padding: 0
|
|
159
|
-
|
|
412
|
+
margin-top: 16px;
|
|
413
|
+
padding: 0 24px;
|
|
414
|
+
position: relative;
|
|
415
|
+
z-index: 2;
|
|
416
|
+
letter-spacing: 0.5px;
|
|
160
417
|
}
|
|
161
418
|
</style>
|
|
162
419
|
</head>
|
|
163
420
|
<body>
|
|
164
421
|
<div id="container">
|
|
422
|
+
<div class="racing-stripes"></div>
|
|
423
|
+
<div class="carbon-texture"></div>
|
|
424
|
+
<div class="neon-line-left"></div>
|
|
425
|
+
<div class="neon-line-right"></div>
|
|
426
|
+
|
|
165
427
|
<div class="header">
|
|
166
|
-
<
|
|
428
|
+
<span class="header-icon">🏁</span>
|
|
429
|
+
<div class="title" id="header-title">里程排行榜</div>
|
|
430
|
+
<div class="title-accent"></div>
|
|
431
|
+
<div class="subtitle" id="header-subtitle">MILEAGE RANKING</div>
|
|
167
432
|
</div>
|
|
168
433
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
434
|
+
<!-- #1 Hero -->
|
|
435
|
+
<div id="hero" class="hero" style="display:none;"></div>
|
|
436
|
+
|
|
437
|
+
<!-- #2 & #3 Podium -->
|
|
438
|
+
<div id="podium-row" class="podium-row" style="display:none;"></div>
|
|
173
439
|
|
|
174
|
-
|
|
440
|
+
<!-- #4-10 Rank List -->
|
|
441
|
+
<div id="rank-list" class="rank-list"></div>
|
|
175
442
|
|
|
176
|
-
<div class="
|
|
177
|
-
|
|
443
|
+
<div id="divider" class="divider" style="display:none;"></div>
|
|
444
|
+
|
|
445
|
+
<!-- Current Player -->
|
|
446
|
+
<div id="current-section" class="current-section" style="display:none;">
|
|
447
|
+
<div class="current-title">你的排名</div>
|
|
178
448
|
<div id="current-player"></div>
|
|
179
449
|
</div>
|
|
180
450
|
|
|
181
|
-
<div
|
|
182
|
-
* 数据统计说明
|
|
183
|
-
</div>
|
|
451
|
+
<div id="footer" class="footer"></div>
|
|
184
452
|
</div>
|
|
185
453
|
|
|
186
454
|
<script>
|
|
187
|
-
function createLeaderboardItem(rank, playerName, mileage, isCurrentPlayer = false, isTop3 = false) {
|
|
188
|
-
const item = document.createElement('div');
|
|
189
|
-
item.className = `leaderboard-item${isTop3 ? ' top3' : ''}${isCurrentPlayer ? ' current-player' : ''}`;
|
|
190
|
-
|
|
191
|
-
let rankClass = '';
|
|
192
|
-
if (rank === 1) rankClass = 'top1';
|
|
193
|
-
else if (rank === 2) rankClass = 'top2';
|
|
194
|
-
else if (rank === 3) rankClass = 'top3';
|
|
195
|
-
|
|
196
|
-
item.innerHTML = `
|
|
197
|
-
<div class="item-content">
|
|
198
|
-
<div class="rank ${rankClass}">#${rank}</div>
|
|
199
|
-
<div class="player-info">
|
|
200
|
-
<div class="player-name">${playerName}</div>
|
|
201
|
-
</div>
|
|
202
|
-
<div class="mileage-value">${formatMileage(mileage)}</div>
|
|
203
|
-
</div>
|
|
204
|
-
`;
|
|
205
|
-
|
|
206
|
-
return item;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
455
|
function formatMileage(mileage) {
|
|
210
456
|
const meters = parseInt(mileage);
|
|
211
|
-
if (isNaN(meters) || meters < 0) return '0 km';
|
|
212
|
-
|
|
457
|
+
if (isNaN(meters) || meters < 0) return { value: '0', unit: 'km' };
|
|
213
458
|
const km = meters / 1000;
|
|
214
|
-
|
|
215
459
|
if (km >= 1000000) {
|
|
216
|
-
const
|
|
217
|
-
return value.endsWith('.00') ? Math.floor(km / 1000000) + '
|
|
460
|
+
const v = (km / 1000000).toFixed(2);
|
|
461
|
+
return { value: v.endsWith('.00') ? Math.floor(km / 1000000) + '' : v, unit: 'M km' };
|
|
218
462
|
} else if (km >= 1000) {
|
|
219
|
-
const
|
|
220
|
-
return value.endsWith('.00') ? Math.floor(km / 1000) + '
|
|
463
|
+
const v = (km / 1000).toFixed(2);
|
|
464
|
+
return { value: v.endsWith('.00') ? Math.floor(km / 1000) + '' : v, unit: 'K km' };
|
|
221
465
|
} else if (km >= 1) {
|
|
222
|
-
return Math.floor(km).toLocaleString()
|
|
466
|
+
return { value: Math.floor(km).toLocaleString(), unit: 'km' };
|
|
223
467
|
} else {
|
|
224
|
-
return meters.toLocaleString()
|
|
468
|
+
return { value: meters.toLocaleString(), unit: 'm' };
|
|
225
469
|
}
|
|
226
470
|
}
|
|
227
471
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// 设置标题和底部脚注
|
|
236
|
-
const titleElement = document.querySelector('.header .title');
|
|
237
|
-
const footerElement = document.getElementById('footer-note');
|
|
238
|
-
|
|
239
|
-
if (titleElement) {
|
|
240
|
-
const titles = {
|
|
241
|
-
1: '- 总行驶里程排行榜 -',
|
|
242
|
-
2: '- 今日行驶里程排行榜 -'
|
|
243
|
-
};
|
|
244
|
-
const footerNotes = {
|
|
245
|
-
1: '* 数据自 2025年8月23日 20:00 开始统计',
|
|
246
|
-
2: '* 每日 0:00 重置统计'
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
titleElement.textContent = titles[apiData.rankingType] || '🚗 行驶里程排行榜';
|
|
250
|
-
if (footerElement) {
|
|
251
|
-
footerElement.textContent = footerNotes[apiData.rankingType] || '* 数据统计说明';
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const topRankings = document.getElementById('top-rankings');
|
|
256
|
-
const currentPlayerContainer = document.getElementById('current-player');
|
|
257
|
-
|
|
258
|
-
// 清空现有内容
|
|
259
|
-
topRankings.innerHTML = '';
|
|
260
|
-
currentPlayerContainer.innerHTML = '';
|
|
261
|
-
|
|
262
|
-
// 渲染前10名排行榜
|
|
263
|
-
if (apiData.mileageRankingList && Array.isArray(apiData.mileageRankingList)) {
|
|
264
|
-
apiData.mileageRankingList.slice(0, 10).forEach((player) => {
|
|
265
|
-
if (player && player.tmpName && typeof player.distance !== 'undefined' && typeof player.ranking !== 'undefined') {
|
|
266
|
-
const isTop3 = player.ranking <= 3;
|
|
267
|
-
const item = createLeaderboardItem(player.ranking, player.tmpName, player.distance, false, isTop3);
|
|
268
|
-
topRankings.appendChild(item);
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
}
|
|
472
|
+
function fmtDist(mileage) {
|
|
473
|
+
const r = formatMileage(mileage);
|
|
474
|
+
return r.value + ' ' + r.unit;
|
|
475
|
+
}
|
|
272
476
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
false
|
|
281
|
-
);
|
|
282
|
-
currentPlayerContainer.appendChild(currentItem);
|
|
283
|
-
} else {
|
|
284
|
-
// 如果没有当前玩家数据,隐藏该部分
|
|
285
|
-
const divider = document.querySelector('.divider');
|
|
286
|
-
const currentPlayerSection = document.querySelector('.current-player-container');
|
|
287
|
-
if (divider) divider.style.display = 'none';
|
|
288
|
-
if (currentPlayerSection) currentPlayerSection.style.display = 'none';
|
|
289
|
-
}
|
|
477
|
+
function avatarHtml(url, name) {
|
|
478
|
+
const fb = (name || '?').charAt(0).toUpperCase();
|
|
479
|
+
return `<div style="position:relative;width:100%;height:100%;">
|
|
480
|
+
<img src="${url || ''}" style="width:100%;height:100%;object-fit:cover;border-radius:50%;"
|
|
481
|
+
onerror="this.style.display='none';this.nextElementSibling.style.display='flex';">
|
|
482
|
+
<div style="display:none;position:absolute;inset:0;border-radius:50%;background:linear-gradient(135deg,#ff6b00,#ff3d00);align-items:center;justify-content:center;font-size:18px;font-weight:800;color:#fff;">${fb}</div>
|
|
483
|
+
</div>`;
|
|
290
484
|
}
|
|
291
485
|
|
|
292
|
-
function
|
|
293
|
-
if (!
|
|
294
|
-
|
|
295
|
-
|
|
486
|
+
function setData(apiData) {
|
|
487
|
+
if (!apiData) return;
|
|
488
|
+
|
|
489
|
+
const titles = { 1: '总里程排行榜', 2: '今日里程排行榜' };
|
|
490
|
+
const subs = { 1: 'ALL-TIME MILEAGE RANKING', 2: 'TODAY\'S MILEAGE RANKING' };
|
|
491
|
+
const footers = { 1: '* 数据自 2025年8月23日 20:00 开始统计', 2: '* 每日 0:00 重置统计' };
|
|
492
|
+
|
|
493
|
+
document.getElementById('header-title').textContent = titles[apiData.rankingType] || '里程排行榜';
|
|
494
|
+
document.getElementById('header-subtitle').textContent = subs[apiData.rankingType] || 'MILEAGE RANKING';
|
|
495
|
+
document.getElementById('footer').textContent = footers[apiData.rankingType] || '';
|
|
496
|
+
|
|
497
|
+
const list = (apiData.mileageRankingList || []).slice(0, 10);
|
|
498
|
+
const maxDist = list.length > 0 ? Math.max(...list.map(p => parseInt(p.distance) || 0)) : 1;
|
|
499
|
+
|
|
500
|
+
// #1 Hero
|
|
501
|
+
if (list[0]) {
|
|
502
|
+
const p = list[0];
|
|
503
|
+
const d = formatMileage(p.distance);
|
|
504
|
+
document.getElementById('hero').style.display = '';
|
|
505
|
+
document.getElementById('hero').innerHTML = `
|
|
506
|
+
<div class="hero-crown">👑</div>
|
|
507
|
+
<div class="hero-info">
|
|
508
|
+
<div class="hero-name">${p.tmpName || '未知'}</div>
|
|
509
|
+
<div class="hero-rank">#1 LEADER</div>
|
|
510
|
+
</div>
|
|
511
|
+
<div class="hero-distance">${d.value}<span class="hero-distance-unit">${d.unit}</span></div>`;
|
|
296
512
|
}
|
|
297
513
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
514
|
+
// #2 & #3
|
|
515
|
+
if (list[1] || list[2]) {
|
|
516
|
+
document.getElementById('podium-row').style.display = '';
|
|
517
|
+
let html = '';
|
|
518
|
+
[list[1], list[2]].forEach((p, i) => {
|
|
519
|
+
if (!p) return;
|
|
520
|
+
const cls = i === 0 ? 'second' : 'third';
|
|
521
|
+
const medal = i === 0 ? '🥈' : '🥉';
|
|
522
|
+
html += `
|
|
523
|
+
<div class="podium-card ${cls}">
|
|
524
|
+
<div class="podium-medal">${medal}</div>
|
|
525
|
+
<div class="podium-card-info">
|
|
526
|
+
<div class="podium-card-name">${p.tmpName || '未知'}</div>
|
|
527
|
+
</div>
|
|
528
|
+
<div class="podium-card-dist">${fmtDist(p.distance)}</div>
|
|
529
|
+
</div>`;
|
|
314
530
|
});
|
|
531
|
+
document.getElementById('podium-row').innerHTML = html;
|
|
315
532
|
}
|
|
316
533
|
|
|
317
|
-
//
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
const currentPlayerSection = document.querySelector('.current-player-container');
|
|
331
|
-
if (divider) divider.style.display = 'none';
|
|
332
|
-
if (currentPlayerSection) currentPlayerSection.style.display = 'none';
|
|
534
|
+
// #4-10 with progress bar
|
|
535
|
+
const rankList = document.getElementById('rank-list');
|
|
536
|
+
rankList.innerHTML = '';
|
|
537
|
+
for (let i = 3; i < list.length; i++) {
|
|
538
|
+
const p = list[i];
|
|
539
|
+
const pct = Math.max(5, ((parseInt(p.distance) || 0) / maxDist) * 100);
|
|
540
|
+
rankList.innerHTML += `
|
|
541
|
+
<div class="rank-item">
|
|
542
|
+
<div class="rank-number">${p.ranking}</div>
|
|
543
|
+
<div class="rank-name">${p.tmpName || '未知'}</div>
|
|
544
|
+
<div class="rank-bar"><div class="rank-bar-fill" style="width:${pct}%"></div></div>
|
|
545
|
+
<div class="rank-distance">${fmtDist(p.distance)}</div>
|
|
546
|
+
</div>`;
|
|
333
547
|
}
|
|
334
|
-
}
|
|
335
548
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
{ name: "R8 anderson", mileage: 319004 },
|
|
348
|
-
{ name: "lorddarki85", mileage: 317788 }
|
|
349
|
-
],
|
|
350
|
-
currentPlayer: {
|
|
351
|
-
rank: 3365,
|
|
352
|
-
name: "ZyRoX Drum",
|
|
353
|
-
mileage: 59515
|
|
549
|
+
// Current Player
|
|
550
|
+
const cp = apiData.playerMileageRanking;
|
|
551
|
+
if (cp && cp.tmpName && typeof cp.ranking !== 'undefined') {
|
|
552
|
+
document.getElementById('divider').style.display = '';
|
|
553
|
+
document.getElementById('current-section').style.display = '';
|
|
554
|
+
document.getElementById('current-player').innerHTML = `
|
|
555
|
+
<div class="current-card">
|
|
556
|
+
<div class="current-rank">#${cp.ranking}</div>
|
|
557
|
+
<div class="current-name">${cp.tmpName}</div>
|
|
558
|
+
<div class="current-distance">${fmtDist(cp.distance)}</div>
|
|
559
|
+
</div>`;
|
|
354
560
|
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// 页面加载时初始化示例数据
|
|
358
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
359
|
-
init(sampleData);
|
|
360
|
-
});
|
|
561
|
+
}
|
|
361
562
|
</script>
|
|
362
563
|
</body>
|
|
363
564
|
</html>
|