mirror of
https://github.com/demostf/cutter.git
synced 2026-06-03 11:54:08 +02:00
filter out deletes that are already processed
This commit is contained in:
parent
e41ebb0db7
commit
18049bfc96
3 changed files with 63 additions and 18 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -5,3 +5,4 @@ bin/
|
||||||
pkg/
|
pkg/
|
||||||
wasm-pack.log
|
wasm-pack.log
|
||||||
out.dem
|
out.dem
|
||||||
|
test_data/*
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::{BTreeMap, BTreeSet, HashMap};
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use tf_demo_parser::demo::message::packetentities::{
|
use tf_demo_parser::demo::message::packetentities::{
|
||||||
|
|
@ -9,7 +9,7 @@ use tf_demo_parser::ParserState;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ActiveEntities {
|
pub struct ActiveEntities {
|
||||||
entities: HashMap<EntityId, PacketEntity>,
|
entities: BTreeMap<EntityId, PacketEntity>,
|
||||||
max_entities: u16,
|
max_entities: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,6 +57,10 @@ impl ActiveEntities {
|
||||||
.or_insert_with(|| entity.clone());
|
.or_insert_with(|| entity.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn entity_ids(&self) -> BTreeSet<EntityId> {
|
||||||
|
self.entities.keys().copied().collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn encode(
|
pub fn encode(
|
||||||
mut self,
|
mut self,
|
||||||
state: &ParserState,
|
state: &ParserState,
|
||||||
|
|
|
||||||
70
src/lib.rs
70
src/lib.rs
|
|
@ -9,10 +9,11 @@ use crate::string_tables::StringTablesUpdates;
|
||||||
use crate::utils::set_panic_hook;
|
use crate::utils::set_panic_hook;
|
||||||
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
|
use std::collections::BTreeSet;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
use tf_demo_parser::demo::header::Header;
|
use tf_demo_parser::demo::header::Header;
|
||||||
use tf_demo_parser::demo::message::packetentities::PacketEntitiesMessage;
|
use tf_demo_parser::demo::message::packetentities::{EntityId, PacketEntitiesMessage, UpdateType};
|
||||||
use tf_demo_parser::demo::message::{Message, NetTickMessage};
|
use tf_demo_parser::demo::message::{Message, NetTickMessage};
|
||||||
use tf_demo_parser::demo::packet::message::{MessagePacket, MessagePacketMeta};
|
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;
|
||||||
|
|
@ -72,12 +73,19 @@ pub fn cut(input: &[u8], start_tick: u32, end_tick: u32) -> Vec<u8> {
|
||||||
|
|
||||||
let mut next = packets.next(&start_handler.state_handler).unwrap().unwrap();
|
let mut next = packets.next(&start_handler.state_handler).unwrap().unwrap();
|
||||||
let mut delta_tick = 0;
|
let mut delta_tick = 0;
|
||||||
|
let mut max = 0;
|
||||||
|
let mut baseline = 0;
|
||||||
if let Packet::Message(MessagePacket { messages, .. }) = &next {
|
if let Packet::Message(MessagePacket { messages, .. }) = &next {
|
||||||
for msg in messages {
|
for msg in messages {
|
||||||
if let Message::PacketEntities(PacketEntitiesMessage {
|
if let Message::PacketEntities(PacketEntitiesMessage {
|
||||||
delta: Some(delta), ..
|
delta: Some(delta),
|
||||||
|
max_entries,
|
||||||
|
base_line,
|
||||||
|
..
|
||||||
}) = msg
|
}) = msg
|
||||||
{
|
{
|
||||||
|
max = *max_entries;
|
||||||
|
baseline = *base_line;
|
||||||
delta_tick = delta.get();
|
delta_tick = delta.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -85,6 +93,8 @@ pub fn cut(input: &[u8], start_tick: u32, end_tick: u32) -> Vec<u8> {
|
||||||
panic!("first packet is not a MessagePacket, pick a different start tick")
|
panic!("first packet is not a MessagePacket, pick a different start tick")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let start_entities = entities.entity_ids();
|
||||||
|
|
||||||
let string_table_updates = string_tables
|
let string_table_updates = string_tables
|
||||||
.encode()
|
.encode()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -98,7 +108,7 @@ pub fn cut(input: &[u8], start_tick: u32, end_tick: u32) -> Vec<u8> {
|
||||||
tick: 0,
|
tick: 0,
|
||||||
messages: vec![
|
messages: vec![
|
||||||
Message::NetTick(NetTickMessage {
|
Message::NetTick(NetTickMessage {
|
||||||
tick: delta_tick,
|
tick: delta_tick - 1,
|
||||||
frame_time: 1881,
|
frame_time: 1881,
|
||||||
std_dev: 263,
|
std_dev: 263,
|
||||||
}),
|
}),
|
||||||
|
|
@ -120,15 +130,13 @@ pub fn cut(input: &[u8], start_tick: u32, end_tick: u32) -> Vec<u8> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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..=last_server_tick).into_iter().map(|tick| {
|
||||||
.into_iter()
|
Message::NetTick(NetTickMessage {
|
||||||
.map(|tick| {
|
tick,
|
||||||
Message::NetTick(NetTickMessage {
|
frame_time: 1881,
|
||||||
tick,
|
std_dev: 263,
|
||||||
frame_time: 1881,
|
})
|
||||||
std_dev: 263,
|
});
|
||||||
})
|
|
||||||
});
|
|
||||||
let fill_packets = fill_ticks.map(|msg| {
|
let fill_packets = fill_ticks.map(|msg| {
|
||||||
Packet::Message(MessagePacket {
|
Packet::Message(MessagePacket {
|
||||||
tick: 0,
|
tick: 0,
|
||||||
|
|
@ -137,9 +145,9 @@ pub fn cut(input: &[u8], start_tick: u32, end_tick: u32) -> Vec<u8> {
|
||||||
Message::PacketEntities(PacketEntitiesMessage {
|
Message::PacketEntities(PacketEntitiesMessage {
|
||||||
entities: vec![],
|
entities: vec![],
|
||||||
removed_entities: vec![],
|
removed_entities: vec![],
|
||||||
max_entries: 0,
|
max_entries: max,
|
||||||
delta: Some(delta_tick.try_into().unwrap()),
|
delta: Some((delta_tick - 1).try_into().unwrap()),
|
||||||
base_line: 0,
|
base_line: baseline,
|
||||||
updated_base_line: false,
|
updated_base_line: false,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|
@ -157,6 +165,7 @@ pub fn cut(input: &[u8], start_tick: u32, end_tick: u32) -> Vec<u8> {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remove_already_deletes(&mut next, &start_entities, last_server_tick);
|
||||||
next.set_tick(next.tick() - start_tick);
|
next.set_tick(next.tick() - start_tick);
|
||||||
next.encode(&mut out_stream, &handler.state_handler)
|
next.encode(&mut out_stream, &handler.state_handler)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -166,6 +175,9 @@ 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);
|
||||||
|
|
||||||
|
remove_already_deletes(&mut packet, &start_entities, last_server_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)
|
||||||
|
|
@ -227,3 +239,31 @@ fn skip_start<'a>(
|
||||||
|
|
||||||
(entities, string_tables, start_packets, server_tick)
|
(entities, string_tables, start_packets, server_tick)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// filter out any ongoing deletes of entities that don't exist
|
||||||
|
fn remove_already_deletes(
|
||||||
|
packet: &mut Packet,
|
||||||
|
current_entities: &BTreeSet<EntityId>,
|
||||||
|
till_delta: u32,
|
||||||
|
) {
|
||||||
|
if let Packet::Message(msg_packet) = packet {
|
||||||
|
for msg in &mut msg_packet.messages {
|
||||||
|
if let Message::PacketEntities(msg) = msg {
|
||||||
|
if let Some(delta) = msg.delta {
|
||||||
|
if delta.get() < till_delta {
|
||||||
|
let packet_entities = std::mem::take(&mut msg.entities);
|
||||||
|
msg.entities = packet_entities
|
||||||
|
.into_iter()
|
||||||
|
.filter(|ent| match ent.update_type {
|
||||||
|
UpdateType::Delete | UpdateType::Leave => {
|
||||||
|
current_entities.contains(&ent.entity_index)
|
||||||
|
}
|
||||||
|
_ => true,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue