Add currently-playing and st granting commands
This commit is contained in:
79
src/main.rs
79
src/main.rs
@@ -1,7 +1,7 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use eyre::{bail, Context as _, Error, OptionExt, Result};
|
use eyre::{bail, Context as _, Error, OptionExt, Result};
|
||||||
use futures::FutureExt;
|
use futures::{FutureExt, TryStreamExt};
|
||||||
use poise::serenity_prelude as serenity;
|
use poise::serenity_prelude as serenity;
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use rusqlite::OptionalExtension;
|
use rusqlite::OptionalExtension;
|
||||||
@@ -13,6 +13,8 @@ struct GuildData {
|
|||||||
guild: serenity::GuildId,
|
guild: serenity::GuildId,
|
||||||
town_square: serenity::ChannelId,
|
town_square: serenity::ChannelId,
|
||||||
cottages: serenity::ChannelId,
|
cottages: serenity::ChannelId,
|
||||||
|
st: serenity::RoleId,
|
||||||
|
currently_playing: serenity::RoleId,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Data(tokio::sync::Mutex<rusqlite::Connection>);
|
struct Data(tokio::sync::Mutex<rusqlite::Connection>);
|
||||||
@@ -20,7 +22,7 @@ struct Data(tokio::sync::Mutex<rusqlite::Connection>);
|
|||||||
impl Data {
|
impl Data {
|
||||||
fn open(path: impl AsRef<Path>) -> Result<Self> {
|
fn open(path: impl AsRef<Path>) -> Result<Self> {
|
||||||
let conn = rusqlite::Connection::open(path)?;
|
let conn = rusqlite::Connection::open(path)?;
|
||||||
conn.execute_batch("CREATE TABLE IF NOT EXISTS guilds(guild TEXT PRIMARY KEY NOT NULL, town_square TEXT NOT NULL, cottages TEXT NOT NULL);")?;
|
conn.execute_batch("CREATE TABLE IF NOT EXISTS guilds(guild TEXT PRIMARY KEY NOT NULL, town_square TEXT NOT NULL, cottages TEXT NOT NULL, st TEXT, currently_playing TEXT);")?;
|
||||||
Ok(Self(tokio::sync::Mutex::new(conn)))
|
Ok(Self(tokio::sync::Mutex::new(conn)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,12 +30,14 @@ impl Data {
|
|||||||
self.0
|
self.0
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.prepare_cached("SELECT guild, town_square, cottages FROM guilds WHERE guild = ?;")?
|
.prepare_cached("SELECT guild, town_square, cottages, st, currently_playing FROM guilds WHERE guild = ?;")?
|
||||||
.query_row(rusqlite::params![guild.to_string()], |row| {
|
.query_row(rusqlite::params![guild.to_string()], |row| {
|
||||||
Ok(GuildData {
|
Ok(GuildData {
|
||||||
guild: row.get_unwrap::<_, String>("guild").parse().unwrap(),
|
guild: row.get_unwrap::<_, String>("guild").parse().unwrap(),
|
||||||
town_square: row.get_unwrap::<_, String>("town_square").parse().unwrap(),
|
town_square: row.get_unwrap::<_, String>("town_square").parse().unwrap(),
|
||||||
cottages: row.get_unwrap::<_, String>("cottages").parse().unwrap(),
|
cottages: row.get_unwrap::<_, String>("cottages").parse().unwrap(),
|
||||||
|
st: row.get_unwrap::<_, String>("st").parse().unwrap(),
|
||||||
|
currently_playing: row.get_unwrap::<_, String>("currently_playing").parse().unwrap(),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.optional()?
|
.optional()?
|
||||||
@@ -46,16 +50,26 @@ impl Data {
|
|||||||
guild,
|
guild,
|
||||||
town_square,
|
town_square,
|
||||||
cottages,
|
cottages,
|
||||||
|
st,
|
||||||
|
currently_playing,
|
||||||
}: GuildData,
|
}: GuildData,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.0
|
self.0
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.prepare_cached("INSERT INTO guilds (guild, town_square, cottages) VALUES (?, ?, ?) ON CONFLICT(guild) DO UPDATE SET town_square = excluded.town_square, cottages = excluded.cottages")?
|
.prepare_cached("INSERT INTO guilds (guild, town_square, cottages, st, currently_playing) VALUES (?, ?, ?, ?, ?)
|
||||||
|
ON CONFLICT(guild) DO UPDATE SET
|
||||||
|
town_square = excluded.town_square,
|
||||||
|
cottages = excluded.cottages,
|
||||||
|
st = excluded.st,
|
||||||
|
currently_playing = excluded.currently_playing;
|
||||||
|
")?
|
||||||
.execute(rusqlite::params![
|
.execute(rusqlite::params![
|
||||||
guild.to_string(),
|
guild.to_string(),
|
||||||
town_square.to_string(),
|
town_square.to_string(),
|
||||||
cottages.to_string()
|
cottages.to_string(),
|
||||||
|
st.to_string(),
|
||||||
|
currently_playing.to_string(),
|
||||||
])?;
|
])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -141,21 +155,68 @@ async fn dawn(ctx: Context<'_>) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[poise::command(slash_command, ephemeral)]
|
||||||
|
async fn st(ctx: Context<'_>, mut spectators: Vec<serenity::UserId>) -> Result<()> {
|
||||||
|
let guild = ctx
|
||||||
|
.guild_id()
|
||||||
|
.ok_or_eyre("This bot only works in servers")?;
|
||||||
|
let GuildData { st, .. } = ctx.data().get(guild).await?;
|
||||||
|
spectators.push(ctx.author().id);
|
||||||
|
|
||||||
|
|
||||||
|
guild
|
||||||
|
.members_iter(&ctx)
|
||||||
|
.try_for_each(|member| {
|
||||||
|
let spectators = &spectators;
|
||||||
|
async move {
|
||||||
|
if spectators.contains(&member.user.id) {
|
||||||
|
member.add_role(&ctx, st).await
|
||||||
|
} else {
|
||||||
|
member.remove_role(&ctx, st).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
ctx.reply(format!("{} members given ST", spectators.len()))
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[poise::command(slash_command, ephemeral)]
|
||||||
|
async fn currently_playing(ctx: Context<'_>, players: Vec<serenity::UserId>) -> Result<()> {
|
||||||
|
let guild = ctx.guild_id().ok_or_eyre("This bot only works in servers")?;
|
||||||
|
let GuildData { currently_playing, .. } = ctx.data().get(guild).await?;
|
||||||
|
for player in &players {
|
||||||
|
guild.member(&ctx, player).await?.add_role(&ctx, currently_playing).await?;
|
||||||
|
}
|
||||||
|
ctx.reply(format!("Given {} members currently playing", players.len())).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[poise::command(slash_command, prefix_command, ephemeral)]
|
#[poise::command(slash_command, prefix_command, ephemeral)]
|
||||||
async fn configure(
|
async fn configure(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
#[channel_types("Voice")] town_square: serenity::ChannelId,
|
#[channel_types("Voice")] town_square: serenity::ChannelId,
|
||||||
#[channel_types("Category")] cottages: serenity::ChannelId,
|
#[channel_types("Category")] cottages: serenity::ChannelId,
|
||||||
|
st: serenity::RoleId,
|
||||||
|
currently_playing: serenity::RoleId
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let guild = ctx
|
let guild = ctx
|
||||||
.guild_id()
|
.guild_id()
|
||||||
.ok_or_eyre("This bot only works in servers")?;
|
.ok_or_eyre("This bot only works in servers")?;
|
||||||
|
|
||||||
ctx.data().insert(GuildData {
|
ctx.data()
|
||||||
|
.insert(GuildData {
|
||||||
guild,
|
guild,
|
||||||
town_square,
|
town_square,
|
||||||
cottages,
|
cottages,
|
||||||
}).await?;
|
st,
|
||||||
|
currently_playing,
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
ctx.reply("Configured successfully!").await?;
|
ctx.reply("Configured successfully!").await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -189,11 +250,11 @@ async fn main() -> Result<()> {
|
|||||||
)
|
)
|
||||||
.wrap_err("A Discord token is required")?;
|
.wrap_err("A Discord token is required")?;
|
||||||
let dbfile = std::env::var_os("DB_FILE").ok_or_eyre("A database file is required")?;
|
let dbfile = std::env::var_os("DB_FILE").ok_or_eyre("A database file is required")?;
|
||||||
let intents = serenity::GatewayIntents::non_privileged();
|
let intents = serenity::GatewayIntents::non_privileged() | serenity::GatewayIntents::GUILD_MEMBERS;
|
||||||
|
|
||||||
let framework = poise::Framework::builder()
|
let framework = poise::Framework::builder()
|
||||||
.options(poise::FrameworkOptions {
|
.options(poise::FrameworkOptions {
|
||||||
commands: vec![dusk(), dawn(), configure()],
|
commands: vec![dusk(), dawn(), st(), currently_playing(), configure()],
|
||||||
event_handler: |ctx, ev, ctxf, data| on_event(ctx, ev, ctxf, data).boxed(),
|
event_handler: |ctx, ev, ctxf, data| on_event(ctx, ev, ctxf, data).boxed(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user