blastmud/blastmud_game/src/message_handler/user_commands/login.rs

68 lines
2.2 KiB
Rust

use super::look;
use super::{user_error, UResult, UserVerb, UserVerbRef, VerbContext};
use async_trait::async_trait;
use tokio::time;
pub struct Verb;
#[async_trait]
impl UserVerb for Verb {
async fn handle(
self: &Self,
ctx: &mut VerbContext,
_verb: &str,
remaining: &str,
) -> UResult<()> {
let (username, password) = match remaining.split_whitespace().collect::<Vec<&str>>()[..] {
[] | [_] => user_error("Too few options to login".to_owned())?,
[username, password] => (username, password),
_ => user_error("Too many options to login".to_owned())?,
};
let username_exact = match ctx.trans.find_by_username(username).await? {
None => user_error("No such user.".to_owned())?,
Some(user) => {
time::sleep(time::Duration::from_secs(5)).await;
if !bcrypt::verify(password, &user.password_hash)? {
user_error("Invalid password.".to_owned())?
}
let username_exact = user.username.clone();
*ctx.user_dat = Some(user);
username_exact
}
};
ctx.trans
.attach_user_to_session(username, ctx.session)
.await?;
if ctx
.trans
.check_task_by_type_code("DestroyUser", &username_exact)
.await?
{
ctx.trans
.queue_for_session(
ctx.session,
Some(
"Your username was scheduled to self-destruct - that has now been \
cancelled because you logged in.\n",
),
)
.await?;
ctx.trans
.delete_task("DestroyUser", &username_exact)
.await?;
}
super::agree::check_and_notify_accepts(ctx).await?;
if let Some(user) = ctx.user_dat {
ctx.trans.save_user_model(user).await?;
look::VERB.handle(ctx, "look", "").await?;
}
Ok(())
}
}
static VERB_INT: Verb = Verb;
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;