Compare commits

..

No commits in common. "34dc14d6b272247c29732f884502ea8b09946e2a" and "de5dbe600ae3ac03958add47d73f98ffc77e474c" have entirely different histories.

5 changed files with 23 additions and 18 deletions

1
Cargo.lock generated
View File

@ -1417,6 +1417,7 @@ dependencies = [
"ncr", "ncr",
"parking_lot", "parking_lot",
"serde_json", "serde_json",
"smallvec",
"tokio", "tokio",
"zip", "zip",
] ]

View File

@ -38,6 +38,7 @@ mlua = { version = "0", features = ["async", "luajit", "send"] }
ncr = { version = "0", features = ["cfb8", "ecb", "gcm"] } ncr = { version = "0", features = ["cfb8", "ecb", "gcm"] }
parking_lot = "0" parking_lot = "0"
serde_json = "1" serde_json = "1"
smallvec = { version = "1", features = ["write"] }
tokio = { version = "1", features = ["macros"] } tokio = { version = "1", features = ["macros"] }
zip = { version = "2", default-features = false, features = ["flate2"] } zip = { version = "2", default-features = false, features = ["flate2"] }

View File

@ -7,8 +7,8 @@ use std::path::PathBuf;
#[command(version = build_info::version_formatted())] #[command(version = build_info::version_formatted())]
pub struct Arguments { pub struct Arguments {
/// Path to Lua entry point /// Path to Lua entry point
#[arg(short, long, default_value = "errornowatcher.lua")] #[arg(short, long)]
pub script: PathBuf, pub script: Option<PathBuf>,
/// Code to execute after loading script /// Code to execute after loading script
#[arg(short, long)] #[arg(short, long)]

View File

@ -29,6 +29,7 @@ use std::{
collections::HashMap, collections::HashMap,
env, env,
fs::{OpenOptions, read_to_string}, fs::{OpenOptions, read_to_string},
path::PathBuf,
sync::Arc, sync::Arc,
}; };
@ -51,15 +52,16 @@ async fn main() -> anyhow::Result<()> {
console_subscriber::init(); console_subscriber::init();
let args = Arguments::parse(); let args = Arguments::parse();
let script_path = args.script.unwrap_or(PathBuf::from("errornowatcher.lua"));
let event_listeners = Arc::new(RwLock::new(HashMap::new())); let event_listeners = Arc::new(RwLock::new(HashMap::new()));
let lua = unsafe { Lua::unsafe_new() }; let lua = unsafe { Lua::unsafe_new() };
let globals = lua.globals(); let globals = lua.globals();
lua::register_globals(&lua, &globals, event_listeners.clone())?; lua::register_globals(&lua, &globals, event_listeners.clone())?;
globals.set("SCRIPT_PATH", &*args.script)?; globals.set("SCRIPT_PATH", &*script_path)?;
lua.load( lua.load(
read_to_string(&args.script) read_to_string(&script_path)
.with_context(|| format!("failed to read {}", args.script.display()))?, .with_context(|| format!("failed to read {}", script_path.display()))?,
) )
.exec()?; .exec()?;
if let Some(code) = args.exec { if let Some(code) = args.exec {

View File

@ -7,16 +7,17 @@ use azalea::{
}; };
use log::debug; use log::debug;
use serde_json::json; use serde_json::json;
use smallvec::SmallVec;
use std::{ use std::{
fs::File, fs::File,
io::{BufWriter, Write}, io::Write,
time::{Instant, SystemTime, UNIX_EPOCH}, time::{Instant, SystemTime, UNIX_EPOCH},
}; };
use zip::{ZipWriter, write::SimpleFileOptions}; use zip::{ZipWriter, write::SimpleFileOptions};
#[derive(Resource)] #[derive(Resource)]
pub struct Recorder { pub struct Recorder {
zip_writer: BufWriter<ZipWriter<File>>, zip_writer: ZipWriter<File>,
start: Instant, start: Instant,
server: String, server: String,
pub should_ignore_compression: bool, pub should_ignore_compression: bool,
@ -33,20 +34,20 @@ impl Recorder {
); );
zip_writer.start_file("recording.tmcpr", SimpleFileOptions::default())?; zip_writer.start_file("recording.tmcpr", SimpleFileOptions::default())?;
Ok(Self { Ok(Self {
zip_writer: BufWriter::new(zip_writer), zip_writer,
start: Instant::now(), start: Instant::now(),
server, server,
should_ignore_compression, should_ignore_compression,
}) })
} }
pub fn finish(self) -> Result<()> { pub fn finish(mut self) -> Result<()> {
debug!("finishing replay recording"); debug!("finishing replay recording");
let elapsed = self.start.elapsed().as_millis(); let elapsed = self.start.elapsed().as_millis();
let mut zip_writer = self.zip_writer.into_inner()?; self.zip_writer
zip_writer.start_file("metaData.json", SimpleFileOptions::default())?; .start_file("metaData.json", SimpleFileOptions::default())?;
zip_writer.write_all( self.zip_writer.write_all(
json!({ json!({
"singleplayer": false, "singleplayer": false,
"serverName": self.server, "serverName": self.server,
@ -61,23 +62,23 @@ impl Recorder {
.to_string() .to_string()
.as_bytes(), .as_bytes(),
)?; )?;
zip_writer.finish()?; self.zip_writer.finish()?;
debug!("finished replay recording"); debug!("finished replay recording");
Ok(()) Ok(())
} }
pub fn save_raw_packet(&mut self, raw_packet: &[u8]) -> Result<()> { pub fn save_raw_packet(&mut self, raw_packet: &[u8]) -> Result<()> {
let mut data = Vec::with_capacity(raw_packet.len() + 8); let mut data = SmallVec::<[u8; 128]>::with_capacity(raw_packet.len() + 8);
data.extend(TryInto::<u32>::try_into(self.start.elapsed().as_millis())?.to_be_bytes()); data.write_all(&TryInto::<u32>::try_into(self.start.elapsed().as_millis())?.to_be_bytes())?;
data.extend(TryInto::<u32>::try_into(raw_packet.len())?.to_be_bytes()); data.write_all(&TryInto::<u32>::try_into(raw_packet.len())?.to_be_bytes())?;
data.extend(raw_packet); data.write_all(raw_packet)?;
self.zip_writer.write_all(&data)?; self.zip_writer.write_all(&data)?;
Ok(()) Ok(())
} }
pub fn save_packet<T: ProtocolPacket>(&mut self, packet: &T) -> Result<()> { pub fn save_packet<T: ProtocolPacket>(&mut self, packet: &T) -> Result<()> {
let mut raw_packet = Vec::with_capacity(64); let mut raw_packet = SmallVec::<[u8; 128]>::new();
packet.id().azalea_write_var(&mut raw_packet)?; packet.id().azalea_write_var(&mut raw_packet)?;
packet.write(&mut raw_packet)?; packet.write(&mut raw_packet)?;
self.save_raw_packet(&raw_packet) self.save_raw_packet(&raw_packet)