JaneDoe-ZS/nap_gameserver/src/commands/player.rs
xeon 370f141f88 more commands, unlock only default avatars at beginning
Implement 'avatar add' command
Implemented 'player procedure' command
2024-07-23 18:12:05 +03:00

129 lines
3.4 KiB
Rust

use data::tables;
use proto::PlayerSyncScNotify;
use crate::ServerState;
pub async fn avatar(
args: &[&str],
state: &ServerState,
) -> Result<String, Box<dyn std::error::Error>> {
const USAGE: &str = "Usage: player avatar [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(player_lock) = state.player_mgr.get_player(uid).await else {
return Ok(String::from("player not found"));
};
if !tables::avatar_base_template_tb::iter().any(|tmpl| tmpl.id == avatar_id) {
return Ok(format!("avatar with id {avatar_id} doesn't exist"));
}
let should_save = {
let mut player = player_lock.lock().await;
player.basic_data_model.frontend_avatar_id = avatar_id as i32;
player.current_session_id().is_none()
};
if should_save {
state.player_mgr.save_and_remove(uid).await;
}
Ok(format!(
"changed frontend_avatar_id, you have to re-enter main city now"
))
}
pub async fn nickname(
args: &[&str],
state: &ServerState,
) -> Result<String, Box<dyn std::error::Error>> {
const USAGE: &str = "Usage: player nickname [uid] [nickname]";
if args.len() != 2 {
return Ok(USAGE.to_string());
}
let uid = args[0].parse::<u32>()?;
let nickname = args[1].trim();
if !matches!(nickname.len(), (4..=15)) {
return Ok(String::from(
"nickname should contain at least 4 and not more than 15 characters",
));
}
let Some(player_lock) = state.player_mgr.get_player(uid).await else {
return Ok(String::from("player not found"));
};
let (session_id, basic_info) = {
let mut player = player_lock.lock().await;
player.basic_data_model.nick_name = Some(nickname.to_string());
(
player.current_session_id(),
player.basic_data_model.player_basic_info(),
)
};
if let Some(session) = session_id.map(|id| state.session_mgr.get(id)).flatten() {
session
.notify(PlayerSyncScNotify {
basic_info: Some(basic_info),
..Default::default()
})
.await?;
} else {
state.player_mgr.save_and_remove(uid).await;
}
Ok(format!(
"successfully changed player {uid} nickname to {nickname}"
))
}
pub async fn procedure(
args: &[&str],
state: &ServerState,
) -> Result<String, Box<dyn std::error::Error>> {
const USAGE: &str = "Usage: player procedure [uid] [procedure_id]";
if args.len() != 2 {
return Ok(USAGE.to_string());
}
let uid = args[0].parse::<u32>()?;
let procedure_id = args[1].parse::<i32>()?;
if procedure_id != -1
&& !tables::procedure_config_template_tb::iter()
.any(|tmpl| tmpl.procedure_id == procedure_id)
{
return Ok(format!("procedure_id {procedure_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 = {
let mut player = player_lock.lock().await;
player.basic_data_model.beginner_procedure_id = procedure_id;
player.current_session_id()
};
if session_id.is_none() {
state.player_mgr.save_and_remove(uid).await;
}
Ok(format!(
"successfully changed procedure_id to {procedure_id}"
))
}