From 2e50d1f7adbc76c3e7e7e8cbce94c2aa2d4985fc Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Fri, 9 May 2025 19:49:40 -0400 Subject: [PATCH] Move some common code out of ZoneConnection and into a new common module --- src/world/common.rs | 103 +++++++++++++++++++++++++++++++++++++ src/world/connection.rs | 109 ++++------------------------------------ src/world/mod.rs | 7 +-- 3 files changed, 116 insertions(+), 103 deletions(-) create mode 100644 src/world/common.rs diff --git a/src/world/common.rs b/src/world/common.rs new file mode 100644 index 0000000..79a6b25 --- /dev/null +++ b/src/world/common.rs @@ -0,0 +1,103 @@ +use std::{ + net::SocketAddr, + sync::{ + Arc, + atomic::{AtomicUsize, Ordering}, + }, +}; + +use tokio::sync::mpsc::Sender; + +use crate::{ + common::Position, + ipc::zone::{ActorControl, ActorControlTarget, ClientTrigger, CommonSpawn}, +}; + +use super::Actor; + +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub struct ClientId(usize); + +pub enum FromServer { + /// A chat message. + Message(String), + /// An actor has been spawned. + ActorSpawn(Actor, CommonSpawn), + /// An actor moved to a new position. + ActorMove(u32, Position, f32), + // An actor has despawned. + ActorDespawn(u32), + /// We need to update an actor + ActorControl(u32, ActorControl), + /// We need to update an actor's target' + ActorControlTarget(u32, ActorControlTarget), +} + +#[derive(Debug, Clone)] +pub struct ClientHandle { + pub id: ClientId, + pub ip: SocketAddr, + pub channel: Sender, + pub actor_id: u32, + pub common: CommonSpawn, +} + +impl ClientHandle { + /// Send a message to this client actor. Will emit an error if sending does + /// not succeed immediately, as this means that forwarding messages to the + /// tcp connection cannot keep up. + pub fn send(&mut self, msg: FromServer) -> Result<(), std::io::Error> { + if self.channel.try_send(msg).is_err() { + Err(std::io::Error::new( + std::io::ErrorKind::BrokenPipe, + "Can't keep up or dead", + )) + } else { + Ok(()) + } + } + + /// Kill the actor. + pub fn kill(self) { + // run the destructor + drop(self); + } +} + +pub enum ToServer { + /// A new connection has started. + NewClient(ClientHandle), + /// The connection sent a message. + Message(ClientId, String), + /// 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), +} + +#[derive(Clone, Debug)] +pub struct ServerHandle { + pub chan: Sender, + pub next_id: Arc, +} + +impl ServerHandle { + pub async fn send(&mut self, msg: ToServer) { + if self.chan.send(msg).await.is_err() { + panic!("Main loop has shut down."); + } + } + pub fn next_id(&self) -> ClientId { + let id = self.next_id.fetch_add(1, Ordering::Relaxed); + ClientId(id) + } +} diff --git a/src/world/connection.rs b/src/world/connection.rs index 132cb13..878bb84 100644 --- a/src/world/connection.rs +++ b/src/world/connection.rs @@ -1,12 +1,9 @@ use std::{ net::SocketAddr, - sync::{ - Arc, Mutex, - atomic::{AtomicUsize, Ordering}, - }, + sync::{Arc, Mutex}, }; -use tokio::{net::TcpStream, sync::mpsc::Sender}; +use tokio::net::TcpStream; use crate::{ OBFUSCATION_ENABLED_MODE, @@ -16,11 +13,10 @@ use crate::{ ipc::{ chat::ServerChatIpcSegment, zone::{ - ActorControl, ActorControlSelf, ActorControlTarget, ClientTrigger, - ClientZoneIpcSegment, CommonSpawn, ContainerInfo, DisplayFlag, Equip, InitZone, - ItemInfo, Move, NpcSpawn, ObjectKind, PlayerStats, PlayerSubKind, ServerZoneIpcData, - ServerZoneIpcSegment, StatusEffect, StatusEffectList, UpdateClassInfo, Warp, - WeatherChange, + ActorControl, ActorControlSelf, ActorControlTarget, ClientZoneIpcSegment, CommonSpawn, + ContainerInfo, DisplayFlag, Equip, InitZone, ItemInfo, Move, NpcSpawn, ObjectKind, + PlayerStats, PlayerSubKind, ServerZoneIpcData, ServerZoneIpcSegment, StatusEffect, + StatusEffectList, UpdateClassInfo, Warp, WeatherChange, }, }, opcodes::ServerZoneIpcType, @@ -31,7 +27,9 @@ use crate::{ }; use super::{ - Actor, CharacterData, Event, LuaPlayer, StatusEffects, WorldDatabase, Zone, lua::Task, + Actor, CharacterData, Event, LuaPlayer, StatusEffects, ToServer, WorldDatabase, Zone, + common::{ClientId, ServerHandle}, + lua::Task, }; #[derive(Debug, Default, Clone)] @@ -56,95 +54,6 @@ pub struct PlayerData { pub inventory: Inventory, } -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub struct ClientId(usize); - -pub enum FromServer { - /// A chat message. - Message(String), - /// An actor has been spawned. - ActorSpawn(Actor, CommonSpawn), - /// An actor moved to a new position. - ActorMove(u32, Position, f32), - // An actor has despawned. - ActorDespawn(u32), - /// We need to update an actor - ActorControl(u32, ActorControl), - /// We need to update an actor's target' - ActorControlTarget(u32, ActorControlTarget), -} - -#[derive(Debug, Clone)] -pub struct ClientHandle { - pub id: ClientId, - pub ip: SocketAddr, - pub channel: Sender, - pub actor_id: u32, - pub common: CommonSpawn, - // TODO: restore, i guess - //pub kill: JoinHandle<()>, -} - -impl ClientHandle { - /// Send a message to this client actor. Will emit an error if sending does - /// not succeed immediately, as this means that forwarding messages to the - /// tcp connection cannot keep up. - pub fn send(&mut self, msg: FromServer) -> Result<(), std::io::Error> { - if self.channel.try_send(msg).is_err() { - Err(std::io::Error::new( - std::io::ErrorKind::BrokenPipe, - "Can't keep up or dead", - )) - } else { - Ok(()) - } - } - - /// Kill the actor. - pub fn kill(self) { - // run the destructor - drop(self); - } -} - -pub enum ToServer { - /// A new connection has started. - NewClient(ClientHandle), - /// The connection sent a message. - Message(ClientId, String), - /// 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), -} - -#[derive(Clone, Debug)] -pub struct ServerHandle { - pub chan: Sender, - pub next_id: Arc, -} - -impl ServerHandle { - pub async fn send(&mut self, msg: ToServer) { - if self.chan.send(msg).await.is_err() { - panic!("Main loop has shut down."); - } - } - pub fn next_id(&self) -> ClientId { - let id = self.next_id.fetch_add(1, Ordering::Relaxed); - ClientId(id) - } -} - /// Represents a single connection between an instance of the client and the world server pub struct ZoneConnection { pub config: WorldConfig, diff --git a/src/world/mod.rs b/src/world/mod.rs index bc8cf0b..07e70de 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -5,9 +5,7 @@ mod chat_handler; pub use chat_handler::ChatHandler; mod connection; -pub use connection::{ - ClientHandle, ClientId, FromServer, PlayerData, ServerHandle, ToServer, ZoneConnection, -}; +pub use connection::{PlayerData, ZoneConnection}; mod database; pub use database::{CharacterData, WorldDatabase}; @@ -29,3 +27,6 @@ pub use server::server_main_loop; mod custom_ipc_handler; pub use custom_ipc_handler::handle_custom_ipc; + +mod common; +pub use common::{ClientHandle, ClientId, FromServer, ServerHandle, ToServer};