1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00
Files
ojrc/rc_services_room/src/vehicle_validators.rs
2026-02-28 10:51:12 -05:00

137 lines
5.8 KiB
Rust

pub type InitedVehicleValidator = Box<dyn oj_rc_plugins::vehicle_validation::VehicleValidatorPlugin>;
pub struct InitedVehicleValidators {
pub multiplayer: std::sync::Arc<InitedVehicleValidator>,
pub custom_game: std::sync::Arc<InitedVehicleValidator>,
pub singleplayer: std::sync::Arc<InitedVehicleValidator>,
pub campaigns: std::sync::Arc<std::collections::HashMap<String, InitedVehicleValidator>>,
}
pub fn validators_from_conf(conf: &oj_rc_core::persist::config::VehicleValidators, parsers: &oj_rc_core::cubes::CubeParsers, plugins_path: impl AsRef<std::path::Path>) -> InitedVehicleValidators {
let plugins_path = plugins_path.as_ref();
InitedVehicleValidators {
multiplayer: std::sync::Arc::new(validator_from_conf(&conf.multiplayer, parsers, plugins_path)),
custom_game: std::sync::Arc::new(validator_from_conf(&conf.multiplayer, parsers, plugins_path)),
singleplayer: std::sync::Arc::new(validator_from_conf(&conf.singleplayer, parsers, plugins_path)),
campaigns: std::sync::Arc::new(
conf.campaigns.iter()
.map(|(campaign_id, validator)| (campaign_id.to_owned(), validator_from_conf(validator, parsers, plugins_path)))
.collect()
),
}
}
fn validator_from_conf(conf: &oj_rc_core::persist::VehicleValidator, parsers: &oj_rc_core::cubes::CubeParsers, plugins_path: impl AsRef<std::path::Path>) -> InitedVehicleValidator {
match conf {
oj_rc_core::persist::VehicleValidator::None => Box::new(AlwaysValid) as _,
oj_rc_core::persist::VehicleValidator::Cpu { min, max } => Box::new(CpuRange {
range: *min..=*max,
parser: parsers.cpu_counter(),
}) as _,
oj_rc_core::persist::VehicleValidator::All { all } => Box::new(All::init(all, parsers, plugins_path)) as _,
oj_rc_core::persist::VehicleValidator::Any { any } => Box::new(Any::init(any, parsers, plugins_path)) as _,
oj_rc_core::persist::VehicleValidator::Custom { path } => {
let full_path = plugins_path.as_ref().join(path);
log::warn!("Custom vehicle validator plugin {} is experimental and insecure", full_path.display());
let result = oj_rc_plugins::vehicle_validation::VehicleValidatorCPlugin::new(&full_path);
match result {
Ok(c_plugin) => Box::new(c_plugin) as _,
Err(e) => {
log::error!("Failed to load custom vehicle validator plugin {}: {} (crashing!)", full_path.display(), e);
panic!("Failed to load custom vehicle validator plugin {}: {}", full_path.display(), e)
}
}
},
}
}
struct AlwaysValid;
impl oj_rc_plugins::vehicle_validation::VehicleValidatorPlugin for AlwaysValid {
fn validate(&self, _cube_data: &[u8], _colour_data: &[u8]) -> oj_rc_plugins::vehicle_validation::ValidationResultCode {
oj_rc_plugins::vehicle_validation::ValidationResultCode::Ok
}
}
impl oj_rc_plugins::Plugin for AlwaysValid {}
struct CpuRange {
range: std::ops::RangeInclusive<u32>,
parser: std::sync::Arc<oj_rc_core::cubes::CpuListParser>,
}
impl oj_rc_plugins::vehicle_validation::VehicleValidatorPlugin for CpuRange {
fn validate(&self, cube_data: &[u8], _colour_data: &[u8]) -> oj_rc_plugins::vehicle_validation::ValidationResultCode {
let cpu_info = self.parser.calculate_cpu(&mut std::io::Cursor::new(cube_data));
if self.range.contains(&(cpu_info.total - cpu_info.cosmetic)) {
oj_rc_plugins::vehicle_validation::ValidationResultCode::Ok
} else {
oj_rc_plugins::vehicle_validation::ValidationResultCode::Invalid
}
}
}
impl oj_rc_plugins::Plugin for CpuRange {}
struct All(Vec<InitedVehicleValidator>);
impl All {
fn init(items: &[oj_rc_core::persist::VehicleValidator], parsers: &oj_rc_core::cubes::CubeParsers, plugins_path: impl AsRef<std::path::Path>) -> Self {
let plugins_path = plugins_path.as_ref();
All(
items.iter()
.map(|item| validator_from_conf(item, parsers, plugins_path))
.collect()
)
}
}
impl oj_rc_plugins::vehicle_validation::VehicleValidatorPlugin for All {
fn validate(&self, cube_data: &[u8], colour_data: &[u8]) -> oj_rc_plugins::vehicle_validation::ValidationResultCode {
self.0.iter()
.filter_map(|item| {
let code = item.validate(cube_data, colour_data);
if matches!(code, oj_rc_plugins::vehicle_validation::ValidationResultCode::Ok) {
None
} else {
Some(code)
}
})
.next()
.unwrap_or(oj_rc_plugins::vehicle_validation::ValidationResultCode::Ok)
}
}
impl oj_rc_plugins::Plugin for All {}
struct Any(Vec<InitedVehicleValidator>);
impl Any {
fn init(items: &[oj_rc_core::persist::VehicleValidator], parsers: &oj_rc_core::cubes::CubeParsers, plugins_path: impl AsRef<std::path::Path>) -> Self {
let plugins_path = plugins_path.as_ref();
Any(
items.iter()
.map(|item| validator_from_conf(item, parsers, plugins_path))
.collect()
)
}
}
impl oj_rc_plugins::vehicle_validation::VehicleValidatorPlugin for Any {
fn validate(&self, cube_data: &[u8], colour_data: &[u8]) -> oj_rc_plugins::vehicle_validation::ValidationResultCode {
self.0.iter()
.map_while(|item| {
let code = item.validate(cube_data, colour_data);
if matches!(code, oj_rc_plugins::vehicle_validation::ValidationResultCode::Ok) {
None
} else {
Some(code)
}
})
.next()
.unwrap_or(oj_rc_plugins::vehicle_validation::ValidationResultCode::Ok)
}
}
impl oj_rc_plugins::Plugin for Any {}