You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
3.4 KiB
146 lines
3.4 KiB
use std::cell::RefCell;
|
|
|
|
use crate::config::Player;
|
|
|
|
// this global stuff is so that we can load up the config and check stuff without
|
|
// being part of the Game struct
|
|
thread_local! {
|
|
/// Minimum length for name
|
|
static NAME_MIN: RefCell<usize> = RefCell::new(0);
|
|
|
|
/// Maximum length for name
|
|
static NAME_MAX: RefCell<usize> = RefCell::new(0);
|
|
|
|
/// Characters allowed to be in name
|
|
static NAME_CHARS: RefCell<&'static str> = RefCell::new("");
|
|
|
|
/// Password minimum length
|
|
static PASS_MIN: RefCell<usize> = RefCell::new(0);
|
|
|
|
/// Password maximum length
|
|
static PASS_MAX: RefCell<usize> = RefCell::new(0);
|
|
|
|
/// Password allowed characters
|
|
static PASS_CHARS: RefCell<&'static str> = RefCell::new("");
|
|
}
|
|
|
|
/// Return value for check functions
|
|
#[derive(Debug)]
|
|
pub enum PlayerCheck {
|
|
/// The value checks out
|
|
Ok(String),
|
|
|
|
/// There is one or more issues
|
|
Err(Vec<String>),
|
|
}
|
|
|
|
/// Initialize the check module from the Player part of the Config.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * config: the Player struct of Config
|
|
///
|
|
/// # Example
|
|
/// ```
|
|
/// use rude::config::Config;
|
|
/// use rude::check;
|
|
///
|
|
/// let config = Config::load("config.toml").unwrap();
|
|
/// check::init(&config.player);
|
|
/// ```
|
|
pub fn init(config: &Player) {
|
|
NAME_MIN.with(|n| *n.borrow_mut() = config.name_min);
|
|
NAME_MAX.with(|n| *n.borrow_mut() = config.name_max);
|
|
NAME_CHARS.with(|n| *n.borrow_mut() = Box::leak(config.name_chars.clone().into_boxed_str()));
|
|
PASS_MIN.with(|p| *p.borrow_mut() = config.pass_min);
|
|
PASS_MAX.with(|p| *p.borrow_mut() = config.pass_max);
|
|
PASS_CHARS.with(|p| *p.borrow_mut() = Box::leak(config.pass_chars.clone().into_boxed_str()));
|
|
}
|
|
|
|
/// Check the player name to ensure it meets guidelines
|
|
pub fn player_name<S: Into<String>>(name: S) -> PlayerCheck {
|
|
let name = name.into();
|
|
let name = name.trim();
|
|
let mut err_vec = Vec::<String>::new();
|
|
|
|
if name.len() < NAME_MIN.with(|n| *n.borrow()) {
|
|
err_vec.push(
|
|
[
|
|
&NAME_MIN.with(|n| *n.borrow()).to_string(),
|
|
" character minimum",
|
|
]
|
|
.concat(),
|
|
);
|
|
} else if name.len() > NAME_MAX.with(|n| *n.borrow()) {
|
|
err_vec.push(
|
|
[
|
|
&NAME_MAX.with(|n| *n.borrow()).to_string(),
|
|
" character maximum"
|
|
]
|
|
.concat()
|
|
);
|
|
}
|
|
|
|
for c in name.chars() {
|
|
if !NAME_CHARS.with(|n| *n.borrow()).contains(&c.to_string()) {
|
|
err_vec.push(
|
|
[
|
|
"Allowed characters are: ",
|
|
&NAME_CHARS.with(|n| *n.borrow())
|
|
]
|
|
.concat()
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if err_vec.is_empty() {
|
|
PlayerCheck::Ok(name.into())
|
|
} else {
|
|
PlayerCheck::Err(err_vec)
|
|
}
|
|
}
|
|
|
|
/// Check the password to ensure it meets password requirements
|
|
pub fn player_password<S: Into<String>>(password: S) -> PlayerCheck {
|
|
let password = password.into();
|
|
let mut err_vec = Vec::<String>::new();
|
|
|
|
if password.len() < PASS_MIN.with(|p| *p.borrow()) {
|
|
err_vec.push(
|
|
[
|
|
&PASS_MIN.with(|p| *p.borrow()).to_string(),
|
|
" character minimum"
|
|
]
|
|
.concat()
|
|
);
|
|
} else if password.len() > PASS_MAX.with(|p| *p.borrow()) {
|
|
err_vec.push(
|
|
[
|
|
&PASS_MAX.with(|p| *p.borrow()).to_string(),
|
|
" character maximum"
|
|
]
|
|
.concat()
|
|
);
|
|
}
|
|
|
|
for c in password.chars() {
|
|
if !PASS_CHARS.with(|p| *p.borrow()).contains(&c.to_string()) {
|
|
err_vec.push(
|
|
[
|
|
"Allowed characters are: ",
|
|
&PASS_CHARS.with(|p| *p.borrow()).to_string()
|
|
]
|
|
.concat()
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if err_vec.is_empty() {
|
|
PlayerCheck::Ok(password.into())
|
|
} else {
|
|
PlayerCheck::Err(err_vec)
|
|
}
|
|
}
|