@sjtdev/koishi-plugin-dota2tracker 1.1.0 → 1.1.2-beta.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 +523 -770
- package/package.json +3 -4
- package/readme.md +6 -7
- package/template/guild_member/guild_member.ejs +131 -0
- package/template/{hero.html → hero/hero_1.ejs} +543 -516
- package/template/images/scepter.png +0 -0
- package/template/images/shard.png +0 -0
- package/template/match/match_1.ejs +9 -8
- package/template/match/match_2.ejs +7 -5
- package/template/player/player_1.ejs +543 -0
- package/template/match_old.html +0 -1029
- package/template/player.html +0 -414
package/lib/index.js
CHANGED
|
@@ -44,13 +44,413 @@ var utils_exports = {};
|
|
|
44
44
|
__export(utils_exports, {
|
|
45
45
|
CONFIGS: () => CONFIGS,
|
|
46
46
|
ImageType: () => ImageType,
|
|
47
|
+
formatNumber: () => formatNumber,
|
|
47
48
|
getFormattedMatchData: () => getFormattedMatchData,
|
|
48
49
|
getImageUrl: () => getImageUrl,
|
|
49
|
-
|
|
50
|
+
playerisValid: () => playerisValid,
|
|
51
|
+
query: () => query,
|
|
52
|
+
readDirectoryFilesSync: () => readDirectoryFilesSync,
|
|
53
|
+
sec2time: () => sec2time,
|
|
54
|
+
winRateColor: () => winRateColor
|
|
50
55
|
});
|
|
51
56
|
var import_axios = __toESM(require("axios"));
|
|
52
57
|
var import_fs = __toESM(require("fs"));
|
|
58
|
+
var dotaconstants2 = __toESM(require("dotaconstants"));
|
|
59
|
+
var import_path = __toESM(require("path"));
|
|
60
|
+
|
|
61
|
+
// src/queries.ts
|
|
53
62
|
var dotaconstants = __toESM(require("dotaconstants"));
|
|
63
|
+
function MATCH_INFO(matchId) {
|
|
64
|
+
return `
|
|
65
|
+
{
|
|
66
|
+
match(id: ${matchId}) {
|
|
67
|
+
id
|
|
68
|
+
didRadiantWin
|
|
69
|
+
lobbyType
|
|
70
|
+
gameMode
|
|
71
|
+
regionId
|
|
72
|
+
parsedDateTime
|
|
73
|
+
startDateTime
|
|
74
|
+
endDateTime
|
|
75
|
+
actualRank
|
|
76
|
+
rank
|
|
77
|
+
averageRank
|
|
78
|
+
durationSeconds
|
|
79
|
+
topLaneOutcome
|
|
80
|
+
midLaneOutcome
|
|
81
|
+
bottomLaneOutcome
|
|
82
|
+
radiantKills
|
|
83
|
+
direKills
|
|
84
|
+
players {
|
|
85
|
+
steamAccountId
|
|
86
|
+
steamAccount {
|
|
87
|
+
name
|
|
88
|
+
}
|
|
89
|
+
level
|
|
90
|
+
hero {
|
|
91
|
+
id
|
|
92
|
+
name
|
|
93
|
+
shortName
|
|
94
|
+
}
|
|
95
|
+
dotaPlus{
|
|
96
|
+
level
|
|
97
|
+
}
|
|
98
|
+
leaverStatus
|
|
99
|
+
partyId
|
|
100
|
+
position
|
|
101
|
+
lane
|
|
102
|
+
imp
|
|
103
|
+
kills
|
|
104
|
+
deaths
|
|
105
|
+
assists
|
|
106
|
+
isRadiant
|
|
107
|
+
networth
|
|
108
|
+
steamAccount {
|
|
109
|
+
seasonRank
|
|
110
|
+
seasonLeaderboardRank
|
|
111
|
+
}
|
|
112
|
+
item0Id
|
|
113
|
+
item1Id
|
|
114
|
+
item2Id
|
|
115
|
+
item3Id
|
|
116
|
+
item4Id
|
|
117
|
+
item5Id
|
|
118
|
+
backpack0Id
|
|
119
|
+
backpack1Id
|
|
120
|
+
backpack2Id
|
|
121
|
+
neutral0Id
|
|
122
|
+
stats {
|
|
123
|
+
matchPlayerBuffEvent {
|
|
124
|
+
abilityId
|
|
125
|
+
itemId
|
|
126
|
+
stackCount
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
playbackData {
|
|
130
|
+
purchaseEvents {
|
|
131
|
+
itemId
|
|
132
|
+
time
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
heroDamage
|
|
136
|
+
towerDamage
|
|
137
|
+
stats {
|
|
138
|
+
heroDamageReport {
|
|
139
|
+
receivedTotal {
|
|
140
|
+
physicalDamage
|
|
141
|
+
magicalDamage
|
|
142
|
+
pureDamage
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
numLastHits
|
|
147
|
+
numDenies
|
|
148
|
+
goldPerMinute
|
|
149
|
+
experiencePerMinute
|
|
150
|
+
heroHealing
|
|
151
|
+
|
|
152
|
+
stats {
|
|
153
|
+
campStack
|
|
154
|
+
heroDamageReport {
|
|
155
|
+
dealtTotal {
|
|
156
|
+
stunDuration
|
|
157
|
+
stunCount
|
|
158
|
+
slowDuration
|
|
159
|
+
slowCount
|
|
160
|
+
disableDuration
|
|
161
|
+
disableCount
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
additionalUnit{
|
|
166
|
+
item0Id
|
|
167
|
+
item1Id
|
|
168
|
+
item2Id
|
|
169
|
+
item3Id
|
|
170
|
+
item4Id
|
|
171
|
+
item5Id
|
|
172
|
+
backpack0Id
|
|
173
|
+
backpack1Id
|
|
174
|
+
backpack2Id
|
|
175
|
+
neutral0Id
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
isRandom
|
|
179
|
+
}
|
|
180
|
+
pickBans {
|
|
181
|
+
isPick
|
|
182
|
+
bannedHeroId
|
|
183
|
+
heroId
|
|
184
|
+
order
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
`;
|
|
190
|
+
}
|
|
191
|
+
__name(MATCH_INFO, "MATCH_INFO");
|
|
192
|
+
function VERIFYING_PLAYER(steamAccountId) {
|
|
193
|
+
return `
|
|
194
|
+
{
|
|
195
|
+
player(steamAccountId: ${steamAccountId}) {
|
|
196
|
+
matchCount
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
`;
|
|
201
|
+
}
|
|
202
|
+
__name(VERIFYING_PLAYER, "VERIFYING_PLAYER");
|
|
203
|
+
function PLAYERS_LASTMATCH(steamAccountIds) {
|
|
204
|
+
return `
|
|
205
|
+
{
|
|
206
|
+
players(steamAccountIds:${JSON.stringify(steamAccountIds)}) {
|
|
207
|
+
steamAccount{id}
|
|
208
|
+
matches(request:{take:1}){
|
|
209
|
+
id
|
|
210
|
+
parsedDateTime
|
|
211
|
+
startDateTime
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
`;
|
|
217
|
+
}
|
|
218
|
+
__name(PLAYERS_LASTMATCH, "PLAYERS_LASTMATCH");
|
|
219
|
+
function PLAYER_INFO_WITH_25_MATCHES(steamAccountId) {
|
|
220
|
+
return `
|
|
221
|
+
{
|
|
222
|
+
player(steamAccountId: ${steamAccountId}) {
|
|
223
|
+
steamAccount {
|
|
224
|
+
avatar
|
|
225
|
+
name
|
|
226
|
+
seasonRank
|
|
227
|
+
seasonLeaderboardRank
|
|
228
|
+
id
|
|
229
|
+
}
|
|
230
|
+
guildMember {
|
|
231
|
+
guild {
|
|
232
|
+
tag
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
matchCount
|
|
236
|
+
winCount
|
|
237
|
+
performance {
|
|
238
|
+
imp
|
|
239
|
+
}
|
|
240
|
+
heroesPerformance(take: 25, request: {matchGroupOrderBy: WIN_COUNT, take: 25}) {
|
|
241
|
+
hero {
|
|
242
|
+
id
|
|
243
|
+
shortName
|
|
244
|
+
}
|
|
245
|
+
imp
|
|
246
|
+
winCount
|
|
247
|
+
matchCount
|
|
248
|
+
}
|
|
249
|
+
matches(request: {take: 25}) {
|
|
250
|
+
id
|
|
251
|
+
rank
|
|
252
|
+
lobbyType
|
|
253
|
+
gameMode
|
|
254
|
+
startDateTime
|
|
255
|
+
durationSeconds
|
|
256
|
+
didRadiantWin
|
|
257
|
+
topLaneOutcome
|
|
258
|
+
midLaneOutcome
|
|
259
|
+
bottomLaneOutcome
|
|
260
|
+
radiantKills
|
|
261
|
+
direKills
|
|
262
|
+
players(steamAccountId: ${steamAccountId}) {
|
|
263
|
+
isRadiant
|
|
264
|
+
lane
|
|
265
|
+
kills
|
|
266
|
+
deaths
|
|
267
|
+
assists
|
|
268
|
+
position
|
|
269
|
+
award
|
|
270
|
+
imp
|
|
271
|
+
hero {
|
|
272
|
+
id
|
|
273
|
+
shortName
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
`;
|
|
282
|
+
}
|
|
283
|
+
__name(PLAYER_INFO_WITH_25_MATCHES, "PLAYER_INFO_WITH_25_MATCHES");
|
|
284
|
+
function PLAYER_EXTRA_INFO(steamAccountId, matchCount, totalHeroCount) {
|
|
285
|
+
return `{
|
|
286
|
+
player(steamAccountId: ${steamAccountId}) {
|
|
287
|
+
heroesPerformance(take: ${totalHeroCount}, request: {matchGroupOrderBy: MATCH_COUNT, take: ${matchCount}}) {
|
|
288
|
+
hero {
|
|
289
|
+
id
|
|
290
|
+
shortName
|
|
291
|
+
}
|
|
292
|
+
winCount
|
|
293
|
+
matchCount
|
|
294
|
+
imp
|
|
295
|
+
}
|
|
296
|
+
dotaPlus {
|
|
297
|
+
heroId
|
|
298
|
+
level
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
`;
|
|
303
|
+
}
|
|
304
|
+
__name(PLAYER_EXTRA_INFO, "PLAYER_EXTRA_INFO");
|
|
305
|
+
function PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD(steamAccountIds) {
|
|
306
|
+
return `{
|
|
307
|
+
players(steamAccountId: [${steamAccountIds.join()}]) {
|
|
308
|
+
steamAccount {
|
|
309
|
+
id
|
|
310
|
+
avatar
|
|
311
|
+
name
|
|
312
|
+
seasonRank
|
|
313
|
+
}
|
|
314
|
+
matches(request: {take: 10}) {
|
|
315
|
+
didRadiantWin
|
|
316
|
+
startDateTime
|
|
317
|
+
players {
|
|
318
|
+
isRadiant
|
|
319
|
+
kills
|
|
320
|
+
deaths
|
|
321
|
+
assists
|
|
322
|
+
steamAccount {
|
|
323
|
+
id
|
|
324
|
+
}
|
|
325
|
+
hero {
|
|
326
|
+
shortName
|
|
327
|
+
}
|
|
328
|
+
imp
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
`;
|
|
334
|
+
}
|
|
335
|
+
__name(PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD, "PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD");
|
|
336
|
+
function CURRENT_GAMEVERSION() {
|
|
337
|
+
return `
|
|
338
|
+
{
|
|
339
|
+
constants {
|
|
340
|
+
gameVersions{name id}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
`;
|
|
345
|
+
}
|
|
346
|
+
__name(CURRENT_GAMEVERSION, "CURRENT_GAMEVERSION");
|
|
347
|
+
function ALL_ABILITIES_CHINESE_NAME() {
|
|
348
|
+
return `
|
|
349
|
+
{
|
|
350
|
+
constants {
|
|
351
|
+
abilities(language:S_CHINESE){
|
|
352
|
+
id
|
|
353
|
+
language{displayName}
|
|
354
|
+
}
|
|
355
|
+
gameVersions{name id}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
`;
|
|
360
|
+
}
|
|
361
|
+
__name(ALL_ABILITIES_CHINESE_NAME, "ALL_ABILITIES_CHINESE_NAME");
|
|
362
|
+
function HERO_INFO(heroId) {
|
|
363
|
+
return `
|
|
364
|
+
{
|
|
365
|
+
constants {
|
|
366
|
+
hero(id: ${heroId}, language: S_CHINESE) {
|
|
367
|
+
id
|
|
368
|
+
name
|
|
369
|
+
shortName
|
|
370
|
+
aliases
|
|
371
|
+
roles {
|
|
372
|
+
roleId
|
|
373
|
+
level
|
|
374
|
+
}
|
|
375
|
+
language {
|
|
376
|
+
displayName
|
|
377
|
+
lore
|
|
378
|
+
hype
|
|
379
|
+
}
|
|
380
|
+
abilities {
|
|
381
|
+
ability(language: S_CHINESE) {
|
|
382
|
+
name
|
|
383
|
+
language {
|
|
384
|
+
displayName
|
|
385
|
+
description
|
|
386
|
+
attributes
|
|
387
|
+
lore
|
|
388
|
+
aghanimDescription
|
|
389
|
+
shardDescription
|
|
390
|
+
notes
|
|
391
|
+
}
|
|
392
|
+
stat {
|
|
393
|
+
type
|
|
394
|
+
behavior
|
|
395
|
+
unitTargetType
|
|
396
|
+
unitTargetTeam
|
|
397
|
+
unitTargetFlags
|
|
398
|
+
unitDamageType
|
|
399
|
+
cooldown
|
|
400
|
+
manaCost
|
|
401
|
+
spellImmunity
|
|
402
|
+
isOnCastbar
|
|
403
|
+
isGrantedByShard
|
|
404
|
+
isGrantedByScepter
|
|
405
|
+
hasShardUpgrade
|
|
406
|
+
hasScepterUpgrade
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
talents {
|
|
411
|
+
abilityId
|
|
412
|
+
slot
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
`;
|
|
419
|
+
}
|
|
420
|
+
__name(HERO_INFO, "HERO_INFO");
|
|
421
|
+
function HERO_MATCHUP_WINRATE(heroId) {
|
|
422
|
+
return `
|
|
423
|
+
{
|
|
424
|
+
heroStats {
|
|
425
|
+
matchUp(heroId: ${heroId}, take: ${Object.keys(dotaconstants.heroes).length - 1},bracketBasicIds:LEGEND_ANCIENT) {
|
|
426
|
+
heroId
|
|
427
|
+
matchCountWith
|
|
428
|
+
matchCountVs
|
|
429
|
+
with {
|
|
430
|
+
heroId1
|
|
431
|
+
winRateHeroId1
|
|
432
|
+
heroId2
|
|
433
|
+
winRateHeroId2
|
|
434
|
+
winCount
|
|
435
|
+
matchCount
|
|
436
|
+
}
|
|
437
|
+
vs {
|
|
438
|
+
heroId1
|
|
439
|
+
winRateHeroId1
|
|
440
|
+
heroId2
|
|
441
|
+
winRateHeroId2
|
|
442
|
+
winCount
|
|
443
|
+
matchCount
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
`;
|
|
450
|
+
}
|
|
451
|
+
__name(HERO_MATCHUP_WINRATE, "HERO_MATCHUP_WINRATE");
|
|
452
|
+
|
|
453
|
+
// src/utils.ts
|
|
54
454
|
var CONFIGS = { STRATZ_API: { URL: "https://api.stratz.com/graphql", TOKEN: "" } };
|
|
55
455
|
async function query(query_str) {
|
|
56
456
|
return await import_axios.default.post(CONFIGS.STRATZ_API.URL, query_str, {
|
|
@@ -182,8 +582,8 @@ function getFormattedMatchData(match) {
|
|
|
182
582
|
const itemId = player[key];
|
|
183
583
|
if (itemId === void 0 || itemId === null) {
|
|
184
584
|
player.items.push(null);
|
|
185
|
-
} else if (
|
|
186
|
-
const name2 =
|
|
585
|
+
} else if (dotaconstants2.item_ids[itemId]) {
|
|
586
|
+
const name2 = dotaconstants2.item_ids[itemId];
|
|
187
587
|
const isRecipe = name2.startsWith(prefix);
|
|
188
588
|
const cleanName = isRecipe ? name2.substring(prefix.length) : name2;
|
|
189
589
|
player.items.push({
|
|
@@ -201,8 +601,8 @@ function getFormattedMatchData(match) {
|
|
|
201
601
|
const itemId = player[key];
|
|
202
602
|
if (itemId === void 0 || itemId === null) {
|
|
203
603
|
player.backpacks.push(null);
|
|
204
|
-
} else if (
|
|
205
|
-
const name2 =
|
|
604
|
+
} else if (dotaconstants2.item_ids[itemId]) {
|
|
605
|
+
const name2 = dotaconstants2.item_ids[itemId];
|
|
206
606
|
const isRecipe = name2.startsWith(prefix);
|
|
207
607
|
const cleanName = isRecipe ? name2.substring(prefix.length) : name2;
|
|
208
608
|
player.backpacks.push({
|
|
@@ -224,8 +624,8 @@ function getFormattedMatchData(match) {
|
|
|
224
624
|
const itemId = player.additionalUnit[key];
|
|
225
625
|
if (itemId === void 0 || itemId === null) {
|
|
226
626
|
player.unitItems.push(null);
|
|
227
|
-
} else if (
|
|
228
|
-
const name2 =
|
|
627
|
+
} else if (dotaconstants2.item_ids[itemId]) {
|
|
628
|
+
const name2 = dotaconstants2.item_ids[itemId];
|
|
229
629
|
const isRecipe = name2.startsWith(prefix2);
|
|
230
630
|
const cleanName = isRecipe ? name2.substring(prefix2.length) : name2;
|
|
231
631
|
player.unitItems.push({
|
|
@@ -243,8 +643,8 @@ function getFormattedMatchData(match) {
|
|
|
243
643
|
const itemId = player.additionalUnit[key];
|
|
244
644
|
if (itemId === void 0 || itemId === null) {
|
|
245
645
|
player.unitBackpacks.push(null);
|
|
246
|
-
} else if (
|
|
247
|
-
const name2 =
|
|
646
|
+
} else if (dotaconstants2.item_ids[itemId]) {
|
|
647
|
+
const name2 = dotaconstants2.item_ids[itemId];
|
|
248
648
|
const isRecipe = name2.startsWith(prefix2);
|
|
249
649
|
const cleanName = isRecipe ? name2.substring(prefix2.length) : name2;
|
|
250
650
|
player.unitBackpacks.push({
|
|
@@ -309,381 +709,74 @@ function getFormattedMatchData(match) {
|
|
|
309
709
|
} else if (currentContribution === lowestContribution) {
|
|
310
710
|
const currentPlayerScore = player.kills + player.assists;
|
|
311
711
|
const lowestPlayerScore = lowest.kills + lowest.assists;
|
|
312
|
-
if (currentPlayerScore < lowestPlayerScore) {
|
|
313
|
-
return player;
|
|
314
|
-
} else if (currentPlayerScore === lowestPlayerScore) {
|
|
315
|
-
return player.heroDamage < lowest.heroDamage ? player : lowest;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
return lowest;
|
|
319
|
-
}).titles.push({ name: "摸", color: "#DDDDDD" });
|
|
320
|
-
return match;
|
|
321
|
-
}
|
|
322
|
-
__name(getFormattedMatchData, "getFormattedMatchData");
|
|
323
|
-
|
|
324
|
-
// src/queries.ts
|
|
325
|
-
var dotaconstants2 = __toESM(require("dotaconstants"));
|
|
326
|
-
function MATCH_INFO(matchId) {
|
|
327
|
-
return `
|
|
328
|
-
{
|
|
329
|
-
match(id: ${matchId}) {
|
|
330
|
-
id
|
|
331
|
-
didRadiantWin
|
|
332
|
-
lobbyType
|
|
333
|
-
gameMode
|
|
334
|
-
regionId
|
|
335
|
-
parsedDateTime
|
|
336
|
-
startDateTime
|
|
337
|
-
endDateTime
|
|
338
|
-
actualRank
|
|
339
|
-
rank
|
|
340
|
-
averageRank
|
|
341
|
-
durationSeconds
|
|
342
|
-
topLaneOutcome
|
|
343
|
-
midLaneOutcome
|
|
344
|
-
bottomLaneOutcome
|
|
345
|
-
radiantKills
|
|
346
|
-
direKills
|
|
347
|
-
players {
|
|
348
|
-
steamAccountId
|
|
349
|
-
steamAccount {
|
|
350
|
-
name
|
|
351
|
-
}
|
|
352
|
-
level
|
|
353
|
-
hero {
|
|
354
|
-
id
|
|
355
|
-
name
|
|
356
|
-
shortName
|
|
357
|
-
}
|
|
358
|
-
dotaPlus{
|
|
359
|
-
level
|
|
360
|
-
}
|
|
361
|
-
leaverStatus
|
|
362
|
-
partyId
|
|
363
|
-
position
|
|
364
|
-
lane
|
|
365
|
-
imp
|
|
366
|
-
kills
|
|
367
|
-
deaths
|
|
368
|
-
assists
|
|
369
|
-
isRadiant
|
|
370
|
-
networth
|
|
371
|
-
steamAccount {
|
|
372
|
-
seasonRank
|
|
373
|
-
seasonLeaderboardRank
|
|
374
|
-
}
|
|
375
|
-
item0Id
|
|
376
|
-
item1Id
|
|
377
|
-
item2Id
|
|
378
|
-
item3Id
|
|
379
|
-
item4Id
|
|
380
|
-
item5Id
|
|
381
|
-
backpack0Id
|
|
382
|
-
backpack1Id
|
|
383
|
-
backpack2Id
|
|
384
|
-
neutral0Id
|
|
385
|
-
stats {
|
|
386
|
-
matchPlayerBuffEvent {
|
|
387
|
-
abilityId
|
|
388
|
-
itemId
|
|
389
|
-
stackCount
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
playbackData {
|
|
393
|
-
purchaseEvents {
|
|
394
|
-
itemId
|
|
395
|
-
time
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
heroDamage
|
|
399
|
-
towerDamage
|
|
400
|
-
stats {
|
|
401
|
-
heroDamageReport {
|
|
402
|
-
receivedTotal {
|
|
403
|
-
physicalDamage
|
|
404
|
-
magicalDamage
|
|
405
|
-
pureDamage
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
numLastHits
|
|
410
|
-
numDenies
|
|
411
|
-
goldPerMinute
|
|
412
|
-
experiencePerMinute
|
|
413
|
-
heroHealing
|
|
414
|
-
|
|
415
|
-
stats {
|
|
416
|
-
campStack
|
|
417
|
-
heroDamageReport {
|
|
418
|
-
dealtTotal {
|
|
419
|
-
stunDuration
|
|
420
|
-
stunCount
|
|
421
|
-
slowDuration
|
|
422
|
-
slowCount
|
|
423
|
-
disableDuration
|
|
424
|
-
disableCount
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
additionalUnit{
|
|
429
|
-
item0Id
|
|
430
|
-
item1Id
|
|
431
|
-
item2Id
|
|
432
|
-
item3Id
|
|
433
|
-
item4Id
|
|
434
|
-
item5Id
|
|
435
|
-
backpack0Id
|
|
436
|
-
backpack1Id
|
|
437
|
-
backpack2Id
|
|
438
|
-
neutral0Id
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
isRandom
|
|
442
|
-
}
|
|
443
|
-
pickBans {
|
|
444
|
-
isPick
|
|
445
|
-
bannedHeroId
|
|
446
|
-
heroId
|
|
447
|
-
order
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
`;
|
|
453
|
-
}
|
|
454
|
-
__name(MATCH_INFO, "MATCH_INFO");
|
|
455
|
-
function VERIFYING_PLAYER(steamAccountId) {
|
|
456
|
-
return `
|
|
457
|
-
{
|
|
458
|
-
player(steamAccountId: ${steamAccountId}) {
|
|
459
|
-
matchCount
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
`;
|
|
464
|
-
}
|
|
465
|
-
__name(VERIFYING_PLAYER, "VERIFYING_PLAYER");
|
|
466
|
-
function PLAYERS_LASTMATCH(steamAccountIds) {
|
|
467
|
-
return `
|
|
468
|
-
{
|
|
469
|
-
players(steamAccountIds:${JSON.stringify(steamAccountIds)}) {
|
|
470
|
-
steamAccount{id}
|
|
471
|
-
matches(request:{take:1}){
|
|
472
|
-
id
|
|
473
|
-
parsedDateTime
|
|
474
|
-
startDateTime
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
`;
|
|
480
|
-
}
|
|
481
|
-
__name(PLAYERS_LASTMATCH, "PLAYERS_LASTMATCH");
|
|
482
|
-
function PLAYER_INFO_WITH_25_MATCHES(steamAccountId) {
|
|
483
|
-
return `
|
|
484
|
-
{
|
|
485
|
-
player(steamAccountId: ${steamAccountId}) {
|
|
486
|
-
steamAccount {
|
|
487
|
-
avatar
|
|
488
|
-
name
|
|
489
|
-
seasonRank
|
|
490
|
-
seasonLeaderboardRank
|
|
491
|
-
id
|
|
492
|
-
}
|
|
493
|
-
guildMember {
|
|
494
|
-
guild {
|
|
495
|
-
tag
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
matchCount
|
|
499
|
-
winCount
|
|
500
|
-
performance {
|
|
501
|
-
imp
|
|
502
|
-
}
|
|
503
|
-
heroesPerformance(take: 25, request: {matchGroupOrderBy: WIN_COUNT, take: 25}) {
|
|
504
|
-
hero {
|
|
505
|
-
id
|
|
506
|
-
shortName
|
|
507
|
-
}
|
|
508
|
-
imp
|
|
509
|
-
winCount
|
|
510
|
-
matchCount
|
|
511
|
-
}
|
|
512
|
-
matches(request: {take: 25}) {
|
|
513
|
-
id
|
|
514
|
-
rank
|
|
515
|
-
lobbyType
|
|
516
|
-
gameMode
|
|
517
|
-
endDateTime
|
|
518
|
-
durationSeconds
|
|
519
|
-
didRadiantWin
|
|
520
|
-
topLaneOutcome
|
|
521
|
-
midLaneOutcome
|
|
522
|
-
bottomLaneOutcome
|
|
523
|
-
radiantKills
|
|
524
|
-
direKills
|
|
525
|
-
players(steamAccountId: ${steamAccountId}) {
|
|
526
|
-
isRadiant
|
|
527
|
-
lane
|
|
528
|
-
kills
|
|
529
|
-
deaths
|
|
530
|
-
assists
|
|
531
|
-
award
|
|
532
|
-
imp
|
|
533
|
-
hero {
|
|
534
|
-
id
|
|
535
|
-
shortName
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
`;
|
|
544
|
-
}
|
|
545
|
-
__name(PLAYER_INFO_WITH_25_MATCHES, "PLAYER_INFO_WITH_25_MATCHES");
|
|
546
|
-
function PLAYER_EXTRA_INFO(steamAccountId, matchCount, totalHeroCount) {
|
|
547
|
-
return `{
|
|
548
|
-
player(steamAccountId: ${steamAccountId}) {
|
|
549
|
-
heroesPerformance(take: ${totalHeroCount}, request: {matchGroupOrderBy: MATCH_COUNT, take: ${matchCount}}) {
|
|
550
|
-
hero {
|
|
551
|
-
id
|
|
552
|
-
shortName
|
|
553
|
-
}
|
|
554
|
-
winCount
|
|
555
|
-
matchCount
|
|
556
|
-
imp
|
|
557
|
-
}
|
|
558
|
-
dotaPlus {
|
|
559
|
-
heroId
|
|
560
|
-
level
|
|
561
|
-
}
|
|
562
|
-
}
|
|
712
|
+
if (currentPlayerScore < lowestPlayerScore) {
|
|
713
|
+
return player;
|
|
714
|
+
} else if (currentPlayerScore === lowestPlayerScore) {
|
|
715
|
+
return player.heroDamage < lowest.heroDamage ? player : lowest;
|
|
563
716
|
}
|
|
564
|
-
|
|
717
|
+
}
|
|
718
|
+
return lowest;
|
|
719
|
+
}).titles.push({ name: "摸", color: "#DDDDDD" });
|
|
720
|
+
return match;
|
|
565
721
|
}
|
|
566
|
-
__name(
|
|
567
|
-
function
|
|
568
|
-
return
|
|
569
|
-
{
|
|
570
|
-
constants {
|
|
571
|
-
gameVersions{name id}
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
`;
|
|
722
|
+
__name(getFormattedMatchData, "getFormattedMatchData");
|
|
723
|
+
function sec2time(sec) {
|
|
724
|
+
return sec ? (sec < 0 ? "-" : "") + Math.floor(Math.abs(sec) / 60) + ":" + ("00" + Math.abs(sec) % 60).slice(-2) : "--:--";
|
|
576
725
|
}
|
|
577
|
-
__name(
|
|
578
|
-
function
|
|
579
|
-
return
|
|
580
|
-
{
|
|
581
|
-
constants {
|
|
582
|
-
abilities(language:S_CHINESE){
|
|
583
|
-
id
|
|
584
|
-
language{displayName}
|
|
585
|
-
}
|
|
586
|
-
gameVersions{name id}
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
`;
|
|
726
|
+
__name(sec2time, "sec2time");
|
|
727
|
+
function formatNumber(num) {
|
|
728
|
+
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
591
729
|
}
|
|
592
|
-
__name(
|
|
593
|
-
function
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
roles {
|
|
603
|
-
roleId
|
|
604
|
-
level
|
|
605
|
-
}
|
|
606
|
-
language {
|
|
607
|
-
displayName
|
|
608
|
-
lore
|
|
609
|
-
hype
|
|
610
|
-
}
|
|
611
|
-
abilities {
|
|
612
|
-
ability(language: S_CHINESE) {
|
|
613
|
-
name
|
|
614
|
-
language {
|
|
615
|
-
displayName
|
|
616
|
-
description
|
|
617
|
-
attributes
|
|
618
|
-
lore
|
|
619
|
-
aghanimDescription
|
|
620
|
-
shardDescription
|
|
621
|
-
notes
|
|
622
|
-
}
|
|
623
|
-
stat {
|
|
624
|
-
type
|
|
625
|
-
behavior
|
|
626
|
-
unitTargetType
|
|
627
|
-
unitTargetTeam
|
|
628
|
-
unitTargetFlags
|
|
629
|
-
unitDamageType
|
|
630
|
-
cooldown
|
|
631
|
-
manaCost
|
|
632
|
-
spellImmunity
|
|
633
|
-
isOnCastbar
|
|
634
|
-
isGrantedByShard
|
|
635
|
-
isGrantedByScepter
|
|
636
|
-
hasShardUpgrade
|
|
637
|
-
hasScepterUpgrade
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
talents {
|
|
642
|
-
abilityId
|
|
643
|
-
slot
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
`;
|
|
730
|
+
__name(formatNumber, "formatNumber");
|
|
731
|
+
function readDirectoryFilesSync(directoryPath) {
|
|
732
|
+
try {
|
|
733
|
+
const files = import_fs.default.readdirSync(directoryPath);
|
|
734
|
+
const fileNames = files.map((file) => import_path.default.basename(file, import_path.default.extname(file)));
|
|
735
|
+
return fileNames;
|
|
736
|
+
} catch (error) {
|
|
737
|
+
console.error("Error reading directory:", error);
|
|
738
|
+
return [];
|
|
739
|
+
}
|
|
650
740
|
}
|
|
651
|
-
__name(
|
|
652
|
-
function
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
heroId1
|
|
670
|
-
winRateHeroId1
|
|
671
|
-
heroId2
|
|
672
|
-
winRateHeroId2
|
|
673
|
-
winCount
|
|
674
|
-
matchCount
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
`;
|
|
741
|
+
__name(readDirectoryFilesSync, "readDirectoryFilesSync");
|
|
742
|
+
function winRateColor(value) {
|
|
743
|
+
value = value * 100;
|
|
744
|
+
value = Math.max(0, Math.min(100, value));
|
|
745
|
+
let red, green, blue;
|
|
746
|
+
if (value <= 50) {
|
|
747
|
+
let scale = Math.round(255 * (value / 50));
|
|
748
|
+
red = 255;
|
|
749
|
+
green = scale;
|
|
750
|
+
blue = scale;
|
|
751
|
+
} else {
|
|
752
|
+
let scale = Math.round(255 * ((value - 50) / 50));
|
|
753
|
+
red = 255 - scale;
|
|
754
|
+
green = 255;
|
|
755
|
+
blue = 255 - scale;
|
|
756
|
+
}
|
|
757
|
+
const toHex = /* @__PURE__ */ __name((color) => color.toString(16).padStart(2, "0").toUpperCase(), "toHex");
|
|
758
|
+
return `#${toHex(red)}${toHex(green)}${toHex(blue)}`;
|
|
681
759
|
}
|
|
682
|
-
__name(
|
|
760
|
+
__name(winRateColor, "winRateColor");
|
|
761
|
+
async function playerisValid(steamAccountId) {
|
|
762
|
+
try {
|
|
763
|
+
let queryRes = await query(VERIFYING_PLAYER(steamAccountId));
|
|
764
|
+
if (queryRes.status == 200) {
|
|
765
|
+
if (queryRes.data.data.player.matchCount != null)
|
|
766
|
+
return { isValid: true };
|
|
767
|
+
else
|
|
768
|
+
return { isValid: false, reason: "SteamID无效或无任何场次。" };
|
|
769
|
+
}
|
|
770
|
+
} catch (error) {
|
|
771
|
+
console.error(error);
|
|
772
|
+
return { isValid: false, reason: "网络状况不佳SteamID验证失败,请稍后重试。" };
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
__name(playerisValid, "playerisValid");
|
|
683
776
|
|
|
684
777
|
// src/index.ts
|
|
685
778
|
var import_fs2 = __toESM(require("fs"));
|
|
686
|
-
var
|
|
779
|
+
var import_path2 = __toESM(require("path"));
|
|
687
780
|
var import_moment = __toESM(require("moment"));
|
|
688
781
|
var dotaconstants3 = __toESM(require("dotaconstants"));
|
|
689
782
|
|
|
@@ -956,14 +1049,19 @@ var dotaconstants_add_default = {
|
|
|
956
1049
|
// src/index.ts
|
|
957
1050
|
var import_koishi2 = require("koishi");
|
|
958
1051
|
var ejs = __toESM(require("ejs"));
|
|
959
|
-
var import_path = __toESM(require("path"));
|
|
960
1052
|
var name = "dota2tracker";
|
|
961
1053
|
var usage = "DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑定),以及一系列查询功能。";
|
|
962
1054
|
var inject = ["database", "puppeteer", "cron"];
|
|
963
|
-
var Config = import_koishi.Schema.
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
})
|
|
1055
|
+
var Config = import_koishi.Schema.intersect([
|
|
1056
|
+
import_koishi.Schema.object({
|
|
1057
|
+
STRATZ_API_TOKEN: import_koishi.Schema.string().required().description("※必须。stratz.com的API TOKEN,可在 https://stratz.com/api 获取")
|
|
1058
|
+
}).description("基础设置"),
|
|
1059
|
+
import_koishi.Schema.object({
|
|
1060
|
+
template_match: import_koishi.Schema.union([...readDirectoryFilesSync(`./node_modules/@sjtdev/koishi-plugin-${name}/template/match`)]).default("match_1").description("生成比赛信息图片使用的模板,见 https://github.com/sjtdev/koishi-plugin-dota2tracker/wiki 有模板展示。"),
|
|
1061
|
+
template_player: import_koishi.Schema.union([...readDirectoryFilesSync(`./node_modules/@sjtdev/koishi-plugin-${name}/template/player`)]).default("player_1").description("生成玩家信息图片使用的模板。(目前仅有一张模板)"),
|
|
1062
|
+
template_hero: import_koishi.Schema.union([...readDirectoryFilesSync(`./node_modules/@sjtdev/koishi-plugin-${name}/template/hero`)]).default("hero_1").description("生成英雄信息图片使用的模板。(目前仅有一张模板)")
|
|
1063
|
+
}).description("模板设置")
|
|
1064
|
+
]);
|
|
967
1065
|
var pendingMatches = [];
|
|
968
1066
|
var random = new import_koishi2.Random(() => Math.random());
|
|
969
1067
|
async function apply(ctx, config) {
|
|
@@ -1008,11 +1106,15 @@ async function apply(ctx, config) {
|
|
|
1008
1106
|
);
|
|
1009
1107
|
return;
|
|
1010
1108
|
}
|
|
1011
|
-
let verifyRes = await
|
|
1012
|
-
if (!verifyRes.
|
|
1109
|
+
let verifyRes = await playerisValid(steam_id);
|
|
1110
|
+
if (!verifyRes.isValid) {
|
|
1013
1111
|
session.send(`绑定失败,${verifyRes.reason}`);
|
|
1014
1112
|
return;
|
|
1015
1113
|
}
|
|
1114
|
+
if (!/^(?:.{1,20})?$/.test(nick_name ?? "")) {
|
|
1115
|
+
session.send("别名过长,请限制在20个字符以内。(也可以留空)");
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1016
1118
|
session.send(
|
|
1017
1119
|
`
|
|
1018
1120
|
绑定成功,
|
|
@@ -1041,6 +1143,10 @@ async function apply(ctx, config) {
|
|
|
1041
1143
|
session.send("请输入你的别名。");
|
|
1042
1144
|
return;
|
|
1043
1145
|
}
|
|
1146
|
+
if (!/^.{1,20}$/.test(nick_name ?? "")) {
|
|
1147
|
+
session.send("别名过长,请限制在20个字符以内。");
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1044
1150
|
sessionPlayer.nickName = nick_name;
|
|
1045
1151
|
await ctx.database.set("dt_subscribed_players", sessionPlayer.id, { nickName: sessionPlayer.nickName });
|
|
1046
1152
|
session.send(`改名成功,现在你叫${nick_name}了。`);
|
|
@@ -1051,8 +1157,30 @@ async function apply(ctx, config) {
|
|
|
1051
1157
|
});
|
|
1052
1158
|
ctx.command("查询群友", "查询本群已绑定的玩家").action(async ({ session }) => {
|
|
1053
1159
|
if (session.guild) {
|
|
1054
|
-
|
|
1055
|
-
|
|
1160
|
+
const subscribedPlayers = await ctx.database.get("dt_subscribed_players", { guildId: session.event.guild.id, platform: session.platform });
|
|
1161
|
+
if (!subscribedPlayers.length) {
|
|
1162
|
+
session.send("本群尚无绑定玩家。");
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1165
|
+
if (subscribedPlayers.length <= 20) {
|
|
1166
|
+
try {
|
|
1167
|
+
const memberList = await session.bot.getGuildMemberList(session.event.guild.id);
|
|
1168
|
+
ctx.logger.info(JSON.stringify(memberList.data));
|
|
1169
|
+
let queryRes = await query(PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD(subscribedPlayers.map((player) => player.steamId)));
|
|
1170
|
+
if (queryRes.status == 200) {
|
|
1171
|
+
const users = subscribedPlayers.map((subscribedPlayer) => {
|
|
1172
|
+
const queryPlayer = queryRes.data.data.players.find((player) => player.steamAccount.id == subscribedPlayer.steamId);
|
|
1173
|
+
const queryMember = memberList.data.find((member) => member.user.id == subscribedPlayer.userId);
|
|
1174
|
+
return { ...subscribedPlayer, ...queryPlayer, ...queryMember };
|
|
1175
|
+
});
|
|
1176
|
+
session.send(await ctx.puppeteer.render(genImageHTML(users, "guild_member" /* GuildMember */, "guild_member" /* GuildMember */)));
|
|
1177
|
+
} else
|
|
1178
|
+
throw 0;
|
|
1179
|
+
} catch (error) {
|
|
1180
|
+
console.error(error);
|
|
1181
|
+
session.send("查询群友失败。");
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1056
1184
|
}
|
|
1057
1185
|
});
|
|
1058
1186
|
async function queryAndDisplayMatch(session, matchId) {
|
|
@@ -1069,7 +1197,7 @@ async function apply(ctx, config) {
|
|
|
1069
1197
|
}
|
|
1070
1198
|
}
|
|
1071
1199
|
if (match && match.parsedDateTime) {
|
|
1072
|
-
session.send(await ctx.puppeteer.render(
|
|
1200
|
+
session.send(await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */)));
|
|
1073
1201
|
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: match.id, data: match, queryTime: /* @__PURE__ */ new Date() }]);
|
|
1074
1202
|
} else {
|
|
1075
1203
|
pendingMatches.push({ matchId, platform: session.event.platform, guildId: session.event.guild.id });
|
|
@@ -1175,7 +1303,7 @@ async function apply(ctx, config) {
|
|
|
1175
1303
|
player.heroesPerformanceTop10 = playerExtra.heroesPerformance.slice(0, 10);
|
|
1176
1304
|
} else
|
|
1177
1305
|
throw 0;
|
|
1178
|
-
session.send(await ctx.puppeteer.render(
|
|
1306
|
+
session.send(await ctx.puppeteer.render(genImageHTML(player, config.template_player, "player" /* Player */)));
|
|
1179
1307
|
} catch (error) {
|
|
1180
1308
|
console.error(error);
|
|
1181
1309
|
session.send("获取玩家信息失败。");
|
|
@@ -1228,7 +1356,7 @@ async function apply(ctx, config) {
|
|
|
1228
1356
|
if (queryRes3.status == 200) {
|
|
1229
1357
|
let hero = queryRes3.data.data.constants.hero;
|
|
1230
1358
|
hero.talents.forEach((talent) => talent.name_cn = AbilitiesConstantsCN.data.abilities.find((item) => item.id == talent.abilityId).language.displayName);
|
|
1231
|
-
await session.send(await ctx.puppeteer.render(
|
|
1359
|
+
await session.send(await ctx.puppeteer.render(genImageHTML(hero, config.template_hero, "hero" /* Hero */)));
|
|
1232
1360
|
} else
|
|
1233
1361
|
throw 0;
|
|
1234
1362
|
} catch (error) {
|
|
@@ -1355,7 +1483,7 @@ async function apply(ctx, config) {
|
|
|
1355
1483
|
const commingMatches = scanningMatches.filter((item) => item.matchId == match.id);
|
|
1356
1484
|
const realCommingMatches = commingMatches.filter((commingMatch, index, self) => index === self.findIndex((t) => t.guildId === commingMatch.guildId && t.platform === commingMatch.platform));
|
|
1357
1485
|
let broadMatchMessage = "";
|
|
1358
|
-
const img = await ctx.puppeteer.render(
|
|
1486
|
+
const img = await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */));
|
|
1359
1487
|
for (let comming of realCommingMatches) {
|
|
1360
1488
|
let commingSubscribedPlayers = subscribedPlayersInGuild.filter((item) => item.platform == comming.platform && item.guildId == comming.guildId);
|
|
1361
1489
|
let idsToFind = commingSubscribedPlayers.map((item) => item.steamId);
|
|
@@ -1394,20 +1522,18 @@ KDA:${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)} [${
|
|
|
1394
1522
|
});
|
|
1395
1523
|
}
|
|
1396
1524
|
__name(apply, "apply");
|
|
1397
|
-
function
|
|
1398
|
-
const templatePath =
|
|
1399
|
-
const
|
|
1400
|
-
|
|
1525
|
+
function genImageHTML(data, template, type) {
|
|
1526
|
+
const templatePath = import_path2.default.join(`./node_modules/@sjtdev/koishi-plugin-${name}/template/${type}`, template + ".ejs");
|
|
1527
|
+
const templateData = {
|
|
1528
|
+
data,
|
|
1401
1529
|
utils: utils_exports,
|
|
1402
1530
|
ImageType,
|
|
1403
1531
|
d2a: dotaconstants_add_exports,
|
|
1404
1532
|
dotaconstants: dotaconstants3,
|
|
1405
|
-
moment: import_moment.default
|
|
1406
|
-
sec2time,
|
|
1407
|
-
formatNumber
|
|
1533
|
+
moment: import_moment.default
|
|
1408
1534
|
};
|
|
1409
1535
|
let result = "";
|
|
1410
|
-
ejs.renderFile(templatePath,
|
|
1536
|
+
ejs.renderFile(templatePath, templateData, (err, html) => {
|
|
1411
1537
|
if (err)
|
|
1412
1538
|
throw err;
|
|
1413
1539
|
else
|
|
@@ -1417,380 +1543,7 @@ function newGenMatchImageHTML(match, template = "match_1") {
|
|
|
1417
1543
|
import_fs2.default.writeFileSync("./node_modules/@sjtdev/koishi-plugin-dota2tracker/temp.html", result);
|
|
1418
1544
|
return result;
|
|
1419
1545
|
}
|
|
1420
|
-
__name(
|
|
1421
|
-
function genHeroHTML(hero) {
|
|
1422
|
-
let $ = cheerio.load(import_fs2.default.readFileSync(`./node_modules/@sjtdev/koishi-plugin-${name}/template/hero.html`, "utf-8"));
|
|
1423
|
-
let html = `
|
|
1424
|
-
<div class="hero" id="${hero.id}">
|
|
1425
|
-
<img src="${getImageUrl(hero.shortName, "heroes" /* Heroes */)}" alt="" />
|
|
1426
|
-
<img class="pri_attr" src="${getImageUrl(primary_attrs[dotaconstants3.heroes[hero.id].primary_attr], "icons" /* Icons */)}" alt="" />
|
|
1427
|
-
<div class="info">
|
|
1428
|
-
<p class="name">${hero.language.displayName}</p>
|
|
1429
|
-
<p class="roles">
|
|
1430
|
-
${hero.roles.map((item) => `<span class="role level${item.level}">${roles[item.roleId]}</span>`).join("")}
|
|
1431
|
-
</p>
|
|
1432
|
-
<p class="attrs">
|
|
1433
|
-
<span class="str">${dotaconstants3.heroes[hero.id].base_str} <span class="gain">+${dotaconstants3.heroes[hero.id].str_gain.toFixed(1)}</span></span>
|
|
1434
|
-
<span class="agi">${dotaconstants3.heroes[hero.id].base_agi} <span class="gain">+${dotaconstants3.heroes[hero.id].agi_gain.toFixed(1)}</span></span>
|
|
1435
|
-
<span class="int">${dotaconstants3.heroes[hero.id].base_int} <span class="gain">+${dotaconstants3.heroes[hero.id].int_gain.toFixed(1)}</span></span>
|
|
1436
|
-
</p>
|
|
1437
|
-
</div>
|
|
1438
|
-
</div>
|
|
1439
|
-
<div class="details">
|
|
1440
|
-
<div class="hype_talents">
|
|
1441
|
-
<div class="hype">
|
|
1442
|
-
${hero.language.hype}
|
|
1443
|
-
</div>
|
|
1444
|
-
<div class="talents">
|
|
1445
|
-
<div class="talent">
|
|
1446
|
-
<div class="left">${hero.talents[7].name_cn}</div>
|
|
1447
|
-
<div class="level">25</div>
|
|
1448
|
-
<div class="right">${hero.talents[6].name_cn}</div>
|
|
1449
|
-
</div>
|
|
1450
|
-
<div class="talent">
|
|
1451
|
-
<div class="left">${hero.talents[5].name_cn}</div>
|
|
1452
|
-
<div class="level">20</div>
|
|
1453
|
-
<div class="right">${hero.talents[4].name_cn}</div>
|
|
1454
|
-
</div>
|
|
1455
|
-
<div class="talent">
|
|
1456
|
-
<div class="left">${hero.talents[3].name_cn}</div>
|
|
1457
|
-
<div class="level">15</div>
|
|
1458
|
-
<div class="right">${hero.talents[2].name_cn}</div>
|
|
1459
|
-
</div>
|
|
1460
|
-
<div class="talent">
|
|
1461
|
-
<div class="left">${hero.talents[1].name_cn}</div>
|
|
1462
|
-
<div class="level">10</div>
|
|
1463
|
-
<div class="right">${hero.talents[0].name_cn}</div>
|
|
1464
|
-
</div>
|
|
1465
|
-
</div>
|
|
1466
|
-
</div>
|
|
1467
|
-
<table class="list">
|
|
1468
|
-
<tbody>
|
|
1469
|
-
<tr>
|
|
1470
|
-
<td>初始生命值</td>
|
|
1471
|
-
<td>${dotaconstants3.heroes[hero.id].base_health + dotaconstants3.heroes[hero.id].base_str * 22}</td>
|
|
1472
|
-
</tr>
|
|
1473
|
-
<tr>
|
|
1474
|
-
<td>初始生命回复</td>
|
|
1475
|
-
<td>${dotaconstants3.heroes[hero.id].base_health_regen}</td>
|
|
1476
|
-
</tr>
|
|
1477
|
-
<tr>
|
|
1478
|
-
<td>初始魔法值</td>
|
|
1479
|
-
<td>${dotaconstants3.heroes[hero.id].base_mana + dotaconstants3.heroes[hero.id].base_int * 12}</td>
|
|
1480
|
-
</tr>
|
|
1481
|
-
<tr>
|
|
1482
|
-
<td>初始魔法回复</td>
|
|
1483
|
-
<td>${dotaconstants3.heroes[hero.id].base_mana_regen}</td>
|
|
1484
|
-
</tr>
|
|
1485
|
-
<tr>
|
|
1486
|
-
<td>初始攻击力</td>
|
|
1487
|
-
<td>${dotaconstants3.heroes[hero.id].base_mr + Math.round(
|
|
1488
|
-
dotaconstants3.heroes[hero.id].primary_attr == "all" ? (dotaconstants3.heroes[hero.id].base_str + dotaconstants3.heroes[hero.id].base_agi + dotaconstants3.heroes[hero.id].base_int) * 0.7 : dotaconstants3.heroes[hero.id]["base_" + dotaconstants3.heroes[hero.id].primary_attr]
|
|
1489
|
-
)}(${dotaconstants3.heroes[hero.id].base_attack_min + Math.round(
|
|
1490
|
-
dotaconstants3.heroes[hero.id].primary_attr == "all" ? (dotaconstants3.heroes[hero.id].base_str + dotaconstants3.heroes[hero.id].base_agi + dotaconstants3.heroes[hero.id].base_int) * 0.7 : dotaconstants3.heroes[hero.id]["base_" + dotaconstants3.heroes[hero.id].primary_attr]
|
|
1491
|
-
)}~${dotaconstants3.heroes[hero.id].base_attack_max + Math.round(
|
|
1492
|
-
dotaconstants3.heroes[hero.id].primary_attr == "all" ? (dotaconstants3.heroes[hero.id].base_str + dotaconstants3.heroes[hero.id].base_agi + dotaconstants3.heroes[hero.id].base_int) * 0.7 : dotaconstants3.heroes[hero.id]["base_" + dotaconstants3.heroes[hero.id].primary_attr]
|
|
1493
|
-
)})</td>
|
|
1494
|
-
</tr>
|
|
1495
|
-
<tr>
|
|
1496
|
-
<td>基础攻击间隔</td>
|
|
1497
|
-
<td>${dotaconstants3.heroes[hero.id].attack_rate.toFixed(1)}</td>
|
|
1498
|
-
</tr>
|
|
1499
|
-
<tr>
|
|
1500
|
-
<td>基础攻击前摇</td>
|
|
1501
|
-
<td>${dotaconstants3.heroes[hero.id].attack_point.toFixed(1)}</td>
|
|
1502
|
-
</tr>
|
|
1503
|
-
<tr>
|
|
1504
|
-
<td>攻击范围</td>
|
|
1505
|
-
<td>${dotaconstants3.heroes[hero.id].attack_range}</td>
|
|
1506
|
-
</tr>
|
|
1507
|
-
<tr>
|
|
1508
|
-
<td>护甲</td>
|
|
1509
|
-
<td>${(Math.round((dotaconstants3.heroes[hero.id].base_armor + dotaconstants3.heroes[hero.id].base_agi * 0.167) * 10) / 10).toFixed(1)}</td>
|
|
1510
|
-
</tr>
|
|
1511
|
-
<tr>
|
|
1512
|
-
<td>移动速度</td>
|
|
1513
|
-
<td>${dotaconstants3.heroes[hero.id].move_speed}</td>
|
|
1514
|
-
</tr>
|
|
1515
|
-
<tr>
|
|
1516
|
-
<td>视野范围</td>
|
|
1517
|
-
<td>${dotaconstants3.heroes[hero.id].day_vision}(${dotaconstants3.heroes[hero.id].night_vision})</td>
|
|
1518
|
-
</tr>
|
|
1519
|
-
</tbody>
|
|
1520
|
-
</table>
|
|
1521
|
-
</div>
|
|
1522
|
-
<div class="skills">
|
|
1523
|
-
${hero.abilities.filter((item) => dotaconstants3.abilities[item.ability.name].behavior != "Hidden").map(
|
|
1524
|
-
(item) => `
|
|
1525
|
-
<div class="skill">
|
|
1526
|
-
<p class="title">${item.ability.language.displayName}</p>
|
|
1527
|
-
${item.ability.stat.isGrantedByScepter ? `<svg class="scepter" viewBox="0 0 19 20" fill="hsla(0,0%,100%,0.16)" width="24"><path d="M4.795 14.99a2.06 2.06 0 00-.96-.388c-1.668-.204-2.506.518-3.107 1.008.464.128.879.364.867.97 2.347-1.605 4.159.84 2.415 2.666-.14.147.65.929.767.718.203-.365.79-1.064 1.445-1.064.964 0 1.529.68 1.823.838.267.144.793-.372.642-.675-.03-.06-.229-.204-.569-.438-1.407-.197-1.935-1.093-2.37-2.026-.276-.593-.503-1.206-.953-1.61zm9.41 0a2.06 2.06 0 01.96-.388c1.668-.204 2.507.518 3.107 1.008-.464.128-.879.364-.867.97-2.347-1.605-4.158.84-2.415 2.666.14.147-.65.929-.768.718-.202-.365-.79-1.064-1.444-1.064-.965 0-1.529.68-1.823.838-.267.144-.793-.372-.642-.675.03-.06.229-.204.569-.438 1.407-.197 1.935-1.093 2.37-2.026.276-.593.503-1.206.953-1.61zm-3.919-2.211c0-.233-.175-.423-.392-.423h-.788c-.217 0-.392.19-.392.423v5.665c0 .232.175.421.392.421h.788c.216 0 .392-.189.392-.421v-5.665zm-1.989 2.543c-.553-.139-2.074-.563-2.702-1.17-.814-.784-1.107-3.135-2.655-3.52-1.29-.32-2.448.27-2.924 1.05-.06.101.055.241.252.178 2.786-.884 2.957 1.674 2.672 2.215a.275.275 0 00-.024.057c.87-.106 1.462.043 1.893.328.447.294.732.738.975 1.231.515 1.042.822 2.335 2.513 2.512v-2.88zm2.406 0c.553-.139 2.074-.563 2.703-1.17.812-.784 1.106-3.135 2.654-3.52 1.29-.32 2.448.27 2.924 1.05.06.101-.055.241-.252.178-2.786-.884-2.957 1.674-2.672 2.215a.27.27 0 01.024.057c-.87-.106-1.462.043-1.893.328-.447.294-.732.738-.975 1.231-.515 1.042-.822 2.335-2.513 2.512v-2.88z" fill="hsla(0,0%,100%,0.6)"></path><path d="M9.753.093a.39.39 0 00-.506 0C8.461.747 6.08 2.946 5.515 3.417a.434.434 0 00-.15.262c-.162.895-.949 4.817-1.12 5.764a.46.46 0 00.067.333c.37.564 1.665 2.752 2.071 3.37a.404.404 0 00.336.187h.768c.19 0 .356-.14.4-.337l.35-1.577a.416.416 0 01.399-.336h1.728c.19 0 .356.139.399.336l.35 1.577a.416.416 0 00.4.337h.768c.133 0 .259-.07.336-.187.406-.618 1.7-2.806 2.07-3.37a.457.457 0 00.067-.333c-.17-.947-.957-4.87-1.118-5.764a.435.435 0 00-.15-.262C12.92 2.946 10.537.747 9.752.093z" fill="url(#activeAghanimScepterGradient)"></path><defs><radialGradient id="activeAghanimScepterGradient" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.03623 10.4684) rotate(-90) scale(9.38905 7.0456)"><stop stop-color="#00CEFF"></stop><stop offset="1" stop-color="#3443C4"></stop></radialGradient></defs></svg>` : ""}
|
|
1528
|
-
${item.ability.stat.isGrantedByShard ? `<svg class="shard" viewBox="0 0 19 10" fill="hsla(0,0%,100%,0.16)" width="24"><path d="M0.259504 4.54746C0.272981 4.60325 0.326002 4.64198 0.386194 4.64198C0.831857 4.62418 2.60461 4.45628 3.91732 2.90727C4.49956 2.22054 4.37916 1.21884 3.64777 0.671532C2.91819 0.125197 1.85256 0.238284 1.27032 0.924899C-0.0423919 2.47305 0.17864 4.13525 0.259504 4.54746Z" fill="url(#activeAghanimLeftShardGradient)"></path><path d="M9.46713 9.98081C9.42698 10.0064 9.37572 10.0064 9.33559 9.98081C8.88968 9.67166 6.33212 7.75166 6.33212 4.38581C6.33212 2.96661 7.70742 1.81406 9.40136 1.81406C11.0953 1.81406 12.4706 2.96661 12.4706 4.38581C12.4706 7.75166 9.91303 9.67166 9.46713 9.98081Z" fill="url(#activeAghanimMidShardGradient)"></path><path d="M18.6888 4.54746C18.6753 4.60325 18.6232 4.64198 18.5631 4.64198C18.1173 4.62418 16.3445 4.45628 15.0317 2.90727C14.4494 2.22054 14.5697 1.21884 15.3003 0.671532C16.0308 0.125197 17.0966 0.238284 17.6788 0.924899C18.9917 2.47305 18.7707 4.13525 18.6888 4.54746Z" fill="url(#activeAghanimRightShardGradient)"></path><defs><radialGradient id="activeAghanimMidShardGradient" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.01787 2.49983) rotate(90) scale(7.50029 5.21143)"><stop stop-color="#00CEFF"></stop><stop offset="1" stop-color="#3443C4"></stop></radialGradient><radialGradient id="activeAghanimLeftShardGradient" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(3.98746 0.625367) rotate(128.66) scale(6.00315 4.79432)"><stop stop-color="#00CEFF"></stop><stop offset="1" stop-color="#3443C4"></stop></radialGradient><radialGradient id="activeAghanimRightShardGradient" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(14.2996 0.625367) rotate(51.3402) scale(6.00316 4.7942)"><stop stop-color="#00CEFF"></stop><stop offset="1" stop-color="#3443C4"></stop></radialGradient></defs></svg>` : ""}
|
|
1529
|
-
<div class="img_stats">
|
|
1530
|
-
<img src="${getImageUrl(item.ability.name, "abilities" /* Abilities */)}" alt="" />
|
|
1531
|
-
<div class="stats">
|
|
1532
|
-
<p class="behavior">技能:${(Array.isArray(dotaconstants3.abilities[item.ability.name].behavior) ? dotaconstants3.abilities[item.ability.name].behavior : [dotaconstants3.abilities[item.ability.name].behavior]).filter((beh) => beh !== "Hidden" || !(item.ability.stat.isGrantedByShard || item.ability.stat.isGrantedByScepter)).map((beh) => behavior[beh]).join("/")}</p>
|
|
1533
|
-
${dotaconstants3.abilities[item.ability.name].target_team ? `<p class="target_team">影响:${(Array.isArray(dotaconstants3.abilities[item.ability.name].target_team) ? dotaconstants3.abilities[item.ability.name].target_team : [dotaconstants3.abilities[item.ability.name].target_team]).map((tt) => target_team[tt]).join("/")}</p>` : ""}
|
|
1534
|
-
${!Array.isArray(dotaconstants3.abilities[item.ability.name].dmg_type) && dotaconstants3.abilities[item.ability.name].dmg_type ? `<p class="dmg_type ${dotaconstants3.abilities[item.ability.name].dmg_type}">伤害类型:</p>` : ""}
|
|
1535
|
-
${dotaconstants3.abilities[item.ability.name].dispellable ? `<p class="dispellable ${dotaconstants3.abilities[item.ability.name].dispellable == "Strong Dispels Only" ? "Strong" : dotaconstants3.abilities[item.ability.name].dispellable}">能否驱散:</p>` : ""}
|
|
1536
|
-
${!Array.isArray(dotaconstants3.abilities[item.ability.name].bkbpierce) && dotaconstants3.abilities[item.ability.name].bkbpierce ? `<p class="bkbpierce">无视减益免疫: ${dotaconstants3.abilities[item.ability.name].bkbpierce == "Yes" ? "是" : "否"}</p>` : ""}
|
|
1537
|
-
</div>
|
|
1538
|
-
</div>
|
|
1539
|
-
${item.ability.language.description.map((desc) => `<p class="description">${desc}</p>`).join("")}
|
|
1540
|
-
${item.ability.language.aghanimDescription ? `<p class="aghanim_description"><span class="title"><svg viewBox="0 0 19 20" fill="hsla(0,0%,100%,0.16)" width="24"><path d="M4.795 14.99a2.06 2.06 0 00-.96-.388c-1.668-.204-2.506.518-3.107 1.008.464.128.879.364.867.97 2.347-1.605 4.159.84 2.415 2.666-.14.147.65.929.767.718.203-.365.79-1.064 1.445-1.064.964 0 1.529.68 1.823.838.267.144.793-.372.642-.675-.03-.06-.229-.204-.569-.438-1.407-.197-1.935-1.093-2.37-2.026-.276-.593-.503-1.206-.953-1.61zm9.41 0a2.06 2.06 0 01.96-.388c1.668-.204 2.507.518 3.107 1.008-.464.128-.879.364-.867.97-2.347-1.605-4.158.84-2.415 2.666.14.147-.65.929-.768.718-.202-.365-.79-1.064-1.444-1.064-.965 0-1.529.68-1.823.838-.267.144-.793-.372-.642-.675.03-.06.229-.204.569-.438 1.407-.197 1.935-1.093 2.37-2.026.276-.593.503-1.206.953-1.61zm-3.919-2.211c0-.233-.175-.423-.392-.423h-.788c-.217 0-.392.19-.392.423v5.665c0 .232.175.421.392.421h.788c.216 0 .392-.189.392-.421v-5.665zm-1.989 2.543c-.553-.139-2.074-.563-2.702-1.17-.814-.784-1.107-3.135-2.655-3.52-1.29-.32-2.448.27-2.924 1.05-.06.101.055.241.252.178 2.786-.884 2.957 1.674 2.672 2.215a.275.275 0 00-.024.057c.87-.106 1.462.043 1.893.328.447.294.732.738.975 1.231.515 1.042.822 2.335 2.513 2.512v-2.88zm2.406 0c.553-.139 2.074-.563 2.703-1.17.812-.784 1.106-3.135 2.654-3.52 1.29-.32 2.448.27 2.924 1.05.06.101-.055.241-.252.178-2.786-.884-2.957 1.674-2.672 2.215a.27.27 0 01.024.057c-.87-.106-1.462.043-1.893.328-.447.294-.732.738-.975 1.231-.515 1.042-.822 2.335-2.513 2.512v-2.88z" fill="hsla(0,0%,100%,0.6)"></path><path d="M9.753.093a.39.39 0 00-.506 0C8.461.747 6.08 2.946 5.515 3.417a.434.434 0 00-.15.262c-.162.895-.949 4.817-1.12 5.764a.46.46 0 00.067.333c.37.564 1.665 2.752 2.071 3.37a.404.404 0 00.336.187h.768c.19 0 .356-.14.4-.337l.35-1.577a.416.416 0 01.399-.336h1.728c.19 0 .356.139.399.336l.35 1.577a.416.416 0 00.4.337h.768c.133 0 .259-.07.336-.187.406-.618 1.7-2.806 2.07-3.37a.457.457 0 00.067-.333c-.17-.947-.957-4.87-1.118-5.764a.435.435 0 00-.15-.262C12.92 2.946 10.537.747 9.752.093z" fill="url(#activeAghanimScepterGradient)"></path><defs><radialGradient id="activeAghanimScepterGradient" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.03623 10.4684) rotate(-90) scale(9.38905 7.0456)"><stop stop-color="#00CEFF"></stop><stop offset="1" stop-color="#3443C4"></stop></radialGradient></defs></svg>
|
|
1541
|
-
阿哈利姆神杖</span><span class="desc">${item.ability.language.aghanimDescription}</span></p>` : ""}
|
|
1542
|
-
${item.ability.language.shardDescription ? `<p class="aghanim_description"><span class="title"><svg viewBox="0 0 19 10" fill="hsla(0,0%,100%,0.16)" width="24"><path d="M0.259504 4.54746C0.272981 4.60325 0.326002 4.64198 0.386194 4.64198C0.831857 4.62418 2.60461 4.45628 3.91732 2.90727C4.49956 2.22054 4.37916 1.21884 3.64777 0.671532C2.91819 0.125197 1.85256 0.238284 1.27032 0.924899C-0.0423919 2.47305 0.17864 4.13525 0.259504 4.54746Z" fill="url(#activeAghanimLeftShardGradient)"></path><path d="M9.46713 9.98081C9.42698 10.0064 9.37572 10.0064 9.33559 9.98081C8.88968 9.67166 6.33212 7.75166 6.33212 4.38581C6.33212 2.96661 7.70742 1.81406 9.40136 1.81406C11.0953 1.81406 12.4706 2.96661 12.4706 4.38581C12.4706 7.75166 9.91303 9.67166 9.46713 9.98081Z" fill="url(#activeAghanimMidShardGradient)"></path><path d="M18.6888 4.54746C18.6753 4.60325 18.6232 4.64198 18.5631 4.64198C18.1173 4.62418 16.3445 4.45628 15.0317 2.90727C14.4494 2.22054 14.5697 1.21884 15.3003 0.671532C16.0308 0.125197 17.0966 0.238284 17.6788 0.924899C18.9917 2.47305 18.7707 4.13525 18.6888 4.54746Z" fill="url(#activeAghanimRightShardGradient)"></path><defs><radialGradient id="activeAghanimMidShardGradient" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.01787 2.49983) rotate(90) scale(7.50029 5.21143)"><stop stop-color="#00CEFF"></stop><stop offset="1" stop-color="#3443C4"></stop></radialGradient><radialGradient id="activeAghanimLeftShardGradient" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(3.98746 0.625367) rotate(128.66) scale(6.00315 4.79432)"><stop stop-color="#00CEFF"></stop><stop offset="1" stop-color="#3443C4"></stop></radialGradient><radialGradient id="activeAghanimRightShardGradient" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(14.2996 0.625367) rotate(51.3402) scale(6.00316 4.7942)"><stop stop-color="#00CEFF"></stop><stop offset="1" stop-color="#3443C4"></stop></radialGradient></defs></svg>
|
|
1543
|
-
阿哈利姆魔晶</span><span class="desc">${item.ability.language.shardDescription}</span></p>` : ""}
|
|
1544
|
-
<div class="notes"${!item.ability.language.notes.length ? ` style="display:none;"` : ""}>
|
|
1545
|
-
${item.ability.language.notes.map((note) => `<p>${note}</p>`).join("")}
|
|
1546
|
-
</div>
|
|
1547
|
-
<div class="attributes">
|
|
1548
|
-
${item.ability.language.attributes.map((attr) => {
|
|
1549
|
-
const parts = attr.split(":");
|
|
1550
|
-
return `<p><span class="item">${parts[0]}</span><span class="values">${parts[1]}</span></p>`;
|
|
1551
|
-
}).join("")}
|
|
1552
|
-
</div>
|
|
1553
|
-
<p>
|
|
1554
|
-
${dotaconstants3.abilities[item.ability.name].cd ? `<span class="cooldown"> ${(Array.isArray(dotaconstants3.abilities[item.ability.name].cd) ? dotaconstants3.abilities[item.ability.name].cd : [dotaconstants3.abilities[item.ability.name].cd]).join(
|
|
1555
|
-
" / "
|
|
1556
|
-
)} </span>` : ""}
|
|
1557
|
-
${dotaconstants3.abilities[item.ability.name].mc ? `<span class="mana_cost"> ${(Array.isArray(dotaconstants3.abilities[item.ability.name].mc) ? dotaconstants3.abilities[item.ability.name].mc : [dotaconstants3.abilities[item.ability.name].mc]).join(
|
|
1558
|
-
" / "
|
|
1559
|
-
)} </span>` : ""}
|
|
1560
|
-
</p>
|
|
1561
|
-
<p class="lore"${!item.ability.language.lore ? ` style="display:none;"` : ""}>${item.ability.language.lore}</p>
|
|
1562
|
-
</div>
|
|
1563
|
-
`
|
|
1564
|
-
).join("")}
|
|
1565
|
-
</div>
|
|
1566
|
-
<div class="lore">
|
|
1567
|
-
${hero.language.lore}
|
|
1568
|
-
</div>
|
|
1569
|
-
`;
|
|
1570
|
-
$(".wrapper").html(html);
|
|
1571
|
-
if (process.env.NODE_ENV === "development")
|
|
1572
|
-
import_fs2.default.writeFileSync("./node_modules/@sjtdev/koishi-plugin-dota2tracker/temp.html", $.html());
|
|
1573
|
-
return $.html();
|
|
1574
|
-
}
|
|
1575
|
-
__name(genHeroHTML, "genHeroHTML");
|
|
1576
|
-
function genPlayerHTML(player) {
|
|
1577
|
-
let $ = cheerio.load(import_fs2.default.readFileSync(`./node_modules/@sjtdev/koishi-plugin-${name}/template/player.html`, "utf-8"));
|
|
1578
|
-
const guildLevel = /* @__PURE__ */ __name((percent) => {
|
|
1579
|
-
if (percent <= 25) {
|
|
1580
|
-
return "Copper";
|
|
1581
|
-
} else if (percent <= 50) {
|
|
1582
|
-
return "Silver";
|
|
1583
|
-
} else if (percent <= 75) {
|
|
1584
|
-
return "Gold";
|
|
1585
|
-
} else {
|
|
1586
|
-
return "Diamond";
|
|
1587
|
-
}
|
|
1588
|
-
}, "guildLevel");
|
|
1589
|
-
const laneSVG = {
|
|
1590
|
-
stomp: `<svg viewBox="0 0 24 24" class="hitagi__sc-1apuy4g-0 hmhZOG"><path d="M8.05731 22.3674L9.60454 22.8002L11.5974 21.6551L12.043 20.0773L13.5902 20.51L15.583 19.3649L16.0287 17.7871L17.5759 18.2199L19.5687 17.0748L20.0143 15.4969L21.5615 15.9297L23.5544 14.7846L24 13.2068L23.4492 12.2014L7.50651 21.3621L8.05731 22.3674ZM12.1328 3.50265L11.0312 1.49196C10.8798 1.21549 10.5316 1.11811 10.2576 1.27556L0.29345 7.00098C0.0194354 7.15843 -0.0808273 7.51346 0.0706444 7.78993L1.44766 10.3033L11.91 4.29159C12.184 4.13414 12.2843 3.77912 12.1328 3.50265ZM18.3935 8.4063L14.1658 9.60458L12.4221 10.6065C12.2851 10.6853 12.111 10.6366 12.0353 10.4983L11.7599 9.99565C11.6842 9.85742 11.7343 9.6799 11.8713 9.60118L13.615 8.59924L13.0642 7.59389L11.3205 8.59584C11.1835 8.67456 11.0094 8.62587 10.9337 8.48765L10.6583 7.98497C10.5826 7.84673 10.6327 7.66922 10.7697 7.5905L12.5134 6.58855L11.9626 5.58321L1.99846 11.3086L6.9557 20.3567L22.8984 11.196L22.2615 10.0336C21.5024 8.64813 19.9073 7.97847 18.3935 8.4063Z"></path></svg>`,
|
|
1591
|
-
victory: `<svg viewBox="0 0 512 512"><path d="M198.844 64.75c-.985 0-1.974.03-2.97.094-15.915 1.015-32.046 11.534-37.78 26.937-34.072 91.532-51.085 128.865-61.5 222.876 14.633 13.49 31.63 26.45 50.25 38.125l66.406-196.467 17.688 5.968L163.28 362.5c19.51 10.877 40.43 20.234 62 27.28l75.407-201.53 17.5 6.53-74.937 200.282c19.454 5.096 39.205 8.2 58.78 8.875L381.345 225.5l17.094 7.594-75.875 170.656c21.82-1.237 43.205-5.768 63.437-14.28 43.317-53.844 72.633-109.784 84.5-172.69 5.092-26.992-14.762-53.124-54.22-54.81l-6.155-.282-2.188-5.75c-8.45-22.388-19.75-30.093-31.5-32.47-11.75-2.376-25.267 1.535-35.468 7.376l-13.064 7.47-.906-15c-.99-16.396-10.343-29.597-24.313-35.626-13.97-6.03-33.064-5.232-54.812 9.906l-10.438 7.25-3.812-12.125c-6.517-20.766-20.007-27.985-34.78-27.97zM103.28 188.344C71.143 233.448 47.728 299.56 51.407 359.656c27.54 21.84 54.61 33.693 80.063 35.438 14.155.97 27.94-1.085 41.405-6.438-35.445-17.235-67.36-39.533-92.594-63.53l-3.343-3.157.5-4.595c5.794-54.638 13.946-91.5 25.844-129.03z"/></svg>`,
|
|
1592
|
-
fail: `<svg viewBox="0 0 36 36"><path fill="#ff6961" d="M36 32a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h28a4 4 0 0 1 4 4v28z"></path><circle fill="#FFF" cx="27" cy="7" r="3"></circle><path fill="#FFF" d="M13.06 13.06l2.367-2.366l3.859 1.158l-2.635 2.847a10.018 10.018 0 0 1 4.392 3.379l5.017-5.017a1.5 1.5 0 0 0-.63-2.497l-9.999-3a1.495 1.495 0 0 0-1.492.376l-3 3a1.5 1.5 0 1 0 2.121 2.12zm16.065 4.949a1.496 1.496 0 0 0-1.262-.503l-6.786.617a9.966 9.966 0 0 1 1.464 2.879l3.548-.322l-1.554 6.995a1.499 1.499 0 1 0 2.928.65l2-9a1.5 1.5 0 0 0-.338-1.316zM13 16a8 8 0 1 0 0 16a8 8 0 0 0 0-16zm0 14a6 6 0 1 1 .002-12.002A6 6 0 0 1 13 30z"></path></svg>`,
|
|
1593
|
-
stomped: `<svg viewBox="-1 0 19 19"><path d="M16.417 9.579A7.917 7.917 0 1 1 8.5 1.662a7.917 7.917 0 0 1 7.917 7.917zm-2.458 2.96a.396.396 0 0 0-.396-.397h-.667a1.527 1.527 0 0 0-1.249-1.114.777.777 0 0 0 .014-.145V9.378a.794.794 0 0 0-.792-.792H8.201a2.984 2.984 0 0 0-1.682-.516l-.11.002V7.42h2.997a.396.396 0 1 0 0-.792H6.41v-1.3a.396.396 0 0 0-.396-.397H4.891a.396.396 0 0 0 0 .792h.727V8.21a2.997 2.997 0 1 0 3.836 3.466h.71a1.526 1.526 0 1 0 2.732 1.26h.667a.396.396 0 0 0 .396-.397zM8.078 9.507a2.205 2.205 0 1 1-1.559-.646 2.19 2.19 0 0 1 1.559.646zm4.078 3.03a.734.734 0 1 1-.733-.734.735.735 0 0 1 .733.733z"/></svg>`,
|
|
1594
|
-
tie: `<svg fill="#fff" viewBox="0 0 512.001 512.001"><g><g><path d="M120.988,239.868c-4.496,10.625-5.122,20.183-5.157,20.811c-0.267,4.607,3.243,8.547,7.849,8.829 c4.618,0.29,8.574-3.228,8.873-7.833c0.265-4.771,2.339-13.092,5.884-19.44C137.421,242.113,141.397,242.649,120.988,239.868z"/></g></g><g><g><path d="M391.178,255.418c-0.211,8.054-2.458,17.62-6.74,28.398c-1.708,4.299,0.393,9.168,4.692,10.875 c4.293,1.708,9.167-0.39,10.875-4.692c5.103-12.842,7.74-24.392,7.943-34.581H391.178z"/></g></g><g><g><path d="M164.769,210.51c1.046,3.339,1.397,6.953,0.893,10.65c-0.293,2.146-0.857,4.188-1.648,6.1c0,0,51.266,3.416,198.065,3.949 c-0.086-6.331,2.19-12.199,6.244-16.732C217.627,214.046,164.769,210.51,164.769,210.51z"/></g></g><g><g><circle cx="37.179" cy="128.669" r="29.491"/></g></g><g><g><path d="M510.146,391.511l-37.916-66.985c14.35-49.173,20.678-68.137,20.678-68.137l8.949-67.014 c1.502-10.977-6.248-21.075-17.235-22.468l-18.183-2.305c-10.984-1.393-20.996,6.445-22.293,17.431l-1.884,15.955l28.718-21.317 l-37.91,42.278h-46.432c-6.571,0-11.898,5.328-11.898,11.898c0,6.57,5.328,11.898,11.898,11.898h51.744 c3.381,0,6.601-1.438,8.859-3.956l41.456-46.234l-32.023,54.694c-5.28,9.018-14.374,8.169-18.293,8.167c-1.959,0-3.31,0-5.295,0 c-0.399,0.898,3.152-7.399-24.44,57.181c-0.548,1.284-0.907,2.642-1.06,4.031l-8.934,80.338 c-0.939,8.447,5.667,15.857,14.208,15.857c7.179,0,13.361-5.401,14.172-12.701l8.702-78.244l21.512-50.353l-14.121,50.463 c-1.158,3.756-0.718,7.823,1.218,11.243l40.949,72.345c3.885,6.864,12.596,9.276,19.459,5.392 C511.615,407.085,514.03,398.373,510.146,391.511z"/></g></g><g><g><circle cx="464.865" cy="128.702" r="29.491"/></g></g><g><g><path d="M142.923,206.051l-59.556-8.118l-39.135-18.451l13.626,2.292c-1.422-10.945-11.411-18.577-22.254-17.202l-18.182,2.305 C6.43,168.271-1.315,178.374,0.186,189.345l9.12,68.689l21.865,70.857l5.829,70.795c0.646,7.848,7.527,13.705,15.401,13.057 c7.859-0.647,13.705-7.542,13.058-15.401l-5.956-72.345c-0.084-1.031-0.281-2.05-0.585-3.039l-14.123-50.463l21.514,50.353 l8.702,78.244c0.873,7.86,7.96,13.486,15.768,12.612c7.838-0.871,13.483-7.931,12.612-15.768l-8.934-80.338 c-0.154-1.388-0.511-2.747-1.06-4.032l-27.336-61.43l-2.945-24.951l-29.029-25.179l40.79,19.231 c1.097,0.517,2.266,0.862,3.468,1.027l61.369,8.365c6.521,0.887,12.509-3.68,13.396-10.183 C153.994,212.936,149.435,206.939,142.923,206.051z"/></g></g></svg>`
|
|
1595
|
-
};
|
|
1596
|
-
const outcomeCounts = {
|
|
1597
|
-
victory: 0,
|
|
1598
|
-
stomp: 0,
|
|
1599
|
-
fail: 0,
|
|
1600
|
-
stomped: 0,
|
|
1601
|
-
tie: 0
|
|
1602
|
-
};
|
|
1603
|
-
const processLaneOutcome = /* @__PURE__ */ __name((outcome) => {
|
|
1604
|
-
switch (outcome) {
|
|
1605
|
-
case "RADIANT_VICTORY":
|
|
1606
|
-
return { radiant: "victory", dire: "fail" };
|
|
1607
|
-
case "RADIANT_STOMP":
|
|
1608
|
-
return { radiant: "stomp", dire: "stomped" };
|
|
1609
|
-
case "DIRE_VICTORY":
|
|
1610
|
-
return { radiant: "fail", dire: "victory" };
|
|
1611
|
-
case "DIRE_STOMP":
|
|
1612
|
-
return { radiant: "stomped", dire: "stomp" };
|
|
1613
|
-
default:
|
|
1614
|
-
return { radiant: "tie", dire: "tie" };
|
|
1615
|
-
}
|
|
1616
|
-
}, "processLaneOutcome");
|
|
1617
|
-
let nearMatchCount = 25, nearWinCount = 0, streak = 0;
|
|
1618
|
-
player.matches.forEach((match) => {
|
|
1619
|
-
const innerPlayer = match.players[0];
|
|
1620
|
-
nearWinCount += match.didRadiantWin == innerPlayer.isRadiant ? 1 : 0;
|
|
1621
|
-
const didWin = match.didRadiantWin === innerPlayer.isRadiant;
|
|
1622
|
-
if (!player.streak) {
|
|
1623
|
-
if (streak != 0) {
|
|
1624
|
-
if (didWin && streak > 0)
|
|
1625
|
-
streak++;
|
|
1626
|
-
else if (!didWin && streak < 0)
|
|
1627
|
-
streak--;
|
|
1628
|
-
else
|
|
1629
|
-
player.streak = streak;
|
|
1630
|
-
} else
|
|
1631
|
-
streak = didWin ? 1 : -1;
|
|
1632
|
-
}
|
|
1633
|
-
const laneResult = {
|
|
1634
|
-
top: processLaneOutcome(match.topLaneOutcome),
|
|
1635
|
-
mid: processLaneOutcome(match.midLaneOutcome),
|
|
1636
|
-
bottom: processLaneOutcome(match.bottomLaneOutcome)
|
|
1637
|
-
};
|
|
1638
|
-
let laneKey = "mid";
|
|
1639
|
-
if (innerPlayer.lane === "SAFE_LANE") {
|
|
1640
|
-
laneKey = innerPlayer.isRadiant ? "bottom" : "top";
|
|
1641
|
-
} else if (innerPlayer.lane === "OFF_LANE") {
|
|
1642
|
-
laneKey = innerPlayer.isRadiant ? "top" : "bottom";
|
|
1643
|
-
}
|
|
1644
|
-
match.laneResult = laneResult[laneKey][innerPlayer.isRadiant ? "radiant" : "dire"];
|
|
1645
|
-
if (match.laneResult in outcomeCounts) {
|
|
1646
|
-
outcomeCounts[match.laneResult]++;
|
|
1647
|
-
}
|
|
1648
|
-
});
|
|
1649
|
-
const playerHTML = `
|
|
1650
|
-
<div class="avatar"><img src="${player.steamAccount.avatar}" alt="" /></div>
|
|
1651
|
-
<div class="info">
|
|
1652
|
-
<p class="name">${player.steamAccount.name}${player.guildMember ? ` <span class="guild ${guildLevel(player.guildMember.guild.currentPercentile)}">[${player.guildMember.guild.tag}]</span></p>` : ""}
|
|
1653
|
-
<p class="matches"><span>场次:${player.matchCount}(<span class="win">${player.winCount}</span>/<span class="lose">${player.matchCount - player.winCount}</span>)</span>胜率:<span style="color:${winRateColor(
|
|
1654
|
-
player.winCount / player.matchCount
|
|
1655
|
-
)};">${(player.winCount / player.matchCount * 100).toFixed(2)}%</span></p>
|
|
1656
|
-
<p class="matches"><span>最近25场:<span class="win">${nearWinCount}</span>/<span class="lose">${nearMatchCount - nearWinCount}</span></span><span>胜率:<span style="color:${winRateColor(nearWinCount / nearMatchCount)};">${(nearWinCount / nearMatchCount * 100).toFixed(2)}%</span></span><span>评分:${player.performance.imp}</span></span></p>
|
|
1657
|
-
<p class="matches"><span>对线:<span class="victory">${outcomeCounts.victory + outcomeCounts.stomp}(<span class="stomp">${outcomeCounts.stomp}</span>)</span>-<span class="tie">${outcomeCounts.tie}</span>-<span class="fail">${outcomeCounts.fail + outcomeCounts.stomped}(<span class="stomped">${outcomeCounts.stomped}</span>)</span></span><span>线优:<span style="color:${winRateColor(
|
|
1658
|
-
(outcomeCounts.victory + outcomeCounts.stomp + outcomeCounts.tie / 2) / (outcomeCounts.victory + outcomeCounts.stomp + outcomeCounts.tie + outcomeCounts.fail + outcomeCounts.stomped)
|
|
1659
|
-
)};">${((outcomeCounts.victory + outcomeCounts.stomp) / (outcomeCounts.victory + outcomeCounts.stomp + outcomeCounts.fail + outcomeCounts.stomped) * 100).toFixed(2)}%</span></span></p>
|
|
1660
|
-
</div>
|
|
1661
|
-
<div class="rank">
|
|
1662
|
-
<img class="medal" src="${getImageUrl(
|
|
1663
|
-
"medal_" + ((player.steamAccount.seasonLeaderboardRank ? player.steamAccount.seasonLeaderboardRank <= 100 ? player.steamAccount.seasonLeaderboardRank <= 10 ? "8c" : "8b" : player.steamAccount.seasonRank?.toString().split("")[0] : player.steamAccount.seasonRank?.toString().split("")[0]) ?? "0")
|
|
1664
|
-
)}" alt="" />
|
|
1665
|
-
<img class="star" src="${getImageUrl("star_" + (player.steamAccount.seasonRank?.toString().split("")[1] ?? "0"))}" alt="" />
|
|
1666
|
-
<p>${player.steamAccount.seasonLeaderboardRank ?? ""}</p>
|
|
1667
|
-
</div>`;
|
|
1668
|
-
const heroesCountPixels = 800 - ($(".tip:not(.row):not(.win_count):not(.lose_count)").length + 1) * 40;
|
|
1669
|
-
const highestCountsTotal = {
|
|
1670
|
-
winCount: Math.max(...player.heroesPerformanceTop10.map((hero) => hero.winCount)),
|
|
1671
|
-
loseCount: Math.max(...player.heroesPerformanceTop10.map((hero) => hero.matchCount - hero.winCount))
|
|
1672
|
-
};
|
|
1673
|
-
const pixelOfPerMatchInTotal = heroesCountPixels / (highestCountsTotal.winCount + highestCountsTotal.loseCount);
|
|
1674
|
-
const highestCountsNear = {
|
|
1675
|
-
winCount: Math.max(...player.heroesPerformance?.filter((hero) => hero.matchCount > 1)?.map((hero) => hero.winCount)),
|
|
1676
|
-
loseCount: Math.max(...player.heroesPerformance?.filter((hero) => hero.matchCount > 1)?.map((hero) => hero.matchCount - hero.winCount))
|
|
1677
|
-
};
|
|
1678
|
-
const nearAdjustmentFactor = Math.min(highestCountsTotal.winCount / (highestCountsTotal.winCount + highestCountsTotal.loseCount), highestCountsTotal.loseCount / (highestCountsTotal.winCount + highestCountsTotal.loseCount));
|
|
1679
|
-
const pixelOfPerMatchInNear = heroesCountPixels / (highestCountsNear?.winCount + highestCountsNear?.loseCount) * nearAdjustmentFactor;
|
|
1680
|
-
const heroesTotalHTML = player.heroesPerformanceTop10.map(
|
|
1681
|
-
(hero) => `
|
|
1682
|
-
<span><img alt="" src="${getImageUrl(hero.hero.shortName, "heroes/icons" /* HeroIcons */)}" /></span>
|
|
1683
|
-
<span class="count">${hero.matchCount}</span>
|
|
1684
|
-
<span class="win_rate">${(hero.winCount / hero.matchCount * 100).toFixed(0)}%</span>
|
|
1685
|
-
<span class="imp">${(hero.imp > 0 ? "+" : "") + hero.imp}</span>
|
|
1686
|
-
<span class="win" style="${hero.winCount == 0 ? "visibility:hidden;" : ""}width: ${hero.winCount * pixelOfPerMatchInTotal}px">${hero.winCount}</span>
|
|
1687
|
-
<span class="lose" style="${hero.matchCount - hero.winCount == 0 ? "visibility:hidden;" : ""}width: ${(hero.matchCount - hero.winCount) * pixelOfPerMatchInTotal}px">${hero.matchCount - hero.winCount}</span>`
|
|
1688
|
-
).join("") + player.heroesPerformance.filter((hero) => hero.matchCount > 1).map(
|
|
1689
|
-
(hero, index) => `
|
|
1690
|
-
<span style="order:${index + 1};"><img alt="" src="${getImageUrl(hero.hero.shortName, "heroes/icons" /* HeroIcons */)}" /></span>
|
|
1691
|
-
<span style="order:${index + 1};" class="count">${hero.matchCount}</span>
|
|
1692
|
-
<span style="order:${index + 1};" class="win_rate">${(hero.winCount / hero.matchCount * 100).toFixed(0)}%</span>
|
|
1693
|
-
<span style="order:${index + 1};" class="imp">${(hero.imp > 0 ? "+" : "") + hero.imp}</span>
|
|
1694
|
-
<span class="win" style="order:${index + 1};${hero.winCount == 0 ? "visibility:hidden;" : ""}width: ${hero.winCount * pixelOfPerMatchInNear}px">${hero.winCount}</span>
|
|
1695
|
-
<span class="lose" style="order:${index + 1};${hero.matchCount - hero.winCount == 0 ? "visibility:hidden;" : ""}width: ${(hero.matchCount - hero.winCount) * pixelOfPerMatchInNear}px">${hero.matchCount - hero.winCount}</span>`
|
|
1696
|
-
).join("");
|
|
1697
|
-
const streakHTML = `<div class="streak" style="box-shadow:none;color:${winRateColor((player.streak + 10) / 20)};">${Math.abs(player.streak) + (player.streak > 0 ? "连胜" : "连败")}</div>`;
|
|
1698
|
-
const matchesHTML = player.matches.map(
|
|
1699
|
-
(match) => `
|
|
1700
|
-
<tr class="match ${match.didRadiantWin == match.players[0].isRadiant ? "win" : "lose"}">
|
|
1701
|
-
<td>${match.id}</td>
|
|
1702
|
-
<td>
|
|
1703
|
-
<p>${lobbyTypes[match.lobbyType] || match.lobbyType}</p>
|
|
1704
|
-
<p>${gameMode[match.gameMode] || match.gameMode}</p>
|
|
1705
|
-
</td>
|
|
1706
|
-
<td><img alt="" src="${getImageUrl(match.players[0].hero.shortName, "heroes/icons" /* HeroIcons */)}" /></td>
|
|
1707
|
-
<td style="line-height: 20px">
|
|
1708
|
-
<p>${((match.players[0].kills + match.players[0].assists) / Math.max(1, match.players[0].deaths)).toFixed(2)} (${((match.players[0].kills + match.players[0].assists) / (match.players[0].isRadiant ? match.radiantKills.reduce((acc, cva) => acc + cva, 0) : match.direKills.reduce((acc, cva) => acc + cva, 0)) * 100).toFixed(0)}%)</p>
|
|
1709
|
-
<p>${match.players[0].kills}/${match.players[0].deaths}/${match.players[0].assists}</p>
|
|
1710
|
-
</td>
|
|
1711
|
-
<td>
|
|
1712
|
-
<div class="player_lane ${match.laneResult}">${laneSVG[match.laneResult]}</div>
|
|
1713
|
-
</td>
|
|
1714
|
-
<td style="line-height: 20px">${(0, import_moment.default)(new Date(match.endDateTime * 1e3)).format("YYYY-MM-DD HH:mm:ss").slice(2)}</td>
|
|
1715
|
-
<td>${sec2time(match.durationSeconds)}</td>
|
|
1716
|
-
<td>${(match.players[0].imp > 0 ? "+" : "") + match.players[0].imp}</td>
|
|
1717
|
-
<td><img class="medal" src="${getImageUrl("medal_" + match.rank.toString().split("")[0])}" style="width: 100%" /></td>
|
|
1718
|
-
</tr>`
|
|
1719
|
-
).join("");
|
|
1720
|
-
const dotaPlusHTML = player.dotaPlus.map(
|
|
1721
|
-
(hero) => `
|
|
1722
|
-
<div class="hero">
|
|
1723
|
-
<img src="${getImageUrl(hero.shortName, "heroes" /* Heroes */)}" alt="" />
|
|
1724
|
-
<div class="level"><img src="${getImageUrl("hero_badge_" + Math.ceil((hero.level + 1) / 6))}" alt="" /><span>${hero.level}</span></div>
|
|
1725
|
-
<span>${(hero.winCount / hero.matchCount * 100).toFixed(2)}%</span>
|
|
1726
|
-
<span>${hero.matchCount}</span>
|
|
1727
|
-
</div>`
|
|
1728
|
-
).join("");
|
|
1729
|
-
$(".player").html(playerHTML);
|
|
1730
|
-
$(".heroes > span:not(.tip)").remove();
|
|
1731
|
-
$(".heroes .tip.near").before(heroesTotalHTML);
|
|
1732
|
-
if (player.streak > 1 || player.streak < -1)
|
|
1733
|
-
$(".streak").replaceWith(streakHTML);
|
|
1734
|
-
$(".matches tbody").html(matchesHTML);
|
|
1735
|
-
$(".plus").html(dotaPlusHTML);
|
|
1736
|
-
if (process.env.NODE_ENV === "development")
|
|
1737
|
-
import_fs2.default.writeFileSync("./node_modules/@sjtdev/koishi-plugin-dota2tracker/temp.html", $.html());
|
|
1738
|
-
return $.html();
|
|
1739
|
-
}
|
|
1740
|
-
__name(genPlayerHTML, "genPlayerHTML");
|
|
1741
|
-
async function playerIsInvalid(steamAccountId) {
|
|
1742
|
-
try {
|
|
1743
|
-
let queryRes = await query(VERIFYING_PLAYER(steamAccountId));
|
|
1744
|
-
if (queryRes.status == 200) {
|
|
1745
|
-
if (queryRes.data.data.player.matchCount != null)
|
|
1746
|
-
return { isInvalid: true };
|
|
1747
|
-
else
|
|
1748
|
-
return { isInvalid: false, reason: "SteamID无效或无任何场次。" };
|
|
1749
|
-
}
|
|
1750
|
-
} catch (error) {
|
|
1751
|
-
console.error(error);
|
|
1752
|
-
return { isInvalid: false, reason: "网络状况不佳SteamID验证失败,请稍后重试。" };
|
|
1753
|
-
}
|
|
1754
|
-
}
|
|
1755
|
-
__name(playerIsInvalid, "playerIsInvalid");
|
|
1756
|
-
function sec2time(sec) {
|
|
1757
|
-
return sec ? (sec < 0 ? "-" : "") + Math.floor(Math.abs(sec) / 60) + ":" + ("00" + Math.abs(sec) % 60).slice(-2) : "--:--";
|
|
1758
|
-
}
|
|
1759
|
-
__name(sec2time, "sec2time");
|
|
1760
|
-
function winRateColor(value) {
|
|
1761
|
-
value = value * 100;
|
|
1762
|
-
value = Math.max(0, Math.min(100, value));
|
|
1763
|
-
let red, green, blue;
|
|
1764
|
-
if (value <= 50) {
|
|
1765
|
-
let scale = Math.round(255 * (value / 50));
|
|
1766
|
-
red = 255;
|
|
1767
|
-
green = scale;
|
|
1768
|
-
blue = scale;
|
|
1769
|
-
} else {
|
|
1770
|
-
let scale = Math.round(255 * ((value - 50) / 50));
|
|
1771
|
-
red = 255 - scale;
|
|
1772
|
-
green = 255;
|
|
1773
|
-
blue = 255 - scale;
|
|
1774
|
-
}
|
|
1775
|
-
const toHex = /* @__PURE__ */ __name((color) => color.toString(16).padStart(2, "0").toUpperCase(), "toHex");
|
|
1776
|
-
return `#${toHex(red)}${toHex(green)}${toHex(blue)}`;
|
|
1777
|
-
}
|
|
1778
|
-
__name(winRateColor, "winRateColor");
|
|
1779
|
-
function formatNumber(num) {
|
|
1780
|
-
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
1781
|
-
}
|
|
1782
|
-
__name(formatNumber, "formatNumber");
|
|
1783
|
-
function readDirectoryFilesSync(directoryPath) {
|
|
1784
|
-
try {
|
|
1785
|
-
const files = import_fs2.default.readdirSync(directoryPath);
|
|
1786
|
-
const fileNames = files.map((file) => import_path.default.basename(file, import_path.default.extname(file)));
|
|
1787
|
-
return fileNames;
|
|
1788
|
-
} catch (error) {
|
|
1789
|
-
console.error("Error reading directory:", error);
|
|
1790
|
-
return [];
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1793
|
-
__name(readDirectoryFilesSync, "readDirectoryFilesSync");
|
|
1546
|
+
__name(genImageHTML, "genImageHTML");
|
|
1794
1547
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1795
1548
|
0 && (module.exports = {
|
|
1796
1549
|
Config,
|