@sjtdev/koishi-plugin-dota2tracker 1.1.5 → 1.1.7
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 +87 -74
- package/package.json +1 -1
- package/readme.md +19 -11
- package/template/match/match_1.ejs +6 -6
- package/template/match/match_2.ejs +4 -4
- package/template/player/player_1.ejs +3 -3
package/lib/index.js
CHANGED
|
@@ -254,60 +254,60 @@ function PLAYER_INFO_WITH_25_MATCHES(steamAccountId, heroId) {
|
|
|
254
254
|
{
|
|
255
255
|
player(steamAccountId: ${steamAccountId}) {
|
|
256
256
|
steamAccount {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
257
|
+
avatar
|
|
258
|
+
name
|
|
259
|
+
seasonRank
|
|
260
|
+
seasonLeaderboardRank
|
|
261
|
+
id
|
|
262
262
|
}
|
|
263
263
|
guildMember {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
264
|
+
guild {
|
|
265
|
+
tag
|
|
266
|
+
}
|
|
267
267
|
}
|
|
268
268
|
matchCount
|
|
269
269
|
winCount
|
|
270
270
|
performance {
|
|
271
|
-
|
|
271
|
+
imp
|
|
272
272
|
}
|
|
273
273
|
heroesPerformance(take: 25, request: {matchGroupOrderBy: WIN_COUNT take: 25 ${heroId ? "heroIds:" + heroId : ""}}) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
274
|
+
hero {
|
|
275
|
+
id
|
|
276
|
+
shortName
|
|
277
|
+
}
|
|
278
|
+
imp
|
|
279
|
+
winCount
|
|
280
|
+
matchCount
|
|
281
281
|
}
|
|
282
282
|
matches(request: {take: 25 ${heroId ? "heroIds:" + heroId : ""}}) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
283
|
+
id
|
|
284
|
+
rank
|
|
285
|
+
lobbyType
|
|
286
|
+
gameMode
|
|
287
|
+
startDateTime
|
|
288
|
+
durationSeconds
|
|
289
|
+
didRadiantWin
|
|
290
|
+
topLaneOutcome
|
|
291
|
+
midLaneOutcome
|
|
292
|
+
bottomLaneOutcome
|
|
293
|
+
radiantKills
|
|
294
|
+
direKills
|
|
295
|
+
players(steamAccountId: ${steamAccountId}) {
|
|
296
|
+
isRadiant
|
|
297
|
+
lane
|
|
298
|
+
kills
|
|
299
|
+
deaths
|
|
300
|
+
assists
|
|
301
|
+
position
|
|
302
|
+
award
|
|
303
|
+
imp
|
|
304
|
+
hero {
|
|
305
|
+
id
|
|
306
|
+
shortName
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
311
|
|
|
312
312
|
}
|
|
313
313
|
|
|
@@ -500,6 +500,7 @@ async function testGetHtml(URL) {
|
|
|
500
500
|
__name(testGetHtml, "testGetHtml");
|
|
501
501
|
var ImageType = /* @__PURE__ */ ((ImageType2) => {
|
|
502
502
|
ImageType2["Icons"] = "icons";
|
|
503
|
+
ImageType2["IconsFacets"] = "icons/facets";
|
|
503
504
|
ImageType2["Heroes"] = "heroes";
|
|
504
505
|
ImageType2["HeroIcons"] = "heroes/icons";
|
|
505
506
|
ImageType2["Items"] = "items";
|
|
@@ -525,11 +526,21 @@ function getFormattedMatchData(match) {
|
|
|
525
526
|
["radiant", "dire"].forEach((team) => {
|
|
526
527
|
match[team] = { killsCount: match[team + "Kills"]?.reduce((acc, cva) => acc + cva, 0) ?? 0, damageReceived: 0, heroDamage: 0, networth: 0, experience: 0 };
|
|
527
528
|
});
|
|
529
|
+
if (!match.parsedDateTime) {
|
|
530
|
+
match.players.reduce((acc, player) => {
|
|
531
|
+
if (player.isRadiant) {
|
|
532
|
+
acc.radiant.killsCount += player.kills;
|
|
533
|
+
} else {
|
|
534
|
+
acc.dire.killsCount += player.kills;
|
|
535
|
+
}
|
|
536
|
+
return acc;
|
|
537
|
+
}, match);
|
|
538
|
+
}
|
|
528
539
|
match.party = {};
|
|
529
540
|
let party_index = 0;
|
|
530
541
|
const party_mark = ["I", "II", "III", "IV"];
|
|
531
542
|
let heroOrderList = {};
|
|
532
|
-
for (let hero of match.pickBans) {
|
|
543
|
+
for (let hero of match.pickBans ?? []) {
|
|
533
544
|
if (hero.isPick)
|
|
534
545
|
heroOrderList[hero.heroId] = hero.order;
|
|
535
546
|
}
|
|
@@ -561,27 +572,29 @@ function getFormattedMatchData(match) {
|
|
|
561
572
|
};
|
|
562
573
|
player.killContribution = (player.kills + player.assists) / match[player.team].killsCount;
|
|
563
574
|
player.deathContribution = player.deaths / match[player.team === "radiant" ? "dire" : player.team].killsCount;
|
|
564
|
-
player.damageReceived = player.stats?.heroDamageReport?.receivedTotal
|
|
575
|
+
player.damageReceived = (player.stats?.heroDamageReport?.receivedTotal?.physicalDamage ?? 0) + (player.stats?.heroDamageReport?.receivedTotal?.magicalDamage ?? 0) + (player.stats?.heroDamageReport?.receivedTotal?.pureDamage ?? 0);
|
|
565
576
|
match[player.team].heroDamage = (match[player.team].heroDamage ?? 0) + player.heroDamage;
|
|
566
577
|
match[player.team].damageReceived = (match[player.team].damageReceived ?? 0) + player.damageReceived;
|
|
567
578
|
match[player.team].networth += player.networth;
|
|
568
579
|
match[player.team].experience += Math.floor(player.experiencePerMinute / 60 * match.durationSeconds);
|
|
569
580
|
player.titles = [];
|
|
570
581
|
player.mvpScore = // 计算MVP分数
|
|
571
|
-
player.kills * 5 + player.assists * 3 + player.stats.heroDamageReport
|
|
582
|
+
player.kills * 5 + player.assists * 3 + (player.stats.heroDamageReport?.dealtTotal.stunDuration ?? 0) / 100 * 0.1 + (player.stats.heroDamageReport?.dealtTotal.disableDuration ?? 0) / 100 * 0.05 + (player.stats.heroDamageReport?.dealtTotal.slowDuration ?? 0) / 100 * 0.025 + player.heroDamage * 1e-3 + player.towerDamage * 0.01 + player.heroHealing * 2e-3 + player.imp * 0.25;
|
|
572
583
|
player.order = heroOrderList[player.hero.id];
|
|
573
584
|
if (player.partyId != null) {
|
|
574
585
|
if (!match.party[player.partyId])
|
|
575
586
|
match.party[player.partyId] = party_mark[party_index++];
|
|
576
587
|
}
|
|
577
|
-
|
|
578
|
-
const
|
|
579
|
-
|
|
580
|
-
acc[key]
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
588
|
+
if (match.parsedDateTime) {
|
|
589
|
+
const maxStackCountsByAbilityOrItem = player.stats.matchPlayerBuffEvent.reduce((acc, event) => {
|
|
590
|
+
const key = event.abilityId !== null ? `ability-${event.abilityId}` : `item-${event.itemId}`;
|
|
591
|
+
if (!acc[key] || event.stackCount > acc[key].stackCount) {
|
|
592
|
+
acc[key] = event;
|
|
593
|
+
}
|
|
594
|
+
return acc;
|
|
595
|
+
}, {});
|
|
596
|
+
player.stats.matchPlayerBuffEvent.splice(0, player.stats.matchPlayerBuffEvent.length, ...Object.values(maxStackCountsByAbilityOrItem));
|
|
597
|
+
}
|
|
585
598
|
switch (player.lane) {
|
|
586
599
|
case "SAFE_LANE":
|
|
587
600
|
player.laneResult = laneResult[player.isRadiant ? "bottom" : "top"][player.team];
|
|
@@ -726,18 +739,20 @@ function getFormattedMatchData(match) {
|
|
|
726
739
|
).titles.push({ name: "魂", color: "#6cf" });
|
|
727
740
|
findMaxByProperty("networth").titles.push({ name: "富", color: "#FFD700" });
|
|
728
741
|
findMaxByProperty("experiencePerMinute").titles.push({ name: "睿", color: "#8888FF" });
|
|
729
|
-
match.
|
|
730
|
-
|
|
731
|
-
|
|
742
|
+
if (match.parsedDateTime) {
|
|
743
|
+
match.players.reduce(
|
|
744
|
+
(max, player) => player.stats.heroDamageReport.dealtTotal.stunDuration + player.stats.heroDamageReport.dealtTotal.disableDuration / 2 + player.stats.heroDamageReport.dealtTotal.slowDuration / 4 > max.stats.heroDamageReport.dealtTotal.stunDuration + max.stats.heroDamageReport.dealtTotal.disableDuration / 2 + max.stats.heroDamageReport.dealtTotal.slowDuration / 4 ? player : max
|
|
745
|
+
).titles.push({ name: "控", color: "#FF00FF" });
|
|
746
|
+
match.players.reduce(
|
|
747
|
+
(max, player) => player.stats.heroDamageReport.receivedTotal.physicalDamage + player.stats.heroDamageReport.receivedTotal.magicalDamage + player.stats.heroDamageReport.receivedTotal.pureDamage > max.stats.heroDamageReport.receivedTotal.physicalDamage + max.stats.heroDamageReport.receivedTotal.magicalDamage + max.stats.heroDamageReport.receivedTotal.pureDamage ? player : max
|
|
748
|
+
).titles.push({ name: "耐", color: "#84A1C7" });
|
|
749
|
+
}
|
|
732
750
|
findMaxByProperty("heroDamage").titles.push({ name: "爆", color: "#CC0088" });
|
|
733
751
|
findMaxByProperty("kills", "heroDamage").titles.push({ name: "破", color: "#DD0000" });
|
|
734
752
|
findMaxByProperty("deaths", "networth", void 0, void 0, "min" /* Min */).titles.push({ name: "鬼", color: "#CCCCCC" });
|
|
735
753
|
findMaxByProperty("assists", "heroDamage").titles.push({ name: "助", color: "#006400" });
|
|
736
754
|
findMaxByProperty("towerDamage", "heroDamage").titles.push({ name: "拆", color: "#FEDCBA" });
|
|
737
755
|
findMaxByProperty("heroHealing").titles.push({ name: "奶", color: "#00FF00" });
|
|
738
|
-
match.players.reduce(
|
|
739
|
-
(max, player) => player.stats.heroDamageReport.receivedTotal.physicalDamage + player.stats.heroDamageReport.receivedTotal.magicalDamage + player.stats.heroDamageReport.receivedTotal.pureDamage > max.stats.heroDamageReport.receivedTotal.physicalDamage + max.stats.heroDamageReport.receivedTotal.magicalDamage + max.stats.heroDamageReport.receivedTotal.pureDamage ? player : max
|
|
740
|
-
).titles.push({ name: "耐", color: "#84A1C7" });
|
|
741
756
|
match.players.reduce((lowest, player) => {
|
|
742
757
|
const currentContribution = (player.kills + player.assists) / match[player.team].KillsCount;
|
|
743
758
|
const lowestContribution = (lowest.kills + lowest.assists) / match[lowest.team].KillsCount;
|
|
@@ -1094,7 +1109,7 @@ var ejs = __toESM(require("ejs"));
|
|
|
1094
1109
|
var name = "dota2tracker";
|
|
1095
1110
|
var usage = `
|
|
1096
1111
|
DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑定),以及一系列查询功能。
|
|
1097
|
-
|
|
1112
|
+
**更多信息请进入插件主页(github本项目仓库)查看。**`;
|
|
1098
1113
|
var inject = ["database", "puppeteer", "cron"];
|
|
1099
1114
|
var Config = import_koishi.Schema.intersect([
|
|
1100
1115
|
import_koishi.Schema.object({
|
|
@@ -1249,9 +1264,10 @@ async function apply(ctx, config) {
|
|
|
1249
1264
|
match = getFormattedMatchData(queryRes.data.data.match);
|
|
1250
1265
|
}
|
|
1251
1266
|
}
|
|
1252
|
-
if (match && match.parsedDateTime) {
|
|
1267
|
+
if (match && (match.parsedDateTime || import_moment.default.unix(match.endDateTime).isBefore((0, import_moment.default)().subtract(1, "hours")))) {
|
|
1253
1268
|
session.send(await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */)));
|
|
1254
|
-
|
|
1269
|
+
if (match.parsedDateTime)
|
|
1270
|
+
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: match.id, data: match, queryTime: /* @__PURE__ */ new Date() }]);
|
|
1255
1271
|
} else {
|
|
1256
1272
|
pendingMatches.push({ matchId, guilds: [{ platform: session.event.platform, guildId: session.event.guild.id, players: [] }] });
|
|
1257
1273
|
session.send("比赛尚未解析,将在解析完成后发布。");
|
|
@@ -1477,7 +1493,7 @@ async function apply(ctx, config) {
|
|
|
1477
1493
|
});
|
|
1478
1494
|
});
|
|
1479
1495
|
let heroes3 = Array.from(mergedMap.values());
|
|
1480
|
-
return heroes3.find((hero) => hero.names_cn.
|
|
1496
|
+
return heroes3.find((hero) => hero.names_cn.some((cn) => cn.toLowerCase() == input.toLowerCase()) || hero.shortName === input.toLowerCase() || hero.id == input);
|
|
1481
1497
|
}
|
|
1482
1498
|
__name(findingHero, "findingHero");
|
|
1483
1499
|
ctx.command("7.36 <input_data>", "查询7.36改动").option("refresh", "-r 重新获取数据").usage("可查询英雄改动并生成图片返回").example("7.36 小松许").action(async ({ session, options }, input_data) => {
|
|
@@ -1517,7 +1533,6 @@ async function apply(ctx, config) {
|
|
|
1517
1533
|
});
|
|
1518
1534
|
heroes3.push({ id: 0, data: result.remainingContent });
|
|
1519
1535
|
await ctx.database.upsert("dt_7_36", (row) => heroes3);
|
|
1520
|
-
import_fs2.default.writeFileSync("./node_modules/@sjtdev/koishi-plugin-dota2tracker/remainingContent.html", result.remainingContent);
|
|
1521
1536
|
await session.send("数据获取完成。");
|
|
1522
1537
|
await page.close();
|
|
1523
1538
|
}
|
|
@@ -1574,9 +1589,6 @@ async function apply(ctx, config) {
|
|
|
1574
1589
|
} else
|
|
1575
1590
|
session.send("https://www.dota2.com/patches/7.36");
|
|
1576
1591
|
});
|
|
1577
|
-
ctx.command("test <input_data>").option("a", "a").action(async ({ session, options }, input_data) => {
|
|
1578
|
-
console.log((await ctx.database.get("dt_7_36", [0]))[0].data);
|
|
1579
|
-
});
|
|
1580
1592
|
ctx.on("ready", async () => {
|
|
1581
1593
|
const tables = await ctx.database.tables;
|
|
1582
1594
|
if (!("dt_subscribed_guilds" in tables)) {
|
|
@@ -1713,10 +1725,10 @@ async function apply(ctx, config) {
|
|
|
1713
1725
|
} else {
|
|
1714
1726
|
let queryRes = await query(MATCH_INFO(pendingMatch.matchId));
|
|
1715
1727
|
if (queryRes.status == 200) {
|
|
1716
|
-
match =
|
|
1728
|
+
match = getFormattedMatchData(queryRes.data.data.match);
|
|
1717
1729
|
}
|
|
1718
1730
|
}
|
|
1719
|
-
if (match.parsedDateTime || import_moment.default.unix(match.
|
|
1731
|
+
if (match.parsedDateTime || import_moment.default.unix(match.endDateTime).isBefore((0, import_moment.default)().subtract(1, "hours"))) {
|
|
1720
1732
|
pendingMatches = pendingMatches.filter((item) => item.matchId != match.id);
|
|
1721
1733
|
const img = await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */));
|
|
1722
1734
|
for (let commingGuild of pendingMatch.guilds) {
|
|
@@ -1741,9 +1753,10 @@ KDA:${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)} [${
|
|
|
1741
1753
|
broadMatchMessage += broadPlayerMessage + "\n";
|
|
1742
1754
|
}
|
|
1743
1755
|
await ctx.broadcast([`${commingGuild.platform}:${commingGuild.guildId}`], broadMatchMessage + img);
|
|
1744
|
-
ctx.logger.info(
|
|
1756
|
+
ctx.logger.info(`${match.id}${match.parsedDateTime ? "已解析," : "已结束超过1小时仍未被解析,放弃解析直接"}生成图片并发布于${commingGuild.platform}:${commingGuild.guildId}。`);
|
|
1745
1757
|
}
|
|
1746
|
-
|
|
1758
|
+
if (match.parsedDateTime)
|
|
1759
|
+
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: match.id, data: match, queryTime: /* @__PURE__ */ new Date() }]);
|
|
1747
1760
|
ctx.database.create("dt_sended_match_id", { matchId: match.id, sendTime: /* @__PURE__ */ new Date() });
|
|
1748
1761
|
} else
|
|
1749
1762
|
ctx.logger.info("比赛 %d 尚未解析完成,继续等待。", match.id);
|
|
@@ -1769,7 +1782,7 @@ function genImageHTML(data, template, type) {
|
|
|
1769
1782
|
moment: import_moment.default
|
|
1770
1783
|
};
|
|
1771
1784
|
let result = "";
|
|
1772
|
-
ejs.renderFile(templatePath, templateData, (err, html) => {
|
|
1785
|
+
ejs.renderFile(templatePath, templateData, { strict: false }, (err, html) => {
|
|
1773
1786
|
if (err)
|
|
1774
1787
|
throw err;
|
|
1775
1788
|
else
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -17,27 +17,35 @@ DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑
|
|
|
17
17
|
指令 <必填参数> [可选参数]
|
|
18
18
|
##### 订阅
|
|
19
19
|
(bot仅向已订阅群组推送信息)
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* `订阅本群`
|
|
21
|
+
* `取消订阅`
|
|
22
22
|
##### 绑定
|
|
23
23
|
(bot会追踪每位绑定玩家的最新对局)
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* `绑定 <玩家SteamID> [玩家别名]`
|
|
25
|
+
* `取消绑定`
|
|
26
|
+
* `改名 <新玩家别名>`
|
|
27
27
|
##### 查询
|
|
28
|
-
*
|
|
28
|
+
* `查询玩家 [SteamID|别名] [<--hero|-o> <英雄ID|英雄名|英雄常用别名>]`
|
|
29
29
|
返回一张图片,包含玩家各类信息。(缺省参数时并且调用者已绑定将自查)(输入--hero或-o并跟上查询英雄的参数时,将查询玩家指定英雄)
|
|
30
|
-
*
|
|
30
|
+
* `查询比赛 <比赛ID>`
|
|
31
31
|
返回一张图片,包含比赛对战信息。
|
|
32
|
-
*
|
|
32
|
+
* `查询最近比赛 [SteamID|别名]`
|
|
33
33
|
查询指定玩家的最近一场比赛,效果同上。(缺省参数时并且调用者已绑定将自查)
|
|
34
|
-
*
|
|
34
|
+
* `查询英雄 <英雄ID|英雄名|英雄常用别名>`
|
|
35
35
|
返回一张图片,包含英雄属性与技能详情。(此处英雄名为中文名)
|
|
36
|
-
* <
|
|
36
|
+
* <del>`查询英雄对战 <英雄ID|英雄名|英雄常用别名>`</del>
|
|
37
37
|
好像不是很实用
|
|
38
|
+
* `7.36 [英雄ID|英雄名|英雄常用别名] [--refresh|-r]`
|
|
39
|
+
查询官网7.36更新日志中指定英雄的改动信息
|
|
40
|
+
无英雄参数时直接返回官网7.36更新日志网址
|
|
41
|
+
首次使用时将缓存更新日志网页,若读取失败或出错,可添加`--refresh`或`-r`指令重新缓存
|
|
42
|
+
|
|
43
|
+
### 英雄ID|英雄名|英雄常用别名 列表
|
|
44
|
+
[dotaconstants_add.json](https://github.com/sjtdev/koishi-plugin-dota2tracker/blob/master/src/dotaconstants_add.json#L102-L226)
|
|
45
|
+
补充或纠错请提issue
|
|
38
46
|
|
|
39
47
|
### 图片模板列表
|
|
40
|
-
展示见[wiki](
|
|
48
|
+
展示见[wiki](https://github.com/sjtdev/koishi-plugin-dota2tracker/wiki)
|
|
41
49
|
生成图片已使用ejs模板实现,所有模板都在[template]文件夹下,若是有大佬想自己设计模板欢迎联系我完善数据接口。(当前有很多在模板中后处理的数据,不是很友好)
|
|
42
50
|
|
|
43
51
|
### 其他问题
|
|
@@ -718,7 +718,7 @@
|
|
|
718
718
|
<img alt="" src="${utils.getImageUrl(player.hero.shortName, ImageType.Heroes)}" />
|
|
719
719
|
<p class="party_line${player.partyId != null ? " party_" + match.party[player.partyId] : ""}"></p>
|
|
720
720
|
<p class="party_mark${player.partyId != null ? " party_" + match.party[player.partyId] : ""}"></p>
|
|
721
|
-
<p class="position p${Math.floor(player.order / 4) + 1}">${player.isRandom ? "随机" : `第<span>${player.order == null ? "-" : player.order + 1}</span>手`}<br/>${d2a.position[player.position?.slice(-1)]}</p>
|
|
721
|
+
<p class="position p${Math.floor(player.order / 4) + 1}">${player.isRandom ? "随机" : `第<span>${player.order == null ? "-" : player.order + 1}</span>手`}<br/>${d2a.position[player.position?.slice(-1)]??""}</p>
|
|
722
722
|
<p class="level">${player.level}</p>
|
|
723
723
|
</div>
|
|
724
724
|
<div class="player_info">
|
|
@@ -804,7 +804,7 @@
|
|
|
804
804
|
<p>${buff.stackCount ?? ""}</p>
|
|
805
805
|
</div>`
|
|
806
806
|
)
|
|
807
|
-
.join("")}
|
|
807
|
+
.join("")??""}
|
|
808
808
|
</section>
|
|
809
809
|
<section>
|
|
810
810
|
<div class="support_item"${player.supportItemsCount[30] > 0 ? "" : ' style="display:none"'}>
|
|
@@ -946,19 +946,19 @@
|
|
|
946
946
|
<section>英雄伤害:<span class="hero_damage">${player.heroDamage}</span></section>
|
|
947
947
|
<section>建筑伤害:<span class="building_damage">${player.towerDamage}</span></section>
|
|
948
948
|
<section>受到伤害(减免后):<span class="tak">${
|
|
949
|
-
player.stats?.heroDamageReport?.receivedTotal.physicalDamage + player.stats?.heroDamageReport?.receivedTotal.magicalDamage + player.stats?.heroDamageReport?.receivedTotal.pureDamage
|
|
949
|
+
(player.stats?.heroDamageReport?.receivedTotal.physicalDamage??0) + (player.stats?.heroDamageReport?.receivedTotal.magicalDamage??0) + (player.stats?.heroDamageReport?.receivedTotal.pureDamage??0)
|
|
950
950
|
}</span></section>
|
|
951
951
|
<section>补刀:<span class="lh">${player.numLastHits}</span>/<span class="dn">${player.numDenies}</span></section>
|
|
952
952
|
<section>GPM/XPM:<span class="gpm">${player.goldPerMinute}</span>/<span class="xpm">${player.experiencePerMinute}</span></section>
|
|
953
953
|
<section>治疗量:<span class="heal">${player.heroHealing}</span></section>
|
|
954
|
-
<section>控制时间:<span class="building_damage">${(player.stats?.heroDamageReport?.dealtTotal.stunDuration / 100).toFixed(2)}/${(player.stats?.heroDamageReport?.dealtTotal.slowDuration / 100).toFixed(2)}/${(
|
|
955
|
-
player.stats?.heroDamageReport?.dealtTotal.disableDuration / 100
|
|
954
|
+
<section>控制时间:<span class="building_damage">${((player.stats?.heroDamageReport?.dealtTotal.stunDuration ?? 0) / 100).toFixed(2)}/${((player.stats?.heroDamageReport?.dealtTotal.slowDuration ?? 0) / 100).toFixed(2)}/${(
|
|
955
|
+
(player.stats?.heroDamageReport?.dealtTotal.disableDuration ?? 0) / 100
|
|
956
956
|
).toFixed(2)}</span>s</section>
|
|
957
957
|
</div>
|
|
958
958
|
</div>`).join("") %>
|
|
959
959
|
</div>
|
|
960
960
|
<div class="ban_list">
|
|
961
|
-
<%- match.pickBans
|
|
961
|
+
<%- (match.pickBans??[])
|
|
962
962
|
.filter((hero) => !hero.isPick)
|
|
963
963
|
.map((hero) => `<div class="ban_hero"><img src="${utils.getImageUrl(/^npc_dota_hero_(?<name>.+)$/.exec(dotaconstants.heroes[hero.bannedHeroId].name)[1], ImageType.Heroes)}" alt="" /></div>`)
|
|
964
964
|
.join("") %>
|
|
@@ -396,11 +396,11 @@
|
|
|
396
396
|
(${(player.heroDamage / player.networth)?.toFixed(2)})
|
|
397
397
|
</p>
|
|
398
398
|
<p class="hero_damage">造成伤害:${player.heroDamage} (${(player.heroDamage/match[player.team].heroDamage*100).toFixed(2)}%)</p>
|
|
399
|
-
<p class="damage_received">承受伤害:${player.damageReceived} (${(player.damageReceived/match[player.team].damageReceived*100).toFixed(2)}%)</p>
|
|
399
|
+
<p class="damage_received">承受伤害:${player.damageReceived} (${match[player.team].damageReceived>0?((player.damageReceived/match[player.team].damageReceived*100).toFixed(2)):"0.00"}%)</p>
|
|
400
400
|
<p class="tower_damage">建筑伤害:${player.towerDamage}</p>
|
|
401
401
|
<p class="kda row-1">${player.kills}/${player.deaths}/${player.assists} (${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)})</p>
|
|
402
402
|
<p class="kill_contribution">参战率:${(player.killContribution * 100).toFixed(2)}%</p>
|
|
403
|
-
<p class="stun_duration">控制时间:${(player.stats.heroDamageReport
|
|
403
|
+
<p class="stun_duration">控制时间:${((player.stats.heroDamageReport?.dealtTotal.stunDuration ?? 0)/ 100).toFixed(2)}s</p>
|
|
404
404
|
<p class="heal">治疗量:${player.heroHealing}</p>
|
|
405
405
|
<div class="items row-1">
|
|
406
406
|
<div class="normal">
|
|
@@ -430,8 +430,8 @@
|
|
|
430
430
|
</div>
|
|
431
431
|
<div class="neutral_item row-1" style="background-image: url(${utils.getImageUrl(dotaconstants.item_ids[player.neutral0Id], ImageType.Items)})"></div>
|
|
432
432
|
<div class="ahgs row-1">
|
|
433
|
-
<img src="${utils.getImageUrl("scepter_"+((player.items.concat(player.backpacks).find(item=>item?.id==108)||player.stats
|
|
434
|
-
<img src="${utils.getImageUrl("shard_"+(player.stats
|
|
433
|
+
<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="" />
|
|
434
|
+
<img src="${utils.getImageUrl("shard_"+((player.stats?.matchPlayerBuffEvent||[]).find(buff=>buff.itemId==609)?1:0))}" alt="" />
|
|
435
435
|
</div>
|
|
436
436
|
</div>
|
|
437
437
|
`).join("") %>
|
|
@@ -385,13 +385,13 @@
|
|
|
385
385
|
|
|
386
386
|
player.positionPerformance=[];
|
|
387
387
|
// 瞎j8定义的各位置代表物品,以后看情况调整
|
|
388
|
-
const
|
|
388
|
+
const positionIcons = ["damage","nuke","armor","speed","healing"];
|
|
389
389
|
for (let index = 0; index < 5; index++) {
|
|
390
390
|
let currentPositionMatches = player.matches.filter(match=>match.players[0].position == ("POSITION_"+(index+1)))
|
|
391
391
|
let winCount = currentPositionMatches.filter(match=>match.didRadiantWin == match.players[0].isRadiant).length;
|
|
392
392
|
player.positionPerformance.push({
|
|
393
393
|
position : (index + 1),
|
|
394
|
-
icon :
|
|
394
|
+
icon : positionIcons[index],
|
|
395
395
|
matchCount : currentPositionMatches.length,
|
|
396
396
|
winCount : winCount,
|
|
397
397
|
loseCount : currentPositionMatches.length - winCount,
|
|
@@ -468,7 +468,7 @@
|
|
|
468
468
|
<span class="tip lose_count" style="justify-self: start; margin-left: 2px">败场</span>
|
|
469
469
|
<%- player.positionPerformance
|
|
470
470
|
.map((position) => `
|
|
471
|
-
<span><img src="${utils.getImageUrl(position.icon,ImageType.
|
|
471
|
+
<span><img src="${utils.getImageUrl(position.icon,ImageType.IconsFacets)}"></span>
|
|
472
472
|
<span class="count">${position.matchCount}</span>
|
|
473
473
|
<span class="win_rate">${position.matchCount>0?(((position.winCount / position.matchCount) * 100).toFixed(0)):"-"}%</span>
|
|
474
474
|
<span class="imp">${(position.imp > 0 ? "+" : "") + position.imp}</span>
|