diff --git a/common/src/character.rs b/common/src/character.rs index 54284345b8..112c4e5a81 100644 --- a/common/src/character.rs +++ b/common/src/character.rs @@ -7,6 +7,8 @@ use serde::{Deserialize, Serialize}; pub const MAX_CHARACTERS_PER_PLAYER: usize = 8; pub type CharacterId = i64; +pub const MAX_NAME_LENGTH: usize = 20; + /// The minimum character data we need to create a new character on the server. #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct Character { diff --git a/server/src/alias_validator.rs b/server/src/alias_validator.rs index d6e02f09c9..7eb27ea3f3 100644 --- a/server/src/alias_validator.rs +++ b/server/src/alias_validator.rs @@ -1,3 +1,4 @@ +use common::character::MAX_NAME_LENGTH; use std::fmt::{self, Display}; #[derive(Debug, Default)] @@ -16,6 +17,10 @@ impl AliasValidator { } pub fn validate(&self, alias: &str) -> Result<(), ValidatorError> { + if alias.len() > MAX_NAME_LENGTH { + return Err(ValidatorError::TooLong(alias.to_owned(), alias.len())); + } + let lowercase_alias = alias.to_lowercase(); for banned_word in self.banned_substrings.iter() { @@ -33,6 +38,7 @@ impl AliasValidator { #[derive(Debug, PartialEq)] pub enum ValidatorError { Forbidden(String, String), + TooLong(String, usize), } impl Display for ValidatorError { @@ -43,6 +49,7 @@ impl Display for ValidatorError { "Character name \"{}\" contains a banned word", name ), + Self::TooLong(name, _) => write!(formatter, "Character name \"{}\" too long", name), } } } @@ -56,7 +63,7 @@ mod tests { let banned_substrings = vec!["bad".to_owned(), "worse".to_owned()]; let validator = AliasValidator::new(banned_substrings); - let bad_alias = "Badplayery Mc WorsePlayeryFace"; + let bad_alias = "BadplayerMcWorseFace"; let result = validator.validate(bad_alias); assert_eq!( @@ -112,4 +119,21 @@ mod tests { assert_eq!(result, Ok(())); } + + #[test] + fn too_long() { + let banned_substrings = vec!["orange".to_owned()]; + let validator = AliasValidator::new(banned_substrings); + + let bad_alias = "Thisnameistoolong Muchtoolong MuchTooLongByFar"; + let result = validator.validate(bad_alias); + + assert_eq!( + result, + Err(ValidatorError::TooLong( + bad_alias.to_owned(), + bad_alias.chars().count() + )) + ); + } } diff --git a/voxygen/src/menu/char_selection/ui/mod.rs b/voxygen/src/menu/char_selection/ui/mod.rs index 14eedb67ea..8fbf62aa1e 100644 --- a/voxygen/src/menu/char_selection/ui/mod.rs +++ b/voxygen/src/menu/char_selection/ui/mod.rs @@ -23,7 +23,7 @@ use crate::{ use client::Client; use common::{ assets::AssetHandle, - character::{CharacterId, CharacterItem, MAX_CHARACTERS_PER_PLAYER}, + character::{CharacterId, CharacterItem, MAX_CHARACTERS_PER_PLAYER, MAX_NAME_LENGTH}, comp::{self, humanoid, inventory::slot::EquipSlot, Inventory, Item}, LoadoutBuilder, }; @@ -1238,7 +1238,7 @@ impl Controls { }, Message::Name(value) => { if let Mode::Create { name, .. } = &mut self.mode { - *name = value; + *name = value.chars().take(MAX_NAME_LENGTH).collect(); } }, Message::BodyType(value) => {