Update formatting

This commit is contained in:
Em (Ethan) Ruszanowski 2023-01-21 19:49:39 -05:00
parent b349263fd0
commit c3a98c4431
No known key found for this signature in database
GPG key ID: C3E7A3C0B1491DFE
3 changed files with 100 additions and 71 deletions

View file

@ -1,5 +1,5 @@
use crate::{Context, Error};
use crate::serenity; use crate::serenity;
use crate::{Context, Error};
use rand::seq::IteratorRandom; use rand::seq::IteratorRandom;
use std::{ use std::{
fs::File, fs::File,
@ -8,22 +8,21 @@ use std::{
/// Basically a ping command /// Basically a ping command
#[poise::command(slash_command)] #[poise::command(slash_command)]
pub(crate) async fn slur( pub(crate) async fn slur(ctx: Context<'_>) -> Result<(), Error> {
ctx: Context<'_>, let file = File::open("quotes.txt").unwrap_or_else(|_e| panic!("Quote file missing.")); // Open the quotes file
) -> Result<(), Error> {
let file = File::open("quotes.txt")
.unwrap_or_else(|_e| panic!("Quote file missing.")); // Open the quotes file
let file = BufReader::new(file); // Read the quotes file let file = BufReader::new(file); // Read the quotes file
let quotes = file.lines() let quotes = file.lines().map(|res| res.expect("Failed to read line."));
.map(|res| res.expect("Failed to read line.")); let quote = quotes
let quote = quotes.choose(&mut rand::thread_rng()) .choose(&mut rand::thread_rng())
.expect("No lines in file."); // Pick a random quote .expect("No lines in file."); // Pick a random quote
ctx.send(|f| f ctx.send(|f| {
.embed(|f| f f.embed(|f| {
.title("DMBrandon Sez:") f.title("DMBrandon Sez:")
.description(format!("\"{}\"", quote)) .description(format!("\"{}\"", quote))
.color(serenity::Colour::GOLD) .color(serenity::Colour::GOLD)
)).await?; // Send embed with team picks })
})
.await?; // Send embed with team picks
Ok(()) Ok(())
} }

View file

@ -4,12 +4,16 @@ use std::string::String;
use poise::serenity_prelude::{Guild, Member, UserId, VoiceState}; use poise::serenity_prelude::{Guild, Member, UserId, VoiceState};
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use crate::{Context, Error};
use crate::serenity; use crate::serenity;
use crate::{Context, Error};
/// Return a string of pingable IDs from a slice of string UserIds /// Return a string of pingable IDs from a slice of string UserIds
fn team_to_ping(team: &[&String]) -> String { fn team_to_ping(team: &[&String]) -> String {
return team.iter().map(|o| format!("<@{}>", o)).collect::<Vec<String>>().join(", "); return team
.iter()
.map(|o| format!("<@{}>", o))
.collect::<Vec<String>>()
.join(", ");
} }
/// Splits up players for custom matches /// Splits up players for custom matches
@ -18,76 +22,101 @@ pub(crate) async fn team(
ctx: Context<'_>, ctx: Context<'_>,
#[description = "Your order voice channel"] #[description = "Your order voice channel"]
#[rename = "order"] #[rename = "order"]
#[channel_types("Voice")] order_channel: serenity::Channel, // Channel to pick all members from #[channel_types("Voice")]
order_channel: serenity::Channel, // Channel to pick all members from
#[description = "Your chaos voice channel"] #[description = "Your chaos voice channel"]
#[rename = "chaos"] #[rename = "chaos"]
#[channel_types("Voice")] chaos_channel: serenity::Channel, // Channel to move chaos team members into #[channel_types("Voice")]
chaos_channel: serenity::Channel, // Channel to move chaos team members into
#[description = "Team size"] #[description = "Team size"]
#[min = 1] size: u8, // Number of members on each team #[min = 1]
size: u8, // Number of members on each team
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut voice_states: HashMap<UserId, VoiceState> = ctx.guild().unwrap().voice_states; // Get hashmap of users' voice states within the guild let mut voice_states: HashMap<UserId, VoiceState> = ctx.guild().unwrap().voice_states; // Get hashmap of users' voice states within the guild
voice_states.retain(|_, state: &mut VoiceState| state.channel_id == Some(order_channel.id())); // Drop users not active in requested voice channel from hashmap voice_states.retain(|_, state: &mut VoiceState| state.channel_id == Some(order_channel.id())); // Drop users not active in requested voice channel from hashmap
if voice_states.keys().len() < size as usize * 2 { // Make sure there are enough members in the voice channel if voice_states.keys().len() < size as usize * 2 {
ctx.send(|f| f // Make sure there are enough members in the voice channel
.embed(|f| f ctx.send(|f| {
.title(format!("Custom {}v{} Teams", size, size)) f.embed(|f| {
f.title(format!("Custom {}v{} Teams", size, size))
.description("You don't have enough friends for that, idiot.") .description("You don't have enough friends for that, idiot.")
.color(serenity::Colour::RED) .color(serenity::Colour::RED)
)).await?; // Insult the user for not having enough friends })
})
.await?; // Insult the user for not having enough friends
return Ok(()); // Break out early if there are not enough members return Ok(()); // Break out early if there are not enough members
} }
let uuid_team: u64 = ctx.id(); // Grab context ID for action row let uuid_team: u64 = ctx.id(); // Grab context ID for action row
let users: Vec<String> = Vec::from_iter(voice_states.keys().map(|u| u.to_string())); // Get vec of PIDs let users: Vec<String> = Vec::from_iter(voice_states.keys().map(|u| u.to_string())); // Get vec of PIDs
let players: Vec<&String> = users.choose_multiple(&mut rand::thread_rng(), size as usize * 2).collect(); // Pick players randomly into slice let players: Vec<&String> = users
.choose_multiple(&mut rand::thread_rng(), size as usize * 2)
.collect(); // Pick players randomly into slice
let (order, chaos) = players.split_at(players.len() / 2); // Split slice into two teams let (order, chaos) = players.split_at(players.len() / 2); // Split slice into two teams
ctx.send(|f| f ctx.send(|f| {
.embed(|f| f f.embed(|f| {
.title(format!("Custom {}v{} Teams", size, size)) f.title(format!("Custom {}v{} Teams", size, size))
.description("VER") .description("VER")
.field("Order", team_to_ping(order), false) .field("Order", team_to_ping(order), false)
.field("Chaos", team_to_ping(chaos), false) .field("Chaos", team_to_ping(chaos), false)
.color(serenity::Colour::DARK_GREEN) .color(serenity::Colour::DARK_GREEN)
).components(|c| c // Create an action row with button })
.create_action_row(|a| a .components(|c| {
.create_button(|b| b c // Create an action row with button
.style(serenity::ButtonStyle::Primary) .create_action_row(|a| {
a.create_button(
|b| {
b.style(serenity::ButtonStyle::Primary)
.label("Swap Channels") .label("Swap Channels")
.custom_id(uuid_team) // Use the context ID as button ID .custom_id(uuid_team)
}, // Use the context ID as button ID
) )
) })
)).await?; // Send embed with team picks })
})
.await?; // Send embed with team picks
while let Some(mci) = serenity::CollectComponentInteraction::new(ctx) // Handle the interaction while let Some(mci) = serenity::CollectComponentInteraction::new(ctx) // Handle the interaction
.await { .await
{
let guild: Guild = ctx.guild().unwrap(); // Grab guild from context let guild: Guild = ctx.guild().unwrap(); // Grab guild from context
for user in chaos { for user in chaos {
let member: Member = guild.member(ctx, UserId(user.parse().unwrap())).await?; // Get the member in the correct guild let member: Member = guild.member(ctx, UserId(user.parse().unwrap())).await?; // Get the member in the correct guild
member.move_to_voice_channel(ctx, chaos_channel.id()).await?; // Move the member to the correct voice channel member
.move_to_voice_channel(ctx, chaos_channel.id())
.await?; // Move the member to the correct voice channel
} }
mci.create_interaction_response(ctx, |ir| { // Edit embed mci.create_interaction_response(ctx, |ir| {
// Edit embed
ir.kind(serenity::InteractionResponseType::UpdateMessage) ir.kind(serenity::InteractionResponseType::UpdateMessage)
.interaction_response_data(|f| f .interaction_response_data(|f| {
.embed(|f| f f.embed(|f| {
.title(format!("Custom {}v{} Teams", size, size)) f.title(format!("Custom {}v{} Teams", size, size))
.description("VVGO VVW VVX") .description("VVGO VVW VVX")
.field("Order", team_to_ping(order), false) .field("Order", team_to_ping(order), false)
.field("Chaos", team_to_ping(chaos), false) .field("Chaos", team_to_ping(chaos), false)
.color(serenity::Colour::DARK_GREEN) .color(serenity::Colour::DARK_GREEN)
).components(|c| c // Create an action row with button })
.create_action_row(|a| a .components(|c| {
.create_button(|b| b c // Create an action row with button
.create_action_row(|a| {
a.create_button(
|b| {
b
.disabled(true) // with disabled button .disabled(true) // with disabled button
.style(serenity::ButtonStyle::Primary) .style(serenity::ButtonStyle::Primary)
.label("Quit Sibelius") // and new text .label("Quit Sibelius") // and new text
.custom_id(uuid_team) // Use the context ID as button ID .custom_id(uuid_team)
}, // Use the context ID as button ID
) )
) })
)) })
}).await?; })
})
.await?;
} }
Ok(()) Ok(())
} }

View file

@ -11,23 +11,24 @@ type Context<'a> = poise::Context<'a, Data, Error>;
async fn main() { async fn main() {
let framework = poise::Framework::builder() let framework = poise::Framework::builder()
.options(poise::FrameworkOptions { .options(poise::FrameworkOptions {
commands: vec![ commands: vec![commands::slur::slur(), commands::team::team()], // IntelliJ doesn't like this, but it's fine.
commands::slur::slur(),
commands::team::team(),
], // IntelliJ doesn't like this, but it's fine.
..Default::default() ..Default::default()
}) })
.token(std::env::var("DISCORD_TOKEN") .token(std::env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN"))
.expect("Missing DISCORD_TOKEN"))
.intents(serenity::GatewayIntents::non_privileged()) // Set intents for Discord dev portal .intents(serenity::GatewayIntents::non_privileged()) // Set intents for Discord dev portal
.setup(|ctx, _ready, framework| { .setup(|ctx, _ready, framework| {
Box::pin(async move { Box::pin(async move {
poise::builtins::register_in_guild( poise::builtins::register_in_guild(
ctx, ctx,
&framework.options().commands, &framework.options().commands,
serenity::GuildId(std::env::var("GUILD_ID") serenity::GuildId(
std::env::var("GUILD_ID")
.expect("Missing GUILD_ID") // Get GID from env and parse .expect("Missing GUILD_ID") // Get GID from env and parse
.parse::<u64>().unwrap())).await?; // Update slash commands in GID .parse::<u64>()
.unwrap(),
),
)
.await?; // Update slash commands in GID
Ok(Data {}) Ok(Data {})
}) })
}); });