@ekmanss/5eplay 20260716.0.0 → 20260716.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/README.md +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/markdown.js +13 -14
- package/dist/transform.js +48 -1
- package/dist/types.d.ts +21 -4
- package/docs/data-contracts.md +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,7 +99,7 @@ The human-readable report is deliberately more compact than the typed snapshot:
|
|
|
99
99
|
- the overview keeps only match status/identity/version/format, capture time, and source URL;
|
|
100
100
|
- completed and live maps show scores, clear half/round results, player tables, duels, highlights,
|
|
101
101
|
milestones, and readable logs; upcoming maps use one short placeholder;
|
|
102
|
-
- head-to-head and recent matches show only time, teams/opponent, score, and result;
|
|
102
|
+
- head-to-head and recent matches show only time, canonical match link, teams/opponent, score, and result;
|
|
103
103
|
- player power is reduced to Rating plus firepower, entry, opening, utility, sniping, clutch, and
|
|
104
104
|
trading scores;
|
|
105
105
|
- transport versions, coordinates, raw round codes, provider JSON, odds, logos, and community
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ export { createFiveEPlayMatchSession } from './session.js';
|
|
|
7
7
|
export { fiveEPlayMarkdownOutputPath, writeFiveEPlayMatchMarkdown, } from './write_markdown.js';
|
|
8
8
|
export type { FiveEPlayMarkdownOptions } from './markdown.js';
|
|
9
9
|
export type { WriteFiveEPlayMatchMarkdownOptions, WriteFiveEPlayMatchMarkdownResult, } from './write_markdown.js';
|
|
10
|
-
export type { CreateFiveEPlayMatchSessionOptions, FiveEPlayAnalysisMap, FiveEPlayAnalysisPlayer, FiveEPlayBombEvent, FiveEPlayClientOptions, FiveEPlayCommunityCard, FiveEPlayCommunityRatings, FiveEPlayCommunityScore, FiveEPlayDiagnosticWarning, FiveEPlayErrorCode, FiveEPlayHalfScore, FiveEPlayJson, FiveEPlayJsonObject, FiveEPlayLiveMatch, FiveEPlayLiveMatchMap, FiveEPlayLiveMatchesData, FiveEPlayLiveMatchesDiagnostics, FiveEPlayLiveMatchTeam, FiveEPlayKillEvent, FiveEPlayLogEvent, FiveEPlayLogPlayer, FiveEPlayMap, FiveEPlayMapStatus, FiveEPlayMatch, FiveEPlayMatchDiagnostics, FiveEPlayMatchIdentity, FiveEPlayMatchSession, FiveEPlayMatchStatus, FiveEPlayOperation, FiveEPlayPlayerDuel, FiveEPlayPlayerEquipment, FiveEPlayPlayerMetrics, FiveEPlayPlayerStats, FiveEPlayPrematchAnalysis, FiveEPlayProgressEvent, FiveEPlayRealtimeUpdate, FiveEPlayRequestDiagnostic, FiveEPlayRequestOptions, FiveEPlayRoundEnd, FiveEPlayRoundStart, FiveEPlaySide, FiveEPlayStage, FiveEPlayTeam, FiveEPlayTeamMapState, FiveEPlayTeamPlayerStats, FiveEPlayTournament, FiveEPlayVetoEntry, FiveEPlayWebSocketFactory, FiveEPlayWebSocketLike, GetFiveEPlayMatchOptions, GetFiveEPlayMatchResult, GetFiveEPlayLiveMatchesOptions, GetFiveEPlayLiveMatchesResult, } from './types.js';
|
|
10
|
+
export type { CreateFiveEPlayMatchSessionOptions, FiveEPlayAnalysisMap, FiveEPlayAnalysisPlayer, FiveEPlayBombEvent, FiveEPlayClientOptions, FiveEPlayCommunityCard, FiveEPlayCommunityRatings, FiveEPlayCommunityScore, FiveEPlayDiagnosticWarning, FiveEPlayErrorCode, FiveEPlayHalfScore, FiveEPlayJson, FiveEPlayJsonObject, FiveEPlayLiveMatch, FiveEPlayLiveMatchMap, FiveEPlayLiveMatchesData, FiveEPlayLiveMatchesDiagnostics, FiveEPlayLiveMatchTeam, FiveEPlayKillEvent, FiveEPlayLogEvent, FiveEPlayLogPlayer, FiveEPlayMap, FiveEPlayMapStatus, FiveEPlayMatch, FiveEPlayMatchDiagnostics, FiveEPlayMatchIdentity, FiveEPlayMatchSession, FiveEPlayMatchStatus, FiveEPlayOperation, FiveEPlayPlayerDuel, FiveEPlayPlayerEquipment, FiveEPlayPlayerMetrics, FiveEPlayPlayerStats, FiveEPlayPrematchAnalysis, FiveEPlayProgressEvent, FiveEPlayRealtimeUpdate, FiveEPlayRecentMatchReference, FiveEPlayRecentMatchTeam, FiveEPlayRequestDiagnostic, FiveEPlayRequestOptions, FiveEPlayRoundEnd, FiveEPlayRoundStart, FiveEPlaySide, FiveEPlayStage, FiveEPlayTeam, FiveEPlayTeamMapState, FiveEPlayTeamPlayerStats, FiveEPlayTeamRecentMatches, FiveEPlayTournament, FiveEPlayVetoEntry, FiveEPlayWebSocketFactory, FiveEPlayWebSocketLike, GetFiveEPlayMatchOptions, GetFiveEPlayMatchResult, GetFiveEPlayLiveMatchesOptions, GetFiveEPlayLiveMatchesResult, } from './types.js';
|
package/dist/markdown.js
CHANGED
|
@@ -342,25 +342,24 @@ function recentMatchesSection(match) {
|
|
|
342
342
|
return [];
|
|
343
343
|
const lines = ['### 近期比赛', ''];
|
|
344
344
|
for (const item of analysis.recentMatches) {
|
|
345
|
-
const rows = item.matches.
|
|
346
|
-
const
|
|
347
|
-
const opponent =
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
const opponentScore = integer(game[teamIsHome ? 'opponent_score' : 'home_score']);
|
|
351
|
-
const opponentName = text((teamIsHome ? opponent : home).disp_name);
|
|
352
|
-
const outcome = teamScore === null || opponentScore === null ? '—'
|
|
353
|
-
: teamScore > opponentScore ? '胜' : teamScore < opponentScore ? '负' : '平';
|
|
345
|
+
const rows = item.matches.map((game) => {
|
|
346
|
+
const team = game.teams.find((candidate) => candidate.id === item.teamId);
|
|
347
|
+
const opponent = game.teams.find((candidate) => candidate.id !== item.teamId);
|
|
348
|
+
const outcome = game.winnerTeamId === null ? '平'
|
|
349
|
+
: game.winnerTeamId === item.teamId ? '胜' : '负';
|
|
354
350
|
return [
|
|
355
|
-
compactTimestamp(
|
|
356
|
-
|
|
357
|
-
|
|
351
|
+
compactTimestamp(game.playedAtUnixSeconds),
|
|
352
|
+
`[${game.id}](${game.url})`,
|
|
353
|
+
opponent?.name,
|
|
354
|
+
`${number(team?.score ?? null)} : ${number(opponent?.score ?? null)}`,
|
|
358
355
|
outcome,
|
|
359
356
|
];
|
|
360
357
|
});
|
|
361
358
|
lines.push(`#### ${plain(teamName(match, item.teamId))}`, '', rows.length
|
|
362
|
-
? table(['比赛时间', '对手', '比分(本队 : 对手)', '结果'], rows)
|
|
363
|
-
: '_暂无近期比赛数据_',
|
|
359
|
+
? table(['比赛时间', '比赛', '对手', '比分(本队 : 对手)', '结果'], rows)
|
|
360
|
+
: '_暂无近期比赛数据_', item.invalidReferenceCount > 0
|
|
361
|
+
? `> 注意:源数据中另有 ${item.invalidReferenceCount} 条近期比赛引用不完整,未纳入报告。`
|
|
362
|
+
: '', '');
|
|
364
363
|
}
|
|
365
364
|
return lines;
|
|
366
365
|
}
|
package/dist/transform.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mergeLogEvents, transformLogRecord } from './log.js';
|
|
2
|
+
import { matchIdentityFromInput } from './input.js';
|
|
2
3
|
import { flag, integer, jsonObjects, numeric, record, records, side, strings, text, } from './value.js';
|
|
3
4
|
function cleanName(value) {
|
|
4
5
|
return text(value) ?? '';
|
|
@@ -298,6 +299,52 @@ function analysisMap(value, teams) {
|
|
|
298
299
|
}),
|
|
299
300
|
};
|
|
300
301
|
}
|
|
302
|
+
function recentMatchRows(value) {
|
|
303
|
+
return records(record(value).matches).flatMap((group) => {
|
|
304
|
+
const nested = records(group.matches);
|
|
305
|
+
return nested.length ? nested : text(group.id) ? [group] : [];
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
function completedRecentMatch(value) {
|
|
309
|
+
const source = record(value);
|
|
310
|
+
const identity = matchIdentityFromInput(text(source.id) ?? '');
|
|
311
|
+
const status = text(source.status)?.toLowerCase();
|
|
312
|
+
const playedAtUnixSeconds = integer(source.ts);
|
|
313
|
+
const first = record(source.home_info);
|
|
314
|
+
const second = record(source.opponent_info);
|
|
315
|
+
const firstId = text(first.id);
|
|
316
|
+
const secondId = text(second.id);
|
|
317
|
+
const firstName = text(first.disp_name);
|
|
318
|
+
const secondName = text(second.disp_name);
|
|
319
|
+
const firstScore = integer(source.home_score);
|
|
320
|
+
const secondScore = integer(source.opponent_score);
|
|
321
|
+
const completed = status === 'past' || status === 'completed' || status === '2';
|
|
322
|
+
if (!identity || !completed || playedAtUnixSeconds === null || playedAtUnixSeconds <= 0
|
|
323
|
+
|| !firstId || !secondId || !firstName || !secondName
|
|
324
|
+
|| firstScore === null || secondScore === null || firstScore < 0 || secondScore < 0) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
...identity,
|
|
329
|
+
status: 'completed',
|
|
330
|
+
playedAtUnixSeconds,
|
|
331
|
+
teams: [
|
|
332
|
+
{ id: firstId, name: firstName, score: firstScore },
|
|
333
|
+
{ id: secondId, name: secondName, score: secondScore },
|
|
334
|
+
],
|
|
335
|
+
winnerTeamId: firstScore === secondScore ? null : firstScore > secondScore ? firstId : secondId,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function recentMatches(value) {
|
|
339
|
+
const rows = recentMatchRows(value);
|
|
340
|
+
const normalized = rows.map(completedRecentMatch);
|
|
341
|
+
const byId = new Map(normalized.flatMap((match) => match ? [[match.id, match]] : []));
|
|
342
|
+
return {
|
|
343
|
+
sourceCount: rows.length,
|
|
344
|
+
invalidReferenceCount: normalized.filter((match) => match === null).length,
|
|
345
|
+
matches: [...byId.values()].sort((left, right) => right.playedAtUnixSeconds - left.playedAtUnixSeconds),
|
|
346
|
+
};
|
|
347
|
+
}
|
|
301
348
|
function prematchAnalysis(value, teams) {
|
|
302
349
|
if (value === null)
|
|
303
350
|
return null;
|
|
@@ -330,7 +377,7 @@ function prematchAnalysis(value, teams) {
|
|
|
330
377
|
})),
|
|
331
378
|
recentMatches: teams.map((team, index) => ({
|
|
332
379
|
teamId: team.id,
|
|
333
|
-
|
|
380
|
+
...recentMatches(result[index === 0 ? 't1_rec_matches' : 't2_rec_matches']),
|
|
334
381
|
})),
|
|
335
382
|
headToHead: {
|
|
336
383
|
teamWinRates: teams.map((team, index) => ({
|
package/dist/types.d.ts
CHANGED
|
@@ -293,6 +293,26 @@ export interface FiveEPlayAnalysisMap {
|
|
|
293
293
|
banRate: number | null;
|
|
294
294
|
}>;
|
|
295
295
|
}
|
|
296
|
+
export interface FiveEPlayRecentMatchTeam {
|
|
297
|
+
id: string;
|
|
298
|
+
name: string;
|
|
299
|
+
score: number;
|
|
300
|
+
}
|
|
301
|
+
export interface FiveEPlayRecentMatchReference {
|
|
302
|
+
id: string;
|
|
303
|
+
numericId: number;
|
|
304
|
+
url: string;
|
|
305
|
+
status: 'completed';
|
|
306
|
+
playedAtUnixSeconds: number;
|
|
307
|
+
teams: [FiveEPlayRecentMatchTeam, FiveEPlayRecentMatchTeam];
|
|
308
|
+
winnerTeamId: string | null;
|
|
309
|
+
}
|
|
310
|
+
export interface FiveEPlayTeamRecentMatches {
|
|
311
|
+
teamId: string;
|
|
312
|
+
sourceCount: number;
|
|
313
|
+
invalidReferenceCount: number;
|
|
314
|
+
matches: FiveEPlayRecentMatchReference[];
|
|
315
|
+
}
|
|
296
316
|
export interface FiveEPlayPrematchAnalysis {
|
|
297
317
|
hidden: boolean;
|
|
298
318
|
teams: Array<{
|
|
@@ -309,10 +329,7 @@ export interface FiveEPlayPrematchAnalysis {
|
|
|
309
329
|
teamId: string;
|
|
310
330
|
players: FiveEPlayJsonObject[];
|
|
311
331
|
}>;
|
|
312
|
-
recentMatches:
|
|
313
|
-
teamId: string;
|
|
314
|
-
matches: FiveEPlayJsonObject[];
|
|
315
|
-
}>;
|
|
332
|
+
recentMatches: FiveEPlayTeamRecentMatches[];
|
|
316
333
|
headToHead: {
|
|
317
334
|
teamWinRates: Array<{
|
|
318
335
|
teamId: string;
|
package/docs/data-contracts.md
CHANGED
|
@@ -44,6 +44,12 @@ weapon, special-kill flag, and coordinate fields. Unknown future event types rem
|
|
|
44
44
|
records, recent matches, and head-to-head matches. Provider-specific power records remain JSON
|
|
45
45
|
objects so new metrics are preserved without a schema bump.
|
|
46
46
|
|
|
47
|
+
Each `analysis.recentMatches[]` group exposes typed, completed match references rather than raw
|
|
48
|
+
provider JSON. Every reference contains its canonical `csgo_mc_*` ID/URL, numeric ID, completion
|
|
49
|
+
status and timestamp, both teams and scores, and the winning team ID. `sourceCount` records how
|
|
50
|
+
many source rows were present; `invalidReferenceCount` makes malformed or incomplete source rows
|
|
51
|
+
explicit so consumers can fail closed instead of treating them as genuinely missing history.
|
|
52
|
+
|
|
47
53
|
`communityRatings` contains every public tab and returned card, including player, coach, and
|
|
48
54
|
big-event cards. Account-specific `my_*` voting state, write actions, and chat messages are not
|
|
49
55
|
returned.
|
package/package.json
CHANGED