@sjtdev/koishi-plugin-dota2tracker 2.2.3 → 2.3.1
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 +28 -0
- package/lib/index.js +200 -162
- package/{queries → lib/queries}/MatchInfo.graphql +13 -0
- package/lib/templates/common/components/building_icons.ejs +20 -0
- package/lib/templates/common/styles/normalize.min.css +1 -0
- package/lib/templates/hero/hero_1.ejs +69 -0
- package/lib/templates/images/7.38_simple_minimap.png +0 -0
- package/lib/templates/item/item/recipe.ejs +9 -0
- package/lib/templates/item/item/style.css +1 -0
- package/lib/templates/item/item.ejs +52 -0
- package/lib/templates/item/itemlist.ejs +11 -0
- package/lib/templates/match/match_1/base.css +1 -0
- package/lib/templates/match/match_1/item.ejs +1 -0
- package/lib/templates/match/match_1/main.ejs +8 -0
- package/lib/templates/match/match_1/player.ejs +1 -0
- package/lib/templates/match/match_1/style.css +1 -0
- package/lib/templates/match/match_1.ejs +18 -0
- package/lib/templates/match/match_2/original.css +1 -0
- package/lib/templates/match/match_2/original.ejs +10 -0
- package/lib/templates/match/match_2+/charts.ejs +1 -0
- package/lib/templates/match/match_2+/extra.css +1 -0
- package/lib/templates/match/match_2+/lane_outcome.ejs +56 -0
- package/lib/templates/match/match_2+/map.ejs +160 -0
- package/lib/templates/match/match_2+.ejs +1 -0
- package/lib/templates/match/match_2.ejs +1 -0
- package/lib/templates/player/player_1/base.css +1 -0
- package/lib/templates/player/player_1/private.ejs +1 -0
- package/lib/templates/player/player_1.ejs +78 -0
- package/lib/templates/rank/rank_fun.ejs +1 -0
- package/lib/templates/report/daily/base.css +1 -0
- package/lib/templates/report/daily.ejs +29 -0
- package/package.json +2 -2
- package/template/hero/hero_1.ejs +0 -900
- package/template/item/item/recipe.ejs +0 -51
- package/template/item/item/style.css +0 -244
- package/template/item/item.ejs +0 -140
- package/template/item/itemlist.ejs +0 -99
- package/template/match/match_1/item.ejs +0 -11
- package/template/match/match_1/main.ejs +0 -37
- package/template/match/match_1/player.ejs +0 -154
- package/template/match/match_1/style.css +0 -764
- package/template/match/match_1.ejs +0 -56
- package/template/match/match_2/original.css +0 -463
- package/template/match/match_2/original.ejs +0 -192
- package/template/match/match_2+/charts.ejs +0 -261
- package/template/match/match_2+/extra.css +0 -143
- package/template/match/match_2+/lane_outcome.ejs +0 -157
- package/template/match/match_2+.ejs +0 -27
- package/template/match/match_2.ejs +0 -18
- package/template/player/player_1/private.ejs +0 -5
- package/template/player/player_1.ejs +0 -654
- package/template/rank/rank_fun.ejs +0 -131
- package/template/report/daily.ejs +0 -191
- /package/{queries → lib/queries}/Constants.graphql +0 -0
- /package/{queries → lib/queries}/GetWeeklyMetaByPosition.graphql +0 -0
- /package/{queries → lib/queries}/PlayerExtraInfo.graphql +0 -0
- /package/{queries → lib/queries}/PlayerInfoWith25Matches.graphql +0 -0
- /package/{queries → lib/queries}/PlayerPerformanceForHeroRecommendation.graphql +0 -0
- /package/{queries → lib/queries}/PlayersInfoWith10MatchesForGuild.graphql +0 -0
- /package/{queries → lib/queries}/PlayersLastmatchRankinfo.graphql +0 -0
- /package/{queries → lib/queries}/PlayersMatchesForDaily.graphql +0 -0
- /package/{queries → lib/queries}/RequestMatchDataAnalysis.graphql +0 -0
- /package/{queries → lib/queries}/VerifyingPlayer.graphql +0 -0
- /package/{template → lib/templates}/images/bei.jpg +0 -0
- /package/{template → lib/templates}/images/disconnected.png +0 -0
- /package/{template → lib/templates}/images/flag_dire.png +0 -0
- /package/{template → lib/templates}/images/flag_radiant.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_1.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_2.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_3.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_4.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_5.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_6.png +0 -0
- /package/{template → lib/templates}/images/lane_fail.svg +0 -0
- /package/{template → lib/templates}/images/lane_jungle.svg +0 -0
- /package/{template → lib/templates}/images/lane_stomp.svg +0 -0
- /package/{template → lib/templates}/images/lane_stomped.svg +0 -0
- /package/{template → lib/templates}/images/lane_tie.svg +0 -0
- /package/{template → lib/templates}/images/lane_victory.svg +0 -0
- /package/{template → lib/templates}/images/logo_dire.png +0 -0
- /package/{template → lib/templates}/images/logo_radiant.png +0 -0
- /package/{template → lib/templates}/images/medal_0.png +0 -0
- /package/{template → lib/templates}/images/medal_1.png +0 -0
- /package/{template → lib/templates}/images/medal_2.png +0 -0
- /package/{template → lib/templates}/images/medal_3.png +0 -0
- /package/{template → lib/templates}/images/medal_4.png +0 -0
- /package/{template → lib/templates}/images/medal_5.png +0 -0
- /package/{template → lib/templates}/images/medal_6.png +0 -0
- /package/{template → lib/templates}/images/medal_7.png +0 -0
- /package/{template → lib/templates}/images/medal_8.png +0 -0
- /package/{template → lib/templates}/images/medal_8b.png +0 -0
- /package/{template → lib/templates}/images/medal_8c.png +0 -0
- /package/{template → lib/templates}/images/scepter.png +0 -0
- /package/{template → lib/templates}/images/scepter_0.png +0 -0
- /package/{template → lib/templates}/images/scepter_1.png +0 -0
- /package/{template → lib/templates}/images/shard.png +0 -0
- /package/{template → lib/templates}/images/shard_0.png +0 -0
- /package/{template → lib/templates}/images/shard_1.png +0 -0
- /package/{template → lib/templates}/images/star_0.png +0 -0
- /package/{template → lib/templates}/images/star_1.png +0 -0
- /package/{template → lib/templates}/images/star_2.png +0 -0
- /package/{template → lib/templates}/images/star_3.png +0 -0
- /package/{template → lib/templates}/images/star_4.png +0 -0
- /package/{template → lib/templates}/images/star_5.png +0 -0
- /package/{template → lib/templates}/images/xi.jpg +0 -0
package/lib/index.js
CHANGED
|
@@ -259,7 +259,8 @@ var require_en_US_constants = __commonJS({
|
|
|
259
259
|
"136": "Marci",
|
|
260
260
|
"137": "Primal Beast",
|
|
261
261
|
"138": "Muerta",
|
|
262
|
-
"145": "Kez"
|
|
262
|
+
"145": "Kez",
|
|
263
|
+
"155": "Largo"
|
|
263
264
|
},
|
|
264
265
|
behavior: {
|
|
265
266
|
"Unit Target": "Unit Target",
|
|
@@ -571,7 +572,8 @@ var require_zh_CN_constants = __commonJS({
|
|
|
571
572
|
"136": "玛西",
|
|
572
573
|
"137": "獸",
|
|
573
574
|
"138": "琼英碧灵",
|
|
574
|
-
"145": "凯"
|
|
575
|
+
"145": "凯",
|
|
576
|
+
"155": "朗戈"
|
|
575
577
|
},
|
|
576
578
|
behavior: {
|
|
577
579
|
"Unit Target": "单位目标",
|
|
@@ -833,7 +835,6 @@ var import_path5 = __toESM(require("path"));
|
|
|
833
835
|
|
|
834
836
|
// src/app/common/i18n.ts
|
|
835
837
|
var import_koishi = require("koishi");
|
|
836
|
-
var dotaconstants = __toESM(require("dotaconstants"));
|
|
837
838
|
|
|
838
839
|
// src/app/common/utils.ts
|
|
839
840
|
var import_luxon = require("luxon");
|
|
@@ -925,14 +926,9 @@ var LanguageTags = {
|
|
|
925
926
|
"zh-CN": { graphqlTag: "S_CHINESE", valveTag: "schinese" }
|
|
926
927
|
};
|
|
927
928
|
var I18NService = class extends import_koishi.Service {
|
|
928
|
-
|
|
929
|
-
__name(this, "I18NService");
|
|
930
|
-
}
|
|
931
|
-
constantLocales = {};
|
|
932
|
-
i18n;
|
|
933
|
-
globalLanguageTag;
|
|
934
|
-
constructor(ctx) {
|
|
929
|
+
constructor(ctx, dotaconstants) {
|
|
935
930
|
super(ctx, "dota2tracker.i18n", true);
|
|
931
|
+
this.dotaconstants = dotaconstants;
|
|
936
932
|
this.config = ctx.config;
|
|
937
933
|
this.i18n = this.ctx.i18n;
|
|
938
934
|
for (const supportLanguageTag of Object.keys(LanguageTags)) {
|
|
@@ -943,6 +939,12 @@ var I18NService = class extends import_koishi.Service {
|
|
|
943
939
|
}
|
|
944
940
|
this.globalLanguageTag = this.i18n.fallback(Object.values(this.i18n.locales).map((locale) => Object.keys(locale).at(0))).find((locale) => Object.keys(LanguageTags).includes(locale));
|
|
945
941
|
}
|
|
942
|
+
static {
|
|
943
|
+
__name(this, "I18NService");
|
|
944
|
+
}
|
|
945
|
+
constantLocales = {};
|
|
946
|
+
i18n;
|
|
947
|
+
globalLanguageTag;
|
|
946
948
|
getGraphqlLanguageTag(languageTag) {
|
|
947
949
|
return LanguageTags[languageTag].graphqlTag;
|
|
948
950
|
}
|
|
@@ -1048,7 +1050,7 @@ var I18NService = class extends import_koishi.Service {
|
|
|
1048
1050
|
*/
|
|
1049
1051
|
_buildNicknameMap(languageTag) {
|
|
1050
1052
|
this.logger.debug(`Building nickname map for ${languageTag}...`);
|
|
1051
|
-
const heroIds = Object.keys(dotaconstants.heroes).map(Number);
|
|
1053
|
+
const heroIds = Object.keys(this.dotaconstants.heroes).map(Number);
|
|
1052
1054
|
const nicknameMap = /* @__PURE__ */ new Map();
|
|
1053
1055
|
for (const heroId of heroIds) {
|
|
1054
1056
|
const allNames = this._getAllHeroNames(heroId, languageTag);
|
|
@@ -1063,7 +1065,7 @@ var I18NService = class extends import_koishi.Service {
|
|
|
1063
1065
|
const inputStr = String(input).toLowerCase();
|
|
1064
1066
|
if (/^\d+$/.test(inputStr)) {
|
|
1065
1067
|
const heroId = Number(inputStr);
|
|
1066
|
-
if (dotaconstants.heroes[heroId]) {
|
|
1068
|
+
if (this.dotaconstants.heroes[heroId]) {
|
|
1067
1069
|
return heroId;
|
|
1068
1070
|
}
|
|
1069
1071
|
}
|
|
@@ -1089,7 +1091,6 @@ var I18NService = class extends import_koishi.Service {
|
|
|
1089
1091
|
|
|
1090
1092
|
// src/app/core/hero.service.ts
|
|
1091
1093
|
var import_koishi2 = require("koishi");
|
|
1092
|
-
var dotaconstants2 = __toESM(require("dotaconstants"));
|
|
1093
1094
|
var import_luxon2 = require("luxon");
|
|
1094
1095
|
|
|
1095
1096
|
// src/app/common/constants.ts
|
|
@@ -1098,12 +1099,13 @@ var RANK_BRACKETS = ["UNCALIBRATED", "HERALD", "GUARDIAN", "CRUSADER", "ARCHON",
|
|
|
1098
1099
|
|
|
1099
1100
|
// src/app/core/hero.service.ts
|
|
1100
1101
|
var HeroService = class _HeroService extends import_koishi2.Service {
|
|
1102
|
+
constructor(ctx, dotaconstants) {
|
|
1103
|
+
super(ctx, "dota2tracker.hero", true);
|
|
1104
|
+
this.dotaconstants = dotaconstants;
|
|
1105
|
+
}
|
|
1101
1106
|
static {
|
|
1102
1107
|
__name(this, "HeroService");
|
|
1103
1108
|
}
|
|
1104
|
-
constructor(ctx) {
|
|
1105
|
-
super(ctx, "dota2tracker.hero", true);
|
|
1106
|
-
}
|
|
1107
1109
|
async getWeeklyHeroMeta(rank) {
|
|
1108
1110
|
const MINIMUM_PICK_RATE = 0.02;
|
|
1109
1111
|
const RECOMMENDATION_COUNT = 3;
|
|
@@ -1138,7 +1140,7 @@ var HeroService = class _HeroService extends import_koishi2.Service {
|
|
|
1138
1140
|
return weeklyHeroMeta;
|
|
1139
1141
|
}
|
|
1140
1142
|
async getHeroDetails(input, languageTag, isRandom = false) {
|
|
1141
|
-
const heroId = this.ctx.dota2tracker.i18n.findHeroIdInLocale(isRandom ? import_koishi2.Random.pick(Object.keys(
|
|
1143
|
+
const heroId = this.ctx.dota2tracker.i18n.findHeroIdInLocale(isRandom ? import_koishi2.Random.pick(Object.keys(this.dotaconstants.heroes)) : input);
|
|
1142
1144
|
if (!heroId) return;
|
|
1143
1145
|
return _HeroService.formatHeroDetails(await this.ctx.dota2tracker.valveAPI.queryHeroDetailsFromValve(heroId, languageTag));
|
|
1144
1146
|
}
|
|
@@ -1298,7 +1300,7 @@ var ItemService = class _ItemService extends import_koishi3.Service {
|
|
|
1298
1300
|
}
|
|
1299
1301
|
static getFormattedItemListData(rawItems) {
|
|
1300
1302
|
const processItemName = /* @__PURE__ */ __name((name2) => name2.replace(/^item_/i, "").replace(/^recipe_/i, "recipe_"), "processItemName");
|
|
1301
|
-
const [recipes,
|
|
1303
|
+
const [recipes, items] = rawItems.reduce(
|
|
1302
1304
|
(acc, item) => {
|
|
1303
1305
|
const processed = {
|
|
1304
1306
|
...item,
|
|
@@ -1312,14 +1314,14 @@ var ItemService = class _ItemService extends import_koishi3.Service {
|
|
|
1312
1314
|
[[], []]
|
|
1313
1315
|
);
|
|
1314
1316
|
const itemMap = /* @__PURE__ */ new Map();
|
|
1315
|
-
|
|
1317
|
+
items.concat(recipes).forEach(
|
|
1316
1318
|
(item) => itemMap.set(item.id, {
|
|
1317
1319
|
id: item.id,
|
|
1318
1320
|
name: item.name,
|
|
1319
1321
|
name_loc: item.name_loc
|
|
1320
1322
|
})
|
|
1321
1323
|
);
|
|
1322
|
-
const processedItems =
|
|
1324
|
+
const processedItems = items.map((baseItem) => {
|
|
1323
1325
|
const recipe = recipes.find((r) => r.name === `recipe_${baseItem.name.replace("item_", "")}`);
|
|
1324
1326
|
return {
|
|
1325
1327
|
...baseItem,
|
|
@@ -1352,19 +1354,19 @@ var ItemService = class _ItemService extends import_koishi3.Service {
|
|
|
1352
1354
|
}))
|
|
1353
1355
|
}));
|
|
1354
1356
|
}
|
|
1355
|
-
searchItems(
|
|
1357
|
+
searchItems(items, keyword, languageTag, config) {
|
|
1356
1358
|
if (!keyword) return [];
|
|
1357
1359
|
const alias = this.ctx.dota2tracker.i18n.getConstantLocale(languageTag).dota2tracker.items_alias?.[keyword] ?? config.customItemAlias.filter((cia) => cia.alias == keyword).map((cia) => cia.keyword);
|
|
1358
|
-
const exactMatch =
|
|
1360
|
+
const exactMatch = items.filter(
|
|
1359
1361
|
(item) => alias?.some((a) => item.name_loc.trim().toLowerCase() == a.toLowerCase()) || item.name_loc.trim().toLowerCase() === keyword.trim().toLowerCase() || Number.isInteger(Number(keyword)) && item.id === Number(keyword)
|
|
1360
1362
|
);
|
|
1361
1363
|
if (exactMatch.length) return exactMatch;
|
|
1362
|
-
return this.fuzzySearchItems(alias.length ? alias : [keyword],
|
|
1364
|
+
return this.fuzzySearchItems(alias.length ? alias : [keyword], items);
|
|
1363
1365
|
}
|
|
1364
|
-
fuzzySearchItems(keywords,
|
|
1366
|
+
fuzzySearchItems(keywords, items) {
|
|
1365
1367
|
const resultMap = /* @__PURE__ */ new Map();
|
|
1366
1368
|
if (!keywords.length) return [];
|
|
1367
|
-
for (const item of
|
|
1369
|
+
for (const item of items) {
|
|
1368
1370
|
const cleanName = item.name_loc.toLowerCase().replace(/[^\p{L}\p{N}]/gu, "").trim();
|
|
1369
1371
|
let matchAllKeywords = true;
|
|
1370
1372
|
for (const keyword of keywords) {
|
|
@@ -1391,7 +1393,6 @@ var ItemService = class _ItemService extends import_koishi3.Service {
|
|
|
1391
1393
|
|
|
1392
1394
|
// src/app/core/match.service.ts
|
|
1393
1395
|
var import_koishi4 = require("koishi");
|
|
1394
|
-
var dotaconstants3 = __toESM(require("dotaconstants"));
|
|
1395
1396
|
|
|
1396
1397
|
// src/app/common/error.ts
|
|
1397
1398
|
var import_util = require("util");
|
|
@@ -1520,9 +1521,10 @@ __name(handleError, "handleError");
|
|
|
1520
1521
|
|
|
1521
1522
|
// src/app/core/match.service.ts
|
|
1522
1523
|
var MatchService = class _MatchService extends import_koishi4.Service {
|
|
1523
|
-
constructor(ctx,
|
|
1524
|
+
constructor(ctx, pluginVersion, dotaconstants) {
|
|
1524
1525
|
super(ctx, "dota2tracker.match", true);
|
|
1525
|
-
this.pluginVersion =
|
|
1526
|
+
this.pluginVersion = pluginVersion;
|
|
1527
|
+
this.dotaconstants = dotaconstants;
|
|
1526
1528
|
}
|
|
1527
1529
|
static {
|
|
1528
1530
|
__name(this, "MatchService");
|
|
@@ -1627,7 +1629,7 @@ var MatchService = class _MatchService extends import_koishi4.Service {
|
|
|
1627
1629
|
}
|
|
1628
1630
|
const facetData = await _MatchService.constantsInjectFacetData(constantsQuery, matchQuery, languageTag, this.ctx.dota2tracker.hero);
|
|
1629
1631
|
this.ctx.dota2tracker.cache.setFacetConstantsCache(languageTag, constantsQuery);
|
|
1630
|
-
const match = _MatchService.extendMatchData(matchQuery, facetData);
|
|
1632
|
+
const match = _MatchService.extendMatchData(matchQuery, facetData, this.dotaconstants);
|
|
1631
1633
|
return match;
|
|
1632
1634
|
} catch (error) {
|
|
1633
1635
|
this.ctx.dota2tracker.cache.deleteFacetConstantsCache(languageTag);
|
|
@@ -1652,7 +1654,7 @@ var MatchService = class _MatchService extends import_koishi4.Service {
|
|
|
1652
1654
|
return facetData;
|
|
1653
1655
|
}
|
|
1654
1656
|
// 对比赛数据进行补充以供生成模板函数使用
|
|
1655
|
-
static extendMatchData(matchQuery, facetData) {
|
|
1657
|
+
static extendMatchData(matchQuery, facetData, dotaconstants) {
|
|
1656
1658
|
const match = matchQuery.match;
|
|
1657
1659
|
const matchParsed = _MatchService.isMatchParsed(matchQuery);
|
|
1658
1660
|
["radiant", "dire"].forEach((team) => {
|
|
@@ -1772,9 +1774,9 @@ var MatchService = class _MatchService extends import_koishi4.Service {
|
|
|
1772
1774
|
}
|
|
1773
1775
|
purchaseTimesMap[item.itemId].push(item.time);
|
|
1774
1776
|
} else {
|
|
1775
|
-
const itemName =
|
|
1777
|
+
const itemName = dotaconstants.item_ids[item.itemId];
|
|
1776
1778
|
if (itemName) {
|
|
1777
|
-
const itemDetails =
|
|
1779
|
+
const itemDetails = dotaconstants.items[itemName];
|
|
1778
1780
|
if (itemDetails && itemDetails.cost) {
|
|
1779
1781
|
player.utilityScore += itemDetails.cost;
|
|
1780
1782
|
}
|
|
@@ -1787,7 +1789,7 @@ var MatchService = class _MatchService extends import_koishi4.Service {
|
|
|
1787
1789
|
for (let itemId in supportItemsCount) {
|
|
1788
1790
|
if (supportItemsCount[itemId] === 0) continue;
|
|
1789
1791
|
player.supportItemsCount.push({
|
|
1790
|
-
name:
|
|
1792
|
+
name: dotaconstants.item_ids[itemId],
|
|
1791
1793
|
count: supportItemsCount[itemId]
|
|
1792
1794
|
});
|
|
1793
1795
|
}
|
|
@@ -1795,13 +1797,13 @@ var MatchService = class _MatchService extends import_koishi4.Service {
|
|
|
1795
1797
|
player.items = [];
|
|
1796
1798
|
for (let i = 0; i <= 5; i++) {
|
|
1797
1799
|
const itemId = player[`item${i}Id`];
|
|
1798
|
-
const itemObject = createItemObject(itemId, purchaseTimesMap, purchaseTimeIndices);
|
|
1800
|
+
const itemObject = createItemObject(itemId, purchaseTimesMap, purchaseTimeIndices, dotaconstants);
|
|
1799
1801
|
player.items.push(itemObject);
|
|
1800
1802
|
}
|
|
1801
1803
|
player.backpacks = [];
|
|
1802
1804
|
for (let i = 0; i <= 2; i++) {
|
|
1803
1805
|
const itemId = player[`backpack${i}Id`];
|
|
1804
|
-
const itemObject = createItemObject(itemId, purchaseTimesMap, purchaseTimeIndices);
|
|
1806
|
+
const itemObject = createItemObject(itemId, purchaseTimesMap, purchaseTimeIndices, dotaconstants);
|
|
1805
1807
|
player.backpacks.push(itemObject);
|
|
1806
1808
|
}
|
|
1807
1809
|
if (player.additionalUnit) {
|
|
@@ -1809,12 +1811,12 @@ var MatchService = class _MatchService extends import_koishi4.Service {
|
|
|
1809
1811
|
player.unitBackpacks = [];
|
|
1810
1812
|
for (let i = 0; i <= 5; i++) {
|
|
1811
1813
|
const itemId = player.additionalUnit[`item${i}Id`];
|
|
1812
|
-
const itemObject = createItemObject(itemId, purchaseTimesMap, purchaseTimeIndices);
|
|
1814
|
+
const itemObject = createItemObject(itemId, purchaseTimesMap, purchaseTimeIndices, dotaconstants);
|
|
1813
1815
|
player.unitItems.push(itemObject);
|
|
1814
1816
|
}
|
|
1815
1817
|
for (let i = 0; i <= 2; i++) {
|
|
1816
1818
|
const itemId = player.additionalUnit[`backpack${i}Id`];
|
|
1817
|
-
const itemObject = createItemObject(itemId, purchaseTimesMap, purchaseTimeIndices);
|
|
1819
|
+
const itemObject = createItemObject(itemId, purchaseTimesMap, purchaseTimeIndices, dotaconstants);
|
|
1818
1820
|
player.unitBackpacks.push(itemObject);
|
|
1819
1821
|
}
|
|
1820
1822
|
}
|
|
@@ -1893,15 +1895,15 @@ var MatchService = class _MatchService extends import_koishi4.Service {
|
|
|
1893
1895
|
return matchQuery?.match?.parsedDateTime && matchQuery?.match?.players.filter((player) => player?.stats?.heroDamageReport?.dealtTotal).length > 0;
|
|
1894
1896
|
}
|
|
1895
1897
|
};
|
|
1896
|
-
function createItemObject(itemId, purchaseTimesMap, purchaseTimeIndices) {
|
|
1898
|
+
function createItemObject(itemId, purchaseTimesMap, purchaseTimeIndices, dotaconstants) {
|
|
1897
1899
|
if (itemId === void 0 || itemId === null) {
|
|
1898
1900
|
return null;
|
|
1899
1901
|
}
|
|
1900
|
-
if (
|
|
1902
|
+
if (dotaconstants.item_ids[itemId]) {
|
|
1901
1903
|
const currentIndex = purchaseTimeIndices.get(itemId) || 0;
|
|
1902
1904
|
const seconds = purchaseTimesMap[itemId]?.[currentIndex];
|
|
1903
1905
|
purchaseTimeIndices.set(itemId, currentIndex + 1);
|
|
1904
|
-
const name2 =
|
|
1906
|
+
const name2 = dotaconstants.item_ids[itemId];
|
|
1905
1907
|
const prefix = "recipe_";
|
|
1906
1908
|
const isRecipe = name2.startsWith(prefix);
|
|
1907
1909
|
const cleanName = isRecipe ? name2.substring(prefix.length) : name2;
|
|
@@ -1919,16 +1921,16 @@ __name(createItemObject, "createItemObject");
|
|
|
1919
1921
|
|
|
1920
1922
|
// src/app/core/player.service.ts
|
|
1921
1923
|
var import_koishi5 = require("koishi");
|
|
1922
|
-
var dotaconstants4 = __toESM(require("dotaconstants"));
|
|
1923
1924
|
var import_luxon3 = require("luxon");
|
|
1924
1925
|
var PlayerService = class _PlayerService extends import_koishi5.Service {
|
|
1925
|
-
|
|
1926
|
-
__name(this, "PlayerService");
|
|
1927
|
-
}
|
|
1928
|
-
constructor(ctx) {
|
|
1926
|
+
constructor(ctx, dotaconstants) {
|
|
1929
1927
|
super(ctx, "dota2tracker.player", true);
|
|
1928
|
+
this.dotaconstants = dotaconstants;
|
|
1930
1929
|
this.config = ctx.config;
|
|
1931
1930
|
}
|
|
1931
|
+
static {
|
|
1932
|
+
__name(this, "PlayerService");
|
|
1933
|
+
}
|
|
1932
1934
|
async getHeroRecommendation(steamId, player) {
|
|
1933
1935
|
const RECENT_IMP_WEIGHT = 0.1;
|
|
1934
1936
|
const LIFETIME_WIN_LOG_WEIGHT = 5;
|
|
@@ -2027,12 +2029,12 @@ var PlayerService = class _PlayerService extends import_koishi5.Service {
|
|
|
2027
2029
|
const lastMatchQuery = await this.ctx.dota2tracker.stratzAPI.queryPlayersLastMatchRankInfo({
|
|
2028
2030
|
steamAccountIds: [steamId]
|
|
2029
2031
|
});
|
|
2030
|
-
if (lastMatchQuery.players[0].steamAccount.isAnonymous) return {
|
|
2032
|
+
if (lastMatchQuery.players[0].steamAccount.isAnonymous) return { id: 0, isAnonymous: true };
|
|
2031
2033
|
lastMatchId = lastMatchQuery.players[0].matches[0]?.id;
|
|
2032
2034
|
} catch (error) {
|
|
2033
2035
|
this.logger.error(error);
|
|
2034
2036
|
}
|
|
2035
|
-
return {
|
|
2037
|
+
return { id: lastMatchId };
|
|
2036
2038
|
}
|
|
2037
2039
|
async getFormattedPlayerData(steamId, heroId, languageTag) {
|
|
2038
2040
|
const playerQuery = await this.ctx.dota2tracker.stratzAPI.queryPlayerInfoWith25Matches({
|
|
@@ -2049,12 +2051,15 @@ var PlayerService = class _PlayerService extends import_koishi5.Service {
|
|
|
2049
2051
|
dotaPlus: null
|
|
2050
2052
|
}
|
|
2051
2053
|
};
|
|
2052
|
-
const player = _PlayerService.extendPlayerData(
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2054
|
+
const player = _PlayerService.extendPlayerData(
|
|
2055
|
+
{
|
|
2056
|
+
playerQuery,
|
|
2057
|
+
playerExtraQuery,
|
|
2058
|
+
genHero: heroId ? { heroId, name: this.ctx.dota2tracker.i18n.getConstantLocale(languageTag).dota2tracker.template.hero_names[heroId] } : null,
|
|
2059
|
+
estimateRank: this.config.playerRankEstimate
|
|
2060
|
+
},
|
|
2061
|
+
this.dotaconstants
|
|
2062
|
+
);
|
|
2058
2063
|
return player;
|
|
2059
2064
|
}
|
|
2060
2065
|
async validateSteamId(steamId) {
|
|
@@ -2076,14 +2081,14 @@ var PlayerService = class _PlayerService extends import_koishi5.Service {
|
|
|
2076
2081
|
};
|
|
2077
2082
|
}
|
|
2078
2083
|
}
|
|
2079
|
-
static extendPlayerData(param) {
|
|
2084
|
+
static extendPlayerData(param, dotaconstants) {
|
|
2080
2085
|
const { playerQuery, playerExtraQuery, genHero, estimateRank } = param;
|
|
2081
2086
|
const player = playerQuery.player;
|
|
2082
2087
|
const playerExtra = playerExtraQuery?.player;
|
|
2083
2088
|
if (player.steamAccount.isAnonymous) {
|
|
2084
2089
|
for (let index = 0; index < 25; index++) {
|
|
2085
2090
|
const random = new import_koishi5.Random(() => enhancedSimpleHashToSeed(`${player.steamAccount.id}-${index}`));
|
|
2086
|
-
const heroId = random.pick(Object.keys(
|
|
2091
|
+
const heroId = random.pick(Object.keys(dotaconstants.heroes));
|
|
2087
2092
|
player.matches.push({
|
|
2088
2093
|
id: 1e9 + index,
|
|
2089
2094
|
gameMode: "UNKNOWN",
|
|
@@ -2100,7 +2105,7 @@ var PlayerService = class _PlayerService extends import_koishi5.Service {
|
|
|
2100
2105
|
kills: random.int(0, 20),
|
|
2101
2106
|
deaths: random.int(0, 20),
|
|
2102
2107
|
assists: random.int(0, 20),
|
|
2103
|
-
hero: { id: heroId, shortName:
|
|
2108
|
+
hero: { id: heroId, shortName: dotaconstants.heroes[heroId].name.match(/^npc_dota_hero_(.+)$/)[1] }
|
|
2104
2109
|
}
|
|
2105
2110
|
]
|
|
2106
2111
|
});
|
|
@@ -2258,8 +2263,8 @@ var CacheService = class extends import_koishi6.Service {
|
|
|
2258
2263
|
async getMatchCache(matchId) {
|
|
2259
2264
|
return this.ctx.cache.get("dt_previous_query_results", String(matchId));
|
|
2260
2265
|
}
|
|
2261
|
-
setMatchCache(matchId, matchQuery,
|
|
2262
|
-
this.ctx.cache.set("dt_previous_query_results", String(matchQuery.match.id), { data: matchQuery, pluginVersion
|
|
2266
|
+
setMatchCache(matchId, matchQuery, pluginVersion) {
|
|
2267
|
+
this.ctx.cache.set("dt_previous_query_results", String(matchQuery.match.id), { data: matchQuery, pluginVersion }, DAYS_30);
|
|
2263
2268
|
}
|
|
2264
2269
|
markMatchAsSended(matchId) {
|
|
2265
2270
|
this.ctx.cache.set("dt_sended_match_id", String(matchId), void 0, DAYS_30);
|
|
@@ -2388,14 +2393,6 @@ var import_path = __toESM(require("path"));
|
|
|
2388
2393
|
var import_axios2 = __toESM(require("axios"));
|
|
2389
2394
|
var import_https_proxy_agent = require("https-proxy-agent");
|
|
2390
2395
|
var StratzAPI = class extends import_koishi8.Service {
|
|
2391
|
-
constructor(ctx, pluginDir3) {
|
|
2392
|
-
super(ctx, "dota2tracker.stratz-api", true);
|
|
2393
|
-
this.pluginDir = pluginDir3;
|
|
2394
|
-
this.config = ctx.config;
|
|
2395
|
-
this.queue = new MiniQueue(ctx, { interval: 200 });
|
|
2396
|
-
this.http = import_axios2.default.create({ timeout: 1e4, signal: this.abortController.signal });
|
|
2397
|
-
ctx.on("dispose", () => this.dispose());
|
|
2398
|
-
}
|
|
2399
2396
|
static {
|
|
2400
2397
|
__name(this, "StratzAPI");
|
|
2401
2398
|
}
|
|
@@ -2403,12 +2400,21 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2403
2400
|
queue;
|
|
2404
2401
|
http;
|
|
2405
2402
|
abortController = new AbortController();
|
|
2403
|
+
graphqlQueriesDir;
|
|
2404
|
+
constructor(ctx, currentDir) {
|
|
2405
|
+
super(ctx, "dota2tracker.stratz-api", true);
|
|
2406
|
+
this.config = ctx.config;
|
|
2407
|
+
this.graphqlQueriesDir = import_path.default.join(currentDir, "queries");
|
|
2408
|
+
this.queue = new MiniQueue(ctx, { interval: 200 });
|
|
2409
|
+
this.http = import_axios2.default.create({ timeout: 15e3, signal: this.abortController.signal });
|
|
2410
|
+
ctx.on("dispose", () => this.dispose());
|
|
2411
|
+
}
|
|
2406
2412
|
dispose() {
|
|
2407
2413
|
this.queue.dispose();
|
|
2408
2414
|
this.abortController.abort();
|
|
2409
2415
|
}
|
|
2410
2416
|
async queryGetWeeklyMetaByPosition({ bracketIds }) {
|
|
2411
|
-
return this.query("GetWeeklyMetaByPosition", { bracketIds }, (data) => !!data
|
|
2417
|
+
return this.query("GetWeeklyMetaByPosition", { bracketIds }, (data) => !!data?.heroStats);
|
|
2412
2418
|
}
|
|
2413
2419
|
async queryPlayerPerformanceForHeroRecommendation({ steamAccountId, recentDateTime }) {
|
|
2414
2420
|
return this.query(
|
|
@@ -2417,7 +2423,7 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2417
2423
|
steamAccountId,
|
|
2418
2424
|
recentDateTime
|
|
2419
2425
|
},
|
|
2420
|
-
(data) => !!data
|
|
2426
|
+
(data) => !!data?.player
|
|
2421
2427
|
);
|
|
2422
2428
|
}
|
|
2423
2429
|
async queryPlayersMatchesForDaily(steamAccountIds, seconds) {
|
|
@@ -2427,11 +2433,11 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2427
2433
|
steamAccountIds,
|
|
2428
2434
|
seconds
|
|
2429
2435
|
},
|
|
2430
|
-
(data) => !!data
|
|
2436
|
+
(data) => !!data?.players
|
|
2431
2437
|
);
|
|
2432
2438
|
}
|
|
2433
2439
|
async queryVerifyingPlayer(steamAccountId) {
|
|
2434
|
-
return this.query("VerifyingPlayer", { steamAccountId }, (data) => !!data
|
|
2440
|
+
return this.query("VerifyingPlayer", { steamAccountId }, (data) => !!data?.player);
|
|
2435
2441
|
}
|
|
2436
2442
|
async queryPlayerExtraInfo({ steamAccountId, matchCount, heroIds }) {
|
|
2437
2443
|
return this.query(
|
|
@@ -2441,11 +2447,11 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2441
2447
|
matchCount,
|
|
2442
2448
|
heroIds
|
|
2443
2449
|
},
|
|
2444
|
-
(data) => !!data
|
|
2450
|
+
(data) => !!data?.player
|
|
2445
2451
|
);
|
|
2446
2452
|
}
|
|
2447
2453
|
async queryPlayersInfoWith10MatchesForGuild({ steamAccountIds }) {
|
|
2448
|
-
return this.query("PlayersInfoWith10MatchesForGuild", { steamAccountIds }, (data) => !!data
|
|
2454
|
+
return this.query("PlayersInfoWith10MatchesForGuild", { steamAccountIds }, (data) => !!data?.players);
|
|
2449
2455
|
}
|
|
2450
2456
|
async queryPlayerInfoWith25Matches({ steamAccountId, heroIds }) {
|
|
2451
2457
|
return this.query(
|
|
@@ -2454,17 +2460,17 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2454
2460
|
steamAccountId,
|
|
2455
2461
|
heroIds
|
|
2456
2462
|
},
|
|
2457
|
-
(data) => !!data
|
|
2463
|
+
(data) => !!data?.player
|
|
2458
2464
|
);
|
|
2459
2465
|
}
|
|
2460
2466
|
async queryPlayersLastMatchRankInfo({ steamAccountIds }) {
|
|
2461
|
-
return this.query("PlayersLastmatchRankinfo", { steamAccountIds }, (data) => !!data
|
|
2467
|
+
return this.query("PlayersLastmatchRankinfo", { steamAccountIds }, (data) => !!data?.players);
|
|
2462
2468
|
}
|
|
2463
2469
|
async queryConstants(languageTag) {
|
|
2464
|
-
return this.query("Constants", { language: this.ctx.dota2tracker.i18n.getGraphqlLanguageTag(languageTag) }, (data) => !!data
|
|
2470
|
+
return this.query("Constants", { language: this.ctx.dota2tracker.i18n.getGraphqlLanguageTag(languageTag) }, (data) => !!data?.constants);
|
|
2465
2471
|
}
|
|
2466
2472
|
async queryMatchInfo(matchId) {
|
|
2467
|
-
return this.query("MatchInfo", { matchId }, (data) => !!data
|
|
2473
|
+
return this.query("MatchInfo", { matchId }, (data) => !!data?.match);
|
|
2468
2474
|
}
|
|
2469
2475
|
async requestParseMatch(matchId) {
|
|
2470
2476
|
const response = await this.query("RequestMatchDataAnalysis", {
|
|
@@ -2525,7 +2531,7 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2525
2531
|
});
|
|
2526
2532
|
}
|
|
2527
2533
|
loadGraphqlFile(queryName) {
|
|
2528
|
-
return import_fs.default.readFileSync(import_path.default.join(this.
|
|
2534
|
+
return import_fs.default.readFileSync(import_path.default.join(this.graphqlQueriesDir, `${queryName}.graphql`), { encoding: "utf-8" }).replace(/[\r\n]+/g, " ");
|
|
2529
2535
|
}
|
|
2530
2536
|
};
|
|
2531
2537
|
var MiniQueue = class {
|
|
@@ -2592,7 +2598,7 @@ var ValveAPI = class extends import_koishi9.Service {
|
|
|
2592
2598
|
constructor(ctx) {
|
|
2593
2599
|
super(ctx, "dota2tracker.valve-api", true);
|
|
2594
2600
|
this.config = ctx.config;
|
|
2595
|
-
this.http = import_axios3.default.create({ timeout:
|
|
2601
|
+
this.http = import_axios3.default.create({ timeout: 15e3, signal: this.abortController.signal, baseURL: this.baseURL });
|
|
2596
2602
|
ctx.on("dispose", () => this.dispose());
|
|
2597
2603
|
}
|
|
2598
2604
|
dispose() {
|
|
@@ -2643,7 +2649,6 @@ var import_koishi10 = require("koishi");
|
|
|
2643
2649
|
var import_ejs = __toESM(require("ejs"));
|
|
2644
2650
|
var import_fs2 = __toESM(require("fs"));
|
|
2645
2651
|
var import_path2 = __toESM(require("path"));
|
|
2646
|
-
var dotaconstants5 = __toESM(require("dotaconstants"));
|
|
2647
2652
|
|
|
2648
2653
|
// src/app/common/types.ts
|
|
2649
2654
|
var ImageType = /* @__PURE__ */ ((ImageType2) => {
|
|
@@ -2666,14 +2671,16 @@ var ImageFormat = /* @__PURE__ */ ((ImageFormat2) => {
|
|
|
2666
2671
|
// src/app/presentation/image.renderer.ts
|
|
2667
2672
|
var import_luxon5 = require("luxon");
|
|
2668
2673
|
var ImageRenderer = class extends import_koishi10.Service {
|
|
2669
|
-
constructor(ctx,
|
|
2674
|
+
constructor(ctx, currentDir, dotaconstants) {
|
|
2670
2675
|
super(ctx, "dota2tracker.image", true);
|
|
2671
|
-
this.
|
|
2676
|
+
this.dotaconstants = dotaconstants;
|
|
2672
2677
|
this.config = ctx.config;
|
|
2678
|
+
this.templateDir = import_path2.default.join(currentDir, "templates");
|
|
2673
2679
|
}
|
|
2674
2680
|
static {
|
|
2675
2681
|
__name(this, "ImageRenderer");
|
|
2676
2682
|
}
|
|
2683
|
+
templateDir;
|
|
2677
2684
|
async renderToImageByFile(data, templateName, type, languageTag) {
|
|
2678
2685
|
const html = await this.generateHTML(data, { source: "FILE", templateName, type }, languageTag);
|
|
2679
2686
|
return this.ctx.puppeteer.render(html);
|
|
@@ -2690,7 +2697,7 @@ var ImageRenderer = class extends import_koishi10.Service {
|
|
|
2690
2697
|
data,
|
|
2691
2698
|
ImageType,
|
|
2692
2699
|
ImageFormat,
|
|
2693
|
-
dotaconstants:
|
|
2700
|
+
dotaconstants: this.dotaconstants,
|
|
2694
2701
|
DateTime: import_luxon5.DateTime,
|
|
2695
2702
|
$t: /* @__PURE__ */ __name((key, params) => this.ctx.dota2tracker.i18n.$t(languageTag, key, params), "$t"),
|
|
2696
2703
|
languageTag,
|
|
@@ -2701,7 +2708,7 @@ var ImageRenderer = class extends import_koishi10.Service {
|
|
|
2701
2708
|
try {
|
|
2702
2709
|
let html;
|
|
2703
2710
|
if (template.source === "FILE") {
|
|
2704
|
-
const templatePath = import_path2.default.join(this.
|
|
2711
|
+
const templatePath = import_path2.default.join(this.templateDir, template.type, `${template.templateName}.ejs`);
|
|
2705
2712
|
html = await import_ejs.default.renderFile(templatePath, templateData, {
|
|
2706
2713
|
strict: false
|
|
2707
2714
|
});
|
|
@@ -2711,7 +2718,7 @@ var ImageRenderer = class extends import_koishi10.Service {
|
|
|
2711
2718
|
async: true
|
|
2712
2719
|
});
|
|
2713
2720
|
}
|
|
2714
|
-
if (process.env.NODE_ENV === "development") import_fs2.default.writeFileSync(import_path2.default.
|
|
2721
|
+
if (process.env.NODE_ENV === "development") import_fs2.default.writeFileSync(import_path2.default.resolve(process.cwd(), "temp.html"), html);
|
|
2715
2722
|
return html;
|
|
2716
2723
|
} catch (error) {
|
|
2717
2724
|
this.logger.error(error);
|
|
@@ -2721,8 +2728,8 @@ var ImageRenderer = class extends import_koishi10.Service {
|
|
|
2721
2728
|
getImageUrl(image, type = "local" /* Local */, format = "png" /* png */) {
|
|
2722
2729
|
if (type === "local" /* Local */) {
|
|
2723
2730
|
try {
|
|
2724
|
-
if (format === "svg" /* svg */) return import_fs2.default.readFileSync(import_path2.default.join(this.
|
|
2725
|
-
const imageData = import_fs2.default.readFileSync(import_path2.default.join(this.
|
|
2731
|
+
if (format === "svg" /* svg */) return import_fs2.default.readFileSync(import_path2.default.join(this.templateDir, "images", `${image}.svg`));
|
|
2732
|
+
const imageData = import_fs2.default.readFileSync(import_path2.default.join(this.templateDir, "images", `${image}.${format}`));
|
|
2726
2733
|
const base64Data = imageData.toString("base64");
|
|
2727
2734
|
return `data:image/png;base64,${base64Data}`;
|
|
2728
2735
|
} catch (error) {
|
|
@@ -3456,20 +3463,25 @@ __name(resolvePlayerAndHandleErrors, "resolvePlayerAndHandleErrors");
|
|
|
3456
3463
|
// src/app/commands/hero-of-the-day.command.ts
|
|
3457
3464
|
var import_luxon10 = require("luxon");
|
|
3458
3465
|
function registerHeroOfTheDayCommand(ctx) {
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3466
|
+
const name2 = "hero-of-the-day";
|
|
3467
|
+
ctx.command(`dota2tracker.${name2} <input_data>`).alias("今日英雄").option("days", "-d <value:number>").action(async ({ session, options }, input_data) => {
|
|
3468
|
+
try {
|
|
3469
|
+
const steamId = await resolvePlayerAndHandleErrors(ctx, session, input_data);
|
|
3470
|
+
if (steamId === null) return;
|
|
3471
|
+
const days = clamp(options.days, 1, 180, 30);
|
|
3472
|
+
const result = await ctx.dota2tracker.stratzAPI.queryPlayerPerformanceForHeroRecommendation({
|
|
3473
|
+
steamAccountId: steamId,
|
|
3474
|
+
recentDateTime: import_luxon10.DateTime.now().minus({ days }).toUnixInteger()
|
|
3475
|
+
});
|
|
3476
|
+
const recommendationPromise = ctx.dota2tracker.player.getHeroRecommendation(steamId, result.player);
|
|
3477
|
+
const metaPromise = ctx.dota2tracker.hero.getWeeklyHeroMeta(PlayerService.estimateWeightedRank(result.player));
|
|
3478
|
+
const [recommendation, weeklyHeroMeta] = await Promise.all([recommendationPromise, metaPromise]);
|
|
3479
|
+
const languageTag = await ctx.dota2tracker.i18n.getLanguageTag({ session });
|
|
3480
|
+
const message = ctx.dota2tracker.messageBuilder.buildHeroOfTheDayMessage(languageTag, recommendation, weeklyHeroMeta);
|
|
3481
|
+
return message;
|
|
3482
|
+
} catch (error) {
|
|
3483
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3484
|
+
}
|
|
3473
3485
|
});
|
|
3474
3486
|
}
|
|
3475
3487
|
__name(registerHeroOfTheDayCommand, "registerHeroOfTheDayCommand");
|
|
@@ -3477,14 +3489,19 @@ __name(registerHeroOfTheDayCommand, "registerHeroOfTheDayCommand");
|
|
|
3477
3489
|
// src/app/commands/query-hero.command.ts
|
|
3478
3490
|
function registerQueryHeroCommand(ctx) {
|
|
3479
3491
|
ctx.command("dota2tracker.query-hero <input_data>").option("random", "-r").alias("查询英雄").action(async ({ session, options }, input_data) => {
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3492
|
+
const name2 = "query-hero";
|
|
3493
|
+
try {
|
|
3494
|
+
if (input_data || options.random) {
|
|
3495
|
+
await session.send(session.text(".querying_hero"));
|
|
3496
|
+
const languageTag = await ctx.dota2tracker.i18n.getLanguageTag({ session });
|
|
3497
|
+
const heroData = await ctx.dota2tracker.hero.getHeroDetails(input_data, languageTag, options.random);
|
|
3498
|
+
if (!heroData) return session.text(".not_found");
|
|
3499
|
+
const image = await ctx.dota2tracker.image.renderToImageByFile(heroData, ctx.config.template_hero, "hero" /* Hero */, languageTag);
|
|
3500
|
+
const message = ctx.dota2tracker.messageBuilder.buildHeroMessage(heroData);
|
|
3501
|
+
await session.send(message + image);
|
|
3502
|
+
}
|
|
3503
|
+
} catch (error) {
|
|
3504
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3488
3505
|
}
|
|
3489
3506
|
});
|
|
3490
3507
|
}
|
|
@@ -3540,25 +3557,40 @@ __name(registerQueryItemCommand, "registerQueryItemCommand");
|
|
|
3540
3557
|
// src/app/commands/query-match.command.ts
|
|
3541
3558
|
function registerQueryMatchCommand(ctx) {
|
|
3542
3559
|
ctx.command("dota2tracker.query-match <match_id>").alias("查询比赛").option("parse", "-p").option("template", "-t <value:string>").action(async ({ session, options }, match_id) => {
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3560
|
+
const name2 = "query-match";
|
|
3561
|
+
try {
|
|
3562
|
+
if (!match_id) return session.text(".empty_input");
|
|
3563
|
+
if (!/^\d{1,11}$/.test(match_id)) return session.text(".match_id_invalid");
|
|
3564
|
+
await session.send(session.text(".querying_match"));
|
|
3565
|
+
return await handleQueryMatchCommand(ctx, ctx.config, session, options, match_id);
|
|
3566
|
+
} catch (error) {
|
|
3567
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3568
|
+
}
|
|
3547
3569
|
});
|
|
3548
3570
|
ctx.command("dota2tracker.query-recent-match [input_data]").alias("查询最近比赛").option("parse", "-p").option("template", "-t <value:string>").action(async ({ session, options }, input_data) => {
|
|
3549
|
-
const
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3571
|
+
const name2 = "query-recent-match";
|
|
3572
|
+
try {
|
|
3573
|
+
const steamId = await resolvePlayerAndHandleErrors(ctx, session, input_data);
|
|
3574
|
+
if (steamId === null) return;
|
|
3575
|
+
session.send(session.text(".querying_match"));
|
|
3576
|
+
let lastMatch;
|
|
3577
|
+
try {
|
|
3578
|
+
lastMatch = await ctx.dota2tracker.player.getLastMatchId(Number(steamId));
|
|
3579
|
+
} catch (error) {
|
|
3580
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3581
|
+
}
|
|
3582
|
+
if (!lastMatch?.id) return session.text(".query_failed");
|
|
3583
|
+
if (lastMatch.isAnonymous) return session.text(".is_anonymous");
|
|
3584
|
+
return await handleQueryMatchCommand(ctx, ctx.config, session, options, lastMatch.id);
|
|
3585
|
+
} catch (error) {
|
|
3586
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3587
|
+
}
|
|
3556
3588
|
});
|
|
3557
3589
|
}
|
|
3558
3590
|
__name(registerQueryMatchCommand, "registerQueryMatchCommand");
|
|
3559
3591
|
async function handleQueryMatchCommand(ctx, config, session, options, matchId) {
|
|
3560
3592
|
const languageTag = await ctx.dota2tracker.i18n.getLanguageTag({ session });
|
|
3561
|
-
const result = await ctx.dota2tracker.match.getMatchResult({ matchId: Number(matchId),
|
|
3593
|
+
const result = await ctx.dota2tracker.match.getMatchResult({ matchId: Number(matchId), waitForParse: options.parse, allowFallback: config.enableOpenDotaFallback });
|
|
3562
3594
|
if (result.status === "PENDING") {
|
|
3563
3595
|
const subscriber = ctx.dota2tracker.parsePolling.createSubscriberByCommand(session, languageTag, { templateName: options?.template });
|
|
3564
3596
|
ctx.dota2tracker.parsePolling.add(result.matchId, [subscriber]);
|
|
@@ -3569,7 +3601,6 @@ async function handleQueryMatchCommand(ctx, config, session, options, matchId) {
|
|
|
3569
3601
|
const formattedMatchData = await ctx.dota2tracker.match.generateMatchData(result.matchData, languageTag);
|
|
3570
3602
|
const message = ctx.dota2tracker.messageBuilder.buildMatchMessage(languageTag, formattedMatchData, []);
|
|
3571
3603
|
const image = await ctx.dota2tracker.image.renderToImageByFile(formattedMatchData, options.template || config.template_match, "match" /* Match */, languageTag);
|
|
3572
|
-
await ctx.dota2tracker.image.renderToImageByFile(formattedMatchData, options.template || config.template_match, "match" /* Match */, languageTag);
|
|
3573
3604
|
return message + image;
|
|
3574
3605
|
}
|
|
3575
3606
|
}
|
|
@@ -3590,18 +3621,23 @@ __name(registerQueryMembersCommand, "registerQueryMembersCommand");
|
|
|
3590
3621
|
// src/app/commands/query-player.command.ts
|
|
3591
3622
|
function registerQueryPlayerCommand(ctx) {
|
|
3592
3623
|
ctx.command("dota2tracker.query-player <input_data>").option("hero", "-o <value:string>").alias("查询玩家").action(async ({ session, options }, input_data) => {
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
if (
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3624
|
+
const name2 = "query-player";
|
|
3625
|
+
try {
|
|
3626
|
+
if (session.guild || !session.guild && input_data) {
|
|
3627
|
+
const steamId = await resolvePlayerAndHandleErrors(ctx, session, input_data);
|
|
3628
|
+
if (steamId === null) return;
|
|
3629
|
+
session.send(session.text(".querying_player"));
|
|
3630
|
+
const heroId = ctx.dota2tracker.i18n.findHeroIdInLocale(options.hero);
|
|
3631
|
+
const languageTag = await ctx.dota2tracker.i18n.getLanguageTag({ session });
|
|
3632
|
+
const formattedPlayerData = await ctx.dota2tracker.player.getFormattedPlayerData(steamId, heroId, languageTag);
|
|
3633
|
+
const image = await ctx.dota2tracker.image.renderToImageByFile(formattedPlayerData, ctx.config.template_player, "player" /* Player */, languageTag);
|
|
3634
|
+
const message = ctx.dota2tracker.messageBuilder.buildPlayerMessage(steamId);
|
|
3635
|
+
return message + image;
|
|
3636
|
+
} else {
|
|
3637
|
+
return session.text("commands.dota2tracker.common.messages.user_not_in_group");
|
|
3638
|
+
}
|
|
3639
|
+
} catch (error) {
|
|
3640
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3605
3641
|
}
|
|
3606
3642
|
});
|
|
3607
3643
|
}
|
|
@@ -3686,7 +3722,7 @@ var OpenDotaAPI = class extends import_koishi15.Service {
|
|
|
3686
3722
|
constructor(ctx) {
|
|
3687
3723
|
super(ctx, "dota2tracker.opendota-api", true);
|
|
3688
3724
|
this.config = ctx.config;
|
|
3689
|
-
this.http = import_axios4.default.create({ timeout:
|
|
3725
|
+
this.http = import_axios4.default.create({ timeout: 15e3, signal: this.abortController.signal, baseURL: this.BASE_URL });
|
|
3690
3726
|
ctx.on("dispose", () => this.dispose());
|
|
3691
3727
|
}
|
|
3692
3728
|
dispose() {
|
|
@@ -3736,14 +3772,14 @@ var OpenDotaAPI = class extends import_koishi15.Service {
|
|
|
3736
3772
|
|
|
3737
3773
|
// src/app/core/opendota.adapter.ts
|
|
3738
3774
|
var import_koishi16 = require("koishi");
|
|
3739
|
-
var dotaconstants6 = __toESM(require("dotaconstants"));
|
|
3740
3775
|
var OpenDotaAdapter = class extends import_koishi16.Service {
|
|
3776
|
+
constructor(ctx, dotaconstants) {
|
|
3777
|
+
super(ctx, "dota2tracker.opendota-adapter", true);
|
|
3778
|
+
this.dotaconstants = dotaconstants;
|
|
3779
|
+
}
|
|
3741
3780
|
static {
|
|
3742
3781
|
__name(this, "OpenDotaAdapter");
|
|
3743
3782
|
}
|
|
3744
|
-
constructor(ctx) {
|
|
3745
|
-
super(ctx, "dota2tracker.opendota-adapter", true);
|
|
3746
|
-
}
|
|
3747
3783
|
transform(_match) {
|
|
3748
3784
|
determinePlayerPositions(_match);
|
|
3749
3785
|
const players = [];
|
|
@@ -3791,9 +3827,9 @@ var OpenDotaAdapter = class extends import_koishi16.Service {
|
|
|
3791
3827
|
steamAccount: { name: _player.personaname, seasonRank: _player.rank_tier, seasonLeaderboardRank: null },
|
|
3792
3828
|
hero: {
|
|
3793
3829
|
id: _player.hero_id,
|
|
3794
|
-
name:
|
|
3795
|
-
shortName:
|
|
3796
|
-
facets: [...
|
|
3830
|
+
name: this.dotaconstants.heroes[_player.hero_id].name,
|
|
3831
|
+
shortName: this.dotaconstants.heroes[_player.hero_id].name.match(/^npc_dota_hero_(.+)$/)[1],
|
|
3832
|
+
facets: [...this.dotaconstants.hero_abilities[this.dotaconstants.heroes[_player.hero_id].name].facets.map((f) => ({ id: -1, name: f.name }))]
|
|
3797
3833
|
},
|
|
3798
3834
|
dotaPlus: null,
|
|
3799
3835
|
stats: {
|
|
@@ -3824,7 +3860,7 @@ var OpenDotaAdapter = class extends import_koishi16.Service {
|
|
|
3824
3860
|
disableCount: 0
|
|
3825
3861
|
}
|
|
3826
3862
|
},
|
|
3827
|
-
itemPurchases: _player.purchase_log.map((p) => ({ time: p.time, itemId:
|
|
3863
|
+
itemPurchases: _player.purchase_log.map((p) => ({ time: p.time, itemId: this.dotaconstants.items[p.key].id }))
|
|
3828
3864
|
},
|
|
3829
3865
|
additionalUnit: null
|
|
3830
3866
|
};
|
|
@@ -3853,8 +3889,8 @@ var OpenDotaAdapter = class extends import_koishi16.Service {
|
|
|
3853
3889
|
const match = {
|
|
3854
3890
|
id: _match.match_id,
|
|
3855
3891
|
didRadiantWin: _match.radiant_win,
|
|
3856
|
-
lobbyType: convertLobbyType(_match.lobby_type),
|
|
3857
|
-
gameMode: convertGameMode(_match.game_mode),
|
|
3892
|
+
lobbyType: convertLobbyType(_match.lobby_type, this.dotaconstants),
|
|
3893
|
+
gameMode: convertGameMode(_match.game_mode, this.dotaconstants),
|
|
3858
3894
|
regionId: _match.region,
|
|
3859
3895
|
parsedDateTime: _match.start_time + _match.duration,
|
|
3860
3896
|
startDateTime: _match.start_time,
|
|
@@ -3939,7 +3975,7 @@ function convertPosition(openDotaPosition) {
|
|
|
3939
3975
|
}
|
|
3940
3976
|
}
|
|
3941
3977
|
__name(convertPosition, "convertPosition");
|
|
3942
|
-
function convertLobbyType(openDotaLobbyType) {
|
|
3978
|
+
function convertLobbyType(openDotaLobbyType, dotaconstants) {
|
|
3943
3979
|
const map = {
|
|
3944
3980
|
lobby_type_normal: "UNRANKED" /* Unranked */,
|
|
3945
3981
|
lobby_type_practice: "PRACTICE" /* Practice */,
|
|
@@ -3956,11 +3992,11 @@ function convertLobbyType(openDotaLobbyType) {
|
|
|
3956
3992
|
lobby_type_new_player: "COOP_VS_BOTS" /* CoopVsBots */,
|
|
3957
3993
|
lobby_type_featured: "EVENT" /* Event */
|
|
3958
3994
|
};
|
|
3959
|
-
return map[
|
|
3995
|
+
return map[dotaconstants.lobby_type[openDotaLobbyType].name] || "EVENT" /* Event */;
|
|
3960
3996
|
}
|
|
3961
3997
|
__name(convertLobbyType, "convertLobbyType");
|
|
3962
|
-
function convertGameMode(openDotaGameModeId) {
|
|
3963
|
-
const gameModeName =
|
|
3998
|
+
function convertGameMode(openDotaGameModeId, dotaconstants) {
|
|
3999
|
+
const gameModeName = dotaconstants.game_mode[openDotaGameModeId]?.name;
|
|
3964
4000
|
switch (gameModeName) {
|
|
3965
4001
|
case "game_mode_all_pick":
|
|
3966
4002
|
return "ALL_PICK" /* AllPick */;
|
|
@@ -4178,7 +4214,7 @@ var globRequire_locales_schema_yml = __glob({
|
|
|
4178
4214
|
});
|
|
4179
4215
|
|
|
4180
4216
|
// src/config.ts
|
|
4181
|
-
var
|
|
4217
|
+
var templateDir = import_path4.default.join(__dirname, "templates");
|
|
4182
4218
|
var allI18nConfigs = Object.fromEntries(Object.keys(LanguageTags).map((lang) => [lang, globRequire_locales_schema_yml(`./locales/${lang}.schema.yml`)._config]));
|
|
4183
4219
|
var Config = import_koishi17.Schema.intersect([
|
|
4184
4220
|
import_koishi17.Schema.intersect([
|
|
@@ -4249,9 +4285,9 @@ var Config = import_koishi17.Schema.intersect([
|
|
|
4249
4285
|
]).i18n(getI18n("report"))
|
|
4250
4286
|
]),
|
|
4251
4287
|
import_koishi17.Schema.object({
|
|
4252
|
-
template_match: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(
|
|
4253
|
-
template_player: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(
|
|
4254
|
-
template_hero: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(
|
|
4288
|
+
template_match: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(templateDir, "match"))]).default("match_1"),
|
|
4289
|
+
template_player: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(templateDir, "player"))]).default("player_1"),
|
|
4290
|
+
template_hero: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(templateDir, "hero"))]).default("hero_1"),
|
|
4255
4291
|
playerRankEstimate: import_koishi17.Schema.boolean().default(true),
|
|
4256
4292
|
templateFonts: import_koishi17.Schema.array(String).default([]).role("table")
|
|
4257
4293
|
}).i18n(getI18n("template"))
|
|
@@ -4285,16 +4321,18 @@ var inject = {
|
|
|
4285
4321
|
required: ["database", "puppeteer", "cache"],
|
|
4286
4322
|
optional: ["cron", "console"]
|
|
4287
4323
|
};
|
|
4288
|
-
var pluginDir2 = import_path5.default.resolve(__dirname, "..");
|
|
4289
|
-
var pluginVersion = require(import_path5.default.join(pluginDir2, "package.json")).version;
|
|
4290
4324
|
async function apply(ctx, config) {
|
|
4325
|
+
const lib = await import("dotaconstants");
|
|
4326
|
+
const dotaconstants = lib.default || lib;
|
|
4291
4327
|
const logger = ctx.logger("dota2tracker");
|
|
4328
|
+
const currentDir = import_path5.default.resolve(__dirname);
|
|
4329
|
+
const pluginVersion = require(import_path5.default.join(currentDir, "..", "package.json")).version;
|
|
4292
4330
|
ctx.dota2tracker = {};
|
|
4293
|
-
ctx.dota2tracker.i18n = new I18NService(ctx);
|
|
4294
|
-
ctx.dota2tracker.image = new ImageRenderer(ctx,
|
|
4331
|
+
ctx.dota2tracker.i18n = new I18NService(ctx, dotaconstants);
|
|
4332
|
+
ctx.dota2tracker.image = new ImageRenderer(ctx, currentDir, dotaconstants);
|
|
4295
4333
|
ctx.dota2tracker.messageBuilder = new MessageBuilder(ctx);
|
|
4296
|
-
ctx.dota2tracker.match = new MatchService(ctx, pluginVersion);
|
|
4297
|
-
ctx.dota2tracker.player = new PlayerService(ctx);
|
|
4334
|
+
ctx.dota2tracker.match = new MatchService(ctx, pluginVersion, dotaconstants);
|
|
4335
|
+
ctx.dota2tracker.player = new PlayerService(ctx, dotaconstants);
|
|
4298
4336
|
if (ctx.cron) {
|
|
4299
4337
|
ctx.dota2tracker.matchWatcher = new MatchWatcherTask(ctx);
|
|
4300
4338
|
ctx.dota2tracker.parsePolling = new ParsePollingTask(ctx);
|
|
@@ -4306,15 +4344,15 @@ async function apply(ctx, config) {
|
|
|
4306
4344
|
} else {
|
|
4307
4345
|
logger.info(ctx.dota2tracker.i18n.gt("dota2tracker.logger.cron_not_enabled"));
|
|
4308
4346
|
}
|
|
4309
|
-
ctx.dota2tracker.hero = new HeroService(ctx);
|
|
4347
|
+
ctx.dota2tracker.hero = new HeroService(ctx, dotaconstants);
|
|
4310
4348
|
ctx.dota2tracker.item = new ItemService(ctx);
|
|
4311
4349
|
ctx.dota2tracker.cache = new CacheService(ctx);
|
|
4312
4350
|
ctx.dota2tracker.database = new DatabaseService(ctx);
|
|
4313
4351
|
ctx.dota2tracker.valveAPI = new ValveAPI(ctx);
|
|
4314
|
-
ctx.dota2tracker.stratzAPI = new StratzAPI(ctx,
|
|
4352
|
+
ctx.dota2tracker.stratzAPI = new StratzAPI(ctx, currentDir);
|
|
4315
4353
|
if (config.enableOpenDotaFallback) {
|
|
4316
4354
|
ctx.dota2tracker.opendotaAPI = new OpenDotaAPI(ctx);
|
|
4317
|
-
ctx.dota2tracker.opendotaAdapter = new OpenDotaAdapter(ctx);
|
|
4355
|
+
ctx.dota2tracker.opendotaAdapter = new OpenDotaAdapter(ctx, dotaconstants);
|
|
4318
4356
|
}
|
|
4319
4357
|
ctx.dota2tracker = ctx.dota2tracker;
|
|
4320
4358
|
usage = await ctx.dota2tracker.i18n.generateUsage();
|
|
@@ -4327,7 +4365,7 @@ async function apply(ctx, config) {
|
|
|
4327
4365
|
registerQueryHeroCommand(ctx);
|
|
4328
4366
|
registerQueryItemCommand(ctx);
|
|
4329
4367
|
registerHeroOfTheDayCommand(ctx);
|
|
4330
|
-
if (config.enableConsole) registerConsolePage(ctx);
|
|
4368
|
+
if (ctx.console && config.enableConsole) registerConsolePage(ctx);
|
|
4331
4369
|
}
|
|
4332
4370
|
__name(apply, "apply");
|
|
4333
4371
|
// Annotate the CommonJS export names for ESM import in node:
|