1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-04-19 22:36:49 +00:00

Send existing actors to any newly connecting client

This commit is contained in:
Joshua Goins 2025-04-01 20:23:23 -04:00
parent 268c157180
commit f1b674320e
3 changed files with 36 additions and 11 deletions

View file

@ -24,8 +24,8 @@ use kawari::world::{
use kawari::world::{ use kawari::world::{
ChatHandler, Zone, ZoneConnection, ChatHandler, Zone, ZoneConnection,
ipc::{ ipc::{
ActorControlCategory, ActorControlSelf, PlayerEntry, PlayerSetup, PlayerSpawn, PlayerStats, ActorControlCategory, ActorControlSelf, CommonSpawn, PlayerEntry, PlayerSetup, PlayerSpawn,
SocialList, PlayerStats, SocialList,
}, },
}; };
@ -45,6 +45,8 @@ struct ExtraLuaState {
#[derive(Default, Debug)] #[derive(Default, Debug)]
struct Data { struct Data {
clients: HashMap<ClientId, ClientHandle>, clients: HashMap<ClientId, ClientHandle>,
// structure temporary, of course
actors: HashMap<ObjectId, CommonSpawn>,
} }
async fn main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::io::Error> { async fn main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::io::Error> {
@ -56,6 +58,23 @@ async fn main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::io::Error> {
ToServer::NewClient(handle) => { ToServer::NewClient(handle) => {
data.clients.insert(handle.id, handle); data.clients.insert(handle.id, handle);
} }
ToServer::ZoneLoaded(from_id) => {
for (id, handle) in &mut data.clients {
let id = *id;
if id == from_id {
// send existing player data
for (id, common) in &data.actors {
let msg =
FromServer::ActorSpawn(Actor { id: *id, hp: 100 }, common.clone());
let _ = handle.send(msg).unwrap();
}
break;
}
}
}
ToServer::Message(from_id, msg) => { ToServer::Message(from_id, msg) => {
for (id, handle) in &mut data.clients { for (id, handle) in &mut data.clients {
let id = *id; let id = *id;
@ -72,6 +91,8 @@ async fn main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::io::Error> {
} }
} }
ToServer::ActorSpawned(from_id, actor, common) => { ToServer::ActorSpawned(from_id, actor, common) => {
data.actors.insert(actor.id, common.clone());
for (id, handle) in &mut data.clients { for (id, handle) in &mut data.clients {
let id = *id; let id = *id;
@ -86,7 +107,7 @@ async fn main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::io::Error> {
} }
} }
} }
ToServer::ActorMoved(from_id, actor_id, position) => { ToServer::ActorMoved(from_id, actor_id, position, rotation) => {
for (id, handle) in &mut data.clients { for (id, handle) in &mut data.clients {
let id = *id; let id = *id;
@ -94,7 +115,7 @@ async fn main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::io::Error> {
continue; continue;
} }
let msg = FromServer::ActorMove(actor_id, position); let msg = FromServer::ActorMove(actor_id, position, rotation);
if handle.send(msg).is_err() { if handle.send(msg).is_err() {
to_remove.push(id); to_remove.push(id);
@ -374,6 +395,9 @@ async fn client_loop(
.unwrap(); .unwrap();
} }
ClientZoneIpcData::FinishLoading { .. } => { ClientZoneIpcData::FinishLoading { .. } => {
// tell the server we loaded into the zone, so it can start sending us acors
connection.handle.send(ToServer::ZoneLoaded(connection.id)).await;
// send player spawn // send player spawn
{ {
let ipc = ServerZoneIpcSegment { let ipc = ServerZoneIpcSegment {
@ -521,7 +545,7 @@ async fn client_loop(
connection.player_data.rotation = *rotation; connection.player_data.rotation = *rotation;
connection.player_data.position = *position; connection.player_data.position = *position;
connection.handle.send(ToServer::ActorMoved(connection.id, connection.player_data.actor_id, *position)).await; connection.handle.send(ToServer::ActorMoved(connection.id, connection.player_data.actor_id, *position, *rotation)).await;
} }
ClientZoneIpcData::LogOut { .. } => { ClientZoneIpcData::LogOut { .. } => {
tracing::info!("Recieved log out from client!"); tracing::info!("Recieved log out from client!");
@ -980,11 +1004,11 @@ async fn client_loop(
} }
msg = internal_recv.recv() => match msg { msg = internal_recv.recv() => match msg {
Some(msg) => match msg { Some(msg) => match msg {
FromServer::Message(msg)=>connection.send_message(&msg).await, FromServer::Message(msg)=> connection.send_message(&msg).await,
FromServer::ActorSpawn(actor, common) => { FromServer::ActorSpawn(actor, common) => {
connection.spawn_actor(actor, common).await connection.spawn_actor(actor, common).await
}, },
FromServer::ActorMove(actor_id, position) => connection.set_actor_position(actor_id, position).await, FromServer::ActorMove(actor_id, position, rotation) => connection.set_actor_position(actor_id, position, rotation).await,
}, },
None => break, None => break,
} }

View file

@ -17,7 +17,7 @@ pub use gamedata::GameData;
#[binrw] #[binrw]
#[brw(little)] #[brw(little)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ObjectId(pub u32); pub struct ObjectId(pub u32);
impl Default for ObjectId { impl Default for ObjectId {

View file

@ -58,7 +58,7 @@ pub enum FromServer {
/// An actor has been spawned. /// An actor has been spawned.
ActorSpawn(Actor, CommonSpawn), ActorSpawn(Actor, CommonSpawn),
/// An actor moved to a new position. /// An actor moved to a new position.
ActorMove(u32, Position), ActorMove(u32, Position, f32),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -96,7 +96,8 @@ pub enum ToServer {
NewClient(ClientHandle), NewClient(ClientHandle),
Message(ClientId, String), Message(ClientId, String),
ActorSpawned(ClientId, Actor, CommonSpawn), ActorSpawned(ClientId, Actor, CommonSpawn),
ActorMoved(ClientId, u32, Position), ActorMoved(ClientId, u32, Position, f32),
ZoneLoaded(ClientId),
FatalError(std::io::Error), FatalError(std::io::Error),
} }
@ -282,7 +283,7 @@ impl ZoneConnection {
} }
} }
pub async fn set_actor_position(&mut self, actor_id: u32, position: Position) { pub async fn set_actor_position(&mut self, actor_id: u32, position: Position, rotation: f32) {
let ipc = ServerZoneIpcSegment { let ipc = ServerZoneIpcSegment {
op_code: ServerZoneIpcType::ActorMove, op_code: ServerZoneIpcType::ActorMove,
timestamp: timestamp_secs(), timestamp: timestamp_secs(),