1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-04-26 08:37:44 +00:00

Use the same nameday/deity/etc information everywhere, add tests for PlayerSpawn

This doesn't really fix anything functionally, but makes the Character window
look nicer. The same (currently unchangable) data is now reflected in the lobby.
This commit is contained in:
Joshua Goins 2025-03-16 14:43:30 -04:00
parent 0bf4cd1264
commit a72199e5af
6 changed files with 61 additions and 10 deletions

Binary file not shown.

View file

@ -8,7 +8,10 @@ use kawari::world::{
ActorControlSelf, ActorControlType, ChatHandler, PlayerEntry, PlayerSetup, PlayerSpawn, ActorControlSelf, ActorControlType, ChatHandler, PlayerEntry, PlayerSetup, PlayerSpawn,
PlayerStats, Position, SocialList, Zone, ZoneConnection, 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::io::AsyncReadExt;
use tokio::net::TcpListener; use tokio::net::TcpListener;
@ -227,6 +230,13 @@ async fn main() {
levels: [100; 32], levels: [100; 32],
name: CHAR_NAME.to_string(), name: CHAR_NAME.to_string(),
char_id: connection.player_id, 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()
}), }),
..Default::default() ..Default::default()

View file

@ -302,7 +302,7 @@ pub enum IPCStructData {
#[br(pre_assert(*magic == IPCOpCode::Unk2))] #[br(pre_assert(*magic == IPCOpCode::Unk2))]
Unk2 { Unk2 {
// TODO: full of possibly interesting information // TODO: full of possibly interesting information
unk: [u8; 16], unk: [u8; 8],
}, },
#[br(pre_assert(*magic == IPCOpCode::Unk3))] #[br(pre_assert(*magic == IPCOpCode::Unk3))]
Unk3 { Unk3 {

View file

@ -56,6 +56,11 @@ pub const CUSTOMIZE_DATA: ClientCustomizeData = ClientCustomizeData {
face_paint_color: 167, 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. /// Maxmimum length of a character's name.
pub const CHAR_NAME_MAX_LENGTH: usize = 32; pub const CHAR_NAME_MAX_LENGTH: usize = 32;

View file

@ -3,7 +3,8 @@ use std::cmp::min;
use tokio::net::TcpStream; use tokio::net::TcpStream;
use crate::{ 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, blowfish::Blowfish,
client_select_data::ClientSelectData, client_select_data::ClientSelectData,
common::timestamp_secs, common::timestamp_secs,
@ -164,12 +165,12 @@ impl LobbyConnection {
game_name_unk: "Final Fantasy".to_string(), game_name_unk: "Final Fantasy".to_string(),
current_class: 2, current_class: 2,
class_levels: [5; 30], class_levels: [5; 30],
race: 0, race: CUSTOMIZE_DATA.race as i32,
subrace: 0, subrace: CUSTOMIZE_DATA.subrace as i32,
gender: 0, gender: CUSTOMIZE_DATA.gender as i32,
birth_month: 5, birth_month: NAMEDAY_MONTH as i32,
birth_day: 5, birth_day: NAMEDAY_DAY as i32,
guardian: 2, guardian: DEITY as i32,
unk8: 0, unk8: 0,
unk9: 0, unk9: 0,
zone_id: ZONE_ID as i32, zone_id: ZONE_ID as i32,

View file

@ -160,5 +160,40 @@ pub struct PlayerSetup {
pub cleared_guildhests: [u8; 10], pub cleared_guildhests: [u8; 10],
pub cleared_trials: [u8; 12], pub cleared_trials: [u8; 12],
pub cleared_pvp: [u8; 5], 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<u8>,
}
#[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
}
} }