From ad4c48a0cd1f09f31e1c12b32dab168ce7fb80cd Mon Sep 17 00:00:00 2001 From: amizing25 Date: Mon, 20 Jan 2025 05:45:17 +0700 Subject: [PATCH] fix: Fix avatar & inventory sync stuff --- gameserver/src/net/handlers/avatar.rs | 34 ++++++---- gameserver/src/net/handlers/chat.rs | 3 + gameserver/src/net/handlers/player.rs | 35 +--------- gameserver/src/net/tools.rs | 92 ++++++++++++++++++++++++--- 4 files changed, 111 insertions(+), 53 deletions(-) diff --git a/gameserver/src/net/handlers/avatar.rs b/gameserver/src/net/handlers/avatar.rs index f7b4c9b..2ec83dc 100644 --- a/gameserver/src/net/handlers/avatar.rs +++ b/gameserver/src/net/handlers/avatar.rs @@ -2,11 +2,11 @@ use crate::net::tools::FreesrData; use super::*; -static UNLOCKED_AVATARS: [u32; 63] = [ - 8001, 1001, 1002, 1003, 1004, 1005, 1006, 1008, 1009, 1013, 1101, 1102, 1103, 1104, 1105, 1106, - 1107, 1108, 1109, 1110, 1111, 1112, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, - 1211, 1212, 1213, 1214, 1215, 1217, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1312, - 1315, 1310, 1314, 1218, 1221, 1220, 1222, 1223, 1317, 1313, 1225, 1402, 1401, 1404, 1403 +static UNLOCKED_AVATARS: [u32; 61] = [ + 1002, 1003, 1004, 1005, 1006, 1008, 1009, 1013, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, + 1109, 1110, 1111, 1112, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, + 1213, 1214, 1215, 1217, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1312, 1315, 1310, + 1314, 1218, 1221, 1220, 1222, 1223, 1317, 1313, 1225, 1402, 1401, 1404, 1403, ]; pub async fn on_get_avatar_data_cs_req( @@ -15,29 +15,41 @@ pub async fn on_get_avatar_data_cs_req( res: &mut GetAvatarDataScRsp, ) { let json = FreesrData::load().await; + + // TODO: HARDCODED + let mc_ids = if json.main_character.get_gender() == Gender::Man { + [8001, 8003, 8005, 8007] + } else { + [8002, 8004, 8006, 8008] + }; + + let march_ids = [1001, 1224]; + res.is_get_all = body.is_get_all; res.avatar_list = UNLOCKED_AVATARS - .iter() + .into_iter() + .chain(mc_ids.iter().copied()) + .chain(march_ids.iter().copied()) .map(|id| { json.avatars - .get(id) + .get(&id) .map(|v| { v.to_avatar_proto( - json.lightcones.iter().find(|v| v.equip_avatar == *id), + json.lightcones.iter().find(|v| v.equip_avatar == id), json.relics .iter() - .filter(|v| v.equip_avatar == *id) + .filter(|v| v.equip_avatar == id) .collect(), ) }) .unwrap_or(Avatar { - base_avatar_id: *id, + base_avatar_id: id, level: 80, promotion: 6, rank: 6, skilltree_list: (1..=4) .map(|m| AvatarSkillTree { - point_id: (*id) * 1000 + m, + point_id: id * 1000 + m, level: 1, }) .collect(), diff --git a/gameserver/src/net/handlers/chat.rs b/gameserver/src/net/handlers/chat.rs index 25a4f07..6934c45 100644 --- a/gameserver/src/net/handlers/chat.rs +++ b/gameserver/src/net/handlers/chat.rs @@ -114,6 +114,8 @@ pub async fn on_send_msg_cs_req( .await .unwrap(); + sync_player(session, json).await; + session .send(RevcMsgScNotify { msg_type: body.msg_type, @@ -201,6 +203,7 @@ async fn sync_player(session: &mut PlayerSession, json: FreesrData) { .map(|avatar| avatar.to_avatar_proto(Option::None, vec![])) .collect::>(), }), + multi_path_avatar_type_info_list: json.get_multi_path_info(), ..Default::default() }) .await diff --git a/gameserver/src/net/handlers/player.rs b/gameserver/src/net/handlers/player.rs index bece613..3090768 100644 --- a/gameserver/src/net/handlers/player.rs +++ b/gameserver/src/net/handlers/player.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::net::tools::{FreesrData, MultiPathAvatar}; +use crate::net::tools::FreesrData; use super::*; @@ -67,36 +67,5 @@ pub async fn on_get_multi_path_avatar_info_cs_req( (1001, json.march_type.get_type().into()), ]); - res.multi_path_avatar_type_info_list = MultiPathAvatar::to_vec() - .iter() - .filter_map(|mp_type| { - let avatar_info = json.avatars.get(&((*mp_type) as u32))?; - Some(MultiPathAvatarTypeInfo { - avatar_id: *mp_type as i32, - rank: avatar_info.data.rank, - equip_relic_list: json - .relics - .iter() - .filter(|relic| relic.equip_avatar == *mp_type as u32) - .map(|relic| relic.to_equipment_relic_proto()) - .collect(), - skilltree_list: avatar_info - .data - .skills - .iter() - .map(|(point_id, level)| AvatarSkillTree { - point_id: *point_id, - level: *level, - }) - .collect(), - path_equipment_id: json - .lightcones - .iter() - .find(|v| v.equip_avatar == *mp_type as u32) - .map(|v| v.internal_uid) - .unwrap_or_default(), - dressed_skin_id: 0, - }) - }) - .collect(); + res.multi_path_avatar_type_info_list = json.get_multi_path_info(); } diff --git a/gameserver/src/net/tools.rs b/gameserver/src/net/tools.rs index b7b11ea..4c5923a 100644 --- a/gameserver/src/net/tools.rs +++ b/gameserver/src/net/tools.rs @@ -29,8 +29,17 @@ pub struct AvatarData { impl AvatarJson { pub fn to_avatar_proto(&self, lightcone: Option<&Lightcone>, relics: Vec<&Relic>) -> Avatar { + // TODO: HARDCODED + let base_avatar_id = if self.avatar_id > 8000 { + 8001 + } else if self.avatar_id == 1001 || self.avatar_id == 1224 { + 1001 + } else { + self.avatar_id + }; + Avatar { - base_avatar_id: self.avatar_id, + base_avatar_id, level: self.level, promotion: self.promotion, rank: self.data.rank, @@ -44,7 +53,7 @@ impl AvatarJson { }) .collect::>(), equipment_unique_id: if let Some(lc) = lightcone { - // ? + // TODO: HARDCODED LIGHTCONE ID 2000 + lc.internal_uid } else { 0 @@ -517,9 +526,10 @@ pub struct FreesrData { pub position: Position, #[serde(default, skip_serializing)] pub scene: Scene, - #[serde(default, skip_serializing)] + + #[serde(skip_serializing, skip_deserializing)] pub main_character: MultiPathAvatar, - #[serde(default, skip_serializing)] + #[serde(skip_serializing, skip_deserializing)] pub march_type: MultiPathAvatar, } @@ -531,9 +541,7 @@ pub struct Persistent { pub position: Position, #[serde(default)] pub scene: Scene, - #[serde(default)] pub main_character: MultiPathAvatar, - #[serde(default)] pub march_type: MultiPathAvatar, } @@ -548,26 +556,27 @@ impl Default for Persistent { Self { lineups, position: Default::default(), - main_character: Default::default(), + main_character: MultiPathAvatar::FemaleRememberance, scene: Default::default(), march_type: MultiPathAvatar::MarchHunt, } } } -#[derive(Serialize, Deserialize, Clone, Debug, Copy, Default, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Clone, Debug, Copy, PartialEq, Eq, Default)] +#[repr(u32)] pub enum MultiPathAvatar { MalePyhsical = 8001, FemalePhysical = 8002, MalePreservation = 8003, FemalePreservation = 8004, MaleHarmony = 8005, - #[default] FemaleHarmony = 8006, MaleRememberance = 8007, FemaleRememberance = 8008, MarchHunt = 1224, MarchPreservation = 1001, + #[default] Unk = 0, } @@ -589,6 +598,24 @@ impl From for MultiPathAvatar { } } +impl From for u32 { + fn from(value: MultiPathAvatar) -> Self { + match value { + MultiPathAvatar::MalePyhsical => 8001, + MultiPathAvatar::FemalePhysical => 8002, + MultiPathAvatar::MalePreservation => 8003, + MultiPathAvatar::FemalePreservation => 8004, + MultiPathAvatar::MaleHarmony => 8005, + MultiPathAvatar::FemaleHarmony => 8006, + MultiPathAvatar::MaleRememberance => 8007, + MultiPathAvatar::FemaleRememberance => 8008, + MultiPathAvatar::MarchHunt => 1224, + MultiPathAvatar::MarchPreservation => 1001, + _ => 8006, + } + } +} + impl MultiPathAvatar { #[allow(unused)] pub fn get_gender(&self) -> Gender { @@ -617,6 +644,10 @@ impl MultiPathAvatar { } } + pub fn is_mc(&self) -> bool { + (*self as u32) > 8000 + } + pub fn to_vec() -> Vec { vec![ Self::MalePyhsical, @@ -654,6 +685,7 @@ impl FreesrData { json.position = json2.position; json.scene = json2.scene; json.main_character = json2.main_character; + json.march_type = json2.march_type; json.verify_lineup().await; @@ -696,4 +728,46 @@ impl FreesrData { ) .await; } + + pub fn get_multi_path_info(&self) -> Vec { + MultiPathAvatar::to_vec() + .iter() + .filter_map(|mp_type| { + if mp_type.is_mc() && mp_type.get_gender() != self.main_character.get_gender() { + return Option::None; + } + + let avatar_info = self.avatars.get(&((*mp_type) as u32))?; + Some(MultiPathAvatarTypeInfo { + avatar_id: *mp_type as i32, + rank: avatar_info.data.rank, + equip_relic_list: self + .relics + .iter() + .filter(|relic| relic.equip_avatar == *mp_type as u32) + .map(|relic| relic.to_equipment_relic_proto()) + .collect(), + skilltree_list: avatar_info + .data + .skills + .iter() + .map(|(point_id, level)| AvatarSkillTree { + point_id: *point_id, + level: *level, + }) + .collect(), + path_equipment_id: self + .lightcones + .iter() + .find(|v| v.equip_avatar == *mp_type as u32) + .map(|v| { + // TODO: HARDCODED LIGHTCONE ID + 2000 + v.internal_uid + }) + .unwrap_or_default(), + dressed_skin_id: 0, + }) + }) + .collect() + } }