1- use std:: path:: PathBuf ;
1+ use std:: {
2+ path:: PathBuf ,
3+ time:: Duration ,
4+ } ;
25
36use anyhow:: Context ;
47use clap:: Parser ;
@@ -11,8 +14,11 @@ use cs2::{
1114use obfstr:: obfstr;
1215use radar_client:: {
1316 CS2RadarGenerator ,
17+ DummyRadarGenerator ,
18+ RadarGenerator ,
1419 WebRadarPublisher ,
1520} ;
21+ use tokio:: signal;
1622use url:: Url ;
1723use utils_state:: StateRegistry ;
1824
@@ -31,6 +37,11 @@ struct Args {
3137 /// instead of resolving them at runtime by the CS2 schema system.
3238 #[ arg( short, long) ]
3339 schema_file : Option < PathBuf > ,
40+
41+ /// Use a dummy generator instead of generating the radar data from CS2.
42+ /// This is usefull when testing the radar client without CS2.
43+ #[ arg( long, hide = true ) ]
44+ dummy_generator : bool ,
3445}
3546
3647#[ tokio:: main]
@@ -49,10 +60,20 @@ async fn main() -> anyhow::Result<()> {
4960 Ok ( ( ) )
5061}
5162
63+ const RECONNECT_INTERVAL : & [ Duration ] = & [
64+ Duration :: from_secs ( 1 ) ,
65+ Duration :: from_secs ( 5 ) ,
66+ Duration :: from_secs ( 10 ) ,
67+ Duration :: from_secs ( 30 ) ,
68+ Duration :: from_secs ( 60 ) ,
69+ ] ;
70+
5271async fn real_main ( args : & Args ) -> anyhow:: Result < ( ) > {
5372 let url = Url :: parse ( & args. publish_url ) . context ( "invalid target server address" ) ?;
5473
55- let radar_generator = {
74+ let radar_generator: Box < dyn RadarGenerator > = if args. dummy_generator {
75+ Box :: new ( DummyRadarGenerator )
76+ } else {
5677 let cs2 = match CS2Handle :: create ( true ) {
5778 Ok ( cs2) => cs2,
5879 Err ( err) => {
@@ -93,7 +114,16 @@ async fn real_main(args: &Args) -> anyhow::Result<()> {
93114
94115 Box :: new ( CS2RadarGenerator :: new ( states) ?)
95116 } ;
96- let radar_client = WebRadarPublisher :: connect ( radar_generator, & url) . await ?;
117+
118+ self :: radar_publish_loop ( radar_generator, & url) . await
119+ }
120+
121+ async fn radar_publish_loop (
122+ radar_generator : Box < dyn RadarGenerator > ,
123+ url : & Url ,
124+ ) -> anyhow:: Result < ( ) > {
125+ let mut radar_client = WebRadarPublisher :: connect ( & url, None ) . await ?;
126+ radar_client. set_generator ( radar_generator) ;
97127
98128 let mut radar_url = url. clone ( ) ;
99129 radar_url. set_path ( & format ! ( "/session/{}" , radar_client. session_id) ) ;
@@ -105,7 +135,56 @@ async fn real_main(args: &Args) -> anyhow::Result<()> {
105135
106136 log:: info!( "Radar session {}" , radar_client. session_id) ;
107137 log:: info!( "Available at {}" , radar_url) ;
138+ log:: info!( "Press CTRL+C to exit" ) ;
139+
140+ loop {
141+ tokio:: select! {
142+ result = radar_client. execute( ) => {
143+ match result {
144+ Ok ( _) => break ,
145+ Err ( error) => {
146+ log:: error!( "{:#}" , error) ;
147+ }
148+ }
149+ } ,
150+ _ = signal:: ctrl_c( ) => {
151+ log:: info!( "Stopping radar..." ) ;
152+ break ;
153+ }
154+ }
155+
156+ let radar_generator = radar_client. take_generator ( ) . context ( "missing generator" ) ?;
157+ let session_auth_token = radar_client. session_auth_token . clone ( ) ;
158+
159+ /* ensure to close the connection in order to reconnect */
160+ drop ( radar_client) ;
161+
162+ let mut reconnect_index = 0 ;
163+ radar_client = loop {
164+ log:: info!( "Reconnecting..." ) ;
165+ match WebRadarPublisher :: connect ( & url, Some ( session_auth_token. clone ( ) ) ) . await {
166+ Ok ( publisher) => break publisher,
167+ Err ( error) => {
168+ log:: error!( "Reconnect failed: {:#}" , error) ;
169+ if reconnect_index >= RECONNECT_INTERVAL . len ( ) {
170+ anyhow:: bail!( "reconnect failed" ) ;
171+ }
172+
173+ let timeout = RECONNECT_INTERVAL [ reconnect_index] ;
174+ reconnect_index += 1 ;
175+
176+ log:: error!( "Try again in {:#?}" , timeout) ;
177+ tokio:: time:: sleep ( timeout) . await ;
178+ }
179+ }
180+ } ;
181+ radar_client. set_generator ( radar_generator) ;
182+ log:: info!(
183+ "Successfully reconnected (session id = {})" ,
184+ radar_client. session_id
185+ ) ;
186+ }
108187
109- radar_client. await . context ( "radar error" ) ? ;
188+ radar_client. close_connection ( ) . await ;
110189 Ok ( ( ) )
111190}
0 commit comments