Add support for controllable physics serialization

This commit is contained in:
lcdr
2021-01-18 19:27:13 +01:00
parent 812f8c30d9
commit 827a7b2cfe
7 changed files with 118 additions and 14 deletions
+27 -9
View File
@@ -13,7 +13,7 @@ use lu_packets::{
bbb::BbbConstruction,
buff::BuffConstruction,
character::CharacterConstruction,
controllable_physics::ControllablePhysicsConstruction,
controllable_physics::{ControllablePhysicsConstruction, ControllablePhysicsSerialization},
destroyable::DestroyableConstruction,
fx::FxConstruction,
inventory::InventoryConstruction,
@@ -32,6 +32,7 @@ static mut PRINT_PACKETS: bool = false;
struct PlayerContext<'a> {
inner: ZipFile<'a>,
player_network_ids: &'a mut Vec<u16>,
}
impl std::io::Read for PlayerContext<'_> {
@@ -42,9 +43,14 @@ impl std::io::Read for PlayerContext<'_> {
// hacky hardcoded components to be able to read player replicas without DB lookup
impl ReplicaContext for PlayerContext<'_> {
fn get_comp_constructions<R: std::io::Read>(&mut self, _lot: Lot) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentConstruction>>> {
fn get_comp_constructions<R: std::io::Read>(&mut self, network_id: u16, lot: Lot) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentConstruction>>> {
use endio::Deserialize;
if lot != 1 {
return vec![];
}
self.player_network_ids.push(network_id);
vec![
|x| Ok(Box::new(ControllablePhysicsConstruction::deserialize(x)?)),
|x| Ok(Box::new(BuffConstruction::deserialize(x)?)),
@@ -60,8 +66,16 @@ impl ReplicaContext for PlayerContext<'_> {
]
}
fn get_comp_serializations<R: std::io::Read>(&mut self, _network_id: u16) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentSerialization>>> {
vec![]
fn get_comp_serializations<R: std::io::Read>(&mut self, network_id: u16) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentSerialization>>> {
use endio::Deserialize;
if !self.player_network_ids.contains(&network_id) {
return vec![];
}
vec![
|x| Ok(Box::new(ControllablePhysicsSerialization::deserialize(x)?)),
]
}
}
@@ -85,6 +99,7 @@ fn parse(path: &Path) -> Res<usize> {
let src = BufReader::new(File::open(path).unwrap());
let mut zip = ZipArchive::new(src).unwrap();
let mut player_network_ids = vec![];
let mut i = 0;
let mut packet_count = 0;
while i < zip.len() {
@@ -159,8 +174,9 @@ fn parse(path: &Path) -> Res<usize> {
&& !file.name().contains("[1647]")
&& !file.name().contains("[1648]"))
|| (file.name().contains("[24]") && file.name().contains("(1)"))
|| file.name().contains("[27]")
{
let mut ctx = PlayerContext { inner: file };
let mut ctx = PlayerContext { inner: file, player_network_ids: &mut player_network_ids };
let msg: WorldClientMessage = ctx.read().expect(&format!("Zip: {}, Filename: {}, {} bytes", path.to_str().unwrap(), ctx.inner.name(), ctx.inner.size()));
file = ctx.inner;
if unsafe { PRINT_PACKETS } {
@@ -168,10 +184,12 @@ fn parse(path: &Path) -> Res<usize> {
}
packet_count += 1;
} else { i += 1; continue }
// assert fully read
let mut rest = vec![];
std::io::Read::read_to_end(&mut file, &mut rest).unwrap();
assert_eq!(rest, vec![], "{}", path.to_str().unwrap());
if !file.name().contains("[27]") {
// assert fully read
let mut rest = vec![];
std::io::Read::read_to_end(&mut file, &mut rest).unwrap();
assert_eq!(rest, vec![], "{}", path.to_str().unwrap());
}
i += 1;
}
Ok(packet_count)
@@ -6,7 +6,7 @@ use lu_packets_derive::{BitVariantTests, ReplicaSerde};
use crate::common::ObjId;
use crate::world::{Vector3, Quaternion};
use super::{ComponentConstruction};
use super::{ComponentConstruction, ComponentSerialization};
#[derive(Debug, PartialEq, ReplicaSerde)]
pub struct JetpackInfo {
@@ -72,8 +72,28 @@ pub struct ControllablePhysicsConstruction {
pub frame_stats: Option<FrameStats>,
}
#[derive(Debug, PartialEq, ReplicaSerde)]
pub struct FrameStatsTeleportInfo {
pub frame_stats: FrameStats,
pub is_teleporting: bool,
}
#[derive(BitVariantTests, Debug, PartialEq, ReplicaSerde)]
pub struct ControllablePhysicsSerialization {
pub cheat_info: Option<CheatInfo>,
pub unknown_1: Option<Unknown1>,
pub unknown_2: Option<Unknown2>,
pub frame_stats_teleport_info: Option<FrameStatsTeleportInfo>,
}
impl ComponentConstruction for ControllablePhysicsConstruction {
fn ser(&self, writer: &mut BEBitWriter<Vec<u8>>) -> Res<()> {
self.serialize(writer)
}
}
impl ComponentSerialization for ControllablePhysicsSerialization {
fn ser(&self, writer: &mut BEBitWriter<Vec<u8>>) -> Res<()> {
self.serialize(writer)
}
}
+9 -4
View File
@@ -82,7 +82,7 @@ pub trait ComponentSerialization: Debug {
}
pub trait ReplicaContext {
fn get_comp_constructions<R: Read>(&mut self, lot: Lot) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentConstruction>>>;
fn get_comp_constructions<R: Read>(&mut self, network_id: u16, lot: Lot) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentConstruction>>>;
fn get_comp_serializations<R: Read>(&mut self, network_id: u16) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentSerialization>>>;
}
@@ -147,7 +147,7 @@ impl<R: Read+ReplicaContext> Deserialize<LE, R> for ReplicaConstruction {
let gm_level = ReplicaD::deserialize(&mut bit_reader)?;
let parent_child_info = ReplicaD::deserialize(&mut bit_reader)?;
let mut components = vec![];
for new in unsafe {bit_reader.get_mut_unchecked()}.get_comp_constructions(lot) {
for new in unsafe {bit_reader.get_mut_unchecked()}.get_comp_constructions(network_id, lot) {
components.push(new(&mut bit_reader)?);
}
@@ -200,6 +200,7 @@ impl<'a, W: Write> Serialize<LE, W> for &'a ReplicaConstruction {
#[derive(Debug)]
pub struct ReplicaSerialization {
pub network_id: u16,
pub parent_child_info: Option<ParentChildInfo>,
pub components: Vec<Box<dyn ComponentSerialization>>,
}
@@ -215,6 +216,7 @@ impl<R: Read+ReplicaContext> Deserialize<LE, R> for ReplicaSerialization {
let network_id = LERead::read(reader)?;
let comp_desers = reader.get_comp_serializations(network_id);
let mut bit_reader = BEBitReader::new(reader);
let parent_child_info = ReplicaD::deserialize(&mut bit_reader)?;
let mut components = vec![];
for new in comp_desers {
components.push(new(&mut bit_reader)?);
@@ -222,6 +224,7 @@ impl<R: Read+ReplicaContext> Deserialize<LE, R> for ReplicaSerialization {
Ok(Self {
network_id,
parent_child_info,
components,
})
}
@@ -231,6 +234,8 @@ impl<'a, W: Write> Serialize<LE, W> for &'a ReplicaSerialization {
fn serialize(self, writer: &mut W) -> Res<()> {
LEWrite::write(writer, self.network_id)?;
let mut bit_writer = BEBitWriter::new(vec![]);
ReplicaS::serialize(&self.parent_child_info, &mut bit_writer)?;
for comp in &self.components {
comp.ser(&mut bit_writer)?;
}
@@ -255,11 +260,11 @@ impl Read for DummyContext<'_> {
#[cfg(test)]
impl ReplicaContext for DummyContext<'_> {
fn get_comp_constructions<R: Read>(&mut self, _lot: Lot) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentConstruction>>> {
fn get_comp_constructions<R: Read>(&mut self, _network_id: u16, _lot: Lot) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentConstruction>>> {
vec![]
}
fn get_comp_serializations<R: Read>(&mut self, network_id: u16) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentSerialization>>> {
fn get_comp_serializations<R: Read>(&mut self, _network_id: u16) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentSerialization>>> {
vec![]
}
}
@@ -0,0 +1,57 @@
ControllablePhysicsSerialization {
cheat_info: Some(CheatInfo {
gravity_scale: 8.0,
run_multiplier: 9.0,
}),
unknown_1: Some(Unknown1 {
unknown_1: 10.0,
unknown_2: true,
}),
unknown_2: Some(Unknown2 {
unknown_1: Some(Unknown1 {
unknown_1: 11.0,
unknown_2: true,
}),
}),
frame_stats_teleport_info: Some(FrameStatsTeleportInfo {
frame_stats: FrameStats {
position: Vector3 {
x: 12.0,
y: 13.0,
z: 14.0,
},
rotation: Quaternion {
x: 15.0,
y: 16.0,
z: 17.0,
w: 18.0,
},
is_on_ground: true,
is_on_rail: true,
linear_velocity: Some(Vector3 {
x: 19.0,
y: 20.0,
z: 21.0,
}),
angular_velocity: Some(Vector3 {
x: 22.0,
y: 23.0,
z: 24.0,
}),
local_space_info: Some(LocalSpaceInfo {
object_id: 25,
position: Vector3 {
x: 26.0,
y: 27.0,
z: 28.0,
},
linear_velocity: Some(Vector3 {
x: 29.0,
y: 30.0,
z: 31.0,
}),
}),
},
is_teleporting: true,
}),
}
Binary file not shown.
@@ -1,6 +1,10 @@
Message::ReplicaSerialization(
ReplicaSerialization {
network_id: 11,
parent_child_info: Some(crate::raknet::client::replica::ParentChildInfo {
parent_info: None,
child_info: None,
}),
components: vec![],
}
)