@sjtdev/koishi-plugin-dota2tracker 1.2.7-beta.3 → 1.2.8-pre

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/changelog.md CHANGED
@@ -1,7 +1,32 @@
1
+ ### 1.2.8-pre
2
+ **改进**:
3
+ - 现在`查询玩家`可在私聊状态使用,必须提供SteamID参数。
4
+ - 将战报中的播报评语由随机选取改为固定种子:比赛ID+玩家SteamID,确保在不同调用时刻、次数及平台下,对同一场比赛中的玩家评语保持一致。
5
+ - `查询玩家`指令图片中,玩家近期比赛表中未解析的场次参战率由"?%"改为估算值,显示为"≈xx%"
6
+ <details>
7
+ <summary>为什么是“估算”?</summary>
8
+ 比赛未解析无法获取“团队击杀数”,若是将己方所有玩家的击杀数相加,则会漏掉那些由小兵、防御塔等非玩家单位击杀数;若是将敌方所有玩家的死亡数相加,又会多出送野、自杀等不应算在己方战果中的计数。<br>目前程序采用将己方所有击杀数累加的方式来估算参战率
9
+ </details>
10
+
11
+ # 1.2.7
12
+ ##### 于1.2.7-beta中尝试修复的功能均已正常工作,正式发布1.2.7
13
+ ##### 以下为包括beta版更新内容在内的所有改动
14
+ ##### **新增**:
15
+ - 可在配置页设置查询比赛与发布战报时附带stratz比赛链接、查询玩家信息时附带stratz玩家页面链接、查询英雄数据信息时附带刀塔百科对应英雄页面链接,这些选项均默认关闭。
16
+ ##### **修复**:
17
+ - 修复当同一个steamId在多个已订阅群组中绑定时,仅会向最早绑定的群组发送战报的问题。
18
+ - 现在若所有玩家某项属性都为0时不会错误地将对应称号赋予玩家1,而是取消此称号赋予。(此版本前例如所有玩家治疗量都为0,玩家1会获得“奶”称号,而现在将不会有玩家获得“奶”称号)
19
+ - 修复无法获取群组相关信息导致的日报功能失效。
20
+ - 修复日报功能中统计组合有可能出现重复的问题。
21
+ <details>
22
+ <summary><b>1.2.7-beta更新日志</b></summary>
23
+
1
24
  ### 1.2.7-beta
2
- **新增**:可在配置页设置发布战报时附带stratz比赛链接、查询玩家信息时附带stratz玩家页面链接,这些选项均默认关闭。
3
- **修复**:(beta测试中) 尝试修复当同一个steamId在多个已订阅群组中绑定时,仅会向最早绑定的群组发送战报的问题。
4
- **修复**:现在若所有玩家某项属性都为0时不会错误地将对应称号赋予玩家1,而是取消此称号赋予。(此版本前例如所有玩家治疗量都为0,玩家1会获得“奶”称号,而现在将不会有玩家获得“奶”称号)
25
+ ##### **新增**:
26
+ - 可在配置页设置发布战报时附带stratz比赛链接、查询玩家信息时附带stratz玩家页面链接,这些选项均默认关闭。
27
+ ##### **修复**:
28
+ - (beta测试中) 尝试修复当同一个steamId在多个已订阅群组中绑定时,仅会向最早绑定的群组发送战报的问题。
29
+ - 现在若所有玩家某项属性都为0时不会错误地将对应称号赋予玩家1,而是取消此称号赋予。(此版本前例如所有玩家治疗量都为0,玩家1会获得“奶”称号,而现在将不会有玩家获得“奶”称号)
5
30
 
6
31
  #### beta.2
7
32
  **修复**:尝试修复无法获取群组相关信息导致的日报功能失效。
@@ -9,8 +34,18 @@
9
34
  #### beta.3
10
35
  **修复**:尝试修复日报功能中统计组合有可能出现重复的问题。
11
36
 
