dcss_api/lobby.rs
1use crate::Error;
2use crate::Webtile;
3use serde_json::json;
4
5impl Webtile {
6 /// Login to the game, using a username and password. It returns a vector
7 /// of all playable game IDs.
8 ///
9 /// # Arguments
10 ///
11 /// * `username` - A string slice of the user's username.
12 /// * `password` - A string slice of the user's password.
13 ///
14 /// # Example
15 ///
16 /// ```no_run
17 /// // Login under the user "Username", with a password of "Password"
18 /// webtile.login_with_credentials("Username", "Password")?;
19 /// ```
20 pub fn login_with_credentials(
21 &mut self,
22 username: &str,
23 password: &str,
24 ) -> Result<Vec<String>, Box<Error>> {
25 self.write_json(json!({
26 "msg": "login",
27 "username": username,
28 "password": password,
29 }))?;
30
31 self.read_until("login_success", None, None)?;
32
33 self.write_json(json!({
34 "msg": "go_lobby"
35 }))?;
36 self.read_until("go_lobby", None, None)?;
37
38 Ok(self.get_playable_games())
39 }
40
41 /// Login to the game, using a cookie. It returns a vector of all playable
42 /// game IDs.
43 ///
44 /// # Arguments
45 ///
46 /// * `cookie` - A string slice of the user's cookie (received previously).
47 ///
48 /// # Example
49 ///
50 /// ```no_run
51 /// // Login under the user "Username", with a cookie
52 /// webtile.login_with_cookie("Username%123456789123456789123456789")?;
53 /// ```
54 pub fn login_with_cookie(&mut self, cookie: &str) -> Result<Vec<String>, Box<Error>> {
55 self.write_json(json!({"msg": "token_login", "cookie": cookie}))?;
56
57 self.read_until("login_success", None, None)?;
58
59 self.write_json(json!({
60 "msg": "go_lobby"
61 }))?;
62 self.read_until("go_lobby", None, None)?;
63
64 Ok(self.get_playable_games())
65 }
66
67 /// Create an account and login to the game, using a username and password. It returns a vector
68 /// of all playable game IDs. If the account exists, it will simply login using the provided
69 /// password.
70 ///
71 /// # Arguments
72 ///
73 /// * `username` - A string slice of the user's username.
74 /// * `password` - A string slice of the user's password.
75 /// * `email` - A optional string slice of the user's email.
76 ///
77 /// # Example
78 ///
79 /// ```no_run
80 /// // Register and login under the user "Username", with a password of "Password"
81 /// webtile.register_account("Username", "Password", None)?;
82 /// ```
83 pub fn register_account(
84 &mut self,
85 username: &str,
86 password: &str,
87 email: Option<&str>,
88 ) -> Result<Vec<String>, Box<Error>> {
89 self.write_json(
90 json!({"msg": "register", "username": username, "password": password, "email": email.unwrap_or("")}),
91 )?;
92
93 if let Err(e) = self.read_until("login_success", None, None) {
94 match *e {
95 Error::RegisterFailed => self.login_with_credentials(username, password)?,
96 _ => Err(e)?,
97 };
98 };
99
100 self.write_json(json!({
101 "msg": "go_lobby"
102 }))?;
103 self.read_until("go_lobby", None, None)?;
104
105 Ok(self.get_playable_games())
106 }
107
108 /// Request a cookie from the DCSS Webtile.
109 ///
110 /// # Example
111 ///
112 /// ```no_run
113 /// webtile.request_cookie()?;
114 /// ```
115 pub fn request_cookie(&mut self) -> Result<String, Box<Error>> {
116 self.write_json(json!({"msg": "set_login_cookie"}))?;
117
118 self.read_until("login_cookie", None, None)?;
119
120 for message in self.read_only_messages() {
121 let message_obj = message.as_object().unwrap();
122 if message_obj["msg"] == "login_cookie" {
123 return Ok(message_obj["cookie"].as_str().unwrap().to_owned());
124 }
125 }
126
127 unreachable!()
128 }
129
130 /// Get the RC file content for a specific game ID.
131 ///
132 /// # Arguments
133 ///
134 /// * `game_id` - A string slice of the game's ID.
135 ///
136 /// # Example
137 ///
138 /// ```no_run
139 /// webtile.get_rc_file("dcss-web-trunk")?;
140 /// ```
141 pub fn get_rc_file(&mut self, game_id: &str) -> Result<String, Box<Error>> {
142 self.write_json(json!({"msg": "get_rc", "game_id": game_id}))?;
143
144 self.read_until("rcfile_contents", None, None)?;
145
146 for message in self.read_only_messages() {
147 let message_obj = message.as_object().unwrap();
148 if message_obj["msg"] == "rcfile_contents" {
149 return Ok(message_obj["contents"].as_str().unwrap().to_owned());
150 }
151 }
152
153 unreachable!()
154 }
155
156 /// Set the RC file content of a specific game ID.
157 ///
158 /// # Arguments
159 ///
160 /// * `game_id` - A string slice of the game's ID.
161 /// * `content` - A string slice of the content to write to the RC file.
162 ///
163 /// # Example
164 ///
165 /// ```no_run
166 /// webtile.set_rc_file("dcss-web-trunk", "show_more = false\nrest_delay = -1")?;
167 /// ```
168 pub fn set_rc_file(&mut self, game_id: &str, content: &str) -> Result<(), Box<Error>> {
169 self.write_json(json!({"msg": "set_rc", "game_id": game_id, "contents": content}))?;
170
171 Ok(())
172 }
173
174 /// Process the data received when successfully logging in, to extract the playable games
175 fn get_playable_games(&self) -> Vec<String> {
176 for message in self.read_only_messages() {
177 let message_obj = message.as_object().unwrap();
178 if message_obj["msg"] == "set_game_links" {
179 return process_playable_game(message_obj["content"].as_str().unwrap());
180 }
181 }
182
183 unreachable!()
184 }
185}
186
187/// Process the data received when successfully logging in, to extract the playable games
188fn process_playable_game(game_list_html: &str) -> Vec<String> {
189 let mut game_list_vec = game_list_html
190 .split('#')
191 .map(|x| x.split('\"').next().unwrap_or("").to_owned())
192 .map(|x| x[5..x.len()].to_owned())
193 .collect::<Vec<String>>();
194
195 game_list_vec.remove(0);
196
197 game_list_vec
198}