use std::fs; use test_case::test_case; use bitbuffer::{BitRead, BitReadBuffer, BitReadStream, BitWrite, BitWriteStream, LittleEndian}; use std::collections::HashMap; use tf_demo_parser::demo::header::Header; use tf_demo_parser::demo::message::Message; use tf_demo_parser::demo::packet::datatable::SendTableName; use tf_demo_parser::demo::packet::Packet; use tf_demo_parser::demo::parser::{DemoHandler, Encode, NullHandler, RawPacketStream}; use tf_demo_parser::demo::sendprop::{RawSendPropDefinition, SendPropIdentifier, SendPropName}; use tf_demo_parser::{Demo, Parse}; #[test_case("test_data/small.dem"; "small.dem")] #[test_case("test_data/gully.dem"; "gully.dem")] #[test_case("test_data/comp.dem"; "comp.dem")] #[test_case("test_data/malformed_cvar.dem"; "malformed_cvar.dem")] #[test_case("test_data/unicode-saytext.dem"; "unicode-saytext.dem")] #[test_case("test_data/nousers.dem"; "nousers.dem")] #[test_case("test_data/decal.dem"; "decal.dem")] #[test_case("test_data/saytext2.dem"; "saytext2.dem")] #[test_case("test_data/emptysaytext.dem"; "emptysaytext.dem")] fn re_encode_test(input_file: &str) { let file = fs::read(input_file).expect("Unable to read file"); let demo = Demo::new(&file); let mut out_buffer = Vec::with_capacity(file.len()); let mut stream = demo.get_stream(); let header = Header::read(&mut stream).unwrap(); let header_size = stream.pos() / 8; assert_eq!(1072, header_size); let mut packets = RawPacketStream::new(stream); let mut handler = DemoHandler::parse_all_with_analyser(NullHandler); { let mut out_stream = BitWriteStream::new(&mut out_buffer, LittleEndian); header.write(&mut out_stream).unwrap(); } assert_eq!(file[0..header_size], out_buffer); let mut prop_names: HashMap< SendPropIdentifier, (SendTableName, SendPropName, RawSendPropDefinition), > = HashMap::new(); while let Some(packet) = packets.next(&handler.state_handler).unwrap() { if let Packet::DataTables(data_table) = &packet { for table in data_table.tables.iter() { for prop_def in &table.props { prop_names.insert( prop_def.identifier(), (table.name.clone(), prop_def.name.clone(), prop_def.clone()), ); } } } out_buffer.clear(); { let mut out_stream = BitWriteStream::new(&mut out_buffer, LittleEndian); packet .encode(&mut out_stream, &handler.state_handler) .unwrap(); } let mut re_read = BitReadStream::new(BitReadBuffer::new(&out_buffer, LittleEndian)); let re_decoded = Packet::parse(&mut re_read, &handler.state_handler) .unwrap_or_else(|_| panic!("while parsing {:?}", packet.packet_type())); assert_eq!(packet.packet_type(), re_decoded.packet_type()); match (&packet, &re_decoded) { ( Packet::Message(msg) | Packet::Signon(msg), Packet::Message(re_msg) | Packet::Signon(re_msg), ) => { assert_eq!(msg.tick, re_msg.tick); assert_eq!(msg.meta, re_msg.meta); assert_eq!( msg.messages .iter() .map(|msg| msg.get_message_type()) .collect::>(), re_msg .messages .iter() .map(|msg| msg.get_message_type()) .collect::>() ); assert_eq!(msg.messages.len(), re_msg.messages.len()); for (msg, re_msg) in msg.messages.iter().zip(re_msg.messages.iter()) { assert_eq!(msg.get_message_type(), re_msg.get_message_type()); match (msg, re_msg) { (Message::PacketEntities(msg), Message::PacketEntities(re_msg)) => { assert_eq!(msg.updated_base_line, re_msg.updated_base_line); assert_eq!(msg.base_line, re_msg.base_line); assert_eq!(msg.delta, re_msg.delta); assert_eq!(msg.max_entries, re_msg.max_entries); assert_eq!(msg.removed_entities, re_msg.removed_entities); assert_eq!(msg.entities.len(), re_msg.entities.len()); for (ent, re_ent) in msg.entities.iter().zip(re_msg.entities.iter()) { let props = ent .props .iter() .map(|prop| { ( prop_names.get(&prop.identifier).unwrap(), prop.value.clone(), ) }) .collect::>(); let re_props = re_ent .props .iter() .map(|prop| { ( prop_names.get(&prop.identifier).unwrap(), prop.value.clone(), ) }) .collect::>(); pretty_assertions::assert_eq!(props, re_props); } } (msg, re_msg) => assert_eq!(msg, re_msg), } } } (Packet::StringTables(packet), Packet::StringTables(re_packet)) => { assert_eq!(packet.tick, re_packet.tick); assert_eq!(packet.tables.len(), re_packet.tables.len()); for (table, re_table) in packet.tables.iter().zip(re_packet.tables.iter()) { assert_eq!(table, re_table); } } (packet, re_decoded) => { assert_eq!(packet, re_decoded); } } handler.handle_packet(packet).unwrap(); } }