@sjtdev/koishi-plugin-dota2tracker 1.2.19 → 1.2.20-pre.2
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 +79 -531
- package/package.json +3 -2
- package/queries/AllAbilitiesChineseName.graphql +14 -0
- package/queries/CurrentGameversion.graphql +8 -0
- package/queries/HeroInfo.graphql +53 -0
- package/queries/HeroMatchupWinrate.graphql +25 -0
- package/queries/MatchInfo.graphql +135 -0
- package/queries/PlayerExtraInfo.graphql +17 -0
- package/queries/PlayerInfoWith25Matches.graphql +62 -0
- package/queries/PlayersInfoWith10MatchesForGuild.graphql +27 -0
- package/queries/PlayersLastmatchRankinfo.graphql +21 -0
- package/queries/PlayersMatchesForDaily.graphql +25 -0
- package/queries/RequestMatchDataAnalysis.graphql +5 -0
- package/queries/VerifyingPlayer.graphql +5 -0
- package/readme.md +0 -5
package/lib/index.js
CHANGED
|
@@ -60,474 +60,8 @@ __export(utils_exports, {
|
|
|
60
60
|
winRateColor: () => winRateColor
|
|
61
61
|
});
|
|
62
62
|
var import_fs = __toESM(require("fs"));
|
|
63
|
-
var dotaconstants2 = __toESM(require("dotaconstants"));
|
|
64
|
-
var import_path = __toESM(require("path"));
|
|
65
|
-
|
|
66
|
-
// src/queries.ts
|
|
67
|
-
var queries_exports = {};
|
|
68
|
-
__export(queries_exports, {
|
|
69
|
-
ALL_ABILITIES_CHINESE_NAME: () => ALL_ABILITIES_CHINESE_NAME,
|
|
70
|
-
CURRENT_GAMEVERSION: () => CURRENT_GAMEVERSION,
|
|
71
|
-
HERO_INFO: () => HERO_INFO,
|
|
72
|
-
HERO_MATCHUP_WINRATE: () => HERO_MATCHUP_WINRATE,
|
|
73
|
-
MATCH_INFO: () => MATCH_INFO,
|
|
74
|
-
PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD: () => PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD,
|
|
75
|
-
PLAYERS_LASTMATCH_RANKINFO: () => PLAYERS_LASTMATCH_RANKINFO,
|
|
76
|
-
PLAYERS_MATCHES_FOR_DAILY: () => PLAYERS_MATCHES_FOR_DAILY,
|
|
77
|
-
PLAYER_EXTRA_INFO: () => PLAYER_EXTRA_INFO,
|
|
78
|
-
PLAYER_INFO_WITH_25_MATCHES: () => PLAYER_INFO_WITH_25_MATCHES,
|
|
79
|
-
REQUEST_MATCH_DATA_ANALYSIS: () => REQUEST_MATCH_DATA_ANALYSIS,
|
|
80
|
-
VERIFYING_PLAYER: () => VERIFYING_PLAYER
|
|
81
|
-
});
|
|
82
63
|
var dotaconstants = __toESM(require("dotaconstants"));
|
|
83
|
-
|
|
84
|
-
return `
|
|
85
|
-
{
|
|
86
|
-
match(id: ${matchId}) {
|
|
87
|
-
id
|
|
88
|
-
didRadiantWin
|
|
89
|
-
lobbyType
|
|
90
|
-
gameMode
|
|
91
|
-
regionId
|
|
92
|
-
parsedDateTime
|
|
93
|
-
startDateTime
|
|
94
|
-
endDateTime
|
|
95
|
-
actualRank
|
|
96
|
-
rank
|
|
97
|
-
averageRank
|
|
98
|
-
durationSeconds
|
|
99
|
-
topLaneOutcome
|
|
100
|
-
midLaneOutcome
|
|
101
|
-
bottomLaneOutcome
|
|
102
|
-
radiantKills
|
|
103
|
-
direKills
|
|
104
|
-
players {
|
|
105
|
-
steamAccountId
|
|
106
|
-
steamAccount {
|
|
107
|
-
name
|
|
108
|
-
}
|
|
109
|
-
level
|
|
110
|
-
hero {
|
|
111
|
-
id
|
|
112
|
-
name
|
|
113
|
-
shortName
|
|
114
|
-
facets {
|
|
115
|
-
facetId
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
variant
|
|
119
|
-
dotaPlus {
|
|
120
|
-
level
|
|
121
|
-
}
|
|
122
|
-
leaverStatus
|
|
123
|
-
partyId
|
|
124
|
-
position
|
|
125
|
-
playerSlot
|
|
126
|
-
lane
|
|
127
|
-
imp
|
|
128
|
-
kills
|
|
129
|
-
deaths
|
|
130
|
-
assists
|
|
131
|
-
isRadiant
|
|
132
|
-
networth
|
|
133
|
-
steamAccount {
|
|
134
|
-
seasonRank
|
|
135
|
-
seasonLeaderboardRank
|
|
136
|
-
}
|
|
137
|
-
item0Id
|
|
138
|
-
item1Id
|
|
139
|
-
item2Id
|
|
140
|
-
item3Id
|
|
141
|
-
item4Id
|
|
142
|
-
item5Id
|
|
143
|
-
backpack0Id
|
|
144
|
-
backpack1Id
|
|
145
|
-
backpack2Id
|
|
146
|
-
neutral0Id
|
|
147
|
-
stats {
|
|
148
|
-
matchPlayerBuffEvent {
|
|
149
|
-
abilityId
|
|
150
|
-
itemId
|
|
151
|
-
stackCount
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
heroDamage
|
|
155
|
-
towerDamage
|
|
156
|
-
stats {
|
|
157
|
-
heroDamageReport {
|
|
158
|
-
receivedTotal {
|
|
159
|
-
physicalDamage
|
|
160
|
-
magicalDamage
|
|
161
|
-
pureDamage
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
numLastHits
|
|
166
|
-
numDenies
|
|
167
|
-
goldPerMinute
|
|
168
|
-
experiencePerMinute
|
|
169
|
-
heroHealing
|
|
170
|
-
stats {
|
|
171
|
-
itemPurchases{
|
|
172
|
-
itemId
|
|
173
|
-
time
|
|
174
|
-
}
|
|
175
|
-
campStack
|
|
176
|
-
heroDamageReport {
|
|
177
|
-
dealtTotal {
|
|
178
|
-
stunDuration
|
|
179
|
-
stunCount
|
|
180
|
-
slowDuration
|
|
181
|
-
slowCount
|
|
182
|
-
disableDuration
|
|
183
|
-
disableCount
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
additionalUnit {
|
|
188
|
-
item0Id
|
|
189
|
-
item1Id
|
|
190
|
-
item2Id
|
|
191
|
-
item3Id
|
|
192
|
-
item4Id
|
|
193
|
-
item5Id
|
|
194
|
-
backpack0Id
|
|
195
|
-
backpack1Id
|
|
196
|
-
backpack2Id
|
|
197
|
-
neutral0Id
|
|
198
|
-
}
|
|
199
|
-
isRandom
|
|
200
|
-
}
|
|
201
|
-
pickBans {
|
|
202
|
-
isPick
|
|
203
|
-
bannedHeroId
|
|
204
|
-
heroId
|
|
205
|
-
order
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
constants {
|
|
209
|
-
facets (language: S_CHINESE) {
|
|
210
|
-
name
|
|
211
|
-
id
|
|
212
|
-
color
|
|
213
|
-
icon
|
|
214
|
-
language {
|
|
215
|
-
displayName
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
`;
|
|
222
|
-
}
|
|
223
|
-
__name(MATCH_INFO, "MATCH_INFO");
|
|
224
|
-
function PLAYERS_MATCHES_FOR_DAILY(steamAccountIds, seconds) {
|
|
225
|
-
return `
|
|
226
|
-
{
|
|
227
|
-
players(steamAccountIds:[${steamAccountIds.join(",")}]) {
|
|
228
|
-
steamAccount{id name avatar}
|
|
229
|
-
matches(request:{startDateTime:${seconds} take:50}){
|
|
230
|
-
id
|
|
231
|
-
didRadiantWin
|
|
232
|
-
parsedDateTime
|
|
233
|
-
startDateTime
|
|
234
|
-
players {
|
|
235
|
-
kills
|
|
236
|
-
deaths
|
|
237
|
-
assists
|
|
238
|
-
imp
|
|
239
|
-
isRadiant
|
|
240
|
-
steamAccount {
|
|
241
|
-
id
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
`;
|
|
248
|
-
}
|
|
249
|
-
__name(PLAYERS_MATCHES_FOR_DAILY, "PLAYERS_MATCHES_FOR_DAILY");
|
|
250
|
-
function VERIFYING_PLAYER(steamAccountId) {
|
|
251
|
-
return `
|
|
252
|
-
{
|
|
253
|
-
player(steamAccountId: ${steamAccountId}) {
|
|
254
|
-
matchCount
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
`;
|
|
259
|
-
}
|
|
260
|
-
__name(VERIFYING_PLAYER, "VERIFYING_PLAYER");
|
|
261
|
-
function PLAYERS_LASTMATCH_RANKINFO(steamAccountIds) {
|
|
262
|
-
return `
|
|
263
|
-
{
|
|
264
|
-
players(steamAccountIds:[${steamAccountIds.join(",")}]) {
|
|
265
|
-
steamAccount{
|
|
266
|
-
id
|
|
267
|
-
name
|
|
268
|
-
avatar
|
|
269
|
-
seasonRank
|
|
270
|
-
seasonLeaderboardRank
|
|
271
|
-
}
|
|
272
|
-
matches(request:{take:1}){
|
|
273
|
-
id
|
|
274
|
-
parsedDateTime
|
|
275
|
-
startDateTime
|
|
276
|
-
players{
|
|
277
|
-
steamAccount{
|
|
278
|
-
id
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
`;
|
|
286
|
-
}
|
|
287
|
-
__name(PLAYERS_LASTMATCH_RANKINFO, "PLAYERS_LASTMATCH_RANKINFO");
|
|
288
|
-
function PLAYER_INFO_WITH_25_MATCHES(steamAccountId, heroId) {
|
|
289
|
-
return `
|
|
290
|
-
{
|
|
291
|
-
player(steamAccountId: ${steamAccountId}) {
|
|
292
|
-
steamAccount {
|
|
293
|
-
avatar
|
|
294
|
-
name
|
|
295
|
-
seasonRank
|
|
296
|
-
seasonLeaderboardRank
|
|
297
|
-
id
|
|
298
|
-
}
|
|
299
|
-
guildMember {
|
|
300
|
-
guild {
|
|
301
|
-
tag
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
matchCount
|
|
305
|
-
winCount
|
|
306
|
-
performance {
|
|
307
|
-
imp
|
|
308
|
-
}
|
|
309
|
-
heroesPerformance(take: 25, request: {matchGroupOrderBy: WIN_COUNT take: 25 ${heroId ? "heroIds:" + heroId : ""}}) {
|
|
310
|
-
hero {
|
|
311
|
-
id
|
|
312
|
-
shortName
|
|
313
|
-
}
|
|
314
|
-
imp
|
|
315
|
-
winCount
|
|
316
|
-
matchCount
|
|
317
|
-
}
|
|
318
|
-
matches(request: {take: 25 ${heroId ? "heroIds:" + heroId : ""}}) {
|
|
319
|
-
id
|
|
320
|
-
rank
|
|
321
|
-
lobbyType
|
|
322
|
-
gameMode
|
|
323
|
-
startDateTime
|
|
324
|
-
parsedDateTime
|
|
325
|
-
durationSeconds
|
|
326
|
-
didRadiantWin
|
|
327
|
-
topLaneOutcome
|
|
328
|
-
midLaneOutcome
|
|
329
|
-
bottomLaneOutcome
|
|
330
|
-
radiantKills
|
|
331
|
-
direKills
|
|
332
|
-
players {
|
|
333
|
-
steamAccount {
|
|
334
|
-
id
|
|
335
|
-
}
|
|
336
|
-
isRadiant
|
|
337
|
-
lane
|
|
338
|
-
kills
|
|
339
|
-
deaths
|
|
340
|
-
assists
|
|
341
|
-
position
|
|
342
|
-
award
|
|
343
|
-
imp
|
|
344
|
-
hero {
|
|
345
|
-
id
|
|
346
|
-
shortName
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
`;
|
|
355
|
-
}
|
|
356
|
-
__name(PLAYER_INFO_WITH_25_MATCHES, "PLAYER_INFO_WITH_25_MATCHES");
|
|
357
|
-
function PLAYER_EXTRA_INFO(steamAccountId, matchCount, totalHeroCount, heroId) {
|
|
358
|
-
return `{
|
|
359
|
-
player(steamAccountId: ${steamAccountId}) {
|
|
360
|
-
heroesPerformance(take: ${totalHeroCount}, request: {matchGroupOrderBy: MATCH_COUNT, take: ${matchCount} ${heroId ? "heroIds:" + heroId : ""}}) {
|
|
361
|
-
hero {
|
|
362
|
-
id
|
|
363
|
-
shortName
|
|
364
|
-
}
|
|
365
|
-
winCount
|
|
366
|
-
matchCount
|
|
367
|
-
imp
|
|
368
|
-
}
|
|
369
|
-
dotaPlus {
|
|
370
|
-
heroId
|
|
371
|
-
level
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
`;
|
|
376
|
-
}
|
|
377
|
-
__name(PLAYER_EXTRA_INFO, "PLAYER_EXTRA_INFO");
|
|
378
|
-
function PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD(steamAccountIds) {
|
|
379
|
-
return `{
|
|
380
|
-
players(steamAccountIds: [${steamAccountIds.join()}]) {
|
|
381
|
-
steamAccount {
|
|
382
|
-
id
|
|
383
|
-
avatar
|
|
384
|
-
name
|
|
385
|
-
seasonRank
|
|
386
|
-
}
|
|
387
|
-
matches(request: {take: 10}) {
|
|
388
|
-
didRadiantWin
|
|
389
|
-
startDateTime
|
|
390
|
-
players {
|
|
391
|
-
isRadiant
|
|
392
|
-
kills
|
|
393
|
-
deaths
|
|
394
|
-
assists
|
|
395
|
-
steamAccount {
|
|
396
|
-
id
|
|
397
|
-
}
|
|
398
|
-
hero {
|
|
399
|
-
shortName
|
|
400
|
-
}
|
|
401
|
-
imp
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
`;
|
|
407
|
-
}
|
|
408
|
-
__name(PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD, "PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD");
|
|
409
|
-
function CURRENT_GAMEVERSION() {
|
|
410
|
-
return `
|
|
411
|
-
{
|
|
412
|
-
constants {
|
|
413
|
-
gameVersions{name id}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
`;
|
|
418
|
-
}
|
|
419
|
-
__name(CURRENT_GAMEVERSION, "CURRENT_GAMEVERSION");
|
|
420
|
-
function ALL_ABILITIES_CHINESE_NAME() {
|
|
421
|
-
return `
|
|
422
|
-
{
|
|
423
|
-
constants {
|
|
424
|
-
abilities(language:S_CHINESE){
|
|
425
|
-
id
|
|
426
|
-
language{displayName}
|
|
427
|
-
}
|
|
428
|
-
gameVersions{name id}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
`;
|
|
433
|
-
}
|
|
434
|
-
__name(ALL_ABILITIES_CHINESE_NAME, "ALL_ABILITIES_CHINESE_NAME");
|
|
435
|
-
function HERO_INFO(heroId) {
|
|
436
|
-
return `
|
|
437
|
-
{
|
|
438
|
-
constants {
|
|
439
|
-
hero(id: ${heroId}, language: S_CHINESE) {
|
|
440
|
-
id
|
|
441
|
-
name
|
|
442
|
-
shortName
|
|
443
|
-
aliases
|
|
444
|
-
roles {
|
|
445
|
-
roleId
|
|
446
|
-
level
|
|
447
|
-
}
|
|
448
|
-
language {
|
|
449
|
-
displayName
|
|
450
|
-
lore
|
|
451
|
-
hype
|
|
452
|
-
}
|
|
453
|
-
abilities {
|
|
454
|
-
ability(language: S_CHINESE) {
|
|
455
|
-
name
|
|
456
|
-
language {
|
|
457
|
-
displayName
|
|
458
|
-
description
|
|
459
|
-
attributes
|
|
460
|
-
lore
|
|
461
|
-
aghanimDescription
|
|
462
|
-
shardDescription
|
|
463
|
-
notes
|
|
464
|
-
}
|
|
465
|
-
stat {
|
|
466
|
-
type
|
|
467
|
-
behavior
|
|
468
|
-
unitTargetType
|
|
469
|
-
unitTargetTeam
|
|
470
|
-
unitTargetFlags
|
|
471
|
-
unitDamageType
|
|
472
|
-
cooldown
|
|
473
|
-
manaCost
|
|
474
|
-
spellImmunity
|
|
475
|
-
isOnCastbar
|
|
476
|
-
isGrantedByShard
|
|
477
|
-
isGrantedByScepter
|
|
478
|
-
hasShardUpgrade
|
|
479
|
-
hasScepterUpgrade
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
talents {
|
|
484
|
-
abilityId
|
|
485
|
-
slot
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
`;
|
|
492
|
-
}
|
|
493
|
-
__name(HERO_INFO, "HERO_INFO");
|
|
494
|
-
function HERO_MATCHUP_WINRATE(heroId) {
|
|
495
|
-
return `
|
|
496
|
-
{
|
|
497
|
-
heroStats {
|
|
498
|
-
matchUp(heroId: ${heroId}, take: ${Object.keys(dotaconstants.heroes).length - 1},bracketBasicIds:LEGEND_ANCIENT) {
|
|
499
|
-
heroId
|
|
500
|
-
matchCountWith
|
|
501
|
-
matchCountVs
|
|
502
|
-
with {
|
|
503
|
-
heroId1
|
|
504
|
-
winRateHeroId1
|
|
505
|
-
heroId2
|
|
506
|
-
winRateHeroId2
|
|
507
|
-
winCount
|
|
508
|
-
matchCount
|
|
509
|
-
}
|
|
510
|
-
vs {
|
|
511
|
-
heroId1
|
|
512
|
-
winRateHeroId1
|
|
513
|
-
heroId2
|
|
514
|
-
winRateHeroId2
|
|
515
|
-
winCount
|
|
516
|
-
matchCount
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
`;
|
|
523
|
-
}
|
|
524
|
-
__name(HERO_MATCHUP_WINRATE, "HERO_MATCHUP_WINRATE");
|
|
525
|
-
function REQUEST_MATCH_DATA_ANALYSIS(matchId) {
|
|
526
|
-
return `stratz{matchRetry(id:${matchId})}`;
|
|
527
|
-
}
|
|
528
|
-
__name(REQUEST_MATCH_DATA_ANALYSIS, "REQUEST_MATCH_DATA_ANALYSIS");
|
|
529
|
-
|
|
530
|
-
// src/utils.ts
|
|
64
|
+
var import_path = __toESM(require("path"));
|
|
531
65
|
var CONFIGS = { STRATZ_API: { URL: "https://api.stratz.com/graphql", TOKEN: "" } };
|
|
532
66
|
var http = null;
|
|
533
67
|
var setTimeout;
|
|
@@ -536,40 +70,46 @@ function init(newHttp, newSetTimeout) {
|
|
|
536
70
|
setTimeout = newSetTimeout;
|
|
537
71
|
}
|
|
538
72
|
__name(init, "init");
|
|
539
|
-
async function fetchData(
|
|
540
|
-
return await http.post(CONFIGS.STRATZ_API.URL,
|
|
73
|
+
async function fetchData(query2) {
|
|
74
|
+
return await http.post(CONFIGS.STRATZ_API.URL, JSON.stringify(query2), {
|
|
541
75
|
responseType: "json",
|
|
542
76
|
headers: {
|
|
543
77
|
"User-Agent": "STRATZ_API",
|
|
544
|
-
"Content-Type": "application/
|
|
78
|
+
"Content-Type": "application/json",
|
|
545
79
|
Authorization: `Bearer ${CONFIGS.STRATZ_API.TOKEN}`
|
|
546
80
|
}
|
|
547
81
|
});
|
|
548
82
|
}
|
|
549
83
|
__name(fetchData, "fetchData");
|
|
550
|
-
async function query(
|
|
551
|
-
if (
|
|
552
|
-
const playerIds =
|
|
84
|
+
async function query(queryName, variables) {
|
|
85
|
+
if (queryName.startsWith("Players") && variables?.steamAccountIds.length > 5) {
|
|
86
|
+
const playerIds = variables?.steamAccountIds ?? [];
|
|
553
87
|
const chunkSize = 5;
|
|
554
88
|
let allPlayers = [];
|
|
555
89
|
for (let i = 0; i < playerIds.length; i += chunkSize) {
|
|
556
90
|
const chunk = playerIds.slice(i, i + chunkSize);
|
|
557
|
-
|
|
558
|
-
const
|
|
559
|
-
|
|
91
|
+
variables.steamAccountIds = chunk;
|
|
92
|
+
const query_str = loadGraphqlFile(queryName);
|
|
93
|
+
const result = await new Promise((resolve) => setTimeout(async () => resolve(await fetchData({ query: query_str, variables })), 200));
|
|
94
|
+
if (result?.errors) throw { errors: result.errors };
|
|
560
95
|
if (result.data && result.data.players) {
|
|
561
96
|
allPlayers = allPlayers.concat(result.data.players);
|
|
562
97
|
}
|
|
563
98
|
}
|
|
564
|
-
return {
|
|
99
|
+
return { players: allPlayers };
|
|
565
100
|
} else {
|
|
566
|
-
const query_str =
|
|
567
|
-
const result = await fetchData(query_str);
|
|
101
|
+
const query_str = loadGraphqlFile(queryName);
|
|
102
|
+
const result = await fetchData({ query: query_str, variables });
|
|
568
103
|
if (result.errors) throw { errors: result.errors };
|
|
569
|
-
return result
|
|
104
|
+
return result.data;
|
|
570
105
|
}
|
|
571
106
|
}
|
|
572
107
|
__name(query, "query");
|
|
108
|
+
function loadGraphqlFile(queryName) {
|
|
109
|
+
const filepath = `./node_modules/@sjtdev/koishi-plugin-dota2tracker/queries/${queryName}.graphql`;
|
|
110
|
+
return import_fs.default.readFileSync(filepath, { encoding: "utf-8" }).replace(/[\r\n]+/g, " ");
|
|
111
|
+
}
|
|
112
|
+
__name(loadGraphqlFile, "loadGraphqlFile");
|
|
573
113
|
async function queryHeroFromValve(heroId) {
|
|
574
114
|
return (await http.get(`https://www.dota2.com/datafeed/herodata?language=schinese&hero_id=${heroId}`)).result.data.heroes[0];
|
|
575
115
|
}
|
|
@@ -611,7 +151,8 @@ function getImageUrl(image, type = "local" /* Local */, format = "png" /* png */
|
|
|
611
151
|
}
|
|
612
152
|
__name(getImageUrl, "getImageUrl");
|
|
613
153
|
function getFormattedMatchData(data) {
|
|
614
|
-
const
|
|
154
|
+
const match = data.match;
|
|
155
|
+
const constants = data.constants;
|
|
615
156
|
["radiant", "dire"].forEach((team) => {
|
|
616
157
|
match[team] = { killsCount: match[team + "Kills"]?.reduce((acc, cva) => acc + cva, 0) ?? 0, damageReceived: 0, heroDamage: 0, networth: 0, experience: 0 };
|
|
617
158
|
});
|
|
@@ -680,7 +221,10 @@ function getFormattedMatchData(data) {
|
|
|
680
221
|
}
|
|
681
222
|
return acc;
|
|
682
223
|
}, {});
|
|
683
|
-
player.
|
|
224
|
+
player.buffs = Object.entries(maxStackCountsByAbilityOrItem).map(([key, event]) => ({
|
|
225
|
+
key,
|
|
226
|
+
event
|
|
227
|
+
}));
|
|
684
228
|
}
|
|
685
229
|
switch (player.lane) {
|
|
686
230
|
case "SAFE_LANE":
|
|
@@ -741,8 +285,8 @@ function getFormattedMatchData(data) {
|
|
|
741
285
|
const itemId = player[key];
|
|
742
286
|
if (itemId === void 0 || itemId === null) {
|
|
743
287
|
player.items.push(null);
|
|
744
|
-
} else if (
|
|
745
|
-
const name2 =
|
|
288
|
+
} else if (dotaconstants.item_ids[itemId]) {
|
|
289
|
+
const name2 = dotaconstants.item_ids[itemId];
|
|
746
290
|
const isRecipe = name2.startsWith(prefix);
|
|
747
291
|
const cleanName = isRecipe ? name2.substring(prefix.length) : name2;
|
|
748
292
|
player.items.push({
|
|
@@ -760,8 +304,8 @@ function getFormattedMatchData(data) {
|
|
|
760
304
|
const itemId = player[key];
|
|
761
305
|
if (itemId === void 0 || itemId === null) {
|
|
762
306
|
player.backpacks.push(null);
|
|
763
|
-
} else if (
|
|
764
|
-
const name2 =
|
|
307
|
+
} else if (dotaconstants.item_ids[itemId]) {
|
|
308
|
+
const name2 = dotaconstants.item_ids[itemId];
|
|
765
309
|
const isRecipe = name2.startsWith(prefix);
|
|
766
310
|
const cleanName = isRecipe ? name2.substring(prefix.length) : name2;
|
|
767
311
|
player.backpacks.push({
|
|
@@ -783,8 +327,8 @@ function getFormattedMatchData(data) {
|
|
|
783
327
|
const itemId = player.additionalUnit[key];
|
|
784
328
|
if (itemId === void 0 || itemId === null) {
|
|
785
329
|
player.unitItems.push(null);
|
|
786
|
-
} else if (
|
|
787
|
-
const name2 =
|
|
330
|
+
} else if (dotaconstants.item_ids[itemId]) {
|
|
331
|
+
const name2 = dotaconstants.item_ids[itemId];
|
|
788
332
|
const isRecipe = name2.startsWith(prefix2);
|
|
789
333
|
const cleanName = isRecipe ? name2.substring(prefix2.length) : name2;
|
|
790
334
|
player.unitItems.push({
|
|
@@ -802,8 +346,8 @@ function getFormattedMatchData(data) {
|
|
|
802
346
|
const itemId = player.additionalUnit[key];
|
|
803
347
|
if (itemId === void 0 || itemId === null) {
|
|
804
348
|
player.unitBackpacks.push(null);
|
|
805
|
-
} else if (
|
|
806
|
-
const name2 =
|
|
349
|
+
} else if (dotaconstants.item_ids[itemId]) {
|
|
350
|
+
const name2 = dotaconstants.item_ids[itemId];
|
|
807
351
|
const isRecipe = name2.startsWith(prefix2);
|
|
808
352
|
const cleanName = isRecipe ? name2.substring(prefix2.length) : name2;
|
|
809
353
|
player.unitBackpacks.push({
|
|
@@ -926,7 +470,7 @@ function winRateColor(value) {
|
|
|
926
470
|
__name(winRateColor, "winRateColor");
|
|
927
471
|
async function playerisValid(steamAccountId) {
|
|
928
472
|
try {
|
|
929
|
-
let queryRes = await query(
|
|
473
|
+
let queryRes = await query("VerifyingPlayer", { steamAccountId });
|
|
930
474
|
if (queryRes.data.player.matchCount != null) return { isValid: true };
|
|
931
475
|
else return { isValid: false, reason: "SteamID无效或无任何场次。" };
|
|
932
476
|
} catch (error) {
|
|
@@ -979,7 +523,7 @@ __name(formatHeroDesc, "formatHeroDesc");
|
|
|
979
523
|
var import_fs2 = __toESM(require("fs"));
|
|
980
524
|
var import_path2 = __toESM(require("path"));
|
|
981
525
|
var import_moment = __toESM(require("moment"));
|
|
982
|
-
var
|
|
526
|
+
var dotaconstants2 = __toESM(require("dotaconstants"));
|
|
983
527
|
|
|
984
528
|
// src/dotaconstants_add.json
|
|
985
529
|
var dotaconstants_add_exports = {};
|
|
@@ -1418,10 +962,10 @@ async function apply(ctx, config) {
|
|
|
1418
962
|
memberList = await session.bot?.getGuildMemberList(session.event.channel.id);
|
|
1419
963
|
} catch (error) {
|
|
1420
964
|
}
|
|
1421
|
-
async function getUsers(subscribedPlayers2,
|
|
1422
|
-
const playerSteamIds = subscribedPlayers2.map((player) => player.steamId);
|
|
1423
|
-
const queryResult = await
|
|
1424
|
-
const playersInfo = queryResult.
|
|
965
|
+
async function getUsers(subscribedPlayers2, memberList2) {
|
|
966
|
+
const playerSteamIds = { steamAccountIds: subscribedPlayers2.map((player) => player.steamId) };
|
|
967
|
+
const queryResult = await query("PlayersInfoWith10MatchesForGuild", { steamAccountIds: playerSteamIds });
|
|
968
|
+
const playersInfo = queryResult.players;
|
|
1425
969
|
const users2 = [];
|
|
1426
970
|
for (const subscribedPlayer of subscribedPlayers2) {
|
|
1427
971
|
const queryPlayer = playersInfo.find((player) => player.steamAccount.id == subscribedPlayer.steamId);
|
|
@@ -1431,7 +975,7 @@ async function apply(ctx, config) {
|
|
|
1431
975
|
return users2;
|
|
1432
976
|
}
|
|
1433
977
|
__name(getUsers, "getUsers");
|
|
1434
|
-
const users = await getUsers(subscribedPlayers,
|
|
978
|
+
const users = await getUsers(subscribedPlayers, memberList);
|
|
1435
979
|
session.send(await ctx.puppeteer.render(genImageHTML(users, "guild_member" /* GuildMember */, "guild_member" /* GuildMember */)));
|
|
1436
980
|
} catch (error) {
|
|
1437
981
|
ctx.logger.error(error);
|
|
@@ -1442,18 +986,17 @@ async function apply(ctx, config) {
|
|
|
1442
986
|
});
|
|
1443
987
|
async function queryMatchAndSend(session, matchId) {
|
|
1444
988
|
try {
|
|
1445
|
-
let
|
|
989
|
+
let matchQuery;
|
|
1446
990
|
let queryLocal = await ctx.database.get("dt_previous_query_results", matchId, ["data"]);
|
|
1447
991
|
if (queryLocal.length > 0) {
|
|
1448
|
-
|
|
1449
|
-
ctx.database.set("dt_previous_query_results", match.id, { queryTime: /* @__PURE__ */ new Date() });
|
|
1450
|
-
} else {
|
|
1451
|
-
|
|
1452
|
-
|
|
992
|
+
matchQuery = queryLocal[0].data;
|
|
993
|
+
ctx.database.set("dt_previous_query_results", matchQuery.match.id, { queryTime: /* @__PURE__ */ new Date() });
|
|
994
|
+
} else matchQuery = await query("MatchInfo", { matchId });
|
|
995
|
+
if (matchQuery.match.parsedDateTime)
|
|
996
|
+
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: matchQuery.match.id, data: matchQuery, queryTime: /* @__PURE__ */ new Date() }]);
|
|
997
|
+
let match = getFormattedMatchData(matchQuery);
|
|
1453
998
|
if (match && (match.parsedDateTime || import_moment.default.unix(match.endDateTime).isBefore((0, import_moment.default)().subtract(config.dataParsingTimeoutMinutes, "minutes")))) {
|
|
1454
999
|
session.send((ctx.config.urlInMessageType.some((type) => type == "match") ? "https://stratz.com/matches/" + matchId : "") + await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */)));
|
|
1455
|
-
if (match.parsedDateTime)
|
|
1456
|
-
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: match.id, data: match, queryTime: /* @__PURE__ */ new Date() }]);
|
|
1457
1000
|
} else {
|
|
1458
1001
|
pendingMatches.push({ matchId, guilds: [{ platform: session.event.platform, guildId: session.event.channel.id, players: [] }] });
|
|
1459
1002
|
session.send("比赛尚未解析,将在解析完成后发布。");
|
|
@@ -1461,7 +1004,7 @@ async function apply(ctx, config) {
|
|
|
1461
1004
|
} catch (error) {
|
|
1462
1005
|
ctx.logger.error(error);
|
|
1463
1006
|
session.send("获取比赛信息失败。");
|
|
1464
|
-
ctx.database.remove("dt_previous_query_results", { matchId
|
|
1007
|
+
await ctx.database.remove("dt_previous_query_results", { matchId });
|
|
1465
1008
|
}
|
|
1466
1009
|
}
|
|
1467
1010
|
__name(queryMatchAndSend, "queryMatchAndSend");
|
|
@@ -1495,7 +1038,7 @@ async function apply(ctx, config) {
|
|
|
1495
1038
|
let lastMatchId = 0;
|
|
1496
1039
|
try {
|
|
1497
1040
|
session.send("正在搜索对局详情,请稍后...");
|
|
1498
|
-
lastMatchId = (await query(
|
|
1041
|
+
lastMatchId = (await query("PlayersLastmatchRankinfo", { steamAccountIds: [parseInt(flagBindedPlayer?.steamId ?? input_data)] })).players[0].matches[0].id;
|
|
1499
1042
|
} catch (error) {
|
|
1500
1043
|
session.send("获取玩家最近比赛失败。");
|
|
1501
1044
|
ctx.logger.error(error);
|
|
@@ -1526,8 +1069,13 @@ async function apply(ctx, config) {
|
|
|
1526
1069
|
let steamId = flagBindedPlayer?.steamId ?? input_data;
|
|
1527
1070
|
let player;
|
|
1528
1071
|
try {
|
|
1529
|
-
player = (await query(
|
|
1530
|
-
let playerExtra = (await query(
|
|
1072
|
+
player = (await query("PlayerInfoWith25Matches", { steamAccountId: steamId, heroIds: hero?.id })).player;
|
|
1073
|
+
let playerExtra = (await query("PlayerExtraInfo", {
|
|
1074
|
+
steamAccountId: steamId,
|
|
1075
|
+
matchCount: player.matchCount,
|
|
1076
|
+
totalHeroCount: Object.keys(dotaconstants2.heroes).length,
|
|
1077
|
+
heroIds: hero?.id
|
|
1078
|
+
})).player;
|
|
1531
1079
|
let filteredDotaPlus = {};
|
|
1532
1080
|
playerExtra.dotaPlus.forEach((item) => {
|
|
1533
1081
|
if (!filteredDotaPlus[item.heroId] || filteredDotaPlus[item.heroId].level < item.level) {
|
|
@@ -1675,15 +1223,15 @@ async function apply(ctx, config) {
|
|
|
1675
1223
|
return;
|
|
1676
1224
|
}
|
|
1677
1225
|
try {
|
|
1678
|
-
let heroStats = (await query(
|
|
1226
|
+
let heroStats = (await query("HeroMatchupWinrate", { heroId: hero.id, take: Object.keys(dotaconstants2.heroes).length - 1 })).heroStats;
|
|
1679
1227
|
let withTopFive = heroStats.matchUp[0].with.filter((item) => item.matchCount / heroStats.matchUp[0].matchCountWith > Math.max(0, Math.min(5, options.filter)) / 100).map((item) => {
|
|
1680
1228
|
const winRate = item.winCount / item.matchCount;
|
|
1681
1229
|
return { ...item, winRate: winRate.toFixed(3) };
|
|
1682
|
-
}).sort((a, b) => b.winRate - a.winRate).slice(0, Math.max(1, Math.min(Object.keys(
|
|
1230
|
+
}).sort((a, b) => b.winRate - a.winRate).slice(0, Math.max(1, Math.min(Object.keys(dotaconstants2.heroes).length - 1, options.limit)));
|
|
1683
1231
|
let vsBottomFive = heroStats.matchUp[0].vs.filter((item) => item.matchCount / heroStats.matchUp[0].matchCountVs > Math.max(0, Math.min(5, options.filter)) / 100).map((item) => {
|
|
1684
1232
|
const winRate = item.winCount / item.matchCount;
|
|
1685
1233
|
return { ...item, winRate: winRate.toFixed(3) };
|
|
1686
|
-
}).sort((a, b) => a.winRate - b.winRate).slice(0, Math.max(1, Math.min(Object.keys(
|
|
1234
|
+
}).sort((a, b) => a.winRate - b.winRate).slice(0, Math.max(1, Math.min(Object.keys(dotaconstants2.heroes).length - 1, options.limit)));
|
|
1687
1235
|
session.send(
|
|
1688
1236
|
`你查询的英雄是${HEROES_CHINESE[heroStats.matchUp[0].heroId][0]}(ID:${heroStats.matchUp[0].heroId}),
|
|
1689
1237
|
以下是7天内传奇-万古分段比赛数据总结而来的搭档与克制关系
|
|
@@ -1699,7 +1247,7 @@ async function apply(ctx, config) {
|
|
|
1699
1247
|
});
|
|
1700
1248
|
function findingHero(input) {
|
|
1701
1249
|
if (!input) return;
|
|
1702
|
-
let dc_heroes = Object.values(
|
|
1250
|
+
let dc_heroes = Object.values(dotaconstants2.heroes).map((hero) => ({
|
|
1703
1251
|
id: hero["id"],
|
|
1704
1252
|
name: hero["name"],
|
|
1705
1253
|
shortName: hero["name"].match(/^npc_dota_hero_(.+)$/)[1]
|
|
@@ -1716,8 +1264,8 @@ async function apply(ctx, config) {
|
|
|
1716
1264
|
else mergedMap.set(item.id, item);
|
|
1717
1265
|
});
|
|
1718
1266
|
});
|
|
1719
|
-
let
|
|
1720
|
-
return
|
|
1267
|
+
let heroes2 = Array.from(mergedMap.values());
|
|
1268
|
+
return heroes2.find((hero) => hero.names_cn.some((cn) => cn.toLowerCase() == input.toLowerCase()) || hero.shortName === input.toLowerCase() || hero.id == input);
|
|
1721
1269
|
}
|
|
1722
1270
|
__name(findingHero, "findingHero");
|
|
1723
1271
|
ctx.on("ready", async () => {
|
|
@@ -1749,7 +1297,7 @@ async function apply(ctx, config) {
|
|
|
1749
1297
|
const subscribedPlayersSteamIds = subscribedPlayersInGuild.map((player) => player.steamId).filter(function(value, index, self) {
|
|
1750
1298
|
return self.indexOf(value) === index;
|
|
1751
1299
|
});
|
|
1752
|
-
const players = (await query(
|
|
1300
|
+
const players = (await query("PlayersLastmatchRankinfo", { steamAccountIds: subscribedPlayersSteamIds })).players;
|
|
1753
1301
|
const lastMatches = players.map((player) => player.matches[0]).filter((item, index, self) => index === self.findIndex((t) => t.id === item.id)).filter((match) => import_moment.default.unix(match.startDateTime).isAfter((0, import_moment.default)().subtract(1, "days"))).filter((match) => !pendingMatches.some((pendingMatch) => pendingMatch.matchId == match.id));
|
|
1754
1302
|
const sendedMatchesIds = (await ctx.database.get("dt_sended_match_id", { matchId: lastMatches.map((match) => match.id) }, ["matchId"])).map((match) => match.matchId);
|
|
1755
1303
|
lastMatches.filter((match) => !sendedMatchesIds.includes(match.id)).forEach((match) => {
|
|
@@ -1764,7 +1312,7 @@ async function apply(ctx, config) {
|
|
|
1764
1312
|
});
|
|
1765
1313
|
});
|
|
1766
1314
|
pendingMatches.push({ matchId: match.id, guilds: tempGuilds });
|
|
1767
|
-
query(
|
|
1315
|
+
query("RequestMatchDataAnalysis", { matchId: match.id });
|
|
1768
1316
|
ctx.logger.info(
|
|
1769
1317
|
tempGuilds.map((guild) => `追踪到来自群组${guild.platform}:${guild.guildId}的用户${guild.players.map((player) => `[${player.nickName ?? ""}(${player.steamId})]`).join("、")}的尚未播报过的最新比赛 ${match.id}。`).join("")
|
|
1770
1318
|
);
|
|
@@ -1824,13 +1372,16 @@ async function apply(ctx, config) {
|
|
|
1824
1372
|
const now = (0, import_moment.default)();
|
|
1825
1373
|
const pendingMatch = pendingMatches[(now.hours() * 60 + now.minutes()) % pendingMatches.length];
|
|
1826
1374
|
try {
|
|
1827
|
-
let
|
|
1375
|
+
let matchQuery;
|
|
1828
1376
|
let queryLocal = await ctx.database.get("dt_previous_query_results", pendingMatch.matchId, ["data"]);
|
|
1829
1377
|
if (queryLocal.length > 0) {
|
|
1830
|
-
|
|
1831
|
-
ctx.database.set("dt_previous_query_results", match.id, { queryTime: /* @__PURE__ */ new Date() });
|
|
1832
|
-
} else
|
|
1833
|
-
if (match.parsedDateTime || import_moment.default.unix(match.endDateTime).isBefore(now.subtract(config.dataParsingTimeoutMinutes, "minutes"))) {
|
|
1378
|
+
matchQuery = queryLocal[0].data;
|
|
1379
|
+
ctx.database.set("dt_previous_query_results", matchQuery.match.id, { queryTime: /* @__PURE__ */ new Date() });
|
|
1380
|
+
} else matchQuery = await query("MatchInfo", { matchId: pendingMatch.matchId });
|
|
1381
|
+
if (matchQuery.match.parsedDateTime || import_moment.default.unix(matchQuery.match.endDateTime).isBefore(now.subtract(config.dataParsingTimeoutMinutes, "minutes"))) {
|
|
1382
|
+
if (matchQuery.match.parsedDateTime)
|
|
1383
|
+
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: matchQuery.match.id, data: matchQuery, queryTime: /* @__PURE__ */ new Date() }]);
|
|
1384
|
+
let match = getFormattedMatchData(matchQuery);
|
|
1834
1385
|
pendingMatches = pendingMatches.filter((item) => item.matchId != match.id);
|
|
1835
1386
|
const img = await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */));
|
|
1836
1387
|
for (let commingGuild of pendingMatch.guilds) {
|
|
@@ -1856,10 +1407,8 @@ KDA:${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)} [${
|
|
|
1856
1407
|
await ctx.broadcast([`${commingGuild.platform}:${commingGuild.guildId}`], broadMatchMessage + (ctx.config.urlInMessageType.some((type) => type == "match") ? "https://stratz.com/matches/" + match.id : "") + img);
|
|
1857
1408
|
ctx.logger.info(`${match.id}${match.parsedDateTime ? "已解析," : "已结束超过1小时仍未被解析,放弃等待解析直接"}生成图片并发布于${commingGuild.platform}:${commingGuild.guildId}。`);
|
|
1858
1409
|
}
|
|
1859
|
-
if (match.parsedDateTime)
|
|
1860
|
-
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: match.id, data: match, queryTime: /* @__PURE__ */ new Date() }]);
|
|
1861
1410
|
ctx.database.create("dt_sended_match_id", { matchId: match.id, sendTime: /* @__PURE__ */ new Date() });
|
|
1862
|
-
} else ctx.logger.info("比赛 %d 尚未解析完成,继续等待。", match.id);
|
|
1411
|
+
} else ctx.logger.info("比赛 %d 尚未解析完成,继续等待。", matchQuery.match.id);
|
|
1863
1412
|
} catch (error) {
|
|
1864
1413
|
ctx.logger.error(error);
|
|
1865
1414
|
ctx.database.remove("dt_previous_query_results", { matchId: pendingMatch.matchId });
|
|
@@ -1870,11 +1419,10 @@ KDA:${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)} [${
|
|
|
1870
1419
|
async function report(timeAgo, title, showCombi) {
|
|
1871
1420
|
const subscribedGuilds = await ctx.database.get("dt_subscribed_guilds", void 0);
|
|
1872
1421
|
const subscribedPlayersInGuild = (await ctx.database.get("dt_subscribed_players", void 0)).filter((player) => subscribedGuilds.some((guild) => guild.guildId == player.guildId));
|
|
1873
|
-
const players = (await query(
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
)).data.players.filter((player) => player.matches.length > 0);
|
|
1422
|
+
const players = (await query("PlayersMatchesForDaily", {
|
|
1423
|
+
steamAccountIds: subscribedPlayersInGuild.map((player) => player.steamId).filter((value, index, self) => self.indexOf(value) === index),
|
|
1424
|
+
seconds: timeAgo
|
|
1425
|
+
})).players.filter((player) => player.matches.length > 0);
|
|
1878
1426
|
const matches = players.map((player) => player.matches.map((match) => match)).flat().filter((item, index, self) => index === self.findIndex((t) => t.id === item.id));
|
|
1879
1427
|
for (let subPlayer of subscribedPlayersInGuild) {
|
|
1880
1428
|
let player = players.find((player2) => subPlayer.steamId == player2.steamAccount.id);
|
|
@@ -1961,7 +1509,7 @@ function genImageHTML(data, template, type) {
|
|
|
1961
1509
|
ImageType,
|
|
1962
1510
|
ImageFormat,
|
|
1963
1511
|
d2a: dotaconstants_add_exports,
|
|
1964
|
-
dotaconstants:
|
|
1512
|
+
dotaconstants: dotaconstants2,
|
|
1965
1513
|
moment: import_moment.default,
|
|
1966
1514
|
escapeHTML: /* @__PURE__ */ __name(function escapeHTML(str) {
|
|
1967
1515
|
if (str == null) return "";
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjtdev/koishi-plugin-dota2tracker",
|
|
3
3
|
"description": "koishi插件-追踪群友的DOTA2对局",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.20-pre.2",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"lib",
|
|
9
9
|
"dist",
|
|
10
10
|
"images",
|
|
11
|
-
"template"
|
|
11
|
+
"template",
|
|
12
|
+
"queries"
|
|
12
13
|
],
|
|
13
14
|
"contributors": [
|
|
14
15
|
"sjtdev <sh1j1n9ta0@foxmail.com>"
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
query HeroInfo($heroId: Short!) {
|
|
2
|
+
constants {
|
|
3
|
+
hero(id: $heroId, language: S_CHINESE) {
|
|
4
|
+
id
|
|
5
|
+
name
|
|
6
|
+
shortName
|
|
7
|
+
aliases
|
|
8
|
+
roles {
|
|
9
|
+
roleId
|
|
10
|
+
level
|
|
11
|
+
}
|
|
12
|
+
language {
|
|
13
|
+
displayName
|
|
14
|
+
lore
|
|
15
|
+
hype
|
|
16
|
+
}
|
|
17
|
+
abilities {
|
|
18
|
+
ability(language: S_CHINESE) {
|
|
19
|
+
name
|
|
20
|
+
language {
|
|
21
|
+
displayName
|
|
22
|
+
description
|
|
23
|
+
attributes
|
|
24
|
+
lore
|
|
25
|
+
aghanimDescription
|
|
26
|
+
shardDescription
|
|
27
|
+
notes
|
|
28
|
+
}
|
|
29
|
+
stat {
|
|
30
|
+
type
|
|
31
|
+
behavior
|
|
32
|
+
unitTargetType
|
|
33
|
+
unitTargetTeam
|
|
34
|
+
unitTargetFlags
|
|
35
|
+
unitDamageType
|
|
36
|
+
cooldown
|
|
37
|
+
manaCost
|
|
38
|
+
spellImmunity
|
|
39
|
+
isOnCastbar
|
|
40
|
+
isGrantedByShard
|
|
41
|
+
isGrantedByScepter
|
|
42
|
+
hasShardUpgrade
|
|
43
|
+
hasScepterUpgrade
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
talents {
|
|
48
|
+
abilityId
|
|
49
|
+
slot
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
query HeroMatchupWinrate($heroId: Short!, $take: Int!) {
|
|
2
|
+
heroStats {
|
|
3
|
+
matchUp(heroId: $heroId, take: $take, bracketBasicIds: LEGEND_ANCIENT) {
|
|
4
|
+
heroId
|
|
5
|
+
matchCountWith
|
|
6
|
+
matchCountVs
|
|
7
|
+
with {
|
|
8
|
+
heroId1
|
|
9
|
+
winRateHeroId1
|
|
10
|
+
heroId2
|
|
11
|
+
winRateHeroId2
|
|
12
|
+
winCount
|
|
13
|
+
matchCount
|
|
14
|
+
}
|
|
15
|
+
vs {
|
|
16
|
+
heroId1
|
|
17
|
+
winRateHeroId1
|
|
18
|
+
heroId2
|
|
19
|
+
winRateHeroId2
|
|
20
|
+
winCount
|
|
21
|
+
matchCount
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
query MatchInfo($matchId: Long!) {
|
|
2
|
+
match(id: $matchId) {
|
|
3
|
+
id
|
|
4
|
+
didRadiantWin
|
|
5
|
+
lobbyType
|
|
6
|
+
gameMode
|
|
7
|
+
regionId
|
|
8
|
+
parsedDateTime
|
|
9
|
+
startDateTime
|
|
10
|
+
endDateTime
|
|
11
|
+
actualRank
|
|
12
|
+
rank
|
|
13
|
+
averageRank
|
|
14
|
+
durationSeconds
|
|
15
|
+
topLaneOutcome
|
|
16
|
+
midLaneOutcome
|
|
17
|
+
bottomLaneOutcome
|
|
18
|
+
radiantKills
|
|
19
|
+
direKills
|
|
20
|
+
players {
|
|
21
|
+
steamAccountId
|
|
22
|
+
steamAccount {
|
|
23
|
+
name
|
|
24
|
+
}
|
|
25
|
+
level
|
|
26
|
+
hero {
|
|
27
|
+
id
|
|
28
|
+
name
|
|
29
|
+
shortName
|
|
30
|
+
facets {
|
|
31
|
+
facetId
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
variant
|
|
35
|
+
dotaPlus {
|
|
36
|
+
level
|
|
37
|
+
}
|
|
38
|
+
leaverStatus
|
|
39
|
+
partyId
|
|
40
|
+
position
|
|
41
|
+
playerSlot
|
|
42
|
+
lane
|
|
43
|
+
imp
|
|
44
|
+
kills
|
|
45
|
+
deaths
|
|
46
|
+
assists
|
|
47
|
+
isRadiant
|
|
48
|
+
networth
|
|
49
|
+
steamAccount {
|
|
50
|
+
seasonRank
|
|
51
|
+
seasonLeaderboardRank
|
|
52
|
+
}
|
|
53
|
+
item0Id
|
|
54
|
+
item1Id
|
|
55
|
+
item2Id
|
|
56
|
+
item3Id
|
|
57
|
+
item4Id
|
|
58
|
+
item5Id
|
|
59
|
+
backpack0Id
|
|
60
|
+
backpack1Id
|
|
61
|
+
backpack2Id
|
|
62
|
+
neutral0Id
|
|
63
|
+
stats {
|
|
64
|
+
matchPlayerBuffEvent {
|
|
65
|
+
abilityId
|
|
66
|
+
itemId
|
|
67
|
+
stackCount
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
heroDamage
|
|
71
|
+
towerDamage
|
|
72
|
+
stats {
|
|
73
|
+
heroDamageReport {
|
|
74
|
+
receivedTotal {
|
|
75
|
+
physicalDamage
|
|
76
|
+
magicalDamage
|
|
77
|
+
pureDamage
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
numLastHits
|
|
82
|
+
numDenies
|
|
83
|
+
goldPerMinute
|
|
84
|
+
experiencePerMinute
|
|
85
|
+
heroHealing
|
|
86
|
+
stats {
|
|
87
|
+
itemPurchases {
|
|
88
|
+
itemId
|
|
89
|
+
time
|
|
90
|
+
}
|
|
91
|
+
campStack
|
|
92
|
+
heroDamageReport {
|
|
93
|
+
dealtTotal {
|
|
94
|
+
stunDuration
|
|
95
|
+
stunCount
|
|
96
|
+
slowDuration
|
|
97
|
+
slowCount
|
|
98
|
+
disableDuration
|
|
99
|
+
disableCount
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
additionalUnit {
|
|
104
|
+
item0Id
|
|
105
|
+
item1Id
|
|
106
|
+
item2Id
|
|
107
|
+
item3Id
|
|
108
|
+
item4Id
|
|
109
|
+
item5Id
|
|
110
|
+
backpack0Id
|
|
111
|
+
backpack1Id
|
|
112
|
+
backpack2Id
|
|
113
|
+
neutral0Id
|
|
114
|
+
}
|
|
115
|
+
isRandom
|
|
116
|
+
}
|
|
117
|
+
pickBans {
|
|
118
|
+
isPick
|
|
119
|
+
bannedHeroId
|
|
120
|
+
heroId
|
|
121
|
+
order
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
constants {
|
|
125
|
+
facets(language: S_CHINESE) {
|
|
126
|
+
name
|
|
127
|
+
id
|
|
128
|
+
color
|
|
129
|
+
icon
|
|
130
|
+
language {
|
|
131
|
+
displayName
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
query PlayerExtraInfo($steamAccountId: Long!, $totalHeroCount: Int!, $matchCount: Int!, $heroIds: [Short]) {
|
|
2
|
+
player(steamAccountId: $steamAccountId) {
|
|
3
|
+
heroesPerformance(take: $totalHeroCount, request: { matchGroupOrderBy: MATCH_COUNT, take: $matchCount, heroIds: $heroIds }) {
|
|
4
|
+
hero {
|
|
5
|
+
id
|
|
6
|
+
shortName
|
|
7
|
+
}
|
|
8
|
+
winCount
|
|
9
|
+
matchCount
|
|
10
|
+
imp
|
|
11
|
+
}
|
|
12
|
+
dotaPlus {
|
|
13
|
+
heroId
|
|
14
|
+
level
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
query PlayerInfoWith25Matches($steamAccountId: Long!, $heroIds: [Short]) {
|
|
2
|
+
player(steamAccountId: $steamAccountId) {
|
|
3
|
+
steamAccount {
|
|
4
|
+
avatar
|
|
5
|
+
name
|
|
6
|
+
seasonRank
|
|
7
|
+
seasonLeaderboardRank
|
|
8
|
+
id
|
|
9
|
+
}
|
|
10
|
+
guildMember {
|
|
11
|
+
guild {
|
|
12
|
+
tag
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
matchCount
|
|
16
|
+
winCount
|
|
17
|
+
performance {
|
|
18
|
+
imp
|
|
19
|
+
}
|
|
20
|
+
heroesPerformance(take: 25, request: { matchGroupOrderBy: WIN_COUNT, take: 25, heroIds: $heroIds }) {
|
|
21
|
+
hero {
|
|
22
|
+
id
|
|
23
|
+
shortName
|
|
24
|
+
}
|
|
25
|
+
imp
|
|
26
|
+
winCount
|
|
27
|
+
matchCount
|
|
28
|
+
}
|
|
29
|
+
matches(request: { take: 25, heroIds: $heroIds }) {
|
|
30
|
+
id
|
|
31
|
+
rank
|
|
32
|
+
lobbyType
|
|
33
|
+
gameMode
|
|
34
|
+
startDateTime
|
|
35
|
+
parsedDateTime
|
|
36
|
+
durationSeconds
|
|
37
|
+
didRadiantWin
|
|
38
|
+
topLaneOutcome
|
|
39
|
+
midLaneOutcome
|
|
40
|
+
bottomLaneOutcome
|
|
41
|
+
radiantKills
|
|
42
|
+
direKills
|
|
43
|
+
players {
|
|
44
|
+
steamAccount {
|
|
45
|
+
id
|
|
46
|
+
}
|
|
47
|
+
isRadiant
|
|
48
|
+
lane
|
|
49
|
+
kills
|
|
50
|
+
deaths
|
|
51
|
+
assists
|
|
52
|
+
position
|
|
53
|
+
award
|
|
54
|
+
imp
|
|
55
|
+
hero {
|
|
56
|
+
id
|
|
57
|
+
shortName
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
query PlayersInfoWith10MatchesForGuild($steamAccountIds: [Long]!) {
|
|
2
|
+
players(steamAccountIds: $steamAccountIds) {
|
|
3
|
+
steamAccount {
|
|
4
|
+
id
|
|
5
|
+
avatar
|
|
6
|
+
name
|
|
7
|
+
seasonRank
|
|
8
|
+
}
|
|
9
|
+
matches(request: { take: 10 }) {
|
|
10
|
+
didRadiantWin
|
|
11
|
+
startDateTime
|
|
12
|
+
players {
|
|
13
|
+
isRadiant
|
|
14
|
+
kills
|
|
15
|
+
deaths
|
|
16
|
+
assists
|
|
17
|
+
steamAccount {
|
|
18
|
+
id
|
|
19
|
+
}
|
|
20
|
+
hero {
|
|
21
|
+
shortName
|
|
22
|
+
}
|
|
23
|
+
imp
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
query PlayersLastmatchRankinfo($steamAccountIds: [Long]!) {
|
|
2
|
+
players(steamAccountIds: $steamAccountIds) {
|
|
3
|
+
steamAccount {
|
|
4
|
+
id
|
|
5
|
+
name
|
|
6
|
+
avatar
|
|
7
|
+
seasonRank
|
|
8
|
+
seasonLeaderboardRank
|
|
9
|
+
}
|
|
10
|
+
matches(request: { take: 1 }) {
|
|
11
|
+
id
|
|
12
|
+
parsedDateTime
|
|
13
|
+
startDateTime
|
|
14
|
+
players {
|
|
15
|
+
steamAccount {
|
|
16
|
+
id
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
query PlayersMatchesForDaily($steamAccountIds: [Long]!, $seconds: Long!) {
|
|
2
|
+
players(steamAccountIds: $steamAccountIds) {
|
|
3
|
+
steamAccount {
|
|
4
|
+
id
|
|
5
|
+
name
|
|
6
|
+
avatar
|
|
7
|
+
}
|
|
8
|
+
matches(request: { startDateTime: $seconds, take: 50 }) {
|
|
9
|
+
id
|
|
10
|
+
didRadiantWin
|
|
11
|
+
parsedDateTime
|
|
12
|
+
startDateTime
|
|
13
|
+
players {
|
|
14
|
+
kills
|
|
15
|
+
deaths
|
|
16
|
+
assists
|
|
17
|
+
imp
|
|
18
|
+
isRadiant
|
|
19
|
+
steamAccount {
|
|
20
|
+
id
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
package/readme.md
CHANGED
|
@@ -53,11 +53,6 @@ DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑
|
|
|
53
53
|
展示见[wiki](https://github.com/sjtdev/koishi-plugin-dota2tracker/wiki)
|
|
54
54
|
生成图片已使用ejs模板实现,所有模板都在[template]文件夹下,若是有大佬想自己设计模板欢迎联系我完善数据接口。(当前有很多在模板中后处理的数据,不是很友好)
|
|
55
55
|
|
|
56
|
-
### 其他问题
|
|
57
|
-
已知问题:当本插件更新版本后,查询已经查询过的比赛数据可能查询失败。
|
|
58
|
-
* 原因:插件的缓存功能,查询过的比赛数据会缓存至本地以节省API调用次数与服务器流量,再次查询时优先调用本地数据也会提高处理速度。当插件更新后若新增数据的处理或API查询字段,会导致旧的缓存内缺失部分数据引发生成时报错。(播报比赛战报应该不会有这个问题)
|
|
59
|
-
* 解决:目前在生成失败时会清除缓存,再查询一次就好了。
|
|
60
|
-
|
|
61
56
|
## 灵感来源&鸣谢
|
|
62
57
|
* 感谢[SonodaHanami](https://github.com/SonodaHanami)大佬的[Steam_watcher](https://github.com/SonodaHanami/Steam_watcher)项目,是本插件最重要的灵感来源,并授权提供了战报称号系统、英雄代称与播报信息的代码数据。
|
|
63
58
|
* 也受到了[koishi-plugin-dota2track(npm)](https://www.npmjs.com/package/koishi-plugin-dota2track)的启发,为我的代码提供了一些思路。
|