diff --git a/src/lobby/client_select_data.rs b/src/lobby/client_select_data.rs index 468ca20..7c5ec1f 100644 --- a/src/lobby/client_select_data.rs +++ b/src/lobby/client_select_data.rs @@ -18,8 +18,8 @@ pub struct ClientSelectData { pub zone_id: i32, pub unk11: i32, pub customize: CustomizeData, - pub unk12: i32, - pub unk13: i32, + pub model_main_weapon: i32, + pub model_sub_weapon: i32, pub unk14: [i32; 10], // probably model ids pub unk15: i32, pub unk16: i32, @@ -28,7 +28,7 @@ pub struct ClientSelectData { pub unk18: i32, pub unk19: i32, pub unk20: i32, - pub unk21: String, + pub world_name: String, pub unk22: i32, pub unk23: i32, } @@ -50,8 +50,8 @@ impl ClientSelectData { self.zone_id.to_string(), self.unk11.to_string(), self.customize.to_json(), - self.unk12.to_string(), - self.unk13.to_string(), + self.model_main_weapon.to_string(), + self.model_sub_weapon.to_string(), self.unk14.map(|x| x.to_string()), self.unk15.to_string(), self.unk16.to_string(), @@ -59,7 +59,7 @@ impl ClientSelectData { self.unk18.to_string(), self.unk19.to_string(), self.unk20.to_string(), - self.unk21, + self.world_name, self.unk22.to_string(), self.unk23.to_string(), ]); diff --git a/src/lobby/ipc/character_list.rs b/src/lobby/ipc/character_list.rs index 8d1dc77..26c514c 100644 --- a/src/lobby/ipc/character_list.rs +++ b/src/lobby/ipc/character_list.rs @@ -1,20 +1,47 @@ use binrw::binrw; +use bitflags::bitflags; use crate::common::CHAR_NAME_MAX_LENGTH; use super::{read_string, write_string}; +bitflags! { + #[binrw] + pub struct CharacterFlag : u8 { + const NONE = 0; + /// "You cannot select this character with your current account." + const LOCKED = 1; + /// "A name change is required to log in with this character." + const NAME_CHANGE_REQUIRED = 2; + /// Not working? + const MISSING_EXPANSION_FOR_LOGIN = 4; + /// "To log in with this character you must first install A Realm Reborn". Depends on an expansion version of the race maybe? + const MISSING_EXPANSION_FOR_EDIT = 8; + /// Shows a DC traveling icon on the right, and changes the text on the left + const DC_TRAVELING = 16; + /// "This character is currently visiting the XYZ data center". ??? + const DC_TRAVELING_MESSAGE = 32; + } +} + +impl Default for CharacterFlag { + fn default() -> Self { + Self::NONE + } +} + #[binrw] #[derive(Debug, Clone, Default)] pub struct CharacterDetails { #[brw(pad_after = 4)] pub actor_id: u32, pub content_id: u64, - #[brw(pad_after = 4)] - pub index: u32, + pub index: u8, + pub flags: CharacterFlag, + pub unk1: [u8; 6], pub origin_server_id: u16, pub current_server_id: u16, - pub unk1: [u8; 16], + pub unk2: [u8; 16], #[bw(pad_size_to = CHAR_NAME_MAX_LENGTH)] #[br(count = CHAR_NAME_MAX_LENGTH)] #[br(map = read_string)] @@ -35,7 +62,7 @@ pub struct CharacterDetails { #[br(map = read_string)] #[bw(map = write_string)] pub character_detail_json: String, - pub unk2: [u8; 20], + pub unk3: [u32; 5], } #[binrw] diff --git a/src/lobby/ipc/mod.rs b/src/lobby/ipc/mod.rs index 88cb5f8..98dd2cf 100644 --- a/src/lobby/ipc/mod.rs +++ b/src/lobby/ipc/mod.rs @@ -4,7 +4,7 @@ mod character_action; pub use character_action::{LobbyCharacterAction, LobbyCharacterActionKind}; mod character_list; -pub use character_list::{CharacterDetails, LobbyCharacterList}; +pub use character_list::{CharacterDetails, CharacterFlag, LobbyCharacterList}; mod client_version_info; diff --git a/src/world/database.rs b/src/world/database.rs index 478c964..d61353d 100644 --- a/src/world/database.rs +++ b/src/world/database.rs @@ -4,7 +4,10 @@ use rusqlite::Connection; use crate::{ common::Position, - lobby::{CharaMake, ClientSelectData, ipc::CharacterDetails}, + lobby::{ + CharaMake, ClientSelectData, + ipc::{CharacterDetails, CharacterFlag}, + }, }; use super::PlayerData; @@ -170,37 +173,39 @@ impl WorldDatabase { birth_month: chara_make.birth_month, birth_day: chara_make.birth_day, guardian: chara_make.guardian, - unk8: 0, - unk9: 0, + unk8: 255, + unk9: 255, zone_id: zone_id as i32, - unk11: 0, + unk11: 255, customize: chara_make.customize, - unk12: 0, - unk13: 0, + model_main_weapon: 0, + model_sub_weapon: 0, unk14: [0; 10], - unk15: 0, - unk16: 0, - legacy_character: 0, - unk18: 0, - unk19: 0, - unk20: 0, - unk21: String::new(), - unk22: 0, - unk23: 0, + unk15: 255, + unk16: 2, + legacy_character: 2, + unk18: 255, + unk19: 255, + unk20: 255, + world_name: String::new(), + unk22: 255, + unk23: 255, }; characters.push(CharacterDetails { actor_id: *actor_id, content_id: *content_id as u64, - index: index as u32, - unk1: [0; 16], + index: index as u8, + flags: CharacterFlag::NONE, + unk1: [255; 6], origin_server_id: world_id, current_server_id: world_id, character_name: name.clone(), origin_server_name: world_name.to_string(), current_server_name: world_name.to_string(), character_detail_json: select_data.to_json(), - unk2: [0; 20], + unk2: [255; 16], + unk3: [4; 5], }); } }