12
- ### 1.2.6
13
- 因koishi更新至4.17.10修复了主动发送消息的函数,本插件的发送消息方式也换回之前的方案以避免可能的代码问题。(功能使用上与1.2.6-pre3版本一致)
37
+ </details>
38
+
39
+ # 1.2.6
40
+ ##### 因koishi更新至4.17.10修复了主动发送消息的函数,本插件的发送消息方式也换回之前的方案以避免可能的代码问题。(功能使用上与1.2.6-pre3版本一致)
41
+
42
+ **改进&修复**:修复了`查询英雄`图片中 技能数值未被正确替换、全才英雄基础攻击力显示错误的问题,并优化了命石描述显示方式
43
+ **改进**:调整比赛战报图片样式:解析失败时显示的“第-手”改为“第?手”
44
+ **改进**:为英雄`艾欧`添加别名:["艾欧", "小精灵"] → ["艾欧", "小精灵", "精灵", "IO"]
45
+ **修复**:修复`查询玩家`图片中场次表现评分为0时显示为?的问题
46
+
47
+ <details>
48
+ <summary><b>1.2.6-pre更新日志</b></summary>
14
49
 
15
50
  ### 1.2.6-pre
16
51
  ##### (因koishi尚未更新发布pre版)
@@ -25,34 +60,36 @@
25
60
  **改进&修复**:继续优化`查询英雄`代码结构使由命石、神杖、魔晶改变的技能属性更直观;修复某些技能数据中有旧天赋加成数据留存、导致的天赋数值未被正确填充。
26
61
  **改进**:为英雄`艾欧`添加别名:["艾欧", "小精灵"] → ["艾欧", "小精灵", "精灵", "IO"]
27
62
 
28
- ### 1.2.5-fix
29
- **修复**:使用临时替代方案修复由koishi-4.17.9的bug引起的无法主动发送消息(播报战报等),待koishi更新修复后回滚此改动。
30
- #### fix3
31
- **修复**:修复日报使用时报错的问题。
63
+ </details>
32
64
 
33
- ### 1.2.5
65
+ # 1.2.5
34
66
  **改进**:优化`查询玩家`图片中近期战绩列表内未解析比赛的显示效果
35
67
  **修复**:修复`查询英雄`图片技能属性名多显示了一个冒号的问题
36
68
 
37
- ### 1.2.4
69
+ #### fix
70
+ **修复**:使用临时替代方案修复由koishi-4.17.9的bug引起的无法主动发送消息(播报战报等),待koishi更新修复后回滚此改动。
71
+ #### fix3
72
+ **修复**:修复使用替代方案导致日报失效的问题。
73
+
74
+ # 1.2.4
38
75
  **修复**:修正调用help指令时本插件某些指令的说明错误
39
76
  **修复**:修复`取消订阅`指令失效的问题
40
77
 
41
- ### 1.2.3
78
+ # 1.2.3
42
79
  **修复**:修复了比赛战报图片中称号`摸`判定不正确的问题
43
80
  **改进**:微调了比赛战报图片模板`match_2`中称号的显示样式
44
81
 
45
- ### 1.2.2
82
+ # 1.2.2
46
83
  **移除**:取消`查询英雄`的缓存功能,原因为valve的API返回的数据可能包含未本地化的字段(例如这次的7.36b更新后获取到的很多改动后技能说明暂时都是英文),这些数据无法根据版本判断是否需要更新缓存。
47
84
  **修复**:修复了`查询英雄`图片中某些命石提供技能可能被判定为先天技能的问题。
48
85
 
49
- ### 1.2.1
86
+ # 1.2.1
50
87
  **改进**:优化比赛战报图片中,对多个同种物品(例如双护腕双挂件一类)的出装时间显示进行优化,原先都将显示为最后一件此种物品的购买时间,现在可以显示不同的时间。
51
88
  > 从第一件购买时间算起,例如火枪于1:00 2:00 3:00购买了三个系带,游戏结束前卖出其中之一,则剩余两个则显示为1:00 2:00
52
89
 
53
90
  **改进**:出于实用性考虑,比赛战报图片中将不再显示辅助道具的购买时间。
54
91
 
55
- ### 1.2.0
92
+ # 1.2.0
56
93
  **改进**:对`查询英雄`模板代码进行了调整与部分重写,完成7.36版本的英雄数据匹配,现在可正常使用。
57
94
  > (人话说就是先天技能和命石适配完成了)
58
95
 
@@ -60,13 +97,13 @@
60
97
  #### hotfix
61
98
  **修复**:删除一些留存的测试用代码
62
99
 
63
- ### 1.1.10
100
+ # 1.1.10
64
101
  **修复**:修复`7.36`指令因DOTA2官网的cdn链接变动导致获取失败的问题,并优化了加载速度。
