diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 7d44e81..dc03e8b 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -9,8 +9,9 @@ use kawari::config::get_config; use kawari::inventory::Item; use kawari::ipc::chat::{ServerChatIpcData, ServerChatIpcSegment}; use kawari::ipc::zone::{ - ActionEffect, ActionResult, ClientZoneIpcData, EffectKind, EventStart, GameMasterCommandType, - GameMasterRank, OnlineStatus, ServerZoneIpcData, ServerZoneIpcSegment, SocialListRequestType, + ActionEffect, ActionResult, ClientZoneIpcData, CommonSpawn, EffectKind, EventStart, + GameMasterCommandType, GameMasterRank, OnlineStatus, ServerZoneIpcData, ServerZoneIpcSegment, + SocialListRequestType, }; use kawari::ipc::zone::{ ActorControlCategory, ActorControlSelf, PlayerEntry, PlayerSpawn, PlayerStatus, SocialList, @@ -76,7 +77,6 @@ pub fn spawn_client(connection: ZoneConnection) { let id = &connection.id.clone(); let ip = &connection.ip.clone(); - let actor_id = connection.player_data.actor_id; let data = ClientData { //id: connection.id, @@ -94,7 +94,8 @@ pub fn spawn_client(connection: ZoneConnection) { id: *id, ip: *ip, channel: send, - actor_id, + actor_id: 0, + common: CommonSpawn::default(), //kill, }; let _ = my_send.send(handle); @@ -167,6 +168,7 @@ async fn client_loop( let mut client_handle = client_handle.clone(); client_handle.actor_id = actor_id; + client_handle.common = connection.get_player_common_spawn(connection.exit_position, connection.exit_rotation); // tell the server we exist, now that we confirmed we are a legitimate connection connection.handle.send(ToServer::NewClient(client_handle)).await; @@ -375,9 +377,6 @@ async fn client_loop( // wipe any exit position so it isn't accidentally reused connection.exit_position = None; connection.exit_rotation = None; - - // tell the other players we're here - connection.handle.send(ToServer::ActorSpawned(connection.id, connection.zone.as_ref().unwrap().id, Actor { id: ObjectId(connection.player_data.actor_id), hp: 100, spawn_index: 0 }, common)).await; } ClientZoneIpcData::ClientTrigger(trigger) => { // inform the server of our trigger, it will handle sending it to other clients diff --git a/src/world/connection.rs b/src/world/connection.rs index 351d2b9..a6b2870 100644 --- a/src/world/connection.rs +++ b/src/world/connection.rs @@ -80,6 +80,7 @@ pub struct ClientHandle { pub ip: SocketAddr, pub channel: Sender, pub actor_id: u32, + pub common: CommonSpawn, // TODO: restore, i guess //pub kill: JoinHandle<()>, } @@ -107,16 +108,22 @@ impl ClientHandle { } pub enum ToServer { + /// A new connection has started. NewClient(ClientHandle), + /// The connection sent a message. Message(ClientId, String), - // TODO: ditto, zone id should not be here - ActorSpawned(ClientId, u16, Actor, CommonSpawn), + /// The connection's player moved. ActorMoved(ClientId, u32, Position, f32), + /// The connection has recieved a client trigger. ClientTrigger(ClientId, u32, ClientTrigger), + /// The connection loaded into a zone. // TODO: the connection should not be in charge and telling the global server what zone they just loaded in! but this will work for now ZoneLoaded(ClientId, u16), + /// The connection left a zone. LeftZone(ClientId, u32, u16), + /// The connection disconnected. Disconnected(ClientId), + /// A fatal error occured. FatalError(std::io::Error), } diff --git a/src/world/server.rs b/src/world/server.rs index e6867a6..3ba8a53 100644 --- a/src/world/server.rs +++ b/src/world/server.rs @@ -97,6 +97,44 @@ pub async fn server_main_loop(mut recv: Receiver) -> Result<(), std::i } } } + + let (client, _) = data.clients.get(&from_id).unwrap().clone(); + + // add the connection's actor to the table + { + let instance = data.find_instance_mut(zone_id); + instance + .actors + .insert(ObjectId(client.actor_id), client.common.clone()); + } + + // Then tell any clients in the zone that we spawned + for (id, (handle, state)) in &mut data.clients { + let id = *id; + + // don't bother telling the client who told us + if id == from_id { + continue; + } + + // skip any clients not in our zone + if state.zone_id != zone_id { + continue; + } + + let msg = FromServer::ActorSpawn( + Actor { + id: ObjectId(client.actor_id), + hp: 0, + spawn_index: 0, + }, + client.common.clone(), + ); + + if handle.send(msg).is_err() { + to_remove.push(id); + } + } } ToServer::LeftZone(from_id, actor_id, zone_id) => { // when the actor leaves the zone, remove them from the instance @@ -139,31 +177,6 @@ pub async fn server_main_loop(mut recv: Receiver) -> Result<(), std::i } } } - ToServer::ActorSpawned(from_id, zone_id, actor, common) => { - let instance = data.find_instance_mut(zone_id); - instance.actors.insert(actor.id, common.clone()); - - // Then tell any clients in the zone that we spawned - for (id, (handle, state)) in &mut data.clients { - let id = *id; - - // don't bother telling the client who told us - if id == from_id { - continue; - } - - // skip any clients not in our zone - if state.zone_id != zone_id { - continue; - } - - let msg = FromServer::ActorSpawn(actor, common.clone()); - - if handle.send(msg).is_err() { - to_remove.push(id); - } - } - } ToServer::ActorMoved(from_id, actor_id, position, rotation) => { if let Some(instance) = data.find_actor_instance_mut(actor_id) { if let Some((_, common)) = instance