wOxlf/src/game/role/spy.rs

78 lines
2.2 KiB
Rust

use crate::game::listener::{EventStatus, Listener, ListenerContext, Priority};
use crate::game::message_router::{
send_private_message, Median, MessageDest, MessageSource, WoxlfMessage,
};
use crate::game::role::Role;
use rand::{thread_rng, Rng};
use serenity::async_trait;
use serenity::model::prelude::UserId;
use serenity::utils::MessageBuilder;
#[derive(Debug)]
pub struct SpyListener {}
#[async_trait]
impl Listener for SpyListener {
fn get_priority(&self) -> Priority {
Priority::Logging
}
async fn on_chat(
&mut self,
ctx: &mut ListenerContext,
msg: &WoxlfMessage,
) -> crate::error::Result<EventStatus> {
if msg.median != Median::DirectMessage {
return Ok(EventStatus::Okay);
}
let src_player = if let MessageSource::Player(p) = &msg.source {
p
} else {
return Ok(EventStatus::Okay);
};
let dest_player = if let MessageDest::Player(p) = &msg.dest {
p
} else {
return Ok(EventStatus::Okay);
};
let spy_player = ctx
.data
.game_state()?
.player_data
.iter()
.find(|p| p.alive && p.role == Role::Spy);
if let Some(spy_player) = spy_player {
if spy_player.discord_id == dest_player.discord_id
|| spy_player.discord_id == src_player.discord_id
{
return Ok(EventStatus::Okay);
}
// 1/4 chance to intercept message
if thread_rng().gen_bool(0.25) {
let msg_content = MessageBuilder::default()
.push_bold_line_safe(format!(
"{} Sent {} a private message:",
src_player.codename, dest_player.codename
))
.push(msg.content.clone())
.build();
send_private_message(
&ctx.ctx.http,
UserId::from(spy_player.discord_id),
&msg_content,
&None,
)
.await?
}
}
return Ok(EventStatus::Okay);
}
}