diff --git a/src/main.rs b/src/main.rs index d67f5c8..fcbd543 100644 --- a/src/main.rs +++ b/src/main.rs @@ -121,20 +121,17 @@ enum Cookie{ File(std::path::PathBuf), } -enum ReaderType<'a,R:Read+Seek>{ - GZip(flate2::read::GzDecoder<&'a mut R>), - Raw(&'a mut R), +enum ReaderType{ + GZip(flate2::read::GzDecoder>), + Raw(std::io::BufReader), } -fn maybe_gzip_decode(input:&mut R)->AResult>{ - let mut first_2=[0u8;2]; - if let (Ok(()),Ok(()))=(std::io::Read::read_exact(input,&mut first_2),std::io::Seek::rewind(input)){ - match &first_2{ - b"\x1f\x8b"=>Ok(ReaderType::GZip(flate2::read::GzDecoder::new(input))), - _=>Ok(ReaderType::Raw(input)), - } - }else{ - Err(anyhow::Error::msg("failed to peek")) +fn maybe_gzip_decode(input:R)->AResult>{ + let mut buf=std::io::BufReader::new(input); + let peek=std::io::BufRead::fill_buf(&mut buf)?; + match &peek[0..2]{ + b"\x1f\x8b"=>Ok(ReaderType::GZip(flate2::read::GzDecoder::new(buf))), + _=>Ok(ReaderType::Raw(buf)), } } @@ -268,7 +265,7 @@ async fn get_version_history(client:&reqwest::Client,cookie:&str,asset_id:AssetI Ok(asset_list) } -async fn download_asset_version(client:&reqwest::Client,cookie:&str,asset_id_str:&str,asset_version_str:&str)->AResult{ +async fn download_asset_version(client:&reqwest::Client,cookie:&str,asset_id_str:&str,asset_version_str:&str)->AResult{ let mut url=reqwest::Url::parse("https://assetdelivery.roblox.com/v1/asset/")?; //url borrow scope { @@ -287,7 +284,7 @@ async fn download_asset_version(client:&reqwest::Client,cookie:&str,asset_id_str continue; } - return Ok(std::io::Cursor::new(resp.bytes().await?)); + return Ok(resp); } Err(anyhow::Error::msg("all requests failed")) } @@ -316,9 +313,8 @@ async fn download_history(config:DownloadHistoryConfig)->AResult<()>{ let asset_id_str=asset_id_string.as_str(); let output_folder=config.output_folder.clone(); async move{ - let mut readable=download_asset_version(client,cookie,asset_id_str,asset_version.assetVersionNumber.to_string().as_str()).await?; - - let contents=match maybe_gzip_decode(&mut readable)?{ + let resp=download_asset_version(client,cookie,asset_id_str,asset_version.assetVersionNumber.to_string().as_str()).await?; + let contents=match maybe_gzip_decode(std::io::Cursor::new(resp.bytes().await?))?{ ReaderType::GZip(readable)=>read_readable(readable)?, ReaderType::Raw(readable)=>read_readable(readable)?, }; @@ -344,21 +340,18 @@ async fn download_history(config:DownloadHistoryConfig)->AResult<()>{ Ok(()) } -fn load_dom(input:&mut R)->AResult{ - let mut first_8=[0u8;8]; - if let (Ok(()),Ok(()))=(std::io::Read::read_exact(input, &mut first_8),std::io::Seek::rewind(input)){ - match &first_8[0..4]{ - b"{ - match &first_8[4..8]{ - b"lox!"=>return rbx_binary::from_reader(input).map_err(anyhow::Error::msg), - b"lox "=>return rbx_xml::from_reader(input,rbx_xml::DecodeOptions::default()).map_err(anyhow::Error::msg), - other=>Err(anyhow::Error::msg(format!("Unknown Roblox file type {:?}",other))), - } - }, - _=>Err(anyhow::Error::msg("unsupported file type")), - } - }else{ - Err(anyhow::Error::msg("peek failed")) +fn load_dom(input:R)->AResult{ + let mut buf=std::io::BufReader::new(input); + let peek=std::io::BufRead::fill_buf(&mut buf)?; + match &peek[0..4]{ + b"{ + match &peek[4..8]{ + b"lox!"=>return rbx_binary::from_reader(buf).map_err(anyhow::Error::msg), + b"lox "=>return rbx_xml::from_reader_default(buf).map_err(anyhow::Error::msg), + other=>Err(anyhow::Error::msg(format!("Unknown Roblox file type {:?}",other))), + } + }, + _=>Err(anyhow::Error::msg("unsupported file type")), } } @@ -451,8 +444,8 @@ struct DecompiledContext{ tree_refs:std::collections::HashMap, } -fn generate_decompiled_context(mut input:R)->AResult{ - let dom=load_dom(&mut input)?; +fn generate_decompiled_context(input:R)->AResult{ + let dom=load_dom(input)?; let mut tree_refs=std::collections::HashMap::new(); tree_refs.insert(dom.root_ref(),TreeNode::new(