feat: Add support for 3.8.5x

This commit is contained in:
amizing25
2026-01-06 23:57:37 +07:00
parent 56bdb1abc1
commit 14692dc78e
17 changed files with 79422 additions and 82321 deletions
+15 -109
View File
@@ -1,4 +1,4 @@
use proto::{Avatar, AvatarSkillTree, MultiPathAvatarInfo};
use proto::{Avatar, AvatarPathData};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
@@ -31,124 +31,30 @@ pub struct FreesrData {
pub main_character: MultiPathAvatar,
#[serde(skip_serializing, skip_deserializing)]
pub march_type: MultiPathAvatar,
// #[serde(skip_serializing, skip_deserializing)]
// pub game_language: AllowedLanguages,
// #[serde(skip_serializing, skip_deserializing)]
// pub voice_langauge: AllowedLanguages,
}
impl FreesrData {
pub fn get_avatar_proto(&self, avatar_id: u32) -> Option<Avatar> {
let avatar = self.avatars.get(&avatar_id)?;
let lightcone = self.lightcones.iter().find(|l| l.equip_avatar == avatar_id);
let relics = self.relics.iter().filter(|r| r.equip_avatar == avatar_id);
// TODO: HARDCODED
let base_avatar_id = if avatar.avatar_id > 8000 {
8001
} else if avatar.avatar_id == 1001 || avatar.avatar_id == 1224 {
1001
} else {
avatar.avatar_id
};
Some(Avatar {
base_avatar_id,
level: avatar.level,
promotion: avatar.promotion,
rank: avatar.data.rank,
skilltree_list: avatar
.data
.skills
.iter()
.map(|v| AvatarSkillTree {
point_id: *v.0,
level: *v.1,
})
.collect::<Vec<_>>(),
equipment_unique_id: lightcone.map(|v| v.get_unique_id()).unwrap_or_default(),
first_met_time_stamp: 1712924677,
equip_relic_list: relics.map(|v| v.into()).collect::<Vec<_>>(),
unk_enhanced_id: avatar.enhanced_id.unwrap_or_default(),
..Default::default()
})
Some(avatar.to_avatar_proto(lightcone))
}
pub fn get_avatar_multipath_proto(&self, avatar_id: u32) -> Option<MultiPathAvatarInfo> {
pub fn get_avatar_path_data_proto(&self, avatar_id: u32) -> Option<AvatarPathData> {
let avatar = self.avatars.get(&avatar_id)?;
let mp_type = MultiPathAvatar::from(avatar_id);
if mp_type == MultiPathAvatar::Unk {
return None;
}
Some(MultiPathAvatarInfo {
avatar_id: mp_type as i32,
rank: avatar.data.rank,
equip_relic_list: self
.relics
.iter()
.filter(|relic| relic.equip_avatar == mp_type as u32)
.map(|relic| relic.into())
.collect(),
multi_path_skill_tree: avatar
.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| v.get_unique_id())
.unwrap_or_default(),
dressed_skin_id: 0,
..Default::default()
})
}
pub fn get_multi_path_info(&self) -> Vec<MultiPathAvatarInfo> {
MultiPathAvatar::to_vec()
.into_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(MultiPathAvatarInfo {
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.into())
.collect(),
multi_path_skill_tree: 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| v.get_unique_id())
.unwrap_or_default(),
dressed_skin_id: 0,
..Default::default()
})
})
.collect()
Some(
avatar.to_avatar_path_data_proto(
self.lightcones
.iter()
.find(|v| v.equip_avatar == avatar_id as u32),
self.relics
.iter()
.filter(|relic| relic.equip_avatar == avatar_id as u32)
.map(|relic| relic.into())
.collect(),
),
)
}
}
+35 -14
View File
@@ -1,8 +1,8 @@
use std::collections::{BTreeMap, HashMap};
use proto::{
Avatar, AvatarSkillTree, AvatarType, BattleAvatar, BattleBuff, ExtraLineupType, Gender,
LineupAvatar, LineupInfo, MultiPathAvatarType, SpBarInfo,
Avatar, AvatarPathData, AvatarPathSkillTree, AvatarSkillTree, AvatarType, BattleAvatar,
BattleBuff, ExtraLineupType, Gender, LineupAvatar, LineupInfo, MultiPathAvatarType, SpBarInfo,
};
use serde::{Deserialize, Serialize};
@@ -135,10 +135,12 @@ pub struct AvatarJson {
pub struct AvatarData {
pub rank: u32,
pub skills: HashMap<u32, u32>,
#[serde(default)]
pub skills_by_anchor_type: HashMap<u32, u32>,
}
impl AvatarJson {
pub fn to_avatar_proto(&self, lightcone: Option<&Lightcone>, relics: Vec<&Relic>) -> Avatar {
pub fn to_avatar_proto(&self, lightcone: Option<&Lightcone>) -> Avatar {
// TODO: HARDCODED
let base_avatar_id = if self.avatar_id > 8000 {
8001
@@ -152,20 +154,39 @@ impl AvatarJson {
base_avatar_id,
level: self.level,
promotion: self.promotion,
rank: self.data.rank,
skilltree_list: self
.data
.skills
.iter()
.map(|v| AvatarSkillTree {
point_id: *v.0,
level: *v.1,
})
.collect::<Vec<_>>(),
equipment_unique_id: lightcone.map(|v| v.get_unique_id()).unwrap_or_default(),
first_met_time_stamp: 1712924677,
equip_relic_list: relics.iter().map(|v| (*v).into()).collect::<Vec<_>>(),
cur_multi_path_avatar_type: self.avatar_id,
has_taken_promotion_reward_list: Vec::with_capacity(0),
is_marked: false,
exp: 0,
..Default::default()
}
}
pub fn to_avatar_path_data_proto(
&self,
lightcone: Option<&Lightcone>,
relics: Vec<&Relic>,
) -> AvatarPathData {
AvatarPathData {
avatar_id: self.avatar_id,
rank: self.data.rank,
equip_relic_list: relics
.iter()
.filter(|relic| relic.equip_avatar == self.avatar_id)
.map(|&relic| relic.into())
.collect(),
avatar_path_skill_tree: self
.data
.skills_by_anchor_type
.iter()
.map(|(&anchor_type, &level)| AvatarPathSkillTree { anchor_type, level })
.collect(),
path_equipment_id: lightcone.map(|v| v.get_unique_id()).unwrap_or_default(),
unk_enhanced_id: self.enhanced_id.unwrap_or_default(),
unlock_timestamp: 0,
dressed_skin_id: 0,
..Default::default()
}
}