Potato/potato/src/main.rs
2025-04-05 00:06:22 +02:00

151 lines
6.1 KiB
Rust

#![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(&registries).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;
}
}
}
});
}
}
}
}
}