2 Commits

Author SHA1 Message Date
cedabe8482 smoke test convert 2026-02-13 12:09:00 -08:00
11a6b8ed79 add bot file temp dep 2026-02-13 12:05:03 -08:00
3 changed files with 133 additions and 1171 deletions

1188
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,6 @@ edition = "2024"
[dependencies]
futures = "0.3.31"
strafesnet_common = { version = "0.8.7", registry = "strafesnet" }
strafesnet_roblox_bot_file = { version = "0.9.4", registry = "strafesnet" }
strafesnet_roblox_bot_player = { version = "0.4.0", registry = "strafesnet" }
strafesnet_roblox_bot_file = { path = "../roblox_bot_file", registry = "strafesnet" }
tokio = { version = "1.48.0", features = ["macros", "rt-multi-thread", "fs"] }
tokio-stream = { version = "0.1.17", features = ["fs"] }

View File

@@ -1,4 +1,4 @@
use strafesnet_roblox_bot_file::v0;
use strafesnet_roblox_bot_file::{v0,v1};
use std::path::PathBuf;
use futures::{StreamExt,TryStreamExt};
@@ -10,7 +10,7 @@ enum Error{
Io(std::io::Error),
BotFile{
path:PathBuf,
err:PlaybackError,
err:RoundTripError,
},
Join(tokio::task::JoinError),
}
@@ -26,9 +26,11 @@ impl From<tokio::task::JoinError> for Error{
}
#[expect(dead_code)]
#[derive(Debug)]
enum PlaybackError{
enum RoundTripError{
Decode(v0::Error),
Panic,
Encode(strafesnet_roblox_bot_file::BinrwError),
RoundTripDecode(v0::Error),
NotEqual,
}
#[tokio::main]
async fn main()->Result<(),Error>{
@@ -38,10 +40,66 @@ async fn main()->Result<(),Error>{
return Err(Error::InvalidArgs);
};
#[derive(Default)]
struct State{
#[derive(Clone,Copy)]
struct Ratio{
num:u64,
den:u64,
}
impl Ratio{
fn float(&self)->f32{
self.num as f32/self.den as f32
}
}
impl PartialEq for Ratio{
fn eq(&self,other:&Self)->bool{
(self.num*other.den).eq(&(other.num*self.den))
}
}
impl Eq for Ratio{}
impl PartialOrd for Ratio{
fn partial_cmp(&self,other:&Self)->Option<core::cmp::Ordering>{
(self.num*other.den).partial_cmp(&(other.num*self.den))
}
}
impl Ord for Ratio{
fn cmp(&self,other:&Self)->core::cmp::Ordering{
(self.num*other.den).cmp(&(other.num*self.den))
}
}
struct FoldState{
count:usize,
errors:Vec<(PathBuf,strafesnet_roblox_bot_player::bot::Error)>,
min_size_ratio:Ratio,
max_size_ratio:Ratio,
total_size_before:u64,
total_size_after:u64,
}
impl std::fmt::Display for FoldState{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
let count=self.count;
let min_size_ratio=self.min_size_ratio.float();
let max_size_ratio=self.max_size_ratio.float();
let total_size_before=self.total_size_before;
let total_size_after=self.total_size_after;
write!(f,"count={count} min_size_ratio={min_size_ratio:.02} max_size_ratio={max_size_ratio:.02} total_size_before={total_size_before:.02} total_size_after={total_size_after:.02}")
}
}
impl FoldState{
fn new()->Self{
FoldState{
count:0,
min_size_ratio:Ratio{num:u64::MAX,den:1},
max_size_ratio:Ratio{num:0,den:1},
total_size_before:0,
total_size_after:0,
}
}
fn accumulate(&mut self,size_before:u64,size_after:u64){
self.count+=1;
let ratio=Ratio{num:size_before,den:size_after};
self.min_size_ratio=self.min_size_ratio.min(ratio);
self.max_size_ratio=self.max_size_ratio.max(ratio);
}
}
let available_parallelism=std::thread::available_parallelism()?.get();
@@ -56,21 +114,13 @@ async fn main()->Result<(),Error>{
.map(|result:Result<_,Error>|async move{
let (path,file)=result?;
let result=tokio::task::spawn_blocking(move||{
let block=v0::read_all_to_block(std::io::Cursor::new(file.as_slice())).map_err(PlaybackError::Decode)?;
let bot=match strafesnet_roblox_bot_player::bot::CompleteBot::new(block){
Ok(bot)=>bot,
Err(e)=>return Ok(Some(e)),
};
let mut head=strafesnet_roblox_bot_player::head::PlaybackHead::new(&bot,strafesnet_common::session::Time::ZERO);
if let Err(e)=std::panic::catch_unwind(move||{
head.get_position_angles(&bot,strafesnet_common::session::Time::ZERO);
head.set_time(&bot,strafesnet_common::session::Time::ZERO,bot.duration().coerce());
head.get_position_angles(&bot,strafesnet_common::session::Time::ZERO);
}){
println!("{e:?}");
return Err(PlaybackError::Panic);
}
Ok(None)
let block_v0=v0::read_all_to_block(std::io::Cursor::new(file.as_slice())).map_err(RoundTripError::Decode)?;
let mut data=Vec::with_capacity(file.len());
let block_v1=strafesnet_roblox_bot_file::convert::from_v0(&block_v0);
v1::serialize(&block_v1,&mut std::io::Cursor::new(&mut data)).map_err(RoundTripError::Encode)?;
let size_before=file.len();
let size_after=data.len();
Ok((size_before,size_after))
}).await?;
match result{
Err(err)=>Err(Error::BotFile{path,err}),
@@ -78,21 +128,11 @@ async fn main()->Result<(),Error>{
}
})
.buffer_unordered(available_parallelism)
.try_fold(State::default(),async|mut state,(path,bot_error)|{
state.count+=1;
// state.accumulate(&path,&block);
match bot_error{
None=>println!("{:07} {:?}",state.count,path.file_name()),
Some(e)=>{
println!("{:07} {:?} {}",state.count,path.file_name(),e);
state.errors.push((path,e));
},
};
.try_fold(FoldState::new(),async|mut state,(path,(size_before,size_after))|{
state.accumulate(size_before as u64,size_after as u64);
println!("{:?} {}",path.file_name(),state);
Ok(state)
}).await?;
println!("{}",tally.count);
for (path,e) in tally.errors{
println!("error: {:?} {}",path.file_name(),e);
}
println!("{}",tally);
Ok(())
}