feat(client): connect to server and complete handshake

This commit is contained in:
Serkyo 2026-07-14 01:38:58 +02:00
parent e941415836
commit 7620c3b54e
2 changed files with 42 additions and 0 deletions

View file

@ -19,3 +19,4 @@ raw-window-handle.workspace = true
ash-window.workspace = true
serde_json.workspace = true
shared = { path = "../shared" }
net = { version = "0.1.0", path = "../net" }

View file

@ -56,6 +56,8 @@ struct App {
input: InputState,
/// Timestamp of the previous frame, used to derive delta-time. `None` before the first frame.
last_frame: Option<Instant>,
/// Receives the outcome of the background connect and handshake, drained non-blocking from the event loop. `None` before the connection is started and once the outcome has been observed.
handshake_rx: Option<net::ConnectOutcome>,
}
impl Default for App {
@ -71,6 +73,7 @@ impl Default for App {
),
input: InputState::default(),
last_frame: None,
handshake_rx: None,
}
}
}
@ -177,6 +180,21 @@ impl ApplicationHandler for App {
.expect("Renderer initialized")
.update_mesh(&vertices, &indices)
.expect("Failed to upload terrain to GPU");
// Kick off a background connect + handshake to the local server.
let hello = shared::protocol::ClientHello {
protocol_version: shared::protocol::PROTOCOL_VERSION,
client_build: env!("CARGO_PKG_VERSION").to_owned(),
player_identity: shared::protocol::PlayerIdentity {
display_name: "Player".to_owned(),
},
installed_packs: Vec::new(),
requested_features: shared::protocol::FeatureFlags(0),
};
let server_addr =
std::net::SocketAddr::from((std::net::Ipv4Addr::LOCALHOST, net::DEFAULT_PORT));
info!("Connecting to server at {server_addr}");
self.handshake_rx = Some(net::connect_in_background(server_addr, hello));
}
fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) {
@ -200,6 +218,29 @@ impl ApplicationHandler for App {
}
}
WindowEvent::RedrawRequested => {
// Non-blocking check for the handshake outcome.
let mut handshake_done = false;
if let Some(rx) = self.handshake_rx.as_ref() {
match rx.try_recv() {
Ok(Ok(ack)) => {
info!(
protocol_version = ack.protocol_version,
"handshake complete"
);
handshake_done = true;
}
Ok(Err(reason)) => {
warn!("handshake failed: {reason}");
handshake_done = true;
}
// Empty: not ready yet. Disconnected: the network thread ended.
Err(_) => {}
}
}
if handshake_done {
self.handshake_rx = None;
}
// Derive delta-time from the previous frame so movement is framerate-independent. The first frame has no predecessor and therefore advances by zero seconds.
let now = Instant::now();
let dt = self