1
1
use {
2
- aeronet:: io:: {
3
- Session ,
4
- connection:: { DisconnectReason , Disconnected , LocalAddr } ,
5
- server:: Server ,
6
- } ,
7
- aeronet_replicon:: server:: { AeronetRepliconServer , AeronetRepliconServerPlugin } ,
8
- aeronet_websocket:: server:: { WebSocketServer , WebSocketServerPlugin } ,
9
- aeronet_webtransport:: {
10
- cert,
11
- server:: { SessionRequest , SessionResponse , WebTransportServer , WebTransportServerPlugin } ,
12
- wtransport,
13
- } ,
2
+ crate :: network:: ServerNetworkPlugin ,
3
+ aeronet:: io:: { Session , connection:: Disconnected } ,
14
4
avian3d:: prelude:: * ,
15
5
bevy:: {
16
6
app:: ScheduleRunnerPlugin ,
19
9
render:: { RenderPlugin , settings:: WgpuSettings } ,
20
10
winit:: WinitPlugin ,
21
11
} ,
22
- bevy_replicon:: prelude:: * ,
12
+ bevy_replicon:: { prelude:: * , server :: increment_tick } ,
23
13
core:: time:: Duration ,
24
14
minigolf:: { LevelMesh , MinigolfPlugin , Player , PlayerInput , TICK_RATE } ,
25
15
} ;
@@ -37,13 +27,13 @@ enum GameLayer {
37
27
38
28
/// `move_box` demo server
39
29
#[ derive( Debug , Resource , clap:: Parser ) ]
40
- struct Args {
30
+ pub ( crate ) struct Args {
41
31
/// Port to listen for WebTransport connections on
42
32
#[ arg( long, default_value_t = WEB_TRANSPORT_PORT ) ]
43
- wt_port : u16 ,
33
+ pub ( crate ) wt_port : u16 ,
44
34
/// Port to listen for WebSocket connections on
45
35
#[ arg( long, default_value_t = WEB_SOCKET_PORT ) ]
46
- ws_port : u16 ,
36
+ pub ( crate ) ws_port : u16 ,
47
37
}
48
38
49
39
impl FromWorld for Args {
@@ -52,6 +42,11 @@ impl FromWorld for Args {
52
42
}
53
43
}
54
44
45
+ #[ derive( Component , Reflect ) ]
46
+ struct PlayerSession {
47
+ player : Entity ,
48
+ }
49
+
55
50
pub fn main ( ) -> AppExit {
56
51
App :: new ( )
57
52
. init_resource :: < Args > ( )
@@ -68,38 +63,20 @@ pub fn main() -> AppExit {
68
63
. disable :: < WinitPlugin > ( ) ,
69
64
)
70
65
. add_plugins ( (
71
- // transport
72
- WebTransportServerPlugin ,
73
- WebSocketServerPlugin ,
74
- // replication
75
- RepliconPlugins . set ( ServerPlugin {
76
- // 1 frame lasts `1.0 / TICK_RATE` anyway
77
- tick_policy : TickPolicy :: Manual ,
78
- ..Default :: default ( )
79
- } ) ,
80
- AeronetRepliconServerPlugin ,
81
- // game
66
+ ServerNetworkPlugin ,
82
67
MinigolfPlugin ,
83
68
PhysicsPlugins :: default ( ) ,
84
69
) )
85
70
. add_plugins ( ScheduleRunnerPlugin :: run_loop ( Duration :: from_secs_f64 (
86
71
1.0 / f64:: from ( TICK_RATE ) ,
87
72
) ) )
88
- . add_systems (
89
- Startup ,
90
- ( open_web_transport_server, open_web_socket_server, setup) ,
91
- )
92
- . add_observer ( on_opened)
93
- . add_observer ( on_session_request)
73
+ . add_systems ( Startup , setup)
94
74
. add_observer ( on_connected)
95
75
. add_observer ( on_disconnected)
96
76
. insert_resource ( Time :: < Fixed > :: from_hz ( 128.0 ) )
97
- . add_systems (
98
- FixedUpdate ,
99
- recv_input. chain ( ) . run_if ( server_or_singleplayer) ,
100
- )
77
+ . add_systems ( FixedUpdate , recv_input. run_if ( server_or_singleplayer) )
101
78
. add_systems ( FixedUpdate , reset)
102
- . add_systems ( FixedPreUpdate , bevy_replicon :: server :: increment_tick)
79
+ . add_systems ( FixedPreUpdate , increment_tick)
103
80
. run ( )
104
81
}
105
82
@@ -181,96 +158,12 @@ fn recv_input(
181
158
}
182
159
}
183
160
184
- //
185
- // WebTransport
186
- //
187
-
188
- fn open_web_transport_server ( mut commands : Commands , args : Res < Args > ) {
189
- let identity = wtransport:: Identity :: self_signed ( [ "localhost" , "127.0.0.1" , "::1" ] )
190
- . expect ( "all given SANs should be valid DNS names" ) ;
191
- let cert = & identity. certificate_chain ( ) . as_slice ( ) [ 0 ] ;
192
- let spki_fingerprint = cert:: spki_fingerprint_b64 ( cert) . expect ( "should be a valid certificate" ) ;
193
- let cert_hash = cert:: hash_to_b64 ( cert. hash ( ) ) ;
194
- info ! ( "************************" ) ;
195
- info ! ( "SPKI FINGERPRINT" ) ;
196
- info ! ( " {spki_fingerprint}" ) ;
197
- info ! ( "CERTIFICATE HASH" ) ;
198
- info ! ( " {cert_hash}" ) ;
199
- info ! ( "************************" ) ;
200
-
201
- let config = web_transport_config ( identity, & args) ;
202
- let server = commands
203
- . spawn ( ( Name :: new ( "WebTransport Server" ) , AeronetRepliconServer ) )
204
- . queue ( WebTransportServer :: open ( config) )
205
- . id ( ) ;
206
- info ! ( "Opening WebTransport server {server}" ) ;
207
- }
208
-
209
- type WebTransportServerConfig = aeronet_webtransport:: server:: ServerConfig ;
210
-
211
- fn web_transport_config ( identity : wtransport:: Identity , args : & Args ) -> WebTransportServerConfig {
212
- WebTransportServerConfig :: builder ( )
213
- . with_bind_default ( args. wt_port )
214
- . with_identity ( identity)
215
- . keep_alive_interval ( Some ( Duration :: from_secs ( 1 ) ) )
216
- . max_idle_timeout ( Some ( Duration :: from_secs ( 5 ) ) )
217
- . expect ( "should be a valid idle timeout" )
218
- . build ( )
219
- }
220
-
221
- fn on_session_request ( mut request : Trigger < SessionRequest > , clients : Query < & Parent > ) {
222
- let client = request. entity ( ) ;
223
- let Ok ( server) = clients. get ( client) . map ( Parent :: get) else {
224
- return ;
225
- } ;
226
-
227
- info ! ( "{client} connecting to {server} with headers:" ) ;
228
- for ( header_key, header_value) in & request. headers {
229
- info ! ( " {header_key}: {header_value}" ) ;
230
- }
231
-
232
- request. respond ( SessionResponse :: Accepted ) ;
233
- }
234
-
235
- //
236
- // WebSocket
237
- //
238
-
239
- type WebSocketServerConfig = aeronet_websocket:: server:: ServerConfig ;
240
-
241
- fn open_web_socket_server ( mut commands : Commands , args : Res < Args > ) {
242
- let config = web_socket_config ( & args) ;
243
- let server = commands
244
- . spawn ( ( Name :: new ( "WebSocket Server" ) , AeronetRepliconServer ) )
245
- . queue ( WebSocketServer :: open ( config) )
246
- . id ( ) ;
247
- info ! ( "Opening WebSocket server {server}" ) ;
248
- }
249
-
250
- fn web_socket_config ( args : & Args ) -> WebSocketServerConfig {
251
- WebSocketServerConfig :: builder ( )
252
- . with_bind_default ( args. ws_port )
253
- . with_no_encryption ( )
254
- }
255
-
256
161
//
257
162
// server logic
258
163
//
259
164
260
- fn on_opened ( trigger : Trigger < OnAdd , Server > , servers : Query < & LocalAddr > ) {
261
- let server = trigger. entity ( ) ;
262
- let local_addr = servers
263
- . get ( server)
264
- . expect ( "opened server should have a binding socket `LocalAddr`" ) ;
265
- info ! ( "{server} opened on {}" , * * local_addr) ;
266
- }
267
-
268
- fn on_connected ( trigger : Trigger < OnAdd , Session > , clients : Query < & Parent > , mut commands : Commands ) {
165
+ fn on_connected ( trigger : Trigger < OnAdd , Session > , mut commands : Commands ) {
269
166
let client = trigger. entity ( ) ;
270
- let Ok ( server) = clients. get ( client) . map ( Parent :: get) else {
271
- return ;
272
- } ;
273
- info ! ( "{client} connected to {server}" ) ;
274
167
275
168
let player = commands
276
169
. spawn ( (
@@ -292,34 +185,12 @@ fn on_connected(trigger: Trigger<OnAdd, Session>, clients: Query<&Parent>, mut c
292
185
commands. entity ( client) . insert ( PlayerSession { player } ) ;
293
186
}
294
187
295
- #[ derive( Component , Reflect ) ]
296
- struct PlayerSession {
297
- player : Entity ,
298
- }
299
-
300
188
fn on_disconnected (
301
189
trigger : Trigger < Disconnected > ,
302
- clients : Query < & Parent > ,
303
190
sessions : Query < & PlayerSession > ,
304
191
mut commands : Commands ,
305
192
) {
306
193
let client = trigger. entity ( ) ;
307
- let Ok ( server) = clients. get ( client) . map ( Parent :: get) else {
308
- return ;
309
- } ;
310
-
311
- match & trigger. reason {
312
- DisconnectReason :: User ( reason) => {
313
- info ! ( "{client} disconnected from {server} by user: {reason}" ) ;
314
- }
315
- DisconnectReason :: Peer ( reason) => {
316
- info ! ( "{client} disconnected from {server} by peer: {reason}" ) ;
317
- }
318
- DisconnectReason :: Error ( err) => {
319
- warn ! ( "{client} disconnected from {server} due to error: {err:?}" ) ;
320
- }
321
- }
322
-
323
194
let Ok ( session) = sessions. get ( client) else {
324
195
return ;
325
196
} ;
0 commit comments