//! Exercises the real deploy chain end to end: resolve, manifest, download, //! checksum, extract. Run manually; it talks to Roblox's servers. use nox_roblox::deploy::{install_package, latest, manifest, Binary, Event}; use std::time::Instant; fn main() { let channel = std::env::args().nth(1).unwrap_or_else(|| "LIVE".into()); println!("http backend: {}", nox_net::backend_name()); let t = Instant::now(); let v = match latest(Binary::Player, &channel) { Ok(v) => v, Err(e) => { eprintln!("resolve failed: {e}"); std::process::exit(1); } }; println!("resolved in {:?}", t.elapsed()); println!(" version {}", v.version); println!(" upload {}", v.upload); let t = Instant::now(); let m = match manifest(&v.upload, &channel) { Ok(m) => m, Err(e) => { eprintln!("manifest failed: {e}"); std::process::exit(1); } }; let list = m.installable(); println!( "manifest in {:?}: {} packages, {} installable, {:.1} MB packed, {:.1} MB unpacked", t.elapsed(), m.packages.len(), list.len(), m.total_packed() as f64 / 1e6, m.total_unpacked() as f64 / 1e6 ); for p in m.packages.iter() { let dest = nox_roblox::package_dir(&p.name).unwrap_or(""); println!(" {:<40} {:>10} -> {}", p.name, p.packed, dest); } let smallest = list.iter().min_by_key(|p| p.packed).expect("packages"); println!("\ndownloading smallest package: {} ({} bytes)", smallest.name, smallest.packed); let dir = std::env::temp_dir().join("nox-livecheck"); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).unwrap(); let t = Instant::now(); let mut last = 0u64; let mut sink = |e: Event| { if let Event::PackageBytes { done, total } = e { if done - last > 200_000 { last = done; println!(" {done} / {total}"); } } true }; match install_package(&v.upload, &channel, smallest, &dir, &mut sink) { Ok(files) => { println!("verified md5 and extracted {files} files in {:?}", t.elapsed()); let sub = nox_roblox::package_dir(&smallest.name).unwrap(); let target = if sub.is_empty() { dir.clone() } else { dir.join(sub.trim_end_matches('/')) }; println!("into {}", target.display()); let mut shown = 0; let mut stack = vec![target.clone()]; while let Some(d) = stack.pop() { let Ok(rd) = std::fs::read_dir(&d) else { continue }; for e in rd.flatten() { if e.path().is_dir() { stack.push(e.path()); } else if shown < 8 { shown += 1; let rel = e.path().strip_prefix(&target).unwrap().to_path_buf(); println!(" {} ({} bytes)", rel.display(), e.metadata().map(|m| m.len()).unwrap_or(0)); } } } println!("total on disk: {} bytes", nox_roblox::deploy::directory_size(&dir)); } Err(e) => { eprintln!("install failed: {e}"); std::process::exit(1); } } }