refactor(replay): move recorder into separate module
This commit is contained in:
parent
dda43999fe
commit
e81fab7bf8
@ -4,7 +4,7 @@ use crate::{
|
|||||||
http::serve,
|
http::serve,
|
||||||
lua::{client, direction::Direction, player::Player, vec3::Vec3},
|
lua::{client, direction::Direction, player::Player, vec3::Vec3},
|
||||||
particle,
|
particle,
|
||||||
replay::Recorder,
|
replay::recorder::Recorder,
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use azalea::{
|
use azalea::{
|
||||||
|
@ -24,7 +24,7 @@ use commands::{CommandSource, register};
|
|||||||
use futures::lock::Mutex;
|
use futures::lock::Mutex;
|
||||||
use futures_locks::RwLock;
|
use futures_locks::RwLock;
|
||||||
use mlua::{Function, Lua, Table};
|
use mlua::{Function, Lua, Table};
|
||||||
use replay::{Recorder, plugin::RecordPlugin};
|
use replay::{plugin::RecordPlugin, recorder::Recorder};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
env,
|
env,
|
||||||
|
@ -1,89 +1,2 @@
|
|||||||
pub mod plugin;
|
pub mod plugin;
|
||||||
|
pub mod recorder;
|
||||||
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<File>,
|
|
||||||
start: Instant,
|
|
||||||
server: String,
|
|
||||||
ignore_compression: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Recorder {
|
|
||||||
pub fn new(path: String, server: String, ignore_compression: bool) -> Result<Self> {
|
|
||||||
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::<u32>::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::<u32>::try_into(raw_packet.len())?.to_be_bytes());
|
|
||||||
data.extend(raw_packet);
|
|
||||||
self.zip_writer.write_all(&data)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn save_packet<T: ProtocolPacket>(&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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::Recorder;
|
use super::recorder::Recorder;
|
||||||
use azalea::{
|
use azalea::{
|
||||||
ecs::{event::EventReader, system::Query},
|
ecs::{event::EventReader, system::Query},
|
||||||
packet_handling::{
|
packet_handling::{
|
||||||
@ -36,7 +36,7 @@ fn record_login_packets(
|
|||||||
) {
|
) {
|
||||||
if let Some(mut recorder) = recorder {
|
if let Some(mut recorder) = recorder {
|
||||||
for event in events.read() {
|
for event in events.read() {
|
||||||
if recorder.ignore_compression
|
if recorder.should_ignore_compression
|
||||||
&& let ClientboundLoginPacket::LoginCompression(_) = *event.packet
|
&& let ClientboundLoginPacket::LoginCompression(_) = *event.packet
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
87
src/replay/recorder.rs
Normal file
87
src/replay/recorder.rs
Normal file
@ -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<File>,
|
||||||
|
start: Instant,
|
||||||
|
server: String,
|
||||||
|
pub should_ignore_compression: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Recorder {
|
||||||
|
pub fn new(path: String, server: String, should_ignore_compression: bool) -> Result<Self> {
|
||||||
|
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::<u32>::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::<u32>::try_into(raw_packet.len())?.to_be_bytes());
|
||||||
|
data.extend(raw_packet);
|
||||||
|
self.zip_writer.write_all(&data)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save_packet<T: ProtocolPacket>(&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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user