@@ -4,12 +4,12 @@ use std::sync::mpsc::{Receiver, TryRecvError, Sender};
44use std:: time:: Duration ;
55use std:: { thread, time} ;
66
7- use rw3d_core:: { constants, commands, packet:: WitcherPacket } ;
7+ use rw3d_core:: { constants, commands, packet:: WitcherPacket , scriptslog } ;
88use clap:: { Parser , Subcommand } ;
99
1010
1111#[ derive( Parser ) ]
12- #[ clap( name="Rusty Witcher 3 Debugger" , version="0.3 " ) ]
12+ #[ clap( name="Rusty Witcher 3 Debugger" , version="0.4 " ) ]
1313#[ clap( about="A standalone debugging tool for The Witcher 3 written in Rust" , long_about=None ) ]
1414struct Cli {
1515 /// IPv4 address of the machine on which the game is run
@@ -39,7 +39,7 @@ struct Cli {
3939 command : CliCommands ,
4040}
4141
42- #[ derive( Subcommand ) ]
42+ #[ derive( Subcommand , PartialEq , Eq ) ]
4343enum CliCommands {
4444 /// Get the root path to game scripts
4545 Rootpath ,
@@ -81,93 +81,115 @@ enum CliCommands {
8181 /// Variable's new value
8282 #[ clap( short) ]
8383 value : String
84- }
84+ } ,
85+ /// Prints game's script logs onto console
86+ Scriptslog
8587}
8688
8789
8890fn main ( ) {
8991 let cli = Cli :: parse ( ) ;
9092
91- let connection = try_connect ( cli. ip . clone ( ) , 5 , 1000 ) ;
92-
93- match connection {
94- Some ( mut stream) => {
95- if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 1000 ) ) }
96- println ! ( "Successfully connected to the game!" ) ;
97-
98- if !cli. no_listen {
93+ if cli. command != CliCommands :: Scriptslog {
94+ let connection = try_connect ( cli. ip . clone ( ) , 5 , 1000 ) ;
95+
96+ match connection {
97+ Some ( mut stream) => {
9998 if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 1000 ) ) }
100- println ! ( "Setting up listeners..." ) ;
101-
102- let listeners = commands:: listen_all ( ) ;
103- for l in & listeners {
104- stream. write ( l. to_bytes ( ) . as_slice ( ) ) . unwrap ( ) ;
105- }
106- }
107-
108-
109- if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 1000 ) ) }
110- println ! ( "Handling the command..." ) ;
111-
112- let p = match cli. command {
113- CliCommands :: Reload => {
114- commands:: scripts_reload ( )
115- }
116- CliCommands :: Exec { cmd } => {
117- commands:: scripts_execute ( cmd)
118- }
119- CliCommands :: Rootpath => {
120- commands:: scripts_root_path ( )
121- }
122- CliCommands :: Modlist => {
123- commands:: mod_list ( )
99+ println ! ( "Successfully connected to the game!" ) ;
100+
101+ if !cli. no_listen {
102+ if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 1000 ) ) }
103+ println ! ( "Setting up listeners..." ) ;
104+
105+ let listeners = commands:: listen_all ( ) ;
106+ for l in & listeners {
107+ stream. write ( l. to_bytes ( ) . as_slice ( ) ) . unwrap ( ) ;
108+ }
124109 }
125- CliCommands :: Opcode { func_name, class_name } => {
126- commands:: opcode ( func_name, class_name)
110+
111+
112+ if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 1000 ) ) }
113+ println ! ( "Handling the command..." ) ;
114+
115+ let p = match cli. command {
116+ CliCommands :: Reload => {
117+ commands:: scripts_reload ( )
118+ }
119+ CliCommands :: Exec { cmd } => {
120+ commands:: scripts_execute ( cmd)
121+ }
122+ CliCommands :: Rootpath => {
123+ commands:: scripts_root_path ( )
124+ }
125+ CliCommands :: Modlist => {
126+ commands:: mod_list ( )
127+ }
128+ CliCommands :: Opcode { func_name, class_name } => {
129+ commands:: opcode ( func_name, class_name)
130+ }
131+ CliCommands :: Varlist { section, name } => {
132+ commands:: var_list ( section, name)
133+ }
134+ CliCommands :: Varset { section, name, value } => {
135+ commands:: var_set ( section, name, value)
136+ }
137+ //FIXME code will need a makeover because of how scriptslog command makes the program behave differently
138+ // this is a temporary measure
139+ CliCommands :: Scriptslog => panic ! ( ) ,
140+ } ;
141+
142+ stream. write ( p. to_bytes ( ) . as_slice ( ) ) . unwrap ( ) ;
143+
144+
145+ if !cli. no_info_wait || !cli. no_listen {
146+ println ! ( "\n You can press Enter at any moment to exit the program.\n " ) ;
147+ if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 3000 ) ) }
127148 }
128- CliCommands :: Varlist { section, name } => {
129- commands:: var_list ( section, name)
149+
150+ if !cli. no_listen {
151+ println ! ( "Game response:\n " ) ;
152+ if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 1000 ) ) }
153+
154+ // Channel to communicate to and from the the reader
155+ let ( reader_snd, reader_rcv) = std:: sync:: mpsc:: channel ( ) ;
156+
157+ // This thread is not expected to finish, so we won't assign a handle to it
158+ // Takes reader_snd so it can communicate to the reader thread to stop execution when user presses Enter
159+ std:: thread:: spawn ( move || input_waiter_thread ( reader_snd) ) ;
160+
161+ // This function can either finish by itself by the means of response timeout
162+ // or be stopped by input waiter thread if that one sends him a signal
163+ read_responses ( & mut stream, cli. response_timeout , reader_rcv, cli. verbose ) ;
164+
165+ } else {
166+ // Wait a little bit to not finish the connection abruptly
167+ thread:: sleep ( time:: Duration :: from_millis ( 500 ) ) ;
130168 }
131- CliCommands :: Varset { section, name, value } => {
132- commands:: var_set ( section, name, value)
169+
170+ if let Err ( e) = stream. shutdown ( Shutdown :: Both ) {
171+ println ! ( "{}" , e) ;
133172 }
134- } ;
135-
136- stream. write ( p. to_bytes ( ) . as_slice ( ) ) . unwrap ( ) ;
137-
138-
139- if !cli. no_info_wait || !cli. no_listen {
140- println ! ( "\n You can press Enter at any moment to exit the program.\n " ) ;
141- if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 3000 ) ) }
173+
174+ }
175+ None => {
176+ println ! ( "Failed to connect to the game on address {}" , cli. ip) ;
142177 }
178+ }
143179
144- if !cli. no_listen {
145- println ! ( "Game response:\n " ) ;
146- if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 1000 ) ) }
147-
148- // Channel to communicate to and from the the reader
149- let ( reader_snd, reader_rcv) = std:: sync:: mpsc:: channel ( ) ;
150-
151- // This thread is not expected to finish, so we won't assign a handle to it
152- // Takes reader_snd so it can communicate to the reader thread to stop execution when user presses Enter
153- std:: thread:: spawn ( move || input_waiter_thread ( reader_snd) ) ;
154-
155- // This function can either finish by itself by the means of response timeout
156- // or be stopped by input waiter thread if that one sends him a signal
157- read_responses ( & mut stream, cli. response_timeout , reader_rcv, cli. verbose ) ;
180+ } else {
181+ if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 1000 ) ) }
182+ println ! ( "Handling the command..." ) ;
158183
159- } else {
160- // Wait a little bit to not finish the connection abruptly
161- thread:: sleep ( time:: Duration :: from_millis ( 500 ) ) ;
162- }
184+ let ( logger_snd, logger_rcv) = std:: sync:: mpsc:: channel ( ) ;
163185
164- if let Err ( e) = stream. shutdown ( Shutdown :: Both ) {
165- println ! ( "{}" , e) ;
166- }
186+ std:: thread:: spawn ( move || input_waiter_thread ( logger_snd) ) ;
167187
168- }
169- None => {
170- println ! ( "Failed to connect to the game on address {}" , cli. ip) ;
188+ println ! ( "\n You can press Enter at any moment to exit the program.\n " ) ;
189+ if !cli. no_info_wait { thread:: sleep ( time:: Duration :: from_millis ( 3000 ) ) }
190+
191+ if let Some ( err) = scriptslog:: read_from_scriptslog ( |s| print ! ( "{}" , s) , 1000 , logger_rcv) {
192+ println ! ( "{}" , err) ;
171193 }
172194 }
173195}
0 commit comments