Compare commits

..

No commits in common. "99f145eb32124f04d32a057ab3a0fdec0e12159f" and "9d49e44b493f30fc1b56c85ce69eefa42ba2ce60" have entirely different histories.

10 changed files with 112 additions and 1731 deletions

1337
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -16,21 +16,9 @@ name = "client"
path = "src/bin/client.rs" path = "src/bin/client.rs"
[dependencies] [dependencies]
axum = "0.8.1"
tower = "0.5.2"
reqwest = "0.12.0"
hyper = { version = "1", features = ["full"] }
http-body-util = "0.1"
hyper-util = { version = "0.1", features = ["full"] }
rand = "0.9.0-beta.1" rand = "0.9.0-beta.1"
clap = "4.5.23" clap = "4.5.23"
<<<<<<< HEAD
tokio = { version = "1.42.0", features = ["full", "tracing"] } tokio = { version = "1.42.0", features = ["full", "tracing"] }
||||||| 45f9b5b
tokio = { version = "1.42.0", features = ["full"] }
=======
tokio = { version = "1.42.0", features = ["full","tracing"] }
>>>>>>> deke/ipertesto
console-subscriber = "0.1.5" console-subscriber = "0.1.5"
anyhow = "1.0.95" anyhow = "1.0.95"
serde_json = "1.0.135" serde_json = "1.0.135"
@ -40,8 +28,4 @@ petname = "2.0.2"
crossterm = "0.28.1" crossterm = "0.28.1"
tracing = "0.1.41" tracing = "0.1.41"
tracing-subscriber = "0.3.19" tracing-subscriber = "0.3.19"
<<<<<<< HEAD
||||||| 45f9b5b
=======
>>>>>>> deke/ipertesto

View file

