validator: marginally improve map check clarity #123
@ -40,51 +40,74 @@ impl From<crate::nats_types::CheckSubmissionRequest> for CheckRequest{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub enum Check{
|
||||||
|
Pass,
|
||||||
|
#[default]
|
||||||
|
Fail,
|
||||||
|
}
|
||||||
|
impl Check{
|
||||||
|
fn pass(&self)->bool{
|
||||||
|
match self{
|
||||||
|
Check::Pass=>true,
|
||||||
|
Check::Fail=>false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl std::fmt::Display for Check{
|
||||||
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
|
match self{
|
||||||
|
Check::Pass=>write!(f,"passed"),
|
||||||
|
Check::Fail=>write!(f,"failed"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct CheckReport{
|
pub struct CheckReport{
|
||||||
// === METADATA CHECKS ===
|
// === METADATA CHECKS ===
|
||||||
// the model must have exactly 1 root part (models uploaded to roblox can have multiple roots)
|
// the model must have exactly 1 root part (models uploaded to roblox can have multiple roots)
|
||||||
exactly_one_root:bool,
|
exactly_one_root:Check,
|
||||||
// the root must be of class Model
|
// the root must be of class Model
|
||||||
root_is_model:bool,
|
root_is_model:Check,
|
||||||
// the prefix of the model's name must match the game it was submitted for. bhop_ for bhop, and surf_ for surf
|
// the prefix of the model's name must match the game it was submitted for. bhop_ for bhop, and surf_ for surf
|
||||||
model_name_prefix_is_valid:bool,
|
model_name_prefix_is_valid:Check,
|
||||||
// your model's name must match this regex: ^[a-z0-9_]
|
// your model's name must match this regex: ^[a-z0-9_]
|
||||||
model_name_is_snake_case:bool,
|
model_name_is_snake_case:Check,
|
||||||
// map must have a StringValue named Creator and DisplayName. additionally, they must both have a value
|
// map must have a StringValue named Creator and DisplayName. additionally, they must both have a value
|
||||||
has_display_name:bool,
|
has_display_name:Check,
|
||||||
has_creator:bool,
|
has_creator:Check,
|
||||||
// the display name must be capitalized
|
// the display name must be capitalized
|
||||||
display_name_is_title_case:bool,
|
display_name_is_title_case:Check,
|
||||||
// you cannot have any Scripts or ModuleScripts that have the keyword 'getfenv" or 'require'
|
// you cannot have any Scripts or ModuleScripts that have the keyword 'getfenv" or 'require'
|
||||||
// you cannot have more than 50 duplicate scripts
|
// you cannot have more than 50 duplicate scripts
|
||||||
|
|
||||||
// === MODE CHECKS ===
|
// === MODE CHECKS ===
|
||||||
// Exactly one MapStart
|
// Exactly one MapStart
|
||||||
exactly_one_mapstart:bool,
|
exactly_one_mapstart:Check,
|
||||||
// At least one MapFinish
|
// At least one MapFinish
|
||||||
at_least_one_mapfinish:bool,
|
at_least_one_mapfinish:Check,
|
||||||
// Spawn0 or Spawn1 must exist
|
// Spawn0 or Spawn1 must exist
|
||||||
spawn1_exists:bool,
|
spawn1_exists:Check,
|
||||||
// No duplicate Spawn#
|
// No duplicate Spawn#
|
||||||
no_duplicate_spawns:bool,
|
no_duplicate_spawns:Check,
|
||||||
// No duplicate WormholeOut# (duplicate WormholeIn# ok)
|
// No duplicate WormholeOut# (duplicate WormholeIn# ok)
|
||||||
no_duplicate_wormhole_out:bool,
|
no_duplicate_wormhole_out:Check,
|
||||||
}
|
}
|
||||||
impl CheckReport{
|
impl CheckReport{
|
||||||
pub fn pass(&self)->bool{
|
pub fn pass(&self)->bool{
|
||||||
return self.exactly_one_root
|
return self.exactly_one_root.pass()
|
||||||
&&self.root_is_model
|
&&self.root_is_model.pass()
|
||||||
&&self.model_name_prefix_is_valid
|
&&self.model_name_prefix_is_valid.pass()
|
||||||
&&self.model_name_is_snake_case
|
&&self.model_name_is_snake_case.pass()
|
||||||
&&self.has_display_name
|
&&self.has_display_name.pass()
|
||||||
&&self.has_creator
|
&&self.has_creator.pass()
|
||||||
&&self.display_name_is_title_case
|
&&self.display_name_is_title_case.pass()
|
||||||
&&self.exactly_one_mapstart
|
&&self.exactly_one_mapstart.pass()
|
||||||
&&self.at_least_one_mapfinish
|
&&self.at_least_one_mapfinish.pass()
|
||||||
&&self.spawn1_exists
|
&&self.spawn1_exists.pass()
|
||||||
&&self.no_duplicate_spawns
|
&&self.no_duplicate_spawns.pass()
|
||||||
&&self.no_duplicate_wormhole_out
|
&&self.no_duplicate_wormhole_out.pass()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl std::fmt::Display for CheckReport{
|
impl std::fmt::Display for CheckReport{
|
||||||
@ -192,13 +215,13 @@ pub fn check(dom:&rbx_dom_weak::WeakDom)->CheckReport{
|
|||||||
return report;
|
return report;
|
||||||
};
|
};
|
||||||
|
|
||||||
report.exactly_one_root=true;
|
report.exactly_one_root=Check::Pass;
|
||||||
|
|
||||||
if model_instance.class=="Model"{
|
if model_instance.class=="Model"{
|
||||||
report.root_is_model=true;
|
report.root_is_model=Check::Pass;
|
||||||
}
|
}
|
||||||
if model_instance.name==model_instance.name.to_snake_case(){
|
if model_instance.name==model_instance.name.to_snake_case(){
|
||||||
report.model_name_is_snake_case=true;
|
report.model_name_is_snake_case=Check::Pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract model info
|
// extract model info
|
||||||
@ -207,9 +230,9 @@ pub fn check(dom:&rbx_dom_weak::WeakDom)->CheckReport{
|
|||||||
// check DisplayName
|
// check DisplayName
|
||||||
if let Ok(display_name)=display_name{
|
if let Ok(display_name)=display_name{
|
||||||
if !display_name.is_empty(){
|
if !display_name.is_empty(){
|
||||||
report.has_display_name=true;
|
report.has_display_name=Check::Pass;
|
||||||
if display_name==display_name.to_title_case(){
|
if display_name==display_name.to_title_case(){
|
||||||
report.display_name_is_title_case=true;
|
report.display_name_is_title_case=Check::Pass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,13 +240,13 @@ pub fn check(dom:&rbx_dom_weak::WeakDom)->CheckReport{
|
|||||||
// check Creator
|
// check Creator
|
||||||
if let Ok(creator)=creator{
|
if let Ok(creator)=creator{
|
||||||
if !creator.is_empty(){
|
if !creator.is_empty(){
|
||||||
report.has_creator=true;
|
report.has_creator=Check::Pass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check GameID
|
// check GameID
|
||||||
if game_id.is_ok(){
|
if game_id.is_ok(){
|
||||||
report.model_name_prefix_is_valid=true;
|
report.model_name_prefix_is_valid=Check::Pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
// === MODE CHECKS ===
|
// === MODE CHECKS ===
|
||||||
@ -257,24 +280,24 @@ pub fn check(dom:&rbx_dom_weak::WeakDom)->CheckReport{
|
|||||||
// MapStart must exist && there must be exactly one of any bonus start zones.
|
// MapStart must exist && there must be exactly one of any bonus start zones.
|
||||||
if counts.mode_start_counts.get(&ModeID::MAIN)==Some(&1)
|
if counts.mode_start_counts.get(&ModeID::MAIN)==Some(&1)
|
||||||
&&counts.mode_start_counts.iter().all(|(_,&c)|c==1){
|
&&counts.mode_start_counts.iter().all(|(_,&c)|c==1){
|
||||||
report.exactly_one_mapstart=true;
|
report.exactly_one_mapstart=Check::Pass;
|
||||||
}
|
}
|
||||||
// iterate over start zones
|
// iterate over start zones
|
||||||
if counts.mode_start_counts.iter().all(|(mode_id,_)|
|
if counts.mode_start_counts.iter().all(|(mode_id,_)|
|
||||||
// ensure that at least one end zone exists with the same mode id
|
// ensure that at least one end zone exists with the same mode id
|
||||||
counts.mode_finish_counts.get(mode_id).is_some_and(|&num|0<num)
|
counts.mode_finish_counts.get(mode_id).is_some_and(|&num|0<num)
|
||||||
){
|
){
|
||||||
report.at_least_one_mapfinish=true;
|
report.at_least_one_mapfinish=Check::Pass;
|
||||||
}
|
}
|
||||||
// Spawn1 must exist
|
// Spawn1 must exist
|
||||||
if counts.spawn_counts.get(&SpawnID::FIRST).is_some(){
|
if counts.spawn_counts.get(&SpawnID::FIRST).is_some(){
|
||||||
report.spawn1_exists=true;
|
report.spawn1_exists=Check::Pass;
|
||||||
}
|
}
|
||||||
if counts.spawn_counts.iter().all(|(_,&c)|c==1){
|
if counts.spawn_counts.iter().all(|(_,&c)|c==1){
|
||||||
report.no_duplicate_spawns=true;
|
report.no_duplicate_spawns=Check::Pass;
|
||||||
}
|
}
|
||||||
if counts.wormhole_out_counts.iter().all(|(_,&c)|c==1){
|
if counts.wormhole_out_counts.iter().all(|(_,&c)|c==1){
|
||||||
report.no_duplicate_wormhole_out=true;
|
report.no_duplicate_wormhole_out=Check::Pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
report
|
report
|
||||||
|
Loading…
x
Reference in New Issue
Block a user