fix: main character switching

This commit is contained in:
amizing25
2026-01-07 17:19:54 +07:00
parent 779efd2771
commit c2b3bb4dd9
8 changed files with 104 additions and 86 deletions
+4 -7
View File
@@ -34,10 +34,10 @@ pub struct FreesrData {
}
impl FreesrData {
pub fn get_avatar_proto(&self, avatar_id: u32) -> Option<Avatar> {
pub fn get_avatar_proto(&self, avatar_id: u32, mc_id: u32, march_id: u32) -> Option<Avatar> {
let avatar = self.avatars.get(&avatar_id)?;
let lightcone = self.lightcones.iter().find(|l| l.equip_avatar == avatar_id);
Some(avatar.to_avatar_proto(lightcone))
Some(avatar.to_avatar_proto(lightcone, mc_id, march_id))
}
pub fn get_avatar_path_data_proto(&self, avatar_id: u32) -> Option<AvatarPathData> {
@@ -45,13 +45,10 @@ impl FreesrData {
Some(
avatar.to_avatar_path_data_proto(
self.lightcones
.iter()
.find(|v| v.equip_avatar == avatar_id as u32),
self.lightcones.iter().find(|v| v.equip_avatar == avatar_id),
self.relics
.iter()
.filter(|relic| relic.equip_avatar == avatar_id as u32)
.map(|relic| relic.into())
.filter(|relic| relic.equip_avatar == avatar_id)
.collect(),
),
)
+27 -14
View File
@@ -19,8 +19,8 @@ pub enum MultiPathAvatar {
FemalePreservation = 8004,
MaleHarmony = 8005,
FemaleHarmony = 8006,
MaleRememberance = 8007,
FemaleRememberance = 8008,
MaleRemembrance = 8007,
FemaleRemembrance = 8008,
MarchHunt = 1224,
MarchPreservation = 1001,
#[default]
@@ -36,8 +36,8 @@ impl From<u32> for MultiPathAvatar {
8004 => Self::FemalePreservation,
8005 => Self::MaleHarmony,
8006 => Self::FemaleHarmony,
8007 => Self::MaleRememberance,
8008 => Self::FemaleRememberance,
8007 => Self::MaleRemembrance,
8008 => Self::FemaleRemembrance,
1224 => Self::MarchHunt,
1001 => Self::MarchPreservation,
_ => Self::Unk,
@@ -54,8 +54,8 @@ impl From<MultiPathAvatar> for u32 {
MultiPathAvatar::FemalePreservation => 8004,
MultiPathAvatar::MaleHarmony => 8005,
MultiPathAvatar::FemaleHarmony => 8006,
MultiPathAvatar::MaleRememberance => 8007,
MultiPathAvatar::FemaleRememberance => 8008,
MultiPathAvatar::MaleRemembrance => 8007,
MultiPathAvatar::FemaleRemembrance => 8008,
MultiPathAvatar::MarchHunt => 1224,
MultiPathAvatar::MarchPreservation => 1001,
_ => 8006,
@@ -86,8 +86,8 @@ impl MultiPathAvatar {
MultiPathAvatar::MarchHunt => MultiPathAvatarType::Mar7thRogueType,
MultiPathAvatar::MarchPreservation => MultiPathAvatarType::Mar7thKnightType,
MultiPathAvatar::Unk => MultiPathAvatarType::None,
MultiPathAvatar::MaleRememberance => MultiPathAvatarType::BoyMemoryType,
MultiPathAvatar::FemaleRememberance => MultiPathAvatarType::GirlMemoryType,
MultiPathAvatar::MaleRemembrance => MultiPathAvatarType::BoyMemoryType,
MultiPathAvatar::FemaleRemembrance => MultiPathAvatarType::GirlMemoryType,
}
}
@@ -103,8 +103,8 @@ impl MultiPathAvatar {
Self::FemalePreservation,
Self::MaleHarmony,
Self::FemaleHarmony,
Self::MaleRememberance,
Self::FemaleRememberance,
Self::MaleRemembrance,
Self::FemaleRemembrance,
Self::MarchHunt,
Self::MarchPreservation,
]
@@ -140,7 +140,13 @@ pub struct AvatarData {
}
impl AvatarJson {
pub fn to_avatar_proto(&self, lightcone: Option<&Lightcone>) -> Avatar {
/// This should only be used to serialize "BaseAvatar". For example, only 8001 for MC and 1001 for March
pub fn to_avatar_proto(
&self,
lightcone: Option<&Lightcone>,
mc_id: u32,
march_id: u32,
) -> Avatar {
// TODO: HARDCODED
let base_avatar_id = if self.avatar_id > 8000 {
8001
@@ -150,17 +156,25 @@ impl AvatarJson {
self.avatar_id
};
// TODO: HARDCODED
let cur_multi_path_avatar_type = if base_avatar_id == 8001 {
mc_id
} else if base_avatar_id == 1001 {
march_id
} else {
base_avatar_id
};
Avatar {
base_avatar_id,
level: self.level,
promotion: self.promotion,
equipment_unique_id: lightcone.map(|v| v.get_unique_id()).unwrap_or_default(),
first_met_time_stamp: 1712924677,
cur_multi_path_avatar_type: self.avatar_id,
cur_multi_path_avatar_type,
has_taken_promotion_reward_list: Vec::with_capacity(0),
is_marked: false,
exp: 0,
..Default::default()
}
}
@@ -187,7 +201,6 @@ impl AvatarJson {
unk_enhanced_id: self.enhanced_id.unwrap_or_default(),
unlock_timestamp: 0,
dressed_skin_id: 0,
..Default::default()
}
}
+1 -1
View File
@@ -50,7 +50,7 @@ impl Default for Persistent {
Self {
lineups: BTreeMap::from([(0, 1313), (1, 1006), (2, 8001), (3, 1405)]),
position: Default::default(),
main_character: MultiPathAvatar::FemaleRememberance,
main_character: MultiPathAvatar::FemaleRemembrance,
scene: Default::default(),
march_type: MultiPathAvatar::MarchHunt,
// game_language: AllowedLanguages::En,
+20 -24
View File
@@ -1,6 +1,8 @@
use super::*;
pub static UNLOCKED_AVATARS: [u32; 76] = [
pub static BASE_AVATAR_IDS: [u32; 78] = [
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,
@@ -18,24 +20,19 @@ pub async fn on_get_avatar_data_cs_req(
return;
};
// 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
res.avatar_list = BASE_AVATAR_IDS
.into_iter()
.chain(mc_ids.iter().copied())
.chain(march_ids.iter().copied())
.map(|id| {
json.avatars
.get(&id)
.map(|v| v.to_avatar_proto(json.lightcones.iter().find(|v| v.equip_avatar == id)))
.map(|v| {
v.to_avatar_proto(
json.lightcones.iter().find(|v| v.equip_avatar == id),
json.main_character as u32,
json.march_type as u32,
)
})
.unwrap_or(Avatar {
base_avatar_id: id,
level: 80,
@@ -50,21 +47,20 @@ pub async fn on_get_avatar_data_cs_req(
})
.collect();
res.avatar_path_data_info_list = UNLOCKED_AVATARS
.into_iter()
.chain(mc_ids.iter().copied())
.chain(march_ids.iter().copied())
.filter_map(|id| {
json.avatars.get(&id).map(|v| {
v.to_avatar_path_data_proto(
json.lightcones.iter().find(|v| v.equip_avatar == id),
res.avatar_path_data_info_list = json
.avatars
.values()
.map(|avatar| {
avatar.to_avatar_path_data_proto(
json.lightcones
.iter()
.find(|l| l.equip_avatar == avatar.avatar_id),
json.relics
.iter()
.filter(|v| v.equip_avatar == id)
.filter(|r| r.equip_avatar == avatar.avatar_id)
.collect(),
)
})
})
.collect();
}
+5 -3
View File
@@ -3,7 +3,7 @@ use proto::{get_big_data_all_recommend_sc_rsp::RecommendType, *};
use crate::net::PlayerSession;
use super::UNLOCKED_AVATARS;
use super::BASE_AVATAR_IDS;
pub async fn on_get_bag_cs_req(
session: &mut PlayerSession,
@@ -122,7 +122,7 @@ pub async fn on_get_big_data_all_recommend_cs_req(
}
BigDataRecommendType::AvatarRelic => {
res.recommend_type = Some(RecommendType::AvatarRelic(BigDataRecommendAvatarRelic {
recomended_relic_info_list: UNLOCKED_AVATARS
recomended_relic_info_list: BASE_AVATAR_IDS
.into_iter()
.map(|avatar_id| RecommendedRelicInfo {
avatar_id,
@@ -324,7 +324,9 @@ fn build_sync(
) {
let avatar_list = avatar_ids
.iter()
.filter_map(|id| player.get_avatar_proto(*id))
.filter_map(|id| {
player.get_avatar_proto(*id, player.main_character as u32, player.march_type as u32)
})
.collect::<Vec<_>>();
let avatar_path_data_info_list = avatar_ids
+22 -14
View File
@@ -17,7 +17,7 @@ use tokio::{
sync::{Mutex, watch},
};
use crate::util;
use crate::{net::handlers::BASE_AVATAR_IDS, util};
use super::{NetPacket, packet::CommandHandler};
@@ -134,11 +134,18 @@ impl PlayerSession {
// clear all avatars equip item
self.send(PlayerSyncScNotify {
avatar_sync: Some(AvatarSync {
avatar_list: json
.avatars
.values()
.map(|avatar| avatar.to_avatar_proto(Option::None))
.collect::<Vec<_>>(),
avatar_list: BASE_AVATAR_IDS
.into_iter()
.filter_map(|id| {
json.avatars.get(&id).map(|v| {
v.to_avatar_proto(
Option::None,
json.main_character as u32,
json.march_type as u32,
)
})
})
.collect(),
avatar_path_data_info_list: json
.avatars
.values()
@@ -165,16 +172,17 @@ impl PlayerSession {
// Sync new avatars equip item
self.send(PlayerSyncScNotify {
avatar_sync: Some(AvatarSync {
avatar_list: json
.avatars
.values()
.map(|avatar| {
avatar.to_avatar_proto(
json.lightcones
.iter()
.find(|v| v.equip_avatar == avatar.avatar_id),
avatar_list: BASE_AVATAR_IDS
.into_iter()
.filter_map(|avatar_id| {
json.avatars.get(&avatar_id).map(|v| {
v.to_avatar_proto(
json.lightcones.iter().find(|v| v.equip_avatar == avatar_id),
json.main_character as u32,
json.march_type as u32,
)
})
})
.collect(),
avatar_path_data_info_list: json
.avatars
+3 -3
View File
@@ -1,8 +1,8 @@
{
"lineups": {
"0": 1501,
"1": 1502,
"2": 1306,
"0": 1015,
"1": 1306,
"2": 1403,
"3": 1414
},
"position": {
+17 -15
View File
@@ -10224,7 +10224,7 @@ pub struct RevcMsgScNotify {
pub chat_type: i32,
/// offset: 16
#[prost(message, optional, tag = "15")]
pub pfjjlomkbfa: ::core::option::Option<ChatMessageData>,
pub revc_message_data: ::core::option::Option<ChatMessageData>,
/// offset: 40
#[prost(message, optional, tag = "6")]
pub chat_message_extend_data: ::core::option::Option<ChatMessageExtendData>,
@@ -31992,7 +31992,7 @@ pub struct GetUnreleasedBlockInfoCsReq {}
#[derive(proto_derive::CmdID)]
#[cmdid(4108)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Pmpmimckpfd {
pub struct GetUnreleasedBlockInfoScRsp {
/// offset: 32
#[prost(uint32, repeated, tag = "14")]
pub eddajppkcak: ::prost::alloc::vec::Vec<u32>,
@@ -50507,7 +50507,7 @@ pub struct EntityMotion {
#[prost(bool, tag = "15")]
pub kcdabafaoof: bool,
}
/// CmdId: 1459
/// CmdId: 1457
#[derive(proto_derive::CmdID)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SceneEntityMoveCsReq {
@@ -67785,7 +67785,7 @@ impl Moghnjidlbb {
pub enum Bljdhpmkadc {
Gkjbaodjmjg = 0,
Ncnneldocll = 1,
Pfjjlomkbfa = 2,
RevcMessageData = 2,
Oijnlbaaamn = 3,
Ocdmojjnfif = 4,
Kjcfnbcdedc = 5,
@@ -67799,7 +67799,7 @@ impl Bljdhpmkadc {
match self {
Self::Gkjbaodjmjg => "BLJDHPMKADC_GKJBAODJMJG",
Self::Ncnneldocll => "BLJDHPMKADC_NCNNELDOCLL",
Self::Pfjjlomkbfa => "BLJDHPMKADC_PFJJLOMKBFA",
Self::RevcMessageData => "BLJDHPMKADC_RevcMessageData",
Self::Oijnlbaaamn => "BLJDHPMKADC_OIJNLBAAAMN",
Self::Ocdmojjnfif => "BLJDHPMKADC_OCDMOJJNFIF",
Self::Kjcfnbcdedc => "BLJDHPMKADC_KJCFNBCDEDC",
@@ -67810,7 +67810,7 @@ impl Bljdhpmkadc {
match value {
"BLJDHPMKADC_GKJBAODJMJG" => Some(Self::Gkjbaodjmjg),
"BLJDHPMKADC_NCNNELDOCLL" => Some(Self::Ncnneldocll),
"BLJDHPMKADC_PFJJLOMKBFA" => Some(Self::Pfjjlomkbfa),
"BLJDHPMKADC_RevcMessageData" => Some(Self::RevcMessageData),
"BLJDHPMKADC_OIJNLBAAAMN" => Some(Self::Oijnlbaaamn),
"BLJDHPMKADC_OCDMOJJNFIF" => Some(Self::Ocdmojjnfif),
"BLJDHPMKADC_KJCFNBCDEDC" => Some(Self::Kjcfnbcdedc),
@@ -82806,7 +82806,7 @@ pub enum CmdMiscModuleType {
CmdObacgniefdk = 4179,
CmdGetMovieRacingDataScRsp = 4196,
CmdAfmhjbfakpl = 4105,
CmdPmpmimckpfd = 4108,
CmdGetUnreleasedBlockInfoScRsp = 4108,
CmdCancelDirectDeliveryNoticeScRsp = 4152,
CmdGetShareDataCsReq = 4155,
CmdGetUnreleasedBlockInfoCsReq = 4156,
@@ -82853,7 +82853,7 @@ impl CmdMiscModuleType {
Self::CmdObacgniefdk => "CmdOBACGNIEFDK",
Self::CmdGetMovieRacingDataScRsp => "CmdGetMovieRacingDataScRsp",
Self::CmdAfmhjbfakpl => "CmdAFMHJBFAKPL",
Self::CmdPmpmimckpfd => "CmdPMPMIMCKPFD",
Self::CmdGetUnreleasedBlockInfoScRsp => "CmdGetUnreleasedBlockInfoScRsp",
Self::CmdCancelDirectDeliveryNoticeScRsp => {
"CmdCancelDirectDeliveryNoticeScRsp"
}
@@ -82911,7 +82911,9 @@ impl CmdMiscModuleType {
"CmdOBACGNIEFDK" => Some(Self::CmdObacgniefdk),
"CmdGetMovieRacingDataScRsp" => Some(Self::CmdGetMovieRacingDataScRsp),
"CmdAFMHJBFAKPL" => Some(Self::CmdAfmhjbfakpl),
"CmdPMPMIMCKPFD" => Some(Self::CmdPmpmimckpfd),
"CmdGetUnreleasedBlockInfoScRsp" => {
Some(Self::CmdGetUnreleasedBlockInfoScRsp)
}
"CmdCancelDirectDeliveryNoticeScRsp" => {
Some(Self::CmdCancelDirectDeliveryNoticeScRsp)
}
@@ -89598,7 +89600,7 @@ pub enum CmdSceneType {
CmdSceneCastSkillMpUpdateScNotify = 1483,
CmdGetSceneMapInfoScRsp = 1404,
CmdRefreshTriggerByClientScNotify = 1436,
CmdSceneEntityMoveCsReq = 1459,
CmdUnkUnk = 1459,
CmdSceneEntityMoveScRsp = 1428,
CmdEjhfmgfcfkm = 1497,
CmdReEnterLastElementStageScRsp = 1468,
@@ -89622,7 +89624,7 @@ pub enum CmdSceneType {
CmdBgokidmfkla = 1429,
CmdActiveFarmElementCsReq = 1441,
AhnedjbifacEmlpfmejeie = 1476,
AhnedjbifacLalbejcannb = 1457,
CmdSceneEntityMoveCsReq = 1457,
CmdDeactivateFarmElementCsReq = 1470,
CmdGroupStateChangeCsReq = 1463,
CmdActiveFarmElementScRsp = 1432,
@@ -89696,7 +89698,7 @@ impl CmdSceneType {
Self::CmdRefreshTriggerByClientScNotify => {
"CmdRefreshTriggerByClientScNotify"
}
Self::CmdSceneEntityMoveCsReq => "CmdSceneEntityMoveCsReq",
Self::CmdUnkUnk => "CmdUnkUnk",
Self::CmdSceneEntityMoveScRsp => "CmdSceneEntityMoveScRsp",
Self::CmdEjhfmgfcfkm => "CmdEJHFMGFCFKM",
Self::CmdReEnterLastElementStageScRsp => "CmdReEnterLastElementStageScRsp",
@@ -89722,7 +89724,7 @@ impl CmdSceneType {
Self::CmdBgokidmfkla => "CmdBGOKIDMFKLA",
Self::CmdActiveFarmElementCsReq => "CmdActiveFarmElementCsReq",
Self::AhnedjbifacEmlpfmejeie => "AHNEDJBIFAC_EMLPFMEJEIE",
Self::AhnedjbifacLalbejcannb => "AHNEDJBIFAC_LALBEJCANNB",
Self::CmdSceneEntityMoveCsReq => "CmdSceneEntityMoveCsReq",
Self::CmdDeactivateFarmElementCsReq => "CmdDeactivateFarmElementCsReq",
Self::CmdGroupStateChangeCsReq => "CmdGroupStateChangeCsReq",
Self::CmdActiveFarmElementScRsp => "CmdActiveFarmElementScRsp",
@@ -89803,7 +89805,7 @@ impl CmdSceneType {
"CmdRefreshTriggerByClientScNotify" => {
Some(Self::CmdRefreshTriggerByClientScNotify)
}
"CmdSceneEntityMoveCsReq" => Some(Self::CmdSceneEntityMoveCsReq),
"CmdUnkUnk" => Some(Self::CmdUnkUnk),
"CmdSceneEntityMoveScRsp" => Some(Self::CmdSceneEntityMoveScRsp),
"CmdEJHFMGFCFKM" => Some(Self::CmdEjhfmgfcfkm),
"CmdReEnterLastElementStageScRsp" => {
@@ -89831,7 +89833,7 @@ impl CmdSceneType {
"CmdBGOKIDMFKLA" => Some(Self::CmdBgokidmfkla),
"CmdActiveFarmElementCsReq" => Some(Self::CmdActiveFarmElementCsReq),
"AHNEDJBIFAC_EMLPFMEJEIE" => Some(Self::AhnedjbifacEmlpfmejeie),
"AHNEDJBIFAC_LALBEJCANNB" => Some(Self::AhnedjbifacLalbejcannb),
"CmdSceneEntityMoveCsReq" => Some(Self::CmdSceneEntityMoveCsReq),
"CmdDeactivateFarmElementCsReq" => Some(Self::CmdDeactivateFarmElementCsReq),
"CmdGroupStateChangeCsReq" => Some(Self::CmdGroupStateChangeCsReq),
"CmdActiveFarmElementScRsp" => Some(Self::CmdActiveFarmElementScRsp),