diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 46660c5..86d78b0 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -1,7 +1,8 @@ use std::sync::Arc; use kawari::common::custom_ipc::{CustomIpcData, CustomIpcSegment, CustomIpcType}; -use kawari::common::{get_citystate, get_world_name}; +use kawari::common::timestamp_secs; +use kawari::common::{determine_initial_starting_zone, get_citystate, get_world_name}; use kawari::config::get_config; use kawari::lobby::CharaMake; use kawari::oodle::OodleNetwork; @@ -21,7 +22,6 @@ use kawari::world::{ }, }; use kawari::world::{PlayerData, WorldDatabase}; -use kawari::{ZONE_ID, common::timestamp_secs}; use physis::common::{Language, Platform}; use physis::gamedata::GameData; use tokio::io::AsyncReadExt; @@ -59,7 +59,7 @@ async fn main() { state, player_data: PlayerData::default(), spawn_index: 0, - zone: Zone::load(ZONE_ID), + zone: None, }; tokio::spawn(async move { @@ -238,11 +238,17 @@ async fn main() { .await; } + let chara_details = database + .find_chara_make(connection.player_data.content_id); + + let zone_id = determine_initial_starting_zone( + chara_details.city_state, + ); + + connection.zone = Some(Zone::load(zone_id)); + // Player Setup { - let chara_details = database - .find_chara_make(connection.player_data.content_id); - let ipc = ServerZoneIpcSegment { op_code: ServerZoneIpcType::PlayerSetup, timestamp: timestamp_secs(), @@ -283,7 +289,7 @@ async fn main() { .await; } - connection.change_zone(ZONE_ID).await; + connection.change_zone(zone_id).await; // send welcome message { @@ -424,7 +430,11 @@ async fn main() { content_id: connection .player_data .content_id, - zone_id: connection.zone.id, + zone_id: connection + .zone + .as_ref() + .unwrap() + .id, zone_id1: 0x0100, class_job: 36, level: 100, @@ -575,6 +585,8 @@ async fn main() { { let (_, exit_box) = connection .zone + .as_ref() + .unwrap() .find_exit_box(*exit_box_id) .unwrap(); tracing::info!("exit box: {:#?}", exit_box); diff --git a/src/common/mod.rs b/src/common/mod.rs index 092d97e..5ab6aae 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -83,3 +83,16 @@ pub fn get_citystate(classjob_id: u16) -> u8 { *town_id } + +/// Gets the initial zone for a given city-state id +pub fn determine_initial_starting_zone(citystate_id: u8) -> u16 { + match citystate_id { + // Limsa + 1 => 128, + // Gridania + 2 => 132, + // Ul'dah + 3 => 130, + _ => panic!("This is not a valid city-state id!"), + } +} diff --git a/src/lib.rs b/src/lib.rs index 50d6821..e8ad7fb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,10 +26,6 @@ pub mod packet; /// Logic server-specific code. pub mod login; -/// The zone ID you initially spawn in. -/// See the TerritoryType excel sheet for a list of possible IDs. -pub const ZONE_ID: u16 = 132; - pub const INVALID_OBJECT_ID: u32 = 0xE0000000; /// Maxmimum length of a character's name. diff --git a/src/world/connection.rs b/src/world/connection.rs index d6dbf35..5352d59 100644 --- a/src/world/connection.rs +++ b/src/world/connection.rs @@ -30,7 +30,7 @@ pub struct ZoneConnection { pub state: PacketState, pub player_data: PlayerData, - pub zone: Zone, + pub zone: Option, pub spawn_index: u8, } @@ -77,7 +77,7 @@ impl ZoneConnection { } pub async fn change_zone(&mut self, new_zone_id: u16) { - self.zone = Zone::load(new_zone_id); + self.zone = Some(Zone::load(new_zone_id)); // Player Class Info { @@ -128,7 +128,7 @@ impl ZoneConnection { timestamp: timestamp_secs(), data: ServerZoneIpcData::InitZone(InitZone { server_id: 0, - zone_id: self.zone.id, + zone_id: self.zone.as_ref().unwrap().id, weather_id: 1, ..Default::default() }), diff --git a/src/world/database.rs b/src/world/database.rs index f7dead8..09ec41b 100644 --- a/src/world/database.rs +++ b/src/world/database.rs @@ -2,10 +2,7 @@ use std::sync::Mutex; use rusqlite::Connection; -use crate::{ - ZONE_ID, - lobby::{CharaMake, ClientSelectData, ipc::CharacterDetails}, -}; +use crate::lobby::{CharaMake, ClientSelectData, ipc::CharacterDetails}; use super::PlayerData; @@ -121,7 +118,7 @@ impl WorldDatabase { guardian: chara_make.guardian, unk8: 0, unk9: 0, - zone_id: ZONE_ID as i32, + zone_id: 130 as i32, unk11: 0, customize: chara_make.customize, unk12: 0,