Implement #[property_accessors] proc macro to reduce boilerplate for accessing optional properties
This commit is contained in:
parent
ec9ddd4ef7
commit
a266b2e12b
13 changed files with 182 additions and 230 deletions
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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, §ion_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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
62
crates/protocol/protocol-macros/src/property_accessors.rs
Normal file
62
crates/protocol/protocol-macros/src/property_accessors.rs
Normal 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>");
|
||||
}
|
||||
}
|
|
@ -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>,
|
||||
|
|
|
@ -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()
|
||||
|
|
Reference in a new issue