From c01adc4fb47273b3881dbc84391014be93174965 Mon Sep 17 00:00:00 2001 From: serxoz Date: Fri, 23 Sep 2022 13:55:10 +0200 Subject: [PATCH] =?UTF-8?q?servidor=20as=C3=ADncrono=20implementado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 68 +++++++++----- src/player.rs | 24 +++-- src/rlib.rs | 47 +++++----- 5 files changed, 326 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07b6942..5307c89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "bitflags" version = "1.3.2" @@ -14,6 +20,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" + [[package]] name = "cfg-if" version = "1.0.0" @@ -72,6 +84,15 @@ dependencies = [ "wasi", ] +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "idna" version = "0.3.0" @@ -88,6 +109,43 @@ version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + [[package]] name = "mysqlclient-sys" version = "0.2.5" @@ -98,12 +156,57 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + [[package]] name = "percent-encoding" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + [[package]] name = "pkg-config" version = "0.3.25" @@ -188,6 +291,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + [[package]] name = "reentrada" version = "0.1.0" @@ -195,9 +307,41 @@ dependencies = [ "diesel", "dotenv", "rand", + "tokio", "uuid", ] +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" + +[[package]] +name = "socket2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "syn" version = "1.0.99" @@ -224,6 +368,38 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "tokio" +version = "1.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-bidi" version = "0.3.8" @@ -295,3 +471,68 @@ name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/Cargo.toml b/Cargo.toml index 3e4b3e2..be88b27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" diesel = { version = "2.0.0", features = ["mysql"] } dotenv = "0.15.0" rand = "0.8.5" +tokio = { version = "1", features = ["full"] } [dependencies.uuid] version = "1.1.2" diff --git a/src/main.rs b/src/main.rs index df20d31..094afee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,7 @@ +use tokio::io::AsyncWriteExt; +use tokio::net::{TcpListener, TcpStream}; +use std::{env, io}; + pub mod rlib; pub mod rlocation; pub mod player; @@ -11,41 +15,57 @@ pub mod npc; use crate::rlib::set_player; use crate::player::update_player; -fn main() { - // intro - print!("\x1B[2J"); // clear screen - print!("\x1B[1;1H"); // position on 1,1 +#[tokio::main] +async fn main() -> io::Result<()> { + let addr = env::args() + .nth(1) + .unwrap_or_else(|| "127.0.0.1:1337".to_string()); - println!(""); - println!(""); - println!(" ██████╗░███████╗███████╗███╗░░██╗████████╗██████╗░░█████╗░██████╗░░█████╗░"); - println!(" ██╔══██╗██╔════╝██╔════╝████╗░██║╚══██╔══╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗"); - println!(" ██████╔╝█████╗░░█████╗░░██╔██╗██║░░░██║░░░██████╔╝███████║██║░░██║███████║"); - println!(" ██╔══██╗██╔══╝░░██╔══╝░░██║╚████║░░░██║░░░██╔══██╗██╔══██║██║░░██║██╔══██║"); - println!(" ██║░░██║███████╗███████╗██║░╚███║░░░██║░░░██║░░██║██║░░██║██████╔╝██║░░██║"); - println!(" ╚═╝░░╚═╝╚══════╝╚══════╝╚═╝░░╚══╝░░░╚═╝░░░╚═╝░░╚═╝╚═╝░░╚═╝╚═════╝░╚═╝░░╚═╝"); - println!(""); - println!(" Bienvenido a Reentrada. Una aventura en el espacio."); - println!(""); + let listener = TcpListener::bind(&addr).await?; + println!("Escoitando en: {}", addr); + + loop { + let (socket, _) = listener.accept().await?; + tokio::spawn(procesar_socket(socket)); // tokio::spawn """"abre un novo fío"""" + } +} + +async fn procesar_socket(mut socket: TcpStream) -> io::Result<()> { + // intro + socket.write_all(b"\x1B[2J").await?; // clear screen + socket.write_all(b"\x1B[1;1H").await?; // position on 1,1 + + let banner = "\n\n\ + ██████╗░███████╗███████╗███╗░░██╗████████╗██████╗░░█████╗░██████╗░░█████╗░\n\ + ██╔══██╗██╔════╝██╔════╝████╗░██║╚══██╔══╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗\n\ + ██████╔╝█████╗░░█████╗░░██╔██╗██║░░░██║░░░██████╔╝███████║██║░░██║███████║\n\ + ██╔══██╗██╔══╝░░██╔══╝░░██║╚████║░░░██║░░░██╔══██╗██╔══██║██║░░██║██╔══██║\n\ + ██║░░██║███████╗███████╗██║░╚███║░░░██║░░░██║░░██║██║░░██║██████╔╝██║░░██║\n\ + ╚═╝░░╚═╝╚══════╝╚══════╝╚═╝░░╚══╝░░░╚═╝░░░╚═╝░░╚═╝╚═╝░░╚═╝╚═════╝░╚═╝░░╚═╝\n\ + \n\ + Bienvenido a Reentrada. Una aventura en el espacio.\n\n"; + socket.write_all(banner.as_bytes()).await?; let mut command = rlib::Command::new(); let mut output: String; - let mut player = set_player(); + let mut player = set_player(&mut socket).await; - println!("Bienvenido {}. Vamos a empezar a jugar...", player.nombre); - println!(""); - println!("Despiertas en la oscuridad con un fuerte dolor de cabeza."); - println!("Un fuerte sonido de alarma machaca tus oídos. No ayuda nada a tu dolor de cabeza."); - println!("Qué vas a hacer?"); + let intro = format!("Bienvenido {}. Vamos a empezar a jugar... \n\n\ + Despiertas en la oscuridad con un fuerte dolor de cabeza. \n\ + Un fuerte sonido de alarma machaca tus oídos. No ayuda nada a tu dolor de cabeza. \n\ + Qué vas a hacer?", player.nombre); + socket.write_all(intro.as_bytes()).await?; // main loop while command.verb != "salir" { - command = rlib::get_input(); + command = rlib::get_input(&mut socket).await; output = rlib::update_state(&mut player, &command); - rlib::update_screen(output); + rlib::update_screen(&mut socket, output).await; update_player(&player).expect("Error actualizando jugador!!"); } // salir - println!("Adiós."); + socket.write_all("Adiós.\n".as_bytes()).await?; + + return Ok(()); } diff --git a/src/player.rs b/src/player.rs index be812c8..9254d3d 100644 --- a/src/player.rs +++ b/src/player.rs @@ -123,7 +123,7 @@ pub fn execute_drop(player: &mut Player, nombre: &str) -> String { // execute_kill intenta matar un npc pub fn execute_kill(player: &mut Player, nombre: &str) -> String { - let output: String; + let mut output= String::from(""); let location = &player.location; let npc = get_npc_here(location.to_string(), nombre.to_string()); @@ -136,9 +136,11 @@ pub fn execute_kill(player: &mut Player, nombre: &str) -> String { if tohit >= malo.ca { let damage = rand::thread_rng().gen_range(1..6); malo.hp = malo.hp - damage; - println!("Golpeas a {} por {} de daño, le quedan {} pg.", malo.nombre, damage, malo.hp); + let tmp = format!("Golpeas a {} por {} de daño, le quedan {} pg.", malo.nombre, damage, malo.hp); + output = format!("{}\n{}", output, tmp); } else { - println!("No consigues golpear a {}.", malo.nombre); + let tmp = format!("No consigues golpear a {}.", malo.nombre); + output = format!("{}\n{}", output, tmp); } // turno do malo @@ -146,19 +148,25 @@ pub fn execute_kill(player: &mut Player, nombre: &str) -> String { if tohit >= player.ca { let damage = rand::thread_rng().gen_range(1..6); player.hp = player.hp - damage; - println!("{} te golpea por {} de daño, te quedan {} pg.", malo.nombre, damage, player.hp); + let tmp = format!("{} te golpea por {} de daño, te quedan {} pg.", malo.nombre, damage, player.hp); + output = format!("{}\n{}", output, tmp); } else { - println!("{} no consigue herirte.", malo.nombre); + let tmp = format!("{} no consigue herirte.", malo.nombre); + output = format!("{}\n{}", output, tmp); } + print!("{}",output); //FIXME si saco esto, non o concatena coa salida } + let resolucion: String; if malo.hp <= 0 { - output = format!("{} ha muerto!", malo.nombre); + resolucion = format!("{} ha muerto!", malo.nombre); } else if player.hp <= 0 { - output = format!("{} ha muerto!", player.nombre); + resolucion = format!("{} ha muerto!", player.nombre); } else { - output = String::from("No se que ha pasado. Alguien debería estar muerto.") + resolucion = String::from("No se que ha pasado. Alguien debería estar muerto."); } + output = format!("{}\n{}", output, resolucion); + } else { output = String::from("No encuentro lo que quieres matar."); } diff --git a/src/rlib.rs b/src/rlib.rs index b76ca24..3ac7038 100644 --- a/src/rlib.rs +++ b/src/rlib.rs @@ -1,4 +1,5 @@ -use std::io::{self, Write}; +use tokio::net::TcpStream; +use tokio::io::{AsyncReadExt,AsyncWriteExt}; use crate::rlocation::{execute_go, execute_look}; use crate::player::*; use crate::models::Player; @@ -25,19 +26,19 @@ impl Command { } } -pub fn set_player() -> Player { +pub async fn set_player(socket: &mut TcpStream) -> Player { // prompt - println!(""); - println!("Cuál es tu nombre?"); - print!("> "); - io::stdout().flush().unwrap(); + socket.write_all(b"\n").await.unwrap(); + socket.write_all("Cuál es tu nombre?\n".as_bytes()).await.unwrap(); + socket.write_all(b"> ").await.unwrap(); - let mut input_str = String::new(); + let mut buf = vec![0; 1024]; + let n = socket + .read(&mut buf) + .await + .unwrap(); - io::stdin() - .read_line(&mut input_str) - .expect("Error leyendo..."); - println!(""); + let input_str = String::from_utf8(buf[0..n].to_vec()).unwrap(); // parse let nick = input_str.trim(); @@ -68,18 +69,18 @@ pub fn set_player() -> Player { player } -pub fn get_input() -> Command { +pub async fn get_input(socket: &mut TcpStream) -> Command { // prompt - println!(""); - print!("> "); - io::stdout().flush().unwrap(); + socket.write_all(b"\n").await.unwrap(); + socket.write_all(b"> ").await.unwrap(); - let mut input_str = String::new(); + let mut buf = vec![0; 1024]; + let n = socket + .read(&mut buf) + .await + .unwrap(); - io::stdin() - .read_line(&mut input_str) - .expect("Error leyendo..."); - println!(""); + let input_str = String::from_utf8(buf[0..n].to_vec()).unwrap(); // parse let mut command = Command::new(); @@ -93,7 +94,7 @@ pub fn update_state(player: &mut Player, command: &Command) -> String { let output: String; match command.verb.as_str() { - "salir" => output = format!("Saliendo.\nGracias por jugar! :D"), + "salir" => output = format!("Saliendo.\nGracias por jugar! :D\n"), "mirar" => output = execute_look(player, command.noun.as_str()), "ir" => output = execute_go(player, command.noun.as_str()), "n" => output = execute_go(player, "n"), @@ -112,6 +113,6 @@ pub fn update_state(player: &mut Player, command: &Command) -> String { output } -pub fn update_screen(output: String) { - println!("{}", output); +pub async fn update_screen(socket: &mut TcpStream, output: String) { + socket.write_all(output.as_bytes()).await.unwrap(); }