From 118a25aa9aa0710ec2a152d3544f48827d7708bc Mon Sep 17 00:00:00 2001
From: Lol3rrr
Date: Tue, 17 Sep 2024 22:31:36 +0200
Subject: [PATCH] Add scoreboard with data to demo view
---
backend/src/api/demos.rs | 42 ++++++++++++++++++++++
common/src/lib.rs | 15 ++++++++
frontend/src/demo.rs | 78 +++++++++++++++++++++++++++++++---------
3 files changed, 119 insertions(+), 16 deletions(-)
diff --git a/backend/src/api/demos.rs b/backend/src/api/demos.rs
index a306432..5610a3c 100644
--- a/backend/src/api/demos.rs
+++ b/backend/src/api/demos.rs
@@ -22,6 +22,7 @@ where
.layer(axum::extract::DefaultBodyLimit::max(500 * 1024 * 1024)),
)
.route("/:id/info", axum::routing::get(info))
+ .route("/:id/analysis/scoreboard", axum::routing::get(scoreboard))
.route("/:id/reanalyse", axum::routing::get(analyise))
.with_state(Arc::new(DemoState {
upload_folder: upload_folder.into(),
@@ -178,3 +179,44 @@ async fn info(
map: result.map,
}))
}
+
+#[tracing::instrument(skip(session))]
+async fn scoreboard(session: UserSession, Path(demo_id): Path) -> Result, axum::http::StatusCode> {
+ let query = crate::schema::demo_players::dsl::demo_players
+ .inner_join(crate::schema::demo_player_stats::dsl::demo_player_stats.on(crate::schema::demo_players::dsl::demo_id.eq(crate::schema::demo_player_stats::dsl::demo_id).and(crate::schema::demo_players::dsl::steam_id.eq(crate::schema::demo_player_stats::dsl::steam_id))))
+ .filter(crate::schema::demo_players::dsl::demo_id.eq(demo_id));
+
+ let mut db_con = crate::db_connection().await;
+
+ let response: Vec<(crate::models::DemoPlayer, crate::models::DemoPlayerStats)> = match query.load(&mut db_con).await {
+ Ok(d) => d,
+ Err(e) => {
+ tracing::error!("Querying DB: {:?}", e);
+ return Err(axum::http::StatusCode::INTERNAL_SERVER_ERROR);
+ }
+ };
+
+ if response.is_empty() {
+ tracing::error!("DB Response was empty");
+ return Err(axum::http::StatusCode::INTERNAL_SERVER_ERROR);
+ }
+
+ let team1_number: i16 = response.last().map(|(p, _)| p.team).unwrap();
+
+ let mut team1 = Vec::new();
+ let mut team2 = Vec::new();
+ for (player, stats) in response {
+ let team_vec = if player.team == team1_number { &mut team1 } else { &mut team2 };
+
+ team_vec.push(common::demo_analysis::ScoreBoardPlayer {
+ name: player.name,
+ kills: stats.kills as usize,
+ deaths: stats.deaths as usize,
+ });
+ }
+
+ Ok(axum::Json(common::demo_analysis::ScoreBoard {
+ team1,
+ team2,
+ }))
+}
diff --git a/common/src/lib.rs b/common/src/lib.rs
index e38be11..b926088 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -15,3 +15,18 @@ pub struct DemoInfo {
pub id: i64,
pub map: String,
}
+
+pub mod demo_analysis {
+ #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
+ pub struct ScoreBoard {
+ pub team1: Vec,
+ pub team2: Vec,
+ }
+
+ #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
+ pub struct ScoreBoardPlayer {
+ pub name: String,
+ pub kills: usize,
+ pub deaths: usize,
+ }
+}
diff --git a/frontend/src/demo.rs b/frontend/src/demo.rs
index 9487eeb..2f0fdbe 100644
--- a/frontend/src/demo.rs
+++ b/frontend/src/demo.rs
@@ -70,26 +70,72 @@ pub fn demo() -> impl leptos::IntoView {
#[leptos::component]
pub fn scoreboard() -> impl leptos::IntoView {
+ use leptos::Suspense;
+
+ let scoreboard_resource = create_resource(leptos_router::use_params_map(), |params| async move {
+ let id = params.get("id").unwrap();
+
+ let res = reqwasm::http::Request::get(&format!("/api/demos/{}/analysis/scoreboard", id))
+ .send()
+ .await
+ .unwrap();
+ res.json::().await.unwrap()
+ });
+
+ let team_display_func = |team: &[common::demo_analysis::ScoreBoardPlayer]| {
+ team.iter().map(|player| {
+ view! {
+
+ | { player.name.clone() } |
+ { player.kills } |
+ { player.deaths } |
+
+ }
+ }).collect::>()
+ };
+
view! {
Scoreboard
-
+ Loading Scoreboard data
}
+ >
+
+
Team 1
+
+
+ | Name |
+ Kills |
+ Deaths |
+
+ {
+ move || {
+ scoreboard_resource.get().map(|s| {
+ let team = s.team1;
+ team_display_func(&team)
+ })
+ }
+ }
+
+
-
+
+
Team 2
+
+
+ | Name |
+
+ {
+ move || {
+ scoreboard_resource.get().map(|s| {
+ let team = s.team2;
+ team_display_func(&team)
+ })
+ }
+ }
+
+
+
}
}