more baseline

This commit is contained in:
Robin Appelman 2022-04-18 13:09:20 +02:00
commit aada3cac55
3 changed files with 64 additions and 51 deletions

View file

@ -4,18 +4,21 @@ use std::mem::replace;
use tf_demo_parser::demo::message::packetentities::{ use tf_demo_parser::demo::message::packetentities::{
EntityId, PacketEntitiesMessage, PacketEntity, UpdateType, EntityId, PacketEntitiesMessage, PacketEntity, UpdateType,
}; };
use tf_demo_parser::demo::sendprop::SendPropIdentifier;
use tf_demo_parser::ParserState; use tf_demo_parser::ParserState;
#[derive(Default)] #[derive(Default)]
pub struct ActiveEntities { pub struct ActiveEntities {
baselines: [HashMap<EntityId, PacketEntity>; 2], baselines: [HashMap<EntityId, PacketEntity>; 2],
entities: HashMap<EntityId, PacketEntity>, entities: HashMap<EntityId, PacketEntity>,
max_entities: u16,
} }
impl ActiveEntities { impl ActiveEntities {
pub fn handle_message(&mut self, msg: &PacketEntitiesMessage, state: &ParserState) { pub fn handle_message(&mut self, msg: &PacketEntitiesMessage, state: &ParserState) {
self.max_entities = self.max_entities.max(msg.max_entries);
for entity in &msg.entities { for entity in &msg.entities {
if entity.update_type == UpdateType::Delete { if entity.update_type == UpdateType::Delete || entity.update_type == UpdateType::Leave {
self.remove_entity(entity.entity_index); self.remove_entity(entity.entity_index);
} else { } else {
self.handle_entity(entity, state); self.handle_entity(entity, state);
@ -32,14 +35,18 @@ impl ActiveEntities {
for entity in &msg.entities { for entity in &msg.entities {
if entity.update_type == UpdateType::Enter { if entity.update_type == UpdateType::Enter {
let entity = match self.baselines[old_index].get(&entity.entity_index) { let mut entity = match self.baselines[old_index].get(&entity.entity_index) {
Some(baseline) if baseline.server_class == entity.server_class => { Some(baseline)
if baseline.server_class == entity.server_class
&& msg.delta.is_some() =>
{
let mut baseline = baseline.clone(); let mut baseline = baseline.clone();
baseline.apply_update(&entity.props); baseline.apply_update(&entity.props);
baseline baseline
} }
_ => entity.clone(), _ => entity.clone(),
}; };
entity.baseline_props = vec![];
self.baselines[new_index].insert(entity.entity_index, entity); self.baselines[new_index].insert(entity.entity_index, entity);
} }
} }
@ -48,8 +55,6 @@ impl ActiveEntities {
fn remove_entity(&mut self, entity_index: EntityId) { fn remove_entity(&mut self, entity_index: EntityId) {
self.entities.remove(&entity_index); self.entities.remove(&entity_index);
self.baselines[0].remove(&entity_index);
self.baselines[1].remove(&entity_index);
} }
fn handle_entity(&mut self, entity: &PacketEntity, state: &ParserState) { fn handle_entity(&mut self, entity: &PacketEntity, state: &ParserState) {
@ -77,40 +82,39 @@ impl ActiveEntities {
.or_insert_with(|| entity.clone()); .or_insert_with(|| entity.clone());
} }
pub fn encode(mut self) -> impl IntoIterator<Item = PacketEntitiesMessage> { pub fn encode(
mut self,
state: &ParserState,
) -> impl IntoIterator<Item = PacketEntitiesMessage> {
// baselines in reverse order
let mut baselines = [ let mut baselines = [
encode_entities(self.baselines[0].clone().into_values().collect::<Vec<_>>()), encode_entities(
encode_entities(self.baselines[1].clone().into_values().collect::<Vec<_>>()), self.baselines[1].clone().into_values().collect::<Vec<_>>(),
self.max_entities,
),
encode_entities(
self.baselines[0].clone().into_values().collect::<Vec<_>>(),
self.max_entities,
),
]; ];
for entity in self.entities.values_mut() { for entity in self.entities.values_mut() {
entity.update_type = UpdateType::Enter; entity.update_type = UpdateType::Enter;
} }
let entities = encode_entities(self.entities.into_values().collect::<Vec<_>>()); let entities = encode_entities(
self.entities.into_values().collect::<Vec<_>>(),
self.max_entities,
);
baselines[0].updated_base_line = true; baselines[0].updated_base_line = true;
baselines[0].base_line = 1; //the baseline that is updated is the other one
baselines[1].base_line = 0;
for ent in baselines[0]
.entities
.iter()
.chain(baselines[1].entities.iter())
.chain(entities.entities.iter())
{
if ent.entity_index == 650 {
// dbg!(ent.update_type, &ent.props);
}
}
baselines[1].updated_base_line = true; baselines[1].updated_base_line = true;
baselines[1].base_line = 1;
baselines.into_iter().chain(once(entities)) baselines.into_iter().chain(once(entities))
} }
} }
fn encode_entities(mut entities: Vec<PacketEntity>) -> PacketEntitiesMessage { fn encode_entities(mut entities: Vec<PacketEntity>, max_entries: u16) -> PacketEntitiesMessage {
entities.sort_by(|a, b| a.entity_index.cmp(&b.entity_index)); entities.sort_by(|a, b| a.entity_index.cmp(&b.entity_index));
let max_entries = entities.len() as u16;
PacketEntitiesMessage { PacketEntitiesMessage {
entities, entities,
removed_entities: vec![], removed_entities: vec![],

View file

@ -16,7 +16,7 @@ use tf_demo_parser::demo::packet::message::{MessagePacket, MessagePacketMeta};
use tf_demo_parser::demo::packet::stop::StopPacket; use tf_demo_parser::demo::packet::stop::StopPacket;
use tf_demo_parser::demo::packet::{Packet, PacketType}; 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, MessageType};
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use web_sys::console; use web_sys::console;
@ -82,27 +82,35 @@ pub fn cut(input: &[u8], start_tick: u32, end_tick: u32) -> Vec<u8> {
panic!("first packet is not a MessagePacket") panic!("first packet is not a MessagePacket")
} }
let msgs = entities.encode().into_iter().map(Message::PacketEntities); let msgs = entities
let packet = Packet::Message(MessagePacket { .encode(&start_handler.state_handler)
tick: 0, .into_iter()
messages: once(Message::NetTick(NetTickMessage { .map(Message::PacketEntities);
tick: delta_tick, let start_packets = msgs.map(|msg| {
frame_time: 1881, Packet::Message(MessagePacket {
std_dev: 263, tick: 0,
})) messages: vec![
.chain(msgs) Message::NetTick(NetTickMessage {
.collect(), tick: delta_tick,
meta: MessagePacketMeta { frame_time: 1881,
flags: 0, std_dev: 263,
view_angles: Default::default(), }),
sequence_in: 0, msg,
sequence_out: 0, ],
}, meta: MessagePacketMeta {
flags: 0,
view_angles: Default::default(),
sequence_in: 0,
sequence_out: 0,
},
})
}); });
packet for packet in start_packets {
.encode(&mut out_stream, &handler.state_handler) packet
.unwrap(); .encode(&mut out_stream, &handler.state_handler)
handler.handle_packet(packet).unwrap(); .unwrap();
handler.handle_packet(packet).unwrap();
}
// create the net ticks needed for later deltas // create the net ticks needed for later deltas
let fill_ticks = ((delta_tick + 1)..=last_server_tick) let fill_ticks = ((delta_tick + 1)..=last_server_tick)
@ -151,11 +159,11 @@ pub fn cut(input: &[u8], start_tick: u32, end_tick: u32) -> Vec<u8> {
let ty = packet.packet_type(); let ty = packet.packet_type();
let original_tick = packet.tick(); let original_tick = packet.tick();
packet.set_tick(original_tick - start_tick); packet.set_tick(original_tick - start_tick);
// if ty != PacketType::ConsoleCmd { if ty != PacketType::ConsoleCmd {
packet packet
.encode(&mut out_stream, &handler.state_handler) .encode(&mut out_stream, &handler.state_handler)
.unwrap(); .unwrap();
// } }
handler.handle_packet(packet).unwrap(); handler.handle_packet(packet).unwrap();
if original_tick >= end_tick { if original_tick >= end_tick {

View file

@ -49,6 +49,7 @@ fn test_reparse_with_analyser<A: BorrowMessageHandler + Default, F: Fn(&A::Outpu
if original_tick.tick >= 50000 { if original_tick.tick >= 50000 {
break; break;
} }
// println!("tick {}", original_tick.tick);
assert_eq!(original_tick.tick, cut_tick.tick + 30000); assert_eq!(original_tick.tick, cut_tick.tick + 30000);
let original_state = &original_tick.state; let original_state = &original_tick.state;
let cut_state = &cut_tick.state; let cut_state = &cut_tick.state;