187 lines
5.6 KiB
Rust
187 lines
5.6 KiB
Rust
use crate::data::{BotConfig, GlobalData, MessageSource, PlayerData};
|
|
use crate::helper::{clear_game_state, save_game_state, send_msg_to_player_channels};
|
|
use rand::Rng;
|
|
use serenity::framework::standard::macros::{command, group};
|
|
use serenity::framework::standard::{Args, CommandResult};
|
|
use serenity::framework::StandardFramework;
|
|
use serenity::model::channel::{PermissionOverwrite, PermissionOverwriteType};
|
|
use serenity::model::guild::{Guild, Member};
|
|
use serenity::model::id::ChannelId;
|
|
use serenity::model::prelude::{Message, UserId};
|
|
use serenity::model::Permissions;
|
|
use serenity::prelude::Context;
|
|
use serenity::utils::MessageBuilder;
|
|
|
|
#[group]
|
|
#[commands(start, say, end, broadcast)]
|
|
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,
|
|
) -> CommandResult {
|
|
let mut codename = generate_codename(&global_data.cfg);
|
|
|
|
while global_data.game_state.codename_exists(&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?;
|
|
|
|
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?;
|
|
|
|
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?;
|
|
|
|
channel.pin(&ctx.http, msg.id).await?;
|
|
|
|
let player_data = PlayerData {
|
|
channel: channel.id.0,
|
|
discord_id: discord_user.user.id.0,
|
|
codename,
|
|
};
|
|
|
|
global_data.game_state.player_data.push(player_data);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[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;
|
|
|
|
clear_game_state(&mut global_data).unwrap();
|
|
|
|
for player in args.iter::<u64>().flatten() {
|
|
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?;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
save_game_state(&global_data).unwrap();
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
#[only_in(guilds)]
|
|
#[allowed_roles("wolfx host")]
|
|
async fn end(ctx: &Context, msg: &Message, mut _args: Args) -> CommandResult {
|
|
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;
|
|
|
|
for player_data in &global_data.game_state.player_data {
|
|
let channel = guild
|
|
.channels
|
|
.get(&ChannelId::from(player_data.channel))
|
|
.unwrap();
|
|
|
|
channel.delete(&ctx.http).await?;
|
|
}
|
|
|
|
clear_game_state(&mut global_data).unwrap();
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
#[only_in(guilds)]
|
|
#[allowed_roles("wolfx host")]
|
|
async fn say(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
let data = ctx.data.read().await;
|
|
let global_data = data.get::<GlobalData>().unwrap();
|
|
let guild = msg.guild(&ctx.cache).await.unwrap();
|
|
|
|
let global_data = global_data.lock().await;
|
|
|
|
let msg = format!("**wOxlf **> {}", args.rest());
|
|
|
|
send_msg_to_player_channels(ctx, &guild, &global_data, MessageSource::Host, &msg, false).await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
#[only_in(guilds)]
|
|
#[allowed_roles("wolfx host")]
|
|
async fn broadcast(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
let data = ctx.data.read().await;
|
|
let global_data = data.get::<GlobalData>().unwrap();
|
|
let guild = msg.guild(&ctx.cache).await.unwrap();
|
|
|
|
let global_data = global_data.lock().await;
|
|
|
|
let msg = MessageBuilder::new()
|
|
.push_bold_line("\\*\\*IMPORTANT wOxlf SYSTEM MESSAGE\\*\\*")
|
|
.push_line("")
|
|
.push_line(args.rest())
|
|
.push_line("")
|
|
.push_bold_line("\\*\\*END OF SYSTEM MESSAGE\\*\\*")
|
|
.build();
|
|
|
|
send_msg_to_player_channels(ctx, &guild, &global_data, MessageSource::Host, &msg, true).await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn command_framework() -> StandardFramework {
|
|
StandardFramework::new()
|
|
.configure(|c| c.prefix("!"))
|
|
.group(&HOST_GROUP)
|
|
}
|