more commands, unlock only default avatars at beginning
Implement 'avatar add' command Implemented 'player procedure' command
This commit is contained in:
parent
4b86d62d3f
commit
370f141f88
5 changed files with 149 additions and 38 deletions
53
nap_gameserver/src/commands/avatar.rs
Normal file
53
nap_gameserver/src/commands/avatar.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
use data::tables;
|
||||
use proto::{AddAvatarPerformType, AddAvatarScNotify, PlayerSyncScNotify};
|
||||
|
||||
use crate::ServerState;
|
||||
|
||||
pub async fn add(args: &[&str], 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(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 (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,
|
||||
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}"
|
||||
))
|
||||
}
|
|
@ -5,6 +5,7 @@ use rustyline_async::{Readline, ReadlineEvent, SharedWriter};
|
|||
|
||||
use crate::ServerState;
|
||||
|
||||
mod avatar;
|
||||
mod player;
|
||||
|
||||
pub struct CommandManager {
|
||||
|
@ -80,5 +81,7 @@ impl CommandManager {
|
|||
commands! {
|
||||
player::avatar "[player_uid] [avatar_id]" "changes player avatar for main city";
|
||||
player::nickname "[player_uid] [nickname]" "changes player nickname";
|
||||
player::procedure "[player_uid] [procedure_id]" "changes current beginner procedure id, parameter -1 can be used for skipping it";
|
||||
avatar::add "[player_uid] [avatar_id]" "gives avatar with specified id to player";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ pub async fn avatar(
|
|||
};
|
||||
|
||||
if !tables::avatar_base_template_tb::iter().any(|tmpl| tmpl.id == avatar_id) {
|
||||
return Ok(format!("section with id {avatar_id} doesn't exist"));
|
||||
return Ok(format!("avatar with id {avatar_id} doesn't exist"));
|
||||
}
|
||||
|
||||
let should_save = {
|
||||
|
@ -72,15 +72,13 @@ pub async fn nickname(
|
|||
)
|
||||
};
|
||||
|
||||
if let Some(session_id) = session_id {
|
||||
if let Some(session) = state.session_mgr.get(session_id) {
|
||||
session
|
||||
.notify(PlayerSyncScNotify {
|
||||
basic_info: Some(basic_info),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -89,3 +87,43 @@ pub async fn nickname(
|
|||
"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}"
|
||||
))
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use data::tables;
|
||||
use proto::RoleModelBin;
|
||||
use proto::{AvatarSync, RoleModelBin};
|
||||
|
||||
use crate::logic::role::Avatar;
|
||||
|
||||
|
@ -10,16 +9,34 @@ pub struct RoleModel {
|
|||
impl Default for RoleModel {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
avatar_list: tables::avatar_base_template_tb::iter()
|
||||
.map(|a| a.id)
|
||||
.filter(|tmpl_id| *tmpl_id < 2000)
|
||||
.map(|tmpl_id| Avatar::new(tmpl_id))
|
||||
avatar_list: Self::DEFAULT_AVATARS
|
||||
.iter()
|
||||
.map(|tmpl_id| Avatar::new(*tmpl_id))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RoleModel {
|
||||
const DEFAULT_AVATARS: [u32; 2] = [1011, 1081];
|
||||
|
||||
pub fn add_avatar(&mut self, template_id: u32) {
|
||||
if !self
|
||||
.avatar_list
|
||||
.iter()
|
||||
.any(|a| a.template_id == template_id)
|
||||
{
|
||||
self.avatar_list.push(Avatar::new(template_id));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn avatar_sync(&self) -> AvatarSync {
|
||||
AvatarSync {
|
||||
avatar_list: self.avatar_list.iter().map(Avatar::to_client).collect(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_bin(bin: RoleModelBin) -> Self {
|
||||
Self {
|
||||
avatar_list: bin.avatar_list.into_iter().map(Avatar::from_bin).collect(),
|
||||
|
|
|
@ -2260,7 +2260,7 @@ pub struct PlayerSyncScNotify {
|
|||
#[prost(message, optional, tag = "7")]
|
||||
pub aklfkgodkde: ::core::option::Option<Dbjpegchcch>,
|
||||
#[prost(message, optional, tag = "8")]
|
||||
pub hpebckigilk: ::core::option::Option<Ibgbjekpnnb>,
|
||||
pub avatar: ::core::option::Option<AvatarSync>,
|
||||
#[prost(message, optional, tag = "9")]
|
||||
pub oalcbialjcp: ::core::option::Option<Lokebkejkad>,
|
||||
#[prost(message, optional, tag = "10")]
|
||||
|
@ -2865,8 +2865,8 @@ pub struct Cbjppjfbabb {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Cbegnphfokb {
|
||||
#[prost(enumeration = "Nnhipbjjhpn", tag = "11")]
|
||||
pub struct AddAvatarScNotify {
|
||||
#[prost(enumeration = "AddAvatarPerformType", tag = "11")]
|
||||
pub perform_type: i32,
|
||||
#[prost(bool, tag = "2")]
|
||||
pub aobemkmdkgo: bool,
|
||||
|
@ -13667,7 +13667,7 @@ pub struct Falmoffnjhn {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Ibgbjekpnnb {
|
||||
pub struct AvatarSync {
|
||||
#[prost(message, repeated, tag = "11")]
|
||||
pub avatar_list: ::prost::alloc::vec::Vec<AvatarInfo>,
|
||||
#[prost(uint32, repeated, tag = "14")]
|
||||
|
@ -29107,7 +29107,7 @@ pub struct Hklkphimdcd {
|
|||
#[prost(enumeration = "TimePeriodType", tag = "4")]
|
||||
pub feanogfdcjh: i32,
|
||||
#[prost(enumeration = "AvatarType", tag = "5")]
|
||||
pub hpebckigilk: i32,
|
||||
pub avatar: i32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -37619,7 +37619,7 @@ impl Iojdgcmbnmj {
|
|||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum Fjfehdiinkj {
|
||||
Dcljkmhcfdh = 0,
|
||||
None = 0,
|
||||
Cpehddkeocl = 1,
|
||||
Ceemppmehlf = 2,
|
||||
}
|
||||
|
@ -37630,7 +37630,7 @@ impl Fjfehdiinkj {
|
|||
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||
pub fn as_str_name(&self) -> &'static str {
|
||||
match self {
|
||||
Fjfehdiinkj::Dcljkmhcfdh => "FJFEHDIINKJ_DCLJKMHCFDH",
|
||||
Fjfehdiinkj::None => "FJFEHDIINKJ_NONE",
|
||||
Fjfehdiinkj::Cpehddkeocl => "FJFEHDIINKJ_CPEHDDKEOCL",
|
||||
Fjfehdiinkj::Ceemppmehlf => "FJFEHDIINKJ_CEEMPPMEHLF",
|
||||
}
|
||||
|
@ -37638,7 +37638,7 @@ impl Fjfehdiinkj {
|
|||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"FJFEHDIINKJ_DCLJKMHCFDH" => Some(Self::Dcljkmhcfdh),
|
||||
"FJFEHDIINKJ_NONE" => Some(Self::None),
|
||||
"FJFEHDIINKJ_CPEHDDKEOCL" => Some(Self::Cpehddkeocl),
|
||||
"FJFEHDIINKJ_CEEMPPMEHLF" => Some(Self::Ceemppmehlf),
|
||||
_ => None,
|
||||
|
@ -37649,29 +37649,29 @@ impl Fjfehdiinkj {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum Nnhipbjjhpn {
|
||||
Dcljkmhcfdh = 0,
|
||||
Dcldpjgpkag = 1,
|
||||
Kcaachafbnc = 2,
|
||||
pub enum AddAvatarPerformType {
|
||||
None = 0,
|
||||
ShowPopup = 1,
|
||||
Gacha = 2,
|
||||
}
|
||||
impl Nnhipbjjhpn {
|
||||
impl AddAvatarPerformType {
|
||||
/// String value of the enum field names used in the ProtoBuf definition.
|
||||
///
|
||||
/// The values are not transformed in any way and thus are considered stable
|
||||
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||
pub fn as_str_name(&self) -> &'static str {
|
||||
match self {
|
||||
Nnhipbjjhpn::Dcljkmhcfdh => "NNHIPBJJHPN_DCLJKMHCFDH",
|
||||
Nnhipbjjhpn::Dcldpjgpkag => "NNHIPBJJHPN_DCLDPJGPKAG",
|
||||
Nnhipbjjhpn::Kcaachafbnc => "NNHIPBJJHPN_KCAACHAFBNC",
|
||||
AddAvatarPerformType::None => "ADD_AVATAR_PERFORM_TYPE_NONE",
|
||||
AddAvatarPerformType::ShowPopup => "ADD_AVATAR_PERFORM_TYPE_SHOW_POPUP",
|
||||
AddAvatarPerformType::Gacha => "ADD_AVATAR_PERFORM_TYPE_GACHA",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"NNHIPBJJHPN_DCLJKMHCFDH" => Some(Self::Dcljkmhcfdh),
|
||||
"NNHIPBJJHPN_DCLDPJGPKAG" => Some(Self::Dcldpjgpkag),
|
||||
"NNHIPBJJHPN_KCAACHAFBNC" => Some(Self::Kcaachafbnc),
|
||||
"ADD_AVATAR_PERFORM_TYPE_NONE" => Some(Self::None),
|
||||
"ADD_AVATAR_PERFORM_TYPE_SHOW_POPUP" => Some(Self::ShowPopup),
|
||||
"ADD_AVATAR_PERFORM_TYPE_GACHA" => Some(Self::Gacha),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -44829,7 +44829,7 @@ impl Cmmembfifpk {
|
|||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum Onmblkkmfje {
|
||||
Dcljkmhcfdh = 0,
|
||||
None = 0,
|
||||
Njkogaelffh = 2,
|
||||
Dbldnilkljk = 3,
|
||||
Lcdlmcjihee = 4,
|
||||
|
@ -44842,7 +44842,7 @@ impl Onmblkkmfje {
|
|||
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||
pub fn as_str_name(&self) -> &'static str {
|
||||
match self {
|
||||
Onmblkkmfje::Dcljkmhcfdh => "ONMBLKKMFJE_DCLJKMHCFDH",
|
||||
Onmblkkmfje::None => "ONMBLKKMFJE_NONE",
|
||||
Onmblkkmfje::Njkogaelffh => "ONMBLKKMFJE_NJKOGAELFFH",
|
||||
Onmblkkmfje::Dbldnilkljk => "ONMBLKKMFJE_DBLDNILKLJK",
|
||||
Onmblkkmfje::Lcdlmcjihee => "ONMBLKKMFJE_LCDLMCJIHEE",
|
||||
|
@ -44852,7 +44852,7 @@ impl Onmblkkmfje {
|
|||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"ONMBLKKMFJE_DCLJKMHCFDH" => Some(Self::Dcljkmhcfdh),
|
||||
"ONMBLKKMFJE_NONE" => Some(Self::None),
|
||||
"ONMBLKKMFJE_NJKOGAELFFH" => Some(Self::Njkogaelffh),
|
||||
"ONMBLKKMFJE_DBLDNILKLJK" => Some(Self::Dbldnilkljk),
|
||||
"ONMBLKKMFJE_LCDLMCJIHEE" => Some(Self::Lcdlmcjihee),
|
||||
|
|
Loading…
Reference in a new issue