diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 1efb82a..dcf5633 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -73,7 +73,6 @@ async fn main() { player_data: PlayerData::default(), spawn_index: 0, zone: None, - position: Position::default(), inventory: Inventory::new(), status_effects: StatusEffects::default(), event: None, @@ -544,11 +543,15 @@ async fn main() { rotation.to_degrees() ); - connection.position = *position; + connection.player_data.rotation = *rotation; + connection.player_data.position = *position; } ClientZoneIpcData::LogOut { .. } => { tracing::info!("Recieved log out from client!"); + // write the player back to the database + database.commit_player_data(&connection.player_data); + // tell the client to disconnect { let ipc = ServerZoneIpcSegment { diff --git a/src/world/chat_handler.rs b/src/world/chat_handler.rs index af12c14..b3522be 100644 --- a/src/world/chat_handler.rs +++ b/src/world/chat_handler.rs @@ -114,7 +114,7 @@ impl ChatHandler { 0, // left finger 0, // right finger ], - pos: connection.position, + pos: connection.player_data.position, ..Default::default() }, ..Default::default() @@ -218,7 +218,7 @@ impl ChatHandler { 0, // left finger 0, // right finger ], - pos: connection.position, + pos: connection.player_data.position, ..Default::default() }, ..Default::default() @@ -257,7 +257,7 @@ impl ChatHandler { level: 1, battalion: 4, model_chara: 297, - pos: connection.position, + pos: connection.player_data.position, ..Default::default() }, ..Default::default() diff --git a/src/world/connection.rs b/src/world/connection.rs index 92257f4..9d18f14 100644 --- a/src/world/connection.rs +++ b/src/world/connection.rs @@ -20,9 +20,16 @@ use super::{ #[derive(Debug, Default, Clone, Copy)] pub struct PlayerData { + // Static data pub actor_id: u32, pub content_id: u64, pub account_id: u32, + + // Dynamic data + pub position: Position, + /// In radians. + pub rotation: f32, + pub zone_id: u16, } #[derive(Debug, Default, Clone)] @@ -66,7 +73,6 @@ pub struct ZoneConnection { pub zone: Option, pub spawn_index: u8, - pub position: Position, pub inventory: Inventory, pub status_effects: StatusEffects, @@ -117,6 +123,7 @@ impl ZoneConnection { pub async fn change_zone(&mut self, new_zone_id: u16) { self.zone = Some(Zone::load(new_zone_id)); + self.player_data.zone_id = new_zone_id; // Player Class Info { diff --git a/src/world/database.rs b/src/world/database.rs index b866ed2..c5e81d1 100644 --- a/src/world/database.rs +++ b/src/world/database.rs @@ -39,7 +39,7 @@ impl WorldDatabase { // Create characters data table { - let query = "CREATE TABLE IF NOT EXISTS character_data (content_id INTEGER PRIMARY KEY, name STRING, chara_make STRING, city_state INTEGER, zone_id INTEGER, pos_x REAL, pos_y REAL, pos_z REAL);"; + let query = "CREATE TABLE IF NOT EXISTS character_data (content_id INTEGER PRIMARY KEY, name STRING, chara_make STRING, city_state INTEGER, zone_id INTEGER, pos_x REAL, pos_y REAL, pos_z REAL, rotation REAL);"; connection.execute(query, ()).unwrap(); } @@ -58,13 +58,53 @@ impl WorldDatabase { .query_row((actor_id,), |row| Ok((row.get(0)?, row.get(1)?))) .unwrap(); + stmt = connection + .prepare("SELECT pos_x, pos_y, pos_z, rotation, zone_id FROM character_data WHERE content_id = ?1") + .unwrap(); + let (pos_x, pos_y, pos_z, rotation, zone_id) = stmt + .query_row((content_id,), |row| { + Ok(( + row.get(0)?, + row.get(1)?, + row.get(2)?, + row.get(3)?, + row.get(4)?, + )) + }) + .unwrap(); + PlayerData { actor_id, content_id, account_id, + position: Position { + x: pos_x, + y: pos_y, + z: pos_z, + }, + rotation, + zone_id, } } + /// Commit the dynamic player data back to the database + pub fn commit_player_data(&self, data: &PlayerData) { + let connection = self.connection.lock().unwrap(); + + let mut stmt = connection + .prepare("UPDATE character_data SET zone_id=?1, pos_x=?2, pos_y=?3, pos_z=?4, rotation=?5 WHERE content_id = ?6") + .unwrap(); + stmt.execute(( + data.zone_id, + data.position.x, + data.position.y, + data.position.z, + data.rotation, + data.content_id, + )) + .unwrap(); + } + // TODO: from/to sql int pub fn find_actor_id(&self, content_id: u64) -> u32 { @@ -199,7 +239,7 @@ impl WorldDatabase { // insert char data connection .execute( - "INSERT INTO character_data VALUES (?1, ?2, ?3, ?4, ?5, 0.0, 0.0, 0.0);", + "INSERT INTO character_data VALUES (?1, ?2, ?3, ?4, ?5, 0.0, 0.0, 0.0, 0.0);", (content_id, name, chara_make, city_state, zone_id), ) .unwrap();