diff --git a/validation/src/check.rs b/validation/src/check.rs index dc112a7..8c39abe 100644 --- a/validation/src/check.rs +++ b/validation/src/check.rs @@ -1,6 +1,6 @@ use std::collections::{HashSet,HashMap}; use crate::download::download_asset_version; -use crate::rbx_util::{class_is_a,get_mapinfo,get_root_instance,read_dom,ReadDomError,GameID,ParseGameIDError,MapInfo,GetRootInstanceError,StringValueError}; +use crate::rbx_util::{get_mapinfo,get_root_instance,read_dom,ReadDomError,GameID,ParseGameIDError,MapInfo,GetRootInstanceError,StringValueError}; use heck::{ToSnakeCase,ToTitleCase}; @@ -225,27 +225,33 @@ pub fn get_model_info<'a>(dom:&'a rbx_dom_weak::WeakDom,model_instance:&'a rbx_d // count objects (default count is 0) let mut counts=Counts::default(); - for instance in dom.descendants_of(model_instance.referent()){ - if class_is_a(instance.class.as_str(),"BasePart"){ - // Zones - match instance.name.parse(){ - Ok(ModeElement{zone:Zone::Start,mode_id})=>counts.mode_start_counts.entry(mode_id).or_default().push(instance.name.as_str()), - Ok(ModeElement{zone:Zone::Finish,mode_id})=>counts.mode_finish_counts.entry(mode_id).or_default().push(instance.name.as_str()), - Ok(ModeElement{zone:Zone::Anticheat,mode_id})=>counts.mode_anticheat_counts.entry(mode_id).or_default().push(instance.name.as_str()), - Err(_)=>(), - } - // Spawns & Teleports - match instance.name.parse(){ - Ok(StageElement{behaviour:StageElementBehaviour::Teleport,stage_id})=>counts.teleport_counts.entry(stage_id).or_default().push(instance.name.as_str()), - Ok(StageElement{behaviour:StageElementBehaviour::Spawn,stage_id})=>*counts.spawn_counts.entry(stage_id).or_insert(0)+=1, - Err(_)=>(), - } - // Wormholes - match instance.name.parse(){ - Ok(WormholeElement{behaviour:WormholeBehaviour::In,wormhole_id})=>*counts.wormhole_in_counts.entry(wormhole_id).or_insert(0)+=1, - Ok(WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id})=>*counts.wormhole_out_counts.entry(wormhole_id).or_insert(0)+=1, - Err(_)=>(), - } + + let db=rbx_reflection_database::get(); + let base_part=&db.classes["BasePart"]; + let base_parts=dom.descendants_of(model_instance.referent()).filter(|&instance| + db.classes.get(instance.class.as_str()).is_some_and(|class| + db.has_superclass(class,base_part) + ) + ); + for instance in base_parts{ + // Zones + match instance.name.parse(){ + Ok(ModeElement{zone:Zone::Start,mode_id})=>counts.mode_start_counts.entry(mode_id).or_default().push(instance.name.as_str()), + Ok(ModeElement{zone:Zone::Finish,mode_id})=>counts.mode_finish_counts.entry(mode_id).or_default().push(instance.name.as_str()), + Ok(ModeElement{zone:Zone::Anticheat,mode_id})=>counts.mode_anticheat_counts.entry(mode_id).or_default().push(instance.name.as_str()), + Err(_)=>(), + } + // Spawns & Teleports + match instance.name.parse(){ + Ok(StageElement{behaviour:StageElementBehaviour::Teleport,stage_id})=>counts.teleport_counts.entry(stage_id).or_default().push(instance.name.as_str()), + Ok(StageElement{behaviour:StageElementBehaviour::Spawn,stage_id})=>*counts.spawn_counts.entry(stage_id).or_insert(0)+=1, + Err(_)=>(), + } + // Wormholes + match instance.name.parse(){ + Ok(WormholeElement{behaviour:WormholeBehaviour::In,wormhole_id})=>*counts.wormhole_in_counts.entry(wormhole_id).or_insert(0)+=1, + Ok(WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id})=>*counts.wormhole_out_counts.entry(wormhole_id).or_insert(0)+=1, + Err(_)=>(), } } diff --git a/validation/src/rbx_util.rs b/validation/src/rbx_util.rs index fdff4d5..59cff0d 100644 --- a/validation/src/rbx_util.rs +++ b/validation/src/rbx_util.rs @@ -28,14 +28,6 @@ pub fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{ rbx_dom_weak::ustr(s) } -pub fn class_is_a(class:&str,superclass:&str)->bool{ - let db=rbx_reflection_database::get(); - let (Some(class),Some(superclass))=(db.classes.get(class),db.classes.get(superclass))else{ - return false; - }; - db.has_superclass(class,superclass) -} - fn find_first_child_name_and_class<'a>(dom:&'a rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance,name:&str,class:&str)->Option<&'a rbx_dom_weak::Instance>{ instance.children().iter().filter_map(|&r|dom.get_by_ref(r)).find(|inst|inst.name==name&&inst.class==class) }