From e22611994a9f7fe87d509a7be7fb3b4b67b3c96f Mon Sep 17 00:00:00 2001 From: Flux Xu Date: Wed, 21 Sep 2022 19:40:22 -0400 Subject: [PATCH] tidy up --- Cargo.lock | 16 ++ Cargo.toml | 1 + binaries/flo-cli/Cargo.toml | 1 + binaries/flo-cli/src/observer.rs | 281 ++-------------------------- crates/observer/src/lib.rs | 2 +- crates/replay/Cargo.toml | 15 ++ crates/replay/src/error.rs | 15 ++ crates/replay/src/lib.rs | 309 +++++++++++++++++++++++++++++++ crates/w3replay/src/records.rs | 74 ++++---- 9 files changed, 409 insertions(+), 305 deletions(-) create mode 100644 crates/replay/Cargo.toml create mode 100644 crates/replay/src/error.rs create mode 100644 crates/replay/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index c08bd2f6..70d5f4f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1485,6 +1485,7 @@ dependencies = [ "flo-observer-archiver", "flo-observer-edge", "flo-observer-fs", + "flo-replay", "flo-types", "flo-util", "flo-w3gs", @@ -1917,6 +1918,21 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "flo-replay" +version = "0.1.0" +dependencies = [ + "bytes", + "flo-net", + "flo-observer", + "flo-observer-fs", + "flo-types", + "flo-w3gs", + "flo-w3replay", + "thiserror", + "tracing", +] + [[package]] name = "flo-state" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index c77ad41b..bb837dd9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ members = [ "crates/observer-fs", "crates/observer-archiver", "crates/kinesis", + "crates/replay", "crates/controller", "crates/node", diff --git a/binaries/flo-cli/Cargo.toml b/binaries/flo-cli/Cargo.toml index 51604289..2487493e 100644 --- a/binaries/flo-cli/Cargo.toml +++ b/binaries/flo-cli/Cargo.toml @@ -23,6 +23,7 @@ flo-kinesis = { path = "../../crates/kinesis" } flo-w3replay = { path = "../../crates/w3replay" } flo-util = { path = "../../crates/util" } flo-types = { path = "../../crates/types" } +flo-replay = { path = "../../crates/replay" } anyhow = "1" tonic = "0.6" diff --git a/binaries/flo-cli/src/observer.rs b/binaries/flo-cli/src/observer.rs index c8bc7f69..280ef383 100644 --- a/binaries/flo-cli/src/observer.rs +++ b/binaries/flo-cli/src/observer.rs @@ -1,12 +1,5 @@ -use flo_net::w3gs::W3GSPacketTypeId; -use flo_observer::record::GameRecordData; use flo_observer_archiver::{ArchiverOptions, Fetcher}; -use flo_observer_fs::GameDataArchiveReader; -use flo_w3gs::player::{PlayerProfileMessage, PlayerSkinsMessage, PlayerUnknown5Message}; -use flo_w3replay::{ - GameInfo, PlayerChatMessage, PlayerInfo, PlayerLeft, ProtoBufPayload, RacePref, ReplayEncoder, - SlotInfo, TimeSlot, TimeSlotAck, -}; +use flo_replay::{generate_replay, GenerateReplayOptions}; use s2_grpc_utils::S2ProtoUnpack; use structopt::StructOpt; @@ -47,9 +40,6 @@ impl Command { client.serve().await; } Command::GenerateReplay { game_id } => { - use flo_types::game::SlotStatus; - use flo_w3replay::Record; - tracing::info!("fetching game information..."); let ctrl = get_grpc_client().await; @@ -63,41 +53,6 @@ impl Command { let game = flo_types::observer::GameInfo::unpack(game).unwrap(); - let occupied_slots: Vec<(usize, _)> = game - .slots - .iter() - .enumerate() - .filter(|(_, slot)| slot.settings.status == SlotStatus::Occupied) - .collect(); - - let (first_player_info, first_player_name) = occupied_slots - .get(0) - .and_then(|(i, slot)| { - let name = slot.player.as_ref().map(|p| p.name.clone())?; - Some((PlayerInfo::new(index_to_player_id(*i), &name), name)) - }) - .unwrap(); - let first_player_id = first_player_info.id; - - let game_info = GameInfo::new( - first_player_info, - &game.name, - flo_w3gs::game::GameSettings::new( - Default::default(), - flo_w3gs::game::GameSettingsMap { - path: game.map.path.clone(), - width: 0, - height: 0, - sha1: { - let mut value = [0_u8; 20]; - value.copy_from_slice(&game.map.sha1[..]); - value - }, - checksum: 0xFFFFFFFF, - }, - ), - ); - tracing::info!("game name = {}, version = {}", game.name, game.game_version); tracing::info!("fetching game archive..."); @@ -110,232 +65,24 @@ impl Command { }; let fetcher = Fetcher::new(opts).unwrap(); - let bytes = fetcher.fetch(game_id).await.unwrap(); - let rdr = GameDataArchiveReader::open_bytes(&bytes).await.unwrap(); - let archive_records = rdr.records().collect_vec().await.unwrap(); - tracing::info!( - "archive: size: {}, records: {}", - bytes.len(), - archive_records.len() - ); - - fn index_to_player_id(index: usize) -> u8 { - return (index + 1) as u8; - } - - const FLO_OB_SLOT: usize = 23; - - let flo_ob_slot_occupied = occupied_slots - .iter() - .find(|(idx, _)| *idx == FLO_OB_SLOT) - .is_some(); - - let mut player_infos = vec![]; - let mut player_skins = vec![]; - let mut player_profiles = vec![]; - - let mut is_first_player = true; - for (i, slot) in game.slots.iter().enumerate() { - if let Some(ref p) = slot.player { - let player_id = index_to_player_id(i); - if is_first_player { - is_first_player = false; - } else { - player_infos.push(PlayerInfo::new(player_id, p.name.as_str())); - } - player_skins.push(ProtoBufPayload::new(PlayerSkinsMessage { - player_id: player_id as _, - ..Default::default() - })); - player_profiles.push(ProtoBufPayload::new(PlayerProfileMessage { - player_id: player_id as _, - battle_tag: p.name.clone(), - portrait: "p042".to_string(), - ..Default::default() - })); - } - } - - if !flo_ob_slot_occupied { - let ob_player_id = index_to_player_id(FLO_OB_SLOT); - player_infos.push(PlayerInfo::new(ob_player_id, "FLO")); - player_profiles.push(ProtoBufPayload::new(PlayerProfileMessage::new( - ob_player_id, - "FLO", - ))); - } - - let mut records = vec![]; - - // 0 GameInfo - records.push(Record::GameInfo(game_info)); - - // 1 PlayerInfo - for item in player_infos { - records.push(Record::PlayerInfo(flo_w3replay::PlayerInfoRecord { - player_info: item, - unknown: 0, - })); - } - - // 2 ProtoBuf PlayerSkins - for item in player_skins { - records.push(Record::ProtoBuf(item)); - } - - // 3 ProtoBuf PlayerProfile - for item in player_profiles { - records.push(Record::ProtoBuf(item)); - } + let archive = fetcher.fetch(game_id).await.unwrap(); + tracing::info!("archive: size: {}", archive.len()); - // special messages - { - let (my_id, my_name) = if flo_ob_slot_occupied { - (first_player_id, first_player_name.clone()) - } else { - (index_to_player_id(FLO_OB_SLOT), "FLO".to_string()) - }; - - // ProtoBuf PlayerSkinsMessage - - records.push(Record::ProtoBuf(ProtoBufPayload::new(PlayerSkinsMessage { - player_id: my_id as _, - ..Default::default() - }))); - - // ProtoBuf PlayerUnknown5 - records.push(Record::ProtoBuf(ProtoBufPayload::new( - PlayerUnknown5Message { - player_id: my_id as _, - unknown_1: 1, - }, - ))); - - let ack_player_profile_count = - if flo_ob_slot_occupied { 0 } else { 1 } + occupied_slots.len() - 1; - let msg = PlayerProfileMessage::new(my_id, &my_name); - for _ in 0..ack_player_profile_count { - records.push(Record::ProtoBuf(ProtoBufPayload::new(msg.clone()))) - } - } - - // 4 SlotInfo - { - let mut b = SlotInfo::build(); - let mut slot_info = b - .random_seed(game.random_seed) - .num_slots(24) - .num_players( - occupied_slots - .iter() - .filter(|(_, slot)| slot.settings.team != 24 && slot.player.is_some()) - .count(), - ) - .build(); - - for (i, player_slot) in &occupied_slots { - use flo_w3gs::slot::SlotStatus; - let slot = slot_info.slot_mut(*i).expect("always has 24 slots"); - - if player_slot.player.is_some() { - slot.player_id = index_to_player_id(*i); - slot.slot_status = SlotStatus::Occupied; - slot.race = player_slot.settings.race.into(); - slot.color = player_slot.settings.color as u8; - slot.team = player_slot.settings.team as u8; - slot.handicap = player_slot.settings.handicap as u8; - slot.download_status = 100; - } else { - slot.computer = true; - slot.computer_type = player_slot.settings.computer.into(); - slot.slot_status = SlotStatus::Occupied; - slot.race = player_slot.settings.race.into(); - slot.color = player_slot.settings.color as u8; - slot.team = player_slot.settings.team as u8; - slot.handicap = player_slot.settings.handicap as u8; - slot.download_status = 100; - } - } - - if !flo_ob_slot_occupied { - use flo_w3gs::slot::SlotStatus; - let slot = slot_info - .slot_mut(FLO_OB_SLOT) - .expect("always has 24 slots"); - - slot.player_id = index_to_player_id(FLO_OB_SLOT); - slot.slot_status = SlotStatus::Occupied; - slot.race = RacePref::RANDOM; - slot.color = 0; - slot.team = 24; - } - - records.push(Record::SlotInfo(slot_info)); - } - - // 5 CountDownStart - records.push(Record::CountDownStart(Default::default())); - - // 6 CountDownEnd - records.push(Record::CountDownEnd(Default::default())); - - // 7 GameStart - records.push(Record::GameStart(Default::default())); - - // archive records - for r in archive_records { - match r { - GameRecordData::W3GS(p) => match p.type_id() { - W3GSPacketTypeId::PlayerLeft => { - let payload: flo_w3gs::protocol::leave::PlayerLeft = p.decode_simple().unwrap(); - records.push(Record::PlayerLeft(PlayerLeft { - reason: payload.reason, - player_id: payload.player_id, - result: 13, // ? - unknown: 2, - })) - } - W3GSPacketTypeId::ChatFromHost => { - let payload: flo_w3gs::protocol::chat::ChatFromHost = p.decode_simple().unwrap(); - if payload - .0 - .to_players - .contains(&index_to_player_id(FLO_OB_SLOT)) - { - records.push(Record::ChatMessage(PlayerChatMessage { - player_id: payload.from_player(), - message: payload.0.message, - })); - } - } - W3GSPacketTypeId::IncomingAction => { - let payload: flo_w3gs::protocol::action::IncomingAction = - p.decode_payload().unwrap(); - records.push(Record::TimeSlot(TimeSlot { - time_increment_ms: payload.0.time_increment_ms, - actions: payload.0.actions, - })) - } - _ => {} - }, - GameRecordData::StartLag(_) => {} - GameRecordData::StopLag(_) => {} - GameRecordData::GameEnd => {} - GameRecordData::TickChecksum { checksum, .. } => { - records.push(Record::TimeSlotAck(TimeSlotAck::new(checksum))) - } - GameRecordData::RTTStats(_) => {} - } - } - - tracing::info!("total replay records: {}", records.len()); tracing::info!("encoding replay..."); let file = std::fs::File::create(format!("{}.w3g", game_id)).unwrap(); let w = std::io::BufWriter::new(file); - let mut encoder = ReplayEncoder::new(&game.game_version, 0x8000, w).unwrap(); - encoder.encode_records(records.iter()).unwrap(); - encoder.finish().unwrap(); + + generate_replay( + GenerateReplayOptions { + game, + archive, + include_chats: true, + }, + w, + ) + .await + .unwrap(); tracing::info!("done"); } diff --git a/crates/observer/src/lib.rs b/crates/observer/src/lib.rs index a8bea99f..c2af13b4 100644 --- a/crates/observer/src/lib.rs +++ b/crates/observer/src/lib.rs @@ -1,6 +1,6 @@ +pub mod error; mod kinesis; pub mod record; -pub mod error; pub mod token; use once_cell::sync::Lazy; diff --git a/crates/replay/Cargo.toml b/crates/replay/Cargo.toml new file mode 100644 index 00000000..1516179c --- /dev/null +++ b/crates/replay/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "flo-replay" +version = "0.1.0" +edition = "2021" + +[dependencies] +flo-net = { path = "../net" } +flo-w3gs = { path = "../w3gs" } +flo-types = { path = "../types" } +flo-w3replay = { path = "../w3replay" } +flo-observer = { path = "../observer" } +flo-observer-fs = { path = "../observer-fs" } +bytes = "1.1.0" +thiserror = "1.0" +tracing = "0.1" \ No newline at end of file diff --git a/crates/replay/src/error.rs b/crates/replay/src/error.rs new file mode 100644 index 00000000..24232635 --- /dev/null +++ b/crates/replay/src/error.rs @@ -0,0 +1,15 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("flo observer slot occupied")] + FloObserverSlotOccupied, + #[error("w3gs: {0}")] + W3GS(#[from] flo_w3gs::error::Error), + #[error("observer fs: {0}")] + ObserverFs(#[from] flo_observer_fs::error::Error), + #[error("w3replay: {0}")] + W3Replay(#[from] flo_w3replay::error::Error), +} + +pub type Result = std::result::Result; diff --git a/crates/replay/src/lib.rs b/crates/replay/src/lib.rs new file mode 100644 index 00000000..0164c47c --- /dev/null +++ b/crates/replay/src/lib.rs @@ -0,0 +1,309 @@ +pub mod error; +use bytes::Bytes; +use error::{Error, Result}; + +use flo_net::w3gs::W3GSPacketTypeId; +use flo_observer::record::GameRecordData; +use flo_observer_fs::GameDataArchiveReader; +use flo_types::game::SlotStatus; +use flo_w3gs::leave::LeaveReason; +use flo_w3gs::player::{PlayerProfileMessage, PlayerSkinsMessage, PlayerUnknown5Message}; +use flo_w3replay::Record; +use flo_w3replay::{ + GameInfo, PlayerChatMessage, PlayerInfo, PlayerLeft, ProtoBufPayload, RacePref, ReplayEncoder, + SlotInfo, TimeSlot, TimeSlotAck, +}; +use std::io::{Seek, Write}; + +const FLO_OB_SLOT: usize = 23; +const FLO_PLAYER_ID: u8 = index_to_player_id(FLO_OB_SLOT); + +pub struct GenerateReplayOptions { + pub game: flo_types::observer::GameInfo, + pub archive: Bytes, + pub include_chats: bool, +} + +pub async fn generate_replay( + GenerateReplayOptions { + game, + archive, + include_chats, + }: GenerateReplayOptions, + w: W, +) -> Result<()> +where + W: Write + Seek, +{ + let occupied_slots: Vec<(usize, _)> = game + .slots + .iter() + .enumerate() + .filter(|(_, slot)| slot.settings.status == SlotStatus::Occupied) + .collect(); + + let (first_player_info, first_player_name) = occupied_slots + .get(0) + .and_then(|(i, slot)| { + let name = slot.player.as_ref().map(|p| p.name.clone())?; + Some((PlayerInfo::new(index_to_player_id(*i), &name), name)) + }) + .unwrap(); + let first_player_id = first_player_info.id; + + let game_info = GameInfo::new( + first_player_info, + &game.name, + flo_w3gs::game::GameSettings::new( + Default::default(), + flo_w3gs::game::GameSettingsMap { + path: game.map.path.clone(), + width: 0, + height: 0, + sha1: { + let mut value = [0_u8; 20]; + value.copy_from_slice(&game.map.sha1[..]); + value + }, + checksum: 0xFFFFFFFF, + }, + ), + ); + + let flo_ob_slot_occupied = occupied_slots + .iter() + .find(|(idx, _)| *idx == FLO_OB_SLOT) + .is_some(); + + if flo_ob_slot_occupied { + return Err(Error::FloObserverSlotOccupied); + } + + let mut player_infos = vec![]; + let mut player_skins = vec![]; + let mut player_profiles = vec![]; + let mut active_player_ids = vec![]; + + let mut is_first_player = true; + for (i, slot) in game.slots.iter().enumerate() { + if let Some(ref p) = slot.player { + let player_id = index_to_player_id(i); + active_player_ids.push(player_id); + if is_first_player { + is_first_player = false; + } else { + player_infos.push(PlayerInfo::new(player_id, p.name.as_str())); + } + player_skins.push(ProtoBufPayload::new(PlayerSkinsMessage { + player_id: player_id as _, + ..Default::default() + })); + player_profiles.push(ProtoBufPayload::new(PlayerProfileMessage { + player_id: player_id as _, + battle_tag: p.name.clone(), + portrait: "p042".to_string(), + ..Default::default() + })); + } + } + + player_infos.push(PlayerInfo::new(FLO_PLAYER_ID, "FLO")); + player_profiles.push(ProtoBufPayload::new(PlayerProfileMessage::new( + FLO_PLAYER_ID, + "FLO", + ))); + + let mut records = vec![]; + + // 0 GameInfo + records.push(Record::GameInfo(game_info)); + + // 1 PlayerInfo + for item in player_infos { + records.push(Record::PlayerInfo(flo_w3replay::PlayerInfoRecord { + player_info: item, + unknown: 0, + })); + } + + // 2 ProtoBuf PlayerSkins + for item in player_skins { + records.push(Record::ProtoBuf(item)); + } + + // 3 ProtoBuf PlayerProfile + for item in player_profiles { + records.push(Record::ProtoBuf(item)); + } + + // special messages + { + let (my_id, my_name) = if flo_ob_slot_occupied { + (first_player_id, first_player_name.clone()) + } else { + (index_to_player_id(FLO_OB_SLOT), "FLO".to_string()) + }; + + // ProtoBuf PlayerSkinsMessage + + records.push(Record::ProtoBuf(ProtoBufPayload::new(PlayerSkinsMessage { + player_id: my_id as _, + ..Default::default() + }))); + + // ProtoBuf PlayerUnknown5 + records.push(Record::ProtoBuf(ProtoBufPayload::new( + PlayerUnknown5Message { + player_id: my_id as _, + unknown_1: 1, + }, + ))); + + let ack_player_profile_count = + if flo_ob_slot_occupied { 0 } else { 1 } + occupied_slots.len() - 1; + let msg = PlayerProfileMessage::new(my_id, &my_name); + for _ in 0..ack_player_profile_count { + records.push(Record::ProtoBuf(ProtoBufPayload::new(msg.clone()))) + } + } + + // 4 SlotInfo + { + let mut b = SlotInfo::build(); + let mut slot_info = b + .random_seed(game.random_seed) + .num_slots(24) + .num_players( + occupied_slots + .iter() + .filter(|(_, slot)| slot.settings.team != 24 && slot.player.is_some()) + .count(), + ) + .build(); + + for (i, player_slot) in &occupied_slots { + use flo_w3gs::slot::SlotStatus; + let slot = slot_info.slot_mut(*i).expect("always has 24 slots"); + + if player_slot.player.is_some() { + slot.player_id = index_to_player_id(*i); + slot.slot_status = SlotStatus::Occupied; + slot.race = player_slot.settings.race.into(); + slot.color = player_slot.settings.color as u8; + slot.team = player_slot.settings.team as u8; + slot.handicap = player_slot.settings.handicap as u8; + slot.download_status = 100; + } else { + slot.computer = true; + slot.computer_type = player_slot.settings.computer.into(); + slot.slot_status = SlotStatus::Occupied; + slot.race = player_slot.settings.race.into(); + slot.color = player_slot.settings.color as u8; + slot.team = player_slot.settings.team as u8; + slot.handicap = player_slot.settings.handicap as u8; + slot.download_status = 100; + } + } + + if !flo_ob_slot_occupied { + use flo_w3gs::slot::SlotStatus; + let slot = slot_info + .slot_mut(FLO_OB_SLOT) + .expect("always has 24 slots"); + + slot.player_id = index_to_player_id(FLO_OB_SLOT); + slot.slot_status = SlotStatus::Occupied; + slot.race = RacePref::RANDOM; + slot.color = 0; + slot.team = 24; + } + + records.push(Record::SlotInfo(slot_info)); + } + + // 5 CountDownStart + records.push(Record::CountDownStart(Default::default())); + + // 6 CountDownEnd + records.push(Record::CountDownEnd(Default::default())); + + // 7 GameStart + records.push(Record::GameStart(Default::default())); + + let rdr = GameDataArchiveReader::open_bytes(&archive).await?; + let archive_records = rdr.records().collect_vec().await?; + + tracing::debug!( + "archive: size: {}, records: {}", + archive.len(), + archive_records.len() + ); + + // archive records + for r in archive_records { + match r { + GameRecordData::W3GS(p) => match p.type_id() { + W3GSPacketTypeId::PlayerLeft => { + let payload: flo_w3gs::protocol::leave::PlayerLeft = p.decode_simple()?; + records.push(Record::PlayerLeft(PlayerLeft { + reason: payload.reason, + player_id: payload.player_id, + // All guesses, referenced w3g_format.txt + result: match payload.reason { + LeaveReason::LeaveDisconnect => 0x01, + LeaveReason::LeaveLost => 0x07, + LeaveReason::LeaveLostBuildings => 0x08, + LeaveReason::LeaveWon => 0x09, + _ => 0x0D, + }, + unknown: 2, + })); + active_player_ids.retain(|id| *id != payload.player_id); + } + W3GSPacketTypeId::ChatFromHost => { + let payload: flo_w3gs::protocol::chat::ChatFromHost = p.decode_simple()?; + if include_chats && payload.0.to_players.contains(&FLO_PLAYER_ID) { + records.push(Record::ChatMessage(PlayerChatMessage { + player_id: payload.from_player(), + message: payload.0.message, + })); + } + } + W3GSPacketTypeId::IncomingAction => { + let payload: flo_w3gs::protocol::action::IncomingAction = p.decode_payload()?; + records.push(Record::TimeSlot(TimeSlot { + time_increment_ms: payload.0.time_increment_ms, + actions: payload.0.actions, + })) + } + _ => {} + }, + GameRecordData::StartLag(_) => {} + GameRecordData::StopLag(_) => {} + GameRecordData::GameEnd => {} + GameRecordData::TickChecksum { checksum, .. } => { + records.push(Record::TimeSlotAck(TimeSlotAck::new(checksum))) + } + GameRecordData::RTTStats(_) => {} + } + } + + for player_id in active_player_ids { + records.push(Record::PlayerLeft(PlayerLeft { + reason: LeaveReason::LeaveDisconnect, + player_id, + result: 0x0D, + unknown: 2, + })); + } + + let mut encoder = ReplayEncoder::new(&game.game_version, 0x8000, w)?; + encoder.encode_records(records.iter())?; + encoder.finish()?; + + Ok(()) +} + +const fn index_to_player_id(index: usize) -> u8 { + return (index + 1) as u8; +} diff --git a/crates/w3replay/src/records.rs b/crates/w3replay/src/records.rs index 830523b1..519f5c22 100644 --- a/crates/w3replay/src/records.rs +++ b/crates/w3replay/src/records.rs @@ -542,7 +542,7 @@ fn test_record_iter() { #[test] fn test_game_info() { - let bytes = flo_util::sample_bytes!("replay", "3506801.w3g"); + let bytes = flo_util::sample_bytes!("replay", "grubby_happy.w3g"); let mut buf = bytes.as_slice(); let header = crate::header::Header::decode(&mut buf).unwrap(); @@ -569,63 +569,63 @@ fn test_game_info() { rec_count = rec_count + 1; match rec { Record::GameInfo(gameinfo) => { - dbg!(gameinfo); + // dbg!(gameinfo); } Record::PlayerInfo(info) => { dbg!(info); } - Record::PlayerLeft(_info) => { - // dbg!(info); + Record::PlayerLeft(info) => { + dbg!(info); } // Record::SlotInfo(info) => { // dbg!(info); // } Record::CountDownStart(info) => { - dbg!(info); + // dbg!(info); } Record::CountDownEnd(info) => { - dbg!(info); + // dbg!(info); } Record::GameStart(info) => { - dbg!(info); + // dbg!(info); } // Record::TimeSlotFragment(_) => todo!(), // Record::TimeSlot(_) => todo!(), Record::ChatMessage(m) => { - dbg!(m); + // dbg!(m); } // Record::TimeSlotAck(_) => todo!(), // Record::Desync(_) => todo!(), // Record::EndTimer(_) => todo!(), - Record::ProtoBuf(p) => { - match dbg!(p.message_type_id()) { - // flo_w3gs::constants::ProtoBufMessageTypeId::Unknown2 => todo!(), - flo_w3gs::constants::ProtoBufMessageTypeId::PlayerProfile => { - let m = p - .decode_message::() - .map_err(|err| { - std::fs::write("1.bin", p.data).unwrap(); - err - }) - .unwrap(); - dbg!(m); - } - flo_w3gs::constants::ProtoBufMessageTypeId::PlayerSkins => { - let m = p - .decode_message::() - .unwrap(); - dbg!(m); - } - flo_w3gs::constants::ProtoBufMessageTypeId::PlayerUnknown5 => { - let m = p - .decode_message::() - .unwrap(); - dbg!(m); - } - // flo_w3gs::constants::ProtoBufMessageTypeId::UnknownValue(_) => todo!(), - _ => {} - } - } + // Record::ProtoBuf(p) => { + // match dbg!(p.message_type_id()) { + // // flo_w3gs::constants::ProtoBufMessageTypeId::Unknown2 => todo!(), + // flo_w3gs::constants::ProtoBufMessageTypeId::PlayerProfile => { + // let m = p + // .decode_message::() + // .map_err(|err| { + // std::fs::write("1.bin", p.data).unwrap(); + // err + // }) + // .unwrap(); + // dbg!(m); + // } + // flo_w3gs::constants::ProtoBufMessageTypeId::PlayerSkins => { + // let m = p + // .decode_message::() + // .unwrap(); + // dbg!(m); + // } + // flo_w3gs::constants::ProtoBufMessageTypeId::PlayerUnknown5 => { + // let m = p + // .decode_message::() + // .unwrap(); + // dbg!(m); + // } + // // flo_w3gs::constants::ProtoBufMessageTypeId::UnknownValue(_) => todo!(), + // _ => {} + // } + // } _ => {} } }