Compare commits
2 commits
c1267d16e6
...
d161d56aca
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d161d56aca | ||
![]() |
94d7ec5e25 |
10 changed files with 976 additions and 181 deletions
857
Cargo.lock
generated
857
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -16,6 +16,9 @@ name = "client"
|
|||
path = "src/bin/client.rs"
|
||||
|
||||
[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"] }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use lib::{client::Client, message::{Message, MessageKind}, message_read::MessageReader};
|
||||
use lib::{client::Client, message::{Message, MessageKind}, message_read::MessageReader, player::Player};
|
||||
use crossterm::{
|
||||
execute,
|
||||
terminal::{
|
||||
|
@ -9,12 +9,17 @@ use crossterm::{
|
|||
},
|
||||
event::Event,
|
||||
};
|
||||
use http_body_util::Empty;
|
||||
use hyper::{client::conn::{self, http1::{self, handshake}}, Request};
|
||||
use hyper::body::Bytes;
|
||||
use hyper_util::rt::TokioIo;
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
#[tokio::main]
|
||||
pub async fn main() -> anyhow::Result<()> {
|
||||
let mut client = Client::connect("127.0.0.1", 8080).await?;
|
||||
let local_address = client.stream.local_addr()?;
|
||||
// let mut client = Client::connect("127.0.0.1", 8080).await?;
|
||||
// let local_address = client.stream.local_addr()?;
|
||||
|
||||
// enable_raw_mode()?;
|
||||
// execute!(
|
||||
|
@ -22,44 +27,17 @@ pub async fn main() -> anyhow::Result<()> {
|
|||
// Clear(ClearType::All),
|
||||
// )?;
|
||||
|
||||
// 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");
|
||||
let addr = "http://127.0.0.1:8080";
|
||||
|
||||
// let (mut rd, mut wr) = client.stream.split();
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
// let mut message_reader = MessageReader::new();
|
||||
let response = client
|
||||
.post([&addr, "/create/player"].concat())
|
||||
.body(Player::new()?.encode()?)
|
||||
.send().await?
|
||||
.text().await?;
|
||||
|
||||
// 'handler: loop {
|
||||
// let mut buffer = vec![];
|
||||
// if tokio::io::copy(&mut rd, &mut buffer).await.is_err() {
|
||||
// println!("failed to copy");
|
||||
// }
|
||||
println!("{}", response);
|
||||
|
||||
|
||||
// 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()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
23
src/db.rs
Normal file
23
src/db.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,3 +8,5 @@ pub mod message;
|
|||
pub mod message_read;
|
||||
pub mod constant;
|
||||
pub mod routine;
|
||||
pub mod db;
|
||||
pub mod router;
|
||||
|
|
69
src/main.rs
69
src/main.rs
|
@ -1,69 +0,0 @@
|
|||
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(())
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
use std::fmt::Display;
|
||||
use axum::body::to_bytes;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Message {
|
||||
pub from: String,
|
||||
pub message_kind: MessageKind,
|
||||
pub length: u16,
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
|
@ -20,12 +21,10 @@ impl Message {
|
|||
pub fn new(from: &str, message_kind: MessageKind, content: impl Into<String>) -> anyhow::Result<Self> {
|
||||
let from = from.into();
|
||||
let content = content.into();
|
||||
let length = content.len() as u16;
|
||||
|
||||
Ok(Self {
|
||||
from,
|
||||
message_kind,
|
||||
length,
|
||||
content,
|
||||
})
|
||||
}
|
||||
|
@ -42,3 +41,9 @@ impl Message {
|
|||
Ok(message)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Message {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,42 @@
|
|||
use tokio::{io::AsyncReadExt, net::TcpStream};
|
||||
use std::net::SocketAddr;
|
||||
use petname::Generator;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha256::digest;
|
||||
|
||||
use crate::{card::Card, message_read::MessageReader};
|
||||
use crate::card::Card;
|
||||
|
||||
#[derive(Serialize, Deserialize, Eq, PartialEq, Hash, Clone)]
|
||||
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 name: String,
|
||||
pub hand: Vec<Card>,
|
||||
}
|
||||
|
||||
impl Player {
|
||||
pub async fn new(addr: SocketAddr, name: &str) -> anyhow::Result<Option<Self>> {
|
||||
pub fn new() -> anyhow::Result<Self> {
|
||||
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);
|
||||
|
||||
Ok(Some(Player {
|
||||
addr,
|
||||
Ok(Player {
|
||||
id,
|
||||
name: name.to_string(),
|
||||
name,
|
||||
hand: hand_empty,
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_addr(self) -> SocketAddr {
|
||||
self.addr
|
||||
pub fn encode(&self) -> anyhow::Result<String> {
|
||||
let player_json: String = serde_json::to_string(self)?;
|
||||
|
||||
Ok(player_json)
|
||||
}
|
||||
|
||||
pub fn decode(player: String) -> anyhow::Result<Self> {
|
||||
let player: Player = serde_json::from_str(&player)?;
|
||||
|
||||
Ok(player)
|
||||
}
|
||||
|
||||
pub fn get_name(self) -> String {
|
||||
|
|
46
src/router.rs
Normal file
46
src/router.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use axum::{
|
||||
Router,
|
||||
body::Bytes,
|
||||
extract::{
|
||||
State,
|
||||
Json,
|
||||
rejection::JsonRejection,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::message::Message;
|
||||
use crate::db::AppState;
|
||||
|
||||
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>,
|
||||
)
|
||||
{
|
||||
match json_body {
|
||||
Ok(Json(message)) => {
|
||||
println!("{:?}", message);
|
||||
}
|
||||
Err(e) => eprintln!("{e}"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
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};
|
||||
|
||||
pub struct Server {
|
||||
pub host: String,
|
||||
|
@ -15,57 +16,23 @@ impl Server {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
|
||||
pub async fn run(&mut self) -> anyhow::Result<()> {
|
||||
let listener = TcpListener::bind(format!(
|
||||
"{}:{}",
|
||||
self.host,
|
||||
self.port
|
||||
)).await?;
|
||||
|
||||
println!("Server is running on {}:{}", self.host, self.port);
|
||||
|
||||
loop {
|
||||
let (mut socket, addr) = listener.accept().await?;
|
||||
println!("Connection received from {}", addr);
|
||||
let app = App::new();
|
||||
|
||||
tokio::task::spawn(async move {
|
||||
let mut message_reader = MessageReader::new();
|
||||
let router = app.router
|
||||
.route("/echo", post(App::echo))
|
||||
.route("/create/player", post(App::create_player))
|
||||
.with_state(app.db);
|
||||
|
||||
|
||||
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>(())
|
||||
});
|
||||
}
|
||||
axum::serve(listener, router).await.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue