add clientlocation functions
This commit is contained in:
parent
3ece862163
commit
c2ceb034d8
@ -3,6 +3,8 @@ use crate::common::serverstate::ClientId;
|
|||||||
// TODO: room passwords?
|
// TODO: room passwords?
|
||||||
// TODO: remove clients from areas (or upon insert, remove that id from anywhere else)
|
// TODO: remove clients from areas (or upon insert, remove that id from anywhere else)
|
||||||
|
|
||||||
|
pub const MAX_ROOMS: usize = 128;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct AreaClient {
|
pub struct AreaClient {
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
@ -42,14 +44,16 @@ impl<const N: usize> InnerClientArea<{N}> {
|
|||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
fn remove(&mut self, id: ClientId) {
|
fn remove(&mut self, id: ClientId) -> bool {
|
||||||
for areaclient in self.clients.iter_mut() {
|
for areaclient in self.clients.iter_mut() {
|
||||||
if let Some(client) = *areaclient {
|
if let Some(client) = *areaclient {
|
||||||
if client.client_id == id {
|
if client.client_id == id {
|
||||||
*areaclient = None;
|
*areaclient = None;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contains(&self, id: ClientId) -> bool {
|
fn contains(&self, id: ClientId) -> bool {
|
||||||
@ -70,17 +74,12 @@ impl<const N: usize> InnerClientArea<{N}> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type LobbyId = usize;
|
pub struct LobbyId(pub usize);
|
||||||
pub type RoomId = usize;
|
pub struct RoomId(pub usize);
|
||||||
|
|
||||||
pub type Lobby = InnerClientArea<12>;
|
pub type Lobby = InnerClientArea<12>;
|
||||||
pub type Room = InnerClientArea<4>;
|
pub type Room = InnerClientArea<4>;
|
||||||
|
|
||||||
pub struct ClientLocation {
|
|
||||||
lobbies: [Lobby; 15],
|
|
||||||
rooms: [Option<Room>; 128],
|
|
||||||
}
|
|
||||||
|
|
||||||
trait ClientArea<'a> {
|
trait ClientArea<'a> {
|
||||||
fn clients(&'a self) -> std::slice::Iter<'_, Option<AreaClient>>;
|
fn clients(&'a self) -> std::slice::Iter<'_, Option<AreaClient>>;
|
||||||
}
|
}
|
||||||
@ -156,35 +155,81 @@ impl<'a> Area<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum CreateRoomError {
|
||||||
|
NoOpenSlots,
|
||||||
|
ClientInAreaAlready,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum JoinRoomError {
|
pub enum JoinRoomError {
|
||||||
RoomDoesNotExist,
|
RoomDoesNotExist,
|
||||||
RoomFull,
|
RoomFull,
|
||||||
|
ClientInAreaAlready,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum JoinLobbyError {
|
pub enum JoinLobbyError {
|
||||||
LobbyDoesNotExist,
|
LobbyDoesNotExist,
|
||||||
LobbyFull,
|
LobbyFull,
|
||||||
|
ClientInAreaAlready,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ClientLocation {
|
||||||
|
lobbies: [Lobby; 15],
|
||||||
|
rooms: [Option<Room>; MAX_ROOMS],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientLocation {
|
impl ClientLocation {
|
||||||
pub fn new() -> ClientLocation {
|
pub fn new() -> ClientLocation {
|
||||||
ClientLocation {
|
ClientLocation {
|
||||||
lobbies: [Lobby::new(); 15],
|
lobbies: [Lobby::new(); 15],
|
||||||
rooms: [None; 128],
|
rooms: [None; MAX_ROOMS],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn err_if_client_is_in_area<E>(&mut self, id: ClientId, err: E) -> Result<(), E> {
|
||||||
|
let in_lobby = self.lobbies.iter()
|
||||||
|
.any(|k| k.contains(id));
|
||||||
|
let in_room = self.rooms.iter()
|
||||||
|
.filter(|k| k.is_none())
|
||||||
|
.map(|k| k.unwrap())
|
||||||
|
.any(|k| k.contains(id));
|
||||||
|
|
||||||
|
if in_lobby || in_room {
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_to_lobby(&mut self, id: ClientId, lobby: LobbyId) -> Result<usize, JoinLobbyError> {
|
pub fn add_to_lobby(&mut self, id: ClientId, lobby: LobbyId) -> Result<usize, JoinLobbyError> {
|
||||||
self.lobbies.get_mut(lobby)
|
self.err_if_client_is_in_area(id, JoinLobbyError::ClientInAreaAlready)?;
|
||||||
|
self.lobbies.get_mut(lobby.0)
|
||||||
.ok_or(JoinLobbyError::LobbyDoesNotExist)?
|
.ok_or(JoinLobbyError::LobbyDoesNotExist)?
|
||||||
.add(id)
|
.add(id)
|
||||||
.ok_or(JoinLobbyError::LobbyFull)
|
.ok_or(JoinLobbyError::LobbyFull)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_room(&mut self, id: ClientId) -> Result<RoomId, CreateRoomError> {
|
||||||
|
self.err_if_client_is_in_area(id, CreateRoomError::ClientInAreaAlready)?;
|
||||||
|
let (room_id, empty_room) = self.rooms.iter_mut()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, k)| k.is_none())
|
||||||
|
.nth(0)
|
||||||
|
.ok_or(CreateRoomError::NoOpenSlots)?;
|
||||||
|
|
||||||
|
let mut new_room = Room::new();
|
||||||
|
new_room.add(id);
|
||||||
|
*empty_room = Some(new_room);
|
||||||
|
|
||||||
|
Ok(RoomId(room_id))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_to_room(&mut self, id: ClientId, room: RoomId) -> Result<usize, JoinRoomError> {
|
pub fn add_to_room(&mut self, id: ClientId, room: RoomId) -> Result<usize, JoinRoomError> {
|
||||||
self.rooms.get_mut(room)
|
self.err_if_client_is_in_area(id, JoinRoomError::ClientInAreaAlready)?;
|
||||||
|
self.rooms.get_mut(room.0)
|
||||||
.ok_or(JoinRoomError::RoomDoesNotExist)?
|
.ok_or(JoinRoomError::RoomDoesNotExist)?
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.ok_or(JoinRoomError::RoomDoesNotExist)?
|
.ok_or(JoinRoomError::RoomDoesNotExist)?
|
||||||
@ -209,4 +254,20 @@ impl ClientLocation {
|
|||||||
|
|
||||||
panic!("client is not in a room/lobby")
|
panic!("client is not in a room/lobby")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove_from_location(&mut self, id: ClientId) {
|
||||||
|
let in_lobby = self.lobbies.iter_mut()
|
||||||
|
.map(|lobby| lobby.remove(id))
|
||||||
|
.any(|k| k);
|
||||||
|
|
||||||
|
if in_lobby {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.rooms.iter_mut()
|
||||||
|
.filter(|lobby| lobby.is_none())
|
||||||
|
.map(|lobby| lobby.unwrap())
|
||||||
|
.map(|mut lobby| lobby.remove(id))
|
||||||
|
.any(|k| k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ use crate::entity::account::{UserAccount, UserSettings, USERFLAG_NEWCHAR, USERFL
|
|||||||
use crate::entity::character::Character;
|
use crate::entity::character::Character;
|
||||||
use crate::entity::item::ItemLocation;
|
use crate::entity::item::ItemLocation;
|
||||||
use crate::login::login::get_login_status;
|
use crate::login::login::get_login_status;
|
||||||
use crate::ship::location::ClientLocation;
|
use crate::ship::location::{ClientLocation, LobbyId, RoomId};
|
||||||
use crate::ship::character::{CharacterBuilder, FullCharacterBuilder};
|
use crate::ship::character::{CharacterBuilder, FullCharacterBuilder};
|
||||||
|
|
||||||
pub const SHIP_PORT: u16 = 23423;
|
pub const SHIP_PORT: u16 = 23423;
|
||||||
@ -197,7 +197,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn send_player_to_lobby(&mut self, id: ClientId, _pkt: &CharData) -> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
|
fn send_player_to_lobby(&mut self, id: ClientId, _pkt: &CharData) -> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
|
||||||
self.client_location.add_to_lobby(id, 0).unwrap();
|
self.client_location.add_to_lobby(id, LobbyId(0)).unwrap();
|
||||||
|
|
||||||
let lobby = self.client_location.get_area_by_user(id);
|
let lobby = self.client_location.get_area_by_user(id);
|
||||||
let clients = lobby.clients();
|
let clients = lobby.clients();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user