diff --git a/src/events.rs b/src/events.rs index a0bbec2..0b92feb 100644 --- a/src/events.rs +++ b/src/events.rs @@ -4,7 +4,7 @@ use crate::{ http::serve, lua::{client, direction::Direction, player::Player, vec3::Vec3}, particle, - replay::Recorder, + replay::recorder::Recorder, }; use anyhow::Context; use azalea::{ diff --git a/src/main.rs b/src/main.rs index 685ee09..8d98330 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,7 @@ use commands::{CommandSource, register}; use futures::lock::Mutex; use futures_locks::RwLock; use mlua::{Function, Lua, Table}; -use replay::{Recorder, plugin::RecordPlugin}; +use replay::{plugin::RecordPlugin, recorder::Recorder}; use std::{ collections::HashMap, env, diff --git a/src/replay/mod.rs b/src/replay/mod.rs index 4abc412..241e306 100644 --- a/src/replay/mod.rs +++ b/src/replay/mod.rs @@ -1,89 +1,2 @@ pub mod plugin; - -use crate::build_info; -use anyhow::Result; -use azalea::{ - buf::AzaleaWriteVar, - prelude::Resource, - protocol::packets::{PROTOCOL_VERSION, ProtocolPacket, VERSION_NAME}, -}; -use serde_json::json; -use smallvec::SmallVec; -use std::{ - fs::File, - io::Write, - time::{Instant, SystemTime, UNIX_EPOCH}, -}; -use zip::{ZipWriter, write::SimpleFileOptions}; - -#[derive(Resource)] -pub struct Recorder { - zip_writer: ZipWriter, - start: Instant, - server: String, - ignore_compression: bool, -} - -impl Recorder { - pub fn new(path: String, server: String, ignore_compression: bool) -> Result { - let mut zip_writer = ZipWriter::new( - File::options() - .write(true) - .create(true) - .truncate(true) - .open(path)?, - ); - zip_writer.start_file("recording.tmcpr", SimpleFileOptions::default())?; - Ok(Self { - zip_writer, - start: Instant::now(), - server, - ignore_compression, - }) - } - - pub fn finish(mut self) -> Result<()> { - let elapsed = self.start.elapsed(); - - self.zip_writer - .start_file("metaData.json", SimpleFileOptions::default())?; - self.zip_writer.write_all( - json!({ - "singleplayer": false, - "serverName": self.server, - "duration": elapsed.as_millis(), - "date": (SystemTime::now().duration_since(UNIX_EPOCH)? - elapsed).as_millis(), - "mcversion": VERSION_NAME, - "fileFormat": "MCPR", - "fileFormatVersion": 14, - "protocol": PROTOCOL_VERSION, - "generator": format!("errornowatcher {}", build_info::version_formatted()), - }) - .to_string() - .as_bytes(), - )?; - self.zip_writer.finish()?; - - Ok(()) - } - - fn get_timestamp(&self) -> Result<[u8; 4]> { - Ok(TryInto::::try_into(self.start.elapsed().as_millis())?.to_be_bytes()) - } - - fn save_raw_packet(&mut self, raw_packet: &[u8]) -> Result<()> { - let mut data = Vec::with_capacity(raw_packet.len() + 8); - data.extend(self.get_timestamp()?); - data.extend(&TryInto::::try_into(raw_packet.len())?.to_be_bytes()); - data.extend(raw_packet); - self.zip_writer.write_all(&data)?; - Ok(()) - } - - fn save_packet(&mut self, packet: &T) -> Result<()> { - let mut raw_packet = SmallVec::<[u8; 256]>::new(); - packet.id().azalea_write_var(&mut raw_packet)?; - packet.write(&mut raw_packet)?; - self.save_raw_packet(&raw_packet) - } -} +pub mod recorder; diff --git a/src/replay/plugin.rs b/src/replay/plugin.rs index 7500b5b..a7f77f4 100644 --- a/src/replay/plugin.rs +++ b/src/replay/plugin.rs @@ -1,4 +1,4 @@ -use super::Recorder; +use super::recorder::Recorder; use azalea::{ ecs::{event::EventReader, system::Query}, packet_handling::{ @@ -36,7 +36,7 @@ fn record_login_packets( ) { if let Some(mut recorder) = recorder { for event in events.read() { - if recorder.ignore_compression + if recorder.should_ignore_compression && let ClientboundLoginPacket::LoginCompression(_) = *event.packet { continue; diff --git a/src/replay/recorder.rs b/src/replay/recorder.rs new file mode 100644 index 0000000..a079d45 --- /dev/null +++ b/src/replay/recorder.rs @@ -0,0 +1,87 @@ +use crate::build_info; +use anyhow::Result; +use azalea::{ + buf::AzaleaWriteVar, + prelude::Resource, + protocol::packets::{PROTOCOL_VERSION, ProtocolPacket, VERSION_NAME}, +}; +use serde_json::json; +use smallvec::SmallVec; +use std::{ + fs::File, + io::Write, + time::{Instant, SystemTime, UNIX_EPOCH}, +}; +use zip::{ZipWriter, write::SimpleFileOptions}; + +#[derive(Resource)] +pub struct Recorder { + zip_writer: ZipWriter, + start: Instant, + server: String, + pub should_ignore_compression: bool, +} + +impl Recorder { + pub fn new(path: String, server: String, should_ignore_compression: bool) -> Result { + let mut zip_writer = ZipWriter::new( + File::options() + .write(true) + .create(true) + .truncate(true) + .open(path)?, + ); + zip_writer.start_file("recording.tmcpr", SimpleFileOptions::default())?; + Ok(Self { + zip_writer, + start: Instant::now(), + server, + should_ignore_compression, + }) + } + + pub fn finish(mut self) -> Result<()> { + let elapsed = self.start.elapsed(); + + self.zip_writer + .start_file("metaData.json", SimpleFileOptions::default())?; + self.zip_writer.write_all( + json!({ + "singleplayer": false, + "serverName": self.server, + "duration": elapsed.as_millis(), + "date": (SystemTime::now().duration_since(UNIX_EPOCH)? - elapsed).as_millis(), + "mcversion": VERSION_NAME, + "fileFormat": "MCPR", + "fileFormatVersion": 14, + "protocol": PROTOCOL_VERSION, + "generator": format!("errornowatcher {}", build_info::version_formatted()), + }) + .to_string() + .as_bytes(), + )?; + self.zip_writer.finish()?; + + Ok(()) + } + + fn get_timestamp(&self) -> Result<[u8; 4]> { + Ok(TryInto::::try_into(self.start.elapsed().as_millis())?.to_be_bytes()) + } + + pub fn save_raw_packet(&mut self, raw_packet: &[u8]) -> Result<()> { + let mut data = Vec::with_capacity(raw_packet.len() + 8); + data.extend(self.get_timestamp()?); + data.extend(&TryInto::::try_into(raw_packet.len())?.to_be_bytes()); + data.extend(raw_packet); + self.zip_writer.write_all(&data)?; + Ok(()) + } + + pub fn save_packet(&mut self, packet: &T) -> Result<()> { + let mut raw_packet = SmallVec::<[u8; 256]>::new(); + packet.id().azalea_write_var(&mut raw_packet)?; + packet.write(&mut raw_packet)?; + self.save_raw_packet(&raw_packet) + } +}