mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-20 20:55:50 +00:00
Add support for uploading models, rename place_id to asset_id
This commit is contained in:
@@ -60,5 +60,5 @@ You'll need an existing place on Roblox.com as well as the `.ROBLOSECURITY` cook
|
|||||||
Generating and uploading your place file is as simple as:
|
Generating and uploading your place file is as simple as:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
rojo upload --place_id [PLACE ID] --cookie "[SECURITY COOKIE]"
|
rojo upload --asset_id [PLACE ID] --cookie "[SECURITY COOKIE]"
|
||||||
```
|
```
|
||||||
@@ -48,10 +48,11 @@ fn main() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
(@subcommand upload =>
|
(@subcommand upload =>
|
||||||
(about: "Generates a place file out of the project and uploads it to Roblox.")
|
(about: "Generates a place or model file out of the project and uploads it to Roblox.")
|
||||||
(@arg PROJECT: "Path to the project to upload. Defaults to the current directory.")
|
(@arg PROJECT: "Path to the project to upload. Defaults to the current directory.")
|
||||||
|
(@arg kind: --kind +takes_value "The kind of asset to generate, 'place', or 'model'. Defaults to place.")
|
||||||
(@arg cookie: --cookie +takes_value +required "Security cookie to authenticate with.")
|
(@arg cookie: --cookie +takes_value +required "Security cookie to authenticate with.")
|
||||||
(@arg place_id: --place_id +takes_value +required "Place ID to upload to.")
|
(@arg asset_id: --asset_id +takes_value +required "Asset ID to upload to.")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -134,10 +135,11 @@ fn main() {
|
|||||||
None => std::env::current_dir().unwrap(),
|
None => std::env::current_dir().unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let kind = sub_matches.value_of("kind");
|
||||||
let security_cookie = sub_matches.value_of("cookie").unwrap();
|
let security_cookie = sub_matches.value_of("cookie").unwrap();
|
||||||
|
|
||||||
let place_id: u64 = {
|
let asset_id: u64 = {
|
||||||
let arg = sub_matches.value_of("place_id").unwrap();
|
let arg = sub_matches.value_of("asset_id").unwrap();
|
||||||
|
|
||||||
match arg.parse() {
|
match arg.parse() {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
@@ -151,7 +153,8 @@ fn main() {
|
|||||||
let options = commands::UploadOptions {
|
let options = commands::UploadOptions {
|
||||||
fuzzy_project_path,
|
fuzzy_project_path,
|
||||||
security_cookie: security_cookie.to_string(),
|
security_cookie: security_cookie.to_string(),
|
||||||
place_id,
|
asset_id,
|
||||||
|
kind,
|
||||||
};
|
};
|
||||||
|
|
||||||
match commands::upload(&options) {
|
match commands::upload(&options) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::{
|
|||||||
|
|
||||||
use failure::Fail;
|
use failure::Fail;
|
||||||
|
|
||||||
use reqwest::header::{USER_AGENT, CONTENT_TYPE, COOKIE};
|
use reqwest::header::{ACCEPT, USER_AGENT, CONTENT_TYPE, COOKIE};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
rbx_session::construct_oneoff_tree,
|
rbx_session::construct_oneoff_tree,
|
||||||
@@ -18,6 +18,9 @@ pub enum UploadError {
|
|||||||
#[fail(display = "Roblox API Error: {}", _0)]
|
#[fail(display = "Roblox API Error: {}", _0)]
|
||||||
RobloxApiError(String),
|
RobloxApiError(String),
|
||||||
|
|
||||||
|
#[fail(display = "Invalid asset kind: {}", _0)]
|
||||||
|
InvalidKind(String),
|
||||||
|
|
||||||
#[fail(display = "Project load error: {}", _0)]
|
#[fail(display = "Project load error: {}", _0)]
|
||||||
ProjectLoadError(#[fail(cause)] ProjectLoadFuzzyError),
|
ProjectLoadError(#[fail(cause)] ProjectLoadFuzzyError),
|
||||||
|
|
||||||
@@ -47,14 +50,14 @@ impl From<reqwest::Error> for UploadError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UploadOptions {
|
pub struct UploadOptions<'a> {
|
||||||
pub fuzzy_project_path: PathBuf,
|
pub fuzzy_project_path: PathBuf,
|
||||||
pub security_cookie: String,
|
pub security_cookie: String,
|
||||||
pub place_id: u64,
|
pub asset_id: u64,
|
||||||
|
pub kind: Option<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upload(options: &UploadOptions) -> Result<(), UploadError> {
|
pub fn upload(options: &UploadOptions) -> Result<(), UploadError> {
|
||||||
// TODO: Support uploading models too
|
|
||||||
// TODO: Switch to uploading binary format?
|
// TODO: Switch to uploading binary format?
|
||||||
|
|
||||||
info!("Looking for project at {}", options.fuzzy_project_path.display());
|
info!("Looking for project at {}", options.fuzzy_project_path.display());
|
||||||
@@ -69,11 +72,20 @@ pub fn upload(options: &UploadOptions) -> Result<(), UploadError> {
|
|||||||
let tree = construct_oneoff_tree(&project, &imfs);
|
let tree = construct_oneoff_tree(&project, &imfs);
|
||||||
|
|
||||||
let root_id = tree.get_root_id();
|
let root_id = tree.get_root_id();
|
||||||
let top_level_ids = tree.get_instance(root_id).unwrap().get_children_ids();
|
|
||||||
let mut contents = Vec::new();
|
let mut contents = Vec::new();
|
||||||
rbx_xml::encode(&tree, top_level_ids, &mut contents);
|
|
||||||
|
|
||||||
let url = format!("https://data.roblox.com/Data/Upload.ashx?json=1&type=Place&assetid={}", options.place_id);
|
match options.kind {
|
||||||
|
Some("place") | None => {
|
||||||
|
let top_level_ids = tree.get_instance(root_id).unwrap().get_children_ids();
|
||||||
|
rbx_xml::encode(&tree, top_level_ids, &mut contents);
|
||||||
|
},
|
||||||
|
Some("model") => {
|
||||||
|
rbx_xml::encode(&tree, &[root_id], &mut contents);
|
||||||
|
},
|
||||||
|
Some(invalid) => return Err(UploadError::InvalidKind(invalid.to_owned())),
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = format!("https://data.roblox.com/Data/Upload.ashx?assetid={}", options.asset_id);
|
||||||
|
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
let mut response = client.post(&url)
|
let mut response = client.post(&url)
|
||||||
@@ -81,6 +93,7 @@ pub fn upload(options: &UploadOptions) -> Result<(), UploadError> {
|
|||||||
.header(USER_AGENT, "Roblox/WinInet")
|
.header(USER_AGENT, "Roblox/WinInet")
|
||||||
.header("Requester", "Client")
|
.header("Requester", "Client")
|
||||||
.header(CONTENT_TYPE, "application/xml")
|
.header(CONTENT_TYPE, "application/xml")
|
||||||
|
.header(ACCEPT, "application/json")
|
||||||
.body(contents)
|
.body(contents)
|
||||||
.send()?;
|
.send()?;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user