@sjtdev/koishi-plugin-dota2tracker 1.0.3 → 1.1.0
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 +152 -323
- package/package.json +3 -2
- package/readme.md +5 -2
- package/template/images/logo_dire.png +0 -0
- package/template/images/logo_radiant.png +0 -0
- package/template/images/scepter_0.png +0 -0
- package/template/images/scepter_1.png +0 -0
- package/template/images/shard_0.png +0 -0
- package/template/images/shard_1.png +0 -0
- package/template/match/match_1.ejs +996 -0
- package/template/match/match_2.ejs +438 -0
- package/template/{match.html → match_old.html} +3 -1
- /package/{images → template/images}/flag_dire.png +0 -0
- /package/{images → template/images}/flag_radiant.png +0 -0
- /package/{images → template/images}/hero_badge_1.png +0 -0
- /package/{images → template/images}/hero_badge_2.png +0 -0
- /package/{images → template/images}/hero_badge_3.png +0 -0
- /package/{images → template/images}/hero_badge_4.png +0 -0
- /package/{images → template/images}/hero_badge_5.png +0 -0
- /package/{images → template/images}/hero_badge_6.png +0 -0
- /package/{images → template/images}/medal_0.png +0 -0
- /package/{images → template/images}/medal_1.png +0 -0
- /package/{images → template/images}/medal_2.png +0 -0
- /package/{images → template/images}/medal_3.png +0 -0
- /package/{images → template/images}/medal_4.png +0 -0
- /package/{images → template/images}/medal_5.png +0 -0
- /package/{images → template/images}/medal_6.png +0 -0
- /package/{images → template/images}/medal_7.png +0 -0
- /package/{images → template/images}/medal_8.png +0 -0
- /package/{images → template/images}/medal_8b.png +0 -0
- /package/{images → template/images}/medal_8c.png +0 -0
- /package/{images → template/images}/star_0.png +0 -0
- /package/{images → template/images}/star_1.png +0 -0
- /package/{images → template/images}/star_2.png +0 -0
- /package/{images → template/images}/star_3.png +0 -0
- /package/{images → template/images}/star_4.png +0 -0
- /package/{images → template/images}/star_5.png +0 -0
package/lib/index.js
CHANGED
|
@@ -40,6 +40,14 @@ module.exports = __toCommonJS(src_exports);
|
|
|
40
40
|
var import_koishi = require("koishi");
|
|
41
41
|
|
|
42
42
|
// src/utils.ts
|
|
43
|
+
var utils_exports = {};
|
|
44
|
+
__export(utils_exports, {
|
|
45
|
+
CONFIGS: () => CONFIGS,
|
|
46
|
+
ImageType: () => ImageType,
|
|
47
|
+
getFormattedMatchData: () => getFormattedMatchData,
|
|
48
|
+
getImageUrl: () => getImageUrl,
|
|
49
|
+
query: () => query
|
|
50
|
+
});
|
|
43
51
|
var import_axios = __toESM(require("axios"));
|
|
44
52
|
var import_fs = __toESM(require("fs"));
|
|
45
53
|
var dotaconstants = __toESM(require("dotaconstants"));
|
|
@@ -53,10 +61,19 @@ async function query(query_str) {
|
|
|
53
61
|
});
|
|
54
62
|
}
|
|
55
63
|
__name(query, "query");
|
|
64
|
+
var ImageType = /* @__PURE__ */ ((ImageType2) => {
|
|
65
|
+
ImageType2["Icons"] = "icons";
|
|
66
|
+
ImageType2["Heroes"] = "heroes";
|
|
67
|
+
ImageType2["HeroIcons"] = "heroes/icons";
|
|
68
|
+
ImageType2["Items"] = "items";
|
|
69
|
+
ImageType2["Abilities"] = "abilities";
|
|
70
|
+
ImageType2["Local"] = "local";
|
|
71
|
+
return ImageType2;
|
|
72
|
+
})(ImageType || {});
|
|
56
73
|
function getImageUrl(image, type = "local" /* Local */) {
|
|
57
74
|
if (type === "local" /* Local */) {
|
|
58
75
|
try {
|
|
59
|
-
const imageData = import_fs.default.readFileSync(`./node_modules/@sjtdev/koishi-plugin-dota2tracker/images/${image}.png`);
|
|
76
|
+
const imageData = import_fs.default.readFileSync(`./node_modules/@sjtdev/koishi-plugin-dota2tracker/template/images/${image}.png`);
|
|
60
77
|
const base64Data = imageData.toString("base64");
|
|
61
78
|
return `data:image/png;base64,${base64Data}`;
|
|
62
79
|
} catch (error) {
|
|
@@ -68,8 +85,9 @@ function getImageUrl(image, type = "local" /* Local */) {
|
|
|
68
85
|
}
|
|
69
86
|
__name(getImageUrl, "getImageUrl");
|
|
70
87
|
function getFormattedMatchData(match) {
|
|
71
|
-
|
|
72
|
-
|
|
88
|
+
["radiant", "dire"].forEach((team) => {
|
|
89
|
+
match[team] = { killsCount: match[team + "Kills"]?.reduce((acc, cva) => acc + cva, 0) ?? 0, damageReceived: 0, heroDamage: 0, networth: 0, experience: 0 };
|
|
90
|
+
});
|
|
73
91
|
match.party = {};
|
|
74
92
|
let party_index = 0;
|
|
75
93
|
const party_mark = ["I", "II", "III", "IV"];
|
|
@@ -97,8 +115,20 @@ function getFormattedMatchData(match) {
|
|
|
97
115
|
laneResult.mid = processLaneOutcome(match.midLaneOutcome);
|
|
98
116
|
laneResult.bottom = processLaneOutcome(match.bottomLaneOutcome);
|
|
99
117
|
match.players.forEach((player) => {
|
|
100
|
-
player.
|
|
101
|
-
player.
|
|
118
|
+
player.team = player.isRadiant ? "radiant" : "dire";
|
|
119
|
+
player.rank = {
|
|
120
|
+
medal: parseInt(player.steamAccount.seasonRank?.toString().split("")[0] ?? 0),
|
|
121
|
+
star: parseInt(player.steamAccount.seasonRank?.toString().split("")[1] ?? 0),
|
|
122
|
+
leaderboard: player.steamAccount.seasonLeaderboardRank,
|
|
123
|
+
inTop100: player.steamAccount.seasonLeaderboardRank ? player.steamAccount.seasonLeaderboardRank <= 10 ? "8c" : player.steamAccount.seasonLeaderboardRank <= 100 ? "8b" : void 0 : void 0
|
|
124
|
+
};
|
|
125
|
+
player.killContribution = (player.kills + player.assists) / match[player.team].killsCount;
|
|
126
|
+
player.deathContribution = player.deaths / match[player.team === "radiant" ? "dire" : player.team].killsCount;
|
|
127
|
+
player.damageReceived = player.stats?.heroDamageReport?.receivedTotal.physicalDamage + player.stats?.heroDamageReport?.receivedTotal.magicalDamage + player.stats?.heroDamageReport?.receivedTotal.pureDamage;
|
|
128
|
+
match[player.team].heroDamage = (match[player.team].heroDamage ?? 0) + player.heroDamage;
|
|
129
|
+
match[player.team].damageReceived = (match[player.team].damageReceived ?? 0) + player.damageReceived;
|
|
130
|
+
match[player.team].networth += player.networth;
|
|
131
|
+
match[player.team].experience += Math.floor(player.experiencePerMinute / 60 * match.durationSeconds);
|
|
102
132
|
player.titles = [];
|
|
103
133
|
player.mvpScore = // 计算MVP分数
|
|
104
134
|
player.kills * 5 + player.assists * 3 + player.stats.heroDamageReport.dealtTotal.stunDuration / 100 * 0.1 + (player.stats.heroDamageReport.dealtTotal.slowDuration + player.stats.heroDamageReport.dealtTotal.disableDuration) / 100 * 0.05 + player.heroDamage * 1e-3 + player.towerDamage * 0.01 + player.heroHealing * 2e-3 + player.imp * 0.25;
|
|
@@ -117,13 +147,13 @@ function getFormattedMatchData(match) {
|
|
|
117
147
|
player.stats.matchPlayerBuffEvent.splice(0, player.stats.matchPlayerBuffEvent.length, ...Object.values(maxStackCountsByAbilityOrItem));
|
|
118
148
|
switch (player.lane) {
|
|
119
149
|
case "SAFE_LANE":
|
|
120
|
-
player.laneResult = laneResult[player.isRadiant ? "bottom" : "top"][player.
|
|
150
|
+
player.laneResult = laneResult[player.isRadiant ? "bottom" : "top"][player.team];
|
|
121
151
|
break;
|
|
122
152
|
case "OFF_LANE":
|
|
123
|
-
player.laneResult = laneResult[!player.isRadiant ? "bottom" : "top"][player.
|
|
153
|
+
player.laneResult = laneResult[!player.isRadiant ? "bottom" : "top"][player.team];
|
|
124
154
|
break;
|
|
125
155
|
default:
|
|
126
|
-
player.laneResult = laneResult.mid[player.
|
|
156
|
+
player.laneResult = laneResult.mid[player.team];
|
|
127
157
|
break;
|
|
128
158
|
}
|
|
129
159
|
let items_timelist = {};
|
|
@@ -272,8 +302,8 @@ function getFormattedMatchData(match) {
|
|
|
272
302
|
(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
|
|
273
303
|
).titles.push({ name: "耐", color: "#84A1C7" });
|
|
274
304
|
match.players.reduce((lowest, player) => {
|
|
275
|
-
const currentContribution = (player.kills + player.assists) /
|
|
276
|
-
const lowestContribution = (lowest.kills + lowest.assists) /
|
|
305
|
+
const currentContribution = (player.kills + player.assists) / match[player.team].KillsCount;
|
|
306
|
+
const lowestContribution = (lowest.kills + lowest.assists) / match[lowest.team].KillsCount;
|
|
277
307
|
if (currentContribution < lowestContribution) {
|
|
278
308
|
return player;
|
|
279
309
|
} else if (currentContribution === lowestContribution) {
|
|
@@ -658,6 +688,24 @@ var import_moment = __toESM(require("moment"));
|
|
|
658
688
|
var dotaconstants3 = __toESM(require("dotaconstants"));
|
|
659
689
|
|
|
660
690
|
// src/dotaconstants_add.json
|
|
691
|
+
var dotaconstants_add_exports = {};
|
|
692
|
+
__export(dotaconstants_add_exports, {
|
|
693
|
+
HEROES_CHINESE: () => HEROES_CHINESE,
|
|
694
|
+
LOSE_NEGATIVE: () => LOSE_NEGATIVE,
|
|
695
|
+
LOSE_POSITIVE: () => LOSE_POSITIVE,
|
|
696
|
+
WIN_NEGATIVE: () => WIN_NEGATIVE,
|
|
697
|
+
WIN_POSITIVE: () => WIN_POSITIVE,
|
|
698
|
+
behavior: () => behavior,
|
|
699
|
+
default: () => dotaconstants_add_default,
|
|
700
|
+
gameMode: () => gameMode,
|
|
701
|
+
lobbyTypes: () => lobbyTypes,
|
|
702
|
+
position: () => position,
|
|
703
|
+
primary_attrs: () => primary_attrs,
|
|
704
|
+
rank: () => rank,
|
|
705
|
+
region: () => region,
|
|
706
|
+
roles: () => roles,
|
|
707
|
+
target_team: () => target_team
|
|
708
|
+
});
|
|
661
709
|
var gameMode = {
|
|
662
710
|
NONE: "",
|
|
663
711
|
ALL_PICK: "全英雄选择",
|
|
@@ -732,6 +780,17 @@ var position = {
|
|
|
732
780
|
"4": "采灵芝",
|
|
733
781
|
"5": "工具人"
|
|
734
782
|
};
|
|
783
|
+
var rank = {
|
|
784
|
+
"0": "未知",
|
|
785
|
+
"1": "先锋",
|
|
786
|
+
"2": "卫士",
|
|
787
|
+
"3": "中军",
|
|
788
|
+
"4": "统帅",
|
|
789
|
+
"5": "传奇",
|
|
790
|
+
"6": "万古流芳",
|
|
791
|
+
"7": "超凡入圣",
|
|
792
|
+
"8": "冠绝一世"
|
|
793
|
+
};
|
|
735
794
|
var roles = { CARRY: "核心", ESCAPE: "逃生", NUKER: "爆发", INITIATOR: "先手", DURABLE: "耐久", DISABLER: "控制", JUNGLER: "打野", SUPPORT: "辅助", PUSHER: "推进" };
|
|
736
795
|
var primary_attrs = { all: "hero_universal", str: "hero_strength", agi: "hero_agility", int: "hero_intelligence" };
|
|
737
796
|
var behavior = {
|
|
@@ -877,14 +936,33 @@ var WIN_NEGATIVE = ["侥幸赢得了比赛", "走狗屎运赢得了比赛", "躺
|
|
|
877
936
|
var WIN_POSITIVE = ["带领团队走向了胜利", "暴打对面后赢得了胜利", " CARRY全场赢得了胜利", "把对面当猪宰了, 赢得了胜利", "又赢了, 这游戏就是这么枯燥, 且乏味", "直接进行一个比赛的赢"];
|
|
878
937
|
var LOSE_NEGATIVE = ["被人按在地上摩擦, 输掉了这场比赛", "悲惨地输掉了比赛", "头都被打歪了, 心态爆炸地输掉了比赛", "捕鱼被鱼吃了, 输掉了比赛", "打的是个几把", "直接进行一个比赛的输"];
|
|
879
938
|
var LOSE_POSITIVE = ["无力回天输掉了比赛", "尽力了, 但还是输了比赛", "背靠世界树, 虽败犹荣", "带不动队友, 输了比赛", "又输了, 很难受, 宁愿输的是我"];
|
|
939
|
+
var dotaconstants_add_default = {
|
|
940
|
+
gameMode,
|
|
941
|
+
lobbyTypes,
|
|
942
|
+
region,
|
|
943
|
+
position,
|
|
944
|
+
rank,
|
|
945
|
+
roles,
|
|
946
|
+
primary_attrs,
|
|
947
|
+
behavior,
|
|
948
|
+
target_team,
|
|
949
|
+
HEROES_CHINESE,
|
|
950
|
+
WIN_NEGATIVE,
|
|
951
|
+
WIN_POSITIVE,
|
|
952
|
+
LOSE_NEGATIVE,
|
|
953
|
+
LOSE_POSITIVE
|
|
954
|
+
};
|
|
880
955
|
|
|
881
956
|
// src/index.ts
|
|
882
957
|
var import_koishi2 = require("koishi");
|
|
958
|
+
var ejs = __toESM(require("ejs"));
|
|
959
|
+
var import_path = __toESM(require("path"));
|
|
883
960
|
var name = "dota2tracker";
|
|
884
961
|
var usage = "DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑定),以及一系列查询功能。";
|
|
885
962
|
var inject = ["database", "puppeteer", "cron"];
|
|
886
963
|
var Config = import_koishi.Schema.object({
|
|
887
|
-
STRATZ_API_TOKEN: import_koishi.Schema.string().required().description("※必须。stratz.com的API TOKEN,可在 https://stratz.com/api 获取")
|
|
964
|
+
STRATZ_API_TOKEN: import_koishi.Schema.string().required().description("※必须。stratz.com的API TOKEN,可在 https://stratz.com/api 获取"),
|
|
965
|
+
template_match: import_koishi.Schema.union([...readDirectoryFilesSync(`./node_modules/@sjtdev/koishi-plugin-${name}/template/match`)]).default("match_1").description("生成比赛图片使用的模板,见 https://github.com/sjtdev/koishi-plugin-dota2tracker/wiki 有模板展示。")
|
|
888
966
|
});
|
|
889
967
|
var pendingMatches = [];
|
|
890
968
|
var random = new import_koishi2.Random(() => Math.random());
|
|
@@ -977,39 +1055,45 @@ async function apply(ctx, config) {
|
|
|
977
1055
|
session.send("开发中,未来此功能会重写。\n" + queryRes.map((item) => `${item.nickName ?? ""},ID:${item.userId},SteamID:${item.steamId}`).join("\n"));
|
|
978
1056
|
}
|
|
979
1057
|
});
|
|
980
|
-
|
|
981
|
-
if (!match_id) {
|
|
982
|
-
session.send("请输入比赛ID。");
|
|
983
|
-
return;
|
|
984
|
-
}
|
|
985
|
-
if (!/^\d{10}$/.test(match_id)) {
|
|
986
|
-
session.send("比赛ID无效。");
|
|
987
|
-
return;
|
|
988
|
-
}
|
|
989
|
-
session.send("正在搜索对局详情,请稍后...");
|
|
1058
|
+
async function queryAndDisplayMatch(session, matchId) {
|
|
990
1059
|
try {
|
|
991
1060
|
let match;
|
|
992
|
-
let queryLocal = await ctx.database.get("dt_previous_query_results",
|
|
1061
|
+
let queryLocal = await ctx.database.get("dt_previous_query_results", matchId, ["data"]);
|
|
993
1062
|
if (queryLocal.length > 0) {
|
|
994
1063
|
match = queryLocal[0].data;
|
|
995
1064
|
ctx.database.set("dt_previous_query_results", match.id, { queryTime: /* @__PURE__ */ new Date() });
|
|
996
1065
|
} else {
|
|
997
|
-
let queryRes = await query(MATCH_INFO(
|
|
1066
|
+
let queryRes = await query(MATCH_INFO(matchId));
|
|
998
1067
|
if (queryRes.status == 200) {
|
|
999
1068
|
match = getFormattedMatchData(queryRes.data.data.match);
|
|
1000
1069
|
}
|
|
1001
1070
|
}
|
|
1002
|
-
if (match.parsedDateTime) {
|
|
1003
|
-
session.send(await ctx.puppeteer.render(
|
|
1071
|
+
if (match && match.parsedDateTime) {
|
|
1072
|
+
session.send(await ctx.puppeteer.render(newGenMatchImageHTML(match, config.template_match)));
|
|
1004
1073
|
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: match.id, data: match, queryTime: /* @__PURE__ */ new Date() }]);
|
|
1005
1074
|
} else {
|
|
1006
|
-
pendingMatches.push({ matchId
|
|
1075
|
+
pendingMatches.push({ matchId, platform: session.event.platform, guildId: session.event.guild.id });
|
|
1007
1076
|
session.send("比赛尚未解析,将在解析完成后发布。");
|
|
1008
1077
|
}
|
|
1009
1078
|
} catch (error) {
|
|
1010
1079
|
console.error(error);
|
|
1011
1080
|
session.send("获取比赛信息失败。");
|
|
1081
|
+
ctx.database.remove("dt_previous_query_results", { matchId: parseInt(matchId) });
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
__name(queryAndDisplayMatch, "queryAndDisplayMatch");
|
|
1085
|
+
ctx.command("查询比赛 <match_id>", "查询比赛ID").usage("查询指定比赛ID的比赛数据,生成图片发布。").example("-查询比赛 1234567890").action(async ({ session }, match_id) => {
|
|
1086
|
+
if (!match_id) {
|
|
1087
|
+
session.send("请输入比赛ID。");
|
|
1088
|
+
return;
|
|
1012
1089
|
}
|
|
1090
|
+
JSON.stringify;
|
|
1091
|
+
if (!/^\d{10}$/.test(match_id)) {
|
|
1092
|
+
session.send("比赛ID无效。");
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
session.send("正在搜索对局详情,请稍后...");
|
|
1096
|
+
queryAndDisplayMatch(session, match_id);
|
|
1013
1097
|
});
|
|
1014
1098
|
ctx.command("查询最近比赛 [input_data]", "查询玩家的最近比赛").usage("查询指定玩家的最近一场比赛的比赛数据,生成图片发布。\n参数可输入该玩家的SteamID或已在本群绑定玩家的别名,无参数时尝试查询调用指令玩家的SteamID").example("-查询最近比赛 123456789").example("-查询最近比赛 张三").action(async ({ session }, input_data) => {
|
|
1015
1099
|
if (session.guild) {
|
|
@@ -1035,28 +1119,7 @@ async function apply(ctx, config) {
|
|
|
1035
1119
|
session.send("获取玩家最近比赛失败。");
|
|
1036
1120
|
return;
|
|
1037
1121
|
}
|
|
1038
|
-
|
|
1039
|
-
let match;
|
|
1040
|
-
let queryLocal = await ctx.database.get("dt_previous_query_results", lastMatchId, ["data"]);
|
|
1041
|
-
if (queryLocal.length > 0) {
|
|
1042
|
-
match = queryLocal[0].data;
|
|
1043
|
-
} else {
|
|
1044
|
-
let queryRes = await query(MATCH_INFO(lastMatchId));
|
|
1045
|
-
if (queryRes.status == 200) {
|
|
1046
|
-
match = getFormattedMatchData(queryRes.data.data.match);
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
if (match.parsedDateTime) {
|
|
1050
|
-
session.send(await ctx.puppeteer.render(genMatchImageHTML(match)));
|
|
1051
|
-
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: match.id, data: match, queryTime: /* @__PURE__ */ new Date() }]);
|
|
1052
|
-
} else {
|
|
1053
|
-
pendingMatches.push({ matchId: lastMatchId, platform: session.event.platform, guildId: session.event.guild.id });
|
|
1054
|
-
session.send("比赛尚未解析,将在解析完成后发布。");
|
|
1055
|
-
}
|
|
1056
|
-
} catch (error) {
|
|
1057
|
-
console.error(error);
|
|
1058
|
-
session.send("获取比赛信息失败。");
|
|
1059
|
-
}
|
|
1122
|
+
queryAndDisplayMatch(session, lastMatchId);
|
|
1060
1123
|
}
|
|
1061
1124
|
});
|
|
1062
1125
|
ctx.command("查询玩家 <input_data>", "查询玩家信息").usage("查询指定玩家的个人信息与最近战绩,生成图片发布。\n参数可输入该玩家的SteamID或已在本群绑定玩家的别名,无参数时尝试查询调用指令玩家的SteamID").example("-查询玩家 123456789").example("-查询玩家 张三").action(async ({ session }, input_data) => {
|
|
@@ -1292,7 +1355,7 @@ async function apply(ctx, config) {
|
|
|
1292
1355
|
const commingMatches = scanningMatches.filter((item) => item.matchId == match.id);
|
|
1293
1356
|
const realCommingMatches = commingMatches.filter((commingMatch, index, self) => index === self.findIndex((t) => t.guildId === commingMatch.guildId && t.platform === commingMatch.platform));
|
|
1294
1357
|
let broadMatchMessage = "";
|
|
1295
|
-
const img = await ctx.puppeteer.render(
|
|
1358
|
+
const img = await ctx.puppeteer.render(newGenMatchImageHTML(match, config.template_match));
|
|
1296
1359
|
for (let comming of realCommingMatches) {
|
|
1297
1360
|
let commingSubscribedPlayers = subscribedPlayersInGuild.filter((item) => item.platform == comming.platform && item.guildId == comming.guildId);
|
|
1298
1361
|
let idsToFind = commingSubscribedPlayers.map((item) => item.steamId);
|
|
@@ -1311,7 +1374,7 @@ async function apply(ctx, config) {
|
|
|
1311
1374
|
broadPlayerMessage += random.pick(LOSE_NEGATIVE);
|
|
1312
1375
|
}
|
|
1313
1376
|
broadPlayerMessage += `。
|
|
1314
|
-
KDA:${((player.kills + player.assists) /
|
|
1377
|
+
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)}%`;
|
|
1315
1378
|
broadMatchMessage += broadPlayerMessage + "\n";
|
|
1316
1379
|
}
|
|
1317
1380
|
await ctx.broadcast([`${comming.platform}:${comming.guildId}`], broadMatchMessage + img);
|
|
@@ -1322,6 +1385,7 @@ KDA:${((player.kills + player.assists) / Math.max(1, player.deaths)).toFixed(2
|
|
|
1322
1385
|
ctx.logger.info("比赛 %d 尚未解析完成,继续等待。", match.id);
|
|
1323
1386
|
} catch (error) {
|
|
1324
1387
|
console.error(error);
|
|
1388
|
+
ctx.database.remove("dt_previous_query_results", { matchId: pendingMatch.matchId });
|
|
1325
1389
|
}
|
|
1326
1390
|
}
|
|
1327
1391
|
});
|
|
@@ -1330,268 +1394,30 @@ KDA:${((player.kills + player.assists) / Math.max(1, player.deaths)).toFixed(2
|
|
|
1330
1394
|
});
|
|
1331
1395
|
}
|
|
1332
1396
|
__name(apply, "apply");
|
|
1333
|
-
function
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
};
|
|
1345
|
-
const laneSVG = {
|
|
1346
|
-
stomp: `<svg viewBox="0 0 24 24" class="hitagi__sc-1apuy4g-0 hmhZOG"><path d="M8.05731 22.3674L9.60454 22.8002L11.5974 21.6551L12.043 20.0773L13.5902 20.51L15.583 19.3649L16.0287 17.7871L17.5759 18.2199L19.5687 17.0748L20.0143 15.4969L21.5615 15.9297L23.5544 14.7846L24 13.2068L23.4492 12.2014L7.50651 21.3621L8.05731 22.3674ZM12.1328 3.50265L11.0312 1.49196C10.8798 1.21549 10.5316 1.11811 10.2576 1.27556L0.29345 7.00098C0.0194354 7.15843 -0.0808273 7.51346 0.0706444 7.78993L1.44766 10.3033L11.91 4.29159C12.184 4.13414 12.2843 3.77912 12.1328 3.50265ZM18.3935 8.4063L14.1658 9.60458L12.4221 10.6065C12.2851 10.6853 12.111 10.6366 12.0353 10.4983L11.7599 9.99565C11.6842 9.85742 11.7343 9.6799 11.8713 9.60118L13.615 8.59924L13.0642 7.59389L11.3205 8.59584C11.1835 8.67456 11.0094 8.62587 10.9337 8.48765L10.6583 7.98497C10.5826 7.84673 10.6327 7.66922 10.7697 7.5905L12.5134 6.58855L11.9626 5.58321L1.99846 11.3086L6.9557 20.3567L22.8984 11.196L22.2615 10.0336C21.5024 8.64813 19.9073 7.97847 18.3935 8.4063Z"></path></svg>`,
|
|
1347
|
-
victory: `<svg viewBox="0 0 512 512"><path d="M198.844 64.75c-.985 0-1.974.03-2.97.094-15.915 1.015-32.046 11.534-37.78 26.937-34.072 91.532-51.085 128.865-61.5 222.876 14.633 13.49 31.63 26.45 50.25 38.125l66.406-196.467 17.688 5.968L163.28 362.5c19.51 10.877 40.43 20.234 62 27.28l75.407-201.53 17.5 6.53-74.937 200.282c19.454 5.096 39.205 8.2 58.78 8.875L381.345 225.5l17.094 7.594-75.875 170.656c21.82-1.237 43.205-5.768 63.437-14.28 43.317-53.844 72.633-109.784 84.5-172.69 5.092-26.992-14.762-53.124-54.22-54.81l-6.155-.282-2.188-5.75c-8.45-22.388-19.75-30.093-31.5-32.47-11.75-2.376-25.267 1.535-35.468 7.376l-13.064 7.47-.906-15c-.99-16.396-10.343-29.597-24.313-35.626-13.97-6.03-33.064-5.232-54.812 9.906l-10.438 7.25-3.812-12.125c-6.517-20.766-20.007-27.985-34.78-27.97zM103.28 188.344C71.143 233.448 47.728 299.56 51.407 359.656c27.54 21.84 54.61 33.693 80.063 35.438 14.155.97 27.94-1.085 41.405-6.438-35.445-17.235-67.36-39.533-92.594-63.53l-3.343-3.157.5-4.595c5.794-54.638 13.946-91.5 25.844-129.03z"/></svg>`,
|
|
1348
|
-
fail: `<svg viewBox="0 0 36 36"><path fill="#ff6961" d="M36 32a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h28a4 4 0 0 1 4 4v28z"></path><circle fill="#FFF" cx="27" cy="7" r="3"></circle><path fill="#FFF" d="M13.06 13.06l2.367-2.366l3.859 1.158l-2.635 2.847a10.018 10.018 0 0 1 4.392 3.379l5.017-5.017a1.5 1.5 0 0 0-.63-2.497l-9.999-3a1.495 1.495 0 0 0-1.492.376l-3 3a1.5 1.5 0 1 0 2.121 2.12zm16.065 4.949a1.496 1.496 0 0 0-1.262-.503l-6.786.617a9.966 9.966 0 0 1 1.464 2.879l3.548-.322l-1.554 6.995a1.499 1.499 0 1 0 2.928.65l2-9a1.5 1.5 0 0 0-.338-1.316zM13 16a8 8 0 1 0 0 16a8 8 0 0 0 0-16zm0 14a6 6 0 1 1 .002-12.002A6 6 0 0 1 13 30z"></path></svg>`,
|
|
1349
|
-
stomped: `<svg viewBox="-1 0 19 19"><path d="M16.417 9.579A7.917 7.917 0 1 1 8.5 1.662a7.917 7.917 0 0 1 7.917 7.917zm-2.458 2.96a.396.396 0 0 0-.396-.397h-.667a1.527 1.527 0 0 0-1.249-1.114.777.777 0 0 0 .014-.145V9.378a.794.794 0 0 0-.792-.792H8.201a2.984 2.984 0 0 0-1.682-.516l-.11.002V7.42h2.997a.396.396 0 1 0 0-.792H6.41v-1.3a.396.396 0 0 0-.396-.397H4.891a.396.396 0 0 0 0 .792h.727V8.21a2.997 2.997 0 1 0 3.836 3.466h.71a1.526 1.526 0 1 0 2.732 1.26h.667a.396.396 0 0 0 .396-.397zM8.078 9.507a2.205 2.205 0 1 1-1.559-.646 2.19 2.19 0 0 1 1.559.646zm4.078 3.03a.734.734 0 1 1-.733-.734.735.735 0 0 1 .733.733z"/></svg>`,
|
|
1350
|
-
tie: `<svg fill="#fff" viewBox="0 0 512.001 512.001"><g><g><path d="M120.988,239.868c-4.496,10.625-5.122,20.183-5.157,20.811c-0.267,4.607,3.243,8.547,7.849,8.829 c4.618,0.29,8.574-3.228,8.873-7.833c0.265-4.771,2.339-13.092,5.884-19.44C137.421,242.113,141.397,242.649,120.988,239.868z"/></g></g><g><g><path d="M391.178,255.418c-0.211,8.054-2.458,17.62-6.74,28.398c-1.708,4.299,0.393,9.168,4.692,10.875 c4.293,1.708,9.167-0.39,10.875-4.692c5.103-12.842,7.74-24.392,7.943-34.581H391.178z"/></g></g><g><g><path d="M164.769,210.51c1.046,3.339,1.397,6.953,0.893,10.65c-0.293,2.146-0.857,4.188-1.648,6.1c0,0,51.266,3.416,198.065,3.949 c-0.086-6.331,2.19-12.199,6.244-16.732C217.627,214.046,164.769,210.51,164.769,210.51z"/></g></g><g><g><circle cx="37.179" cy="128.669" r="29.491"/></g></g><g><g><path d="M510.146,391.511l-37.916-66.985c14.35-49.173,20.678-68.137,20.678-68.137l8.949-67.014 c1.502-10.977-6.248-21.075-17.235-22.468l-18.183-2.305c-10.984-1.393-20.996,6.445-22.293,17.431l-1.884,15.955l28.718-21.317 l-37.91,42.278h-46.432c-6.571,0-11.898,5.328-11.898,11.898c0,6.57,5.328,11.898,11.898,11.898h51.744 c3.381,0,6.601-1.438,8.859-3.956l41.456-46.234l-32.023,54.694c-5.28,9.018-14.374,8.169-18.293,8.167c-1.959,0-3.31,0-5.295,0 c-0.399,0.898,3.152-7.399-24.44,57.181c-0.548,1.284-0.907,2.642-1.06,4.031l-8.934,80.338 c-0.939,8.447,5.667,15.857,14.208,15.857c7.179,0,13.361-5.401,14.172-12.701l8.702-78.244l21.512-50.353l-14.121,50.463 c-1.158,3.756-0.718,7.823,1.218,11.243l40.949,72.345c3.885,6.864,12.596,9.276,19.459,5.392 C511.615,407.085,514.03,398.373,510.146,391.511z"/></g></g><g><g><circle cx="464.865" cy="128.702" r="29.491"/></g></g><g><g><path d="M142.923,206.051l-59.556-8.118l-39.135-18.451l13.626,2.292c-1.422-10.945-11.411-18.577-22.254-17.202l-18.182,2.305 C6.43,168.271-1.315,178.374,0.186,189.345l9.12,68.689l21.865,70.857l5.829,70.795c0.646,7.848,7.527,13.705,15.401,13.057 c7.859-0.647,13.705-7.542,13.058-15.401l-5.956-72.345c-0.084-1.031-0.281-2.05-0.585-3.039l-14.123-50.463l21.514,50.353 l8.702,78.244c0.873,7.86,7.96,13.486,15.768,12.612c7.838-0.871,13.483-7.931,12.612-15.768l-8.934-80.338 c-0.154-1.388-0.511-2.747-1.06-4.032l-27.336-61.43l-2.945-24.951l-29.029-25.179l40.79,19.231 c1.097,0.517,2.266,0.862,3.468,1.027l61.369,8.365c6.521,0.887,12.509-3.68,13.396-10.183 C153.994,212.936,149.435,206.939,142.923,206.051z"/></g></g></svg>`
|
|
1397
|
+
function newGenMatchImageHTML(match, template = "match_1") {
|
|
1398
|
+
const templatePath = import_path.default.join(`./node_modules/@sjtdev/koishi-plugin-${name}/template/match`, template + ".ejs");
|
|
1399
|
+
const data = {
|
|
1400
|
+
match,
|
|
1401
|
+
utils: utils_exports,
|
|
1402
|
+
ImageType,
|
|
1403
|
+
d2a: dotaconstants_add_exports,
|
|
1404
|
+
dotaconstants: dotaconstants3,
|
|
1405
|
+
moment: import_moment.default,
|
|
1406
|
+
sec2time,
|
|
1407
|
+
formatNumber
|
|
1351
1408
|
};
|
|
1352
|
-
let
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
<p>模式:<span class="mode">${lobbyTypes[match.lobbyType] || match.lobbyType}/${gameMode[match.gameMode] || match.gameMode}</span></p>
|
|
1359
|
-
<p>服务器:<span class="server">${region[match.regionId]}</span></p>
|
|
1360
|
-
<p>起始时间:<span class="start_time">${(0, import_moment.default)(new Date(match.startDateTime * 1e3)).format("YYYY-MM-DD HH:mm:ss").slice(2)}</span></p>
|
|
1361
|
-
<img src="${getImageUrl("star_" + match.rank?.toString().split("")[1])}" alt="" class="star">
|
|
1362
|
-
<img src="${getImageUrl("medal_" + match.rank?.toString().split("")[0])}" alt="" class="rank">
|
|
1363
|
-
<p>结束时间:<span class="end_time">${(0, import_moment.default)(new Date(match.endDateTime * 1e3)).format("YYYY-MM-DD HH:mm:ss").slice(2)}</span></p>
|
|
1364
|
-
<div class="score">
|
|
1365
|
-
<p class="score radiant">${match.radiantKillsCount}</p>
|
|
1366
|
-
<p class="time">${sec2time(match.durationSeconds)}</p>
|
|
1367
|
-
<p class="score dire">${match.direKillsCount}</p>
|
|
1368
|
-
</div>
|
|
1369
|
-
</div>
|
|
1370
|
-
`;
|
|
1371
|
-
$(".match_info").html(matchInfo_html);
|
|
1372
|
-
let players_html = { radiant: "", dire: "" };
|
|
1373
|
-
match.players.forEach((player) => {
|
|
1374
|
-
players_html[player.isRadiant ? "radiant" : "dire"] += sanitizeHTML`
|
|
1375
|
-
<div class="player${player.hero.id == 80 ? " bear" : ""}${player.leaverStatus != "NONE" && player.leaverStatus != "DISCONNECTED" ? " giveup" : ""}" style="order:${player.position?.slice(-1)}">
|
|
1376
|
-
<div class="hero">
|
|
1377
|
-
<div class="player_avatar">
|
|
1378
|
-
<img alt="" src="${getImageUrl(player.hero.shortName, "heroes" /* Heroes */)}" />
|
|
1379
|
-
<p class="party_line${player.partyId != null ? " party_" + match.party[player.partyId] : ""}"></p>
|
|
1380
|
-
<p class="party_mark${player.partyId != null ? " party_" + match.party[player.partyId] : ""}"></p>
|
|
1381
|
-
<p class="position p${Math.floor(player.order / 4) + 1}">${player.isRandom ? "随机" : `第<span>${player.order ? player.order + 1 : "-"}</span>手`}<br/>${position[player.position?.slice(-1)]}</p>
|
|
1382
|
-
<p class="level">${player.level}</p>
|
|
1383
|
-
</div>
|
|
1384
|
-
<div class="player_info">
|
|
1385
|
-
<summary class="player_name">${player.steamAccount.name}</summary>
|
|
1386
|
-
<summary class="player_performance">
|
|
1387
|
-
<span class="kda">${player.kills}/${player.deaths}/${player.assists}</span>
|
|
1388
|
-
<span class="kc" style="color:${kcndcStyle.kc(player.killContribution * 100)}">${Math.floor(player.killContribution * 100)}%</span>
|
|
1389
|
-
<span class="dc" style="color:${kcndcStyle.dc(player.deathContribution * 100)}">${Math.floor(player.deathContribution * 100)}%</span></summary>
|
|
1390
|
-
<summary class="player_net"><span class="networth">${player.networth}</span> <span class="score">${(player.heroDamage / player.networth)?.toFixed(2)}</span></summary>
|
|
1391
|
-
</div>
|
|
1392
|
-
<div class="player_lane ${player.laneResult}">
|
|
1393
|
-
${laneSVG[player.laneResult]}
|
|
1394
|
-
</div>
|
|
1395
|
-
<div class="player_rank">
|
|
1396
|
-
${player.steamAccount.seasonRank ? `
|
|
1397
|
-
<div class="rank">
|
|
1398
|
-
<img class="medal" src="${getImageUrl(
|
|
1399
|
-
"medal_" + (player.steamAccount.seasonLeaderboardRank ? player.steamAccount.seasonLeaderboardRank <= 100 ? player.steamAccount.seasonLeaderboardRank <= 10 ? "8c" : "8b" : player.steamAccount.seasonRank.toString().split("")[0] : player.steamAccount.seasonRank.toString().split("")[0])
|
|
1400
|
-
)}" alt="" />
|
|
1401
|
-
${!player.steamAccount.seasonLeaderboardRank ? `
|
|
1402
|
-
<img class="star" src="${getImageUrl("star_" + player.steamAccount.seasonRank.toString().split("")[1])}" alt="" />` : `
|
|
1403
|
-
<p>${player.steamAccount.seasonLeaderboardRank}</p>`}
|
|
1404
|
-
</div>` : `
|
|
1405
|
-
<div class="norank">
|
|
1406
|
-
<img class="medal" src="${getImageUrl("medal_0")}" alt="" />
|
|
1407
|
-
</div>`}
|
|
1408
|
-
<div class="dotaPlusLevel"${!player.dotaPlus ? ` style="display:none"` : ""}>
|
|
1409
|
-
<img src="${getImageUrl("hero_badge_" + (player.dotaPlus ? Math.ceil((player.dotaPlus?.level + 1) / 6) : 1))}" alt="" class="badge">
|
|
1410
|
-
<p class="level">${player.dotaPlus?.level}</p>
|
|
1411
|
-
</div>
|
|
1412
|
-
</div>
|
|
1413
|
-
</div>
|
|
1414
|
-
<div class="titles">
|
|
1415
|
-
${player.titles.map((item) => `<span style="color: ${item.color};">${item.name}</span>`).join(" ")}
|
|
1416
|
-
</div>
|
|
1417
|
-
${player.hero.id != 80 ? `
|
|
1418
|
-
<div class="items">
|
|
1419
|
-
<div class="items_normal">
|
|
1420
|
-
${player.items.map(
|
|
1421
|
-
(item) => item ? `
|
|
1422
|
-
<div class="item${item.isRecipe ? " recipe" : ""}">
|
|
1423
|
-
<img src="${getImageUrl(item.name, "items" /* Items */)}" alt="" />
|
|
1424
|
-
<p class="time">${sec2time(item.time)}</p>
|
|
1425
|
-
</div>` : `
|
|
1426
|
-
<div class="item" style="visibility:hidden"}">
|
|
1427
|
-
<img src="${getImageUrl("blink", "items" /* Items */)}" alt="" />
|
|
1428
|
-
<p class="time">--:--</p>
|
|
1429
|
-
</div>`
|
|
1430
|
-
).join("")}
|
|
1431
|
-
</div>
|
|
1432
|
-
<div class="items_backpack">
|
|
1433
|
-
${player.backpacks.map(
|
|
1434
|
-
(item) => item ? `
|
|
1435
|
-
<div class="item back${item.isRecipe ? " recipe" : ""}">
|
|
1436
|
-
<img src="${getImageUrl(item.name, "items" /* Items */)}" alt="" />
|
|
1437
|
-
<p class="time">${sec2time(item.time)}</p>
|
|
1438
|
-
</div>` : `
|
|
1439
|
-
<div class="item back" style="visibility:hidden"}">
|
|
1440
|
-
<img src="${getImageUrl("blink", "items" /* Items */)}" alt="" />
|
|
1441
|
-
<p class="time">--:--</p>
|
|
1442
|
-
</div>`
|
|
1443
|
-
).join("")}
|
|
1444
|
-
</div>
|
|
1445
|
-
<div class="item neutral" style="background-image: url(${getImageUrl(dotaconstants3.item_ids[player.neutral0Id], "items" /* Items */)})"></div>
|
|
1446
|
-
</div>
|
|
1447
|
-
<div class="buffs">
|
|
1448
|
-
<section>
|
|
1449
|
-
${player.stats?.matchPlayerBuffEvent?.map(
|
|
1450
|
-
(buff) => `
|
|
1451
|
-
<div class="buff">
|
|
1452
|
-
<img src="${getImageUrl(dotaconstants3[buff.abilityId ? "ability_ids" : "item_ids"][buff.abilityId ?? buff.itemId], buff.abilityId ? "abilities" /* Abilities */ : "items" /* Items */)}" alt="" />
|
|
1453
|
-
<p>${buff.stackCount ?? ""}</p>
|
|
1454
|
-
</div>`
|
|
1455
|
-
).join("")}
|
|
1456
|
-
</section>
|
|
1457
|
-
<section>
|
|
1458
|
-
<div class="support_item"${player.supportItemsCount[30] > 0 ? "" : ' style="display:none"'}>
|
|
1459
|
-
<img src="${getImageUrl("gem", "items" /* Items */)}" alt="" />
|
|
1460
|
-
<p>${player.supportItemsCount[30]}</p>
|
|
1461
|
-
</div>
|
|
1462
|
-
<div class="support_item"${player.supportItemsCount[40] > 0 ? "" : ' style="display:none"'}>
|
|
1463
|
-
<img src="${getImageUrl("dust", "items" /* Items */)}" alt="" />
|
|
1464
|
-
<p>${player.supportItemsCount[40]}</p>
|
|
1465
|
-
</div>
|
|
1466
|
-
<div class="support_item"${player.supportItemsCount[42] > 0 ? "" : ' style="display:none"'}>
|
|
1467
|
-
<img src="${getImageUrl("ward_observer", "items" /* Items */)}" alt="" />
|
|
1468
|
-
<p>${player.supportItemsCount[42]}</p>
|
|
1469
|
-
</div>
|
|
1470
|
-
<div class="support_item"${player.supportItemsCount[43] > 0 ? "" : ' style="display:none"'}>
|
|
1471
|
-
<img src="${getImageUrl("ward_sentry", "items" /* Items */)}" alt="" />
|
|
1472
|
-
<p>${player.supportItemsCount[43]}</p>
|
|
1473
|
-
</div>
|
|
1474
|
-
<div class="support_item"${player.supportItemsCount[188] > 0 ? "" : ' style="display:none"'}>
|
|
1475
|
-
<img src="${getImageUrl("smoke_of_deceit", "items" /* Items */)}" alt="" />
|
|
1476
|
-
<p>${player.supportItemsCount[188]}</p>
|
|
1477
|
-
</div>
|
|
1478
|
-
</section>
|
|
1479
|
-
</div>` : `
|
|
1480
|
-
<div class="items_buffs master">
|
|
1481
|
-
<div class="items master">
|
|
1482
|
-
${player.items.map(
|
|
1483
|
-
(item) => item ? `
|
|
1484
|
-
<div class="item${item.isRecipe ? " recipe" : ""}">
|
|
1485
|
-
<img src="${getImageUrl(item.name, "items" /* Items */)}" alt="" />
|
|
1486
|
-
<p class="time">${sec2time(item.time)}</p>
|
|
1487
|
-
</div>` : `
|
|
1488
|
-
<div class="item" style="visibility:hidden"}">
|
|
1489
|
-
<img src="${getImageUrl("blink", "items" /* Items */)}" alt="" />>
|
|
1490
|
-
<p class="time">--:--</p>
|
|
1491
|
-
</div>`
|
|
1492
|
-
).join("")}
|
|
1493
|
-
${player.backpacks.map(
|
|
1494
|
-
(item) => item ? `
|
|
1495
|
-
<div class="item back${item.isRecipe ? " recipe" : ""}">
|
|
1496
|
-
<img src="${getImageUrl(item.name, "items" /* Items */)}" alt="" />
|
|
1497
|
-
<p class="time">${sec2time(item.time)}</p>
|
|
1498
|
-
</div>` : `
|
|
1499
|
-
<div class="item back" style="visibility:hidden"}">
|
|
1500
|
-
<img src="${getImageUrl("blink", "items" /* Items */)}" alt="" />
|
|
1501
|
-
<p class="time">--:--</p>
|
|
1502
|
-
</div>`
|
|
1503
|
-
).join("")}
|
|
1504
|
-
<div class="item neutral">
|
|
1505
|
-
<img src="${getImageUrl(dotaconstants3.item_ids[player.neutral0Id], "items" /* Items */)}" alt="" />
|
|
1506
|
-
</div>
|
|
1507
|
-
</div>
|
|
1508
|
-
<div class="buffs master">
|
|
1509
|
-
${player.stats?.matchPlayerBuffEvent?.map(
|
|
1510
|
-
(buff) => `
|
|
1511
|
-
<div class="buff">
|
|
1512
|
-
<img src="${getImageUrl(dotaconstants3[buff.abilityId ? "ability_ids" : "item_ids"][buff.abilityId ?? buff.itemId], buff.abilityId ? "abilities" /* Abilities */ : "items" /* Items */)}" alt="" />
|
|
1513
|
-
<p>${buff.stackCount ?? ""}</p>
|
|
1514
|
-
</div>`
|
|
1515
|
-
).join("")}
|
|
1516
|
-
</div>
|
|
1517
|
-
</div>
|
|
1518
|
-
<div class="items_buffs slave">
|
|
1519
|
-
<div class="items slave">
|
|
1520
|
-
${player.unitItems.map(
|
|
1521
|
-
(item) => item ? `
|
|
1522
|
-
<div class="item${item.isRecipe ? " recipe" : ""}">
|
|
1523
|
-
<img src="${getImageUrl(item.name, "items" /* Items */)}" alt="" />
|
|
1524
|
-
<p class="time">${sec2time(item.time)}</p>
|
|
1525
|
-
</div>` : `
|
|
1526
|
-
<div class="item" style="visibility:hidden"}">
|
|
1527
|
-
<img src="${getImageUrl("blink", "items" /* Items */)}" alt="" />>
|
|
1528
|
-
<p class="time">--:--</p>
|
|
1529
|
-
</div>`
|
|
1530
|
-
).join("")}
|
|
1531
|
-
${player.unitBackpacks.map(
|
|
1532
|
-
(item) => item ? `
|
|
1533
|
-
<div class="item back${item.isRecipe ? " recipe" : ""}">
|
|
1534
|
-
<img src="${getImageUrl(item.name, "items" /* Items */)}" alt="" />
|
|
1535
|
-
<p class="time">${sec2time(item.time)}</p>
|
|
1536
|
-
</div>` : `
|
|
1537
|
-
<div class="item back" style="visibility:hidden"}">
|
|
1538
|
-
<img src="${getImageUrl("blink", "items" /* Items */)}" alt="" />
|
|
1539
|
-
<p class="time">--:--</p>
|
|
1540
|
-
</div>`
|
|
1541
|
-
).join("")}
|
|
1542
|
-
<div class="item neutral">
|
|
1543
|
-
<img src="${getImageUrl(dotaconstants3.item_ids[player.additionalUnit.neutral0Id], "items" /* Items */)}" alt="" />
|
|
1544
|
-
</div>
|
|
1545
|
-
</div>
|
|
1546
|
-
<div class="buffs_supportItems slave">
|
|
1547
|
-
<div class="buffs">
|
|
1548
|
-
<!-- 无有效API获取熊灵buff -->
|
|
1549
|
-
</div>
|
|
1550
|
-
<div class="support_items">
|
|
1551
|
-
<div class="support_item"${player.supportItemsCount[30] > 0 ? "" : ' style="display:none"'}>
|
|
1552
|
-
<img src="${getImageUrl("gem", "items" /* Items */)}" alt="" />
|
|
1553
|
-
<p>${player.supportItemsCount[30]}</p>
|
|
1554
|
-
</div>
|
|
1555
|
-
<div class="support_item"${player.supportItemsCount[40] > 0 ? "" : ' style="display:none"'}>
|
|
1556
|
-
<img src="${getImageUrl("dust", "items" /* Items */)}" alt="" />
|
|
1557
|
-
<p>${player.supportItemsCount[40]}</p>
|
|
1558
|
-
</div>
|
|
1559
|
-
<div class="support_item"${player.supportItemsCount[42] > 0 ? "" : ' style="display:none"'}>
|
|
1560
|
-
<img src="${getImageUrl("ward_observer", "items" /* Items */)}" alt="" />
|
|
1561
|
-
<p>${player.supportItemsCount[42]}</p>
|
|
1562
|
-
</div>
|
|
1563
|
-
<div class="support_item"${player.supportItemsCount[43] > 0 ? "" : ' style="display:none"'}>
|
|
1564
|
-
<img src="${getImageUrl("ward_sentry", "items" /* Items */)}" alt="" />
|
|
1565
|
-
<p>${player.supportItemsCount[43]}</p>
|
|
1566
|
-
</div>
|
|
1567
|
-
<div class="support_item"${player.supportItemsCount[188] > 0 ? "" : ' style="display:none"'}>
|
|
1568
|
-
<img src="${getImageUrl("smoke_of_deceit", "items" /* Items */)}" alt="" />
|
|
1569
|
-
<p>${player.supportItemsCount[188]}</p>
|
|
1570
|
-
</div>
|
|
1571
|
-
</div>
|
|
1572
|
-
</div>
|
|
1573
|
-
</div>`}
|
|
1574
|
-
<div class="details">
|
|
1575
|
-
<section>英雄伤害:<span class="hero_damage">${player.heroDamage}</span></section>
|
|
1576
|
-
<section>建筑伤害:<span class="building_damage">${player.towerDamage}</span></section>
|
|
1577
|
-
<section>受到伤害(减免后):<span class="tak">${player.stats?.heroDamageReport?.receivedTotal.physicalDamage + player.stats?.heroDamageReport?.receivedTotal.magicalDamage + player.stats?.heroDamageReport?.receivedTotal.pureDamage}</span></section>
|
|
1578
|
-
<section>补刀:<span class="lh">${player.numLastHits}</span>/<span class="dn">${player.numDenies}</span></section>
|
|
1579
|
-
<section>GPM/XPM:<span class="gpm">${player.goldPerMinute}</span>/<span class="xpm">${player.experiencePerMinute}</span></section>
|
|
1580
|
-
<section>治疗量:<span class="heal">${player.heroHealing}</span></section>
|
|
1581
|
-
<section>控制时间:<span class="building_damage">${(player.stats?.heroDamageReport?.dealtTotal.stunDuration / 100).toFixed(2)}/${(player.stats?.heroDamageReport?.dealtTotal.slowDuration / 100).toFixed(2)}/${(player.stats?.heroDamageReport?.dealtTotal.disableDuration / 100).toFixed(2)}</span>s</section>
|
|
1582
|
-
</div>
|
|
1583
|
-
</div>`;
|
|
1409
|
+
let result = "";
|
|
1410
|
+
ejs.renderFile(templatePath, data, (err, html) => {
|
|
1411
|
+
if (err)
|
|
1412
|
+
throw err;
|
|
1413
|
+
else
|
|
1414
|
+
result = html;
|
|
1584
1415
|
});
|
|
1585
|
-
$(".radiant_players").html(players_html.radiant);
|
|
1586
|
-
$(".dire_players").html(players_html.dire);
|
|
1587
|
-
$(".ban_list").html(
|
|
1588
|
-
match.pickBans.filter((hero) => !hero.isPick).map((hero) => `<div class="ban_hero"><img src="${getImageUrl(/^npc_dota_hero_(?<name>.+)$/.exec(dotaconstants3.heroes[hero.bannedHeroId].name)[1], "heroes" /* Heroes */)}" alt="" /></div>`).join("")
|
|
1589
|
-
);
|
|
1590
1416
|
if (process.env.NODE_ENV === "development")
|
|
1591
|
-
import_fs2.default.writeFileSync("./node_modules/@sjtdev/koishi-plugin-dota2tracker/temp.html",
|
|
1592
|
-
return
|
|
1417
|
+
import_fs2.default.writeFileSync("./node_modules/@sjtdev/koishi-plugin-dota2tracker/temp.html", result);
|
|
1418
|
+
return result;
|
|
1593
1419
|
}
|
|
1594
|
-
__name(
|
|
1420
|
+
__name(newGenMatchImageHTML, "newGenMatchImageHTML");
|
|
1595
1421
|
function genHeroHTML(hero) {
|
|
1596
1422
|
let $ = cheerio.load(import_fs2.default.readFileSync(`./node_modules/@sjtdev/koishi-plugin-${name}/template/hero.html`, "utf-8"));
|
|
1597
1423
|
let html = `
|
|
@@ -1832,18 +1658,13 @@ function genPlayerHTML(player) {
|
|
|
1832
1658
|
(outcomeCounts.victory + outcomeCounts.stomp + outcomeCounts.tie / 2) / (outcomeCounts.victory + outcomeCounts.stomp + outcomeCounts.tie + outcomeCounts.fail + outcomeCounts.stomped)
|
|
1833
1659
|
)};">${((outcomeCounts.victory + outcomeCounts.stomp) / (outcomeCounts.victory + outcomeCounts.stomp + outcomeCounts.fail + outcomeCounts.stomped) * 100).toFixed(2)}%</span></span></p>
|
|
1834
1660
|
</div>
|
|
1835
|
-
${player.steamAccount.seasonRank ? `
|
|
1836
1661
|
<div class="rank">
|
|
1837
1662
|
<img class="medal" src="${getImageUrl(
|
|
1838
|
-
"medal_" + (player.steamAccount.seasonLeaderboardRank ? player.steamAccount.seasonLeaderboardRank <= 100 ? player.steamAccount.seasonLeaderboardRank <= 10 ? "8c" : "8b" : player.steamAccount.seasonRank
|
|
1663
|
+
"medal_" + ((player.steamAccount.seasonLeaderboardRank ? player.steamAccount.seasonLeaderboardRank <= 100 ? player.steamAccount.seasonLeaderboardRank <= 10 ? "8c" : "8b" : player.steamAccount.seasonRank?.toString().split("")[0] : player.steamAccount.seasonRank?.toString().split("")[0]) ?? "0")
|
|
1839
1664
|
)}" alt="" />
|
|
1840
|
-
${
|
|
1841
|
-
<
|
|
1842
|
-
|
|
1843
|
-
</div>` : `
|
|
1844
|
-
<div class="rank">
|
|
1845
|
-
<img class="medal" src="${getImageUrl("medal_0")}" alt="" />
|
|
1846
|
-
</div>`}`;
|
|
1665
|
+
<img class="star" src="${getImageUrl("star_" + (player.steamAccount.seasonRank?.toString().split("")[1] ?? "0"))}" alt="" />
|
|
1666
|
+
<p>${player.steamAccount.seasonLeaderboardRank ?? ""}</p>
|
|
1667
|
+
</div>`;
|
|
1847
1668
|
const heroesCountPixels = 800 - ($(".tip:not(.row):not(.win_count):not(.lose_count)").length + 1) * 40;
|
|
1848
1669
|
const highestCountsTotal = {
|
|
1849
1670
|
winCount: Math.max(...player.heroesPerformanceTop10.map((hero) => hero.winCount)),
|
|
@@ -1955,13 +1776,21 @@ function winRateColor(value) {
|
|
|
1955
1776
|
return `#${toHex(red)}${toHex(green)}${toHex(blue)}`;
|
|
1956
1777
|
}
|
|
1957
1778
|
__name(winRateColor, "winRateColor");
|
|
1958
|
-
function
|
|
1959
|
-
return
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1779
|
+
function formatNumber(num) {
|
|
1780
|
+
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
1781
|
+
}
|
|
1782
|
+
__name(formatNumber, "formatNumber");
|
|
1783
|
+
function readDirectoryFilesSync(directoryPath) {
|
|
1784
|
+
try {
|
|
1785
|
+
const files = import_fs2.default.readdirSync(directoryPath);
|
|
1786
|
+
const fileNames = files.map((file) => import_path.default.basename(file, import_path.default.extname(file)));
|
|
1787
|
+
return fileNames;
|
|
1788
|
+
} catch (error) {
|
|
1789
|
+
console.error("Error reading directory:", error);
|
|
1790
|
+
return [];
|
|
1791
|
+
}
|
|
1963
1792
|
}
|
|
1964
|
-
__name(
|
|
1793
|
+
__name(readDirectoryFilesSync, "readDirectoryFilesSync");
|
|
1965
1794
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1966
1795
|
0 && (module.exports = {
|
|
1967
1796
|
Config,
|