Compare commits
No commits in common. 'f5382ffaf0886ed60e2513141cef58c3a849b4c3' and 'b0e2763521e0c0d968ed7a9bc96e759a73eaebbe' have entirely different histories.
f5382ffaf0
...
b0e2763521
7 changed files with 432 additions and 2420 deletions
File diff suppressed because it is too large
Load Diff
@ -1,133 +1,29 @@ |
|||||||
use { |
use bevy::{prelude::*, window::WindowResolution}; |
||||||
aeronet::{ |
|
||||||
io::{ |
|
||||||
connection::{DisconnectReason, Disconnected}, |
|
||||||
Session, SessionEndpoint, |
|
||||||
}, |
|
||||||
transport::TransportConfig, |
|
||||||
}, |
|
||||||
aeronet_webtransport::{ |
|
||||||
cert, |
|
||||||
cert::CertificateHash, |
|
||||||
client::{ClientConfig, WebTransportClient, WebTransportClientPlugin}, |
|
||||||
}, |
|
||||||
bevy::{prelude::*, window::WindowResolution}, |
|
||||||
}; |
|
||||||
|
|
||||||
fn main() -> AppExit { |
fn main() -> AppExit { |
||||||
App::new() |
App::new() |
||||||
.add_plugins(( |
.add_plugins(DefaultPlugins.set(WindowPlugin { |
||||||
DefaultPlugins.set(WindowPlugin { |
primary_window: Some(Window { |
||||||
primary_window: Some(Window { |
title: "gæmstone Client".into(), |
||||||
title: "gæmstone Client".into(), |
// Steam Deck: DPI appears pretty high, causing everything to be scaled up.
|
||||||
// Steam Deck: DPI appears pretty high, causing everything to be scaled up.
|
// Setting scale factor override prevents this from happening.
|
||||||
// Setting scale factor override prevents this from happening.
|
resolution: WindowResolution::new(1280., 720.).with_scale_factor_override(1.0), |
||||||
resolution: WindowResolution::new(1280., 720.).with_scale_factor_override(1.0), |
// WASM: Fit canvas to parent element, so `Window` resizes automatically.
|
||||||
// WASM: Fit canvas to parent element, so `Window` resizes automatically.
|
fit_canvas_to_parent: true, |
||||||
fit_canvas_to_parent: true, |
// WASM: Don't override default event handling like browser hotkeys while focused.
|
||||||
// WASM: Don't override default event handling like browser hotkeys while focused.
|
prevent_default_event_handling: false, |
||||||
prevent_default_event_handling: false, |
|
||||||
..default() |
|
||||||
}), |
|
||||||
..default() |
..default() |
||||||
}), |
}), |
||||||
WebTransportClientPlugin, |
..default() |
||||||
)) |
})) |
||||||
.add_systems(Startup, (setup, connect_to_server)) |
.add_systems(Startup, setup) |
||||||
.add_observer(on_connecting) |
|
||||||
.add_observer(on_connected) |
|
||||||
.add_observer(on_disconnected) |
|
||||||
.run() |
.run() |
||||||
} |
} |
||||||
|
|
||||||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { |
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { |
||||||
commands.spawn(Camera2d::default()); |
commands.spawn(Camera2dBundle::default()); |
||||||
commands.spawn(Sprite::from_image(asset_server.load("heck.png"))); |
commands.spawn(SpriteBundle { |
||||||
} |
texture: asset_server.load("heck.png"), |
||||||
|
..default() |
||||||
fn connect_to_server(mut commands: Commands) { |
}); |
||||||
// When using a self-signed cert, its hash needs to be provided to the
|
|
||||||
// client for it to accept it. Works on native and WASM. On WASM we have
|
|
||||||
// the option to just accept the HTTPS server's certificate. On native we
|
|
||||||
// could theoretically disable cert checking entirely, but that kind of
|
|
||||||
// defeats the point.
|
|
||||||
|
|
||||||
// TODO: Do not hardcode the server's certificate hash. Enter in a UI of some sort?
|
|
||||||
// For now, just manually replace the `todo!` with the hash that gets
|
|
||||||
// logged in the server output. It looks something like this:
|
|
||||||
// ************************
|
|
||||||
// SPKI FINGERPRINT
|
|
||||||
// 1YLqE3c3ZsRBos35nUrMETfZtCUVIxyIjcskEq0LFYE=
|
|
||||||
// CERTIFICATE HASH
|
|
||||||
// z3cWU+Pc209kffV440ksqcWxMcCTi9QO6qI7VjVOQfU=
|
|
||||||
// ************************
|
|
||||||
|
|
||||||
let target = format!("https://[::1]:{}", common::WEB_TRANSPORT_PORT); |
|
||||||
let cert_hash = todo!(); |
|
||||||
let cert_hash = cert::hash_from_b64(cert_hash).unwrap(); |
|
||||||
let config = web_transport_config(Some(cert_hash)); |
|
||||||
commands |
|
||||||
.spawn(Name::new(target.clone())) |
|
||||||
.queue(WebTransportClient::connect(config, target)); |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(target_family = "wasm")] |
|
||||||
fn web_transport_config(cert_hash: Option<CertificateHash>) -> ClientConfig { |
|
||||||
use aeronet_webtransport::xwt_web_sys::{CertificateHash, HashAlgorithm}; |
|
||||||
let server_certificate_hashes = cert_hash |
|
||||||
.map(|hash| CertificateHash { |
|
||||||
algorithm: HashAlgorithm::Sha256, |
|
||||||
value: Vec::from(hash), |
|
||||||
}) |
|
||||||
.into_iter() |
|
||||||
.collect::<Vec<_>>(); |
|
||||||
ClientConfig { |
|
||||||
server_certificate_hashes, |
|
||||||
..Default::default() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(not(target_family = "wasm"))] |
|
||||||
fn web_transport_config(cert_hash: Option<CertificateHash>) -> ClientConfig { |
|
||||||
use {aeronet_webtransport::wtransport::tls::Sha256Digest, core::time::Duration}; |
|
||||||
let server_certificate_hashes = cert_hash |
|
||||||
.map(Sha256Digest::new) |
|
||||||
.into_iter() |
|
||||||
.collect::<Vec<_>>(); |
|
||||||
ClientConfig::builder() |
|
||||||
.with_bind_default() |
|
||||||
.with_server_certificate_hashes(server_certificate_hashes) |
|
||||||
.keep_alive_interval(Some(Duration::from_secs(1))) |
|
||||||
.max_idle_timeout(Some(Duration::from_secs(5))) |
|
||||||
.unwrap() |
|
||||||
.build() |
|
||||||
} |
|
||||||
|
|
||||||
fn on_connecting(trigger: Trigger<OnAdd, SessionEndpoint>, names: Query<&Name>) { |
|
||||||
let session = trigger.entity(); |
|
||||||
let name = names.get(session).unwrap(); |
|
||||||
info!("Connecting to '{name}' ..."); |
|
||||||
} |
|
||||||
|
|
||||||
fn on_connected(trigger: Trigger<OnAdd, Session>, mut commands: Commands) { |
|
||||||
let session = trigger.entity(); |
|
||||||
info!("Connected!"); |
|
||||||
commands.entity(session).insert((TransportConfig { |
|
||||||
max_memory_usage: 64 * 1024, |
|
||||||
send_bytes_per_sec: 4 * 1024, |
|
||||||
},)); |
|
||||||
} |
|
||||||
|
|
||||||
fn on_disconnected(trigger: Trigger<Disconnected>) { |
|
||||||
match &trigger.event().reason { |
|
||||||
DisconnectReason::User(reason) => { |
|
||||||
info!("Disconnected (user): {reason}") |
|
||||||
} |
|
||||||
DisconnectReason::Peer(reason) => { |
|
||||||
info!("Disconnected (server): {reason}") |
|
||||||
} |
|
||||||
DisconnectReason::Error(err) => { |
|
||||||
info!("Disconnected (error): {err:#}") |
|
||||||
} |
|
||||||
}; |
|
||||||
} |
} |
||||||
|
@ -1 +1,14 @@ |
|||||||
pub const WEB_TRANSPORT_PORT: u16 = 25565; |
pub fn add(left: u64, right: u64) -> u64 { |
||||||
|
left + right |
||||||
|
} |
||||||
|
|
||||||
|
#[cfg(test)] |
||||||
|
mod tests { |
||||||
|
use super::*; |
||||||
|
|
||||||
|
#[test] |
||||||
|
fn it_works() { |
||||||
|
let result = add(2, 2); |
||||||
|
assert_eq!(result, 4); |
||||||
|
} |
||||||
|
} |
||||||
|
Loading…
Reference in new issue