1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-03 18:24:05 +02:00
This commit is contained in:
Robin Appelman 2021-07-21 23:44:04 +02:00
commit 0162eea68e
3 changed files with 91 additions and 11 deletions

View file

@ -3,11 +3,24 @@ use std::fs;
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian}; use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
use main_error::MainError; use main_error::MainError;
use steamid_ng::SteamID;
use tf_demo_parser::demo::data::UserInfo;
use tf_demo_parser::demo::header::Header; use tf_demo_parser::demo::header::Header;
use tf_demo_parser::demo::packet::stop::StopPacket; use tf_demo_parser::demo::message::Message;
use tf_demo_parser::demo::packet::Packet; use tf_demo_parser::demo::packet::stringtable::{StringTable, StringTableEntry};
use tf_demo_parser::demo::packet::{Packet, PacketType};
use tf_demo_parser::demo::parser::{DemoHandler, Encode, NullHandler, RawPacketStream}; use tf_demo_parser::demo::parser::{DemoHandler, Encode, NullHandler, RawPacketStream};
use tf_demo_parser::Demo; use tf_demo_parser::{Demo, Parse};
const COPY_TYPES: &[PacketType] = &[
// PacketType::Sigon,
// PacketType::Message,
// PacketType::SyncTick, // bit perfect
// PacketType::ConsoleCmd, // bit perfect
// PacketType::DataTables, // bit perfect
// PacketType::StringTables, // bit perfect
// PacketType::UserCmd, // bit perfect
];
fn main() -> Result<(), MainError> { fn main() -> Result<(), MainError> {
#[cfg(feature = "better_panic")] #[cfg(feature = "better_panic")]
@ -31,17 +44,83 @@ fn main() -> Result<(), MainError> {
let header = Header::read(&mut stream)?; let header = Header::read(&mut stream)?;
header.write(&mut out_stream)?; header.write(&mut out_stream)?;
let mut packets = RawPacketStream::new(stream); let mut packets = RawPacketStream::new(stream.clone());
let mut handler = DemoHandler::parse_all_with_analyser(NullHandler); let mut handler = DemoHandler::parse_all_with_analyser(NullHandler);
while let Some(packet) = packets.next(&handler.state_handler)? { let mut packet_start = packets.pos();
packet.encode(&mut out_stream, &handler.state_handler)?; let mut userinfo_table_id = 0;
while let Some(mut packet) = packets.next(&handler.state_handler)? {
let packet_end = packets.pos();
let packet_bits = stream.read_bits(packet_end - packet_start)?;
assert_eq!(
Packet::parse(&mut packet_bits.clone(), &handler.state_handler)?,
packet
);
if COPY_TYPES.contains(&packet.packet_type()) {
packet_bits.write(&mut out_stream)?;
} else {
match &mut packet {
Packet::Sigon(message_packet) | Packet::Message(message_packet) => {
message_packet.meta.view_angles = Default::default();
for message in message_packet.messages.iter_mut() {
match message {
Message::CreateStringTable(table_message) => {
if table_message.table.name == "userinfo" {
for (_i, entry) in table_message.table.entries.iter_mut() {
mut_string_user_info(entry);
}
}
}
Message::UpdateStringTable(table_message) => {
let table_name = &handler.string_table_names
[table_message.table_id as usize];
if table_name == "userinfo" {
for (_i, entry) in table_message.entries.iter_mut() {
mut_string_user_info(entry);
}
}
}
_ => {}
}
}
}
Packet::StringTables(table_packet) => {
for table in table_packet.tables.iter_mut() {
if table.name == "userinfo" {
for (_i, entry) in table.entries.iter_mut() {
mut_string_user_info(entry);
}
}
}
}
_ => {}
}
packet.encode(&mut out_stream, &handler.state_handler)?;
}
handler.handle_packet(packet)?; handler.handle_packet(packet)?;
packet_start = packet_end;
} }
Packet::Stop(StopPacket).encode(&mut out_stream, &handler.state_handler)?; assert_eq!(false, packets.incomplete);
} }
fs::write(out_path, out_buffer)?; fs::write(out_path, out_buffer)?;
Ok(()) Ok(())
} }
fn mut_string_user_info(entry: &mut StringTableEntry) {
if let Some(mut user_info) = UserInfo::parse_from_string_table(
entry.text.as_deref(),
entry.extra_data.as_ref().map(|data| data.data.clone()),
)
.unwrap()
{
// dbg!(&user_info);
user_info.player_info.name = "[GC]Kimo".into();
user_info.player_info.steam_id = "[U:1:32061783]".into();
user_info.player_info.friends_id =
SteamID::from_steam3("[U:1:32061783]").unwrap().account_id();
// *entry = user_info.encode_to_string_table().unwrap();
}
}

