ai generated solutions to our ai generated problems
This commit is contained in:
+73
-2
@@ -242,6 +242,14 @@ struct GameParticipant {
|
||||
result: String,
|
||||
player_count: i64,
|
||||
stats: GameStats,
|
||||
players: Vec<GamePlayer>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct GamePlayer {
|
||||
uid: String,
|
||||
nick: Option<String>,
|
||||
stats: GameStats,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -1423,7 +1431,7 @@ fn game_participants_for(
|
||||
)
|
||||
.map_err(db_error)?;
|
||||
|
||||
let rows = stmt
|
||||
let mut participants = stmt
|
||||
.query_map(params![session_id], |row| {
|
||||
Ok(GameParticipant {
|
||||
team_name: row.get(0)?,
|
||||
@@ -1440,13 +1448,76 @@ fn game_participants_for(
|
||||
shell_interceptions: row.get(10)?,
|
||||
team_kills_stat: row.get(11)?,
|
||||
},
|
||||
players: Vec::new(),
|
||||
})
|
||||
})
|
||||
.map_err(db_error)?
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(db_error)?;
|
||||
|
||||
Ok(rows)
|
||||
for participant in &mut participants {
|
||||
participant.players = game_players_for(conn, session_id, &participant.team_name)?;
|
||||
}
|
||||
|
||||
Ok(participants)
|
||||
}
|
||||
|
||||
fn game_players_for(
|
||||
conn: &Connection,
|
||||
session_id: &str,
|
||||
team_name: &str,
|
||||
) -> Result<Vec<GamePlayer>, ApiError> {
|
||||
let mut stmt = conn
|
||||
.prepare(
|
||||
"SELECT
|
||||
p.UID,
|
||||
(SELECT pg.nick
|
||||
FROM player_games_hist pg
|
||||
WHERE pg.session_id = p.session_id
|
||||
AND pg.UID = p.UID
|
||||
AND pg.nick IS NOT NULL
|
||||
AND pg.nick != ''
|
||||
ORDER BY pg.endtime_unix DESC
|
||||
LIMIT 1),
|
||||
COALESCE(SUM(p.ground_kills), 0),
|
||||
COALESCE(SUM(p.air_kills), 0),
|
||||
COALESCE(SUM(p.assists), 0),
|
||||
COALESCE(SUM(p.captures), 0),
|
||||
COALESCE(SUM(p.deaths), 0),
|
||||
COALESCE(SUM(p.score), 0),
|
||||
COALESCE(SUM(p.missile_evades), 0),
|
||||
COALESCE(SUM(p.shell_interceptions), 0),
|
||||
COALESCE(SUM(p.team_kills_stat), 0)
|
||||
FROM player_games_hist p
|
||||
WHERE p.session_id = ?1 AND p.team_name = ?2 COLLATE NOCASE
|
||||
GROUP BY p.UID
|
||||
ORDER BY COALESCE(SUM(p.score), 0) DESC, p.UID",
|
||||
)
|
||||
.map_err(db_error)?;
|
||||
|
||||
let players = stmt
|
||||
.query_map(params![session_id, team_name], |row| {
|
||||
Ok(GamePlayer {
|
||||
uid: row.get(0)?,
|
||||
nick: row.get(1)?,
|
||||
stats: GameStats {
|
||||
ground_kills: row.get(2)?,
|
||||
air_kills: row.get(3)?,
|
||||
assists: row.get(4)?,
|
||||
captures: row.get(5)?,
|
||||
deaths: row.get(6)?,
|
||||
score: row.get(7)?,
|
||||
missile_evades: row.get(8)?,
|
||||
shell_interceptions: row.get(9)?,
|
||||
team_kills_stat: row.get(10)?,
|
||||
},
|
||||
})
|
||||
})
|
||||
.map_err(db_error)?
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(db_error)?;
|
||||
|
||||
Ok(players)
|
||||
}
|
||||
|
||||
fn validate_team_name(name: &str) -> Result<&str, ApiError> {
|
||||
|
||||
+34
-16
@@ -2786,10 +2786,9 @@ function GamePage({ gameId, navigate }) {
|
||||
) : null}
|
||||
|
||||
{game ? (
|
||||
<div className="mt-6 grid gap-5 sm:grid-cols-2 xl:grid-cols-4">
|
||||
<div className="mt-6 grid gap-5 sm:grid-cols-3">
|
||||
<Stat label="Players" value={formatNumber(game.player_count)} />
|
||||
<Stat label="Assists" value={formatNumber(game.stats?.assists)} />
|
||||
<Stat label="Score" value={formatNumber(game.stats?.score)} />
|
||||
<Stat label="Deaths" value={formatNumber(game.stats?.deaths)} />
|
||||
</div>
|
||||
) : null}
|
||||
@@ -2807,20 +2806,39 @@ function GamePage({ gameId, navigate }) {
|
||||
{participants.map((participant) => {
|
||||
const won = String(participant.result || '').toLowerCase() === 'win'
|
||||
return (
|
||||
<button
|
||||
className="grid w-full gap-4 border-b border-surface px-5 py-4 text-left transition hover:bg-surface md:grid-cols-[1fr_repeat(4,auto)] md:items-center"
|
||||
key={participant.team_name}
|
||||
onClick={() => navigate(teamPath(participant.team_name))}
|
||||
type="button"
|
||||
>
|
||||
<p className={`truncate font-semibold ${won ? 'text-fury-violet' : 'text-text-soft'}`}>
|
||||
{participant.team_name}
|
||||
</p>
|
||||
<p className="text-sm">{formatNumber(participant.player_count)} players</p>
|
||||
<p className="text-sm">{formatNumber(participant.stats?.assists)} assists</p>
|
||||
<p className="text-sm">{formatNumber(participant.stats?.score)} score</p>
|
||||
<p className="text-sm">{formatNumber(participant.stats?.deaths)} deaths</p>
|
||||
</button>
|
||||
<div className="border-b border-surface" key={participant.team_name}>
|
||||
<button
|
||||
className="grid w-full gap-4 px-5 py-4 text-left transition hover:bg-surface md:grid-cols-[1fr_repeat(3,auto)] md:items-center"
|
||||
onClick={() => navigate(teamPath(participant.team_name))}
|
||||
type="button"
|
||||
>
|
||||
<p className={`truncate font-semibold ${won ? 'text-fury-violet' : 'text-text-soft'}`}>
|
||||
{participant.team_name}
|
||||
</p>
|
||||
<p className="text-sm">{formatNumber(participant.player_count)} players</p>
|
||||
<p className="text-sm">{formatNumber(participant.stats?.assists)} assists</p>
|
||||
<p className="text-sm">{formatNumber(participant.stats?.deaths)} deaths</p>
|
||||
</button>
|
||||
|
||||
<div className="pb-3">
|
||||
{(participant.players || []).map((player) => (
|
||||
<button
|
||||
className="grid w-full gap-3 px-5 py-2 pl-10 text-left text-sm transition hover:bg-surface md:grid-cols-[1fr_repeat(3,auto)] md:items-center sm:pl-14"
|
||||
key={player.uid}
|
||||
onClick={() => navigate(`/players/${encodeURIComponent(player.uid)}`)}
|
||||
type="button"
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<p className="truncate font-semibold text-text">{player.nick || player.uid}</p>
|
||||
<p className="text-xs text-text-soft">{player.uid}</p>
|
||||
</div>
|
||||
<p>{formatNumber(player.stats?.assists)} assists</p>
|
||||
<p>{formatNumber(player.stats?.score)} score</p>
|
||||
<p>{formatNumber(player.stats?.deaths)} deaths</p>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user