diff -r c5c53ebb2d91 -r e514ceb5e7d6 rust/hedgewars-server/src/server/database.rs --- a/rust/hedgewars-server/src/server/database.rs Fri Mar 24 03:26:08 2023 +0300 +++ b/rust/hedgewars-server/src/server/database.rs Sat Mar 25 03:29:22 2023 +0300 @@ -1,5 +1,6 @@ use mysql_async::{self, from_row_opt, params, prelude::*, Pool}; use sha1::{Digest, Sha1}; +use tokio::sync::mpsc::{channel, Receiver, Sender}; use crate::handlers::{AccountInfo, Sha1Digest}; @@ -25,14 +26,96 @@ pub struct Achievements {} +pub enum DatabaseQuery { + CheckRegistered { + nick: String, + }, + GetAccount { + nick: String, + protocol: u16, + password_hash: String, + client_salt: String, + server_salt: String, + }, + GetCheckerAccount { + nick: String, + password: String, + }, + GetReplayFilename { + id: u32, + }, +} + +pub enum DatabaseResponse { + AccountRegistered(bool), + Account(Option), + CheckerAccount { is_registered: bool }, +} + pub struct Database { pool: Pool, + query_rx: Receiver, + response_tx: Sender, } impl Database { pub fn new(url: &str) -> Self { + let (query_tx, query_rx) = channel(32); + let (response_tx, response_rx) = channel(32); Self { pool: Pool::new(url), + query_rx, + response_tx, + } + } + + pub async fn run(&mut self) { + use DatabaseResponse::*; + loop { + let query = self.query_rx.recv().await; + if let Some(query) = query { + match query { + DatabaseQuery::CheckRegistered { nick } => { + let is_registered = self.get_is_registered(&nick).await.unwrap_or(false); + self.response_tx + .send(AccountRegistered(is_registered)) + .await; + } + DatabaseQuery::GetAccount { + nick, + protocol, + password_hash, + client_salt, + server_salt, + } => { + let account = self + .get_account( + &nick, + protocol, + &password_hash, + &client_salt, + &server_salt, + ) + .await + .unwrap_or(None); + self.response_tx.send(Account(account)).await; + } + DatabaseQuery::GetCheckerAccount { nick, password } => { + let is_registered = self + .get_checker_account(&nick, &password) + .await + .unwrap_or(false); + self.response_tx + .send(CheckerAccount { is_registered }) + .await; + } + DatabaseQuery::GetReplayFilename { id } => { + let filename = self.get_replay_name(id).await; + } + }; + } else { + break; + } } } @@ -40,9 +123,9 @@ let mut connection = self.pool.get_conn().await?; let result = CHECK_ACCOUNT_EXISTS_QUERY .with(params! { "username" => nick }) - .first(&mut connection) + .first::(&mut connection) .await?; - Ok(!result.is_empty()) + Ok(!result.is_some()) } pub async fn get_account(