Switch to custom demo parser
This commit is contained in:
@@ -17,62 +17,44 @@ pub struct BaseInfo {
|
||||
pub fn analyse_base(input: AnalysisInput) -> BaseInfo {
|
||||
tracing::info!("Performing Base analysis");
|
||||
|
||||
let huf = l_demoparser::second_pass::parser_settings::create_huffman_lookup_table();
|
||||
let settings = l_demoparser::first_pass::parser_settings::ParserInputs {
|
||||
wanted_players: Vec::new(),
|
||||
real_name_to_og_name: ahash::AHashMap::default(),
|
||||
wanted_player_props: vec!["X".to_string(), "team_num".to_string()],
|
||||
wanted_events: vec!["player_death".to_string(), "player_team".to_string(), "team_info".to_string(), "player_spawn".to_string(), "team_score".to_string(), "round_end".to_string(), "game_end".to_string(), "match_end_conditions".to_string(), "switch_team".to_string(), "player_given_c4".to_string()],
|
||||
wanted_other_props: vec![],
|
||||
parse_ents: true,
|
||||
wanted_ticks: Vec::new(),
|
||||
parse_projectiles: false,
|
||||
only_header: false,
|
||||
count_props: false,
|
||||
only_convars: false,
|
||||
huffman_lookup_table: &huf,
|
||||
order_by_steamid: false,
|
||||
};
|
||||
|
||||
let mut ds = l_demoparser::parse_demo::Parser::new(settings, l_demoparser::parse_demo::ParsingMode::ForceSingleThreaded);
|
||||
let file = std::fs::File::open(&input.path).unwrap();
|
||||
let mmap = unsafe { memmap2::MmapOptions::new().map(&file).unwrap() };
|
||||
let output = ds.parse_demo(&mmap).unwrap();
|
||||
|
||||
|
||||
let header = output.header.as_ref().unwrap();
|
||||
let tmp = csdemo::Container::parse(&mmap).unwrap();
|
||||
let output = csdemo::parser::parse(csdemo::FrameIterator::parse(tmp.inner)).unwrap();
|
||||
|
||||
let header = &output.header;
|
||||
|
||||
tracing::info!("Header: {:?}", header);
|
||||
|
||||
for event in output.game_events.iter() {
|
||||
match event.name.as_str() {
|
||||
"player_team" => {
|
||||
let team = event.fields.iter().find_map(|f| match (f.name.as_str(), &f.data) {
|
||||
("team", Some(d)) => Some(d),
|
||||
("team", None) => {
|
||||
tracing::warn!("'team' field without data");
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
let user_name = event.fields.iter().find_map(|f| match (f.name.as_str(), &f.data) {
|
||||
("user_name", Some(d)) => Some(d),
|
||||
("user_name", None) => {
|
||||
tracing::warn!("'user_name' field without data");
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
let steamid = event.fields.iter().find_map(|f| match (f.name.as_str(), &f.data) {
|
||||
("user_steamid", Some(d)) => Some(d),
|
||||
("user_steamid", None) => {
|
||||
tracing::warn!("'user_steamid' field without data");
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
dbg!(&output.player_info);
|
||||
|
||||
tracing::info!("'{:?}' ({:?}) -> {:?}", user_name, steamid, team);
|
||||
for event in output.events.iter() {
|
||||
match event {
|
||||
csdemo::DemoEvent::Tick(tick) => {}
|
||||
csdemo::DemoEvent::ServerInfo(info) => {}
|
||||
csdemo::DemoEvent::RankUpdate(update) => {}
|
||||
csdemo::DemoEvent::RankReveal(reveal) => {}
|
||||
csdemo::DemoEvent::GameEvent(gevent) => {
|
||||
match gevent {
|
||||
csdemo::game_event::GameEvent::PlayerTeam(pteam) => {
|
||||
tracing::info!("{:?}", pteam);
|
||||
}
|
||||
csdemo::game_event::GameEvent::RoundOfficiallyEnded(r_end) => {
|
||||
tracing::info!("{:?}", r_end);
|
||||
}
|
||||
csdemo::game_event::GameEvent::PlayerDeath(pdeath) => {
|
||||
tracing::info!("{:?}", pdeath);
|
||||
}
|
||||
other => {}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
match event.name.as_str() {
|
||||
"team_info" => {
|
||||
tracing::info!("Team Info: {:?}", event);
|
||||
}
|
||||
@@ -82,34 +64,6 @@ pub fn analyse_base(input: AnalysisInput) -> BaseInfo {
|
||||
"team_score" => {
|
||||
tracing::info!("Team Score: {:?}", event);
|
||||
}
|
||||
"round_end" => {
|
||||
let winner = event.fields.iter().find_map(|f| match (f.name.as_str(), &f.data) {
|
||||
("winner", Some(d)) => Some(d),
|
||||
("winner", None) => {
|
||||
tracing::warn!("'winner' field without data");
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
let round = event.fields.iter().find_map(|f| match (f.name.as_str(), &f.data) {
|
||||
("round", Some(d)) => Some(d),
|
||||
("round", None) => {
|
||||
tracing::warn!("'round' field without data");
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
let reason = event.fields.iter().find_map(|f| match (f.name.as_str(), &f.data) {
|
||||
("reason", Some(d)) => Some(d),
|
||||
("reason", None) => {
|
||||
tracing::warn!("'reason' field without data");
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
|
||||
tracing::info!(?winner, ?round, ?reason, "Round End");
|
||||
}
|
||||
"game_end" => {
|
||||
tracing::info!("Game End: {:?}", event);
|
||||
}
|
||||
@@ -124,10 +78,13 @@ pub fn analyse_base(input: AnalysisInput) -> BaseInfo {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
*/
|
||||
}
|
||||
|
||||
let map = header.map_name().to_owned();
|
||||
|
||||
BaseInfo {
|
||||
map: header.get("map_name").cloned().unwrap_or_default(),
|
||||
map,
|
||||
players: Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use crate::UserSession;
|
||||
.route("/list", axum::routing::get(list))
|
||||
.route("/upload", axum::routing::post(upload).layer(axum::extract::DefaultBodyLimit::max(500*1024*1024)))
|
||||
.route("/:id/info", axum::routing::get(info))
|
||||
.route("/:id/reanalyse", axum::routing::get(analyise))
|
||||
.with_state(Arc::new(DemoState {
|
||||
upload_folder: upload_folder.into(),
|
||||
base_analysis,
|
||||
@@ -75,6 +76,31 @@ use crate::UserSession;
|
||||
Ok(axum::response::Redirect::to("/"))
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(state, session))]
|
||||
async fn analyise(State(state): State<Arc<DemoState>>, session: crate::UserSession, Path(demo_id): Path<i64>) -> Result<(), (axum::http::StatusCode, &'static str)> {
|
||||
let steam_id = session.data().steam_id.ok_or_else(|| (axum::http::StatusCode::UNAUTHORIZED, "Not logged in"))?;
|
||||
|
||||
tracing::info!("Upload for Session: {:?}", steam_id);
|
||||
|
||||
let mut db_con = crate::db_connection().await;
|
||||
|
||||
let query = crate::schema::demos::dsl::demos.filter(crate::schema::demos::dsl::steam_id.eq(steam_id.to_string())).filter(crate::schema::demos::dsl::demo_id.eq(demo_id));
|
||||
let result: Vec<_> = query.load::<crate::models::Demo>(&mut db_con).await.unwrap();
|
||||
|
||||
if result.len() != 1 {
|
||||
return Err((axum::http::StatusCode::BAD_REQUEST, "Expected exactly 1 demo to match"));
|
||||
}
|
||||
|
||||
let user_folder = std::path::Path::new(&state.upload_folder).join(format!("{}/", steam_id));
|
||||
state.base_analysis.send(crate::analysis::AnalysisInput {
|
||||
path: user_folder.join(format!("{}.dem", demo_id)),
|
||||
demoid: demo_id,
|
||||
steamid: steam_id.to_string(),
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(session))]
|
||||
async fn info(session: UserSession, Path(demo_id): Path<i64>) -> Result<axum::response::Json<common::DemoInfo>, axum::http::StatusCode> {
|
||||
tracing::info!("Get info for Demo: {:?}", demo_id);
|
||||
|
||||
@@ -28,6 +28,8 @@ async fn main() {
|
||||
|
||||
let (base_analysis_tx, mut base_analysis_rx) = tokio::sync::mpsc::unbounded_channel::<backend::analysis::AnalysisInput>();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
use diesel_async::AsyncConnection;
|
||||
|
||||
while let Some(input) = base_analysis_rx.blocking_recv() {
|
||||
let demo_id = input.demoid;
|
||||
let result = backend::analysis::analyse_base(input);
|
||||
@@ -47,8 +49,11 @@ async fn main() {
|
||||
tracing::trace!(?store_info_query, "Store demo info query");
|
||||
tracing::trace!(?update_process_info, "Update processing info query");
|
||||
|
||||
store_info_query.execute(&mut db_con).await.unwrap();
|
||||
update_process_info.execute(&mut db_con).await.unwrap();
|
||||
db_con.transaction::<'_, '_, '_, _, diesel::result::Error, _>(|conn| Box::pin(async move {
|
||||
store_info_query.execute(conn).await.map(|e| ())?;
|
||||
update_process_info.execute(conn).await.map(|e| ())?;
|
||||
Ok(())
|
||||
})).await;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user