add download textures command
This commit is contained in:
parent
19a455ee5e
commit
34b6a869f0
45
Cargo.lock
generated
45
Cargo.lock
generated
@ -2,6 +2,15 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.5.0"
|
||||
@ -270,8 +279,15 @@ dependencies = [
|
||||
"rbx_binary",
|
||||
"rbx_dom_weak",
|
||||
"rbx_reflection_database",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.16"
|
||||
@ -423,6 +439,35 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
|
||||
[[package]]
|
||||
name = "rmp"
|
||||
version = "0.8.12"
|
||||
|
@ -10,6 +10,7 @@ clap = { version = "4.4.2", features = ["derive"] }
|
||||
rbx_binary = "0.7.1"
|
||||
rbx_dom_weak = "2.5.0"
|
||||
rbx_reflection_database = "0.2.7"
|
||||
regex = "1.9.5"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
96
src/main.rs
96
src/main.rs
@ -19,6 +19,7 @@ struct Cli {
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
Download(MapList),
|
||||
DownloadTextures(PathBufList),
|
||||
Upload,
|
||||
Scan,
|
||||
Extract(PathBufList),
|
||||
@ -92,6 +93,14 @@ fn get_script_refs(dom:&rbx_dom_weak::WeakDom) -> Vec<rbx_dom_weak::types::Ref>{
|
||||
recursive_collect_superclass(&mut scripts, dom, dom.root(),"LuaSourceContainer");
|
||||
scripts
|
||||
}
|
||||
fn get_texture_refs(dom:&rbx_dom_weak::WeakDom) -> Vec<rbx_dom_weak::types::Ref>{
|
||||
let mut objects = std::vec::Vec::new();
|
||||
recursive_collect_superclass(&mut objects, dom, dom.root(),"Decal");
|
||||
//get ids
|
||||
//clear vec
|
||||
//next class
|
||||
objects
|
||||
}
|
||||
|
||||
fn get_id() -> BoxResult<u32>{
|
||||
match std::fs::read_to_string("id"){
|
||||
@ -196,6 +205,92 @@ fn download(map_list: Vec<u64>) -> BoxResult<()>{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct RobloxAssetId(u64);
|
||||
struct RobloxAssetIdParseErr;
|
||||
impl std::str::FromStr for RobloxAssetId {
|
||||
type Err=RobloxAssetIdParseErr;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err>{
|
||||
let regman=regex::Regex::new(r"(\d+)$").unwrap();
|
||||
if let Some(captures) = regman.captures(s) {
|
||||
if captures.len()==2{//captures[0] is all captures concatenated, and then each individual capture
|
||||
if let Ok(id) = captures[0].parse::<u64>() {
|
||||
return Ok(Self(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(RobloxAssetIdParseErr)
|
||||
}
|
||||
}
|
||||
/* The ones I'm interested in:
|
||||
Beam.Texture
|
||||
Decal.Texture
|
||||
FileMesh.MeshId
|
||||
FileMesh.TextureId
|
||||
MaterialVariant.ColorMap
|
||||
MaterialVariant.MetalnessMap
|
||||
MaterialVariant.NormalMap
|
||||
MaterialVariant.RoughnessMap
|
||||
MeshPart.MeshId
|
||||
MeshPart.TextureID
|
||||
ParticleEmitter.Texture
|
||||
Sky.MoonTextureId
|
||||
Sky.SkyboxBk
|
||||
Sky.SkyboxDn
|
||||
Sky.SkyboxFt
|
||||
Sky.SkyboxLf
|
||||
Sky.SkyboxRt
|
||||
Sky.SkyboxUp
|
||||
Sky.SunTextureId
|
||||
SurfaceAppearance.ColorMap
|
||||
SurfaceAppearance.MetalnessMap
|
||||
SurfaceAppearance.NormalMap
|
||||
SurfaceAppearance.RoughnessMap
|
||||
SurfaceAppearance.TexturePack
|
||||
*/
|
||||
fn download_textures(paths: Vec<std::path::PathBuf>) -> BoxResult<()>{
|
||||
println!("download_textures paths:{:?}",paths);
|
||||
let header=format!("Cookie: .ROBLOSECURITY={}",std::env::var("RBXCOOKIE")?);
|
||||
let shared_args=&[
|
||||
"-q",
|
||||
"--header",
|
||||
header.as_str(),
|
||||
"-O",
|
||||
];
|
||||
let mut texture_list=std::collections::HashSet::new();
|
||||
for path in paths {
|
||||
let input = std::io::BufReader::new(std::fs::File::open(path)?);
|
||||
|
||||
let dom = rbx_binary::from_reader(input)?;
|
||||
|
||||
let object_refs = get_texture_refs(&dom);
|
||||
|
||||
for &object_ref in object_refs.iter() {
|
||||
if let Some(object)=dom.get_by_ref(object_ref){
|
||||
if let Some(rbx_dom_weak::types::Variant::Content(content)) = object.properties.get("Texture") {
|
||||
println!("Texture content:{:?}",content);
|
||||
if let Ok(asset_id)=content.clone().into_string().parse::<RobloxAssetId>(){
|
||||
texture_list.insert(asset_id.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("Texture list:{:?}",texture_list);
|
||||
let processes_result:Result<Vec<_>, _>=texture_list.iter().map(|asset_id|{
|
||||
std::process::Command::new("wget")
|
||||
.args(shared_args)
|
||||
.arg(format!("textures/{}",asset_id))
|
||||
.arg(format!("https://assetdelivery.roblox.com/v1/asset/?ID={}",asset_id))
|
||||
.spawn()
|
||||
}).collect();
|
||||
//naively wait for all because idk how to make an async progress bar lmao
|
||||
for child in processes_result?{
|
||||
let output=child.wait_with_output()?;
|
||||
println!("texture exit_success:{}",output.status.success());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
enum Scan{
|
||||
Passed,
|
||||
Blocked,
|
||||
@ -651,6 +746,7 @@ fn main() -> BoxResult<()> {
|
||||
let cli = Cli::parse();
|
||||
match cli.command {
|
||||
Commands::Download(map_list)=>download(map_list.maps),
|
||||
Commands::DownloadTextures(pathlist)=>download_textures(pathlist.paths),
|
||||
Commands::Upload=>upload(),
|
||||
Commands::Scan=>scan(),
|
||||
Commands::Replace=>replace(),
|
||||
|
Loading…
Reference in New Issue
Block a user