wOxlf/src/discord/helper.rs

170 lines
4.9 KiB
Rust

use serenity::client::Context;
use serenity::framework::standard::Args;
use serenity::http::AttachmentType;
use serenity::model::channel::{PermissionOverwrite, PermissionOverwriteType};
use serenity::model::guild::{Guild, Member};
use serenity::model::id::{ChannelId, UserId};
use serenity::model::Permissions;
use serenity::utils::MessageBuilder;
use crate::error::WoxlfError;
use crate::game::game_state::PhaseDuration;
use crate::game::global_data::GlobalData;
use crate::game::player_data::PlayerData;
use crate::game::MessageSource;
use crate::{error, game};
pub async fn send_msg_to_player_channels(
ctx: &Context,
guild: &Guild,
global_data: &mut GlobalData,
msg_source: MessageSource,
msg: &str,
attachment: Option<Vec<AttachmentType<'_>>>,
pin: bool,
) -> error::Result<()> {
for player_data in &global_data.game_state_mut()?.player_data {
if let MessageSource::Player(channel_id) = msg_source {
if channel_id == player_data.channel {
continue;
}
}
let channel = guild
.channels
.get(&ChannelId::from(player_data.channel))
.unwrap();
let msg = channel
.send_message(&ctx.http, |m| {
m.content(&msg);
if let Some(attachment) = attachment.clone() {
m.add_files(attachment);
}
m
})
.await?;
if pin {
// pin system messages
msg.pin(&ctx.http).await?;
}
}
let host_channel = guild
.channels
.get(&ChannelId::from(global_data.cfg.host_channel))
.unwrap();
let source = match msg_source {
MessageSource::Player(channel_id) => {
let discord_id = global_data
.game_state_mut()?
.get_player_from_channel(channel_id)
.unwrap()
.discord_id;
let name = guild
.members
.get(&UserId::from(discord_id))
.unwrap()
.display_name();
name.to_string()
}
MessageSource::Host => "Host".to_string(),
MessageSource::Automated => "Automated".to_string(),
};
host_channel
.send_message(&ctx.http, |m| {
m.content(format!("({}): {}", source, msg));
if let Some(attachment) = attachment {
m.add_files(attachment);
}
m
})
.await?;
Ok(())
}
pub async fn add_user_to_game(
ctx: &Context,
guild: &Guild,
global_data: &mut GlobalData,
discord_user: &Member,
) -> error::Result<()> {
let mut codename = game::generate_codename(&global_data.cfg);
while global_data.game_state_mut()?.codename_exists(&codename) {
codename = game::generate_codename(&global_data.cfg);
}
let channel = guild
.create_channel(&ctx.http, |c| {
c.category(&ChannelId::from(global_data.cfg.category))
.name(format!("{}'s Channel", discord_user.display_name()))
})
.await?;
let allow =
Permissions::SEND_MESSAGES | Permissions::READ_MESSAGE_HISTORY | Permissions::READ_MESSAGES;
let overwrite = PermissionOverwrite {
allow,
deny: Default::default(),
kind: PermissionOverwriteType::Member(discord_user.user.id),
};
channel.create_permission(&ctx.http, &overwrite).await?;
let msg = channel.send_message(&ctx.http, |m| {
m.content(MessageBuilder::new()
.push("Welcome ")
.mention(discord_user)
.push_line(" to your WOxlf Terminal. You may use this terminal to communicate to other subjects.")
.push_line("You will also use this terminal for choosing one of your fellow subjects for termination.")
.push_line("Happy testing :)")
.push_line("")
.push_line("Do $help to see all commands.")
.push_line("")
.push("SUBJECT CODENAME: ")
.push_line(&codename)
.push(global_data.print_game_status())
)
}).await?;
channel.pin(&ctx.http, msg.id).await?;
let player_data = PlayerData {
channel: channel.id.0,
discord_id: discord_user.user.id.0,
vote_target: None,
codename,
};
global_data.game_state_mut()?.player_data.push(player_data);
Ok(())
}
pub fn build_system_message(msg: &str) -> String {
MessageBuilder::new()
.push_bold_line("\\*\\*IMPORTANT wOxlf SYSTEM MESSAGE\\*\\*")
.push_line("")
.push_line(msg)
.push_line("")
.push_bold_line("\\*\\*END OF SYSTEM MESSAGE\\*\\*")
.build()
}
pub async fn parse_duration_arg(args: &mut Args) -> error::Result<PhaseDuration> {
match args.single::<PhaseDuration>() {
Ok(d) => Ok(d),
Err(_) => Err(WoxlfError::DurationParseError),
}
}