@sjtdev/koishi-plugin-dota2tracker 1.5.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +2429 -1625
- package/package.json +7 -3
- package/queries/GetWeeklyMetaByPosition.graphql +29 -0
- package/queries/PlayerExtraInfo.graphql +2 -2
- package/queries/PlayerPerformanceForHeroRecommendation.graphql +23 -0
- package/template/hero/hero_1.ejs +29 -29
- package/template/item/item/recipe.ejs +3 -3
- package/template/item/item.ejs +3 -3
- package/template/item/itemlist.ejs +1 -1
- package/template/match/match_1/item.ejs +4 -4
- package/template/match/match_1/main.ejs +8 -8
- package/template/match/match_1/player.ejs +10 -10
- package/template/match/match_1/style.css +12 -0
- package/template/match/match_1.ejs +6 -6
- package/template/match/match_2/original.ejs +122 -82
- package/template/match/match_2+/charts.ejs +3 -3
- package/template/match/match_2+/lane_outcome.ejs +2 -2
- package/template/player/player_1.ejs +49 -23
- package/template/rank/rank_fun.ejs +6 -6
- package/queries/HeroMatchupWinrate.graphql +0 -25
- package/template/guild_member/guild_member.ejs +0 -176
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
</div>
|
|
35
35
|
<div class="start_time">
|
|
36
36
|
<p><%= $t("dota2tracker.template.start_time_").slice(0, -1) %></p>
|
|
37
|
-
<p><%-
|
|
37
|
+
<p><%-DateTime.fromSeconds(match.startDateTime).toFormat("yyyy-MM-dd HH:mm:ss").slice(2)%></p>
|
|
38
38
|
</div>
|
|
39
39
|
<div class="duration">
|
|
40
40
|
<p><%= $t("dota2tracker.template.duration_").slice(0, -1) %></p>
|
|
41
|
-
<p><%-
|
|
41
|
+
<p><%-match.durationTime%></p>
|
|
42
42
|
</div>
|
|
43
43
|
<div class="region">
|
|
44
44
|
<p><%= $t("dota2tracker.template.region_").slice(0, -1) %></p>
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
<p><%-$t("dota2tracker.template.lobby_types."+match.lobbyType) || match.lobbyType%>/<%-$t("dota2tracker.template.game_modes."+match.gameMode) || match.gameMode%></p>
|
|
50
50
|
</div>
|
|
51
51
|
<div class="rank">
|
|
52
|
-
<img src="<%-
|
|
53
|
-
<img style="z-index: 1;" src="<%-
|
|
52
|
+
<img src="<%-getImageUrl('medal_' + (match.rank?.toString().split('')[0] ?? '0'))%>" alt="" />
|
|
53
|
+
<img style="z-index: 1;" src="<%-getImageUrl('star_' + (match.rank?.toString().split('')[1] ?? '0'))%>" alt="" />
|
|
54
54
|
</div>
|
|
55
55
|
</nav>
|
|
56
56
|
<section class="match_result">
|
|
@@ -59,85 +59,125 @@
|
|
|
59
59
|
<span class="kills dire"><%-match.dire.killsCount%></span>
|
|
60
60
|
</section>
|
|
61
61
|
<section class="players">
|
|
62
|
-
|
|
63
|
-
<section class="panel
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
<p class="
|
|
68
|
-
|
|
69
|
-
<p
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
</
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
62
|
+
<% ['radiant','dire'].forEach(function(team) { %>
|
|
63
|
+
<section class="panel <%= team %>" <%- `style="order: ${team === 'radiant' ? 0 : 50 }"`%>>
|
|
64
|
+
<img src="<%- getImageUrl('logo_' + team) %>">
|
|
65
|
+
<p><%- (team === 'radiant' ? ['Radiant','天辉'] : ['Dire','夜魇']).join('<br>') %></p>
|
|
66
|
+
<% if ((team === 'radiant') === match.didRadiantWin) { %>
|
|
67
|
+
<p class="win"><%= $t('dota2tracker.template.won') %></p>
|
|
68
|
+
<% } else { %>
|
|
69
|
+
<p></p>
|
|
70
|
+
<% } %>
|
|
71
|
+
<p class="data"><%= $t('dota2tracker.template.kill') %><br><%= match[team].killsCount %></p>
|
|
72
|
+
<p class="data"><%= $t('dota2tracker.template.total_damage') %><br><%= match[team].heroDamage %></p>
|
|
73
|
+
<p class="data"><%= $t('dota2tracker.template.total_gold') %><br><%= match[team].networth %></p>
|
|
74
|
+
<p class="data"><%= $t('dota2tracker.template.total_experience') %><br><%= match[team].experience %></p>
|
|
75
|
+
</section>
|
|
76
|
+
<% }); %>
|
|
77
|
+
|
|
78
|
+
<% match.players.forEach(function(player) { %>
|
|
79
|
+
<div class="player <%= player.team %><%= player.hero.id == 80 ? ' bear' : '' %>" <%- `style="order: ${player.team === 'radiant' ? 1 : 100}"` %>;>
|
|
80
|
+
<div class="hero_avatar row-1<%= player.partyId != null ? ' party_' + match.party[player.partyId] : '' %>">
|
|
81
|
+
<img src="<%- getImageUrl(player.hero.shortName, ImageType.Heroes) %>" />
|
|
82
|
+
<p class="level"><%= player.level %></p>
|
|
83
|
+
<p class="party_line"></p>
|
|
84
|
+
<p class="party_mark"></p>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="facet <%= player.facet?.color ?? 'Black' %>">
|
|
87
|
+
<% if (player.facet) { %>
|
|
88
|
+
<img src="<%- getImageUrl(player.facet.icon, ImageType.IconsFacets) %>">
|
|
89
|
+
<% } %>
|
|
90
|
+
<span <%- `style="font-size: ${player.facet?.name?.length > 4 ? 8 : 11}px;"`%>>
|
|
91
|
+
<p><%= player.facet?.displayName ?? '?' %></p>
|
|
92
|
+
</span>
|
|
93
|
+
</div>
|
|
94
|
+
<div class="rank">
|
|
95
|
+
<img src="<%- getImageUrl('medal_' + (player.rank.inTop100 ?? player.rank.medal)) %>" class="medal" />
|
|
96
|
+
<img src="<%- getImageUrl('star_' + player.rank.star) %>" class="stars" />
|
|
97
|
+
<p><%= player.steamAccount.seasonLeaderboardRank ?? '' %></p>
|
|
98
|
+
</div>
|
|
99
|
+
<div class="titles">
|
|
100
|
+
<% player.titles.forEach(function(item) {
|
|
101
|
+
const [title, color] = $t(item).split('-'); %>
|
|
102
|
+
<span <%- `style="color: ${darkenHexColor(color, 25)};"` %>><%= title %></span>
|
|
103
|
+
<% }); %>
|
|
104
|
+
</div>
|
|
105
|
+
<div class="player_name row-1">
|
|
106
|
+
<span class="rank">[<%= $t('dota2tracker.template.ranks.' + player.rank.medal) %><%= player.rank.star || '' %>]</span>
|
|
107
|
+
<span class="name"><%= player.steamAccount.name %></span>
|
|
108
|
+
</div>
|
|
109
|
+
<p class="pick">
|
|
110
|
+
<%- player.isRandom ? $t('dota2tracker.template.random') : $t('dota2tracker.template.pick_order', [player.order == null ? '?' : player.order + 1]) %>
|
|
111
|
+
<%= $t('dota2tracker.template.position_' + player.position?.slice(-1)) ?? '' %>
|
|
112
|
+
</p>
|
|
113
|
+
<p class="networth">
|
|
114
|
+
<span class="gold"><%= player.formattedNetworth %></span>
|
|
115
|
+
(<%= (player.heroDamage / player.networth)?.toFixed(2) %>)
|
|
116
|
+
</p>
|
|
117
|
+
<p class="hero_damage">
|
|
118
|
+
<%= $t('dota2tracker.template.hero_damage_') %><%= player.heroDamage %>
|
|
119
|
+
(<%= (player.heroDamage / match[player.team].heroDamage * 100).toFixed(2) %>%)
|
|
120
|
+
</p>
|
|
121
|
+
<p class="damage_received">
|
|
122
|
+
<%= $t('dota2tracker.template.damage_received_') %><%= player.damageReceived %>
|
|
123
|
+
(<%= match[player.team].damageReceived > 0 ? ((player.damageReceived / match[player.team].damageReceived * 100).toFixed(2)) : '0.00' %>%)
|
|
124
|
+
</p>
|
|
125
|
+
<p class="tower_damage">
|
|
126
|
+
<%= $t('dota2tracker.template.building_damage_') %><%= player.towerDamage %>
|
|
127
|
+
</p>
|
|
128
|
+
<p class="kda row-1">
|
|
129
|
+
<%= player.kills %>/<%= player.deaths %>/<%= player.assists %>
|
|
130
|
+
(<%= ((player.kills + player.assists) / (player.deaths || 1)).toFixed(2) %>)
|
|
131
|
+
</p>
|
|
132
|
+
<p class="kill_contribution">
|
|
133
|
+
<%= $t('dota2tracker.template.kill_contribution_') %><%= (player.killContribution * 100).toFixed(2) %>%
|
|
134
|
+
</p>
|
|
135
|
+
<p class="stun_duration">
|
|
136
|
+
<%= $t('dota2tracker.template.crowd_control_duration_') %>
|
|
137
|
+
<%= ((player.stats.heroDamageReport?.dealtTotal.stunDuration ?? 0) / 100).toFixed(2) %>s
|
|
138
|
+
</p>
|
|
139
|
+
<p class="heal">
|
|
140
|
+
<%= $t('dota2tracker.template.heal_') %><%= player.heroHealing %>
|
|
141
|
+
</p>
|
|
142
|
+
<div class="items row-1">
|
|
143
|
+
<div class="normal">
|
|
144
|
+
<% player.items.forEach(function(item) { %>
|
|
145
|
+
<div class="item<%= item?.isRecipe ? ' recipe' : '' %>" data-id="<%= item?.id ?? 0 %>">
|
|
146
|
+
<img src="<%- item ? getImageUrl(item.name, ImageType.Items) : '' %>" alt="" />
|
|
147
|
+
<% if (item) { %>
|
|
148
|
+
<p class="time"><%= item?.time ?? '' %></p>
|
|
149
|
+
<% } %>
|
|
132
150
|
</div>
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
</div>
|
|
136
|
-
<div class="neutral_item row-1" style="background-image: url(${utils.getImageUrl(dotaconstants.item_ids[player.neutral0Id], ImageType.Items)})"></div>
|
|
137
|
-
<div class="ahgs row-1">
|
|
138
|
-
<img src="${utils.getImageUrl("scepter_"+((player.items.concat(player.backpacks).find(item=>item?.id==108)||(player.stats?.matchPlayerBuffEvent||[]).find(buff=>buff.itemId==108))?1:0))}" alt="" />
|
|
139
|
-
<img src="${utils.getImageUrl("shard_"+((player.stats?.matchPlayerBuffEvent||[]).find(buff=>buff.itemId==609)?1:0))}" alt="" />
|
|
151
|
+
<% }); %>
|
|
140
152
|
</div>
|
|
153
|
+
<% if (player.hero.id != 80) { %>
|
|
154
|
+
<div class="backpack">
|
|
155
|
+
<% player.backpacks.forEach(function(item) { %>
|
|
156
|
+
<div class="item<%= item?.isRecipe ? ' recipe' : '' %>">
|
|
157
|
+
<img src="<%- item ? getImageUrl(item.name, ImageType.Items) : '' %>" alt="" />
|
|
158
|
+
</div>
|
|
159
|
+
<% }); %>
|
|
160
|
+
</div>
|
|
161
|
+
<% } else { %>
|
|
162
|
+
<img class="bear_icon" src="<%- getImageUrl('lone_druid_spirit_bear', ImageType.Abilities) %>" alt="">
|
|
163
|
+
<div class="bear">
|
|
164
|
+
<% player.unitItems.forEach(function(item) { %>
|
|
165
|
+
<div class="item<%= item?.isRecipe ? ' recipe' : '' %>" data-id="<%= item?.id ?? 0 %>">
|
|
166
|
+
<img src="<%- item ? getImageUrl(item.name, ImageType.Items) : '' %>" alt="" />
|
|
167
|
+
<% if (item) { %>
|
|
168
|
+
<p class="time"><%= item?.time ?? '' %></p>
|
|
169
|
+
<% } %>
|
|
170
|
+
</div>
|
|
171
|
+
<% }); %>
|
|
172
|
+
</div>
|
|
173
|
+
<div class="neutral_item" <%- `style="background-image: url(${getImageUrl(dotaconstants.item_ids[player.additionalUnit.neutral0Id], ImageType.Items)})"` %>></div>
|
|
174
|
+
<% } %>
|
|
175
|
+
</div>
|
|
176
|
+
<div class="neutral_item row-1" <%- `style="background-image: url(${getImageUrl(dotaconstants.item_ids[player.neutral0Id], ImageType.Items)})"` %>></div>
|
|
177
|
+
<div class="ahgs row-1">
|
|
178
|
+
<img src="<%- getImageUrl('scepter_' + ((player.items.concat(player.backpacks).find(item => item?.id == 108) || (player.stats?.matchPlayerBuffEvent || []).find(buff => buff.itemId == 108)) ? 1 : 0)) %>" alt="" />
|
|
179
|
+
<img src="<%- getImageUrl('shard_' + ((player.stats?.matchPlayerBuffEvent || []).find(buff => buff.itemId == 609) ? 1 : 0)) %>" alt="" />
|
|
180
|
+
</div>
|
|
141
181
|
</div>
|
|
142
|
-
|
|
182
|
+
<% }); %>
|
|
143
183
|
</section>
|
|
@@ -84,8 +84,8 @@
|
|
|
84
84
|
%>
|
|
85
85
|
<svg width="<%= svgWidth %>" height="<%= svgHeight %>" xmlns="http://www.w3.org/2000/svg">
|
|
86
86
|
<text x="50%" y="30" text-anchor="middle" font-size="16" font-weight="bold"><%= $t("dota2tracker.template.situation") %></text>
|
|
87
|
-
<image x="<%= padding %>" y="<%= padding %>" width="20" height="20" href="<%=
|
|
88
|
-
<image x="<%= padding %>" y="<%= svgHeight - padding * 1.4 %>" width="20" height="20" href="<%=
|
|
87
|
+
<image x="<%= padding %>" y="<%= padding %>" width="20" height="20" href="<%= getImageUrl("logo_radiant") %>"/>
|
|
88
|
+
<image x="<%= padding %>" y="<%= svgHeight - padding * 1.4 %>" width="20" height="20" href="<%= getImageUrl("logo_dire") %>"/>
|
|
89
89
|
<text x="<%= padding + 20 %>" y="<%= padding + 10 %>" dominant-baseline="middle" fill="#3c9028"><%= $t("dota2tracker.template.radiant") %></text>
|
|
90
90
|
<text x="<%= padding + 20 %>" y="<%= svgHeight - padding * 1.4 + 10 %>" dominant-baseline="middle" fill="#9c3628"><%= $t("dota2tracker.template.dire") %></text>
|
|
91
91
|
<!-- 横轴线与标签 -->
|
|
@@ -228,7 +228,7 @@
|
|
|
228
228
|
y="0"
|
|
229
229
|
width="24"
|
|
230
230
|
height="24"
|
|
231
|
-
href="<%=
|
|
231
|
+
href="<%= getImageUrl(player.hero.shortName, ImageType.HeroIcons) %>"
|
|
232
232
|
clip-path="inset(0 round 6)"
|
|
233
233
|
/>
|
|
234
234
|
<% }) %>
|
|
@@ -69,7 +69,7 @@ function generateDetails(rivals) {
|
|
|
69
69
|
const goldSplit = gold.radiant / (gold.radiant + gold.dire);
|
|
70
70
|
return `
|
|
71
71
|
<div class="details">
|
|
72
|
-
<img src="${
|
|
72
|
+
<img src="${getImageUrl(rivals[0].hero.shortName, ImageType.HeroIcons)}" class="hero radiant" />
|
|
73
73
|
${generateLevelCircle(rivals[0].stats.experiencePerMinute.slice(0, Math.min(11, rivals[0].stats.experiencePerMinute.length - 1)).reduce((a, b) => a + b, 0))}
|
|
74
74
|
<p class="kda">${kills.radiant}/${deaths.radiant}/${assists.radiant}</p>
|
|
75
75
|
<div class="graph">
|
|
@@ -108,7 +108,7 @@ ${generateLevelCircle(rivals[0].stats.experiencePerMinute.slice(0, Math.min(11,
|
|
|
108
108
|
</div>
|
|
109
109
|
<p class="kda">${kills.dire}/${deaths.dire}/${assists.dire}</p>
|
|
110
110
|
${generateLevelCircle(rivals[1].stats.experiencePerMinute.slice(0, Math.min(11, rivals[1].stats.experiencePerMinute.length - 1)).reduce((a, b) => a + b, 0))}
|
|
111
|
-
<img src="${
|
|
111
|
+
<img src="${getImageUrl(rivals[1].hero.shortName, ImageType.HeroIcons)}" class="hero dire" />
|
|
112
112
|
</div>
|
|
113
113
|
`
|
|
114
114
|
}
|
|
@@ -366,12 +366,12 @@
|
|
|
366
366
|
}
|
|
367
367
|
};
|
|
368
368
|
const laneSVG = {
|
|
369
|
-
stomp:
|
|
370
|
-
victory:
|
|
371
|
-
fail:
|
|
372
|
-
stomped:
|
|
373
|
-
tie:
|
|
374
|
-
jungle:
|
|
369
|
+
stomp: getImageUrl("lane_stomp", undefined, ImageFormat.svg),
|
|
370
|
+
victory: getImageUrl("lane_victory", undefined, ImageFormat.svg),
|
|
371
|
+
fail: getImageUrl("lane_fail", undefined, ImageFormat.svg),
|
|
372
|
+
stomped: getImageUrl("lane_stomped", undefined, ImageFormat.svg),
|
|
373
|
+
tie: getImageUrl("lane_tie", undefined, ImageFormat.svg),
|
|
374
|
+
jungle: getImageUrl("lane_jungle", undefined, ImageFormat.svg),
|
|
375
375
|
};
|
|
376
376
|
const outcomeCounts = {
|
|
377
377
|
victory: 0,
|
|
@@ -461,19 +461,45 @@
|
|
|
461
461
|
};
|
|
462
462
|
const pixelOfPerMatchInPosition = (heroesCountPixels / (highestCountsPosition.winCount + highestCountsPosition.loseCount ?? 1)) * nearAdjustmentFactor;
|
|
463
463
|
%>
|
|
464
|
+
<% function winRateColor(value) {
|
|
465
|
+
value = value * 100;
|
|
466
|
+
value = Math.max(0, Math.min(100, value));
|
|
467
|
+
|
|
468
|
+
let red, green, blue;
|
|
469
|
+
|
|
470
|
+
if (value <= 50) {
|
|
471
|
+
// 从纯红到纯白
|
|
472
|
+
let scale = Math.round(255 * (value / 50)); // Scale of 0 to 255
|
|
473
|
+
red = 255;
|
|
474
|
+
green = scale;
|
|
475
|
+
blue = scale;
|
|
476
|
+
} else {
|
|
477
|
+
// 从纯白到纯绿
|
|
478
|
+
let scale = Math.round(255 * ((value - 50) / 50)); // Scale of 0 to 255
|
|
479
|
+
red = 255 - scale;
|
|
480
|
+
green = 255;
|
|
481
|
+
blue = 255 - scale;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// 将RGB值转换为两位十六进制代码
|
|
485
|
+
const toHex = (color) => color.toString(16).padStart(2, "0").toUpperCase();
|
|
486
|
+
|
|
487
|
+
return `#${toHex(red)}${toHex(green)}${toHex(blue)}`;
|
|
488
|
+
}
|
|
489
|
+
%>
|
|
464
490
|
|
|
465
491
|
<div class="wrapper">
|
|
466
492
|
<div class="player">
|
|
467
493
|
<div class="avatar"><img src="<%= player.steamAccount?.avatar %>" alt="" /></div>
|
|
468
494
|
<div class="info">
|
|
469
495
|
<p class="name">
|
|
470
|
-
<%=
|
|
471
|
-
<%- player.guildMember ? ` <span class="guild ${guildLevel(player.guildMember.guild.currentPercentile)}">${
|
|
496
|
+
<%= player.steamAccount.name %>
|
|
497
|
+
<%- player.guildMember ? ` <span class="guild ${guildLevel(player.guildMember.guild.currentPercentile)}">${player.guildMember.guild.tag}</span>` : "" %>
|
|
472
498
|
<%- player.genHero ? `<span class="hero_name">${player.genHero.name}</span>` : "" %>
|
|
473
499
|
</p>
|
|
474
500
|
<p class="matches">
|
|
475
501
|
<%=$t("dota2tracker.template.match_count_")%><%=player.matchCount%> (<span class="win"><%=player.winCount%></span>/<span class="lose"><%=player.matchCount - player.winCount%></span>)
|
|
476
|
-
<%=$t("dota2tracker.template.winrate_")%><span <%-`style="color:${
|
|
502
|
+
<%=$t("dota2tracker.template.winrate_")%><span <%-`style="color:${winRateColor(player.winCount / player.matchCount)};"`%>><%=((player.winCount / player.matchCount) * 100).toFixed(2)%>%</span>
|
|
477
503
|
</p>
|
|
478
504
|
<p class="matches<%- player.steamAccount.isAnonymous ? " blur" : "" %>">
|
|
479
505
|
<span><%-$t("dota2tracker.template.last25matches_")%>
|
|
@@ -481,7 +507,7 @@
|
|
|
481
507
|
<span class="lose"><%-nearMatchCount - nearWinCount%></span>
|
|
482
508
|
</span>
|
|
483
509
|
<span><%-$t("dota2tracker.template.winrate_")%>
|
|
484
|
-
<span <%-`style="color:${
|
|
510
|
+
<span <%-`style="color:${winRateColor(nearWinCount / nearMatchCount)};"`%>><%-((nearWinCount / nearMatchCount) * 100).toFixed(2)%>%</span>
|
|
485
511
|
</span>
|
|
486
512
|
<span><%-$t("dota2tracker.template.imp_")%><%-player.steamAccount.isAnonymous?"?":((player.performance?.imp > 0 ? "+" : "") + player.performance?.imp)%></span>
|
|
487
513
|
</p>
|
|
@@ -490,13 +516,13 @@
|
|
|
490
516
|
<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>
|
|
491
517
|
</span>
|
|
492
518
|
<span><%-$t("dota2tracker.template.lane_advantage_rate_")%>
|
|
493
|
-
<span <%-`style="color:${
|
|
519
|
+
<span <%-`style="color:${winRateColor((outcomeCounts.victory + outcomeCounts.stomp + outcomeCounts.tie / 2) / (outcomeCounts.victory + outcomeCounts.stomp + outcomeCounts.tie + outcomeCounts.fail + outcomeCounts.stomped))};"`%>><%-player.steamAccount.isAnonymous?"?":(((outcomeCounts.victory + outcomeCounts.stomp + outcomeCounts.tie / 2) / (outcomeCounts.victory + outcomeCounts.stomp + outcomeCounts.tie + outcomeCounts.fail + outcomeCounts.stomped)) * 100).toFixed(2)%>%</span>
|
|
494
520
|
</span>
|
|
495
521
|
</p>
|
|
496
522
|
</div>
|
|
497
523
|
<div class="rank<%= player.isEstimatedRank ? " estimated" : "" %>">
|
|
498
|
-
<img class="medal" src="<%-
|
|
499
|
-
<img class="star" src="<%-
|
|
524
|
+
<img class="medal" src="<%-getImageUrl('medal_' +(player.rank.inTop100??player.rank.medal))%>" alt="" />
|
|
525
|
+
<img class="star" src="<%-getImageUrl('star_' + player.rank.star)%>" alt="" />
|
|
500
526
|
<p><%-player.steamAccount.seasonLeaderboardRank ?? ""%></p>
|
|
501
527
|
</div>
|
|
502
528
|
</div>
|
|
@@ -511,7 +537,7 @@
|
|
|
511
537
|
<span class="tip lose_count" style="justify-self: start; margin-left: 2px"><%= $t("dota2tracker.template.lose_count") %></span>
|
|
512
538
|
<%- player.heroesPerformanceTop10
|
|
513
539
|
.map((hero) => `
|
|
514
|
-
<span><img alt="" src="${
|
|
540
|
+
<span><img alt="" src="${getImageUrl(hero.hero.shortName, ImageType.HeroIcons)}" /></span>
|
|
515
541
|
<span class="count">${hero.matchCount}</span>
|
|
516
542
|
<span class="win_rate">${((hero.winCount / hero.matchCount) * 100).toFixed(0)}%</span>
|
|
517
543
|
<span class="imp">${(hero.imp > 0 ? "+" : "") + hero.imp}</span>
|
|
@@ -524,7 +550,7 @@
|
|
|
524
550
|
<%- player.heroesPerformance
|
|
525
551
|
.filter((hero) => hero.matchCount > 1)
|
|
526
552
|
.map((hero, index) => `
|
|
527
|
-
<span><img alt="" src="${
|
|
553
|
+
<span><img alt="" src="${getImageUrl(hero.hero.shortName, ImageType.HeroIcons)}" /></span>
|
|
528
554
|
<span class="count">${hero.matchCount}</span>
|
|
529
555
|
<span class="win_rate">${((hero.winCount / hero.matchCount) * 100).toFixed(0)}%</span>
|
|
530
556
|
<span class="imp">${(hero.imp > 0 ? "+" : "") + hero.imp}</span>
|
|
@@ -539,7 +565,7 @@
|
|
|
539
565
|
<span class="tip lose_count" style="justify-self: start; margin-left: 2px"><%= $t("dota2tracker.template.lose_count") %></span>
|
|
540
566
|
<%- player.positionPerformance
|
|
541
567
|
.map((position) => `
|
|
542
|
-
<span><img src="${
|
|
568
|
+
<span><img src="${getImageUrl(position.icon,ImageType.IconsFacets)}"></span>
|
|
543
569
|
<span class="count">${position.matchCount}</span>
|
|
544
570
|
<span class="win_rate">${position.matchCount>0?(((position.winCount / position.matchCount) * 100).toFixed(0)):"-"}%</span>
|
|
545
571
|
<span class="imp">${(position.imp > 0 ? "+" : "") + position.imp}</span>
|
|
@@ -551,7 +577,7 @@
|
|
|
551
577
|
<% } %>
|
|
552
578
|
</div>
|
|
553
579
|
<%- Math.abs(player.streak) > 1 && !player.steamAccount.isAnonymous ?
|
|
554
|
-
`<div class="streak" style="box-shadow:none;color:${
|
|
580
|
+
`<div class="streak" style="box-shadow:none;color:${winRateColor((player.streak + 10) / 20)};">${Math.abs(player.streak) + (player.streak > 0 ? $t("dota2tracker.template.winning_streak") : $t("dota2tracker.template.losing_streak"))}</div>`:"" %>
|
|
555
581
|
<div>
|
|
556
582
|
<table class="matches">
|
|
557
583
|
<colgroup>
|
|
@@ -593,17 +619,17 @@
|
|
|
593
619
|
<p>${$t("dota2tracker.template.lobby_types."+match.lobbyType) || match.lobbyType}</p>
|
|
594
620
|
<p>${$t("dota2tracker.template.game_modes."+match.gameMode) || match.gameMode}</p>
|
|
595
621
|
</td>
|
|
596
|
-
<td><img alt="" src="${
|
|
622
|
+
<td><img alt="" src="${getImageUrl(innerPlayer.hero.shortName, ImageType.HeroIcons)}" /></td>
|
|
597
623
|
<td style="line-height: 20px">
|
|
598
624
|
<p>${((innerPlayer.kills + innerPlayer.assists) / Math.max(1, innerPlayer.deaths)).toFixed(2)} (${(match.parsedDateTime?"":"≈")+((((innerPlayer.kills + innerPlayer.assists) /
|
|
599
625
|
innerPlayer.teamKillsCount) * 100)?.toFixed(0))}%)</p>
|
|
600
626
|
<p>${innerPlayer.kills}/${innerPlayer.deaths}/${innerPlayer.assists}</p>
|
|
601
627
|
</td>
|
|
602
628
|
<td><div class="player_lane ${match.laneResult}">${laneSVG[match.laneResult]}</div></td>
|
|
603
|
-
<td style="line-height: 20px">${
|
|
604
|
-
<td>${
|
|
629
|
+
<td style="line-height: 20px">${DateTime.fromSeconds(match.startDateTime ?? 0).toFormat("yyyy-MM-dd HH:mm:ss").slice(2)}</td>
|
|
630
|
+
<td>${match.durationTime}</td>
|
|
605
631
|
<td>${innerPlayer.imp != null ? ((innerPlayer.imp >= 0 ? "+" : "") + innerPlayer.imp) : "?"}</td>
|
|
606
|
-
<td><img class="medal" src="${
|
|
632
|
+
<td><img class="medal" src="${getImageUrl("medal_" + match.rank?.toString().split("")[0])}" style="width: 100%" /></td>
|
|
607
633
|
</tr>`}).join("")%>
|
|
608
634
|
</tbody>
|
|
609
635
|
</table>
|
|
@@ -614,8 +640,8 @@
|
|
|
614
640
|
<div class="plus">
|
|
615
641
|
<%- player.dotaPlus.map((hero) => `
|
|
616
642
|
<div class="hero">
|
|
617
|
-
<img src="${
|
|
618
|
-
<div class="level"><img src="${
|
|
643
|
+
<img src="${getImageUrl(hero.shortName, ImageType.Heroes)}" alt="" />
|
|
644
|
+
<div class="level"><img src="${getImageUrl("hero_badge_" + Math.ceil((hero.level + 1) / 6))}" alt="" /><span>${hero.level}</span></div>
|
|
619
645
|
<span>${((hero.winCount / hero.matchCount) * 100).toFixed(2)}%</span>
|
|
620
646
|
<span>${hero.matchCount}</span>
|
|
621
647
|
</div>`).join("") %>
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
prev: `<span class="rank prev">${$t("dota2tracker.template.ranks."+prevRank.medal)}${prevRank.leader ?? prevRank.star}</span>`,
|
|
97
97
|
curr: `<span class="rank curr">${$t("dota2tracker.template.ranks."+currRank.medal)}${currRank.leader ?? currRank.star}</span>`,
|
|
98
98
|
} %>
|
|
99
|
-
<body class="<%= kind %>" <%- `style="background-image: url( ${
|
|
99
|
+
<body class="<%= kind %>" <%- `style="background-image: url( ${getImageUrl(kind, undefined, "jpg")} )"`%>>
|
|
100
100
|
<div class="wrapper">
|
|
101
101
|
<p class="<%= kind %>">
|
|
102
102
|
<%- kind == "xi" ?
|
|
@@ -107,17 +107,17 @@
|
|
|
107
107
|
<p></p>
|
|
108
108
|
<div class="ranks">
|
|
109
109
|
<div class="rank prev">
|
|
110
|
-
<img src="<%=
|
|
111
|
-
<img src="<%=
|
|
110
|
+
<img src="<%= getImageUrl('medal_' +(prevRank.inTop100 ?? prevRank.medal)) %>" alt="" />
|
|
111
|
+
<img src="<%= getImageUrl('star_' + prevRank.star) %>" alt="" />
|
|
112
112
|
<p><%= prevRank.leader ?? "" %></p>
|
|
113
113
|
</div>
|
|
114
114
|
<div class="rank curr">
|
|
115
|
-
<img src="<%=
|
|
116
|
-
<img src="<%=
|
|
115
|
+
<img src="<%= getImageUrl('medal_' +(currRank.inTop100 ?? currRank.medal)) %>" alt="" />
|
|
116
|
+
<img src="<%= getImageUrl('star_' + currRank.star) %>" alt="" />
|
|
117
117
|
<p><%= currRank.leader ?? "" %></p>
|
|
118
118
|
</div>
|
|
119
119
|
</div>
|
|
120
|
-
<p style="text-align: right; margin-top: 40px;">—— <%= date
|
|
120
|
+
<p style="text-align: right; margin-top: 40px;">—— <%= date %></p>
|
|
121
121
|
</div>
|
|
122
122
|
</body>
|
|
123
123
|
</html>
|
|
@@ -1,25 +0,0 @@
|
|
|
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
|
-
}
|