JaneDoe-ZS/nap_gameserver/src/commands/avatar.rs
xeon 99123a15ef newtype fun
use newtypes for template ids, pros:
1) enforces id validation
2) ease of use (helper method for getting template struct right away)
2024-07-25 01:24:48 +03:00

57 lines
1.6 KiB
Rust

use data::tables::AvatarBaseID;
use proto::{AddAvatarPerformType, AddAvatarScNotify, PlayerSyncScNotify};
use crate::ServerState;
use super::ArgSlice;
pub async fn add(
args: ArgSlice<'_>,
state: &ServerState,
) -> Result<String, Box<dyn std::error::Error>> {
const USAGE: &str = "Usage: avatar add [player_uid] [avatar_id]";
if args.len() != 2 {
return Ok(USAGE.to_string());
}
let uid = args[0].parse::<u32>()?;
let avatar_id = args[1].parse::<u32>()?;
let Some(avatar_id) = AvatarBaseID::new(avatar_id) else {
return Ok(format!("avatar with id {avatar_id} doesn't exist"));
};
let Some(player_lock) = state.player_mgr.get_player(uid).await else {
return Ok(String::from("player not found"));
};
let (session_id, avatar_sync) = {
let mut player = player_lock.lock().await;
player.role_model.add_avatar(avatar_id);
(player.current_session_id(), player.role_model.avatar_sync())
};
if let Some(session) = session_id.map(|id| state.session_mgr.get(id)).flatten() {
session
.notify(AddAvatarScNotify {
avatar_id: avatar_id.value(),
perform_type: AddAvatarPerformType::Gacha.into(),
..Default::default()
})
.await?;
session
.notify(PlayerSyncScNotify {
avatar: Some(avatar_sync),
..Default::default()
})
.await?;
} else {
state.player_mgr.save_and_remove(uid).await;
}
Ok(format!(
"successfully added avatar {avatar_id} to player {uid}"
))
}