wOxlf/src/commands.rs

111 lines
3.6 KiB
Rust

use serenity::prelude::Context;
use serenity::model::prelude::{Message, UserId};
use serenity::framework::standard::{CommandResult, Args};
use serenity::framework::StandardFramework;
use serenity::framework::standard::macros::{command, group};
use crate::data::{GlobalData, BotConfig, PlayerData};
use rand::Rng;
use serenity::model::guild::{Member, Guild};
use serenity::model::id::ChannelId;
use serenity::model::Permissions;
use serenity::model::channel::{PermissionOverwrite, PermissionOverwriteType};
use serenity::utils::MessageBuilder;
#[group]
#[commands(start)]
struct Host;
fn generate_codename(config: &BotConfig) -> String {
let mut rng = rand::thread_rng();
let occupation = &config.occupation[rng.gen_range(0..config.occupation.len())];
let adj = &config.adjective[rng.gen_range(0..config.adjective.len())];
format!("{} {}", adj, occupation)
}
async fn add_user_to_game(ctx: &Context, guild: &Guild, global_data: &mut GlobalData, discord_user: &Member) {
let mut codename = generate_codename(&global_data.cfg);
while global_data.game_state.codename_exists(&mut codename) {
codename = 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.unwrap();
let allow = Permissions::SEND_MESSAGES | Permissions::READ_MESSAGE_HISTORY | Permissions::READ_MESSAGE_HISTORY;
let overwrite = PermissionOverwrite {
allow,
deny: Default::default(),
kind: PermissionOverwriteType::Member(discord_user.user.id),
};
channel.create_permission(&ctx.http, &overwrite).await.unwrap();
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("SUBJECT CODENAME: ")
.push_line(&codename)
)
}).await.unwrap();
channel.pin(&ctx.http, msg.id).await.unwrap();
let player_data = PlayerData {
discord_id: discord_user.user.id.0,
codename: codename
};
global_data.game_state.player_channels.insert(channel.id.0, player_data);
}
#[command]
#[only_in(guilds)]
#[allowed_roles("wolfx host")]
async fn start(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
msg.channel_id.say(&ctx.http, "Starting game").await?;
let mut data = ctx.data.write().await;
let global_data = data.get_mut::<GlobalData>().unwrap();
let guild = msg.guild(&ctx.cache).await.unwrap();
let mut global_data = global_data.lock().await;
global_data.game_state.clear();
for player in args.iter::<u64>() {
if let Ok(player) = player {
if let Some(discord_user) = guild.members.get(&UserId::from(player)) {
add_user_to_game(ctx, &guild, &mut global_data, &discord_user).await;
}
else {
msg.reply(&ctx.http,format!("User {} is invalid or not in this server!", player)).await.unwrap();
break;
}
}
}
Ok(())
}
pub fn command_framework() -> StandardFramework {
StandardFramework::new()
.configure(|c| {
c.prefix("!")
})
.group(&HOST_GROUP)
}