diff --git a/resources/tests/player_setup.bin b/resources/tests/player_setup.bin new file mode 100644 index 0000000..602220c Binary files /dev/null and b/resources/tests/player_setup.bin differ diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index aaff236..0f3df46 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -8,7 +8,10 @@ use kawari::world::{ ActorControlSelf, ActorControlType, ChatHandler, PlayerEntry, PlayerSetup, PlayerSpawn, PlayerStats, Position, SocialList, Zone, ZoneConnection, }; -use kawari::{CHAR_NAME, CONTENT_ID, CUSTOMIZE_DATA, WORLD_ID, ZONE_ID, timestamp_secs}; +use kawari::{ + CHAR_NAME, CITY_STATE, CONTENT_ID, CUSTOMIZE_DATA, DEITY, NAMEDAY_DAY, NAMEDAY_MONTH, WORLD_ID, + ZONE_ID, timestamp_secs, +}; use tokio::io::AsyncReadExt; use tokio::net::TcpListener; @@ -227,6 +230,13 @@ async fn main() { levels: [100; 32], name: CHAR_NAME.to_string(), char_id: connection.player_id, + race: CUSTOMIZE_DATA.race, + gender: CUSTOMIZE_DATA.gender, + tribe: CUSTOMIZE_DATA.subrace, + city_state: CITY_STATE, + nameday_month: NAMEDAY_MONTH, + nameday_day: NAMEDAY_DAY, + deity: DEITY, ..Default::default() }), ..Default::default() diff --git a/src/ipc.rs b/src/ipc.rs index 03bdca2..5586c4c 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -302,7 +302,7 @@ pub enum IPCStructData { #[br(pre_assert(*magic == IPCOpCode::Unk2))] Unk2 { // TODO: full of possibly interesting information - unk: [u8; 16], + unk: [u8; 8], }, #[br(pre_assert(*magic == IPCOpCode::Unk3))] Unk3 { diff --git a/src/lib.rs b/src/lib.rs index 36e3e95..57d75f7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,6 +56,11 @@ pub const CUSTOMIZE_DATA: ClientCustomizeData = ClientCustomizeData { face_paint_color: 167, }; +pub const DEITY: u8 = 0x8; +pub const NAMEDAY_MONTH: u8 = 0x1; +pub const NAMEDAY_DAY: u8 = 0x1; +pub const CITY_STATE: u8 = 0x3; + /// Maxmimum length of a character's name. pub const CHAR_NAME_MAX_LENGTH: usize = 32; diff --git a/src/lobby/connection.rs b/src/lobby/connection.rs index 51438b6..6689b26 100644 --- a/src/lobby/connection.rs +++ b/src/lobby/connection.rs @@ -3,7 +3,8 @@ use std::cmp::min; use tokio::net::TcpStream; use crate::{ - CHAR_NAME, CONTENT_ID, CUSTOMIZE_DATA, WORLD_ID, WORLD_NAME, ZONE_ID, + CHAR_NAME, CONTENT_ID, CUSTOMIZE_DATA, DEITY, NAMEDAY_DAY, NAMEDAY_MONTH, WORLD_ID, WORLD_NAME, + ZONE_ID, blowfish::Blowfish, client_select_data::ClientSelectData, common::timestamp_secs, @@ -164,12 +165,12 @@ impl LobbyConnection { game_name_unk: "Final Fantasy".to_string(), current_class: 2, class_levels: [5; 30], - race: 0, - subrace: 0, - gender: 0, - birth_month: 5, - birth_day: 5, - guardian: 2, + race: CUSTOMIZE_DATA.race as i32, + subrace: CUSTOMIZE_DATA.subrace as i32, + gender: CUSTOMIZE_DATA.gender as i32, + birth_month: NAMEDAY_MONTH as i32, + birth_day: NAMEDAY_DAY as i32, + guardian: DEITY as i32, unk8: 0, unk9: 0, zone_id: ZONE_ID as i32, diff --git a/src/world/player_setup.rs b/src/world/player_setup.rs index 0762167..2e04392 100644 --- a/src/world/player_setup.rs +++ b/src/world/player_setup.rs @@ -160,5 +160,40 @@ pub struct PlayerSetup { pub cleared_guildhests: [u8; 10], pub cleared_trials: [u8; 12], pub cleared_pvp: [u8; 5], - pub unknown948: [u8; 15], + + // meh, this is where i put all of the new data + #[br(count = 192)] + #[bw(pad_size_to = 192)] + pub unknown948: Vec, +} + +#[cfg(test)] +mod tests { + use std::{fs::read, io::Cursor, path::PathBuf}; + + use binrw::BinRead; + + use super::*; + + #[test] + fn read_playerspawn() { + let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + d.push("resources/tests/player_setup.bin"); + + let buffer = read(d).unwrap(); + let mut buffer = Cursor::new(&buffer); + + let player_setup = PlayerSetup::read_le(&mut buffer).unwrap(); + assert_eq!(player_setup.content_id, 0x004000174c50560d); + assert_eq!(player_setup.char_id, 0x107476e7); + assert_eq!(player_setup.name, "Lavenaa Warren"); + assert_eq!(player_setup.max_level, 100); + assert_eq!(player_setup.gender, 1); + assert_eq!(player_setup.race, 1); + assert_eq!(player_setup.tribe, 2); + assert_eq!(player_setup.expansion, 5); + assert_eq!(player_setup.current_job, 1); // adventurer + assert_eq!(player_setup.current_class, 1); // ditto + assert_eq!(player_setup.levels[1], 1); // adventurer + } }