@ -1,56 +1,33 @@
use std::{io::{Stdout, Write}, ops::BitOrAssign, time::Duration}; use lib::{client::Client, message::{Message, MessageKind}, message_read::MessageReader};
use axum::response::sse::Event;
use clap::builder::NonEmptyStringValueParser;
use lib::{client::Client, message::{Message, MessageKind}, message_read::MessageReader, player::Player};
use crossterm::{ use crossterm::{
cursor, event::{self, poll, Event as TermEvent, KeyCode, KeyModifiers}, execute, queue, style, terminal::{ execute,
disable_raw_mode, enable_raw_mode, Clear, ClearType, EnableLineWrap, EnterAlternateScreen terminal::{
} Clear,
ClearType,
enable_raw_mode,
disable_raw_mode
},
event::Event,
}; };
use tokio::io::{self, AsyncReadExt, AsyncWriteExt}; use tokio::io::{self, AsyncReadExt, AsyncWriteExt};
const HELP: &str = r#"CIAOTERPIA #[allow(unreachable_code)]
atm posso fare questo: #[tokio::main]
(ricorda di premere i bottoni) pub async fn main() -> anyhow::Result<()> {
- '1' mando giocante let mut client = Client::connect("127.0.0.1", 8080).await?;
- '2' mando lobbando (futuro) let local_address = client.stream.local_addr()?;
"#;
fn create_message_player(player: &Player) -> anyhow::Result<Message, anyhow::Error> { // enable_raw_mode()?;
Message::new( // execute!(
&player.get_name(), // std::io::stdout(),
MessageKind::Test, // Clear(ClearType::All),
player.encode()? // )?;
)
}
<<<<<<< HEAD
let (mut rd, mut wr) = io::split(client.stream); let (mut rd, mut wr) = io::split(client.stream);
||||||| 45f9b5b
// tokio::task::spawn(async move {
client.send_message(Message::new(&local_address.to_string(), MessageKind::Test, "test json").unwrap()).await.expect("failed to write to socket");
=======
async fn delete_player(player: &Player, client: reqwest::Client, addr: &str) -> anyhow::Result<()> {
let player_id = &player.name;
let response = client
.get([&addr, "/delete/", &player_id].concat())
.send().await;
>>>>>>> deke/ipertesto
<<<<<<< HEAD
let mut buf: Vec<u8> = Vec::with_capacity(4); let mut buf: Vec<u8> = Vec::with_capacity(4);
let mut message_reader = MessageReader::new(); let mut message_reader = MessageReader::new();
||||||| 45f9b5b
// let (mut rd, mut wr) = client.stream.split();
=======
if let Err(e) = &response {
println!("{e}\n");
return Ok(())
}
>>>>>>> deke/ipertesto
<<<<<<< HEAD
loop { loop {
match rd.read_exact(&mut buf).await { match rd.read_exact(&mut buf).await {
Ok(0) => { Ok(0) => {
@ -66,92 +43,7 @@ async fn delete_player(player: &Player, client: reqwest::Client, addr: &str) ->
Err(e) => eprintln!("failed reading from socket: {}", e), Err(e) => eprintln!("failed reading from socket: {}", e),
} }
} }
||||||| 45f9b5b
// let mut message_reader = MessageReader::new();
// 'handler: loop {
// let mut buffer = vec![];
// if tokio::io::copy(&mut rd, &mut buffer).await.is_err() {
// println!("failed to copy");
// }
=======
println!("{}", response?.text().await?);
Ok(())
}
async fn send_player(player: &Player, client: reqwest::Client, addr: &str) -> anyhow::Result<()> {
let player_message = create_message_player(&player)?;
let response = client
.post([&addr, "/create/player"].concat())
.header("Content-Type", "application/json")
.body(player_message.encode()?)
.send().await;
if let Err(e) = &response {
println!("{e}\n");
return Ok(())
}
println!("{}", response?.text().await?);
Ok(())
}
async fn handle_terminal(player: &Player, stdout: &mut Stdout, client: reqwest::Client, addr: &str) -> anyhow::Result<()> {
'handler: loop {
while let Ok(_event_happened) = poll(Duration::from_millis(2)) {
match event::read().expect("diomerds") {
TermEvent::Key(key) => {
match (key.code, key.modifiers) {
(KeyCode::Char('c'), KeyModifiers::CONTROL) => break 'handler,
(KeyCode::Char('h'), KeyModifiers::NONE) => {
for line in HELP.split('\n') {
println!("{line}")
}
},
(KeyCode::Char('1'), KeyModifiers::NONE) => {
send_player(&player, client.clone(), addr).await?;
},
(KeyCode::Char('2'), KeyModifiers::NONE) => {
delete_player(&player, client.clone(), addr).await?;
},
(_, _) => println!("{:?}\n", key),
}
},
_ => continue,
}
}
}
Ok(())
}
#[tokio::main]
pub async fn main() -> anyhow::Result<()> {
let mut stdout = std::io::stdout();
enable_raw_mode()?;
execute!(
stdout,
Clear(ClearType::All),
EnableLineWrap,
cursor::Show,
cursor::EnableBlinking,
EnterAlternateScreen,
)?;
let player = Player::new()?;
let addr = "http://127.0.0.1:8080";
let client = reqwest::Client::new();
// println!("{}", HELP);
handle_terminal(&player, &mut stdout, client.clone(), &addr).await?;
disable_raw_mode()?;
>>>>>>> deke/ipertesto
<<<<<<< HEAD
// loop { // loop {
// let n = rd.read_exact(&mut buf).await.expect("fallito lettura"); // let n = rd.read_exact(&mut buf).await.expect("fallito lettura");
@ -178,34 +70,5 @@ pub async fn main() -> anyhow::Result<()> {
// disable_raw_mode()?; // disable_raw_mode()?;
||||||| 45f9b5b
// let message = message_reader.read(&buffer).expect("failed to read from socket");
// println!("{:?}", message);
// break 'handler;
// }
// });
// client.send_message(Message::new(&local_address.to_string(), MessageKind::Test, "test json").unwrap()).await?;
// let (mut rd, mut wr) = client.stream.split();
// let mut message_reader = MessageReader::new();
// 'handler: loop {
// let mut buffer = vec![];
// if tokio::io::copy(&mut rd, &mut buffer).await.is_err() {
// println!("failed to copy");
// }
// let message = message_reader.read(&buffer)?;
// println!("{:?}", message);
// break 'handler;
// }
// disable_raw_mode()?;
=======
>>>>>>> deke/ipertesto
Ok(()) Ok(())
} }

View file

@ -1,23 +0,0 @@
use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use axum::body::Bytes;
pub type Db = Arc<Mutex<HashMap<String, Bytes>>>;
#[derive(Clone)]
pub struct AppState {
pub lobbies: Db,
pub players: Db,
}
impl AppState {
pub fn new() -> Self {
let lobbies = Arc::new(Mutex::new(HashMap::new()));
let players = Arc::new(Mutex::new(HashMap::new()));
Self {
lobbies,
players,
}
}
}

View file

@ -8,5 +8,3 @@ pub mod message;
pub mod message_read; pub mod message_read;
pub mod constant; pub mod constant;
pub mod routine; pub mod routine;
pub mod db;
pub mod router;

69
src/main.rs Normal file
View file

@ -0,0 +1,69 @@
use std::collections::HashMap;
use std::io::{self, Error};
use std::net::SocketAddr;
use lib::lobby::Lobby;
use lib::player::Player;
use std::sync::{Arc, Mutex};
use anyhow::Result;
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader};
use tokio::net::{TcpListener, TcpStream};
async fn handle_connection(mut stream: TcpStream, addr: SocketAddr) -> (Option<Player>, Option<Lobby>) {
let (mut read, mut write) = stream.split();
let mut buf = [0; 1024];
let mut name = String::new();
write.write_all(b"provide name\n").await.expect("failed to write to socket");
let n = match read.read(&mut buf).await {
Ok(0) => return (None, None),
Ok(n) => n,
Err(e) => {
eprintln!("failed to read from socket; err: {:?}", e);
return (None, None);
},
};
name = String::from_utf8_lossy(&buf[0..n]).to_string();
// if let Err(e) = write.write_all(&buf[0..n]).await {
// eprintln!("failed to write to socket; err = {:?}", e);
// return (None, None);
// }
let player = Player::new(addr, &name);
write.write_all(b"your name is\n").await.expect("failed to write to socket");
write.write_all(name.as_bytes()).await.expect("failed to write to socket");
(Some(player), None)
}
#[tokio::main]
async fn main() -> io::Result<()> {
let address = "127.0.0.1:8080".to_string();
let listener = TcpListener::bind(&address).await?;
let mut lobbies: Arc<Mutex<HashMap<String, Lobby>>> = Arc::new(Mutex::new(HashMap::new()));
loop {
let (mut stream, addr) = listener.accept().await?;
println!("new connection from: {}", addr);
let lobby_player_handle = tokio::spawn(handle_connection(stream, addr));
let (player, lobby) = lobby_player_handle.await?;
match lobby {
Some(lobby) => lobbies.insert(lobby.get_id(), lobby),
None => continue,
};
}
Ok(())
}

View file

@ -1,5 +1,3 @@
use std::fmt::Display;
use axum::body::to_bytes;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@ -17,8 +15,6 @@ pub enum MessageKind {
Move, Move,
CreatePlayer, CreatePlayer,
CreateLobby, CreateLobby,
DeletePlayer,
DeleteLobby,
} }
impl Message { impl Message {
@ -57,9 +53,3 @@ impl Message {
Ok(buffer) Ok(buffer)
} }
} }
impl Display for Message {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
todo!()
}
}

