From d1dbd8d043299f726efd71d114498ecd197b6862 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 23 Nov 2019 19:01:03 -0800 Subject: [PATCH] ClientLocation struct --- src/main.rs | 2 + src/ship/location.rs | 106 +++++++++++++++++++++++++++++++++++++++++++ src/ship/mod.rs | 3 +- src/ship/ship.rs | 3 ++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 src/ship/location.rs diff --git a/src/main.rs b/src/main.rs index d5df569..a7a6bd4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,6 @@ +#![allow(incomplete_features)] #![feature(const_generics)] +#![feature(maybe_uninit_extra)] mod common; diff --git a/src/ship/location.rs b/src/ship/location.rs new file mode 100644 index 0000000..586bd14 --- /dev/null +++ b/src/ship/location.rs @@ -0,0 +1,106 @@ + +use crate::common::serverstate::ClientId; +// TODO: room passwords? + +#[derive(Copy, Clone)] +pub struct ClientArea { + clients: [Option; N], +} + +impl ClientArea<{N}> { + pub fn new() -> ClientArea<{N}> { + let mut clients: [std::mem::MaybeUninit>; N] = unsafe { + std::mem::MaybeUninit::uninit().assume_init() + }; + for i in clients.iter_mut() { + i.write(None); + } + + ClientArea { + clients: unsafe { (&clients as *const _ as *const [Option; N]).read()} + } + } + + + fn add(&mut self, id: ClientId) -> Option { + for (i, client) in self.clients.iter_mut().enumerate() { + if client.is_none() { + *client = Some(id); + return Some(i); + } + } + return None; + } + fn remove(&mut self, id: ClientId) { + for client in self.clients.iter_mut() { + if *client == Some(id) { + *client = None + } + } + } +} + +pub type Lobby = ClientArea<12>; +pub type Room = ClientArea<4>; + +pub type LobbyId = usize; +pub type RoomId = usize; + +pub struct ClientLocation { + lobbies: [Lobby; 15], + rooms: [Option; 128], +} + + +enum JoinRoomError { + RoomDoesNotExist, + RoomFull, +} + +enum JoinLobbyError { + LobbyDoesNotExist, + LobbyFull, +} + +impl ClientLocation { + pub fn new() -> ClientLocation { + ClientLocation { + lobbies: [Lobby::new(); 15], + rooms: [None; 128], + } + } + + pub fn add_to_lobby(&mut self, id: ClientId, lobby: LobbyId) -> Result { + self.lobbies.get_mut(lobby) + .ok_or(JoinLobbyError::LobbyDoesNotExist)? + .add(id) + .ok_or(JoinLobbyError::LobbyFull) + } + + pub fn add_to_room(&mut self, id: ClientId, room: RoomId) -> Result { + self.rooms.get_mut(room) + .ok_or(JoinRoomError::RoomDoesNotExist)? + .as_mut() + .ok_or(JoinRoomError::RoomDoesNotExist)? + .add(id) + .ok_or(JoinRoomError::RoomFull) + } + + pub fn get_client_neighbors(&self, id: ClientId) -> Vec { + for lobby in self.lobbies.iter() { + if lobby.clients.contains(&Some(id)) { + return lobby.clients.iter().filter(|c| c.is_some()).map(|c| c.unwrap()).collect(); + } + } + + for room in self.rooms.iter() { + if let Some(room) = room { + if room.clients.contains(&Some(id)) { + return room.clients.iter().filter(|c| c.is_some()).map(|c| c.unwrap()).collect(); + } + } + } + + panic!() + } +} diff --git a/src/ship/mod.rs b/src/ship/mod.rs index 3df90d6..ed1787d 100644 --- a/src/ship/mod.rs +++ b/src/ship/mod.rs @@ -1 +1,2 @@ -pub mod ship; \ No newline at end of file +pub mod ship; +pub mod location; diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 0ae1eb3..57e35d3 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -16,6 +16,7 @@ use crate::entity::gateway::EntityGateway; use crate::entity::account::{UserAccount, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; use crate::entity::character::Character; use crate::login::login::get_login_status; +use crate::ship::location::ClientLocation; pub const SHIP_PORT: u16 = 23423; @@ -73,6 +74,7 @@ struct ClientState { character: Character, session: Session, block: u32, + client_location: ClientLocation, } impl ClientState { @@ -82,6 +84,7 @@ impl ClientState { character: Character::default(), session: Session::new(), block: 0, + client_location: ClientLocation::new(), } } }