107 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
		
		
			
		
	
	
			107 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
|  | 
 | ||
|  | use crate::common::serverstate::ClientId;
 | ||
|  | // TODO: room passwords?
 | ||
|  | 
 | ||
|  | #[derive(Copy, Clone)]
 | ||
|  | pub struct ClientArea<const N: usize> {
 | ||
|  |     clients: [Option<ClientId>; N],
 | ||
|  | }
 | ||
|  | 
 | ||
|  | impl<const N: usize> ClientArea<{N}> {
 | ||
|  |     pub fn new() -> ClientArea<{N}> {
 | ||
|  |         let mut clients: [std::mem::MaybeUninit<Option<ClientId>>; 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<ClientId>; N]).read()}
 | ||
|  |         }
 | ||
|  |     }
 | ||
|  |     
 | ||
|  |     
 | ||
|  |     fn add(&mut self, id: ClientId) -> Option<usize> {
 | ||
|  |         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<Room>; 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<usize, JoinLobbyError> {
 | ||
|  |         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<usize, JoinRoomError> {
 | ||
|  |         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<ClientId> {
 | ||
|  |         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!()
 | ||
|  |     }
 | ||
|  | }
 |