2022-10-04 16:59:12 -05:00
|
|
|
use std::{
|
2022-10-12 10:08:23 -05:00
|
|
|
sync::Arc,
|
2022-10-04 16:59:12 -05:00
|
|
|
io::Error as IoError,
|
|
|
|
collections::HashMap,
|
|
|
|
};
|
|
|
|
|
2022-10-12 10:08:23 -05:00
|
|
|
use tokio::{
|
|
|
|
net::{TcpListener},
|
|
|
|
sync::{mpsc, Mutex},
|
|
|
|
};
|
|
|
|
|
|
|
|
use futures::{
|
|
|
|
select,
|
|
|
|
FutureExt,
|
|
|
|
};
|
2022-10-03 13:18:40 -05:00
|
|
|
|
2022-10-03 14:18:25 -05:00
|
|
|
mod message;
|
2022-10-04 16:59:12 -05:00
|
|
|
use message::{Message, MessageWebSocket};
|
2022-10-03 14:42:15 -05:00
|
|
|
mod code_generator;
|
|
|
|
use code_generator::CodeGenerator;
|
2022-10-03 13:18:40 -05:00
|
|
|
|
2022-10-04 16:59:12 -05:00
|
|
|
#[tokio::main]
|
|
|
|
async fn main() -> Result<(), IoError> {
|
|
|
|
let global_state = Arc::new(GlobalState::default());
|
2022-10-12 10:08:23 -05:00
|
|
|
|
|
|
|
// Bind socket
|
2022-10-04 16:59:12 -05:00
|
|
|
let socket = TcpListener::bind("127.0.0.1:8080").await;
|
|
|
|
let listener = socket.expect("Could not bind to localhost:8080");
|
|
|
|
println!("Server running");
|
|
|
|
|
2022-10-12 10:08:23 -05:00
|
|
|
// Accept all incoming connections
|
2022-10-04 16:59:12 -05:00
|
|
|
while let Ok((stream, addr)) = listener.accept().await {
|
|
|
|
let global_state = Arc::clone(&global_state);
|
|
|
|
let mut local_state = LocalState::default();
|
|
|
|
tokio::spawn(async move {
|
|
|
|
// Upgrade to a WS connection
|
|
|
|
let mut ws = MessageWebSocket(tokio_tungstenite::accept_async(stream)
|
|
|
|
.await
|
|
|
|
.expect("Could not establish connection"));
|
|
|
|
println!("Connected to {}", addr);
|
2022-10-04 09:46:17 -05:00
|
|
|
|
2022-10-12 10:08:23 -05:00
|
|
|
loop {
|
|
|
|
match &mut local_state.channel {
|
|
|
|
Some(channel) => {
|
|
|
|
select! {
|
|
|
|
msg = channel.rx.recv().fuse() =>
|
|
|
|
handle_server_msg(msg.unwrap(), &mut local_state, &mut ws).await,
|
|
|
|
msg = ws.next().fuse() =>
|
|
|
|
handle_client_msg(msg.unwrap(), &global_state, &mut local_state, &mut ws).await,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
let msg = ws.next().await;
|
|
|
|
handle_client_msg(msg.unwrap(), &global_state, &mut local_state, &mut ws).await;
|
|
|
|
}
|
|
|
|
}
|
2022-10-04 16:59:12 -05:00
|
|
|
}
|
2022-10-03 13:18:40 -05:00
|
|
|
});
|
2022-09-20 15:53:53 -05:00
|
|
|
}
|
2022-10-04 16:59:12 -05:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2022-10-12 10:08:23 -05:00
|
|
|
async fn handle_client_msg(
|
2022-10-04 16:59:12 -05:00
|
|
|
msg: Message,
|
|
|
|
global_state: &GlobalState,
|
|
|
|
local_state: &mut LocalState,
|
|
|
|
ws: &mut MessageWebSocket
|
|
|
|
) {
|
|
|
|
match msg.command.as_str() {
|
|
|
|
"HOST" => {
|
2022-10-12 10:08:23 -05:00
|
|
|
let room_code = global_state.code_generator.lock().await.generate();
|
|
|
|
let mut game_controller = GameController::default();
|
|
|
|
|
|
|
|
let [client_channel, server_channel] = channel_pair();
|
|
|
|
local_state.channel = Some(client_channel);
|
|
|
|
game_controller.channels.push(server_channel);
|
|
|
|
|
|
|
|
let game_controller = Arc::new(Mutex::new(game_controller));
|
|
|
|
global_state.rooms.lock().await.insert(room_code.clone(), Arc::clone(&game_controller));
|
|
|
|
tokio::spawn(async move {game_loop(game_controller)});
|
|
|
|
ws.send(msg!("ROOM_CODE", room_code)).await.unwrap();
|
2022-10-04 16:59:12 -05:00
|
|
|
}
|
|
|
|
"JOIN" => {
|
|
|
|
let room_code = &msg.args[0];
|
2022-10-12 10:08:23 -05:00
|
|
|
let rooms = global_state.rooms.lock().await;
|
|
|
|
let room = rooms.get(room_code);
|
|
|
|
|
|
|
|
match room {
|
|
|
|
Some(room) => {
|
|
|
|
let mut room = room.lock().await;
|
|
|
|
let [client_channel, server_channel] = channel_pair();
|
|
|
|
local_state.channel = Some(client_channel);
|
|
|
|
room.channels.push(server_channel);
|
|
|
|
ws.send(msg!("JOIN_OK")).await.unwrap();
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
ws.send(msg!("JOIN_INVALID")).await.unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => if let Some(channel) = &local_state.channel {
|
|
|
|
// Forward message to the server
|
|
|
|
channel.tx.send(msg).await;
|
2022-10-04 16:59:12 -05:00
|
|
|
}
|
|
|
|
}
|
2022-09-20 15:53:53 -05:00
|
|
|
}
|
2022-10-04 09:46:17 -05:00
|
|
|
|
2022-10-12 10:08:23 -05:00
|
|
|
async fn handle_server_msg(
|
|
|
|
msg: Message,
|
|
|
|
local_state: &mut LocalState,
|
|
|
|
ws: &mut MessageWebSocket
|
|
|
|
) {
|
|
|
|
todo!();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn game_loop(game_controller: Arc<Mutex<GameController>>) {
|
|
|
|
todo!();
|
|
|
|
}
|
|
|
|
|
2022-10-03 13:18:40 -05:00
|
|
|
#[derive(Default)]
|
2022-10-04 16:59:12 -05:00
|
|
|
struct GlobalState {
|
|
|
|
code_generator: Arc<Mutex<CodeGenerator>>,
|
2022-10-12 10:08:23 -05:00
|
|
|
rooms: Arc<Mutex<HashMap<String, Arc<Mutex<GameController>>>>>,
|
2022-09-20 15:53:53 -05:00
|
|
|
}
|
|
|
|
|
2022-10-04 16:59:12 -05:00
|
|
|
#[derive(Default)]
|
2022-10-12 10:08:23 -05:00
|
|
|
struct GameController {
|
|
|
|
channels: Vec<Channel>,
|
|
|
|
}
|
2022-10-04 16:59:12 -05:00
|
|
|
|
|
|
|
#[derive(Default)]
|
|
|
|
struct LocalState {
|
2022-10-12 10:08:23 -05:00
|
|
|
channel: Option<Channel>,
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Channel {
|
|
|
|
tx: mpsc::Sender<Message>,
|
|
|
|
rx: mpsc::Receiver<Message>,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn channel_pair() -> [Channel; 2] {
|
|
|
|
let (atx, brx) = mpsc::channel(32);
|
|
|
|
let (btx, arx) = mpsc::channel(32);
|
|
|
|
[
|
|
|
|
Channel { tx: atx, rx: arx },
|
|
|
|
Channel { tx: btx, rx: brx },
|
|
|
|
]
|
2022-09-20 15:53:53 -05:00
|
|
|
}
|