mirror of
https://github.com/amineo/t2-stat-parser.git
synced 2026-01-19 17:34:43 +00:00
Merge pull request #16 from exogen/feature/leaderboard-time-period
Add time period support to leaderboard queries
This commit is contained in:
commit
7f1f34364e
|
|
@ -40,6 +40,9 @@ export class TopAccuracyQueryDto {
|
||||||
@IsPositive()
|
@IsPositive()
|
||||||
@Max(100)
|
@Max(100)
|
||||||
limit: number;
|
limit: number;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
timePeriod: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TopWinsQueryDto {
|
export class TopWinsQueryDto {
|
||||||
|
|
@ -51,4 +54,7 @@ export class TopWinsQueryDto {
|
||||||
@IsPositive()
|
@IsPositive()
|
||||||
@Max(100)
|
@Max(100)
|
||||||
limit: number;
|
limit: number;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
timePeriod: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ export class PlayersController {
|
||||||
minGames = 10,
|
minGames = 10,
|
||||||
minShots = 100,
|
minShots = 100,
|
||||||
limit = 10,
|
limit = 10,
|
||||||
|
timePeriod,
|
||||||
} = topPlayersQuery;
|
} = topPlayersQuery;
|
||||||
return this.playerService.findTopAccuracy({
|
return this.playerService.findTopAccuracy({
|
||||||
stat,
|
stat,
|
||||||
|
|
@ -39,6 +40,7 @@ export class PlayersController {
|
||||||
minGames,
|
minGames,
|
||||||
minShots,
|
minShots,
|
||||||
limit,
|
limit,
|
||||||
|
timePeriod,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,10 +50,11 @@ export class PlayersController {
|
||||||
summary: 'Return a leaderboard of players for win percentage',
|
summary: 'Return a leaderboard of players for win percentage',
|
||||||
})
|
})
|
||||||
findTopWins(@Query() topPlayersQuery: TopWinsQueryDto) {
|
findTopWins(@Query() topPlayersQuery: TopWinsQueryDto) {
|
||||||
const { minGames = 100, limit = 10 } = topPlayersQuery;
|
const { minGames = 100, limit = 10, timePeriod } = topPlayersQuery;
|
||||||
return this.playerService.findTopWins({
|
return this.playerService.findTopWins({
|
||||||
minGames,
|
minGames,
|
||||||
limit,
|
limit,
|
||||||
|
timePeriod,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ export class PlayersService {
|
||||||
minGames,
|
minGames,
|
||||||
minShots,
|
minShots,
|
||||||
limit,
|
limit,
|
||||||
|
timePeriod = null,
|
||||||
} = topAccuracyQuery;
|
} = topAccuracyQuery;
|
||||||
|
|
||||||
const shotsStat = {
|
const shotsStat = {
|
||||||
|
|
@ -102,6 +103,8 @@ export class PlayersService {
|
||||||
// Cast to float to avoid integer division truncating the result.
|
// Cast to float to avoid integer division truncating the result.
|
||||||
const aggregatedAccuracy = `(${aggregatedHits}::float / ${aggregatedShots}::float)`;
|
const aggregatedAccuracy = `(${aggregatedHits}::float / ${aggregatedShots}::float)`;
|
||||||
|
|
||||||
|
const sinceDate = '(now() - (:timePeriod)::interval)';
|
||||||
|
|
||||||
// TODO: This whole query could probably be turned into a `ViewEntity` at
|
// TODO: This whole query could probably be turned into a `ViewEntity` at
|
||||||
// some point, but I couldn't get that to work.
|
// some point, but I couldn't get that to work.
|
||||||
|
|
||||||
|
|
@ -112,6 +115,7 @@ export class PlayersService {
|
||||||
shotsStat,
|
shotsStat,
|
||||||
minGames,
|
minGames,
|
||||||
minShots,
|
minShots,
|
||||||
|
timePeriod,
|
||||||
})
|
})
|
||||||
.select([
|
.select([
|
||||||
'player.player_guid',
|
'player.player_guid',
|
||||||
|
|
@ -121,6 +125,10 @@ export class PlayersService {
|
||||||
'stats.shots',
|
'stats.shots',
|
||||||
'stats.accuracy',
|
'stats.accuracy',
|
||||||
])
|
])
|
||||||
|
.addSelect(
|
||||||
|
timePeriod ? sinceDate : 'NULL',
|
||||||
|
'since_date'
|
||||||
|
)
|
||||||
.innerJoin(
|
.innerJoin(
|
||||||
(subQuery) => {
|
(subQuery) => {
|
||||||
let statsQuery = subQuery
|
let statsQuery = subQuery
|
||||||
|
|
@ -131,6 +139,7 @@ export class PlayersService {
|
||||||
.addSelect(aggregatedShots, 'shots')
|
.addSelect(aggregatedShots, 'shots')
|
||||||
.addSelect(aggregatedAccuracy, 'accuracy')
|
.addSelect(aggregatedAccuracy, 'accuracy')
|
||||||
.where(`${shotsValue} > 0`)
|
.where(`${shotsValue} > 0`)
|
||||||
|
.andWhere(timePeriod ? `game.datestamp >= ${sinceDate}` : 'TRUE')
|
||||||
.groupBy('game.player_guid');
|
.groupBy('game.player_guid');
|
||||||
|
|
||||||
if (excludeDiscJumps) {
|
if (excludeDiscJumps) {
|
||||||
|
|
@ -190,16 +199,20 @@ export class PlayersService {
|
||||||
minGames,
|
minGames,
|
||||||
minShots,
|
minShots,
|
||||||
limit,
|
limit,
|
||||||
|
timePeriod,
|
||||||
|
sinceDate: rows.length ? rows[0].since_date : null,
|
||||||
players,
|
players,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async findTopWins(topWinsQuery: TopWinsQueryDto) {
|
async findTopWins(topWinsQuery: TopWinsQueryDto) {
|
||||||
const { minGames, limit } = topWinsQuery;
|
const { minGames, limit, timePeriod = null } = topWinsQuery;
|
||||||
|
|
||||||
|
const sinceDate = '(now() - (:timePeriod)::interval)';
|
||||||
|
|
||||||
const query = this.playersRepository
|
const query = this.playersRepository
|
||||||
.createQueryBuilder('player')
|
.createQueryBuilder('player')
|
||||||
.setParameters({ minGames })
|
.setParameters({ minGames, timePeriod })
|
||||||
.select(['stats.player_name', 'stats.player_guid'])
|
.select(['stats.player_name', 'stats.player_guid'])
|
||||||
.addSelect('COUNT(stats.game_id)::integer', 'game_count')
|
.addSelect('COUNT(stats.game_id)::integer', 'game_count')
|
||||||
.addSelect(
|
.addSelect(
|
||||||
|
|
@ -218,6 +231,10 @@ export class PlayersService {
|
||||||
"(COUNT(stats.player_match_result = 'win' OR NULL)::float + COUNT(stats.player_match_result = 'draw' OR NULL)::float / 2.0) / COUNT(stats.game_id)::float",
|
"(COUNT(stats.player_match_result = 'win' OR NULL)::float + COUNT(stats.player_match_result = 'draw' OR NULL)::float / 2.0) / COUNT(stats.game_id)::float",
|
||||||
'win_percent',
|
'win_percent',
|
||||||
)
|
)
|
||||||
|
.addSelect(
|
||||||
|
timePeriod ? sinceDate : 'NULL',
|
||||||
|
'since_date'
|
||||||
|
)
|
||||||
.innerJoin(
|
.innerJoin(
|
||||||
(qb) => {
|
(qb) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -309,6 +326,8 @@ export class PlayersService {
|
||||||
// Each team must have at least 2 players.
|
// Each team must have at least 2 players.
|
||||||
.andWhere('join_g.team_size_storm >= 2')
|
.andWhere('join_g.team_size_storm >= 2')
|
||||||
.andWhere('join_g.team_size_inferno >= 2')
|
.andWhere('join_g.team_size_inferno >= 2')
|
||||||
|
// Must fall within the specified time period.
|
||||||
|
.andWhere(timePeriod ? `game.datestamp >= ${sinceDate}` : 'TRUE')
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'stats',
|
'stats',
|
||||||
|
|
@ -351,6 +370,8 @@ export class PlayersService {
|
||||||
minGames,
|
minGames,
|
||||||
gameType: ['CTFGame', 'SCtFGame'],
|
gameType: ['CTFGame', 'SCtFGame'],
|
||||||
limit,
|
limit,
|
||||||
|
timePeriod,
|
||||||
|
sinceDate: rows.length ? rows[0].since_date : null,
|
||||||
players,
|
players,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue