228 lines
5.8 KiB
Rust
228 lines
5.8 KiB
Rust
use crate::error;
|
|
use crate::game::global_data::GlobalData;
|
|
use crate::game::player_data::PlayerData;
|
|
use serenity::client::Context;
|
|
use serenity::http::Http;
|
|
use serenity::model::guild::Guild;
|
|
use serenity::model::id::UserId;
|
|
use serenity::model::prelude::AttachmentType;
|
|
use serenity::utils::MessageBuilder;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum MessageSource {
|
|
Player(Box<PlayerData>),
|
|
Host,
|
|
Automated,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum MessageDest {
|
|
PlayerChannel(Box<PlayerData>),
|
|
PlayerDm(Box<PlayerData>),
|
|
Broadcast,
|
|
}
|
|
|
|
|
|
fn filter_source_channel(player_data: &&PlayerData, msg_source: &MessageSource) -> bool {
|
|
if let MessageSource::Player(source_player) = &msg_source {
|
|
if source_player.channel == player_data.channel {
|
|
return false;
|
|
}
|
|
}
|
|
true
|
|
}
|
|
|
|
async fn send_webhook_msg(
|
|
http: &Http,
|
|
webhook_id: u64,
|
|
username: &str,
|
|
profile_pic_url: Option<String>,
|
|
msg: &str,
|
|
attachments: &Option<Vec<AttachmentType<'_>>>,
|
|
) -> error::Result<()> {
|
|
let webhook = http.get_webhook(webhook_id).await?;
|
|
|
|
webhook
|
|
.execute(http, false, move |w| {
|
|
w.content(&msg).username(username);
|
|
|
|
if let Some(profile_pic_url) = profile_pic_url {
|
|
w.avatar_url(profile_pic_url);
|
|
}
|
|
|
|
if let Some(attachments) = attachments {
|
|
w.add_files(attachments.clone());
|
|
}
|
|
|
|
w
|
|
})
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn send_private_message(
|
|
http: &Http,
|
|
src_username: &str,
|
|
dest: UserId,
|
|
msg: &str,
|
|
attachments: &Option<Vec<AttachmentType<'_>>>,
|
|
) -> error::Result<()> {
|
|
let dest_user = dest.to_user(http).await?;
|
|
|
|
let mut dm_message = MessageBuilder::new();
|
|
|
|
dm_message.push_bold_line_safe(format!("{} has sent you a DM:", src_username));
|
|
dm_message.push(msg);
|
|
|
|
dest_user
|
|
.dm(http, |msg| {
|
|
msg.content(dm_message);
|
|
|
|
if let Some(attachments) = attachments {
|
|
msg.add_files(attachments.clone());
|
|
}
|
|
|
|
msg
|
|
})
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn send_to_host_channel(
|
|
http: &Http,
|
|
guild: &Guild,
|
|
global_data: &mut GlobalData,
|
|
msg_username: &str,
|
|
msg_source: MessageSource,
|
|
msg_dest: MessageDest,
|
|
profile_pic_url: Option<String>,
|
|
msg: &str,
|
|
attachments: &Option<Vec<AttachmentType<'_>>>,
|
|
) -> error::Result<()> {
|
|
let source = match &msg_source {
|
|
MessageSource::Player(player_data) => {
|
|
let name = guild
|
|
.members
|
|
.get(&UserId::from(player_data.discord_id))
|
|
.unwrap()
|
|
.display_name();
|
|
|
|
name.to_string()
|
|
}
|
|
MessageSource::Host => "Host".to_string(),
|
|
MessageSource::Automated => "Automated".to_string(),
|
|
};
|
|
|
|
let dest = match &msg_dest {
|
|
MessageDest::PlayerChannel(p) | MessageDest::PlayerDm(p) => {
|
|
let name = guild
|
|
.members
|
|
.get(&UserId::from(p.discord_id))
|
|
.unwrap()
|
|
.display_name();
|
|
|
|
format!(" to {} ({})", p.codename, name)
|
|
}
|
|
MessageDest::Broadcast => "".to_string(),
|
|
};
|
|
|
|
let host_channel_username = format!("{} ({}){}", msg_username, source, dest);
|
|
|
|
send_webhook_msg(
|
|
http,
|
|
global_data.cfg.discord_config.host_webhook_id,
|
|
&host_channel_username,
|
|
profile_pic_url,
|
|
msg,
|
|
attachments,
|
|
)
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn dispatch_message(
|
|
ctx: &Context,
|
|
guild: &Guild,
|
|
global_data: &mut GlobalData,
|
|
msg_source: MessageSource,
|
|
msg_dest: MessageDest,
|
|
msg: &str,
|
|
attachments: Option<Vec<AttachmentType<'_>>>,
|
|
) -> error::Result<()> {
|
|
let msg_username = match &msg_source {
|
|
MessageSource::Player(p) => p.codename.clone(),
|
|
MessageSource::Host => "Woxlf".to_string(),
|
|
MessageSource::Automated => "Woxlf System Message".to_string(),
|
|
};
|
|
|
|
let profile_pic = match &msg_source {
|
|
MessageSource::Player(p) => Some(p.profile_pic_url.clone()),
|
|
MessageSource::Host | MessageSource::Automated => {
|
|
Some(global_data.game_cfg()?.bot_profile_pic.clone())
|
|
}
|
|
};
|
|
|
|
let msg_tasks: Vec<&PlayerData> = global_data
|
|
.game_state_mut()?
|
|
.player_data
|
|
.iter()
|
|
.filter(|player| filter_source_channel(player, &msg_source))
|
|
.collect();
|
|
|
|
for player_data in msg_tasks {
|
|
match &msg_dest {
|
|
MessageDest::PlayerChannel(dest_player) => {
|
|
if dest_player.discord_id == player_data.discord_id {
|
|
send_webhook_msg(
|
|
&ctx.http,
|
|
player_data.channel_webhook_id,
|
|
&msg_username,
|
|
profile_pic.clone(),
|
|
msg,
|
|
&attachments,
|
|
)
|
|
.await?;
|
|
}
|
|
}
|
|
MessageDest::PlayerDm(dest_player) => {
|
|
send_private_message(
|
|
&ctx.http,
|
|
&msg_username,
|
|
UserId(dest_player.discord_id),
|
|
msg,
|
|
&attachments,
|
|
)
|
|
.await?
|
|
}
|
|
MessageDest::Broadcast => {
|
|
send_webhook_msg(
|
|
&ctx.http,
|
|
player_data.channel_webhook_id,
|
|
&msg_username,
|
|
profile_pic.clone(),
|
|
msg,
|
|
&attachments,
|
|
)
|
|
.await?
|
|
}
|
|
}
|
|
}
|
|
|
|
send_to_host_channel(
|
|
&ctx.http,
|
|
guild,
|
|
global_data,
|
|
&msg_username,
|
|
msg_source,
|
|
msg_dest,
|
|
profile_pic,
|
|
msg,
|
|
&attachments,
|
|
)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|