use chrono::Utc; use log::warn; use mio::Token; use crate::command::Command; use crate::game::{Game, PlayerCheck}; use crate::player::Player; use crate::queue::SendQueue; use crate::state::*; impl Game { pub fn login(&mut self, token: Token, message: String, state: &Login) -> SendQueue { let mut send_queue = SendQueue::new(); match state { // get the username Login::Username => { if message.is_empty() { send_queue.push(token, "\n\nUsername: ", false, None); } else { match self.check_player_name(message) { PlayerCheck::Ok(name) => match self.db.find_player_by_name(&name) { Ok(Some(_)) => { send_queue.push( token, "\nPassword: ", false, Some(State::Login(Login::Password(name))), ); } Ok(None) => { send_queue.push( token, format!("\nCreate {}? [y/N]: ", name), false, Some(State::Login(Login::CreateUser(name))), ); } Err(_) => { send_queue.push(token, "\nError\n\nUsername: ", false, None); } }, PlayerCheck::Err(err) => { send_queue.push(token, "\nInvalid username:\n", false, None); for line in err { send_queue.push(token, format!("{}\n", line), false, None); } send_queue.push(token, "\n\nUsername: ", false, None); } }; } } // username not found Login::CreateUser(username) => { if !message.clone().is_empty() && message == "y" { send_queue.push( token, "\nNew password: ", false, Some(State::Login(Login::CreatePassword(username.to_owned()))), ); } else { send_queue.push( token, "\n\nUsername: ", false, Some(State::Login(Login::Username)), ); } } // first new user password Login::CreatePassword(username) => { if message.is_empty() { send_queue.push( token, "\n\nUsername: ", false, Some(State::Login(Login::Username)), ); } else { match self.check_player_password(message) { PlayerCheck::Ok(pass) => { send_queue.push( token, "\nNew password again: ", false, Some(State::Login(Login::CreatePassword2(( username.to_owned(), pass, )))), ); } PlayerCheck::Err(err) => { send_queue.push(token, "\nInvalid password:\n", false, None); for line in err { send_queue.push(token, format!("{}\n", line), false, None); } send_queue.push(token, "\nNew password: ", false, None); } } } } Login::CreatePassword2((username, pass)) => { let pass = pass.to_owned(); if message.is_empty() || message != pass { send_queue.push( token, "\n\nUsername: ", false, Some(State::Login(Login::Username)), ); } else { if let Ok(id) = self.db.new_player_id() { let player = Player { id, name: username.clone(), password: pass, created: Utc::now(), location: self.config.player.starting_location.clone(), }; if self.db.single_save_player(token, &player).is_ok() { send_queue.push( token, format!("Welcome, {}\n", username), false, Some(State::Action), ); send_queue.push(token, "", true, None); send_queue.append(&mut Command::dispatch_look( &Command::default(), String::new(), token, &mut self.db, )); } else { send_queue.push(token, "Error", true, None); } } else { send_queue.push(token, "Error", true, None); } } } Login::Password(username) => { if message.is_empty() { send_queue.push( token, "\n\nUsername: ", false, Some(State::Login(Login::Username)), ); } else { match self.db.find_player_by_name(username) { Ok(Some(player)) => { if message == player.password { if self.db.save_connected_player(token, &player).is_ok() { send_queue.push( token, format!("Welcome back, {}\n\n", username), false, Some(State::Action), ); send_queue.append(&mut Command::dispatch_look( &Command::default(), String::new(), token, &mut self.db, )); } else { send_queue.push(token, "Unable to login\n", false, None); send_queue.push( token, "\n\nUsername: ", false, Some(State::Login(Login::Username)), ); } } else { send_queue.push(token, "Incorrect password\n", false, None); send_queue.push( token, "\n\nUsername: ", false, Some(State::Login(Login::Username)), ); } } Ok(None) | Err(_) => { send_queue.push(token, "Error\n", false, None); send_queue.push( token, "\n\nUsername: ", false, Some(State::Login(Login::Username)), ); } } } } }; send_queue } }