Add support for extras, conditionally displaying commands in the help command, and start working on moderation commands
This commit is contained in:
@@ -1,24 +1,16 @@
|
||||
use async_trait::async_trait;
|
||||
|
||||
use crate::{
|
||||
constants::DEFAULT_PREFIX,
|
||||
database::models::Server,
|
||||
discord::sanitizing::SanitizeDiscordMarkdown,
|
||||
framework::commands::{
|
||||
Command, CommandError,
|
||||
arguments::{Argument, GreedyString, ParseArguments},
|
||||
context::CommandContext,
|
||||
permissions::Permission,
|
||||
},
|
||||
groups::servers::permissions::{GuildOnlyPermission, ServerModeratorPermission},
|
||||
state::State,
|
||||
constants::DEFAULT_PREFIX, database::models::Server, discord::sanitizing::SanitizeDiscordMarkdown, extras::Extras, framework::commands::{
|
||||
arguments::{Arg, Argument, GreedyString, ParseArguments}, context::CommandContext, permissions::Permission, Command, CommandError
|
||||
}, groups::servers::permissions::{GuildOnlyPermission, ServerModeratorPermission}, state::State
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrefixCommand;
|
||||
|
||||
#[async_trait]
|
||||
impl Command<State> for PrefixCommand {
|
||||
impl Command<State, Extras> for PrefixCommand {
|
||||
fn name(&self) -> &'static str {
|
||||
"prefix"
|
||||
}
|
||||
@@ -39,7 +31,7 @@ impl Command<State> for PrefixCommand {
|
||||
}]
|
||||
}
|
||||
|
||||
fn permissions(&self) -> Vec<Box<dyn Permission<State> + Send + Sync + 'static>> {
|
||||
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
|
||||
vec![
|
||||
Box::new(GuildOnlyPermission),
|
||||
Box::new(ServerModeratorPermission),
|
||||
@@ -48,10 +40,10 @@ impl Command<State> for PrefixCommand {
|
||||
|
||||
async fn execute(
|
||||
&self,
|
||||
ctx: CommandContext<'_, State>,
|
||||
ctx: CommandContext<'_, State, Extras>,
|
||||
args: &str,
|
||||
) -> Result<(), CommandError> {
|
||||
let prefix: GreedyString = ParseArguments::parse(args).unwrap();
|
||||
let Arg(prefix) = Arg::<GreedyString>::parse(args, &ctx).await.unwrap();
|
||||
let mut prefix = prefix.trim();
|
||||
|
||||
let mut server = Server::get_or_create_by_id(
|
||||
@@ -64,7 +56,7 @@ impl Command<State> for PrefixCommand {
|
||||
)
|
||||
.await
|
||||
.inspect_err(|e| log::error!("Failed to get or create server: {e}"))
|
||||
.map_err(|_| CommandError::DatabaseQueryFailed)?;
|
||||
.map_err(|_| CommandError::DatabaseFailed)?;
|
||||
|
||||
if prefix.is_empty() {
|
||||
prefix = DEFAULT_PREFIX;
|
||||
@@ -74,7 +66,7 @@ impl Command<State> for PrefixCommand {
|
||||
server
|
||||
.upsert(&ctx.rt.state.db)
|
||||
.await
|
||||
.map_err(|_| CommandError::DatabaseQueryFailed)?;
|
||||
.map_err(|_| CommandError::DatabaseFailed)?;
|
||||
|
||||
ctx.send()
|
||||
.content(format!(
|
||||
|
||||
@@ -7,6 +7,7 @@ use twilight_model::gateway::payload::incoming::{GuildCreate, GuildDelete, Guild
|
||||
|
||||
use crate::{
|
||||
database::models::Server,
|
||||
extras::Extras,
|
||||
framework::{
|
||||
events::traits::{
|
||||
EventResult, OnServerCreateHandler, OnServerDeleteHandler, OnServerUpdateHandler,
|
||||
@@ -21,8 +22,12 @@ use crate::{
|
||||
pub struct ServerCreateHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl OnServerCreateHandler<State> for ServerCreateHandler {
|
||||
async fn on_server_create(&self, event: &GuildCreate, rt: Arc<Runtime<State>>) -> EventResult {
|
||||
impl OnServerCreateHandler<State, Extras> for ServerCreateHandler {
|
||||
async fn on_server_create(
|
||||
&self,
|
||||
event: &GuildCreate,
|
||||
rt: Arc<Runtime<State, Extras>>,
|
||||
) -> EventResult {
|
||||
let server = match event {
|
||||
GuildCreate::Available(guild) => Server::from(guild.clone()),
|
||||
GuildCreate::Unavailable(_) => {
|
||||
@@ -51,8 +56,12 @@ impl OnServerCreateHandler<State> for ServerCreateHandler {
|
||||
pub struct ServerUpdateHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl OnServerUpdateHandler<State> for ServerUpdateHandler {
|
||||
async fn on_server_update(&self, event: &GuildUpdate, rt: Arc<Runtime<State>>) -> EventResult {
|
||||
impl OnServerUpdateHandler<State, Extras> for ServerUpdateHandler {
|
||||
async fn on_server_update(
|
||||
&self,
|
||||
event: &GuildUpdate,
|
||||
rt: Arc<Runtime<State, Extras>>,
|
||||
) -> EventResult {
|
||||
let mut server = match Server::get_by_id(event.0.id.get(), &rt.state.db)
|
||||
.await
|
||||
.inspect_err(|e| {
|
||||
@@ -83,8 +92,12 @@ impl OnServerUpdateHandler<State> for ServerUpdateHandler {
|
||||
pub struct ServerDeleteHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl OnServerDeleteHandler<State> for ServerDeleteHandler {
|
||||
async fn on_server_delete(&self, event: &GuildDelete, rt: Arc<Runtime<State>>) -> EventResult {
|
||||
impl OnServerDeleteHandler<State, Extras> for ServerDeleteHandler {
|
||||
async fn on_server_delete(
|
||||
&self,
|
||||
event: &GuildDelete,
|
||||
rt: Arc<Runtime<State, Extras>>,
|
||||
) -> EventResult {
|
||||
Server::delete_by_id(event.id.get(), &rt.state.db)
|
||||
.await
|
||||
.inspect(|_| log::debug!("Deleted server with ID {} because Payphone left", event.id))
|
||||
|
||||
@@ -6,6 +6,7 @@ use twilight_model::{
|
||||
use twilight_util::permission_calculator::PermissionCalculator;
|
||||
|
||||
use crate::{
|
||||
extras::Extras,
|
||||
framework::commands::{CommandError, context::CommandContext, permissions::Permission},
|
||||
state::State,
|
||||
};
|
||||
@@ -14,12 +15,15 @@ use crate::{
|
||||
pub struct GuildOnlyPermission;
|
||||
|
||||
#[async_trait]
|
||||
impl Permission<State> for GuildOnlyPermission {
|
||||
async fn check(&self, ctx: &CommandContext<State>) -> Result<bool, CommandError> {
|
||||
impl Permission<State, Extras> for GuildOnlyPermission {
|
||||
async fn check(&self, ctx: &CommandContext<State, Extras>) -> Result<bool, CommandError> {
|
||||
Ok(ctx.event.guild_id.is_some())
|
||||
}
|
||||
|
||||
async fn on_handle_denied(&self, ctx: &CommandContext<State>) -> Result<(), CommandError> {
|
||||
async fn on_handle_denied(
|
||||
&self,
|
||||
ctx: &CommandContext<State, Extras>,
|
||||
) -> Result<(), CommandError> {
|
||||
ctx.send()
|
||||
.content("❌ This command can only be used in a server.")
|
||||
.await?;
|
||||
@@ -32,8 +36,8 @@ impl Permission<State> for GuildOnlyPermission {
|
||||
pub struct ServerModeratorPermission;
|
||||
|
||||
#[async_trait]
|
||||
impl Permission<State> for ServerModeratorPermission {
|
||||
async fn check(&self, ctx: &CommandContext<State>) -> Result<bool, CommandError> {
|
||||
impl Permission<State, Extras> for ServerModeratorPermission {
|
||||
async fn check(&self, ctx: &CommandContext<State, Extras>) -> Result<bool, CommandError> {
|
||||
if let Some(guild_id) = ctx.event.guild_id {
|
||||
let Some(guild) = ctx.rt.cache.guild(guild_id) else {
|
||||
log::warn!("Could not get guild for ID {guild_id}!");
|
||||
@@ -76,14 +80,19 @@ impl Permission<State> for ServerModeratorPermission {
|
||||
)
|
||||
.owner_id(guild.owner_id());
|
||||
|
||||
return Ok(calculator.root().contains(Permissions::MANAGE_CHANNELS | Permissions::MANAGE_MESSAGES));
|
||||
return Ok(calculator
|
||||
.root()
|
||||
.contains(Permissions::MANAGE_CHANNELS | Permissions::MANAGE_MESSAGES));
|
||||
}
|
||||
|
||||
// DMs channel, the user has all permissions.
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
async fn on_handle_denied(&self, ctx: &CommandContext<State>) -> Result<(), CommandError> {
|
||||
async fn on_handle_denied(
|
||||
&self,
|
||||
ctx: &CommandContext<State, Extras>,
|
||||
) -> Result<(), CommandError> {
|
||||
ctx.send()
|
||||
.content("❌ This command can only be run by a server moderator.\n-# 🛈 Moderators must have permission to manage messages and to manage channels.")
|
||||
.await?;
|
||||
|
||||
Reference in New Issue
Block a user