diff --git a/Cargo.lock b/Cargo.lock index 21d5f59..63b704b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.5" @@ -97,6 +112,7 @@ name = "asset-tool" version = "0.1.0" dependencies = [ "anyhow", + "chrono", "clap", "flate2", "futures", @@ -107,6 +123,8 @@ dependencies = [ "rbx_reflection_database", "rbx_xml", "reqwest", + "serde", + "serde_json", "tokio", ] @@ -201,6 +219,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.48.5", +] + [[package]] name = "clap" version = "4.4.12" @@ -600,6 +633,29 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.2.3" @@ -913,9 +969,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" dependencies = [ "unicode-ident", ] @@ -957,9 +1013,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1230,18 +1286,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", @@ -1250,9 +1306,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -1298,9 +1354,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.43" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -1629,6 +1685,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 1c4129c..08d604d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0.75" +chrono = { version = "0.4.31", features = ["serde"] } clap = { version = "4.4.2", features = ["derive"] } flate2 = "1.0.28" futures = "0.3.30" @@ -16,7 +17,9 @@ rbx_binary = "0.7.1" rbx_dom_weak = "2.5.0" rbx_reflection_database = "0.2.7" rbx_xml = "0.13.1" -reqwest = { version = "0.11.23", features = ["cookies"] } +reqwest = { version = "0.11.23", features = ["cookies", "json"] } +serde = { version = "1.0.194", features = ["derive"] } +serde_json = "1.0.111" tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread", "fs"] } [profile.release] diff --git a/src/main.rs b/src/main.rs index f0b00e1..3902700 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use std::io::{Read,Seek}; use clap::{Args,Parser,Subcommand}; use anyhow::Result as AResult; use futures::StreamExt; +use serde::Serialize; type AssetID=u64; type AssetIDFileMap=Vec<(AssetID,std::path::PathBuf)>; @@ -53,6 +54,24 @@ struct PathBufList{ paths:Vec } +#[derive(serde::Deserialize)] +struct VersionPage{ + previousPageCursor:Option, + nextPageCursor:Option, + data:Vec, +} +#[derive(serde::Deserialize,serde::Serialize)] +struct AssetVersion{ + Id:u64, + assetId:AssetID, + assetVersionNumber:u64, + creatorType:String, + creatorTargetId:u64, + creatingUniverseId:Option, + created:chrono::DateTime, + isPublished:bool, +} + #[tokio::main] async fn main()->AResult<()>{ let cli=Cli::parse(); @@ -68,18 +87,57 @@ async fn main()->AResult<()>{ let cookie=format!(".ROBLOSECURITY={}",match cookie_enum{ Cookie::Literal(s)=>s, Cookie::Environment(var)=>std::env::var(var)?, - Cookie::File(path)=>tokio::fs::read_to_string(path).await?, + Cookie::File(path)=>tokio::fs::read_to_string(path).await?.trim().to_string(), }); let group=match cli.group{ Some(group_id)=>Owner::Group(group_id), None=>Owner::User, }; + { + let client=reqwest::Client::new(); + let mut cursor:Option=None; + let mut asset_list=Vec::new(); + loop{ + let mut url=reqwest::Url::parse("https://develop.roblox.com/v1/assets/252877716/saved-versions")?; + //url borrow scope + { + let mut query=url.query_pairs_mut();//borrow here + //query.append_pair("sortOrder","Asc"); + //query.append_pair("limit","100"); + //query.append_pair("count","100"); + match &cursor{ + Some(next_page)=>{query.append_pair("cursor",next_page);} + None=>(), + } + } + println!("url={}",url); + let resp=client.get(url) + .header("Cookie",cookie.clone()) + .send().await?; + println!("resp:{:?}",resp); + match resp.json::().await{ + Ok(mut page)=>{ + asset_list.append(&mut page.data); + if page.nextPageCursor.is_none(){ + break; + } + cursor=page.nextPageCursor; + }, + Err(e)=>panic!("error: {}",e), + } + } + asset_list.sort_by(|a,b|a.assetVersionNumber.cmp(&b.assetVersionNumber)); + let mut path=std::path::PathBuf::new(); + path.set_file_name("versions.json"); + tokio::fs::write(path,serde_json::to_string(&asset_list)?).await?; + }; + Ok(()) - match cli.command{ - Commands::Download=>download_list(cookie,vec![cli.asset_id]).await, - Commands::Upload=>upload_list(cookie,group,vec![cli.asset_id]).await, - } + // match cli.command{ + // Commands::Download=>download_list(cookie,vec![cli.asset_id]).await, + // Commands::Upload=>upload_list(cookie,group,vec![cli.asset_id]).await, + // } } enum Owner{