From e0e8744bfd93eafce36784f1ccb6c5c6cb2692f1 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 12 Sep 2023 16:41:24 -0700 Subject: [PATCH] interactive mode v1 --- src/main.rs | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 153 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index aa86a6f..f7cbc72 100644 --- a/src/main.rs +++ b/src/main.rs @@ -53,9 +53,9 @@ fn get_full_name(dom:&rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance) -> //scan (scripts) //iter maps/unprocessed //passing moves to maps/verified - //failing moves to maps/purgatory + //failing moves to maps/blocked //replace (edits & deletions) - //iter maps/purgatory + //iter maps/blocked //replace scripts and put in maps/unprocessed //upload //iter maps/verified @@ -193,7 +193,7 @@ fn scan() -> Result<(), Box>{ Scan::Passed => std::path::PathBuf::from("maps/processed"), Scan::Blocked => { println!("{:?} - {} {} not allowed.",file_thing.file_name(),fail_count,if fail_count==1 {"script"}else{"scripts"}); - std::path::PathBuf::from("maps/purgatory") + std::path::PathBuf::from("maps/blocked") } Scan::Flagged => std::path::PathBuf::from("maps/flagged") }; @@ -207,7 +207,7 @@ fn replace() -> Result<(), Box>{ let allowed_map=get_allowed_map()?; let replace_map=get_replace_map()?; - for entry in std::fs::read_dir("maps/purgatory")? { + for entry in std::fs::read_dir("maps/blocked")? { let file_thing=entry?; let input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?); @@ -266,8 +266,156 @@ fn upload() -> Result<(), Box>{ unimplemented!() } +enum Interactive{ + Passed, + Blocked, + Flagged, + ReplaceFailed, +} +enum ScriptAction { + Pass, + Replace(u32), + Flag, + Block, +} +enum ScriptActionParseResult { + Pass, + Block, +} +struct ParseScriptActionErr; +impl std::str::FromStr for ScriptActionParseResult { + type Err=ParseScriptActionErr; + fn from_str(s: &str) -> Result{ + if s=="pass"||s=="1"{ + Ok(Self::Pass) + }else if s=="block"{ + Ok(Self::Block) + }else{ + Err(ParseScriptActionErr) + } + } +} + fn interactive() -> Result<(), Box>{ - unimplemented!() + let mut id=get_id()?; + //Construct allowed scripts + let mut allowed_set=get_allowed_set()?; + let mut allowed_map=get_allowed_map()?; + let mut replace_map=get_replace_map()?; + + for entry in std::fs::read_dir("maps/unprocessed")? { + let file_thing=entry?; + println!("processing map={:?}",file_thing.file_name()); + let input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?); + + let dom = rbx_binary::from_reader(input)?; + + let mut write_dom = rbx_dom_weak::WeakDom::new(rbx_dom_weak::InstanceBuilder::empty()); + dom.clone_into_external(dom.root_ref(), &mut write_dom); + + let scripts = get_scripts(dom); + + //check scribb + let mut fail_type=Interactive::Passed; + for script in scripts.iter() { + if let Some(rbx_dom_weak::types::Variant::String(source)) = script.properties.get("Source") { + let source_action=if check_source_illegal_keywords(source) { + ScriptAction::Flag//script triggers flagging -> Flag + } else if allowed_set.contains(source) { + ScriptAction::Pass//script is allowed -> Pass + }else if let Some(replace_id)=replace_map.get(source) { + ScriptAction::Replace(*replace_id) + }else{ + //interactive logic goes here + //load source into current.lua + std::fs::write("current.lua",source)?; + //prompt action in terminal + println!("unresolved source location={}",get_full_name(&write_dom, script)); + //wait for input + let script_action; + loop{ + let mut action_string = String::new(); + std::io::stdin().read_line(&mut action_string)?; + if let Ok(parsed_script_action)=action_string.parse::(){ + script_action=parsed_script_action; + break; + }else{ + println!("illegal action string."); + } + } + //update allowed/replace/blocked + match script_action{ + ScriptActionParseResult::Pass => { + //if current.lua was updated, create an allowed and replace file and set script_action to replace(new_id) + let modified_source=std::fs::read_to_string("current.lua")?; + if &modified_source==source{ + //it's always new. + //insert allowed_set + allowed_set.insert(modified_source.clone()); + //insert allowed_map + allowed_map.insert(id,modified_source.clone()); + //write allowed/id.lua + std::fs::write(format!("scripts/allowed/{}.lua",id),modified_source)?; + id+=1; + ScriptAction::Pass + }else{ + //insert allowed_set + allowed_set.insert(modified_source.clone()); + //insert allowed_map + allowed_map.insert(id,modified_source.clone()); + //insert replace_map + replace_map.insert(source.clone(),id);//this cannot be reached if it already exists + //write allowed/id.lua + std::fs::write(format!("scripts/allowed/{}.lua",id),modified_source)?; + //write replace/id.lua + std::fs::write(format!("scripts/replace/{}.lua",id),source)?; + let ret=ScriptAction::Replace(id); + id+=1; + ret + } + }, + ScriptActionParseResult::Block => ScriptAction::Block, + } + }; + + match source_action{ + ScriptAction::Pass => println!("passed source location={}",get_full_name(&write_dom, script)), + ScriptAction::Replace(replace_id)=>{ + //replace the source + let location=get_full_name(&write_dom, script); + if let (Some(replace_source),Some(replace_script))=(allowed_map.get(&replace_id),write_dom.get_by_ref_mut(script.referent())){ + println!("replaced source id={} location={}",replace_id,location); + replace_script.properties.insert("Source".to_string(), rbx_dom_weak::types::Variant::String(replace_source.clone())); + }else{ + println!("failed to get replacement source id={} location={}",replace_id,location); + fail_type=Interactive::ReplaceFailed; + } + } + ScriptAction::Flag => { + println!("flagged source location={}",get_full_name(&write_dom, script)); + fail_type=Interactive::Flagged; + }, + ScriptAction::Block => { + println!("blocked source location={}",get_full_name(&write_dom, script)); + match fail_type{ + Interactive::Passed => fail_type=Interactive::Blocked, + _=>(), + } + }, + } + } + } + let mut dest=match fail_type{ + Interactive::Passed => std::path::PathBuf::from("maps/processed"),//write map into maps/processed + Interactive::Blocked => std::path::PathBuf::from("maps/blocked"),//write map into maps/blocked + Interactive::Flagged => std::path::PathBuf::from("maps/flagged"),//write map into maps/flagged + Interactive::ReplaceFailed => continue,//do nothing, map is still unprocessed + }; + dest.push(file_thing.file_name()); + std::fs::rename(file_thing.path(), dest)?; + } + std::fs::write("id",id.to_string())?; + Ok(()) } fn main() -> Result<(), Box> {