Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
cedabe8482
|
|||
|
11a6b8ed79
|
116
Cargo.lock
generated
116
Cargo.lock
generated
@@ -54,12 +54,36 @@ version = "1.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
"libc",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.31"
|
||||
@@ -149,6 +173,18 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.14.0"
|
||||
@@ -158,6 +194,22 @@ dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.182"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
@@ -182,6 +234,12 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.103"
|
||||
@@ -200,6 +258,18 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.11"
|
||||
@@ -209,12 +279,11 @@ checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
|
||||
[[package]]
|
||||
name = "strafesnet_roblox_bot_file"
|
||||
version = "0.8.1"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "33d0fa524476d8b6cf23269b0c9cff6334b70585546b807cb8ec193858defecd"
|
||||
dependencies = [
|
||||
"binrw",
|
||||
"bitflags",
|
||||
"itertools",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -265,3 +334,46 @@ name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.2+wasi-0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
|
||||
dependencies = [
|
||||
"zstd-safe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-safe"
|
||||
version = "7.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"
|
||||
dependencies = [
|
||||
"zstd-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-sys"
|
||||
version = "2.0.16+zstd.1.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
@@ -5,6 +5,6 @@ edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.31"
|
||||
strafesnet_roblox_bot_file = { version = "0.8.1", 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"] }
|
||||
|
||||
110
src/main.rs
110
src/main.rs
@@ -1,6 +1,6 @@
|
||||
use strafesnet_roblox_bot_file::v0;
|
||||
use strafesnet_roblox_bot_file::{v0,v1};
|
||||
|
||||
use std::path::{Path,PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use futures::{StreamExt,TryStreamExt};
|
||||
|
||||
#[expect(dead_code)]
|
||||
@@ -40,42 +40,65 @@ async fn main()->Result<(),Error>{
|
||||
return Err(Error::InvalidArgs);
|
||||
};
|
||||
|
||||
const ONE_SECOND:u64=1<<32;
|
||||
#[derive(Default)]
|
||||
#[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,
|
||||
jumps:u64,
|
||||
duration:u64,
|
||||
settings:u64,
|
||||
outliers:Vec<PathBuf>,
|
||||
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{
|
||||
write!(f,"count={} jumps={} duration={:.3} settings={}",self.count,self.jumps,self.duration as f64/(ONE_SECOND as f64),self.settings)
|
||||
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 accumulate(&mut self,path:&Path,block:&v0::Block){
|
||||
if let (Some(first),Some(last))=(block.output_events.first(),block.output_events.last()){
|
||||
let last=last.time*ONE_SECOND as f64;
|
||||
let first=first.time*ONE_SECOND as f64;
|
||||
let duration=last as u64-first as u64;
|
||||
if 30000*ONE_SECOND<duration{
|
||||
self.outliers.push(path.to_owned());
|
||||
return;
|
||||
}
|
||||
self.duration+=duration;
|
||||
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;
|
||||
self.jumps+=block.sound_events.iter()
|
||||
.filter(|event|event.event.sound_type==v0::SoundType::JumpGround)
|
||||
.count() as u64;
|
||||
// find settings events after run has started
|
||||
if let Some(run_start)=block.run_events.iter().find(|event|matches!(event.event,v0::RunEvent::Start(_))){
|
||||
self.settings+=block.setting_events.iter()
|
||||
.filter(|event|run_start.time<event.time)
|
||||
.count() as u64;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,23 +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(RoundTripError::Decode)?;
|
||||
let mut data=Vec::with_capacity(file.len()+1024);
|
||||
v0::serialize(&block,&mut std::io::Cursor::new(&mut data)).map_err(RoundTripError::Encode)?;
|
||||
let block_rt=v0::read_all_to_block(std::io::Cursor::new(data)).map_err(RoundTripError::RoundTripDecode)?;
|
||||
if !(
|
||||
block_rt.input_events.len()==block.input_events.len()&&
|
||||
block_rt.output_events.len()==block.output_events.len()&&
|
||||
block_rt.sound_events.len()==block.sound_events.len()&&
|
||||
block_rt.world_events.len()==block.world_events.len()&&
|
||||
block_rt.gravity_events.len()==block.gravity_events.len()&&
|
||||
block_rt.run_events.len()==block.run_events.len()&&
|
||||
block_rt.camera_events.len()==block.camera_events.len()&&
|
||||
block_rt.setting_events.len()==block.setting_events.len()
|
||||
){
|
||||
return Err(RoundTripError::NotEqual);
|
||||
}
|
||||
Ok(block)
|
||||
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}),
|
||||
@@ -115,14 +128,11 @@ async fn main()->Result<(),Error>{
|
||||
}
|
||||
})
|
||||
.buffer_unordered(available_parallelism)
|
||||
.try_fold(FoldState::default(),async|mut state,(path,block)|{
|
||||
state.accumulate(&path,&block);
|
||||
.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?;
|
||||
for path in &tally.outliers{
|
||||
println!("outlier: {:?}",path.file_name());
|
||||
}
|
||||
println!("{}",tally);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user