Implement #[property_accessors] proc macro to reduce boilerplate for accessing optional properties

This commit is contained in:
xeon 2024-12-12 21:53:27 +03:00
parent ec9ddd4ef7
commit a266b2e12b
13 changed files with 182 additions and 230 deletions

View file

@ -75,7 +75,7 @@ impl DbContext {
}
pub async fn save_player_data(&self, last_uid: u32, player_info: &PlayerInfo) -> Result<()> {
let player_uid = player_info.uid.unwrap();
let player_uid = *player_info.uid();
let _: PlayerData = self
.0

View file

@ -73,8 +73,8 @@ pub fn execute_action(
match action {
ActionCreateNpcCfg { id, tag_id } => {
let uid = session.uid_counter.next();
let sdg = session.player_info.single_dungeon_group.as_mut().unwrap();
sdg.npcs.as_mut().unwrap().insert(
let sdg = session.player_info.single_dungeon_group_mut();
sdg.npcs_mut().insert(
scene_uid,
uid,
NpcInfo {
@ -100,10 +100,8 @@ pub fn execute_action(
section_listen_events,
..
} => {
let sdg = session.player_info.single_dungeon_group.as_mut().unwrap();
sdg.npcs
.as_ref()
.unwrap()
let sdg = session.player_info.single_dungeon_group_mut();
sdg.npcs()
.iter()
.filter(|(s_uid, _, _)| **s_uid == scene_uid)
.for_each(|(_, &uid, npc)| {
@ -133,12 +131,7 @@ pub fn execute_action(
});
}
ActionSetMainCityObjectState { object_state, .. } => {
let main_city_objects_state = session
.player_info
.main_city_objects_state
.as_mut()
.unwrap();
let main_city_objects_state = session.player_info.main_city_objects_state_mut();
object_state
.iter()
.for_each(|(&obj, &state)| main_city_objects_state.insert(obj, state));

View file

@ -323,7 +323,7 @@ pub fn create_starting_player_info(uid: u64, nick_name: &str) -> (UidCounter, Pl
.filter(|tmpl| tmpl.camp() != 0)
.for_each(|tmpl| {
let uid = counter.next();
player_info.items.as_mut().unwrap().insert(
player_info.items_mut().insert(
uid,
ItemInfo::AvatarInfo {
uid,
@ -354,7 +354,7 @@ pub fn create_starting_player_info(uid: u64, nick_name: &str) -> (UidCounter, Pl
.iter()
.for_each(|tmpl| {
let uid = counter.next();
player_info.items.as_mut().unwrap().insert(
player_info.items_mut().insert(
uid,
ItemInfo::Weapon {
uid,

View file

@ -75,9 +75,7 @@ pub async fn on_rpc_weapon_dress_arg(
) -> Result<RpcWeaponDressRet, i32> {
let Some(target_avatar_uid) = session
.player_info
.items
.as_ref()
.unwrap()
.items()
.iter()
.find(|(_, item)| {
if let ItemInfo::AvatarInfo { id, .. } = item {
@ -94,9 +92,7 @@ pub async fn on_rpc_weapon_dress_arg(
let Some((_, ItemInfo::Weapon { avatar_uid, .. })) = session
.player_info
.items
.as_mut()
.unwrap()
.items_mut()
.iter_mut()
.find(|(uid, _)| (*uid & 0xFFFFFFFF) as u32 == arg.weapon_uid)
else {
@ -124,9 +120,7 @@ pub async fn on_rpc_weapon_un_dress_arg(
) -> Result<RpcWeaponUnDressRet, i32> {
let Some(target_avatar_uid) = session
.player_info
.items
.as_ref()
.unwrap()
.items()
.iter()
.find(|(_, item)| {
if let ItemInfo::AvatarInfo { id, .. } = item {
@ -143,9 +137,7 @@ pub async fn on_rpc_weapon_un_dress_arg(
session
.player_info
.items
.as_mut()
.unwrap()
.items_mut()
.iter_mut()
.for_each(|(_, item)| {
if let ItemInfo::Weapon { avatar_uid, .. } = item {

View file

@ -118,17 +118,13 @@ pub async fn on_rpc_mod_time_arg(
debug!("{arg:?}");
let player_info = &mut session.player_info;
let scene_uid = player_info.scene_uid.unwrap();
let dungeon_collection = player_info.dungeon_collection.as_mut().unwrap();
let scene_uid = *player_info.scene_uid();
let dungeon_collection = player_info.dungeon_collection_mut();
if let Some(protocol::scene_info::SceneInfo::Hall {
main_city_time_info,
..
}) = dungeon_collection
.scenes
.as_mut()
.unwrap()
.get_mut(&scene_uid)
}) = dungeon_collection.scenes_mut().get_mut(&scene_uid)
{
let prev_time = main_city_time_info.initial_time;
main_city_time_info.initial_time = match arg.time_period {

View file

@ -99,8 +99,8 @@ pub async fn on_rpc_player_transaction_arg(
session: &mut PlayerSession,
_: RpcPlayerTransactionArg,
) -> Result<RpcPlayerTransactionRet, i32> {
let player_uid = session.player_info.uid.unwrap_or_default();
let scene_uid = session.player_info.scene_uid.unwrap_or_default();
let player_uid = session.player_info.uid();
let scene_uid = session.player_info.scene_uid();
Ok(RpcPlayerTransactionRet {
retcode: 0,

View file

@ -17,20 +17,18 @@ pub async fn on_rpc_get_archive_info_arg(
session: &mut PlayerSession,
_: RpcGetArchiveInfoArg,
) -> Result<RpcGetArchiveInfoRet, i32> {
let archive_info = session.player_info.archive_info.as_ref().unwrap();
let archive_info = session.player_info.archive_info();
Ok(RpcGetArchiveInfoRet {
retcode: 0,
archive_info: ArchiveInfo {
hollow_archive_id_list: archive_info
.hollow_archive_id
.as_ref()
.map(|set| set.iter().map(|id| *id as u32).collect())
.unwrap_or_default(),
.hollow_archive_id()
.iter()
.map(|id| *id as u32)
.collect(),
videotaps_info: archive_info
.videotaps_info
.as_ref()
.unwrap()
.videotaps_info()
.iter()
.map(|(id, videotape)| VideotapeInfo {
archive_file_id: *id as u32,
@ -52,10 +50,10 @@ pub async fn on_rpc_get_yorozuya_info_arg(
retcode: 0,
yorozuya_info: YorozuyaInfo {
unlock_hollow_id_list: yorozuya_info
.unlock_hollow_id
.as_ref()
.map(|list| list.iter().map(|id| *id as u32).collect())
.unwrap_or_default(),
.unlock_hollow_id()
.iter()
.map(|id| *id as u32)
.collect(),
},
})
}

View file

@ -15,14 +15,7 @@ pub async fn on_rpc_enter_world_arg(
) -> Result<RpcEnterWorldRet, i32> {
let player_info = &mut session.player_info;
if player_info
.dungeon_collection
.as_ref()
.unwrap()
.default_scene_uid
.unwrap()
== 0
{
if *player_info.dungeon_collection().default_scene_uid() == 0 {
let dungeon_uid = session.uid_counter.next();
let scene_uid = session.uid_counter.next();
@ -79,38 +72,25 @@ pub async fn on_rpc_enter_world_arg(
},
};
let dungeon_collection = player_info.dungeon_collection.as_mut().unwrap();
let dungeon_collection = player_info.dungeon_collection_mut();
dungeon_collection
.dungeons
.as_mut()
.unwrap()
.dungeons_mut()
.insert(dungeon_uid, dungeon_info);
dungeon_collection
.scenes
.as_mut()
.unwrap()
.scenes_mut()
.insert(scene_uid, scene_info);
dungeon_collection.default_scene_uid = Some(scene_uid);
*dungeon_collection.default_scene_uid_mut() = scene_uid;
}
let scene_uid = session
.player_info
.dungeon_collection
.as_ref()
.unwrap()
.default_scene_uid
.unwrap();
let scene_uid = *session.player_info.dungeon_collection().default_scene_uid();
session.player_info.scene_uid = Some(scene_uid);
if let Some(section_id) = session
.player_info
.dungeon_collection
.as_ref()
.unwrap()
.scenes
.as_ref()
.unwrap()
.dungeon_collection()
.scenes()
.get(&scene_uid)
.map(|sc| *sc.get_section_id())
{
@ -154,13 +134,11 @@ pub async fn on_rpc_save_pos_in_main_city_arg(
session: &mut PlayerSession,
arg: RpcSavePosInMainCityArg,
) -> Result<RpcSavePosInMainCityRet, i32> {
let pos_in_main_city = session.player_info.pos_in_main_city.as_mut().unwrap();
let scene_uid = session.player_info.scene_uid.unwrap();
let dungeon_collection = session.player_info.dungeon_collection.as_ref().unwrap();
let scene_uid = *session.player_info.scene_uid();
let dungeon_collection = session.player_info.dungeon_collection();
let Some(protocol::scene_info::SceneInfo::Hall { section_id, .. }) =
dungeon_collection.scenes.as_ref().unwrap().get(&scene_uid)
dungeon_collection.scenes().get(&scene_uid)
else {
return Err(-1);
};
@ -170,9 +148,10 @@ pub async fn on_rpc_save_pos_in_main_city_arg(
arg.position.position.clone().try_into(),
arg.position.rotation.clone().try_into(),
) {
pos_in_main_city.position = Some(position);
pos_in_main_city.rotation = Some(rotation);
pos_in_main_city.initial_pos_id = Some(String::with_capacity(0));
session.player_info.pos_in_main_city_mut().position = Some(position);
session.player_info.pos_in_main_city_mut().rotation = Some(rotation);
session.player_info.pos_in_main_city_mut().initial_pos_id =
Some(String::with_capacity(0));
debug!(
"player_uid: {}, pos in main city updated: {arg:?}",
@ -195,24 +174,19 @@ pub async fn on_rpc_enter_section_arg(
arg: RpcEnterSectionArg,
) -> Result<RpcEnterSectionRet, i32> {
let player_info = &mut session.player_info;
let cur_scene_uid = player_info.scene_uid.unwrap();
let cur_scene_uid = *player_info.scene_uid();
let dungeon_collection = player_info.dungeon_collection.as_mut().unwrap();
let dungeon_collection = player_info.dungeon_collection_mut();
let Some(scene_info::SceneInfo::Hall { section_id, .. }) = dungeon_collection
.scenes
.as_mut()
.unwrap()
.get_mut(&cur_scene_uid)
let Some(scene_info::SceneInfo::Hall { section_id, .. }) =
dungeon_collection.scenes_mut().get_mut(&cur_scene_uid)
else {
error!("RpcEnterSection: current scene is not Hall!");
return Err(-1);
};
*section_id = arg.section_id as i32;
let player_pos_in_main_city = player_info.pos_in_main_city.as_mut().unwrap();
player_pos_in_main_city.initial_pos_id = Some(arg.transform_id);
player_info.pos_in_main_city_mut().initial_pos_id = Some(arg.transform_id);
scene_section_util::init_hall_scene_section(session, cur_scene_uid, arg.section_id as i32);
level::on_section_enter(session, cur_scene_uid, arg.section_id as i32);
@ -249,7 +223,7 @@ pub async fn on_rpc_begin_training_course_battle_arg(
let dungeon_uid = session.uid_counter.next();
let scene_uid = session.uid_counter.next();
let cur_scene_uid = player_info.scene_uid.unwrap();
let cur_scene_uid = *player_info.scene_uid();
let dungeon_info = protocol::dungeon_info::DungeonInfo {
uid: dungeon_uid,
id: 12254000,
@ -327,16 +301,12 @@ pub async fn on_rpc_begin_training_course_battle_arg(
weather: WeatherType::Rain,
};
let dungeon_collection = player_info.dungeon_collection.as_mut().unwrap();
let dungeon_collection = player_info.dungeon_collection_mut();
dungeon_collection
.dungeons
.as_mut()
.unwrap()
.dungeons_mut()
.insert(dungeon_uid, dungeon_info);
dungeon_collection
.scenes
.as_mut()
.unwrap()
.scenes_mut()
.insert(scene_uid, scene_info);
let mut scene_info = build_client_scene_info(&session.player_info, scene_uid).unwrap();
@ -371,23 +341,13 @@ pub async fn on_rpc_leave_cur_dungeon_arg(
session: &mut PlayerSession,
_: RpcLeaveCurDungeonArg,
) -> Result<RpcLeaveCurDungeonRet, i32> {
let scene_uid = session
.player_info
.dungeon_collection
.as_ref()
.unwrap()
.default_scene_uid
.unwrap();
let scene_uid = *session.player_info.dungeon_collection().default_scene_uid();
session.player_info.scene_uid = Some(scene_uid);
if let Some(section_id) = session
.player_info
.dungeon_collection
.as_ref()
.unwrap()
.scenes
.as_ref()
.unwrap()
.dungeon_collection()
.scenes()
.get(&scene_uid)
.map(|sc| *sc.get_section_id())
{

View file

@ -10,18 +10,15 @@ use qwer::{phashmap, phashset, PropertyHashMap, PropertyHashSet};
use crate::{level, PlayerSession};
pub fn init_hall_scene_section(session: &mut PlayerSession, scene_uid: u64, section_id: i32) {
let single_dungeon_group = session.player_info.single_dungeon_group.as_mut().unwrap();
let single_dungeon_group = session.player_info.single_dungeon_group_mut();
if single_dungeon_group
.section
.as_ref()
.unwrap()
.section()
.contains(&scene_uid, &section_id)
{
return;
}
let section_map = single_dungeon_group.section.as_mut().unwrap();
section_map.insert(
single_dungeon_group.section_mut().insert(
scene_uid,
section_id,
SectionInfo {
@ -67,10 +64,8 @@ fn build_scene_unit_protocol_info(
scene_uid: u64,
section_id: u32,
) -> Vec<SceneUnitProtocolInfo> {
let sdg = session.player_info.single_dungeon_group.as_ref().unwrap();
sdg.npcs
.as_ref()
.unwrap()
let sdg = session.player_info.single_dungeon_group();
sdg.npcs()
.iter()
.filter(|(s_uid, _, npc)| {
**s_uid == scene_uid && npc.scene_data.section_id == section_id as i32

View file

@ -1,8 +1,16 @@
use polymorphic::implement_polymorphic;
use proc_macro::TokenStream;
use property_accessors::implement_property_accessors;
mod polymorphic;
mod property_accessors;
#[proc_macro]
pub fn polymorphic(input: TokenStream) -> TokenStream {
implement_polymorphic(input)
}
#[proc_macro_attribute]
pub fn property_accessors(_attr: TokenStream, item: TokenStream) -> TokenStream {
implement_property_accessors(item)
}

View file

@ -0,0 +1,62 @@
use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{parse_macro_input, Fields, GenericArgument, ItemStruct, PathArguments, Type};
pub fn implement_property_accessors(input: TokenStream) -> TokenStream {
let input_struct = parse_macro_input!(input as ItemStruct);
let struct_name = &input_struct.ident;
let Fields::Named(fields) = &input_struct.fields else {
panic!("only structs with named fields are supported by #[property_accessors]");
};
let mut get_methods = proc_macro2::TokenStream::new();
let mut get_mut_methods = proc_macro2::TokenStream::new();
for field in fields.named.iter() {
let name = field.ident.as_ref().unwrap();
let ty = get_underlying_type(&field.ty);
get_methods.extend(quote! {
pub fn #name(&self) -> &#ty {
self.#name.as_ref().unwrap()
}
});
let mut_getter_name = format_ident!("{}_mut", name);
get_mut_methods.extend(quote! {
pub fn #mut_getter_name(&mut self) -> &mut #ty {
self.#name.as_mut().unwrap()
}
});
}
quote! {
#input_struct
impl #struct_name {
#get_methods
#get_mut_methods
}
}
.into()
}
fn get_underlying_type(ty: &Type) -> &Type {
let Type::Path(path) = ty else {
panic!("all fields of struct for #[property_accessor] should be Option<T>");
};
let last_segment = path.path.segments.last();
let last_segment = last_segment.as_ref().unwrap();
let PathArguments::AngleBracketed(args) = &last_segment.arguments else {
panic!("all fields of struct for #[property_accessor] should be Option<T>");
};
if let GenericArgument::Type(ty) = args.args.first().unwrap() {
ty
} else {
panic!("all fields of struct for #[property_accessor] should be Option<T>");
}
}

View file

@ -1,5 +1,6 @@
use std::collections::{HashMap, HashSet};
use protocol_macros::property_accessors;
use qwer::{OctData, PropertyDoubleKeyHashMap, PropertyHashMap, PropertyHashSet};
use crate::action_info::ActionInfo;
@ -86,6 +87,7 @@ pub struct EventGraphsInfo {
#[derive(OctData, Clone, Debug, Default)]
#[property_object(u16, 0x01)]
#[root]
#[property_accessors]
pub struct PlayerInfo {
#[tag = 1]
pub uid: Option<u64>,
@ -215,6 +217,7 @@ pub struct PlayerInfo {
#[derive(OctData, Clone, Debug, Default)]
#[property_object]
#[property_accessors]
pub struct DungeonCollection {
#[tag = 1]
pub dungeons: Option<PropertyHashMap<u64, DungeonInfo>>,
@ -264,6 +267,7 @@ pub struct VideotapeInfo {
#[derive(OctData, Clone, Debug, Default)]
#[property_object]
#[property_accessors]
pub struct ArchiveInfo {
#[tag = 1]
pub videotaps_info: Option<PropertyHashMap<i32, VideotapeInfo>>,
@ -283,6 +287,7 @@ pub struct UnlockInfo {
#[derive(OctData, Clone, Debug, Default)]
#[property_object]
#[property_accessors]
pub struct YorozuyaInfo {
#[tag = 1]
pub last_refresh_timestamp_common: Option<u64>,
@ -333,6 +338,7 @@ pub struct EquipGachaInfo {
#[derive(OctData, Clone, Debug)]
#[property_object]
#[property_accessors]
pub struct BeginnerProcedureInfo {
#[tag = 1]
pub procedure_id: Option<i32>,
@ -340,6 +346,7 @@ pub struct BeginnerProcedureInfo {
#[derive(OctData, Clone, Debug, Default)]
#[property_object]
#[property_accessors]
pub struct PlayerPosInMainCity {
#[tag = 1]
pub position: Option<Vector3f>,
@ -777,6 +784,7 @@ pub struct SectionInfo {
#[derive(OctData, Clone, Debug, Default)]
#[property_object]
#[property_accessors]
pub struct SingleDungeonGroup {
#[tag = 1]
pub dungeons: Option<PropertyHashMap<u64, DungeonTable>>,
@ -874,6 +882,7 @@ pub struct AreasInfo {
#[derive(OctData, Clone, Debug)]
#[property_object]
#[property_accessors]
pub struct BGMInfo {
#[tag = 1]
pub bgm_id: Option<u32>,

View file

@ -8,18 +8,12 @@ use crate::{
pub fn build_player_basic_info(player_info: &PlayerInfo) -> PlayerBasicInfo {
PlayerBasicInfo {
last_enter_world_timestamp: player_info.last_enter_world_timestamp.unwrap_or_default()
as i64,
avatar_id: player_info.avatar_id.unwrap_or_default(),
player_avatar_id: player_info.avatar_id.unwrap_or_default(),
main_city_avatar_id: player_info.main_city_avatar_id.unwrap_or_default(),
nick_name: player_info.nick_name.clone().unwrap_or_default(),
level: player_info
.yorozuya_info
.as_ref()
.map(|yi| yi.yorozuya_level)
.flatten()
.unwrap_or_default(),
last_enter_world_timestamp: *player_info.last_enter_world_timestamp() as i64,
avatar_id: *player_info.avatar_id(),
player_avatar_id: *player_info.avatar_id(),
main_city_avatar_id: *player_info.main_city_avatar_id(),
nick_name: player_info.nick_name().clone(),
level: *player_info.yorozuya_info().yorozuya_level(),
}
}
@ -27,16 +21,13 @@ pub fn build_client_scene_info(
player_info: &PlayerInfo,
scene_uid: u64,
) -> Option<crate::SceneInfo> {
let dungeon_collection = player_info.dungeon_collection.as_ref().unwrap();
let Some(scene_info) = dungeon_collection.scenes.as_ref().unwrap().get(&scene_uid) else {
let dungeon_collection = player_info.dungeon_collection();
let Some(scene_info) = dungeon_collection.scenes().get(&scene_uid) else {
return None;
};
let player_pos_in_main_city = player_info.pos_in_main_city.as_ref().unwrap();
let initial_transform = player_pos_in_main_city
.initial_pos_id
.clone()
.unwrap_or_default();
let player_pos_in_main_city = player_info.pos_in_main_city();
let initial_transform = player_pos_in_main_city.initial_pos_id().clone();
Some(match scene_info {
SceneInfo::Hall {
@ -49,35 +40,22 @@ pub fn build_client_scene_info(
scene_type: 1,
hall_scene_info: Some(crate::HallSceneInfo {
section_id: *section_id as u32,
player_avatar_id: player_info.avatar_id.unwrap_or_default(),
main_city_avatar_id: player_info.main_city_avatar_id.unwrap_or_default(),
bgm_id: player_info
.bgm_info
.as_ref()
.map(|bgm| bgm.bgm_id.clone())
.flatten()
.unwrap_or_default(),
player_avatar_id: *player_info.avatar_id(),
main_city_avatar_id: *player_info.main_city_avatar_id(),
bgm_id: *player_info.bgm_info().bgm_id(),
day_of_week: main_city_time_info.day_of_week as u32,
time_of_day: main_city_time_info.initial_time,
camera_x: *camera_x,
camera_y: *camera_y,
position: initial_transform.is_empty().then(|| crate::Transform {
position: player_pos_in_main_city
.position
.clone()
.unwrap_or_default()
.into(),
rotation: player_pos_in_main_city
.rotation
.clone()
.unwrap_or_default()
.into(),
position: player_pos_in_main_city.position().clone().into(),
rotation: player_pos_in_main_city.rotation().clone().into(),
}),
main_city_objects_state: player_info
.main_city_objects_state
.as_ref()
.map(|map| map.iter().map(|(&k, &v)| (k, v)).collect())
.unwrap_or_default(),
.main_city_objects_state()
.iter()
.map(|(&k, &v)| (k, v))
.collect(),
scene_unit_list: Vec::new(),
transform_id: initial_transform,
}),
@ -86,12 +64,7 @@ pub fn build_client_scene_info(
SceneInfo::Fresh { .. } => crate::SceneInfo {
scene_type: 4,
fresh_scene_info: Some(crate::FreshSceneInfo {
beginner_procedure_id: player_info
.beginner_procedure_info
.as_ref()
.unwrap()
.procedure_id
.unwrap_or_default() as u32,
beginner_procedure_id: *player_info.beginner_procedure_info().procedure_id() as u32,
}),
..Default::default()
},
@ -123,8 +96,8 @@ pub fn build_client_dungeon_info(
player_info: &PlayerInfo,
scene_uid: u64,
) -> Option<crate::DungeonInfo> {
let dungeon_collection = player_info.dungeon_collection.as_ref().unwrap();
let Some(scene_info) = dungeon_collection.scenes.as_ref().unwrap().get(&scene_uid) else {
let dungeon_collection = player_info.dungeon_collection();
let Some(scene_info) = dungeon_collection.scenes().get(&scene_uid) else {
return None;
};
@ -134,9 +107,7 @@ pub fn build_client_dungeon_info(
}
let dungeon_info = dungeon_collection
.dungeons
.as_ref()
.unwrap()
.dungeons()
.get(scene_info.get_dungeon_uid())
.unwrap();
@ -147,7 +118,7 @@ pub fn build_client_dungeon_info(
.avatars
.iter()
.map(|(_, unit)| {
let avatar_info = player_info.items.as_ref().unwrap().get(&unit.uid).unwrap();
let avatar_info = player_info.items().get(&unit.uid).unwrap();
AvatarUnitInfo {
avatar_id: *avatar_info.get_id() as u32,
}
@ -162,13 +133,9 @@ pub fn build_hall_refresh_arg(
hall_scene_uid: u64,
refresh_immediately: bool,
) -> Option<PtcHallRefreshArg> {
let dungeon_collection = player_info.dungeon_collection.as_ref().unwrap();
let scene_info = dungeon_collection
.scenes
.as_ref()
.unwrap()
.get(&hall_scene_uid);
let player_pos_in_main_city = player_info.pos_in_main_city.as_ref().unwrap();
let dungeon_collection = player_info.dungeon_collection();
let scene_info = dungeon_collection.scenes().get(&hall_scene_uid);
let player_pos_in_main_city = player_info.pos_in_main_city();
match scene_info {
Some(SceneInfo::Hall {
@ -180,39 +147,23 @@ pub fn build_hall_refresh_arg(
}) => Some(PtcHallRefreshArg {
refresh_immediately,
section_id: *section_id as u32,
player_avatar_id: player_info.avatar_id.unwrap_or_default(),
main_city_avatar_id: player_info.main_city_avatar_id.unwrap_or_default(),
transform_id: player_pos_in_main_city
.initial_pos_id
.clone()
.unwrap_or_default(),
bgm_id: player_info
.bgm_info
.as_ref()
.map(|bgm| bgm.bgm_id.clone())
.flatten()
.unwrap_or_default(),
player_avatar_id: *player_info.avatar_id(),
main_city_avatar_id: *player_info.main_city_avatar_id(),
transform_id: player_pos_in_main_city.initial_pos_id().clone(),
bgm_id: *player_info.bgm_info().bgm_id(),
day_of_week: main_city_time_info.day_of_week as u32,
time_of_day: main_city_time_info.initial_time,
camera_x: *camera_x,
camera_y: *camera_y,
position: crate::Transform {
position: player_pos_in_main_city
.position
.clone()
.unwrap_or_default()
.into(),
rotation: player_pos_in_main_city
.rotation
.clone()
.unwrap_or_default()
.into(),
position: player_pos_in_main_city.position().clone().into(),
rotation: player_pos_in_main_city.rotation().clone().into(),
},
main_city_objects_state: player_info
.main_city_objects_state
.as_ref()
.map(|map| map.iter().map(|(&k, &v)| (k, v)).collect())
.unwrap_or_default(),
.main_city_objects_state()
.iter()
.map(|(&k, &v)| (k, v))
.collect(),
scene_unit_list: Vec::new(),
}),
_ => None,
@ -221,9 +172,7 @@ pub fn build_hall_refresh_arg(
pub fn build_sync_avatar_info_list(player_info: &PlayerInfo) -> Vec<AvatarInfo> {
player_info
.items
.as_ref()
.unwrap()
.items()
.iter()
.map(|(uid, item)| {
if let ItemInfo::AvatarInfo {
@ -249,9 +198,7 @@ pub fn build_sync_avatar_info_list(player_info: &PlayerInfo) -> Vec<AvatarInfo>
first_get_time: *first_get_time as i64,
talent_switch_list: talent_switch.clone(),
cur_weapon_uid: player_info
.items
.as_ref()
.unwrap()
.items()
.iter()
.find(|(_, item)| {
if let ItemInfo::Weapon { avatar_uid, .. } = item {
@ -280,9 +227,7 @@ pub fn build_sync_avatar_info_list(player_info: &PlayerInfo) -> Vec<AvatarInfo>
pub fn build_sync_weapon_info_list(player_info: &PlayerInfo) -> Vec<WeaponInfo> {
player_info
.items
.as_ref()
.unwrap()
.items()
.iter()
.map(|(_, item)| {
if let ItemInfo::Weapon {
@ -315,9 +260,7 @@ pub fn build_sync_weapon_info_list(player_info: &PlayerInfo) -> Vec<WeaponInfo>
pub fn build_sync_equip_info_list(player_info: &PlayerInfo) -> Vec<EquipInfo> {
player_info
.items
.as_ref()
.unwrap()
.items()
.iter()
.map(|(_, item)| {
if let ItemInfo::Equip {
@ -348,9 +291,7 @@ pub fn build_sync_equip_info_list(player_info: &PlayerInfo) -> Vec<EquipInfo> {
pub fn build_sync_resource_info_list(player_info: &PlayerInfo) -> Vec<ResourceInfo> {
player_info
.items
.as_ref()
.unwrap()
.items()
.iter()
.map(|(_, item)| match item {
ItemInfo::Currency { id, count, .. } => Some(ResourceInfo {
@ -379,9 +320,7 @@ pub fn build_sync_auto_recovery_info(
player_info: &PlayerInfo,
) -> HashMap<u32, crate::AutoRecoveryInfo> {
player_info
.auto_recovery_info
.as_ref()
.unwrap()
.auto_recovery_info()
.iter()
.map(|(id, info)| (*id as u32, info.clone()))
.collect()