diff --git a/Cargo.lock b/Cargo.lock index 45cbe51..7f5bcaf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -110,7 +110,7 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "asset-tool" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index 131bdda..a51cd1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ workspace = { members = ["rbx_asset", "rox_compiler"] } [package] name = "asset-tool" -version = "0.4.1" +version = "0.4.2" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/main.rs b/src/main.rs index e356e80..7e7b636 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,9 @@ enum Commands{ DownloadDecompile(DownloadDecompileSubcommand), DownloadGroupInventoryJson(DownloadGroupInventoryJsonSubcommand), CreateAsset(CreateAssetSubcommand), + CreateAssetMedia(CreateAssetMediaSubcommand), UploadAsset(UpdateAssetSubcommand), + UploadAssetMedia(UpdateAssetMediaSubcommand), UploadPlace(UpdatePlaceSubcommand), Compile(CompileSubcommand), CompileUploadAsset(CompileUploadAssetSubcommand), @@ -82,6 +84,27 @@ struct DownloadGroupInventoryJsonSubcommand{ } #[derive(Args)] struct CreateAssetSubcommand{ + #[arg(long,group="cookie",required=true)] + cookie_literal:Option, + #[arg(long,group="cookie",required=true)] + cookie_envvar:Option, + #[arg(long,group="cookie",required=true)] + cookie_file:Option, + #[arg(long)] + group_id:Option, + #[arg(long)] + input_file:PathBuf, + #[arg(long)] + model_name:String, + #[arg(long)] + description:Option, + #[arg(long)] + free_model:Option, + #[arg(long)] + allow_comments:Option, +} +#[derive(Args)] +struct CreateAssetMediaSubcommand{ #[arg(long,group="api_key",required=true)] api_key_literal:Option, #[arg(long,group="api_key",required=true)] @@ -95,12 +118,40 @@ struct CreateAssetSubcommand{ #[arg(long)] input_file:PathBuf, #[arg(long)] + asset_type:AssetType, + #[arg(long)] creator_user_id:u64, #[arg(long)] creator_group_id:Option, + /// Expected price limits how much robux can be spent to create the asset (defaults to 0) + #[arg(long)] + expected_price:Option, } #[derive(Args)] struct UpdateAssetSubcommand{ + #[arg(long)] + asset_id:AssetID, + #[arg(long,group="cookie",required=true)] + cookie_literal:Option, + #[arg(long,group="cookie",required=true)] + cookie_envvar:Option, + #[arg(long,group="cookie",required=true)] + cookie_file:Option, + #[arg(long)] + group_id:Option, + #[arg(long)] + input_file:PathBuf, + #[arg(long)] + change_name:Option, + #[arg(long)] + change_description:Option, + #[arg(long)] + change_free_model:Option, + #[arg(long)] + change_allow_comments:Option, +} +#[derive(Args)] +struct UpdateAssetMediaSubcommand{ #[arg(long)] asset_id:AssetID, #[arg(long,group="api_key",required=true)] @@ -270,6 +321,21 @@ impl Style{ } } } +#[derive(Clone,Copy,Debug,clap::ValueEnum)] +enum AssetType{ + Audio, + Decal, + Model, +} +impl AssetType{ + fn cloud(&self)->rbx_asset::cloud::AssetType{ + match self{ + AssetType::Audio=>rbx_asset::cloud::AssetType::Audio, + AssetType::Decal=>rbx_asset::cloud::AssetType::Decal, + AssetType::Model=>rbx_asset::cloud::AssetType::Model, + } + } +} #[tokio::main] async fn main()->AResult<()>{ @@ -326,7 +392,20 @@ async fn main()->AResult<()>{ subcommand.group, subcommand.output_folder.unwrap_or_else(||std::env::current_dir().unwrap()), ).await, - Commands::CreateAsset(subcommand)=>create(CreateConfig{ + Commands::CreateAsset(subcommand)=>create_asset(CreateAssetConfig{ + cookie:cookie_from_args( + subcommand.cookie_literal, + subcommand.cookie_envvar, + subcommand.cookie_file, + ).await?, + group:subcommand.group_id, + input_file:subcommand.input_file, + model_name:subcommand.model_name, + description:subcommand.description.unwrap_or_else(||String::with_capacity(0)), + free_model:subcommand.free_model.unwrap_or(false), + allow_comments:subcommand.allow_comments.unwrap_or(false), + }).await, + Commands::CreateAssetMedia(subcommand)=>create_asset_media(CreateAssetMediaConfig{ api_key:api_key_from_args( subcommand.api_key_literal, subcommand.api_key_envvar, @@ -335,10 +414,26 @@ async fn main()->AResult<()>{ creator_user_id:subcommand.creator_user_id, creator_group_id:subcommand.creator_group_id, input_file:subcommand.input_file, + asset_type:subcommand.asset_type.cloud(), model_name:subcommand.model_name, description:subcommand.description.unwrap_or_else(||String::with_capacity(0)), + expected_price:subcommand.expected_price, }).await, Commands::UploadAsset(subcommand)=>upload_asset(UploadAssetConfig{ + cookie:cookie_from_args( + subcommand.cookie_literal, + subcommand.cookie_envvar, + subcommand.cookie_file, + ).await?, + asset_id:subcommand.asset_id, + group_id:subcommand.group_id, + input_file:subcommand.input_file, + change_name:subcommand.change_name, + change_description:subcommand.change_description, + change_free_model:subcommand.change_free_model, + change_allow_comments:subcommand.change_allow_comments, + }).await, + Commands::UploadAssetMedia(subcommand)=>upload_asset_media(UploadAssetMediaConfig{ api_key:api_key_from_args( subcommand.api_key_literal, subcommand.api_key_envvar, @@ -441,20 +536,44 @@ async fn api_key_from_args(literal:Option,environment:Option,fil Ok(ApiKey::new(api_key)) } -struct CreateConfig{ +struct CreateAssetConfig{ + cookie:Cookie, + model_name:String, + description:String, + input_file:PathBuf, + group:Option, + free_model:bool, + allow_comments:bool, +} + +async fn create_asset(config:CreateAssetConfig)->AResult<()>{ + let resp=CookieContext::new(config.cookie) + .create(rbx_asset::cookie::CreateRequest{ + name:config.model_name, + description:config.description, + ispublic:config.free_model, + allowComments:config.allow_comments, + groupId:config.group, + },tokio::fs::read(config.input_file).await?).await?; + println!("UploadResponse={:?}",resp); + Ok(()) +} + +struct CreateAssetMediaConfig{ api_key:ApiKey, + asset_type:rbx_asset::cloud::AssetType, model_name:String, description:String, input_file:PathBuf, creator_user_id:u64, creator_group_id:Option, + expected_price:Option, } -///This is hardcoded to create models atm -async fn create(config:CreateConfig)->AResult<()>{ +async fn create_asset_media(config:CreateAssetMediaConfig)->AResult<()>{ let resp=CloudContext::new(config.api_key) .create_asset(rbx_asset::cloud::CreateAssetRequest{ - assetType:rbx_asset::cloud::AssetType::Model, + assetType:config.asset_type, displayName:config.model_name, description:config.description, creationContext:rbx_asset::cloud::CreationContext{ @@ -462,7 +581,7 @@ async fn create(config:CreateConfig)->AResult<()>{ userId:config.creator_user_id, groupId:config.creator_group_id.unwrap_or(0), }, - expectedPrice:0, + expectedPrice:config.expected_price.unwrap_or(0), } },tokio::fs::read(config.input_file).await?).await?; println!("CreateResponse={:?}",resp); @@ -470,11 +589,35 @@ async fn create(config:CreateConfig)->AResult<()>{ } struct UploadAssetConfig{ + cookie:Cookie, + asset_id:AssetID, + change_name:Option, + change_description:Option, + change_free_model:Option, + change_allow_comments:Option, + group_id:Option, + input_file:PathBuf, +} +async fn upload_asset(config:UploadAssetConfig)->AResult<()>{ + let context=CookieContext::new(config.cookie); + let resp=context.upload(rbx_asset::cookie::UploadRequest{ + assetid:config.asset_id, + name:config.change_name, + description:config.change_description, + ispublic:config.change_free_model, + allowComments:config.change_allow_comments, + groupId:config.group_id, + },tokio::fs::read(config.input_file).await?).await?; + println!("UploadResponse={:?}",resp); + Ok(()) +} + +struct UploadAssetMediaConfig{ api_key:ApiKey, asset_id:u64, input_file:PathBuf, } -async fn upload_asset(config:UploadAssetConfig)->AResult<()>{ +async fn upload_asset_media(config:UploadAssetMediaConfig)->AResult<()>{ let context=CloudContext::new(config.api_key); let resp=context.update_asset(rbx_asset::cloud::UpdateAssetRequest{ assetId:config.asset_id,