@@ -2,9 +2,11 @@ mod game_state;
2
2
3
3
use game_state:: GameState ;
4
4
use mini_http;
5
- use mini_http:: Server ;
5
+ use mini_http:: { Request , Server } ;
6
6
use rand:: Rng ;
7
+ use std:: collections:: HashMap ;
7
8
use std:: rc:: Rc ;
9
+ use url:: { ParseError , Url } ;
8
10
9
11
// All the web server and network code by Harald H.
10
12
// https://github.com/haraldh
@@ -31,40 +33,49 @@ const NOT_FOUND: &str = r#"
31
33
</body></html>
32
34
"# ;
33
35
36
+ fn get_url ( req : & Request ) -> Result < Url , ParseError > {
37
+ let k = req. headers ( ) ;
38
+ if let Some ( base) = k. get ( "host" ) {
39
+ let base_url: String = base. to_str ( ) . unwrap_or ( "http://localhost:10030" ) . into ( ) ;
40
+ let url = format ! ( "{}{}" , base_url, req. uri( ) . to_string( ) ) ;
41
+ Url :: parse ( & * url)
42
+ } else {
43
+ Err ( ParseError :: EmptyHost )
44
+ }
45
+ }
46
+
34
47
// Single-player mode
35
48
//
36
49
// Color scheme:
37
50
// y (yellow): right letter, wrong position
38
51
// g (green): letter at the right position
39
52
40
- fn check_single ( query : Option < & str > , state : Rc < GameState > ) -> Vec < u8 > {
53
+ fn check_single ( req : & Request , state : Rc < GameState > ) -> Vec < u8 > {
41
54
let mut response = vec ! [ b'c' ; 5 ] ;
55
+ let url = get_url ( & req) ;
42
56
43
57
// Get guess parameter
44
- if query. is_some ( ) {
45
- let the_params = query. unwrap ( ) ;
46
- let the_params_parts = the_params. split_once ( "&" ) . unwrap ( ) ;
47
- let the_guess = the_params_parts. 0 ;
48
- let the_guess_parts = the_guess. split_once ( "=" ) . unwrap ( ) ;
49
- let guess = the_guess_parts. 1 ;
50
- //println!("The guess: {}", guess);
51
-
52
- let guess_size: usize = guess. len ( ) as usize ;
53
- if guess_size == 5 {
54
- for letter_index in 0 ..guess_size {
55
- if guess. as_bytes ( ) [ letter_index] == state. word . as_bytes ( ) [ letter_index] {
56
- response[ letter_index] = b'g' ;
57
- } else {
58
- for letter_byte in state. word . as_bytes ( ) {
59
- if guess. as_bytes ( ) [ letter_index] . eq ( letter_byte)
60
- && response[ letter_index] == b'c'
61
- {
62
- response[ letter_index] = b'y' ;
58
+ if let Ok ( url) = url {
59
+ let query: HashMap < String , String > = url. query_pairs ( ) . into_owned ( ) . collect ( ) ;
60
+ if let Some ( guess) = query. get ( "guess" ) {
61
+ let guess_size: usize = guess. len ( ) ;
62
+ if guess_size == 5 {
63
+ for letter_index in 0 ..guess_size {
64
+ if guess. as_bytes ( ) [ letter_index] == state. word . as_bytes ( ) [ letter_index] {
65
+ response[ letter_index] = b'g' ;
66
+ } else {
67
+ for letter_byte in state. word . as_bytes ( ) {
68
+ if guess. as_bytes ( ) [ letter_index] . eq ( letter_byte)
69
+ && response[ letter_index] == b'c'
70
+ {
71
+ response[ letter_index] = b'y' ;
72
+ }
63
73
}
64
74
}
65
75
}
66
76
}
67
77
}
78
+ //println!("The guess: {}", guess);
68
79
}
69
80
70
81
return response;
@@ -77,72 +88,64 @@ fn check_single(query: Option<&str>, state: Rc<GameState>) -> Vec<u8> {
77
88
// p (purple): word match
78
89
// r (red): word was already a match
79
90
80
- fn check_multi ( query : Option < & str > , state : Rc < GameState > ) -> Vec < u8 > {
91
+ fn check_multi ( req : & Request , state : Rc < GameState > ) -> Vec < u8 > {
81
92
let mut response = vec ! [ b'c' ; 5 ] ;
82
-
93
+ let url = get_url ( & req ) ;
83
94
// Get guess and player parameters
84
- if query. is_some ( ) {
85
- let the_params = query. unwrap ( ) ;
86
- let the_params_parts = the_params. split_once ( "&" ) . unwrap ( ) ;
87
- let the_guess = the_params_parts. 0 ;
88
- let the_player = the_params_parts. 1 ;
89
- let the_guess_parts = the_guess. split_once ( "=" ) . unwrap ( ) ;
90
- let guess = the_guess_parts. 1 ;
91
- //println!("The guess: {}", guess);
92
- let the_player_parts = the_player. split_once ( "=" ) . unwrap ( ) ;
93
- let player = the_player_parts. 1 ;
94
- //println!("The player: {}", player);
95
-
96
- // Wrong word size
97
- let word_size: usize = guess. len ( ) as usize ;
98
- if word_size != 5 {
99
- return response;
100
- }
101
-
102
- // Check if this word was already a match
103
- let matches_index = state. matches . borrow ( ) . iter ( ) . position ( |x| x == guess) ;
104
- if matches_index. is_some ( ) {
105
- response = vec ! [ b'r' ; 5 ] ;
106
- return response;
107
- }
108
-
109
- // Check letters
110
- for letter_index in 0 ..word_size {
111
- let letter_char = guess. as_bytes ( ) [ letter_index] as char ;
112
- let found_char = state. letters . borrow ( ) [ letter_index]
113
- . chars ( )
114
- . any ( |ch| ch == letter_char) ;
115
- if found_char {
116
- response[ letter_index] = b'b' ;
117
- } else {
118
- state. letters . borrow_mut ( ) [ letter_index] . push_str ( & letter_char. to_string ( ) ) ;
95
+ if let Ok ( url) = url {
96
+ let query: HashMap < String , String > = url. query_pairs ( ) . into_owned ( ) . collect ( ) ;
97
+ if let ( Some ( guess) , Some ( player) ) = ( query. get ( "guess" ) , query. get ( "player" ) ) {
98
+ // Wrong word size
99
+ let word_size: usize = guess. len ( ) as usize ;
100
+ if word_size != 5 {
101
+ return response;
119
102
}
120
- }
121
103
122
- // Check if this word is a new match
123
- let guesses_index = state. guesses . borrow ( ) . iter ( ) . position ( |x| x == guess) ;
124
- if guesses_index. is_some ( ) {
125
- // Check if it matches a previous guess from the player
126
- let winner = & state. players . borrow ( ) [ guesses_index. unwrap ( ) ] ;
127
- if winner == player {
104
+ // Check if this word was already a match
105
+ let matches_index = state. matches . borrow ( ) . iter ( ) . position ( |x| x == guess) ;
106
+ if matches_index. is_some ( ) {
128
107
response = vec ! [ b'r' ; 5 ] ;
129
108
return response;
130
109
}
131
110
132
- // Push word to matches
133
- state. matches . borrow_mut ( ) . push ( guess. to_string ( ) ) ;
134
- response = vec ! [ b'p' ; 5 ] ;
135
- //println!("New match: {}", guess.to_string());
111
+ // Check letters
112
+ for letter_index in 0 ..word_size {
113
+ let letter_char = guess. as_bytes ( ) [ letter_index] as char ;
114
+ let found_char = state. letters . borrow ( ) [ letter_index]
115
+ . chars ( )
116
+ . any ( |ch| ch == letter_char) ;
117
+ if found_char {
118
+ response[ letter_index] = b'b' ;
119
+ } else {
120
+ state. letters . borrow_mut ( ) [ letter_index] . push_str ( & letter_char. to_string ( ) ) ;
121
+ }
122
+ }
123
+
124
+ // Check if this word is a new match
125
+ let guesses_index = state. guesses . borrow ( ) . iter ( ) . position ( |x| x == guess) ;
126
+ if guesses_index. is_some ( ) {
127
+ // Check if it matches a previous guess from the player
128
+ let winner = & state. players . borrow ( ) [ guesses_index. unwrap ( ) ] ;
129
+ if winner == player {
130
+ response = vec ! [ b'r' ; 5 ] ;
131
+ return response;
132
+ }
136
133
137
- // Push winners
138
- state. winners . borrow_mut ( ) . push ( player. to_string ( ) ) ;
139
- state. winners . borrow_mut ( ) . push ( winner. to_string ( ) ) ;
140
- //println!("Winners: {}, {}", player.to_string(), winner.to_string());
141
- } else {
142
- // Push new word to guesses
143
- state. guesses . borrow_mut ( ) . push ( guess. to_string ( ) ) ;
144
- state. players . borrow_mut ( ) . push ( player. to_string ( ) ) ;
145
- //println!("New word: {}", guess.to_string());
134
+ // Push word to matches
135
+ state. matches . borrow_mut ( ) . push ( guess. to_string ( ) ) ;
136
+ response = vec ! [ b'p' ; 5 ] ;
137
+ //println!("New match: {}", guess.to_string());
138
+
139
+ // Push winners
140
+ state. winners . borrow_mut ( ) . push ( player. to_string ( ) ) ;
141
+ state. winners . borrow_mut ( ) . push ( winner. to_string ( ) ) ;
142
+ //println!("Winners: {}, {}", player.to_string(), winner.to_string());
143
+ } else {
144
+ // Push new word to guesses
145
+ state. guesses . borrow_mut ( ) . push ( guess. to_string ( ) ) ;
146
+ state. players . borrow_mut ( ) . push ( player. to_string ( ) ) ;
147
+ //println!("New word: {}", guess.to_string());
148
+ }
146
149
}
147
150
}
148
151
@@ -230,12 +233,12 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
230
233
"/single" => mini_http:: Response :: builder ( )
231
234
. status ( 200 )
232
235
. header ( "Content-Type" , "text/plain" )
233
- . body ( check_single ( req. uri ( ) . query ( ) , state. clone ( ) ) )
236
+ . body ( check_single ( & req, state. clone ( ) ) )
234
237
. unwrap ( ) ,
235
238
"/multi" => mini_http:: Response :: builder ( )
236
239
. status ( 200 )
237
240
. header ( "Content-Type" , "text/plain" )
238
- . body ( check_multi ( req. uri ( ) . query ( ) , state. clone ( ) ) )
241
+ . body ( check_multi ( & req, state. clone ( ) ) )
239
242
. unwrap ( ) ,
240
243
"/winners" => mini_http:: Response :: builder ( )
241
244
. status ( 200 )
0 commit comments