1+ use futures_util:: { SinkExt , StreamExt } ;
2+ use image:: EncodableLayout ;
13use smh_heightmap_ripper:: Heightmap ;
2- use smh_util:: { image, log, async_channel, anyhow, FromBytesSlice , Rect } ;
3- use futures_util:: { StreamExt , SinkExt } ;
4+ use smh_util:: { anyhow, async_channel, image, log, FromBytesSlice , Rect } ;
45use std:: {
56 net:: { Ipv4Addr , SocketAddr , SocketAddrV4 } ,
6- thread:: JoinHandle ,
77 sync:: Arc ,
8- time:: Duration
8+ thread:: JoinHandle ,
9+ time:: Duration ,
910} ;
10- use tokio:: net:: { TcpListener , TcpStream } ;
11- use image:: EncodableLayout ;
11+ use tokio:: net:: { TcpListener , TcpStream , UdpSocket } ;
1212
1313// TODO use byteorder
1414
@@ -32,7 +32,7 @@ mod ws;
3232
3333pub enum Interaction {
3434 AddCustomMarker ( [ [ f32 ; 2 ] ; 2 ] ) ,
35- DeleteCustomMarker ( u32 )
35+ DeleteCustomMarker ( u32 ) ,
3636}
3737impl Interaction {
3838 pub fn deserialize ( data : & [ u8 ] ) -> Option < Self > {
@@ -50,21 +50,19 @@ impl Interaction {
5050 return None ;
5151 }
5252
53- Some ( Interaction :: AddCustomMarker (
54- [
55- [ f32:: from_le_bytes_slice ( & data[ 0 ..4 ] ) , f32:: from_le_bytes_slice ( & data[ 4 ..8 ] ) ] ,
56- [ f32:: from_le_bytes_slice ( & data[ 8 ..12 ] ) , f32:: from_le_bytes_slice ( & data[ 12 ..16 ] ) ] ,
57- ]
58- ) )
59- } ,
53+ Some ( Interaction :: AddCustomMarker ( [
54+ [ f32:: from_le_bytes_slice ( & data[ 0 ..4 ] ) , f32:: from_le_bytes_slice ( & data[ 4 ..8 ] ) ] ,
55+ [ f32:: from_le_bytes_slice ( & data[ 8 ..12 ] ) , f32:: from_le_bytes_slice ( & data[ 12 ..16 ] ) ] ,
56+ ] ) )
57+ }
6058 2 => {
6159 if data. len ( ) != core:: mem:: size_of :: < u32 > ( ) {
6260 log:: warn!( "Invalid custom marker data length" ) ;
6361 return None ;
6462 }
6563
6664 Some ( Interaction :: DeleteCustomMarker ( u32:: from_le_bytes_slice ( & data[ 0 ..4 ] ) ) )
67- } ,
65+ }
6866 _ => {
6967 log:: warn!( "Unknown interaction type: {interaction}" ) ;
7068 None
@@ -215,7 +213,7 @@ pub struct EventData {
215213 pub custom_markers : Box < [ [ [ f32 ; 2 ] ; 2 ] ] > ,
216214 pub meters_to_px_ratio : Option < f64 > ,
217215 pub minimap_bounds : Option < Rect < u32 > > ,
218- pub heightmap : Option < smh_heightmap_ripper:: Heightmap >
216+ pub heightmap : Option < smh_heightmap_ripper:: Heightmap > ,
219217}
220218
221219pub struct WebServer {
@@ -228,7 +226,7 @@ pub struct WebServer {
228226 event_tx : tokio:: sync:: mpsc:: Sender < Arc < Event > > ,
229227 interaction_rx : tokio:: sync:: mpsc:: Receiver < Interaction > ,
230228
231- num_clients : Arc < ( ) >
229+ num_clients : Arc < ( ) > ,
232230}
233231impl WebServer {
234232 pub fn shutdown ( self ) { }
@@ -294,7 +292,12 @@ impl Drop for WebServer {
294292 }
295293}
296294
297- async fn server ( port : u16 , wake_ui : fn ( ) , server_tx : & mut Option < tokio:: sync:: oneshot:: Sender < Result < WebServer , AnyError > > > , mut event_data : EventData ) -> Result < ( ) , AnyError > {
295+ async fn server (
296+ port : u16 ,
297+ wake_ui : fn ( ) ,
298+ server_tx : & mut Option < tokio:: sync:: oneshot:: Sender < Result < WebServer , AnyError > > > ,
299+ mut event_data : EventData ,
300+ ) -> Result < ( ) , AnyError > {
298301 let ( shutdown_tx, mut shutdown_rx) = tokio:: sync:: mpsc:: channel ( 1 ) ;
299302 let ( interaction_tx, interaction_rx) = tokio:: sync:: mpsc:: channel ( 8 ) ;
300303 let ( event_tx, mut event_rx) = tokio:: sync:: mpsc:: channel ( 8 ) ;
@@ -308,11 +311,13 @@ async fn server(port: u16, wake_ui: fn(), server_tx: &mut Option<tokio::sync::on
308311 let http = TcpListener :: bind ( addr) . await ?;
309312 log:: info!( "HTTP server listening on {}" , http. local_addr( ) ?) ;
310313
314+ let http_addr = http. local_addr ( ) ?;
311315 let ws_port = ws. local_addr ( ) ?. port ( ) . to_string ( ) ;
312316
313317 let num_clients = Arc :: new ( ( ) ) ;
314318
315- server_tx. take ( )
319+ server_tx
320+ . take ( )
316321 . unwrap ( )
317322 . send ( Ok ( WebServer {
318323 num_clients : num_clients. clone ( ) ,
@@ -321,12 +326,29 @@ async fn server(port: u16, wake_ui: fn(), server_tx: &mut Option<tokio::sync::on
321326 interaction_rx,
322327 shutdown_tx,
323328 addr : {
324- let mut addr = http. local_addr ( ) ?;
325- match local_ip_address:: local_ip ( ) {
326- Ok ( local_ip) => addr. set_ip ( local_ip) ,
327- Err ( err) => log:: warn!( "Error getting local IP address: {err}" ) ,
329+ let addr = match UdpSocket :: bind ( "0.0.0.0:0" ) . await . ok ( ) {
330+ None => None ,
331+ Some ( socket) => tokio:: time:: timeout ( Duration :: from_secs ( 2 ) , socket. connect ( "8.8.8.8:80" ) )
332+ . await
333+ . ok ( )
334+ . and_then ( Result :: ok)
335+ . and_then ( |_| {
336+ let mut addr = http_addr;
337+ addr. set_ip ( socket. local_addr ( ) . ok ( ) ?. ip ( ) ) ;
338+ Some ( addr)
339+ } )
340+ . or_else ( || {
341+ let mut addr = http_addr;
342+ addr. set_ip ( local_ip_address:: local_ip ( ) . ok ( ) ?) ;
343+ Some ( addr)
344+ } ) ,
345+ } ;
346+
347+ if let Some ( addr) = addr {
348+ format ! ( "http://{addr}" ) . into_boxed_str ( )
349+ } else {
350+ format ! ( "http://localhost:{port}" ) . into_boxed_str ( )
328351 }
329- format ! ( "http://{addr}" ) . into_boxed_str ( )
330352 } ,
331353 } ) )
332354 . ok ( ) ;
@@ -403,4 +425,4 @@ async fn server(port: u16, wake_ui: fn(), server_tx: &mut Option<tokio::sync::on
403425 log:: info!( "Shut down" ) ;
404426
405427 Ok ( ( ) )
406- }
428+ }
0 commit comments