@sjtdev/koishi-plugin-dota2tracker 1.2.1 → 1.2.3
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 +85 -0
- package/lib/index.js +63 -79
- package/package.json +3 -3
- package/readme.md +6 -4
- package/template/hero/hero_1.ejs +3 -6
- package/template/match/match_2.ejs +32 -2
package/changelog.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
### 1.2.3
|
|
2
|
+
**修复**:修复了比赛战报图片中称号`摸`判定不正确的问题
|
|
3
|
+
**改进**:微调了比赛战报图片中称号的显示样式
|
|
4
|
+
|
|
5
|
+
### 1.2.2
|
|
6
|
+
**移除**:取消`查询英雄`的缓存功能,原因为valve的API返回的数据可能包含未本地化的字段(例如这次的7.36b更新后获取到的很多改动后技能说明暂时都是英文),这些数据无法根据版本判断是否需要更新缓存。
|
|
7
|
+
**修复**:修复了`查询英雄`图片中某些命石提供技能可能被判定为先天技能的问题。(实际为API缺陷)
|
|
8
|
+
|
|
9
|
+
### 1.2.1
|
|
10
|
+
**改进**:优化比赛战报图片中,对多个同种物品(例如双护腕双挂件一类)的出装时间显示进行优化,原先都将显示为最后一件此种物品的购买时间,现在可以显示不同的时间。
|
|
11
|
+
> 从第一件购买时间算起,例如火枪于1:00 2:00 3:00购买了三个系带,游戏结束前卖出其中之一,则剩余两个则显示为1:00 2:00
|
|
12
|
+
|
|
13
|
+
**改进**:出于实用性考虑,比赛战报图片中将不再显示辅助道具的购买时间。
|
|
14
|
+
|
|
15
|
+
### 1.2.0
|
|
16
|
+
**改进**:对`查询英雄`模板代码进行了调整与部分重写,完成7.36版本的英雄数据匹配,现在可正常使用。
|
|
17
|
+
> (人话说就是先天技能和命石适配完成了)
|
|
18
|
+
|
|
19
|
+
**移除**:因`查询英雄`指令已适配7.36版本,`7.36`指令退役。(删除)
|
|
20
|
+
#### hotfix
|
|
21
|
+
**修复**:删除一些留存的测试用代码
|
|
22
|
+
|
|
23
|
+
### 1.1.10
|
|
24
|
+
**修复**:修复`7.36`指令因DOTA2官网的cdn链接变动导致获取失败的问题,并优化了加载速度。
|
|
25
|
+
**修复**:修复每次在koishi重新启动后,使用指令`7.36`都会重新获取数据的问题。
|
|
26
|
+
#### hotfix
|
|
27
|
+
**修复**:修复一处编译问题导致`7.36`指令无法使用的问题
|
|
28
|
+
|
|
29
|
+
### 1.1.9
|
|
30
|
+
**新增**:v1.1.6加入的功能等待解析时间现在可以配置,位于插件页配置项`dataParsingTimeoutMinutes`
|
|
31
|
+
**修复**:修复因v1.1.8修改数据获取方式导致的`绑定`指令失效
|
|
32
|
+
**修复**:修复指令`查询英雄`报错问题(数据仍为7.35d,等待上游API更新)
|
|
33
|
+
**改进**:兼容Discord、KOOK等频道类平台,将订阅与绑定存储时群组(guild)改为频道(channel),对onebot(qq)类无影响(出现使用问题请联系我)
|
|
34
|
+
<details>
|
|
35
|
+
<summary>若此前已在使用频道类平台……</summary>
|
|
36
|
+
此版本前频道类平台应该无法使用战报功能与日报功能。此版本在订阅本群与绑定玩家时将存储channelId而不是guildID,对于非频道类平台这两个值是一样的,不会造成影响。但频道类平台应该会彻底失效,解决方案只有操作数据库,将channelId填入原先guildId处(兼容原因,未修改数据库字段名[guildId],但实际上存入的已经是channel的ID了;guildId和channelId可参考数据库表channel中的数据),或重新订阅与绑定。(若是重新订阅与绑定,不会覆盖原先存储guildId的数据,也就是说旧数据依然会存在,可根据需求选择是否删除)
|
|
37
|
+
</details>
|
|
38
|
+
|
|
39
|
+
### 1.1.8
|
|
40
|
+
**改进**:将数据获取方式从 npm 包 `axios` 切换为 Koishi 提供的 `http` 服务,并简化了相关代码(用户体验无差别)。
|
|
41
|
+
**改进**:为 `match_2` 模板添加了玩家小队标识(效果与 `match_1` 模板中的相同功能一致,但在显示上进行了微调)。
|
|
42
|
+
|
|
43
|
+
### 1.1.7
|
|
44
|
+
**改进**:玩家信息模板中代表位置的图标替换为简约风格图标
|
|
45
|
+
**修复**:于v1.1.5新增的`7.36`指令生成英雄改动图片时会额外产生的测试用的`remainingContent.html`文件,现已不再生成。(如果之前使用了该命令并产生了此文件,可根据需要手动删除。位于`koishi/node_modules/@sjtdev/koishi-plugin-dota2tracker/`)
|
|
46
|
+
|
|
47
|
+
### 1.1.6
|
|
48
|
+
由于近期stratz网站问题,比赛数据无法自动解析,导致bot会一直等待解析后的战报数据而无法发送。
|
|
49
|
+
**新增**:现在调整为比赛结束1小时后仍然未解析时将直接发出缺失部分数据的战报(缺失包括BP顺序、出装时间、英雄受到伤害等)
|
|
50
|
+
#### hotfix
|
|
51
|
+
**修复**:修复引发播报未解析比赛战报失败的一个小问题
|
|
52
|
+
|
|
53
|
+
### 1.1.5
|
|
54
|
+
**新增**:为新版本7.36添加新指令`7.36`
|
|
55
|
+
`7.36 <英雄ID|英雄名|英雄常用别名>`可查询对应英雄的改动信息,未输入英雄查询参数时直接返回官网7.36更新日志链接
|
|
56
|
+
添加`--refresh|-r`参数可强制重新获取数据,如`7.36 -r`,也可在查询时使用,如`7.36 敌法师 -r`
|
|
57
|
+
|
|
58
|
+
### 1.1.4
|
|
59
|
+
**改进**:完善查询玩家指定英雄的生成模板
|
|
60
|
+
|
|
61
|
+
### 1.1.3
|
|
62
|
+
**新增**:新增实验性功能【日报昨日总结】,在指定时间播报昨日已订阅群组中已绑定群友的战绩(简略文字),默认关闭,可在插件配置中打开
|
|
63
|
+
`查询玩家`指令新增功能,现在额外输入参数`--hero <英雄ID|英雄名|英雄常用别名>`可查询目标玩家指定英雄的详情(--hero可替换为-o)
|
|
64
|
+
例如:
|
|
65
|
+
* `查询玩家 123456789 --hero 敌法师`
|
|
66
|
+
* `查询玩家 -o 敌法师` (仍可缺省玩家参数以自查)
|
|
67
|
+
|
|
68
|
+
### 1.1.2
|
|
69
|
+
**改进**:完成查询群友功能
|
|
70
|
+
**修复**:修复玩家模板中显示NaN的部分
|
|
71
|
+
#### hotfix
|
|
72
|
+
**修复**:修复查询远古玩家账号时可能意外失败的问题
|
|
73
|
+
**改进**:调整mvp中的控制分与[控]称号算法
|
|
74
|
+
#### hotfix.2
|
|
75
|
+
**修复**:修复初次使用查询英雄指令时,技能名初始化失败导致的错误
|
|
76
|
+
|
|
77
|
+
### 1.1.2-beta
|
|
78
|
+
**改进**:为`查询群友`添加模板,还在调整布局中
|
|
79
|
+
|
|
80
|
+
### 1.1.1
|
|
81
|
+
**改进**:玩家信息模板添加近25场内各个位置表现展示
|
|
82
|
+
|
|
83
|
+
### 1.1.0
|
|
84
|
+
**改进**:使用ejs重写模板相关代码使其模块化,使新增模板更方便
|
|
85
|
+
**新增**:为比赛信息添加了仿MAX+模板,效果可见[match_2](./wiki/match_2),可在插件配置中切换
|
package/lib/index.js
CHANGED
|
@@ -808,8 +808,8 @@ function getFormattedMatchData(match) {
|
|
|
808
808
|
findMaxByProperty("towerDamage", "heroDamage").titles.push({ name: "拆", color: "#FEDCBA" });
|
|
809
809
|
findMaxByProperty("heroHealing").titles.push({ name: "奶", color: "#00FF00" });
|
|
810
810
|
match.players.reduce((lowest, player) => {
|
|
811
|
-
const currentContribution = (player.kills + player.assists) / match[player.team].
|
|
812
|
-
const lowestContribution = (lowest.kills + lowest.assists) / match[lowest.team].
|
|
811
|
+
const currentContribution = (player.kills + player.assists) / match[player.team].killsCount;
|
|
812
|
+
const lowestContribution = (lowest.kills + lowest.assists) / match[lowest.team].killsCount;
|
|
813
813
|
if (currentContribution < lowestContribution) {
|
|
814
814
|
return player;
|
|
815
815
|
} else if (currentContribution === lowestContribution) {
|
|
@@ -1469,7 +1469,7 @@ async function apply(ctx, config) {
|
|
|
1469
1469
|
}
|
|
1470
1470
|
}
|
|
1471
1471
|
});
|
|
1472
|
-
ctx.command("查询英雄 <input_data>", "查询英雄技能/面板信息").usage("查询英雄的技能说明与各项数据,生成图片发布。\n参数可输入英雄ID、英雄名、英雄常用别名").option("random", "-r 随机选择英雄").
|
|
1472
|
+
ctx.command("查询英雄 <input_data>", "查询英雄技能/面板信息").usage("查询英雄的技能说明与各项数据,生成图片发布。\n参数可输入英雄ID、英雄名、英雄常用别名").option("random", "-r 随机选择英雄").example("-查询英雄 15").example("-查询英雄 雷泽").example("-查询英雄 电魂").action(async ({ session, options }, input_data) => {
|
|
1473
1473
|
if (options.random)
|
|
1474
1474
|
input_data = random.pick(Object.keys(HEROES_CHINESE));
|
|
1475
1475
|
if (input_data) {
|
|
@@ -1478,94 +1478,81 @@ async function apply(ctx, config) {
|
|
|
1478
1478
|
session.send("未找到输入的英雄,请确认后重新输入。");
|
|
1479
1479
|
return;
|
|
1480
1480
|
}
|
|
1481
|
+
await session.send("正在获取英雄数据,请稍后...");
|
|
1481
1482
|
try {
|
|
1482
|
-
const
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
if (
|
|
1486
|
-
|
|
1483
|
+
const queryHero = await queryHeroFromValve(hero.id);
|
|
1484
|
+
Object.assign(hero, queryHero);
|
|
1485
|
+
hero.facet_abilities.forEach((fa, i) => {
|
|
1486
|
+
if (fa.abilities.length) {
|
|
1487
|
+
fa.abilities.forEach((ab) => {
|
|
1488
|
+
if (!hero.facets[i].abilities)
|
|
1489
|
+
hero.facets[i].abilities = [];
|
|
1490
|
+
if (hero.facets[i].description_loc !== ab.desc_loc)
|
|
1491
|
+
hero.facets[i].abilities.push({ id: ab.id, name: ab.name, name_loc: ab.name_loc, description_ability_loc: formatHeroDesc(ab.desc_loc, ab.special_values, "facet" /* Facet */) });
|
|
1492
|
+
else
|
|
1493
|
+
hero.facets[i].description_loc = formatHeroDesc(hero.facets[i].description_loc, ab.special_values, "facet" /* Facet */);
|
|
1494
|
+
ab.ability_is_facet = true;
|
|
1495
|
+
hero.abilities.push(ab);
|
|
1496
|
+
});
|
|
1487
1497
|
}
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
if (
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
if (hero.facets[i].description_loc !== ab.desc_loc)
|
|
1497
|
-
hero.facets[i].abilities.push({ id: ab.id, name: ab.name, name_loc: ab.name_loc, description_ability_loc: formatHeroDesc(ab.desc_loc, ab.special_values, "facet" /* Facet */) });
|
|
1498
|
-
else
|
|
1499
|
-
hero.facets[i].description_loc = formatHeroDesc(hero.facets[i].description_loc, ab.special_values, "facet" /* Facet */);
|
|
1500
|
-
hero.abilities.push(ab);
|
|
1501
|
-
});
|
|
1498
|
+
});
|
|
1499
|
+
const all_special_values = [...hero.abilities.flatMap((ab) => ab.special_values), ...hero.facet_abilities.flatMap((fas) => fas.abilities.flatMap((fa) => fa.special_values))];
|
|
1500
|
+
hero.abilities.forEach((ab) => {
|
|
1501
|
+
ab.facets_loc.forEach((facet, i) => {
|
|
1502
|
+
if (facet) {
|
|
1503
|
+
if (!hero.facets[i].abilities)
|
|
1504
|
+
hero.facets[i].abilities = [];
|
|
1505
|
+
hero.facets[i].abilities.push({ id: ab.id, name: ab.name, name_loc: ab.name_loc, description_ability_loc: formatHeroDesc(facet, all_special_values, "facet" /* Facet */), attributes: [] });
|
|
1502
1506
|
}
|
|
1503
1507
|
});
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
if (
|
|
1508
|
-
|
|
1509
|
-
hero.facets[i].abilities = [];
|
|
1510
|
-
hero.facets[i].abilities.push({ id: ab.id, name: ab.name, name_loc: ab.name_loc, description_ability_loc: formatHeroDesc(facet, all_special_values, "facet" /* Facet */), attributes: [] });
|
|
1508
|
+
hero.facets.forEach((facet) => {
|
|
1509
|
+
const svs = ab.special_values.filter((sv) => sv.facet_bonus.name === facet.name);
|
|
1510
|
+
svs.forEach((sv) => {
|
|
1511
|
+
if (sv.heading_loc) {
|
|
1512
|
+
facet.abilities.find((ability) => ab.id == ability.id)?.attributes.push({ heading_loc: sv.heading_loc, values: [...sv.facet_bonus.values] });
|
|
1511
1513
|
}
|
|
1512
1514
|
});
|
|
1513
|
-
hero.facets.forEach((facet) => {
|
|
1514
|
-
const svs = ab.special_values.filter((sv) => sv.facet_bonus.name === facet.name);
|
|
1515
|
-
svs.forEach((sv) => {
|
|
1516
|
-
if (sv.heading_loc) {
|
|
1517
|
-
facet.abilities.find((ability) => ab.id == ability.id)?.attributes.push({ heading_loc: sv.heading_loc, values: [...sv.facet_bonus.values] });
|
|
1518
|
-
}
|
|
1519
|
-
});
|
|
1520
|
-
});
|
|
1521
|
-
ab.desc_loc = formatHeroDesc(ab.desc_loc, all_special_values);
|
|
1522
|
-
ab.notes_loc = ab.notes_loc.map((note) => formatHeroDesc(note, all_special_values));
|
|
1523
|
-
if (ab.ability_has_scepter)
|
|
1524
|
-
ab.scepter_loc = formatHeroDesc(ab.scepter_loc, ab.special_values, "scepter" /* Scepter */);
|
|
1525
|
-
if (ab.ability_has_shard)
|
|
1526
|
-
ab.shard_loc = formatHeroDesc(ab.shard_loc, ab.special_values, "shard" /* Shard */);
|
|
1527
1515
|
});
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1516
|
+
ab.desc_loc = formatHeroDesc(ab.desc_loc, all_special_values);
|
|
1517
|
+
ab.notes_loc = ab.notes_loc.map((note) => formatHeroDesc(note, all_special_values));
|
|
1518
|
+
if (ab.ability_has_scepter)
|
|
1519
|
+
ab.scepter_loc = formatHeroDesc(ab.scepter_loc, ab.special_values, "scepter" /* Scepter */);
|
|
1520
|
+
if (ab.ability_has_shard)
|
|
1521
|
+
ab.shard_loc = formatHeroDesc(ab.shard_loc, ab.special_values, "shard" /* Shard */);
|
|
1522
|
+
});
|
|
1523
|
+
hero.talents.forEach((talent) => {
|
|
1524
|
+
const regex = /\{s:(.*?)\}/g;
|
|
1525
|
+
let match;
|
|
1526
|
+
while ((match = regex.exec(talent.name_loc)) !== null) {
|
|
1527
|
+
const specialValueName = match[1];
|
|
1528
|
+
const target = talent.special_values?.find((sv) => sv.name === specialValueName);
|
|
1529
|
+
if (target) {
|
|
1530
|
+
talent.name_loc = talent.name_loc.replace(match[0], target.values_float.join("/"));
|
|
1531
|
+
} else {
|
|
1532
|
+
const ability = hero.abilities.find((ability2) => ability2.special_values.some((specialValue) => specialValue.bonuses.some((bonus) => bonus.name === talent.name)));
|
|
1533
|
+
if (ability) {
|
|
1534
|
+
const specialValues = ability.special_values.filter((specialValue) => specialValue.bonuses.some((bonus) => bonus.name === talent.name));
|
|
1535
|
+
const regex2 = /{s:bonus_(.*?)}/g;
|
|
1536
|
+
let match2;
|
|
1537
|
+
const replacements = [];
|
|
1538
|
+
while ((match2 = regex2.exec(talent.name_loc)) !== null) {
|
|
1539
|
+
const specialValue = specialValues.find((sv) => sv.name === String(match2[1]));
|
|
1540
|
+
const replacement = specialValue?.bonuses.find((bonus) => bonus.name === talent.name)?.value;
|
|
1541
|
+
if (replacement !== void 0) {
|
|
1542
|
+
replacements.push({ original: match2[0], replacement });
|
|
1549
1543
|
}
|
|
1550
|
-
replacements.forEach(({ original, replacement }) => {
|
|
1551
|
-
talent.name_loc = talent.name_loc.replace(original, replacement);
|
|
1552
|
-
});
|
|
1553
1544
|
}
|
|
1545
|
+
replacements.forEach(({ original, replacement }) => {
|
|
1546
|
+
talent.name_loc = talent.name_loc.replace(original, replacement);
|
|
1547
|
+
});
|
|
1554
1548
|
}
|
|
1555
1549
|
}
|
|
1556
|
-
});
|
|
1557
|
-
try {
|
|
1558
|
-
const gameVersionId = (await query(CURRENT_GAMEVERSION())).data.constants.gameVersions[0].id;
|
|
1559
|
-
await ctx.database.upsert("dt_hero_data_cache", (row) => [{ id: hero.id, hero, gameVersionId }]);
|
|
1560
|
-
} catch (error) {
|
|
1561
|
-
ctx.logger.error(error);
|
|
1562
|
-
await session.send("数据缓存失败。");
|
|
1563
1550
|
}
|
|
1564
|
-
}
|
|
1551
|
+
});
|
|
1565
1552
|
await session.send(await ctx.puppeteer.render(genImageHTML(hero, config.template_hero, "hero" /* Hero */)));
|
|
1566
1553
|
} catch (error) {
|
|
1567
1554
|
ctx.logger.error(error);
|
|
1568
|
-
|
|
1555
|
+
session.send("获取数据失败");
|
|
1569
1556
|
}
|
|
1570
1557
|
} else {
|
|
1571
1558
|
session.send("请输入参数。");
|
|
@@ -1641,9 +1628,6 @@ async function apply(ctx, config) {
|
|
|
1641
1628
|
if (!("dt_previous_query_results" in tables)) {
|
|
1642
1629
|
ctx.model.extend("dt_previous_query_results", { matchId: "unsigned", data: "json", queryTime: "timestamp" }, { primary: "matchId" });
|
|
1643
1630
|
}
|
|
1644
|
-
if (!("dt_hero_data_cache" in tables)) {
|
|
1645
|
-
ctx.model.extend("dt_hero_data_cache", { id: "unsigned", gameVersionId: "unsigned", hero: "json" });
|
|
1646
|
-
}
|
|
1647
1631
|
ctx.cron("0 */6 * * *", () => {
|
|
1648
1632
|
const oneMonthAgo = (0, import_moment.default)().subtract(1, "months").toDate();
|
|
1649
1633
|
ctx.database.remove("dt_sended_match_id", { sendTime: { $lt: oneMonthAgo } });
|
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.
|
|
4
|
+
"version": "1.2.3",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"moment": "^2.30.1"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"koishi": "^4.17.
|
|
34
|
+
"koishi": "^4.17.8"
|
|
35
35
|
},
|
|
36
36
|
"koishi": {
|
|
37
37
|
"preview": "true",
|
|
@@ -47,4 +47,4 @@
|
|
|
47
47
|
"zh"
|
|
48
48
|
]
|
|
49
49
|
}
|
|
50
|
-
}
|
|
50
|
+
}
|
package/readme.md
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑定),以及一系列查询功能。
|
|
6
6
|
### 安装
|
|
7
|
-
在koishi插件市场搜索安装
|
|
7
|
+
在koishi插件市场搜索安装
|
|
8
|
+
有关koishi的使用说明:([koishi官方文档](https://koishi.chat/))
|
|
8
9
|
|
|
9
10
|
### 使用
|
|
10
11
|
需在插件配置页填入STRATZ API TOKEN,否则无法使用。(配置中提供了API的获取链接)
|
|
@@ -36,10 +37,11 @@ DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑
|
|
|
36
37
|
返回一张图片,包含英雄属性与技能详情。(此处英雄名为中文名)
|
|
37
38
|
* <del>`查询英雄对战 <英雄ID|英雄名|英雄常用别名>`</del>
|
|
38
39
|
好像不是很实用
|
|
39
|
-
*
|
|
40
|
-
|
|
40
|
+
* <del>`7.36 [英雄ID|英雄名|英雄常用别名] [--refresh|-r]`</del>
|
|
41
|
+
<del>查询官网7.36更新日志中指定英雄的改动信息
|
|
41
42
|
无英雄参数时直接返回官网7.36更新日志网址
|
|
42
|
-
首次使用时将缓存更新日志网页,若读取失败或出错,可添加`--refresh`或`-r
|
|
43
|
+
首次使用时将缓存更新日志网页,若读取失败或出错,可添加`--refresh`或`-r`指令重新缓存</del>
|
|
44
|
+
`查询英雄`指令已适配7.36改动,所以此指令已废弃
|
|
43
45
|
|
|
44
46
|
### 英雄ID|英雄名|英雄常用别名 列表
|
|
45
47
|
[dotaconstants_add.json](https://github.com/sjtdev/koishi-plugin-dota2tracker/blob/master/src/dotaconstants_add.json#L102-L226)
|
package/template/hero/hero_1.ejs
CHANGED
|
@@ -189,9 +189,6 @@
|
|
|
189
189
|
background-color: #444;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
.details .list {
|
|
193
|
-
}
|
|
194
|
-
|
|
195
192
|
.details .list td {
|
|
196
193
|
width: 50%;
|
|
197
194
|
text-align: center;
|
|
@@ -648,10 +645,10 @@
|
|
|
648
645
|
<div class="skills">
|
|
649
646
|
${hero.abilities//.filter((item) => dotaconstants.abilities[item.name].behavior != "Hidden")
|
|
650
647
|
.map((item) => `
|
|
651
|
-
<div class="skill" data-
|
|
648
|
+
<div class="skill" data-innate="${item.ability_is_innate&&!item.ability_is_facet}">
|
|
652
649
|
<p class="title">
|
|
653
650
|
<span class="name">${item.name_loc}</span>
|
|
654
|
-
${item.ability_is_innate?`<span class="is_innate">先天技能</span>`:""}
|
|
651
|
+
${item.ability_is_innate&&!item.ability_is_facet?`<span class="is_innate">先天技能</span>`:""}
|
|
655
652
|
${item.ability_is_granted_by_scepter ?`<img src="${utils.getImageUrl("scepter")}" class="scepter">`:""}
|
|
656
653
|
${item.ability_is_granted_by_shard ?`<img src="${utils.getImageUrl("shard")}" class="shard">`:""}
|
|
657
654
|
</p>
|
|
@@ -736,7 +733,7 @@
|
|
|
736
733
|
const items = document.querySelectorAll('.skills > .skill');
|
|
737
734
|
items.forEach(item => {
|
|
738
735
|
// const name = item.getAttribute('data-name');
|
|
739
|
-
const abilityIsInnate = item.getAttribute('data-
|
|
736
|
+
const abilityIsInnate = item.getAttribute('data-innate') === 'true';
|
|
740
737
|
const img = item.querySelector('.img_stats > img');
|
|
741
738
|
const imageUrl = img.src;
|
|
742
739
|
|
|
@@ -242,7 +242,10 @@
|
|
|
242
242
|
.player > .titles {
|
|
243
243
|
grid-row: 4;
|
|
244
244
|
grid-column: 1 / span 3;
|
|
245
|
-
text-shadow: 1px 1px 0 #333;
|
|
245
|
+
/* text-shadow: 1px 1px 0 #333; 设置阴影颜色及偏移 */
|
|
246
|
+
}
|
|
247
|
+
.player > .titles > span {
|
|
248
|
+
margin-right: 1.5px;
|
|
246
249
|
}
|
|
247
250
|
|
|
248
251
|
.player > .player_name {
|
|
@@ -398,6 +401,33 @@
|
|
|
398
401
|
</head>
|
|
399
402
|
<body>
|
|
400
403
|
<% const match = data; %>
|
|
404
|
+
<% function darkenHexColor(hex, percentage) {
|
|
405
|
+
// 移除前缀 #
|
|
406
|
+
hex = hex.replace(/^#/, '');
|
|
407
|
+
|
|
408
|
+
// 处理三位 hex 颜色值
|
|
409
|
+
if (hex.length === 3) {
|
|
410
|
+
hex = hex.split('').map(char => char + char).join('');
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// 将 hex 转换为 RGB
|
|
414
|
+
let r = parseInt(hex.substring(0, 2), 16);
|
|
415
|
+
let g = parseInt(hex.substring(2, 4), 16);
|
|
416
|
+
let b = parseInt(hex.substring(4, 6), 16);
|
|
417
|
+
|
|
418
|
+
// 将 RGB 变暗
|
|
419
|
+
r = Math.floor(r * (1 - percentage / 100));
|
|
420
|
+
g = Math.floor(g * (1 - percentage / 100));
|
|
421
|
+
b = Math.floor(b * (1 - percentage / 100));
|
|
422
|
+
|
|
423
|
+
// 将 RGB 转换回 hex
|
|
424
|
+
const darkenedHex = `#${((1 << 24) + (r << 16) + (g << 8) + b)
|
|
425
|
+
.toString(16)
|
|
426
|
+
.slice(1)
|
|
427
|
+
.toUpperCase()}`;
|
|
428
|
+
|
|
429
|
+
return darkenedHex;
|
|
430
|
+
} %>
|
|
401
431
|
<nav>
|
|
402
432
|
<div class="match_id">
|
|
403
433
|
<p>比赛 <%-match.id%></p>
|
|
@@ -456,7 +486,7 @@
|
|
|
456
486
|
<img src="${utils.getImageUrl('star_' + player.rank.star)}" class="stars" />
|
|
457
487
|
<p>${player.steamAccount.seasonLeaderboardRank??""}</p>
|
|
458
488
|
</div>
|
|
459
|
-
<div class="titles">${player.titles.map((item) => `<span style="color: ${item.color};">${item.name}</span>`).join('
|
|
489
|
+
<div class="titles">${player.titles.map((item) => `<span style="color: ${darkenHexColor(item.color, 25)};">${item.name}</span>`).join('')}</div>
|
|
460
490
|
<div class="player_name row-1">
|
|
461
491
|
<span class="rank">${`[${d2a.rank[player.rank.medal]}${player.rank.star||""}]`}</span>
|
|
462
492
|
<span class="name">${player.steamAccount.name}</span>
|