~yujiri/roguelike

ca91f548a516fd28bdf7abd35ab6e9a965c19ce1 — Evin Yulo 10 months ago bdebbf9
fix lobby shit!
3 files changed, 45 insertions(+), 22 deletions(-)

M client/src/lobby.rs
M client/src/main.rs
M server/src/main.rs
M client/src/lobby.rs => client/src/lobby.rs +1 -1
@@ 20,7 20,7 @@ impl State {
		}
		let x = mode.w as i16 / 2;
		let y = mode.h as i16 - 108;
		sdl.draw_text_centered(&to_hex(&self.lobby.code), WHITE, x as i32, y as i32);
		sdl.draw_text_centered(&to_hex(&self.lobby.code), WHITE, x as i32, y as i32 - 108);
		let clicked = sdl.button(x - 216, y, "Leave", GREEN, BLACK);
		if clicked {
			outgoing.lock().unwrap().push(GlobalAction::Leave);

M client/src/main.rs => client/src/main.rs +3 -0
@@ 54,6 54,9 @@ impl Globals {
			(State::Search(state), GlobalEvent::Available(lobby)) => {
				state.lobbies.push(lobby);
			},
			(State::Search(state), GlobalEvent::Unavailable(code)) => {
				state.lobbies.retain(|l| l.code != code);
			},
			(State::Search(_), GlobalEvent::Created(code)) => {
				self.state = State::Lobby(lobby::State::from_create(self.me.clone(), code));
			},

M server/src/main.rs => server/src/main.rs +41 -21
@@ 2,6 2,7 @@ use roguelike_common::*;
use sodiumoxide::crypto::box_::*;
use sodiumoxide::crypto::sealedbox::{self, SEALBYTES};
use sodiumoxide::randombytes;
use std::collections::HashMap;
use std::env;
use std::io::Read;
use std::net::{TcpListener, TcpStream};


@@ 46,17 47,31 @@ impl Lobby {
}

pub struct Context {
	searchers: Vec<Arc<RwLock<Player>>>,
	searchers: HashMap<Id, Arc<RwLock<Player>>>,
	lobbies: Vec<Arc<RwLock<Lobby>>>,
	incoming: Vec<(Arc<RwLock<Player>>, GlobalAction)>,
}
impl Context {
	pub fn add_searcher(&mut self, player: Arc<RwLock<Player>>) {
		let mut player_unlocked = player.write().unwrap();
		player_unlocked.status = PlayerStatus::Searching;
		self.searchers.insert(player_unlocked.external.id, Arc::clone(&player));
		for lobby in &self.lobbies {
			let lobby = lobby.read().unwrap();
			if lobby.public {
				player_unlocked.outgoing.push(GlobalEvent::Available(lobby.external()));
			}
		}

	}
}

fn main() {
	sodiumoxide::init().unwrap();
	let addr = env::args().nth(1).unwrap_or_else(|| "[::]".into());
	let listener = TcpListener::bind(format!("{}:{}", addr, PORT)).unwrap();
	let ctx = Arc::new(RwLock::new(Context{
		searchers: vec![],
		searchers: HashMap::new(),
		lobbies: vec![],
		incoming: vec![],
	}));


@@ 86,15 101,10 @@ fn handle_lobby_action(ctx: &Arc<RwLock<Context>>, player: Arc<RwLock<Player>>, 
	match action {
		GlobalAction::Name(name) => {
			let mut ctx = ctx.write().unwrap();
			ctx.searchers.push(Arc::clone(&player));
			let mut player = player.write().unwrap();
			player.external.name = name;
			for lobby in &ctx.lobbies {
				let lobby = lobby.read().unwrap();
				if lobby.public {
					player.outgoing.push(GlobalEvent::Available(lobby.external()));
				}
			}
			let mut player_unlocked = player.write().unwrap();
			player_unlocked.external.name = name;
			drop(player_unlocked);
			ctx.add_searcher(player);
		},
		GlobalAction::Create => {
			let mut player_unlocked = player.write().unwrap();


@@ 107,13 117,15 @@ fn handle_lobby_action(ctx: &Arc<RwLock<Context>>, player: Arc<RwLock<Player>>, 
				in_game: false,
			}));
			player_unlocked.status = PlayerStatus::Lobby(Arc::clone(&lobby));
			ctx.write().unwrap().lobbies.push(lobby);
			player_unlocked.outgoing.push(GlobalEvent::Created(code));
			let mut ctx = ctx.write().unwrap();
			ctx.lobbies.push(lobby);
			ctx.searchers.remove(&player_unlocked.external.id);
		},
		GlobalAction::Join(code) => {
			let mut player_unlocked = player.write().unwrap();
			if !matches!(player_unlocked.status, PlayerStatus::Searching) { return }
			let ctx = ctx.read().unwrap();
			let mut ctx = ctx.write().unwrap();
			for lobby in &ctx.lobbies {
				let mut lobby_unlocked = lobby.write().unwrap();
				if lobby_unlocked.code == code {


@@ 124,19 136,20 @@ fn handle_lobby_action(ctx: &Arc<RwLock<Context>>, player: Arc<RwLock<Player>>, 
					}
					player_unlocked.outgoing.push(GlobalEvent::Accepted(lobby_unlocked.external()));
					lobby_unlocked.players.push(Arc::clone(&player));
					drop(lobby_unlocked);
					ctx.searchers.remove(&player_unlocked.external.id);
					break;
				}
			}
		},
		GlobalAction::Leave => {
			let mut player = player.write().unwrap();
			let id = player.external.id;
			let lobby = match &player.status {
			let player_unlocked = player.read().unwrap();
			let id = player_unlocked.external.id;
			let lobby = match &player_unlocked.status {
				PlayerStatus::Lobby(l) => Arc::clone(l),
				_ => return,
			};
			// TODO send them the list
			player.status = PlayerStatus::Searching;
			drop(player);
			drop(player_unlocked);
			let mut lobby = lobby.write().unwrap();
			let mut i = 0;
			while i < lobby.players.len() {


@@ 150,6 163,14 @@ fn handle_lobby_action(ctx: &Arc<RwLock<Context>>, player: Arc<RwLock<Player>>, 
					i += 1;
				}
			}
			let empty = lobby.players.is_empty();
			let code = lobby.code;
			drop(lobby);
			let mut ctx = ctx.write().unwrap();
			if empty {
				ctx.lobbies.retain(|l| l.read().unwrap().code != code);
			}
			ctx.add_searcher(player);
		},
		GlobalAction::SetPublic(public) => {
			let lobby = match &player.read().unwrap().status {


@@ 168,7 189,7 @@ fn handle_lobby_action(ctx: &Arc<RwLock<Context>>, player: Arc<RwLock<Player>>, 
			} else {
				GlobalEvent::Unavailable(lobby_unlocked.code)
			};
			for searcher in &ctx.read().unwrap().searchers {
			for searcher in ctx.read().unwrap().searchers.values() {
				searcher.write().unwrap().outgoing.push(event.clone());
			}
		},


@@ 197,7 218,6 @@ fn handle_lobby_action(ctx: &Arc<RwLock<Context>>, player: Arc<RwLock<Player>>, 
				player.write().unwrap().outgoing.push(GlobalEvent::Action(id, action.clone()));
			}
		},
		_ => {},
	}
}