65
102
  **修复**:修复每次在koishi重新启动后,使用指令`7.36`都会重新获取数据的问题。
66
103
  #### hotfix
67
104
  **修复**:修复一处编译问题导致`7.36`指令无法使用的问题
68
105
 
69
- ### 1.1.9
106
+ # 1.1.9
70
107
  **新增**:v1.1.6加入的功能等待解析时间现在可以配置,位于插件页配置项`dataParsingTimeoutMinutes`
71
108
  **修复**:修复因v1.1.8修改数据获取方式导致的`绑定`指令失效
72
109
  **修复**:修复指令`查询英雄`报错问题(数据仍为7.35d,等待上游API更新)
@@ -76,36 +113,36 @@
76
113
  此版本前频道类平台应该无法使用战报功能与日报功能。此版本在订阅本群与绑定玩家时将存储channelId而不是guildID,对于非频道类平台这两个值是一样的,不会造成影响。但频道类平台应该会彻底失效,解决方案只有操作数据库,将channelId填入原先guildId处(兼容原因,未修改数据库字段名[guildId],但实际上存入的已经是channel的ID了;guildId和channelId可参考数据库表channel中的数据),或重新订阅与绑定。(若是重新订阅与绑定,不会覆盖原先存储guildId的数据,也就是说旧数据依然会存在,可根据需求选择是否删除)
77
114
  </details>
78
115
 
79
- ### 1.1.8
116
+ # 1.1.8
80
117
  **改进**:将数据获取方式从 npm 包 `axios` 切换为 Koishi 提供的 `http` 服务,并简化了相关代码(用户体验无差别)。
81
118
  **改进**:为 `match_2` 模板添加了玩家小队标识(效果与 `match_1` 模板中的相同功能一致,但在显示上进行了微调)。
82
119
 
83
- ### 1.1.7
120
+ # 1.1.7
84
121
  **改进**:玩家信息模板中代表位置的图标替换为简约风格图标
85
122
  **修复**:于v1.1.5新增的`7.36`指令生成英雄改动图片时会额外产生的测试用的`remainingContent.html`文件,现已不再生成。(如果之前使用了该命令并产生了此文件,可根据需要手动删除。位于`koishi/node_modules/@sjtdev/koishi-plugin-dota2tracker/`)
86
123
 
87
- ### 1.1.6
124
+ # 1.1.6
88
125
  由于近期stratz网站问题,比赛数据无法自动解析,导致bot会一直等待解析后的战报数据而无法发送。
89
126
  **新增**:现在调整为比赛结束1小时后仍然未解析时将直接发出缺失部分数据的战报(缺失包括BP顺序、出装时间、英雄受到伤害等)
90
127
  #### hotfix
91
128
  **修复**:修复引发播报未解析比赛战报失败的一个小问题
92
129
 
93
- ### 1.1.5
130
+ # 1.1.5
94
131
  **新增**:为新版本7.36添加新指令`7.36`
95
132
  `7.36 <英雄ID|英雄名|英雄常用别名>`可查询对应英雄的改动信息,未输入英雄查询参数时直接返回官网7.36更新日志链接
96
133
  添加`--refresh|-r`参数可强制重新获取数据,如`7.36 -r`,也可在查询时使用,如`7.36 敌法师 -r`
97
134
 
98
- ### 1.1.4
135
+ # 1.1.4
99
136
  **改进**:完善查询玩家指定英雄的生成模板
100
137
 
101
- ### 1.1.3
138
+ # 1.1.3
102
139
  **新增**:新增实验性功能【日报昨日总结】,在指定时间播报昨日已订阅群组中已绑定群友的战绩(简略文字),默认关闭,可在插件配置中打开
103
140
  `查询玩家`指令新增功能,现在额外输入参数`--hero <英雄ID|英雄名|英雄常用别名>`可查询目标玩家指定英雄的详情(--hero可替换为-o)
104
141
  例如:
105
142
  * `查询玩家 123456789 --hero 敌法师`
106
143
  * `查询玩家 -o 敌法师` (仍可缺省玩家参数以自查)
107
144
 
108
- ### 1.1.2
145
+ # 1.1.2
109
146
  **改进**:完成查询群友功能
110
147
  **修复**:修复玩家模板中显示NaN的部分
111
148
  #### hotfix
