diff --git a/CHANGELOG.md b/CHANGELOG.md index d6329f32..3b51a413 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Rojo Changelog ## Unreleased Changes +* Added support for the new Open Cloud API when uploading. ([#486]) ## [7.0.0] - December 10, 2021 * Fixed Rojo's interactions with properties enabled by FFlags that are not yet enabled. ([#493]) @@ -9,6 +10,7 @@ * Connection settings are now remembered when reconnecting in Roblox Studio. ([#500]) * Updated reflection database to Roblox v503. +[#486]: https://github.com/rojo-rbx/rojo/issues/486 [#430]: https://github.com/rojo-rbx/rojo/issues/430 [#493]: https://github.com/rojo-rbx/rojo/pull/493 [#500]: https://github.com/rojo-rbx/rojo/pull/500 @@ -475,4 +477,4 @@ This is a general maintenance release for the Rojo 0.5.x release series. * More robust syncing with a new reconciler ## [0.1.0](https://github.com/rojo-rbx/rojo/releases/tag/v0.1.0) (November 29, 2017) -* Initial release, functionally very similar to [rbxfs](https://github.com/LPGhatguy/rbxfs) \ No newline at end of file +* Initial release, functionally very similar to [rbxfs](https://github.com/LPGhatguy/rbxfs) diff --git a/src/cli/upload.rs b/src/cli/upload.rs index 8c862618..2006ac66 100644 --- a/src/cli/upload.rs +++ b/src/cli/upload.rs @@ -24,6 +24,14 @@ pub struct UploadCommand { #[structopt(long)] pub cookie: Option, + /// API key obtained from create.roblox.com/credentials. Rojo will use the Open Cloud API when this is provided. Only supports uploading to a place. + #[structopt(long = "api_key")] + pub api_key: Option, + + /// The Universe ID of the given place. Required when using the Open Cloud API. + #[structopt(long = "universe_id")] + pub universe_id: Option, + /// Asset ID to upload to. #[structopt(long = "asset_id")] pub asset_id: u64, @@ -33,10 +41,6 @@ impl UploadCommand { pub fn run(self) -> Result<(), anyhow::Error> { let project_path = resolve_path(&self.project); - let cookie = self.cookie.or_else(get_auth_cookie).context( - "Rojo could not find your Roblox auth cookie. Please pass one via --cookie.", - )?; - let vfs = Vfs::new_default(); let session = ServeSession::new(vfs, project_path)?; @@ -54,7 +58,36 @@ impl UploadCommand { log::trace!("Encoding binary model"); rbx_binary::to_writer(&mut buffer, tree.inner(), &encode_ids)?; - do_upload(buffer, self.asset_id, &cookie) + + match (self.cookie, self.api_key, self.universe_id) { + (cookie, None, universe) => { + // using legacy. notify if universe is provided. + if universe.is_some() { + log::warn!( + "--universe_id was provided but is ignored when using legacy upload" + ); + } + + let cookie = cookie.or_else(get_auth_cookie).context( + "Rojo could not find your Roblox auth cookie. Please pass one via --cookie.", + )?; + do_upload(buffer, self.asset_id, &cookie) + } + + (cookie, Some(api_key), Some(universe_id)) => { + // using open cloud. notify if cookie is provided. + if cookie.is_some() { + log::warn!("--cookie was provided but is ignored when using Open Cloud API"); + } + + do_upload_open_cloud(buffer, universe_id, self.asset_id, &api_key) + } + + (_, Some(_), None) => { + // API key is provided, universe id is not. + bail!("--universe_id must be provided to use the Open Cloud API"); + } + } } } @@ -125,3 +158,38 @@ fn do_upload(buffer: Vec, asset_id: u64, cookie: &str) -> anyhow::Result<()> Ok(()) } + +/// Implementation of do_upload that supports the new open cloud api. +/// see https://developer.roblox.com/en-us/articles/open-cloud +fn do_upload_open_cloud( + buffer: Vec, + universe_id: u64, + asset_id: u64, + api_key: &str, +) -> anyhow::Result<()> { + let url = format!( + "https://apis.roblox.com/universes/v1/{}/places/{}/versions?versionType=Published", + universe_id, asset_id + ); + + let client = reqwest::Client::new(); + + log::debug!("Uploading to Roblox..."); + let mut response = client + .post(&url) + .header("x-api-key", api_key) + .header(CONTENT_TYPE, "application/xml") + .header(ACCEPT, "application/json") + .body(buffer) + .send()?; + + let status = response.status(); + if !status.is_success() { + bail!( + "The Roblox API returned an unexpected error: {}", + response.text()? + ); + } + + Ok(()) +}