View file

@ -1,51 +1,48 @@
use petname::Generator; use tokio::{io::AsyncReadExt, net::TcpStream};
use std::net::SocketAddr;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha256::digest; use sha256::digest;
use axum::Json; use crate::{card::Card, message_read::MessageReader};
use crate::card::Card;
#[derive(Serialize, Deserialize, Eq, PartialEq, Hash, Clone)] #[derive(Serialize, Deserialize, Eq, PartialEq, Hash, Clone)]
pub struct Player { pub struct Player {
// addr will change because at this stage i really
// don't know what i am doing
// it will probably be something like id or playerid
// or some other identifier idk
pub addr: SocketAddr,
// same goes for id because rn it's just the sha256 of
// the ip
pub id: String, pub id: String,
pub name: String, pub name: String,
pub hand: Vec<Card>, pub hand: Vec<Card>,
} }
impl Player { impl Player {
pub fn new() -> anyhow::Result<Self> { pub async fn new(addr: SocketAddr, name: &str) -> anyhow::Result<Option<Self>> {
let hand_empty: Vec<Card> = Vec::new(); let hand_empty: Vec<Card> = Vec::new();
let to_digest: String = addr.to_string();
let name = petname::Petnames::default().generate_one(2, "-").expect("no nomi");
let to_digest = &name;
let id = digest(to_digest); let id = digest(to_digest);
Ok(Player { Ok(Some(Player {
addr,
id, id,
name, name: name.to_string(),
hand: hand_empty, hand: hand_empty,
}) }))
} }
pub fn encode(&self) -> anyhow::Result<String> { pub fn get_addr(self) -> SocketAddr {
let player_json = serde_json::to_string(self)?; self.addr
Ok(player_json)
} }
pub fn decode(player: String) -> anyhow::Result<Self> { pub fn get_name(self) -> String {
let player: Player = serde_json::from_str(&player)?; self.name
Ok(player)
} }
pub fn get_name(&self) -> String { pub fn get_hand(self) -> Vec<Card> {
self.name.clone() self.hand
}
pub fn get_hand(&self) -> Vec<Card> {
self.hand.clone()
} }
} }

