SupportChild/SupportChild/EventHandler.cs

275 lines
8.4 KiB
C#
Raw Normal View History

2022-02-21 08:40:09 +00:00
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.Exceptions;
2022-08-21 07:33:27 +00:00
using DSharpPlus.SlashCommands;
using DSharpPlus.SlashCommands.Attributes;
using DSharpPlus.SlashCommands.EventArgs;
using SupportChild.Commands;
2022-02-21 08:40:09 +00:00
2022-08-21 07:33:27 +00:00
namespace SupportChild;
internal static class EventHandler
2022-02-21 08:40:09 +00:00
{
2022-08-21 07:33:27 +00:00
internal static Task OnReady(DiscordClient client, ReadyEventArgs e)
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
Logger.Log("Client is ready to process events.");
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
// Checking activity type
if (!Enum.TryParse(Config.presenceType, true, out ActivityType activityType))
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
Logger.Log("Presence type '" + Config.presenceType + "' invalid, using 'Playing' instead.");
activityType = ActivityType.Playing;
2022-05-17 13:09:25 +00:00
}
2022-08-21 07:33:27 +00:00
client.UpdateStatusAsync(new DiscordActivity(Config.presenceText, activityType), UserStatus.Online);
return Task.CompletedTask;
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
internal static Task OnGuildAvailable(DiscordClient _, GuildCreateEventArgs e)
{
Logger.Log("Guild available: " + e.Guild.Name);
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
IReadOnlyDictionary<ulong, DiscordRole> roles = e.Guild.Roles;
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
foreach ((ulong roleID, DiscordRole role) in roles)
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
Logger.Log(role.Name.PadRight(40, '.') + roleID);
2022-05-17 13:09:25 +00:00
}
2022-08-21 07:33:27 +00:00
return Task.CompletedTask;
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
internal static Task OnClientError(DiscordClient _, ClientErrorEventArgs e)
{
Logger.Error("Client exception occured:\n" + e.Exception);
switch (e.Exception)
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
case BadRequestException ex:
Logger.Error("JSON Message: " + ex.JsonMessage);
break;
2022-05-17 13:09:25 +00:00
}
2022-08-21 07:33:27 +00:00
return Task.CompletedTask;
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
internal static async Task OnMessageCreated(DiscordClient client, MessageCreateEventArgs e)
{
if (e.Author.IsBot)
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
return;
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
// Check if ticket exists in the database and ticket notifications are enabled
if (!Database.TryGetOpenTicket(e.Channel.Id, out Database.Ticket ticket) || !Config.ticketUpdatedNotifications)
{
return;
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
// Sends a DM to the assigned staff member if at least a day has gone by since the last message and the user sending the message isn't staff
IReadOnlyList<DiscordMessage> messages = await e.Channel.GetMessagesAsync(2);
if (messages.Count > 1 && messages[1].Timestamp < DateTimeOffset.UtcNow.AddDays(Config.ticketUpdatedNotificationDelay * -1) && !Database.IsStaff(e.Author.Id))
{
try
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
DiscordMember staffMember = await e.Guild.GetMemberAsync(ticket.assignedStaffID);
await staffMember.SendMessageAsync(new DiscordEmbedBuilder
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
Color = DiscordColor.Green,
Description = "A ticket you are assigned to has been updated: " + e.Channel.Mention
});
2022-05-17 13:09:25 +00:00
}
2022-08-21 07:33:27 +00:00
catch (NotFoundException) { }
catch (UnauthorizedException) { }
2022-05-17 13:09:25 +00:00
}
2022-08-21 07:33:27 +00:00
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
internal static async Task OnCommandError(SlashCommandsExtension commandSystem, SlashCommandErrorEventArgs e)
{
switch (e.Exception)
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
case SlashExecutionChecksFailedException checksFailedException:
{
foreach (SlashCheckBaseAttribute attr in checksFailedException.FailedChecks)
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
await e.Context.Channel.SendMessageAsync(new DiscordEmbedBuilder
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
Color = DiscordColor.Red,
Description = ParseFailedCheck(attr)
});
2022-05-17 13:09:25 +00:00
}
2022-08-21 07:33:27 +00:00
return;
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
case BadRequestException ex:
Logger.Error("Command exception occured:\n" + e.Exception);
Logger.Error("JSON Message: " + ex.JsonMessage);
return;
default:
{
Logger.Error("Exception occured: " + e.Exception.GetType() + ": " + e.Exception);
await e.Context.Channel.SendMessageAsync(new DiscordEmbedBuilder
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
Color = DiscordColor.Red,
Description = "Internal error occured, please report this to the developer."
});
return;
}
2022-05-17 13:09:25 +00:00
}
2022-08-21 07:33:27 +00:00
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
internal static async Task OnMemberAdded(DiscordClient client, GuildMemberAddEventArgs e)
{
if (!Database.TryGetOpenTickets(e.Member.Id, out List<Database.Ticket> ownTickets))
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
return;
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
foreach (Database.Ticket ticket in ownTickets)
{
try
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
DiscordChannel channel = await client.GetChannelAsync(ticket.channelID);
if (channel?.GuildId == e.Guild.Id)
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
await channel.SendMessageAsync(new DiscordEmbedBuilder
2022-05-17 13:09:25 +00:00
{
Color = DiscordColor.Green,
2022-08-21 07:33:27 +00:00
Description = "User '" + e.Member.Username + "#" + e.Member.Discriminator + "' has rejoined the server, and has been re-added to the ticket."
});
2022-05-17 13:09:25 +00:00
}
}
2022-08-21 07:33:27 +00:00
catch (Exception) { /* ignored */ }
2022-05-17 13:09:25 +00:00
}
2022-08-21 07:33:27 +00:00
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
internal static async Task OnMemberRemoved(DiscordClient client, GuildMemberRemoveEventArgs e)
{
if (Database.TryGetOpenTickets(e.Member.Id, out List<Database.Ticket> ownTickets))
2022-05-17 13:09:25 +00:00
{
foreach (Database.Ticket ticket in ownTickets)
{
try
{
DiscordChannel channel = await client.GetChannelAsync(ticket.channelID);
if (channel?.GuildId == e.Guild.Id)
{
2022-08-21 07:33:27 +00:00
await channel.SendMessageAsync(new DiscordEmbedBuilder
{
Color = DiscordColor.Red,
Description = "User '" + e.Member.Username + "#" + e.Member.Discriminator + "' has left the server."
});
2022-05-17 13:09:25 +00:00
}
}
2022-08-21 07:33:27 +00:00
catch (Exception) { /* ignored */ }
2022-05-17 13:09:25 +00:00
}
}
2022-08-21 07:33:27 +00:00
if (Database.TryGetAssignedTickets(e.Member.Id, out List<Database.Ticket> assignedTickets) && Config.logChannel != 0)
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
DiscordChannel logChannel = await client.GetChannelAsync(Config.logChannel);
if (logChannel != null)
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
foreach (Database.Ticket ticket in assignedTickets)
2022-05-17 13:09:25 +00:00
{
try
{
DiscordChannel channel = await client.GetChannelAsync(ticket.channelID);
if (channel?.GuildId == e.Guild.Id)
{
2022-08-21 07:33:27 +00:00
await logChannel.SendMessageAsync(new DiscordEmbedBuilder
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
Color = DiscordColor.Red,
Description = "Assigned staff member '" + e.Member.Username + "#" + e.Member.Discriminator + "' has left the server: <#" + channel.Id + ">"
});
2022-05-17 13:09:25 +00:00
}
}
2022-08-21 07:33:27 +00:00
catch (Exception) { /* ignored */ }
2022-05-17 13:09:25 +00:00
}
}
}
2022-08-21 07:33:27 +00:00
}
2022-05-17 13:09:25 +00:00
2022-08-21 07:33:27 +00:00
internal static async Task OnComponentInteractionCreated(DiscordClient client, ComponentInteractionCreateEventArgs e)
{
try
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
switch (e.Interaction.Data.ComponentType)
2022-05-17 13:09:25 +00:00
{
2022-08-21 07:33:27 +00:00
case ComponentType.Button:
switch (e.Id)
{
case "supportchild_closeconfirm":
await CloseCommand.OnConfirmed(e.Interaction);
return;
case { } when e.Id.StartsWith("supportchild_newcommandbutton"):
await NewCommand.OnCategorySelection(e.Interaction);
return;
case { } when e.Id.StartsWith("supportchild_newticketbutton"):
await CreateButtonPanelCommand.OnButtonUsed(e.Interaction);
return;
case "right":
return;
case "left":
return;
case "rightskip":
return;
case "leftskip":
return;
case "stop":
return;
default:
Logger.Warn("Unknown button press received! '" + e.Id + "'");
return;
}
case ComponentType.Select:
switch (e.Id)
{
case { } when e.Id.StartsWith("supportchild_newcommandselector"):
await NewCommand.OnCategorySelection(e.Interaction);
return;
case { } when e.Id.StartsWith("supportchild_newticketselector"):
await CreateSelectionBoxPanelCommand.OnSelectionMenuUsed(e.Interaction);
return;
default:
Logger.Warn("Unknown selection box option received! '" + e.Id + "'");
return;
}
case ComponentType.ActionRow:
Logger.Warn("Unknown action row received! '" + e.Id + "'");
return;
case ComponentType.FormInput:
Logger.Warn("Unknown form input received! '" + e.Id + "'");
return;
2022-05-17 13:09:25 +00:00
default:
2022-08-21 07:33:27 +00:00
Logger.Warn("Unknown interaction type received! '" + e.Interaction.Data.ComponentType + "'");
break;
2022-05-17 13:09:25 +00:00
}
}
2022-08-21 07:33:27 +00:00
catch (DiscordException ex)
{
Logger.Error("Interaction Exception occurred: " + ex);
Logger.Error("JsomMessage: " + ex.JsonMessage);
}
catch (Exception ex)
{
Logger.Error("Interaction Exception occured: " + ex.GetType() + ": " + ex);
}
}
private static string ParseFailedCheck(SlashCheckBaseAttribute attr)
{
return attr switch
{
SlashRequireDirectMessageAttribute => "This command can only be used in direct messages!",
SlashRequireOwnerAttribute => "Only the server owner can use that command!",
SlashRequirePermissionsAttribute => "You don't have permission to do that!",
SlashRequireBotPermissionsAttribute => "The bot doesn't have the required permissions to do that!",
SlashRequireUserPermissionsAttribute => "You don't have permission to do that!",
SlashRequireGuildAttribute => "This command has to be used in a Discord server!",
_ => "Unknown Discord API error occured, please try again later."
};
2022-05-17 13:09:25 +00:00
}
}