#![feature(lock_value_accessors)] pub mod connection; pub mod player; pub mod server; pub mod world; use std::{ sync::{Arc, atomic::Ordering}, time::Duration, }; use connection::Client; use player::Player; use potato_data::text_component::TextComponent; use potato_protocol::packet::clientbound; use server::Server; use tokio::{net::TcpListener, time::interval}; #[tokio::main] async fn main() { let server = PotatoServer::new(); server.listen_for_connections().await; } pub struct PotatoServer { server: Server, } impl PotatoServer { pub fn new() -> Self { PotatoServer { server: Server::new(), } } pub async fn listen_for_connections(&self) { let listener = TcpListener::bind("0.0.0.0:25565") .await .expect("Failed to start listening on port 25565"); println!("listening started, ready to accept"); loop { if let Ok((stream, _)) = listener.accept().await { let (stream_read, mut stream_send) = stream.into_split(); let (tx, mut rx) = tokio::sync::mpsc::channel(64); let Ok(client) = Client::new(tx, stream_read) else { println!("Failed to create client"); continue; }; let client = Arc::new(client); { let client = client.clone(); tokio::spawn(async move { while let Some(packet) = rx.recv().await { if let Err(e) = packet.write_to_stream(&mut stream_send).await { client .disconnect(TextComponent::from_str( "Error while sending packet", )) .await; println!("Error while sending packet: {}", e); break; } } }); } // Keep alive task { let client = client.clone(); tokio::spawn(async move { let mut interval = interval(Duration::from_secs(10)); loop { interval.tick().await; if !client.connected.load(Ordering::Relaxed) { break; } if client.needs_keep_alive().await { // TODO: Use a unique id for each keep alive packet (or at least a // timestamp) client .send_packet(&clientbound::KeepAlivePacket { id: 0 }) .await; } } }); } { let registries = self.server.registries.clone(); let world = self.server.world.clone(); tokio::spawn(async move { while !client.convert_to_player.load(Ordering::Relaxed) && client.connected.load(Ordering::Relaxed) { if let Err(e) = client.read_packets().await { // Log the issue in the console and inform the client. println!("Error while reading packet: {}", e); client .disconnect(TextComponent::from_str( "Error while reading packets", )) .await; break; } if let Err(e) = client.handle_packets(®istries).await { // Log the issue in the console and inform the client. println!("Error while handeling packet: {}", e); client .disconnect(TextComponent::from_str( "Error while handeling packet", )) .await; break; } } if client.connected.load(Ordering::Relaxed) { let player = Player::upgrade_client(client, world).await; while player.client.connected.load(Ordering::Relaxed) { if let Err(e) = player.read_packets().await { // Log the issue in the console and inform the client. println!("Error while reading packet: {}", e); player .disconnect(TextComponent::from_str( "Error while reading packets", )) .await; break; } if let Err(e) = player.handle_packets().await { // Log the issue in the console and inform the client. println!("Error while handeling packet: {}", e); player .disconnect(TextComponent::from_str( "Error while handeling packet", )) .await; break; } } } }); } } } } }