View file

@ -11,13 +11,13 @@ struct RawPlayerInfo {
pub steam_id: String, pub steam_id: String,
pub extra: u32, // all my sources say these 4 bytes don't exist pub extra: u32, // all my sources say these 4 bytes don't exist
pub friends_id: u32, pub friends_id: u32,
#[size = 32]
pub friends_name_bytes: [u8; 32], // seem to all be 0 now pub friends_name_bytes: [u8; 32], // seem to all be 0 now
pub is_fake_player: u8, pub is_fake_player: u8,
pub is_hl_tv: u8, pub is_hl_tv: u8,
pub is_replay: u8, pub is_replay: u8,
pub custom_file: [u32; 4], pub custom_file: [u32; 4],
pub files_downloaded: u32, pub files_downloaded: u32,
pub more_extra: u8,
} }
#[derive(BitWrite, Debug, Clone)] #[derive(BitWrite, Debug, Clone)]
@ -29,13 +29,13 @@ pub struct PlayerInfo {
pub steam_id: String, pub steam_id: String,
pub extra: u32, // all my sources say these 4 bytes don't exist pub extra: u32, // all my sources say these 4 bytes don't exist
pub friends_id: u32, pub friends_id: u32,
#[size = 32]
pub friends_name_bytes: [u8; 32], // seem to all be 0 now pub friends_name_bytes: [u8; 32], // seem to all be 0 now
pub is_fake_player: u8, pub is_fake_player: u8,
pub is_hl_tv: u8, pub is_hl_tv: u8,
pub is_replay: u8, pub is_replay: u8,
pub custom_file: [u32; 4], pub custom_file: [u32; 4],
pub files_downloaded: u32, pub files_downloaded: u32,
pub more_extra: u8,
} }
impl From<RawPlayerInfo> for PlayerInfo { impl From<RawPlayerInfo> for PlayerInfo {
@ -52,6 +52,7 @@ impl From<RawPlayerInfo> for PlayerInfo {
is_replay: raw.is_replay, is_replay: raw.is_replay,
custom_file: raw.custom_file, custom_file: raw.custom_file,
files_downloaded: raw.files_downloaded, files_downloaded: raw.files_downloaded,
more_extra: raw.more_extra,
} }
} }
} }
@ -88,7 +89,7 @@ impl UserInfo {
pub fn encode_to_string_table(&self) -> ReadResult<StringTableEntry<'static>> { pub fn encode_to_string_table(&self) -> ReadResult<StringTableEntry<'static>> {
let text = format!("{}", self.entity_id); let text = format!("{}", self.entity_id);
let mut extra_data = Vec::with_capacity(128); let mut extra_data = Vec::with_capacity(132);
{ {
let mut stream = BitWriteStream::new(&mut extra_data, LittleEndian); let mut stream = BitWriteStream::new(&mut extra_data, LittleEndian);
self.player_info.write(&mut stream)?; self.player_info.write(&mut stream)?;

View file

@ -1,4 +1,4 @@
use bitbuffer::{BitRead, BitWrite, BitWriteSized, LittleEndian}; use bitbuffer::{BitRead, BitWrite, LittleEndian};
use crate::{ReadResult, Stream}; use crate::{ReadResult, Stream};