@sjtdev/koishi-plugin-dota2tracker 1.2.7 → 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 +47 -25
- package/lib/index.js +23 -7
- package/package.json +1 -1
- package/template/player/player_1.ejs +12 -7
package/changelog.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
### 1.2.
|
|
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
|
|
2
12
|
##### 于1.2.7-beta中尝试修复的功能均已正常工作,正式发布1.2.7
|
|
13
|
+
##### 以下为包括beta版更新内容在内的所有改动
|
|
3
14
|
##### **新增**:
|
|
4
15
|
- 可在配置页设置查询比赛与发布战报时附带stratz比赛链接、查询玩家信息时附带stratz玩家页面链接、查询英雄数据信息时附带刀塔百科对应英雄页面链接,这些选项均默认关闭。
|
|
5
16
|
##### **修复**:
|
|
@@ -8,7 +19,8 @@
|
|
|
8
19
|
- 修复无法获取群组相关信息导致的日报功能失效。
|
|
9
20
|
- 修复日报功能中统计组合有可能出现重复的问题。
|
|
10
21
|
<details>
|
|
11
|
-
<summary>1.2.7-beta更新日志</summary>
|
|
22
|
+
<summary><b>1.2.7-beta更新日志</b></summary>
|
|
23
|
+
|
|
12
24
|
### 1.2.7-beta
|
|
13
25
|
##### **新增**:
|
|
14
26
|
- 可在配置页设置发布战报时附带stratz比赛链接、查询玩家信息时附带stratz玩家页面链接,这些选项均默认关闭。
|
|
@@ -24,8 +36,16 @@
|
|
|
24
36
|
|
|
25
37
|
</details>
|
|
26
38
|
|
|
27
|
-
|
|
28
|
-
因koishi更新至4.17.10修复了主动发送消息的函数,本插件的发送消息方式也换回之前的方案以避免可能的代码问题。(功能使用上与1.2.6-pre3版本一致)
|
|
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>
|
|
29
49
|
|
|
30
50
|
### 1.2.6-pre
|
|
31
51
|
##### (因koishi尚未更新发布pre版)
|
|
@@ -40,34 +60,36 @@
|
|
|
40
60
|
**改进&修复**:继续优化`查询英雄`代码结构使由命石、神杖、魔晶改变的技能属性更直观;修复某些技能数据中有旧天赋加成数据留存、导致的天赋数值未被正确填充。
|
|
41
61
|
**改进**:为英雄`艾欧`添加别名:["艾欧", "小精灵"] → ["艾欧", "小精灵", "精灵", "IO"]
|
|
42
62
|
|
|
43
|
-
|
|
44
|
-
**修复**:使用临时替代方案修复由koishi-4.17.9的bug引起的无法主动发送消息(播报战报等),待koishi更新修复后回滚此改动。
|
|
45
|
-
#### fix3
|
|
46
|
-
**修复**:修复日报使用时报错的问题。
|
|
63
|
+
</details>
|
|
47
64
|
|
|
48
|
-
|
|
65
|
+
# 1.2.5
|
|
49
66
|
**改进**:优化`查询玩家`图片中近期战绩列表内未解析比赛的显示效果
|
|
50
67
|
**修复**:修复`查询英雄`图片技能属性名多显示了一个冒号的问题
|
|
51
68
|
|
|
52
|
-
|
|
69
|
+
#### fix
|
|
70
|
+
**修复**:使用临时替代方案修复由koishi-4.17.9的bug引起的无法主动发送消息(播报战报等),待koishi更新修复后回滚此改动。
|
|
71
|
+
#### fix3
|
|
72
|
+
**修复**:修复使用替代方案导致日报失效的问题。
|
|
73
|
+
|
|
74
|
+
# 1.2.4
|
|
53
75
|
**修复**:修正调用help指令时本插件某些指令的说明错误
|
|
54
76
|
**修复**:修复`取消订阅`指令失效的问题
|
|
55
77
|
|
|
56
|
-
|
|
78
|
+
# 1.2.3
|
|
57
79
|
**修复**:修复了比赛战报图片中称号`摸`判定不正确的问题
|
|
58
80
|
**改进**:微调了比赛战报图片模板`match_2`中称号的显示样式
|
|
59
81
|
|
|
60
|
-
|
|
82
|
+
# 1.2.2
|
|
61
83
|
**移除**:取消`查询英雄`的缓存功能,原因为valve的API返回的数据可能包含未本地化的字段(例如这次的7.36b更新后获取到的很多改动后技能说明暂时都是英文),这些数据无法根据版本判断是否需要更新缓存。
|
|
62
84
|
**修复**:修复了`查询英雄`图片中某些命石提供技能可能被判定为先天技能的问题。
|
|
63
85
|
|
|
64
|
-
|
|
86
|
+
# 1.2.1
|
|
65
87
|
**改进**:优化比赛战报图片中,对多个同种物品(例如双护腕双挂件一类)的出装时间显示进行优化,原先都将显示为最后一件此种物品的购买时间,现在可以显示不同的时间。
|
|
66
88
|
> 从第一件购买时间算起,例如火枪于1:00 2:00 3:00购买了三个系带,游戏结束前卖出其中之一,则剩余两个则显示为1:00 2:00
|
|
67
89
|
|
|
68
90
|
**改进**:出于实用性考虑,比赛战报图片中将不再显示辅助道具的购买时间。
|
|
69
91
|
|
|
70
|
-
|
|
92
|
+
# 1.2.0
|
|
71
93
|
**改进**:对`查询英雄`模板代码进行了调整与部分重写,完成7.36版本的英雄数据匹配,现在可正常使用。
|
|
72
94
|
> (人话说就是先天技能和命石适配完成了)
|
|
73
95
|
|
|
@@ -75,13 +97,13 @@
|
|
|
75
97
|
#### hotfix
|
|
76
98
|
**修复**:删除一些留存的测试用代码
|
|
77
99
|
|
|
78
|
-
|
|
100
|
+
# 1.1.10
|
|
79
101
|
**修复**:修复`7.36`指令因DOTA2官网的cdn链接变动导致获取失败的问题,并优化了加载速度。
|
|
80
102
|
**修复**:修复每次在koishi重新启动后,使用指令`7.36`都会重新获取数据的问题。
|
|
81
103
|
#### hotfix
|
|
82
104
|
**修复**:修复一处编译问题导致`7.36`指令无法使用的问题
|
|
83
105
|
|
|
84
|
-
|
|
106
|
+
# 1.1.9
|
|
85
107
|
**新增**:v1.1.6加入的功能等待解析时间现在可以配置,位于插件页配置项`dataParsingTimeoutMinutes`
|
|
86
108
|
**修复**:修复因v1.1.8修改数据获取方式导致的`绑定`指令失效
|
|
87
109
|
**修复**:修复指令`查询英雄`报错问题(数据仍为7.35d,等待上游API更新)
|
|
@@ -91,36 +113,36 @@
|
|
|
91
113
|
此版本前频道类平台应该无法使用战报功能与日报功能。此版本在订阅本群与绑定玩家时将存储channelId而不是guildID,对于非频道类平台这两个值是一样的,不会造成影响。但频道类平台应该会彻底失效,解决方案只有操作数据库,将channelId填入原先guildId处(兼容原因,未修改数据库字段名[guildId],但实际上存入的已经是channel的ID了;guildId和channelId可参考数据库表channel中的数据),或重新订阅与绑定。(若是重新订阅与绑定,不会覆盖原先存储guildId的数据,也就是说旧数据依然会存在,可根据需求选择是否删除)
|
|
92
114
|
</details>
|
|
93
115
|
|
|
94
|
-
|
|
116
|
+
# 1.1.8
|
|
95
117
|
**改进**:将数据获取方式从 npm 包 `axios` 切换为 Koishi 提供的 `http` 服务,并简化了相关代码(用户体验无差别)。
|
|
96
118
|
**改进**:为 `match_2` 模板添加了玩家小队标识(效果与 `match_1` 模板中的相同功能一致,但在显示上进行了微调)。
|
|
97
119
|
|
|
98
|
-
|
|
120
|
+
# 1.1.7
|
|
99
121
|
**改进**:玩家信息模板中代表位置的图标替换为简约风格图标
|
|
100
122
|
**修复**:于v1.1.5新增的`7.36`指令生成英雄改动图片时会额外产生的测试用的`remainingContent.html`文件,现已不再生成。(如果之前使用了该命令并产生了此文件,可根据需要手动删除。位于`koishi/node_modules/@sjtdev/koishi-plugin-dota2tracker/`)
|
|
101
123
|
|
|
102
|
-
|
|
124
|
+
# 1.1.6
|
|
103
125
|
由于近期stratz网站问题,比赛数据无法自动解析,导致bot会一直等待解析后的战报数据而无法发送。
|
|
104
126
|
**新增**:现在调整为比赛结束1小时后仍然未解析时将直接发出缺失部分数据的战报(缺失包括BP顺序、出装时间、英雄受到伤害等)
|
|
105
127
|
#### hotfix
|
|
106
128
|
**修复**:修复引发播报未解析比赛战报失败的一个小问题
|
|
107
129
|
|
|
108
|
-
|
|
130
|
+
# 1.1.5
|
|
109
131
|
**新增**:为新版本7.36添加新指令`7.36`
|
|
110
132
|
`7.36 <英雄ID|英雄名|英雄常用别名>`可查询对应英雄的改动信息,未输入英雄查询参数时直接返回官网7.36更新日志链接
|
|
111
133
|
添加`--refresh|-r`参数可强制重新获取数据,如`7.36 -r`,也可在查询时使用,如`7.36 敌法师 -r`
|
|
112
134
|
|
|
113
|
-
|
|
135
|
+
# 1.1.4
|
|
114
136
|
**改进**:完善查询玩家指定英雄的生成模板
|
|
115
137
|
|
|
116
|
-
|
|
138
|
+
# 1.1.3
|
|
117
139
|
**新增**:新增实验性功能【日报昨日总结】,在指定时间播报昨日已订阅群组中已绑定群友的战绩(简略文字),默认关闭,可在插件配置中打开
|
|
118
140
|
`查询玩家`指令新增功能,现在额外输入参数`--hero <英雄ID|英雄名|英雄常用别名>`可查询目标玩家指定英雄的详情(--hero可替换为-o)
|
|
119
141
|
例如:
|
|
120
142
|
* `查询玩家 123456789 --hero 敌法师`
|
|
121
143
|
* `查询玩家 -o 敌法师` (仍可缺省玩家参数以自查)
|
|
122
144
|
|
|
123
|
-
|
|
145
|
+
# 1.1.2
|
|
124
146
|
**改进**:完成查询群友功能
|
|
125
147
|
**修复**:修复玩家模板中显示NaN的部分
|
|
126
148
|
#### hotfix
|
|
@@ -132,9 +154,9 @@
|
|
|
132
154
|
### 1.1.2-beta
|
|
133
155
|
**改进**:为`查询群友`添加模板,还在调整布局中
|
|
134
156
|
|
|
135
|
-
|
|
157
|
+
# 1.1.1
|
|
136
158
|
**改进**:玩家信息模板添加近25场内各个位置表现展示
|
|
137
159
|
|
|
138
|
-
|
|
160
|
+
# 1.1.0
|
|
139
161
|
**改进**:使用ejs重写模板相关代码使其模块化,使新增模板更方便
|
|
140
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
|
|
313
|
+
players {
|
|
314
|
+
steamAccount {
|
|
315
|
+
id
|
|
316
|
+
}
|
|
314
317
|
isRadiant
|
|
315
318
|
lane
|
|
316
319
|
kills
|
|
@@ -1420,7 +1423,7 @@ async function apply(ctx, config) {
|
|
|
1420
1423
|
}
|
|
1421
1424
|
});
|
|
1422
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) => {
|
|
1423
|
-
if (session.guild) {
|
|
1426
|
+
if (session.guild || !session.guild && input_data) {
|
|
1424
1427
|
let sessionPlayer;
|
|
1425
1428
|
if (!input_data) {
|
|
1426
1429
|
sessionPlayer = (await ctx.database.get("dt_subscribed_players", { guildId: session.event.channel.id, platform: session.event.platform, userId: session.event.user.id }))[0];
|
|
@@ -1486,6 +1489,8 @@ async function apply(ctx, config) {
|
|
|
1486
1489
|
ctx.logger.error(error);
|
|
1487
1490
|
session.send("获取玩家信息失败。");
|
|
1488
1491
|
}
|
|
1492
|
+
} else {
|
|
1493
|
+
session.send("<p>指令调用失败。</p><p>当前不属于群聊状态,必须提供指定玩家的SteamID。</p>");
|
|
1489
1494
|
}
|
|
1490
1495
|
});
|
|
1491
1496
|
ctx.command("查询英雄 <input_data>", "查询英雄技能/面板信息").usage("查询英雄的技能说明与各项数据,生成图片发布。\n参数可输入英雄ID、英雄名、英雄常用别名").option("random", "-r 随机选择英雄").example("查询英雄 15").example("查询英雄 雷泽").example("查询英雄 电魂").action(async ({ session, options }, input_data) => {
|
|
@@ -1781,17 +1786,18 @@ async function apply(ctx, config) {
|
|
|
1781
1786
|
let idsToFind = commingGuild.players.map((player) => player.steamId);
|
|
1782
1787
|
let broadPlayers = match.players.filter((item) => idsToFind.includes(item.steamAccountId));
|
|
1783
1788
|
for (let player of broadPlayers) {
|
|
1784
|
-
|
|
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])}`;
|
|
1785
1791
|
if (player.isRadiant == match.didRadiantWin) {
|
|
1786
1792
|
if (player.deathContribution < 0.2 || player.killContribution > 0.75 || player.heroDamage / player.networth > 1.5 || player.towerDamage > 1e4 || player.imp > 0)
|
|
1787
|
-
broadPlayerMessage +=
|
|
1793
|
+
broadPlayerMessage += random2.pick(WIN_POSITIVE);
|
|
1788
1794
|
else
|
|
1789
|
-
broadPlayerMessage +=
|
|
1795
|
+
broadPlayerMessage += random2.pick(WIN_NEGATIVE);
|
|
1790
1796
|
} else {
|
|
1791
1797
|
if (player.deathContribution < 0.25 || player.killContribution > 0.75 || player.heroDamage / player.networth > 1.25 || player.towerDamage > 5e3 || player.imp > 0)
|
|
1792
|
-
broadPlayerMessage +=
|
|
1798
|
+
broadPlayerMessage += random2.pick(LOSE_POSITIVE);
|
|
1793
1799
|
else
|
|
1794
|
-
broadPlayerMessage +=
|
|
1800
|
+
broadPlayerMessage += random2.pick(LOSE_NEGATIVE);
|
|
1795
1801
|
}
|
|
1796
1802
|
broadPlayerMessage += `。
|
|
1797
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)}%`;
|
|
@@ -1838,6 +1844,16 @@ function genImageHTML(data, template, type) {
|
|
|
1838
1844
|
return result;
|
|
1839
1845
|
}
|
|
1840
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");
|
|
1841
1857
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1842
1858
|
0 && (module.exports = {
|
|
1843
1859
|
Config,
|
package/package.json
CHANGED
|
@@ -338,7 +338,7 @@
|
|
|
338
338
|
nearWinCount = 0,
|
|
339
339
|
streak = 0;
|
|
340
340
|
player.matches.forEach((match) => {
|
|
341
|
-
const innerPlayer = match.players
|
|
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
|
|
391
|
-
let winCount = currentPositionMatches.filter(match=>match.didRadiantWin == match.players
|
|
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
|
|
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
|
|
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
|
-
|
|
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>
|