feat(server): accept QUIC client connections

This commit is contained in:
Serkyo 2026-07-14 01:38:58 +02:00
parent e9d6854e7a
commit e941415836
3 changed files with 24 additions and 8 deletions

2
Cargo.lock generated
View file

@ -548,6 +548,7 @@ dependencies = [
"anyhow", "anyhow",
"ash-window", "ash-window",
"glam 0.33.2", "glam 0.33.2",
"net",
"raw-window-handle", "raw-window-handle",
"renderer", "renderer",
"serde_json", "serde_json",
@ -2421,6 +2422,7 @@ dependencies = [
"crossbeam-channel", "crossbeam-channel",
"glam 0.33.2", "glam 0.33.2",
"lru", "lru",
"net",
"serde_json", "serde_json",
"shared", "shared",
"tempfile", "tempfile",

View file

@ -14,6 +14,7 @@ bevy_ecs = "0.19"
crossbeam-channel = "0.5.16" crossbeam-channel = "0.5.16"
glam.workspace = true glam.workspace = true
lru = "0.18.1" lru = "0.18.1"
net = { version = "0.1.0", path = "../net" }
serde_json.workspace = true serde_json.workspace = true
shared = { path = "../shared" } shared = { path = "../shared" }
tracing.workspace = true tracing.workspace = true

View file

@ -15,6 +15,8 @@ pub mod world_server;
use std::collections::HashSet; use std::collections::HashSet;
use std::fs; use std::fs;
use std::net::{Ipv4Addr, SocketAddr};
use std::time::Duration;
use anyhow::Context; use anyhow::Context;
use bevy_ecs::prelude::{Query, ResMut, Schedule, With, World}; use bevy_ecs::prelude::{Query, ResMut, Schedule, With, World};
@ -23,6 +25,7 @@ use shared::generator::{VoxelGenerator, WorldGenConfig};
use shared::world::{ChunkPos, EntityPos}; use shared::world::{ChunkPos, EntityPos};
use tracing::{debug, info}; use tracing::{debug, info};
use net::NetworkServer;
use player::{Player, Position, ViewDistance}; use player::{Player, Position, ViewDistance};
use world_server::{ServerWorld, cylinder_chunks}; use world_server::{ServerWorld, cylinder_chunks};
@ -116,16 +119,26 @@ fn main() -> anyhow::Result<()> {
} }
info!("Initial region ready; granting player control"); info!("Initial region ready; granting player control");
// Drive several ticks, marching the dummy one chunk along +X between each. The manual movement stands in for network-driven player input and exists only to exercise load/unload as the anchor moves. // Spawn the networking thread and bind the QUIC endpoint. The synchronous simulation loop below communicates with it only by draining events.
for step in 0..5 { let bind = SocketAddr::from((Ipv4Addr::LOCALHOST, net::DEFAULT_PORT));
info!(step, "tick"); let (network, local_addr) = NetworkServer::spawn(
bind,
env!("CARGO_PKG_VERSION").to_owned(),
// Placeholder advisory tick rate.
20,
)
.context("spawning network server")?;
info!(%local_addr, "network endpoint listening");
// Authoritative simulation loop.
loop {
schedule.run(&mut world); schedule.run(&mut world);
let mut movers = world.query_filtered::<&mut Position, With<Player>>(); for event in network.poll_events() {
for mut position in movers.iter_mut(&mut world) { info!(?event, "network event");
position.0.chunk.x += 1;
}
} }
Ok(()) // Advisory ~20 Hz cadence until the real tick scheduler lands.
std::thread::sleep(Duration::from_millis(50));
}
} }