@@ -117,9 +154,9 @@
117
154
  ### 1.1.2-beta
118
155
  **改进**:为`查询群友`添加模板,还在调整布局中
119
156
 
120
- ### 1.1.1
157
+ # 1.1.1
121
158
  **改进**:玩家信息模板添加近25场内各个位置表现展示
122
159
 
123
- ### 1.1.0
160
+ # 1.1.0
124
161
  **改进**:使用ejs重写模板相关代码使其模块化,使新增模板更方便
125
162
  **新增**:为比赛信息添加了仿MAX+模板,效果可见[match_2](https://github.com/sjtdev/koishi-plugin-dota2tracker/wiki/match_2),可在插件配置中切换
package/lib/index.js CHANGED
@@ -310,7 +310,10 @@ function PLAYER_INFO_WITH_25_MATCHES(steamAccountId, heroId) {
310
310
  bottomLaneOutcome
311
311
  radiantKills
312
312
  direKills
313
- players(steamAccountId: ${steamAccountId}) {
313
+ players {
314
+ steamAccount {
315
+ id
316
+ }
314
317
  isRadiant
315
318
  lane
316
319
  kills
@@ -1216,7 +1219,11 @@ var Config = import_koishi.Schema.intersect([
1216
1219
  ]),
1217
1220
  import_koishi.Schema.object({
1218
1221
  urlInMessageType: import_koishi.Schema.array(
1219
- import_koishi.Schema.union([import_koishi.Schema.const("match").description("在查询比赛与战报消息中附带stratz比赛链接"), import_koishi.Schema.const("player").description("在查询玩家信息消息中附带stratz玩家链接"), import_koishi.Schema.const("hero").description("---").disabled()])
1222
+ import_koishi.Schema.union([
1223
+ import_koishi.Schema.const("match").description("在查询比赛与战报消息中附带stratz比赛页面链接"),
1224
+ import_koishi.Schema.const("player").description("在查询玩家信息消息中附带stratz玩家页面链接"),
1225
+ import_koishi.Schema.const("hero").description("在查询英雄数据消息中附带刀塔百科对应英雄页面链接")
1226
+ ])
1220
1227
  ).role("checkbox").description("在消息中附带链接,<br/>请选择消息类型:")
1221
1228
  }),
1222
1229
  import_koishi.Schema.object({
@@ -1416,7 +1423,7 @@ async function apply(ctx, config) {
1416
1423
  }
1417
1424
  });
1418
1425
  ctx.command("查询玩家 <input_data>", "查询玩家信息,可指定英雄").usage("查询指定玩家的个人信息与最近战绩,生成图片发布。\n参数可输入该玩家的SteamID或已在本群绑定玩家的别名,无参数时尝试查询调用指令玩家的SteamID").option("hero", "-o <value:string> 查询玩家指定英雄使用情况(同其他英雄查询,可用简称与ID)").example("查询玩家 123456789").example("查询玩家 张三").example("查询玩家 张三 hero 敌法师").action(async ({ session, options }, input_data) => {
1419
- if (session.guild) {
1426
+ if (session.guild || !session.guild && input_data) {
1420
1427
  let sessionPlayer;
1421
1428
  if (!input_data) {
1422
1429
  sessionPlayer = (await ctx.database.get("dt_subscribed_players", { guildId: session.event.channel.id, platform: session.event.platform, userId: session.event.user.id }))[0];
@@ -1482,6 +1489,8 @@ async function apply(ctx, config) {
1482
1489
  ctx.logger.error(error);
1483
1490
  session.send("获取玩家信息失败。");
1484
1491
  }
1492
+ } else {
1493
+ session.send("<p>指令调用失败。</p><p>当前不属于群聊状态,必须提供指定玩家的SteamID。</p>");
1485
1494
  }
1486
1495
  });
1487
1496
  ctx.command("查询英雄 <input_data>", "查询英雄技能/面板信息").usage("查询英雄的技能说明与各项数据,生成图片发布。\n参数可输入英雄ID、英雄名、英雄常用别名").option("random", "-r 随机选择英雄").example("查询英雄 15").example("查询英雄 雷泽").example("查询英雄 电魂").action(async ({ session, options }, input_data) => {
@@ -1565,7 +1574,9 @@ async function apply(ctx, config) {
1565
1574
  }
1566
1575
  }
1567
1576
  });
1568
- await session.send(await ctx.puppeteer.render(genImageHTML(hero, config.template_hero, "hero" /* Hero */)));
1577
+ await session.send(
1578
+ (ctx.config.urlInMessageType.some((type) => type == "hero") ? `https://wiki.dota2.com.cn/hero/${hero.shortName}.html` : "") + await ctx.puppeteer.render(genImageHTML(hero, config.template_hero, "hero" /* Hero */))
1579
+ );
1569
1580
  } catch (error) {
1570
1581
  ctx.logger.error(error);
1571
1582
  session.send("获取数据失败");
@@ -1775,17 +1786,18 @@ async function apply(ctx, config) {
1775
1786
  let idsToFind = commingGuild.players.map((player) => player.steamId);
1776
1787
  let broadPlayers = match.players.filter((item) => idsToFind.includes(item.steamAccountId));
1777
1788
  for (let player of broadPlayers) {
1778
- let broadPlayerMessage = `${player.steamAccount.name}的${random.pick(HEROES_CHINESE[player.hero.id])}`;
1789
+ const random2 = new import_koishi2.Random(() => simpleHashToSeed(match.id, player.steamAccountId));
1790
+ let broadPlayerMessage = `${player.steamAccount.name}的${random2.pick(HEROES_CHINESE[player.hero.id])}`;
1779
1791
  if (player.isRadiant == match.didRadiantWin) {
1780
1792
  if (player.deathContribution < 0.2 || player.killContribution > 0.75 || player.heroDamage / player.networth > 1.5 || player.towerDamage > 1e4 || player.imp > 0)
1781
- broadPlayerMessage += random.pick(WIN_POSITIVE);
1793
+ broadPlayerMessage += random2.pick(WIN_POSITIVE);
1782
1794
  else
1783
- broadPlayerMessage += random.pick(WIN_NEGATIVE);
1795
+ broadPlayerMessage += random2.pick(WIN_NEGATIVE);
1784
1796
  } else {
1785
1797
  if (player.deathContribution < 0.25 || player.killContribution > 0.75 || player.heroDamage / player.networth > 1.25 || player.towerDamage > 5e3 || player.imp > 0)
1786
- broadPlayerMessage += random.pick(LOSE_POSITIVE);
1798
+ broadPlayerMessage += random2.pick(LOSE_POSITIVE);
1787
1799
  else
1788
- broadPlayerMessage += random.pick(LOSE_NEGATIVE);
1800
+ broadPlayerMessage += random2.pick(LOSE_NEGATIVE);
1789
1801
  }
1790
1802
  broadPlayerMessage += `。
1791
1803
  KDA:${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)} [${player.kills}/${player.deaths}/${player.assists}],GPM/XPM:${player.goldPerMinute}/${player.experiencePerMinute},补刀数:${player.numLastHits}/${player.numDenies},伤害/塔伤:${player.heroDamage}/${player.towerDamage},参战/参葬率:${(player.killContribution * 100).toFixed(2)}%/${(player.deathContribution * 100).toFixed(2)}%`;
@@ -1832,6 +1844,16 @@ function genImageHTML(data, template, type) {
1832
1844
  return result;
1833
1845
  }
1834
1846
  __name(genImageHTML, "genImageHTML");
1847
+ function simpleHashToSeed(matchId, playerId) {
1848
+ const input = `${matchId}-${playerId}`;
1849
+ const encoded = btoa(input);
1850
+ let total = 0;
1851
+ for (let i = 0; i < encoded.length; i++) {
1852
+ total += encoded.charCodeAt(i);
1853
+ }
1854
+ return total % 1e3 / 1e3;
1855
+ }
1856
+ __name(simpleHashToSeed, "simpleHashToSeed");
1835
1857
  // Annotate the CommonJS export names for ESM import in node:
1836
1858
  0 && (module.exports = {
1837
1859
  Config,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sjtdev/koishi-plugin-dota2tracker",
3
3
  "description": "koishi插件-追踪群友的DOTA2对局",
4
- "version": "1.2.7-beta.3",
4
+ "version": "1.2.8-pre",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -338,7 +338,7 @@
338
338
  nearWinCount = 0,
339
339
  streak = 0;
340
340
  player.matches.forEach((match) => {
341
- const innerPlayer = match.players[0];
341
+ const innerPlayer = match.players.find(innerPlayer=>player.steamAccount.id==innerPlayer.steamAccount.id);
342
342
  nearWinCount += match.didRadiantWin == innerPlayer.isRadiant ? 1 : 0;
343
343
  const didWin = match.didRadiantWin === innerPlayer.isRadiant;
344
344
  if (!player.streak) {
@@ -387,15 +387,15 @@
387
387
  // 瞎j8定义的各位置代表物品,以后看情况调整
388
388
  const positionIcons = ["damage","nuke","armor","speed","healing"];
389
389
  for (let index = 0; index < 5; index++) {
390
- let currentPositionMatches = player.matches.filter(match=>match.players[0].position == ("POSITION_"+(index+1)))
391
- let winCount = currentPositionMatches.filter(match=>match.didRadiantWin == match.players[0].isRadiant).length;
390
+ let currentPositionMatches = player.matches.filter(match=>match.players.find(innerPlayer=>player.steamAccount.id==innerPlayer.steamAccount.id).position == ("POSITION_"+(index+1)))
391
+ let winCount = currentPositionMatches.filter(match=>match.didRadiantWin == match.players.find(innerPlayer=>player.steamAccount.id==innerPlayer.steamAccount.id).isRadiant).length;
392
392
  player.positionPerformance.push({
393
393
  position : (index + 1),
394
394
  icon : positionIcons[index],
395
395
  matchCount : currentPositionMatches.length,
396
396
  winCount : winCount,
397
397
  loseCount : currentPositionMatches.length - winCount,
398
- imp : currentPositionMatches.length>0? Math.round(currentPositionMatches.reduce((acc,match)=>acc+match.players[0].imp,0)/currentPositionMatches.length):"-"
398
+ imp : currentPositionMatches.length>0? Math.round(currentPositionMatches.reduce((acc,match)=>acc+match.players.find(innerPlayer=>player.steamAccount.id==innerPlayer.steamAccount.id).imp,0)/currentPositionMatches.length):"-"
399
399
  })
400
400
  }
401
401
  const highestCountsPosition = {
@@ -504,7 +504,12 @@
504
504
  </thead>
505
505
  <tbody>
506
506
  <%- player.matches.map((match) => {
507
- const innerPlayer = match.players[0];
507
+ const innerPlayer = match.players.find(innerPlayer => player.steamAccount.id == innerPlayer.steamAccount.id);
508
+ innerPlayer.teamKillsCount = match.parsedDateTime ?
509
+ (match[(innerPlayer.isRadiant ? "radiant" : "dire") + "Kills"]?.reduce((acc, cva) => acc + cva, 0) ?? 0) :
510
+ match.players
511
+ .filter(p => p.isRadiant === innerPlayer.isRadiant)
512
+ .reduce((k, p) => k + p.kills, 0);
508
513
  return `
509
514
  <tr class="match ${match.didRadiantWin == innerPlayer.isRadiant ? "win" : "lose"}">
510
515
  <td>${match.parsedDateTime ? match.id : `<p>${match.id}</p><p>(未解析)</p>`}</td>
@@ -514,8 +519,8 @@
514
519
  </td>
515
520
  <td><img alt="" src="${utils.getImageUrl(innerPlayer.hero.shortName, ImageType.HeroIcons)}" /></td>
516
521
  <td style="line-height: 20px">
517
- <p>${((innerPlayer.kills + innerPlayer.assists) / Math.max(1, innerPlayer.deaths)).toFixed(2)} (${match.parsedDateTime?((((innerPlayer.kills + innerPlayer.assists) /
518
- (match[(innerPlayer.isRadiant ? "radiant" : "dire")+"Kills"]?.reduce((acc, cva) => acc + cva, 0))) * 100)?.toFixed(0)):"?"}%)</p>
522
+ <p>${((innerPlayer.kills + innerPlayer.assists) / Math.max(1, innerPlayer.deaths)).toFixed(2)} (${(match.parsedDateTime?"":"≈")+((((innerPlayer.kills + innerPlayer.assists) /
523
+ innerPlayer.teamKillsCount) * 100)?.toFixed(0))}%)</p>
519
524
  <p>${innerPlayer.kills}/${innerPlayer.deaths}/${innerPlayer.assists}</p>
520
525
  </td>
521
526
  <td><div class="player_lane ${match.laneResult}">${laneSVG[match.laneResult]}</div></td>