View file

@ -1,89 +0,0 @@
use anyhow::Result;
use axum::{
body::Bytes, extract::{
rejection::JsonRejection, Json, Path, State
},
http::StatusCode,
Router
};
use crate::{message::Message, player::Player};
use crate::db::AppState;
use crate::message::MessageKind;
pub struct App {
pub db: AppState,
pub router: Router<AppState>,
}
impl App {
pub fn new() -> Self {
let db = AppState::new();
let router: Router<AppState> = Router::new();
Self {
db,
router,
}
}
pub async fn echo(body: Bytes) -> Bytes {
body
}
pub async fn create_player(
State(db): State<AppState>,
json_body: Result<Json<Message>, JsonRejection>,
) -> Result<axum::Json<Message>, StatusCode> {
match json_body {
Ok(Json(message)) => {
println!("{:?}", message);
let player: Player = serde_json::from_str(&message.content).expect("niente json");
{
let mut players = db.players
.lock().expect("ciao");
if players.contains_key(&player.name) {
return Err(StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS)
}
players.insert(
player.get_name(),
Bytes::copy_from_slice(player.encode().expect("failed encoding player").as_ref())
);
}
println!("{:?}", db.players);
Ok(Json(Message::new("server", MessageKind::CreatePlayer, "user created").expect("failed creating message")))
}
Err(_) => Err(StatusCode::UNPROCESSABLE_ENTITY)
}
}
pub async fn delete_player(
State(db): State<AppState>,
Path(player_id): Path<String>
) -> Result<axum::response::Json<Message>, StatusCode> {
{
let mut players = db.players
.lock().expect("ciao");
match players.contains_key(&player_id) {
true => {
players.remove(&player_id);
println!("{:?}", players);
Ok(Json(Message::new("server", MessageKind::DeletePlayer, "user deleted").expect("a")))
},
false => Err(StatusCode::NOT_FOUND),
}
}
}
pub async fn create_lobby(
State(db): State<AppState>,
json_body: Result<Json<Message>, JsonRejection>,
) -> Result<axum::Json<Message>, StatusCode> {
todo!()
}
}

View file

