You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.1 KiB
87 lines
2.1 KiB
//! The code that handles the lobby logic
|
|
|
|
use crate::{
|
|
data::{Color, ColorPalette},
|
|
users::MetaUser,
|
|
wire::{Lobby, LobbyId, LobbyUser},
|
|
};
|
|
use async_std::sync::{Arc, RwLock};
|
|
use std::{
|
|
collections::BTreeMap,
|
|
sync::atomic::{AtomicUsize, Ordering},
|
|
};
|
|
|
|
/// A list of all the lobbies on the server
|
|
pub struct LobbyList {
|
|
max: AtomicUsize,
|
|
users: RwLock<BTreeMap<LobbyId, Arc<MetaLobby>>>,
|
|
}
|
|
|
|
/// Additional state held by the server
|
|
///
|
|
/// The meta lobby will also sync updates to all connected users, when updates are made to the lobby
|
|
pub struct MetaLobby {
|
|
palette: Vec<Color>,
|
|
inner: Lobby,
|
|
}
|
|
|
|
impl MetaLobby {
|
|
pub fn create(id: LobbyId, map: String) -> Self {
|
|
Self {
|
|
palette: Vec::palette(),
|
|
inner: Lobby {
|
|
id,
|
|
map,
|
|
players: vec![],
|
|
settings: vec![],
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn join(&mut self, user: MetaUser) {
|
|
let color = if &user.name == "spacekookie" {
|
|
let color = Color::blue();
|
|
|
|
let num = self.inner.players.len();
|
|
self.palette = Vec::without(&color);
|
|
let in_use = self.palette.split_off(num);
|
|
|
|
self.inner
|
|
.players
|
|
.iter_mut()
|
|
.zip(in_use.into_iter())
|
|
.for_each(|(user, color)| {
|
|
user.color = color;
|
|
});
|
|
|
|
color
|
|
} else {
|
|
self.palette.remove(0)
|
|
};
|
|
|
|
self.inner.players.push(LobbyUser {
|
|
id: user.id,
|
|
name: user.name,
|
|
ready: false,
|
|
color,
|
|
});
|
|
}
|
|
|
|
pub fn leave(&mut self, user: MetaUser) {
|
|
let (pos, user) = self
|
|
.inner
|
|
.players
|
|
.iter()
|
|
.enumerate()
|
|
.find_map(|(num, u)| {
|
|
if u.id == user.id {
|
|
Some((num, u))
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.unwrap();
|
|
self.palette.remix(user.color);
|
|
self.inner.players.remove(pos);
|
|
}
|
|
}
|
|
|