4 Commits

Author SHA1 Message Date
1f8a66638f rewrite get_full_name function 2025-03-27 12:20:29 -07:00
0995ced783 skip non-files (directories) 2025-02-12 13:47:59 -08:00
49d071fd56 move writeattributes to map fixer 2025-01-27 07:06:24 -08:00
d9a39cc046 print output on failure 2024-12-23 19:53:08 -08:00

@ -19,6 +19,7 @@ enum Commands {
Replace,
Scan,
Upload,
WriteAttributes,
}
#[derive(Args)]
@ -39,6 +40,7 @@ fn main() -> AResult<()> {
Commands::Replace=>replace(),
Commands::Scan=>scan(),
Commands::Upload=>upload(),
Commands::WriteAttributes=>write_attributes(),
}
}
@ -64,15 +66,16 @@ fn recursive_collect_superclass(objects: &mut std::vec::Vec<rbx_dom_weak::types:
}
}
}
fn get_full_name(dom:&rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance) -> String{
let mut full_name=instance.name.clone();
let mut pref=instance.parent();
while let Some(parent)=dom.get_by_ref(pref){
full_name.insert(0, '.');
full_name.insert_str(0, &parent.name);
pref=parent.parent();
}
full_name
fn get_full_name(dom:&rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance)->String{
let mut names:Vec<_>=core::iter::successors(
Some(instance),
|i|dom.get_by_ref(i.parent())
).map(
|i|i.name.as_str()
).collect();
names.reverse();
names.join(".")
}
//scan (scripts)
@ -374,6 +377,10 @@ fn upload() -> AResult<()>{
//interactive prompt per upload:
for entry in std::fs::read_dir("maps/passed")? {
let file_thing=entry?;
if !file_thing.file_type()?.is_file(){
println!("skipping non-file: {:?}",file_thing.file_name());
continue;
}
println!("map file: {:?}",file_thing.file_name());
let mut input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?);
@ -397,7 +404,7 @@ fn upload() -> AResult<()>{
}
match upload_action {
UploadAction::Upload(asset_id) => {
let status=std::process::Command::new("asset-tool")
let output=std::process::Command::new("asset-tool")
.args([
"upload-asset",
"--cookie-envvar","RBXCOOKIE",
@ -405,16 +412,17 @@ fn upload() -> AResult<()>{
])
.arg("--asset-id").arg(asset_id.to_string())
.arg("--input-file").arg(file_thing.path().into_os_string().into_string().unwrap())
.status()?;
match status.code() {
.output()?;
match output.status.code() {
Some(0)=>{
//move file
let mut dest=PathBuf::from("maps/uploaded");
dest.push(file_thing.file_name());
std::fs::rename(file_thing.path(), dest)?;
}
Some(code)=>println!("upload failed! code={}",code),
None => println!("no status code!"),
other=>{
println!("upload failed! code={:?}\noutput={}\nerr={}",other,String::from_utf8_lossy(&output.stdout),String::from_utf8_lossy(&output.stderr));
},
}
}
UploadAction::Skip => continue,
@ -436,9 +444,10 @@ fn upload() -> AResult<()>{
let mut dest=PathBuf::from("maps/uploaded");
dest.push(file_thing.file_name());
std::fs::rename(file_thing.path(), dest)?;
}
Some(code)=>println!("upload failed! code={}",code),
None => println!("no status code!"),
},
other=>{
println!("upload failed! code={:?}\noutput={}\nerr={}",other,String::from_utf8_lossy(&output.stdout),String::from_utf8_lossy(&output.stderr));
},
}
}
UploadAction::Delete => std::fs::remove_file(file_thing.path())?,
@ -753,3 +762,65 @@ fn interactive() -> AResult<()>{
std::fs::write("id",id.to_string())?;
Ok(())
}
fn recursive_collect_regex(objects: &mut std::vec::Vec<rbx_dom_weak::types::Ref>,dom: &rbx_dom_weak::WeakDom, instance: &rbx_dom_weak::Instance, regex: &lazy_regex::Lazy<lazy_regex::Regex>){
for &referent in instance.children() {
if let Some(c) = dom.get_by_ref(referent) {
if regex.captures(c.name.as_str()).is_some(){
objects.push(c.referent());//copy ref
}
recursive_collect_regex(objects,dom,c,regex);
}
}
}
fn get_button_refs(dom:&rbx_dom_weak::WeakDom) -> Vec<rbx_dom_weak::types::Ref>{
let mut buttons = std::vec::Vec::new();
recursive_collect_regex(&mut buttons, dom, dom.root(),lazy_regex::regex!(r"Button(\d+)$"));
buttons
}
fn write_attributes() -> AResult<()>{
for entry in std::fs::read_dir("maps/unprocessed")? {
let file_thing=entry?;
println!("processing map={:?}",file_thing.file_name());
let mut input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?);
let mut dom = load_dom(&mut input)?;
let button_refs = get_button_refs(&dom);
for &button_ref in &button_refs {
if let Some(button)=dom.get_by_ref_mut(button_ref){
match button.properties.get_mut("Attributes"){
Some(rbx_dom_weak::types::Variant::Attributes(attributes))=>{
println!("Appending Ref={} to existing attributes for {}",button_ref,button.name);
attributes.insert("Ref".to_string(),rbx_dom_weak::types::Variant::String(button_ref.to_string()));
},
None=>{
println!("Creating new attributes with Ref={} for {}",button_ref,button.name);
let mut attributes=rbx_dom_weak::types::Attributes::new();
attributes.insert("Ref".to_string(),rbx_dom_weak::types::Variant::String(button_ref.to_string()));
button.properties.insert("Attributes".to_string(),rbx_dom_weak::types::Variant::Attributes(attributes));
}
_=>unreachable!("Fetching attributes did not return attributes."),
}
}
}
let mut dest={
let mut dest=PathBuf::from("maps/attributes");
dest.push(file_thing.file_name());
let output = std::io::BufWriter::new(std::fs::File::create(dest)?);
//write workspace:GetChildren()[1]
let workspace_children=dom.root().children();
if workspace_children.len()!=1{
return Err(anyhow::Error::msg("there can only be one model"));
}
rbx_binary::to_writer(output, &dom, &[workspace_children[0]])?;
//move original to processed folder
PathBuf::from("maps/unaltered")
};
dest.push(file_thing.file_name());
std::fs::rename(file_thing.path(), dest)?;
}
Ok(())
}