Rework avatars.

Now we have a concept of an avatar at the server, realm, and scene level
and we have the groundwork for a realm store. New uesrs no longer props,
they get a default avatar. New system supports gender
{male,female,neutral} and {child,adult}.
This commit is contained in:
Evan Carroll 2026-01-22 21:04:27 -06:00
parent e4abdb183f
commit 6fb90e42c3
55 changed files with 7392 additions and 512 deletions

View file

@ -16,6 +16,8 @@ pub struct AppConfig {
pub websocket: WebSocketConfig,
/// Stale member cleanup configuration.
pub cleanup: CleanupConfig,
/// Signup form configuration.
pub signup: SignupConfig,
}
/// WebSocket configuration.
@ -40,11 +42,62 @@ pub struct CleanupConfig {
pub clear_on_startup: bool,
}
/// Signup form configuration.
/// Controls what fields are shown during user registration.
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct SignupConfig {
/// Whether to show birthday field during signup.
/// None = don't ask, Some("ask") = show field
pub birthday: Option<SignupField>,
/// How to determine user's age category.
pub age: AgeConfig,
/// How to determine user's gender preference.
pub gender: GenderConfig,
}
/// Signup field option.
#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum SignupField {
/// Show the field during signup
Ask,
}
/// Age category configuration.
#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum AgeConfig {
/// Ask user to select their age category
Ask,
/// Infer age category from birthday (requires birthday = "ask")
Infer,
/// Default to adult without asking
DefaultAdult,
/// Default to child without asking
DefaultChild,
}
/// Gender preference configuration.
#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum GenderConfig {
/// Ask user to select their gender preference
Ask,
/// Default to neutral without asking
DefaultNeutral,
/// Default to male without asking
DefaultMale,
/// Default to female without asking
DefaultFemale,
}
impl Default for AppConfig {
fn default() -> Self {
Self {
websocket: WebSocketConfig::default(),
cleanup: CleanupConfig::default(),
signup: SignupConfig::default(),
}
}
}
@ -68,6 +121,28 @@ impl Default for CleanupConfig {
}
}
impl Default for SignupConfig {
fn default() -> Self {
Self {
birthday: None,
age: AgeConfig::default(),
gender: GenderConfig::default(),
}
}
}
impl Default for AgeConfig {
fn default() -> Self {
Self::DefaultAdult
}
}
impl Default for GenderConfig {
fn default() -> Self {
Self::DefaultNeutral
}
}
impl AppConfig {
/// Load configuration from a TOML file.
///