From 0818bdc54bd948664dc7be6139d6fede67a50fc2 Mon Sep 17 00:00:00 2001 From: Selyatin Ismet Date: Sun, 21 Nov 2021 14:39:55 +0200 Subject: [PATCH] Multiplayer now kinda works --- Cargo.toml | 1 - src/main.rs | 21 +++++++++++---------- src/screens.rs | 26 +++++++++++++------------- src/socket.rs | 12 ++++++++---- src/types.rs | 5 +++-- 5 files changed, 35 insertions(+), 30 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 70be898..028c888 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ lto = "fat" opt-level = 3 [dependencies] -anyhow = "1.0.47" crossterm = "0.22.1" fastrand = "1.5.0" lazy_static = "1.4.0" diff --git a/src/main.rs b/src/main.rs index c5674cb..9bc6b76 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,19 +8,16 @@ use crossterm::{ cursor::{Hide, MoveTo, Show}, event::{self, Event, KeyCode, KeyEvent, KeyModifiers}, execute, queue, - style::{style, Color, Print, PrintStyledContent, SetForegroundColor, Stylize}, + style::{style, Print, PrintStyledContent, Stylize}, terminal::{self, Clear, ClearType}, - ExecutableCommand, QueueableCommand, }; use socket::Socket; use std::{ env, - io::{stdout, Read, Stdout, Write}, - net::TcpStream, - thread, + io::{self, stdout, Stdout, Write}, time::{Duration, Instant}, }; -use types::{Action, Player, Screen, State, Word}; +use types::{Player, Screen, State, Word}; lazy_static! { static ref DICTIONARY: Vec = include_str!("../dictionary.txt") @@ -40,7 +37,7 @@ fn reset_state(state: &mut State) { state.players.push(player); } -fn main_loop(stdout: &mut Stdout, state: &mut State) -> anyhow::Result<()> { +fn main_loop(stdout: &mut Stdout, state: &mut State) -> io::Result<()> { // Clear the previous frame queue!(stdout, Clear(ClearType::All))?; @@ -94,7 +91,7 @@ fn main_loop(stdout: &mut Stdout, state: &mut State) -> anyhow::Result<()> { state.socket = Some(Socket::new(&state.sock_addr)?); - let session_token: u16 = player.input.parse()?; + let session_token: u16 = player.input.parse().map_err(|_| io::Error::new(io::ErrorKind::Other, "Invalid Number."))?; player.sort_position = state.socket.as_mut().unwrap().join_session(session_token)?; @@ -125,6 +122,9 @@ fn main_loop(stdout: &mut Stdout, state: &mut State) -> anyhow::Result<()> { }) => { if let Some(player) = state.players.get_mut(state.current_player) { player.input.pop(); + if let Some(socket) = &mut state.socket { + socket.send_input('-')?; + } } } Event::Key(KeyEvent { @@ -136,6 +136,7 @@ fn main_loop(stdout: &mut Stdout, state: &mut State) -> anyhow::Result<()> { terminal::disable_raw_mode()?; std::process::exit(0); } + reset_state(state); state.screen = Screen::Main; } Event::Key(KeyEvent { @@ -207,7 +208,7 @@ fn main_loop(stdout: &mut Stdout, state: &mut State) -> anyhow::Result<()> { -fn main() -> anyhow::Result<()> { +fn main() -> io::Result<()> { let sock_addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_owned()); terminal::enable_raw_mode()?; @@ -244,7 +245,7 @@ fn main() -> anyhow::Result<()> { loop { if let Err(err) = main_loop(&mut stdout, &mut state) { - state.err = Some(err); + state.err = Some(Box::new(err)); } } } diff --git a/src/screens.rs b/src/screens.rs index 9d5a76b..7ca0f1c 100644 --- a/src/screens.rs +++ b/src/screens.rs @@ -2,15 +2,12 @@ use super::types::{Action, Player, State}; use crossterm::{ cursor::MoveTo, queue, - style::{style, Attribute, Color, Print, PrintStyledContent, SetForegroundColor, Stylize}, - terminal::{self, Clear, ClearType}, - ExecutableCommand, QueueableCommand, + style::{style, Attribute, Color, Print, PrintStyledContent, Stylize}, + terminal::{Clear, ClearType}, }; use std::{ - io::{self, Read, Stdout, Write}, + io::{self, Stdout}, iter, - net::TcpStream, - time::{Duration, Instant}, }; pub fn main(stdout: &mut Stdout, state: &State) -> io::Result<()> { @@ -96,6 +93,8 @@ pub fn multi_player(stdout: &mut Stdout, state: &mut State) -> io::Result<()> { let socket = state.socket.as_ref().unwrap(); + let mut should_go_forward = false; + for action in socket.actions().drain(..) { match action { Action::Join(position) => { @@ -126,18 +125,19 @@ pub fn multi_player(stdout: &mut Stdout, state: &mut State) -> io::Result<()> { } Action::Input((position, c)) => { if let Some(player) = state.players.get_mut(position) { - player.input.push(c); + if c == '-' { + player.input.pop(); + } else { + player.input.push(c); + } } } + Action::Forward => should_go_forward = true, }; } let (columns, rows) = (state.columns, state.rows as f32); - let elapsed_millis = state.instant.elapsed().as_millis(); - - let should_go_forward: bool = elapsed_millis - state.last_instant > 500; - let players_len = state.players.len(); let space_per_player = (rows / players_len as f32) as u16 - 2; @@ -150,7 +150,7 @@ pub fn multi_player(stdout: &mut Stdout, state: &mut State) -> io::Result<()> { // Might use multithreading to calculate each player's section, // but that might be overengineering too, so we'll see. for (i, player) in state.players.iter_mut().enumerate() { - let y_start = (i as u16 * space_per_player); + let y_start = i as u16 * space_per_player; let y_end = y_start + space_per_player; let color = match i { 0 => Color::Blue, @@ -159,6 +159,7 @@ pub fn multi_player(stdout: &mut Stdout, state: &mut State) -> io::Result<()> { 3 => Color::Yellow, _ => Color::White, }; + queue!( stdout, MoveTo(0, y_end), @@ -206,7 +207,6 @@ pub fn multi_player(stdout: &mut Stdout, state: &mut State) -> io::Result<()> { if should_go_forward { word.x += add_x; - state.last_instant = elapsed_millis; } add_x -= 1; diff --git a/src/socket.rs b/src/socket.rs index bac1e78..f9cdc8f 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -55,10 +55,14 @@ impl Socket { break; } - let action = match &buffer[..4] { - b"Join" => Action::Join(buffer[4]), - b"Left" => Action::Left(buffer[4].into()), - _ => Action::Input((buffer[0].into(), buffer[1].into())), + let action = if buffer[0] == b'+' { + Action::Forward + } else { + match &buffer[..4] { + b"Join" => Action::Join(buffer[4]), + b"Left" => Action::Left(buffer[4].into()), + _ => Action::Input((buffer[0].into(), buffer[1].into())), + } }; if let Ok(mut vec) = actions.try_lock() { diff --git a/src/types.rs b/src/types.rs index 10bb0e4..1bbb357 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,5 +1,5 @@ use super::socket::Socket; -use std::{net::TcpStream, time::Instant}; +use std::{time::Instant}; pub struct State { pub columns: u16, @@ -13,7 +13,7 @@ pub struct State { pub current_player: usize, pub session_token: Option, pub socket: Option, - pub err: Option, + pub err: Option>, } /// Used in Multiplayer to determine what kind of data is received @@ -22,6 +22,7 @@ pub enum Action { Input((usize, char)), Join(u8), Left(usize), + Forward } #[derive(Eq, PartialEq)]