@ -1,19 +1,8 @@
<<<<<<< HEAD
use tokio::{io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader}, net::{tcp::WriteHalf, TcpListener}, sync::mpsc}; use tokio::{io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader}, net::{tcp::WriteHalf, TcpListener}, sync::mpsc};
use tokio::sync::broadcast; use tokio::sync::broadcast;
use std::{collections::HashMap, net::SocketAddr}; use std::{collections::HashMap, net::SocketAddr};
use tokio::net::TcpStream; use tokio::net::TcpStream;
use crate::{message::{Message, MessageKind}, message_read::MessageReader, server}; use crate::{message::{Message, MessageKind}, message_read::MessageReader, server};
||||||| 45f9b5b
use tokio::{io::{AsyncReadExt, AsyncWriteExt, BufReader}, net::{tcp::WriteHalf, TcpListener}};
use std::net::SocketAddr;
use crate::{message::{Message, MessageKind}, message_read::MessageReader, server};
=======
use tokio::net::TcpListener;
use crate::router::App;
use axum::routing::{get, post};
>>>>>>> deke/ipertesto
#[derive(Debug)] #[derive(Debug)]
pub struct Server { pub struct Server {
@ -29,7 +18,6 @@ impl Server {
} }
} }
<<<<<<< HEAD
async fn process_connection(mut stream: TcpStream, addr: SocketAddr) -> anyhow::Result<()> { async fn process_connection(mut stream: TcpStream, addr: SocketAddr) -> anyhow::Result<()> {
let (mut rd, mut wr) = stream.split(); let (mut rd, mut wr) = stream.split();
@ -58,20 +46,15 @@ impl Server {
#[allow(unreachable_code)] #[allow(unreachable_code)]
#[tracing::instrument] #[tracing::instrument]
||||||| 45f9b5b
#[allow(unreachable_code)]
=======
>>>>>>> deke/ipertesto
pub async fn run(&mut self) -> anyhow::Result<()> { pub async fn run(&mut self) -> anyhow::Result<()> {
let listener = TcpListener::bind(format!( let listener = TcpListener::bind(format!(
"{}:{}", "{}:{}",
self.host, self.host,
self.port self.port
)).await?; )).await?;
println!("Server is running on {}:{}", self.host, self.port); println!("Server is running on {}:{}", self.host, self.port);
<<<<<<< HEAD
// let mut db = HashMap::new(); // let mut db = HashMap::new();
loop { loop {
@ -86,62 +69,6 @@ impl Server {
} }
} }
||||||| 45f9b5b
loop {
let (mut socket, addr) = listener.accept().await?;
println!("Connection received from {}", addr);
tokio::task::spawn(async move {
let mut message_reader = MessageReader::new();
let (mut rd, mut wr) = socket.split();
let mut bufread = BufReader::new(&mut rd);
'handler: loop {
let mut buffer = vec![];
let _bytes_read = match bufread.read_to_end(&mut buffer).await {
Ok(0) => {
println!("connection closed by client");
break 'handler;
},
Ok(_n) => {
let message = message_reader.read(&buffer).expect("failed to parse message");
println!("{:?}", message); },
Err(e) => {
eprintln!("error reading from stream: {}", e);
break 'handler;
},
};
// if tokio::io::copy(&mut rd, &mut buffer).await.is_err() {
// eprintln!("failed to copy");
// }
// let message = message_reader.read(&buffer)?;
// println!("{:?}", message);
// let local_address = &rd.local_addr()?;
// let message_client = Message::new(&local_address.to_string(), MessageKind::Test, "toto test")?;
// wr.write_all(&message_client.encode()?.as_bytes()).await?;
}
Ok::<(), anyhow::Error>(())
});
}
=======
let app = App::new();
let router = app.router
.route("/echo", post(App::echo))
.route("/create/player", post(App::create_player))
.route("/create/lobby", post(App::create_lobby))
.route("/delete/{player-id}", get(App::delete_player))
.with_state(app.db);
axum::serve(listener, router).await.unwrap();
>>>>>>> deke/ipertesto
Ok(()) Ok(())
} }
} }