Refactor PlayerSession, in-game lineup editing
This commit is contained in:
parent
dfffe1612e
commit
a856f719f0
14 changed files with 231 additions and 86 deletions
|
@ -1,2 +1,5 @@
|
|||
mod global_config;
|
||||
mod player_info;
|
||||
|
||||
pub use global_config::INSTANCE as globals;
|
||||
pub use player_info::PlayerInfo;
|
||||
|
|
57
gameserver/src/game/player_info.rs
Normal file
57
gameserver/src/game/player_info.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
use crate::net::PlayerSession;
|
||||
|
||||
use super::globals;
|
||||
use anyhow::Result;
|
||||
use proto::*;
|
||||
|
||||
pub struct PlayerInfo {
|
||||
pub lineup: LineupInfo,
|
||||
}
|
||||
|
||||
impl PlayerInfo {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
lineup: default_lineup(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn sync_lineup(&self, session: &PlayerSession) -> Result<()> {
|
||||
session
|
||||
.send(
|
||||
CMD_SYNC_LINEUP_NOTIFY,
|
||||
SyncLineupNotify {
|
||||
lineup: Some(self.lineup.clone()),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
fn default_lineup() -> LineupInfo {
|
||||
LineupInfo {
|
||||
plane_id: 10001,
|
||||
name: String::from("Lineup 1"),
|
||||
index: 0,
|
||||
leader_slot: 0,
|
||||
mp: 5,
|
||||
mp_max: 5,
|
||||
avatar_list: globals
|
||||
.lineup
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, id)| LineupAvatar {
|
||||
id: *id,
|
||||
slot: idx as u32,
|
||||
hp: 10000,
|
||||
sp: Some(AmountInfo {
|
||||
cur_amount: 10000,
|
||||
max_amount: 10000,
|
||||
}),
|
||||
satiety: 100,
|
||||
avatar_type: 3,
|
||||
})
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ use proto::*;
|
|||
use crate::{net::PlayerSession, util};
|
||||
|
||||
pub async fn on_player_get_token_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
_body: &PlayerGetTokenCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
@ -21,7 +21,7 @@ pub async fn on_player_get_token_cs_req(
|
|||
}
|
||||
|
||||
pub async fn on_player_login_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
body: &PlayerLoginCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
|
|
@ -8,7 +8,7 @@ static UNLOCKED_AVATARS: [u32; 49] = [
|
|||
];
|
||||
|
||||
pub async fn on_get_avatar_data_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
body: &GetAvatarDataCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
|
|
@ -2,9 +2,11 @@ use super::*;
|
|||
use crate::game::globals;
|
||||
|
||||
pub async fn on_start_cocoon_stage_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
body: &StartCocoonStageCsReq,
|
||||
) -> Result<()> {
|
||||
let player_info = session.player_info();
|
||||
|
||||
let rsp = StartCocoonStageScRsp {
|
||||
retcode: 0,
|
||||
prop_entity_id: body.prop_entity_id,
|
||||
|
@ -14,13 +16,13 @@ pub async fn on_start_cocoon_stage_cs_req(
|
|||
stage_id: 201012311,
|
||||
logic_random_seed: 4444,
|
||||
battle_id: 1,
|
||||
battle_avatar_list: globals
|
||||
battle_avatar_list: player_info
|
||||
.lineup
|
||||
.avatar_list
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, id)| BattleAvatar {
|
||||
index: idx as u32,
|
||||
id: *id,
|
||||
.map(|avatar| BattleAvatar {
|
||||
index: avatar.slot,
|
||||
id: avatar.id,
|
||||
level: 80,
|
||||
promotion: 6,
|
||||
rank: 6,
|
||||
|
@ -55,7 +57,7 @@ pub async fn on_start_cocoon_stage_cs_req(
|
|||
}
|
||||
|
||||
pub async fn on_pve_battle_result_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
body: &PveBattleResultCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
|
|
@ -1,86 +1,47 @@
|
|||
use super::*;
|
||||
use crate::game::globals;
|
||||
|
||||
pub async fn on_get_all_lineup_data_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
_body: &GetAllLineupDataCsReq,
|
||||
) -> Result<()> {
|
||||
let player_info = session.player_info();
|
||||
|
||||
session
|
||||
.send(
|
||||
CMD_GET_ALL_LINEUP_DATA_SC_RSP,
|
||||
GetAllLineupDataScRsp {
|
||||
retcode: 0,
|
||||
cur_index: 0,
|
||||
lineup_list: vec![LineupInfo {
|
||||
plane_id: 10001,
|
||||
name: String::from("Lineup 1"),
|
||||
index: 0,
|
||||
avatar_list: globals
|
||||
.lineup
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, id)| LineupAvatar {
|
||||
id: *id,
|
||||
slot: idx as u32,
|
||||
hp: 10000,
|
||||
sp: Some(AmountInfo {
|
||||
cur_amount: 10000,
|
||||
max_amount: 10000,
|
||||
}),
|
||||
satiety: 100,
|
||||
avatar_type: 3,
|
||||
})
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}],
|
||||
lineup_list: vec![player_info.lineup.clone()],
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn on_get_cur_lineup_data_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
_body: &GetCurLineupDataCsReq,
|
||||
) -> Result<()> {
|
||||
let player_info = session.player_info();
|
||||
|
||||
session
|
||||
.send(
|
||||
CMD_GET_CUR_LINEUP_DATA_SC_RSP,
|
||||
GetCurLineupDataScRsp {
|
||||
retcode: 0,
|
||||
lineup: Some(LineupInfo {
|
||||
plane_id: 10001,
|
||||
name: String::from("Lineup 1"),
|
||||
index: 0,
|
||||
leader_slot: 0,
|
||||
mp: 5,
|
||||
mp_max: 5,
|
||||
avatar_list: globals
|
||||
.lineup
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, id)| LineupAvatar {
|
||||
id: *id,
|
||||
slot: idx as u32,
|
||||
hp: 10000,
|
||||
sp: Some(AmountInfo {
|
||||
cur_amount: 10000,
|
||||
max_amount: 10000,
|
||||
}),
|
||||
satiety: 100,
|
||||
avatar_type: 3,
|
||||
})
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}),
|
||||
lineup: Some(player_info.lineup.clone()),
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn on_change_lineup_leader_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
body: &ChangeLineupLeaderCsReq,
|
||||
) -> Result<()> {
|
||||
let mut player_info = session.player_info_mut();
|
||||
player_info.lineup.leader_slot = body.slot;
|
||||
|
||||
session
|
||||
.send(
|
||||
CMD_CHANGE_LINEUP_LEADER_SC_RSP,
|
||||
|
@ -91,3 +52,101 @@ pub async fn on_change_lineup_leader_cs_req(
|
|||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn on_join_lineup_cs_req(session: &PlayerSession, body: &JoinLineupCsReq) -> Result<()> {
|
||||
let mut player_info = session.player_info_mut();
|
||||
|
||||
if !(0..4).contains(&body.slot) {
|
||||
return session
|
||||
.send(
|
||||
CMD_JOIN_LINEUP_CS_REQ,
|
||||
JoinLineupScRsp {
|
||||
retcode: Retcode::RetLineupInvalidMemberPos as u32,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
if player_info
|
||||
.lineup
|
||||
.avatar_list
|
||||
.iter()
|
||||
.any(|avatar| avatar.slot == body.slot)
|
||||
{
|
||||
return session
|
||||
.send(
|
||||
CMD_JOIN_LINEUP_CS_REQ,
|
||||
JoinLineupScRsp {
|
||||
retcode: Retcode::RetLineupAvatarAlreadyInit as u32,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
player_info
|
||||
.lineup
|
||||
.avatar_list
|
||||
.push(lineup_avatar(body.base_avatar_id, body.slot));
|
||||
|
||||
player_info.sync_lineup(session).await?;
|
||||
session
|
||||
.send(CMD_JOIN_LINEUP_SC_RSP, JoinLineupScRsp::default())
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn on_replace_lineup_cs_req(
|
||||
session: &PlayerSession,
|
||||
body: &ReplaceLineupCsReq,
|
||||
) -> Result<()> {
|
||||
let mut player_info = session.player_info_mut();
|
||||
|
||||
player_info.lineup.avatar_list.clear();
|
||||
for slot_info in &body.lineup_slots {
|
||||
player_info
|
||||
.lineup
|
||||
.avatar_list
|
||||
.push(lineup_avatar(slot_info.id, slot_info.slot));
|
||||
}
|
||||
player_info.lineup.leader_slot = body.leader_slot;
|
||||
|
||||
player_info.sync_lineup(session).await?;
|
||||
session
|
||||
.send(CMD_REPLACE_LINEUP_SC_RSP, ReplaceLineupScRsp::default())
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn on_quit_lineup_cs_req(session: &PlayerSession, body: &QuitLineupCsReq) -> Result<()> {
|
||||
let mut player_info = session.player_info_mut();
|
||||
player_info
|
||||
.lineup
|
||||
.avatar_list
|
||||
.retain(|avatar| avatar.id != body.base_avatar_id);
|
||||
|
||||
player_info.sync_lineup(session).await?;
|
||||
session
|
||||
.send(
|
||||
CMD_QUIT_LINEUP_SC_RSP,
|
||||
QuitLineupScRsp {
|
||||
plane_id: body.plane_id,
|
||||
is_mainline: !body.is_virtual,
|
||||
is_virtual: body.is_virtual,
|
||||
base_avatar_id: body.base_avatar_id,
|
||||
retcode: 0,
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
fn lineup_avatar(id: u32, slot: u32) -> LineupAvatar {
|
||||
LineupAvatar {
|
||||
id,
|
||||
slot,
|
||||
hp: 10000,
|
||||
sp: Some(AmountInfo {
|
||||
cur_amount: 10000,
|
||||
max_amount: 10000,
|
||||
}),
|
||||
satiety: 100,
|
||||
avatar_type: 3,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ static FINISHED_MAIN_MISSIONS: [u32; 365] = [
|
|||
];
|
||||
|
||||
pub async fn on_get_mission_status_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
body: &GetMissionStatusCsReq,
|
||||
) -> Result<()> {
|
||||
let rsp = GetMissionStatusScRsp {
|
||||
|
|
|
@ -46,7 +46,7 @@ macro_rules! dummy {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn send_dummy_response(&mut self, req_id: u16) -> Result<()> {
|
||||
pub async fn send_dummy_response(&self, req_id: u16) -> Result<()> {
|
||||
let cmd_type = match req_id {
|
||||
$(
|
||||
x if x == [<Cmd $cmd CsReq>] as u16 => [<Cmd $cmd ScRsp>] as u16,
|
||||
|
@ -61,7 +61,7 @@ macro_rules! dummy {
|
|||
}
|
||||
.into();
|
||||
|
||||
self.client_socket.write_all(&payload).await?;
|
||||
self.client_socket().await.write_all(&payload).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::util;
|
|||
use super::*;
|
||||
|
||||
pub async fn on_get_basic_info_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
_body: &GetBasicInfoCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
@ -19,7 +19,7 @@ pub async fn on_get_basic_info_cs_req(
|
|||
}
|
||||
|
||||
pub async fn on_get_hero_basic_type_info_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
_body: &GetHeroBasicTypeInfoCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
@ -40,7 +40,7 @@ pub async fn on_get_hero_basic_type_info_cs_req(
|
|||
}
|
||||
|
||||
pub async fn on_player_heart_beat_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
body: &PlayerHeartBeatCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use super::*;
|
||||
|
||||
pub async fn on_get_cur_scene_info_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
_body: &GetCurSceneInfoCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
|
|
@ -8,7 +8,7 @@ static TUTORIAL_IDS: [u32; 55] = [
|
|||
];
|
||||
|
||||
pub async fn on_get_tutorial_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
_body: &GetTutorialCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
@ -29,7 +29,7 @@ pub async fn on_get_tutorial_cs_req(
|
|||
}
|
||||
|
||||
pub async fn on_get_tutorial_guide_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
_body: &GetTutorialGuideCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
@ -44,7 +44,7 @@ pub async fn on_get_tutorial_guide_cs_req(
|
|||
}
|
||||
|
||||
pub async fn on_unlock_tutorial_guide_cs_req(
|
||||
session: &mut PlayerSession,
|
||||
session: &PlayerSession,
|
||||
body: &UnlockTutorialGuideCsReq,
|
||||
) -> Result<()> {
|
||||
session
|
||||
|
|
|
@ -62,13 +62,13 @@ macro_rules! trait_handler {
|
|||
pub trait CommandHandler {
|
||||
$(
|
||||
paste! {
|
||||
async fn [<on_$name:snake>](session: &mut PlayerSession, body: &$name) -> Result<()> {
|
||||
async fn [<on_$name:snake>](session: &PlayerSession, body: &$name) -> Result<()> {
|
||||
[<on_$name:snake>](session, body).await
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
async fn on_message(session: &mut PlayerSession, cmd_type: u16, payload: Vec<u8>) -> Result<()> {
|
||||
async fn on_message(session: &PlayerSession, cmd_type: u16, payload: Vec<u8>) -> Result<()> {
|
||||
use ::prost::Message;
|
||||
if PlayerSession::should_send_dummy_rsp(cmd_type) {
|
||||
session.send_dummy_response(cmd_type).await?;
|
||||
|
@ -641,18 +641,18 @@ trait_handler! {
|
|||
// ExtraLineupDestroyNotify 763;
|
||||
// GetLineupAvatarDataCsReq 768;
|
||||
// SwitchLineupIndexScRsp 795;
|
||||
// JoinLineupCsReq 702;
|
||||
JoinLineupCsReq 702;
|
||||
// GetAllLineupDataScRsp 716;
|
||||
// SetLineupNameCsReq 742;
|
||||
// ChangeLineupLeaderScRsp 733;
|
||||
ChangeLineupLeaderCsReq 706;
|
||||
// ReplaceLineupCsReq 785;
|
||||
ReplaceLineupCsReq 785;
|
||||
// SwapLineupCsReq 786;
|
||||
// QuitLineupScRsp 743;
|
||||
// GetLineupAvatarDataScRsp 796;
|
||||
// ReplaceLineupScRsp 756;
|
||||
// GetStageLineupCsReq 734;
|
||||
// QuitLineupCsReq 719;
|
||||
QuitLineupCsReq 719;
|
||||
// SetLineupNameScRsp 737;
|
||||
// SwitchLineupIndexCsReq 759;
|
||||
GetCurLineupDataCsReq 762;
|
||||
|
|
|
@ -1,26 +1,38 @@
|
|||
use anyhow::Result;
|
||||
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
|
||||
use prost::Message;
|
||||
use tokio::{io::AsyncWriteExt, net::TcpStream};
|
||||
use std::sync::Arc;
|
||||
use tokio::{
|
||||
io::AsyncWriteExt,
|
||||
net::TcpStream,
|
||||
sync::{Mutex, MutexGuard},
|
||||
};
|
||||
|
||||
use crate::game::PlayerInfo;
|
||||
|
||||
use super::{packet::CommandHandler, NetPacket};
|
||||
|
||||
pub struct PlayerSession {
|
||||
pub(crate) client_socket: TcpStream,
|
||||
client_socket: Arc<Mutex<TcpStream>>,
|
||||
player_info: Arc<AtomicRefCell<PlayerInfo>>,
|
||||
}
|
||||
|
||||
impl PlayerSession {
|
||||
pub const fn new(client_socket: TcpStream) -> Self {
|
||||
Self { client_socket }
|
||||
pub fn new(client_socket: TcpStream) -> Self {
|
||||
Self {
|
||||
client_socket: Arc::new(Mutex::new(client_socket)),
|
||||
player_info: Arc::new(AtomicRefCell::new(PlayerInfo::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(&mut self) -> Result<()> {
|
||||
loop {
|
||||
let net_packet = NetPacket::read(&mut self.client_socket).await?;
|
||||
let net_packet = NetPacket::read(&mut *self.client_socket().await).await?;
|
||||
Self::on_message(self, net_packet.cmd_type, net_packet.body).await?;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send(&mut self, cmd_type: u16, body: impl Message) -> Result<()> {
|
||||
pub async fn send(&self, cmd_type: u16, body: impl Message) -> Result<()> {
|
||||
let mut buf = Vec::new();
|
||||
body.encode(&mut buf)?;
|
||||
|
||||
|
@ -31,9 +43,21 @@ impl PlayerSession {
|
|||
}
|
||||
.into();
|
||||
|
||||
self.client_socket.write_all(&payload).await?;
|
||||
self.client_socket().await.write_all(&payload).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn client_socket(&self) -> MutexGuard<'_, TcpStream> {
|
||||
self.client_socket.lock().await
|
||||
}
|
||||
|
||||
pub fn player_info(&self) -> AtomicRef<PlayerInfo> {
|
||||
self.player_info.borrow()
|
||||
}
|
||||
|
||||
pub fn player_info_mut(&self) -> AtomicRefMut<PlayerInfo> {
|
||||
self.player_info.borrow_mut()
|
||||
}
|
||||
}
|
||||
|
||||
// Auto implemented
|
||||
|
|
|
@ -9165,7 +9165,7 @@ pub struct VirtualLineupDestroyNotify {
|
|||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Kcllnhmojig {
|
||||
pub struct LineupSlotInfo {
|
||||
#[prost(uint32, tag = "11")]
|
||||
pub slot: u32,
|
||||
#[prost(enumeration = "AvatarType", tag = "14")]
|
||||
|
@ -9182,13 +9182,13 @@ pub struct ReplaceLineupCsReq {
|
|||
#[prost(uint32, tag = "6")]
|
||||
pub djdbkfnekpf: u32,
|
||||
#[prost(uint32, tag = "12")]
|
||||
pub hpammbapokf: u32,
|
||||
pub leader_slot: u32,
|
||||
#[prost(bool, tag = "10")]
|
||||
pub is_virtual: bool,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub plane_id: u32,
|
||||
#[prost(message, repeated, tag = "5")]
|
||||
pub jkifflmenfn: ::prost::alloc::vec::Vec<Kcllnhmojig>,
|
||||
pub lineup_slots: ::prost::alloc::vec::Vec<LineupSlotInfo>,
|
||||
#[prost(enumeration = "ExtraLineupType", tag = "9")]
|
||||
pub extra_lineup_type: i32,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue