@@ -3,6 +3,7 @@ use crate::controller::rooms::legacy;
33use crate :: controller:: states:: { AppState , AppStateCapture } ;
44use crate :: controller:: { ExceptionType , Room , RoomKind , SCAFFOLDING_PORT } ;
55use crate :: easytier;
6+ use crate :: easytier:: argument:: { Argument , PortForward , Proto } ;
67use crate :: mc:: fakeserver:: FakeServer ;
78use crate :: ports:: PortRequest ;
89use crate :: scaffolding:: client:: ClientSession ;
@@ -11,10 +12,12 @@ use crate::scaffolding::PacketResponse;
1112use rand_chacha:: ChaCha12Rng ;
1213use rand_core:: { OsRng , RngCore , SeedableRng , TryRngCore } ;
1314use serde_json:: { json, Value } ;
15+ use std:: borrow:: Cow ;
1416use std:: net:: { IpAddr , Ipv4Addr , Ipv6Addr , SocketAddrV4 , SocketAddrV6 } ;
1517use std:: str:: FromStr ;
1618use std:: time:: { Duration , SystemTime } ;
1719use std:: { io, thread} ;
20+ use std:: mem:: { transmute, MaybeUninit } ;
1821
1922static CHARS : & [ u8 ] = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ" . as_bytes ( ) ;
2023
@@ -137,13 +140,11 @@ pub fn start_host(room: Room, port: u16, player: Option<String>, capture: AppSta
137140 let scaffolding = * SCAFFOLDING_PORT ;
138141
139142 let mut args = compute_arguments ( & room) ;
140- args. push ( "--hostname" . to_string ( ) ) ;
141- args. push ( format ! ( "scaffolding-mc-server-{}" , scaffolding) ) ;
142- args. push ( "--ipv4" . to_string ( ) ) ;
143- args. push ( "10.144.144.1" . to_string ( ) ) ;
144- args. push ( format ! ( "--tcp-whitelist={}" , scaffolding) ) ;
145- args. push ( format ! ( "--tcp-whitelist={}" , port) ) ;
146- args. push ( format ! ( "--udp-whitelist={}" , port) ) ;
143+ args. push ( Argument :: HostName ( Cow :: Owned ( format ! ( "scaffolding-mc-server-{}" , scaffolding) ) ) ) ;
144+ args. push ( Argument :: IPv4 ( Ipv4Addr :: new ( 10 , 144 , 144 , 1 ) ) ) ;
145+ args. push ( Argument :: TcpWhitelist ( scaffolding) ) ;
146+ args. push ( Argument :: TcpWhitelist ( port) ) ;
147+ args. push ( Argument :: UdpWhitelist ( port) ) ;
147148
148149 let easytier = easytier:: FACTORY . create ( args) ;
149150 let capture = {
@@ -213,9 +214,9 @@ pub fn start_host(room: Room, port: u16, player: Option<String>, capture: AppSta
213214
214215pub fn start_guest ( room : Room , player : Option < String > , capture : AppStateCapture ) {
215216 let mut args = compute_arguments ( & room) ;
216- args. push ( "-d" . to_string ( ) ) ;
217- args. push ( "--tcp-whitelist=0" . to_string ( ) ) ;
218- args. push ( "--udp-whitelist=0" . to_string ( ) ) ;
217+ args. push ( Argument :: DHCP ) ;
218+ args. push ( Argument :: TcpWhitelist ( 0 ) ) ;
219+ args. push ( Argument :: UdpWhitelist ( 0 ) ) ;
219220 let easytier = easytier:: FACTORY . create ( args) ;
220221 let capture = {
221222 let Some ( state) = capture. try_capture ( ) else {
@@ -250,10 +251,11 @@ pub fn start_guest(room: Room, player: Option<String>, capture: AppStateCapture)
250251
251252 let local_port = PortRequest :: Scaffolding . request ( ) ;
252253
253- if !easytier. add_port_forward ( & [ (
254- SocketAddrV4 :: new ( Ipv4Addr :: UNSPECIFIED , local_port) . into ( ) ,
255- SocketAddrV4 :: new ( ip, port) . into ( ) ,
256- ) ] ) {
254+ if !easytier. add_port_forward ( & [ PortForward {
255+ local : SocketAddrV4 :: new ( Ipv4Addr :: UNSPECIFIED , local_port) . into ( ) ,
256+ remote : SocketAddrV4 :: new ( ip, port) . into ( ) ,
257+ proto : Proto :: TCP
258+ } ] ) {
257259 logging ! ( "RoomExperiment" , "Cannot create a port-forward {} -> {} for Scaffolding Connection." , local_port, port) ;
258260 state. set ( AppState :: Exception { kind : ExceptionType :: GuestEasytierCrash } ) ;
259261 return ;
@@ -346,17 +348,31 @@ pub fn start_guest(room: Room, player: Option<String>, capture: AppStateCapture)
346348 // If failed, use a dynamic free port instead.
347349 let local_port = PortRequest :: request_specific ( port) . unwrap_or_else ( || PortRequest :: Minecraft . request ( ) ) ;
348350
349- if !easytier. add_port_forward ( & [ (
350- SocketAddrV4 :: new ( Ipv4Addr :: UNSPECIFIED , local_port) . into ( ) ,
351- SocketAddrV4 :: new ( host_ip, port) . into ( )
352- ) , (
353- SocketAddrV6 :: new ( Ipv6Addr :: UNSPECIFIED , local_port, 0 , 0 ) . into ( ) ,
354- SocketAddrV4 :: new ( host_ip, port) . into ( )
355- ) ] ) {
351+ if !easytier. add_port_forward ( & {
352+ let locals = [
353+ SocketAddrV4 :: new ( Ipv4Addr :: UNSPECIFIED , local_port) . into ( ) ,
354+ SocketAddrV6 :: new ( Ipv6Addr :: UNSPECIFIED , local_port, 0 , 0 ) . into ( ) ,
355+ ] ;
356+ let protos = [ Proto :: TCP , Proto :: UDP ] ;
357+
358+ // TODO: Compute SIZE automatically.
359+ const SIZE : usize = 4 ;
360+ assert_eq ! ( locals. len( ) * protos. len( ) , SIZE ) ;
361+ let mut forwards: [ MaybeUninit < PortForward > ; SIZE ] = [ const { MaybeUninit :: uninit ( ) } ; _] ;
362+ for ( i, local) in locals. into_iter ( ) . enumerate ( ) {
363+ for ( j, proto) in protos. iter ( ) . enumerate ( ) {
364+ forwards[ i * 2 + j] . write ( PortForward {
365+ remote : SocketAddrV4 :: new ( host_ip, port) . into ( ) , local, proto : proto. clone ( )
366+ } ) ;
367+ }
368+ }
369+ // SAFETY: These two types are of the same size and all elements have been properly initialized.
370+ unsafe { transmute :: < [ MaybeUninit < PortForward > ; SIZE ] , [ PortForward ; SIZE ] > ( forwards) }
371+ } ) {
356372 logging ! ( "RoomExperiment" , "Cannot create a port-forward {} -> {} for MC Connection." , local_port, port) ;
357373 state. set ( AppState :: Exception { kind : ExceptionType :: GuestEasytierCrash } ) ;
358374 return ;
359- }
375+ } else { }
360376
361377 local_port
362378 } ;
@@ -549,44 +565,40 @@ static FALLBACK_SERVERS: [&str; 2] = [
549565 "tcp://public2.easytier.cn:54321" ,
550566] ;
551567
552- fn compute_arguments ( room : & Room ) -> Vec < String > {
553- static DEFAULT_ARGUMENTS : [ & str ; 7 ] = [
554- "--no-tun" ,
555- "--compression=zstd" ,
556- "--multi-thread" ,
557- "--latency-first" ,
558- "--enable-kcp-proxy" ,
559- "-l" ,
560- "udp://0.0.0.0:0" ,
568+ fn compute_arguments ( room : & Room ) -> Vec < Argument > {
569+ static DEFAULT_ARGUMENTS : [ Argument ; 6 ] = [
570+ Argument :: NoTun ,
571+ Argument :: Compression ( Cow :: Borrowed ( "zstd" ) ) ,
572+ Argument :: MultiThread ,
573+ Argument :: LatencyFirst ,
574+ Argument :: EnableKcpProxy ,
575+ Argument :: Listener {
576+ address : SocketAddrV4 :: new ( Ipv4Addr :: UNSPECIFIED , 0 ) . into ( ) ,
577+ proto : Proto :: UDP
578+ } ,
561579 ] ;
562580
563- let mut args: Vec < String > = Vec :: with_capacity ( 32 ) ;
581+ let mut args: Vec < Argument > = Vec :: with_capacity ( 32 ) ;
564582 args. extend_from_slice ( & [
565- "--network-name" . to_string ( ) ,
566- room. network_name . clone ( ) ,
567- "--network-secret" . to_string ( ) ,
568- room. network_secret . clone ( ) ,
583+ Argument :: NetworkName ( Cow :: Owned ( room. network_name . clone ( ) ) ) ,
584+ Argument :: NetworkSecret ( Cow :: Owned ( room. network_secret . clone ( ) ) ) ,
569585 ] ) ;
570586
571587 match fetch_public_nodes ( room) {
572588 Ok ( nodes) => {
573589 for replay in nodes {
574- args. push ( "-p" . to_string ( ) ) ;
575- args. push ( replay) ;
590+ args. push ( Argument :: PublicServer ( Cow :: Owned ( replay) ) ) ;
576591 }
577592 }
578593 Err ( e) => {
579594 logging ! ( "RoomExperiment" , "Cannot fetch EasyTier public nodes: {:?}." , e) ;
580595 for replay in FALLBACK_SERVERS {
581- args. push ( "-p" . to_string ( ) ) ;
582- args. push ( replay. to_string ( ) ) ;
596+ args. push ( Argument :: PublicServer ( Cow :: Borrowed ( replay) ) ) ;
583597 }
584598 }
585599 }
586600
587- for arg in DEFAULT_ARGUMENTS {
588- args. push ( arg. to_string ( ) ) ;
589- }
601+ args. extend_from_slice ( & DEFAULT_ARGUMENTS ) ;
590602 args
591603}
592604
0 commit comments