@sjtdev/koishi-plugin-dota2tracker 1.2.8-pre → 1.2.8
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 +26 -3
- package/lib/index.js +103 -83
- package/package.json +2 -2
- package/readme.md +2 -0
- package/template/hero/hero_1.ejs +15 -21
- package/template/match/match_2.ejs +16 -3
package/changelog.md
CHANGED
|
@@ -1,11 +1,34 @@
|
|
|
1
|
+
# 1.2.8
|
|
2
|
+
**新增**:
|
|
3
|
+
- 新增周报功能,效果等同日报。
|
|
4
|
+
- 日报与周报中新增可关闭总结中显示组合的功能。
|
|
5
|
+
|
|
6
|
+
**改进**:
|
|
7
|
+
- 现在`查询玩家`与`查询最近比赛`指令可在私聊状态下使用,必须提供SteamID参数。
|
|
8
|
+
- 将战报中的播报评语由随机选取改为固定种子:比赛ID+玩家SteamID+玩家位置,确保在不同调用时刻、次数及平台下,对同一场比赛中的玩家评语保持一致。
|
|
9
|
+
- `查询玩家`指令图片中,玩家近期比赛表中未解析的场次参战率由"?%"改为估算值,显示为"≈xx%"。
|
|
10
|
+
- `查询英雄`指令图片中,由于命石带来的属性数值无法确定作用方式(增加或是替换等),去除命石属性前的“+”,请结合命石说明自行判断。(7.37版本更新带来的API变动,导致使用指令查询某些英雄报错问题,暂无法解决)
|
|
11
|
+
- 比赛图片模板`match_2`中,现在冠绝排名数字位置更准确了。
|
|
12
|
+
- 比赛图片模板`match_2`中,比赛段位可以显示星级了。
|
|
13
|
+
|
|
14
|
+
<details>
|
|
15
|
+
<summary>为什么未解析的比赛需要“估算”?</summary>
|
|
16
|
+
比赛未解析无法获取“团队击杀数”,若是将己方所有玩家的击杀数相加,则会漏掉那些由小兵、防御塔等非玩家单位击杀数;若是将敌方所有玩家的死亡数相加,又会多出送野、自杀等不应算在己方战果中的计数。<br>目前程序采用将己方所有击杀数累加的方式来估算参战率,可能会略高于实际值。
|
|
17
|
+
</details>
|
|
18
|
+
|
|
19
|
+
<details>
|
|
20
|
+
<summary><b>1.2.8-pre更新日志</b></summary>
|
|
21
|
+
|
|
1
22
|
### 1.2.8-pre
|
|
2
23
|
**改进**:
|
|
3
24
|
- 现在`查询玩家`可在私聊状态使用,必须提供SteamID参数。
|
|
4
25
|
- 将战报中的播报评语由随机选取改为固定种子:比赛ID+玩家SteamID,确保在不同调用时刻、次数及平台下,对同一场比赛中的玩家评语保持一致。
|
|
5
26
|
- `查询玩家`指令图片中,玩家近期比赛表中未解析的场次参战率由"?%"改为估算值,显示为"≈xx%"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
27
|
+
|
|
28
|
+
##### pre.2
|
|
29
|
+
**改进**:
|
|
30
|
+
- 比赛图片模板`match_2`中,现在冠绝排名数字位置更准确了。
|
|
31
|
+
- 比赛图片模板`match_2`中,比赛段位可以显示星级了。
|
|
9
32
|
</details>
|
|
10
33
|
|
|
11
34
|
# 1.2.7
|
package/lib/index.js
CHANGED
|
@@ -117,6 +117,7 @@ function MATCH_INFO(matchId) {
|
|
|
117
117
|
leaverStatus
|
|
118
118
|
partyId
|
|
119
119
|
position
|
|
120
|
+
playerSlot
|
|
120
121
|
lane
|
|
121
122
|
imp
|
|
122
123
|
kills
|
|
@@ -1213,7 +1214,19 @@ var Config = import_koishi.Schema.intersect([
|
|
|
1213
1214
|
import_koishi.Schema.union([
|
|
1214
1215
|
import_koishi.Schema.object({
|
|
1215
1216
|
dailyReportSwitch: import_koishi.Schema.const(true).required(),
|
|
1216
|
-
dailyReportHours: import_koishi.Schema.number().min(0).max(23).default(6).description("日报时间小时")
|
|
1217
|
+
dailyReportHours: import_koishi.Schema.number().min(0).max(23).default(6).description("日报时间小时"),
|
|
1218
|
+
dailyReportShowCombi: import_koishi.Schema.boolean().default(true).description("日报是否显示组合")
|
|
1219
|
+
}),
|
|
1220
|
+
import_koishi.Schema.object({})
|
|
1221
|
+
]),
|
|
1222
|
+
import_koishi.Schema.object({
|
|
1223
|
+
weeklyReportSwitch: import_koishi.Schema.boolean().default(false).description("周报功能").experimental()
|
|
1224
|
+
}),
|
|
1225
|
+
import_koishi.Schema.union([
|
|
1226
|
+
import_koishi.Schema.object({
|
|
1227
|
+
weeklyReportSwitch: import_koishi.Schema.const(true).required(),
|
|
1228
|
+
weeklyReportDayHours: import_koishi.Schema.tuple([import_koishi.Schema.number().min(1).max(7), import_koishi.Schema.number().min(0).max(23)]).default([1, 10]).description("周报发布于周(几)的(几)点"),
|
|
1229
|
+
weeklyReportShowCombi: import_koishi.Schema.boolean().default(true).description("周报是否显示组合")
|
|
1217
1230
|
}),
|
|
1218
1231
|
import_koishi.Schema.object({})
|
|
1219
1232
|
]),
|
|
@@ -1397,7 +1410,7 @@ async function apply(ctx, config) {
|
|
|
1397
1410
|
queryMatchAndSend(session, match_id);
|
|
1398
1411
|
});
|
|
1399
1412
|
ctx.command("查询最近比赛 [input_data]", "查询玩家的最近比赛").usage("查询指定玩家的最近一场比赛的比赛数据,生成图片发布。\n参数可输入该玩家的SteamID或已在本群绑定玩家的别名,无参数时尝试查询调用指令玩家的SteamID").example("查询最近比赛 123456789").example("查询最近比赛 张三").action(async ({ session }, input_data) => {
|
|
1400
|
-
if (session.guild) {
|
|
1413
|
+
if (session.guild || !session.guild && input_data) {
|
|
1401
1414
|
let sessionPlayer;
|
|
1402
1415
|
if (!input_data) {
|
|
1403
1416
|
sessionPlayer = (await ctx.database.get("dt_subscribed_players", { guildId: session.event.channel.id, platform: session.event.platform, userId: session.event.user.id }))[0];
|
|
@@ -1420,6 +1433,8 @@ async function apply(ctx, config) {
|
|
|
1420
1433
|
return;
|
|
1421
1434
|
}
|
|
1422
1435
|
queryMatchAndSend(session, lastMatchId);
|
|
1436
|
+
} else {
|
|
1437
|
+
session.send("<p>指令调用失败。</p><p>当前不属于群聊状态,必须提供指定玩家的SteamID。</p>");
|
|
1423
1438
|
}
|
|
1424
1439
|
});
|
|
1425
1440
|
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) => {
|
|
@@ -1663,81 +1678,13 @@ async function apply(ctx, config) {
|
|
|
1663
1678
|
if (config.dailyReportSwitch) {
|
|
1664
1679
|
ctx.cron(`0 ${config.dailyReportHours} * * *`, async function() {
|
|
1665
1680
|
const oneDayAgo = (0, import_moment.default)().subtract(1, "days").unix();
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
)).data.players.filter((player) => player.matches.length > 0);
|
|
1674
|
-
const matches = players.map((player) => player.matches.map((match) => match)).flat().filter((item, index, self) => index === self.findIndex((t) => t.id === item.id));
|
|
1675
|
-
for (let subPlayer of subscribedPlayersInGuild) {
|
|
1676
|
-
let player = players.find((player2) => subPlayer.steamId == player2.steamAccount.id);
|
|
1677
|
-
if (!player)
|
|
1678
|
-
continue;
|
|
1679
|
-
let guildMember;
|
|
1680
|
-
try {
|
|
1681
|
-
guildMember = await ctx.bots.find((bot) => bot.platform == subPlayer.platform)?.getGuildMember(subPlayer.guildId, subPlayer.userId);
|
|
1682
|
-
} catch (error) {
|
|
1683
|
-
ctx.logger.error("获取群组信息失败。" + error);
|
|
1684
|
-
}
|
|
1685
|
-
subPlayer.name = subPlayer.nickName || (guildMember?.nick ?? players.find((player2) => player2.steamAccount.id == subPlayer.steamId)?.steamAccount.name);
|
|
1686
|
-
player.winCount = player.matches.filter((match) => match.didRadiantWin == match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).isRadiant).length;
|
|
1687
|
-
player.loseCount = player.matches.length - player.winCount;
|
|
1688
|
-
player.avgKills = roundToDecimalPlaces(player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).kills, 0) / player.matches.length, 2);
|
|
1689
|
-
player.avgDeaths = roundToDecimalPlaces(player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).deaths, 0) / player.matches.length, 2);
|
|
1690
|
-
player.avgAssists = roundToDecimalPlaces(
|
|
1691
|
-
player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).assists, 0) / player.matches.length,
|
|
1692
|
-
2
|
|
1693
|
-
);
|
|
1694
|
-
player.avgKDA = roundToDecimalPlaces((player.avgKills + player.avgAssists) / (player.avgDeaths || 1), 2);
|
|
1695
|
-
player.avgImp = roundToDecimalPlaces(player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).imp, 0) / player.matches.length, 0);
|
|
1696
|
-
subPlayer = Object.assign(subPlayer, player);
|
|
1697
|
-
}
|
|
1698
|
-
for (let guild of subscribedGuilds) {
|
|
1699
|
-
const currentsubscribedPlayers = subscribedPlayersInGuild.filter((player) => player.platform == guild.platform && player.guildId == guild.guildId && player.matches?.length);
|
|
1700
|
-
if (currentsubscribedPlayers.length) {
|
|
1701
|
-
const currentsubscribedPlayersIds = currentsubscribedPlayers.map((player) => player.steamId);
|
|
1702
|
-
const combinationsMap = /* @__PURE__ */ new Map();
|
|
1703
|
-
matches.forEach((match) => {
|
|
1704
|
-
const sortedPlayerIds = match.players.map((player) => player.steamAccount.id).filter((id) => currentsubscribedPlayersIds.includes(id)).sort((a, b) => a - b);
|
|
1705
|
-
const key = sortedPlayerIds.join(",");
|
|
1706
|
-
if (!combinationsMap.has(key)) {
|
|
1707
|
-
const players2 = currentsubscribedPlayers.filter((subPlayer) => sortedPlayerIds.includes(subPlayer.steamId));
|
|
1708
|
-
if (players2.length > 0) {
|
|
1709
|
-
const name2 = players2.map((subPlayer) => subPlayer.name).join("/");
|
|
1710
|
-
combinationsMap.set(key, {
|
|
1711
|
-
players: players2,
|
|
1712
|
-
name: name2,
|
|
1713
|
-
winCount: match.didRadiantWin == match.players.find((innerPlayer) => innerPlayer.steamAccount.id == players2[0].steamId).isRadiant ? 1 : 0,
|
|
1714
|
-
matches: [match]
|
|
1715
|
-
});
|
|
1716
|
-
}
|
|
1717
|
-
} else {
|
|
1718
|
-
const combi = combinationsMap.get(key);
|
|
1719
|
-
combi.matches.push(match);
|
|
1720
|
-
combi.winCount += match.didRadiantWin == match.players.find((innerPlayer) => innerPlayer.steamAccount.id == combi.players[0].steamId).isRadiant ? 1 : 0;
|
|
1721
|
-
}
|
|
1722
|
-
});
|
|
1723
|
-
const combinations = Array.from(combinationsMap.values());
|
|
1724
|
-
try {
|
|
1725
|
-
await ctx.broadcast(
|
|
1726
|
-
[`${guild.platform}:${guild.guildId}`],
|
|
1727
|
-
`昨日总结:
|
|
1728
|
-
${currentsubscribedPlayers.map(
|
|
1729
|
-
(player) => `${player.name}: ${player.winCount}胜${player.loseCount}负 胜率${Math.round(player.winCount / player.matches.length * 100)}%,平均KDA: [${player.avgKills}/${player.avgDeaths}/${player.avgAssists}](${player.avgKDA}),平均表现: ${player.avgImp > 0 ? "+" : ""}${player.avgImp}`
|
|
1730
|
-
).join("\n")}
|
|
1731
|
-
${combinations.map((combi) => `组合[${combi.name}]: ${combi.winCount}胜${combi.matches.length - combi.winCount}负 胜率${Math.round(combi.winCount / combi.matches.length * 100)}%`).join("\n")}`.replace(
|
|
1732
|
-
/\s*\n\s*/g,
|
|
1733
|
-
"\n"
|
|
1734
|
-
)
|
|
1735
|
-
);
|
|
1736
|
-
} catch (error) {
|
|
1737
|
-
ctx.logger.error(error);
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1740
|
-
}
|
|
1681
|
+
await report(oneDayAgo, "昨日总结", config.dailyReportShowCombi);
|
|
1682
|
+
});
|
|
1683
|
+
}
|
|
1684
|
+
if (config.weeklyReportSwitch) {
|
|
1685
|
+
ctx.cron(`0 ${config.weeklyReportDayHours[1]} * * ${config.weeklyReportDayHours[0]}`, async function() {
|
|
1686
|
+
const oneWeekAgo = (0, import_moment.default)().subtract(1, "weeks").unix();
|
|
1687
|
+
await report(oneWeekAgo, "上周总结", config.weeklyReportShowCombi);
|
|
1741
1688
|
});
|
|
1742
1689
|
}
|
|
1743
1690
|
ctx.cron("* * * * *", async function() {
|
|
@@ -1786,15 +1733,16 @@ async function apply(ctx, config) {
|
|
|
1786
1733
|
let idsToFind = commingGuild.players.map((player) => player.steamId);
|
|
1787
1734
|
let broadPlayers = match.players.filter((item) => idsToFind.includes(item.steamAccountId));
|
|
1788
1735
|
for (let player of broadPlayers) {
|
|
1789
|
-
const random2 = new import_koishi2.Random(() => simpleHashToSeed(match.id
|
|
1736
|
+
const random2 = new import_koishi2.Random(() => simpleHashToSeed(`${match.id}-${player.steamAccountId}-${player.playerSlot}`));
|
|
1790
1737
|
let broadPlayerMessage = `${player.steamAccount.name}的${random2.pick(HEROES_CHINESE[player.hero.id])}`;
|
|
1738
|
+
console.log([player.deathContribution, player.killContribution]);
|
|
1791
1739
|
if (player.isRadiant == match.didRadiantWin) {
|
|
1792
1740
|
if (player.deathContribution < 0.2 || player.killContribution > 0.75 || player.heroDamage / player.networth > 1.5 || player.towerDamage > 1e4 || player.imp > 0)
|
|
1793
1741
|
broadPlayerMessage += random2.pick(WIN_POSITIVE);
|
|
1794
1742
|
else
|
|
1795
1743
|
broadPlayerMessage += random2.pick(WIN_NEGATIVE);
|
|
1796
1744
|
} else {
|
|
1797
|
-
if (player.deathContribution < 0.25 || player.killContribution > 0.75 || player.heroDamage / player.networth > 1
|
|
1745
|
+
if (player.deathContribution < 0.25 || player.killContribution > 0.75 || player.heroDamage / player.networth > 1 || player.towerDamage > 5e3 || player.imp > 0)
|
|
1798
1746
|
broadPlayerMessage += random2.pick(LOSE_POSITIVE);
|
|
1799
1747
|
else
|
|
1800
1748
|
broadPlayerMessage += random2.pick(LOSE_NEGATIVE);
|
|
@@ -1804,7 +1752,7 @@ KDA:${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)} [${
|
|
|
1804
1752
|
broadMatchMessage += broadPlayerMessage + "\n";
|
|
1805
1753
|
}
|
|
1806
1754
|
await ctx.broadcast([`${commingGuild.platform}:${commingGuild.guildId}`], broadMatchMessage + (ctx.config.urlInMessageType.some((type) => type == "match") ? "https://stratz.com/matches/" + match.id : "") + img);
|
|
1807
|
-
ctx.logger.info(`${match.id}${match.parsedDateTime ? "已解析," : "已结束超过1
|
|
1755
|
+
ctx.logger.info(`${match.id}${match.parsedDateTime ? "已解析," : "已结束超过1小时仍未被解析,放弃等待解析直接"}生成图片并发布于${commingGuild.platform}:${commingGuild.guildId}。`);
|
|
1808
1756
|
}
|
|
1809
1757
|
if (match.parsedDateTime)
|
|
1810
1758
|
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: match.id, data: match, queryTime: /* @__PURE__ */ new Date() }]);
|
|
@@ -1818,6 +1766,79 @@ KDA:${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)} [${
|
|
|
1818
1766
|
}
|
|
1819
1767
|
});
|
|
1820
1768
|
});
|
|
1769
|
+
async function report(timeAgo, title, showCombi) {
|
|
1770
|
+
const subscribedGuilds = await ctx.database.get("dt_subscribed_guilds", void 0);
|
|
1771
|
+
const subscribedPlayersInGuild = (await ctx.database.get("dt_subscribed_players", void 0)).filter((player) => subscribedGuilds.some((guild) => guild.guildId == player.guildId));
|
|
1772
|
+
const players = (await query(
|
|
1773
|
+
MATCHES_FOR_DAILY(
|
|
1774
|
+
subscribedPlayersInGuild.map((player) => player.steamId).filter((value, index, self) => self.indexOf(value) === index),
|
|
1775
|
+
timeAgo
|
|
1776
|
+
)
|
|
1777
|
+
)).data.players.filter((player) => player.matches.length > 0);
|
|
1778
|
+
const matches = players.map((player) => player.matches.map((match) => match)).flat().filter((item, index, self) => index === self.findIndex((t) => t.id === item.id));
|
|
1779
|
+
for (let subPlayer of subscribedPlayersInGuild) {
|
|
1780
|
+
let player = players.find((player2) => subPlayer.steamId == player2.steamAccount.id);
|
|
1781
|
+
if (!player)
|
|
1782
|
+
continue;
|
|
1783
|
+
let guildMember;
|
|
1784
|
+
try {
|
|
1785
|
+
guildMember = await ctx.bots.find((bot) => bot.platform == subPlayer.platform)?.getGuildMember(subPlayer.guildId, subPlayer.userId);
|
|
1786
|
+
} catch (error) {
|
|
1787
|
+
ctx.logger.error("获取群组信息失败。" + error);
|
|
1788
|
+
}
|
|
1789
|
+
subPlayer.name = subPlayer.nickName || (guildMember?.nick ?? players.find((player2) => player2.steamAccount.id == subPlayer.steamId)?.steamAccount.name);
|
|
1790
|
+
player.winCount = player.matches.filter((match) => match.didRadiantWin == match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).isRadiant).length;
|
|
1791
|
+
player.loseCount = player.matches.length - player.winCount;
|
|
1792
|
+
player.avgKills = roundToDecimalPlaces(player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).kills, 0) / player.matches.length, 2);
|
|
1793
|
+
player.avgDeaths = roundToDecimalPlaces(player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).deaths, 0) / player.matches.length, 2);
|
|
1794
|
+
player.avgAssists = roundToDecimalPlaces(player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).assists, 0) / player.matches.length, 2);
|
|
1795
|
+
player.avgKDA = roundToDecimalPlaces((player.avgKills + player.avgAssists) / (player.avgDeaths || 1), 2);
|
|
1796
|
+
player.avgImp = roundToDecimalPlaces(player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).imp, 0) / player.matches.length, 0);
|
|
1797
|
+
subPlayer = Object.assign(subPlayer, player);
|
|
1798
|
+
}
|
|
1799
|
+
for (let guild of subscribedGuilds) {
|
|
1800
|
+
const currentsubscribedPlayers = subscribedPlayersInGuild.filter((player) => player.platform == guild.platform && player.guildId == guild.guildId && player.matches?.length);
|
|
1801
|
+
if (currentsubscribedPlayers.length) {
|
|
1802
|
+
const currentsubscribedPlayersIds = currentsubscribedPlayers.map((player) => player.steamId);
|
|
1803
|
+
const combinationsMap = /* @__PURE__ */ new Map();
|
|
1804
|
+
matches.forEach((match) => {
|
|
1805
|
+
const sortedPlayerIds = match.players.map((player) => player.steamAccount.id).filter((id) => currentsubscribedPlayersIds.includes(id)).sort((a, b) => a - b);
|
|
1806
|
+
const key = sortedPlayerIds.join(",");
|
|
1807
|
+
if (!combinationsMap.has(key)) {
|
|
1808
|
+
const players2 = currentsubscribedPlayers.filter((subPlayer) => sortedPlayerIds.includes(subPlayer.steamId));
|
|
1809
|
+
if (players2.length > 0) {
|
|
1810
|
+
const name2 = players2.map((subPlayer) => subPlayer.name).join("/");
|
|
1811
|
+
combinationsMap.set(key, {
|
|
1812
|
+
players: players2,
|
|
1813
|
+
name: name2,
|
|
1814
|
+
winCount: match.didRadiantWin == match.players.find((innerPlayer) => innerPlayer.steamAccount.id == players2[0].steamId).isRadiant ? 1 : 0,
|
|
1815
|
+
matches: [match]
|
|
1816
|
+
});
|
|
1817
|
+
}
|
|
1818
|
+
} else {
|
|
1819
|
+
const combi = combinationsMap.get(key);
|
|
1820
|
+
combi.matches.push(match);
|
|
1821
|
+
combi.winCount += match.didRadiantWin == match.players.find((innerPlayer) => innerPlayer.steamAccount.id == combi.players[0].steamId).isRadiant ? 1 : 0;
|
|
1822
|
+
}
|
|
1823
|
+
});
|
|
1824
|
+
const combinations = Array.from(combinationsMap.values());
|
|
1825
|
+
try {
|
|
1826
|
+
await ctx.broadcast(
|
|
1827
|
+
[`${guild.platform}:${guild.guildId}`],
|
|
1828
|
+
`${title}:
|
|
1829
|
+
${currentsubscribedPlayers.map(
|
|
1830
|
+
(player) => `${player.name}: ${player.winCount}胜${player.loseCount}负 胜率${Math.round(player.winCount / player.matches.length * 100)}%,平均KDA: [${player.avgKills}/${player.avgDeaths}/${player.avgAssists}](${player.avgKDA}),平均表现: ${player.avgImp > 0 ? "+" : ""}${player.avgImp}`
|
|
1831
|
+
).join("\n")}
|
|
1832
|
+
${showCombi ? combinations.map((combi) => `组合[${combi.name}]: ${combi.winCount}胜${combi.matches.length - combi.winCount}负 胜率${Math.round(combi.winCount / combi.matches.length * 100)}%`).join("\n") : ""}`.replace(/\s*\n\s*/g, "\n")
|
|
1833
|
+
);
|
|
1834
|
+
ctx.logger.info(`发布日报于${guild.platform}:${guild.guildId}`);
|
|
1835
|
+
} catch (error) {
|
|
1836
|
+
ctx.logger.error(error);
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
__name(report, "report");
|
|
1821
1842
|
ctx.on("dispose", async () => {
|
|
1822
1843
|
});
|
|
1823
1844
|
}
|
|
@@ -1844,9 +1865,8 @@ function genImageHTML(data, template, type) {
|
|
|
1844
1865
|
return result;
|
|
1845
1866
|
}
|
|
1846
1867
|
__name(genImageHTML, "genImageHTML");
|
|
1847
|
-
function simpleHashToSeed(
|
|
1848
|
-
const
|
|
1849
|
-
const encoded = btoa(input);
|
|
1868
|
+
function simpleHashToSeed(inputString) {
|
|
1869
|
+
const encoded = btoa(inputString);
|
|
1850
1870
|
let total = 0;
|
|
1851
1871
|
for (let i = 0; i < encoded.length; i++) {
|
|
1852
1872
|
total += encoded.charCodeAt(i);
|
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.8
|
|
4
|
+
"version": "1.2.8",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dota2"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"dotaconstants": "^8.
|
|
29
|
+
"dotaconstants": "^8.10.0",
|
|
30
30
|
"ejs": "^3.1.10",
|
|
31
31
|
"moment": "^2.30.1"
|
|
32
32
|
},
|
package/readme.md
CHANGED
|
@@ -12,6 +12,8 @@ DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑
|
|
|
12
12
|
在希望推送战报信息的群组(或频道)使用指令`订阅本群`,玩家可使用指令`绑定`来将自身账号与Steam账号绑定,bot会尝试追踪已订阅群组(或频道)中的绑定玩家的最新对局信息。
|
|
13
13
|
其他查询功能见下方指令说明。
|
|
14
14
|
**直接调用help指令可获取更详细的说明,调用【指令 -h】还会有用法示例。(例如:订阅本群 -h)**
|
|
15
|
+
**本插件使用的所有SteamID均为SteamID3类型(即DOTA2游戏内个人页面显示的好友ID与stratz登录后个人页面链接中显示的ID),有关SteamID类型见 https://steamid.tatlead.com/ (由[issue](../../issues/1)提供,感谢这位用户)**
|
|
16
|
+
|
|
15
17
|
**更新日志见[changelog](changelog.md)**
|
|
16
18
|
|
|
17
19
|
### 指令
|
package/template/hero/hero_1.ejs
CHANGED
|
@@ -683,7 +683,7 @@
|
|
|
683
683
|
`).join("")}
|
|
684
684
|
</div>
|
|
685
685
|
<div class="skills">
|
|
686
|
-
${hero.abilities//.filter((item) => dotaconstants.abilities[item.name]
|
|
686
|
+
${hero.abilities//.filter((item) => dotaconstants.abilities[item.name]?.behavior != "Hidden")
|
|
687
687
|
.map((item) => `
|
|
688
688
|
<div class="skill" data-innate="${item.ability_is_innate&&!item.ability_is_facet}">
|
|
689
689
|
<p class="title">
|
|
@@ -695,26 +695,20 @@
|
|
|
695
695
|
<div class="img_stats">
|
|
696
696
|
<img src="${utils.getImageUrl(item.name, ImageType.Abilities)}" onerror="this.onerror=null; this.src='${utils.getImageUrl(`innate_icon`,ImageType.Icons)}';"/>
|
|
697
697
|
<div class="stats">
|
|
698
|
-
<p class="behavior">技能:${
|
|
698
|
+
<p class="behavior">技能:${[].concat(dotaconstants.abilities[item.name]?.behavior)
|
|
699
699
|
.filter((beh) => beh !== "Hidden" || !(item.ability_is_granted_by_shard || item.ability_is_granted_by_scepter))
|
|
700
|
-
.map((beh) => d2a.behavior[beh])
|
|
701
|
-
|
|
702
|
-
${dotaconstants.abilities[item.name]
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
${
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
${dotaconstants.abilities[item.name].dispellable
|
|
713
|
-
? `<p class="dispellable ${dotaconstants.abilities[item.name].dispellable == "Strong Dispels Only" ? "Strong" : dotaconstants.abilities[item.name].dispellable}">能否驱散:</p>`
|
|
714
|
-
: ""}
|
|
715
|
-
${!Array.isArray(dotaconstants.abilities[item.name].bkbpierce) && dotaconstants.abilities[item.name].bkbpierce
|
|
716
|
-
? `<p class="bkbpierce">无视减益免疫: ${dotaconstants.abilities[item.name].bkbpierce == "Yes" ? "是" : "否"}</p>`
|
|
717
|
-
: ""}
|
|
700
|
+
.map((beh) => d2a.behavior[beh]).join("/")}
|
|
701
|
+
</p>
|
|
702
|
+
${dotaconstants.abilities[item.name]?.target_team ?
|
|
703
|
+
`<p class="target_team">影响:${[].concat(dotaconstants.abilities[item.name]?.target_team)
|
|
704
|
+
.map((tt) => d2a.target_team[tt]).join("/")}
|
|
705
|
+
</p>` : ""}
|
|
706
|
+
${!Array.isArray(dotaconstants.abilities[item.name]?.dmg_type) && dotaconstants.abilities[item.name]?.dmg_type ?
|
|
707
|
+
`<p class="dmg_type ${dotaconstants.abilities[item.name]?.dmg_type}">伤害类型:</p>` : ""}
|
|
708
|
+
${dotaconstants.abilities[item.name]?.dispellable ?
|
|
709
|
+
`<p class="dispellable ${dotaconstants.abilities[item.name]?.dispellable == "Strong Dispels Only" ? "Strong" : dotaconstants.abilities[item.name]?.dispellable}">能否驱散:</p>` : ""}
|
|
710
|
+
${!Array.isArray(dotaconstants.abilities[item.name]?.bkbpierce) && dotaconstants.abilities[item.name]?.bkbpierce ?
|
|
711
|
+
`<p class="bkbpierce">无视减益免疫: ${dotaconstants.abilities[item.name]?.bkbpierce == "Yes" ? "是" : "否"}</p>` : ""}
|
|
718
712
|
</div>
|
|
719
713
|
</div>
|
|
720
714
|
<p class="description">${item.desc_loc}</p>
|
|
@@ -768,7 +762,7 @@
|
|
|
768
762
|
</span>` : "" }
|
|
769
763
|
${sv.facet_bonus.name ?
|
|
770
764
|
`<span class="alternative facet">
|
|
771
|
-
<span class="facet"><span class="name_back type_${hero.facets.find(facet=>facet.name==sv.facet_bonus.name).color}"><img src="${utils.getImageUrl(hero.facets.find(facet=>facet.name==sv.facet_bonus.name).icon, ImageType.IconsFacets)}" />${sv.facet_bonus.values.map(value =>
|
|
765
|
+
<span class="facet"><span class="name_back type_${hero.facets.find(facet=>facet.name==sv.facet_bonus.name).color}"><img src="${utils.getImageUrl(hero.facets.find(facet=>facet.name==sv.facet_bonus.name).icon, ImageType.IconsFacets)}" />${sv.facet_bonus.values.map(value => value + (sv.is_percentage ? "%" : "")).join(" / ")}</span></span>
|
|
772
766
|
</span>` : "" }
|
|
773
767
|
${sv.bonuses.length ?
|
|
774
768
|
`<span class="alternative talent">
|
|
@@ -49,6 +49,18 @@
|
|
|
49
49
|
color: #ffb400;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
nav > .rank {
|
|
53
|
+
width: 48px;
|
|
54
|
+
height: 48px;
|
|
55
|
+
position: relative;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
nav > .rank > img {
|
|
59
|
+
width: 48px;
|
|
60
|
+
height: 48px;
|
|
61
|
+
position: absolute;
|
|
62
|
+
}
|
|
63
|
+
|
|
52
64
|
.radiant {
|
|
53
65
|
color: #3c9028;
|
|
54
66
|
}
|
|
@@ -232,9 +244,9 @@
|
|
|
232
244
|
.player > .rank > p {
|
|
233
245
|
position: absolute;
|
|
234
246
|
width: 100%;
|
|
235
|
-
bottom:
|
|
247
|
+
bottom: 1.5px;
|
|
236
248
|
text-align: center;
|
|
237
|
-
font-size:
|
|
249
|
+
font-size: 8px;
|
|
238
250
|
color: #fff;
|
|
239
251
|
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; /* 文字描边 */
|
|
240
252
|
}
|
|
@@ -450,7 +462,8 @@
|
|
|
450
462
|
<p><%-d2a.lobbyTypes[match.lobbyType] || match.lobbyType%>/<%-d2a.gameMode[match.gameMode] || match.gameMode%></p>
|
|
451
463
|
</div>
|
|
452
464
|
<div class="rank">
|
|
453
|
-
<img
|
|
465
|
+
<img src="<%-utils.getImageUrl('medal_' + (match.rank?.toString().split('')[0] ?? '0'))%>" alt="" />
|
|
466
|
+
<img style="z-index: 1;" src="<%-utils.getImageUrl('star_' + (match.rank?.toString().split('')[1] ?? '0'))%>" alt="" />
|
|
454
467
|
</div>
|
|
455
468
|
</nav>
|
|
456
469
|
<section class="match_result">
|