From ad0916477b031ebce8460b7b1ec82d7e599712f0 Mon Sep 17 00:00:00 2001 From: EmotionChild Date: Wed, 18 May 2022 01:09:25 +1200 Subject: [PATCH] updated some stuff --- .gitignore | 3 + SupportChild/Commands/AddCommand.cs | 184 ++-- SupportChild/Database.cs | 1254 +++++++++++++-------------- SupportChild/EventHandler.cs | 512 +++++------ SupportChild/default_config.yml | 148 ++-- 5 files changed, 1052 insertions(+), 1049 deletions(-) diff --git a/.gitignore b/.gitignore index 5e49400..f8206f5 100644 --- a/.gitignore +++ b/.gitignore @@ -362,5 +362,8 @@ MigrationBackup/ # Fody - auto-generated XML schema FodyWeavers.xsd +# Manually added folders Windows-x64/ Linux-x64/ +.idea +.vs diff --git a/SupportChild/Commands/AddCommand.cs b/SupportChild/Commands/AddCommand.cs index dd3fcc2..64e5935 100644 --- a/SupportChild/Commands/AddCommand.cs +++ b/SupportChild/Commands/AddCommand.cs @@ -8,100 +8,100 @@ using Microsoft.Extensions.Logging; namespace SupportChild.Commands { - public class AddCommand : BaseCommandModule - { - [Command("add")] - [Description("Adds a user to a ticket.")] - public async Task OnExecute(CommandContext command, [RemainingText] string commandArgs) - { - // Check if the user has permission to use this command. - if (!Config.HasPermission(command.Member, "add")) - { - DiscordEmbed error = new DiscordEmbedBuilder - { - Color = DiscordColor.Red, - Description = "You do not have permission to use this command." - }; - await command.RespondAsync(error); - command.Client.Logger.Log(LogLevel.Information, "User tried to use the add command but did not have permission."); - return; - } + public class AddCommand : BaseCommandModule + { + [Command("add")] + [Description("Adds a user to a ticket.")] + public async Task OnExecute(CommandContext command, [RemainingText] string commandArgs) + { + // Check if the user has permission to use this command. + if (!Config.HasPermission(command.Member, "add")) + { + DiscordEmbed error = new DiscordEmbedBuilder + { + Color = DiscordColor.Red, + Description = "You do not have permission to use this command." + }; + await command.RespondAsync(error); + command.Client.Logger.Log(LogLevel.Information, "User tried to use the add command but did not have permission."); + return; + } - // Check if ticket exists in the database - if (!Database.IsOpenTicket(command.Channel.Id)) - { - DiscordEmbed error = new DiscordEmbedBuilder - { - Color = DiscordColor.Red, - Description = "This channel is not a ticket." - }; - await command.RespondAsync(error); - return; - } + // Check if ticket exists in the database + if (!Database.IsOpenTicket(command.Channel.Id)) + { + DiscordEmbed error = new DiscordEmbedBuilder + { + Color = DiscordColor.Red, + Description = "This channel is not a ticket." + }; + await command.RespondAsync(error); + return; + } - string[] parsedArgs = Utilities.ParseIDs(command.RawArgumentString); - foreach (string parsedArg in parsedArgs) - { - if (!ulong.TryParse(parsedArg, out ulong userID)) - { - DiscordEmbed error = new DiscordEmbedBuilder - { - Color = DiscordColor.Red, - Description = "Invalid ID/Mention. (Could not convert to numerical)" - }; - await command.RespondAsync(error); - continue; - } + string[] parsedArgs = Utilities.ParseIDs(command.RawArgumentString); + foreach (string parsedArg in parsedArgs) + { + if (!ulong.TryParse(parsedArg, out ulong userID)) + { + DiscordEmbed error = new DiscordEmbedBuilder + { + Color = DiscordColor.Red, + Description = "Invalid ID/Mention. (Could not convert to numerical)" + }; + await command.RespondAsync(error); + continue; + } - DiscordMember mentionedMember; - try - { - mentionedMember = await command.Guild.GetMemberAsync(userID); - } - catch (Exception) - { - DiscordEmbed error = new DiscordEmbedBuilder - { - Color = DiscordColor.Red, - Description = "Invalid ID/Mention. (Could not find user on this server)" - }; - await command.RespondAsync(error); - continue; - } + DiscordMember mentionedMember; + try + { + mentionedMember = await command.Guild.GetMemberAsync(userID); + } + catch (Exception) + { + DiscordEmbed error = new DiscordEmbedBuilder + { + Color = DiscordColor.Red, + Description = "Invalid ID/Mention. (Could not find user on this server)" + }; + await command.RespondAsync(error); + continue; + } - try - { - await command.Channel.AddOverwriteAsync(mentionedMember, Permissions.AccessChannels, Permissions.None); - DiscordEmbed message = new DiscordEmbedBuilder - { - Color = DiscordColor.Green, - Description = "Added " + mentionedMember.Mention + " to ticket." - }; - await command.RespondAsync(message); + try + { + await command.Channel.AddOverwriteAsync(mentionedMember, Permissions.AccessChannels, Permissions.None); + DiscordEmbed message = new DiscordEmbedBuilder + { + Color = DiscordColor.Green, + Description = "Added " + mentionedMember.Mention + " to ticket." + }; + await command.RespondAsync(message); - // Log it if the log channel exists - DiscordChannel logChannel = command.Guild.GetChannel(Config.logChannel); - if (logChannel != null) - { - DiscordEmbed logMessage = new DiscordEmbedBuilder - { - Color = DiscordColor.Green, - Description = mentionedMember.Mention + " was added to " + command.Channel.Mention + - " by " + command.Member.Mention + "." - }; - await logChannel.SendMessageAsync(logMessage); - } - } - catch (Exception) - { - DiscordEmbed message = new DiscordEmbedBuilder - { - Color = DiscordColor.Red, - Description = "Could not add <@" + parsedArg + "> to ticket, unknown error occured." - }; - await command.RespondAsync(message); - } - } - } - } -} + // Log it if the log channel exists + DiscordChannel logChannel = command.Guild.GetChannel(Config.logChannel); + if (logChannel != null) + { + DiscordEmbed logMessage = new DiscordEmbedBuilder + { + Color = DiscordColor.Green, + Description = mentionedMember.Mention + " was added to " + command.Channel.Mention + + " by " + command.Member.Mention + "." + }; + await logChannel.SendMessageAsync(logMessage); + } + } + catch (Exception) + { + DiscordEmbed message = new DiscordEmbedBuilder + { + Color = DiscordColor.Red, + Description = "Could not add <@" + parsedArg + "> to ticket, unknown error occured." + }; + await command.RespondAsync(message); + } + } + } + } +} \ No newline at end of file diff --git a/SupportChild/Database.cs b/SupportChild/Database.cs index 9f1010b..57ecbca 100644 --- a/SupportChild/Database.cs +++ b/SupportChild/Database.cs @@ -5,687 +5,687 @@ using MySql.Data.MySqlClient; namespace SupportChild { - public static class Database - { - private static string connectionString = ""; + public static class Database + { + private static string connectionString = ""; - private static Random random = new Random(); + private static Random random = new Random(); - public static void SetConnectionString(string host, int port, string database, string username, string password) - { - connectionString = "server=" + host + - ";database=" + database + - ";port=" + port + - ";userid=" + username + - ";password=" + password; - } - public static MySqlConnection GetConnection() - { - return new MySqlConnection(connectionString); - } - public static long GetNumberOfTickets() - { - try - { - using (MySqlConnection c = GetConnection()) - { - MySqlCommand countTickets = new MySqlCommand("SELECT COUNT(*) FROM tickets", c); - c.Open(); - return (long)countTickets.ExecuteScalar(); - } - } - catch (Exception e) - { - Console.WriteLine("Error occured when attempting to count number of open tickets: " + e); - } + public static void SetConnectionString(string host, int port, string database, string username, string password) + { + connectionString = "server=" + host + + ";database=" + database + + ";port=" + port + + ";userid=" + username + + ";password=" + password; + } + public static MySqlConnection GetConnection() + { + return new MySqlConnection(connectionString); + } + public static long GetNumberOfTickets() + { + try + { + using (MySqlConnection c = GetConnection()) + { + MySqlCommand countTickets = new MySqlCommand("SELECT COUNT(*) FROM tickets", c); + c.Open(); + return (long)countTickets.ExecuteScalar(); + } + } + catch (Exception e) + { + Console.WriteLine("Error occured when attempting to count number of open tickets: " + e); + } - return -1; - } - public static long GetNumberOfClosedTickets() - { - try - { - using (MySqlConnection c = GetConnection()) - { - MySqlCommand countTickets = new MySqlCommand("SELECT COUNT(*) FROM ticket_history", c); - c.Open(); - return (long)countTickets.ExecuteScalar(); - } - } - catch (Exception e) - { - Console.WriteLine("Error occured when attempting to count number of open tickets: " + e); - } + return -1; + } + public static long GetNumberOfClosedTickets() + { + try + { + using (MySqlConnection c = GetConnection()) + { + MySqlCommand countTickets = new MySqlCommand("SELECT COUNT(*) FROM ticket_history", c); + c.Open(); + return (long)countTickets.ExecuteScalar(); + } + } + catch (Exception e) + { + Console.WriteLine("Error occured when attempting to count number of open tickets: " + e); + } - return -1; - } - public static void SetupTables() - { - using (MySqlConnection c = GetConnection()) - { - MySqlCommand createTickets = new MySqlCommand( - "CREATE TABLE IF NOT EXISTS tickets(" + - "id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT," + - "created_time DATETIME NOT NULL," + - "creator_id BIGINT UNSIGNED NOT NULL," + - "assigned_staff_id BIGINT UNSIGNED NOT NULL DEFAULT 0," + - "summary VARCHAR(5000) NOT NULL," + - "channel_id BIGINT UNSIGNED NOT NULL UNIQUE," + - "INDEX(created_time, assigned_staff_id, channel_id))", - c); - MySqlCommand createTicketHistory = new MySqlCommand( - "CREATE TABLE IF NOT EXISTS ticket_history(" + - "id INT UNSIGNED NOT NULL PRIMARY KEY," + - "created_time DATETIME NOT NULL," + - "closed_time DATETIME NOT NULL," + - "creator_id BIGINT UNSIGNED NOT NULL," + - "assigned_staff_id BIGINT UNSIGNED NOT NULL DEFAULT 0," + - "summary VARCHAR(5000) NOT NULL," + - "channel_id BIGINT UNSIGNED NOT NULL UNIQUE," + - "INDEX(created_time, closed_time, channel_id))", - c); - MySqlCommand createBlacklisted = new MySqlCommand( - "CREATE TABLE IF NOT EXISTS blacklisted_users(" + - "user_id BIGINT UNSIGNED NOT NULL PRIMARY KEY," + - "time DATETIME NOT NULL," + - "moderator_id BIGINT UNSIGNED NOT NULL," + - "INDEX(user_id, time))", - c); - MySqlCommand createStaffList = new MySqlCommand( - "CREATE TABLE IF NOT EXISTS staff(" + - "user_id BIGINT UNSIGNED NOT NULL PRIMARY KEY," + - "name VARCHAR(256) NOT NULL," + - "active BOOLEAN NOT NULL DEFAULT true)", - c); - MySqlCommand createMessages = new MySqlCommand( - "CREATE TABLE IF NOT EXISTS messages(" + - "identifier VARCHAR(256) NOT NULL PRIMARY KEY," + - "user_id BIGINT UNSIGNED NOT NULL," + - "message VARCHAR(5000) NOT NULL)", - c); - c.Open(); - createTickets.ExecuteNonQuery(); - createBlacklisted.ExecuteNonQuery(); - createTicketHistory.ExecuteNonQuery(); - createStaffList.ExecuteNonQuery(); - createMessages.ExecuteNonQuery(); - } - } - public static bool IsOpenTicket(ulong channelID) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets WHERE channel_id=@channel_id", c); - selection.Parameters.AddWithValue("@channel_id", channelID); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + return -1; + } + public static void SetupTables() + { + using (MySqlConnection c = GetConnection()) + { + MySqlCommand createTickets = new MySqlCommand( + "CREATE TABLE IF NOT EXISTS tickets(" + + "id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT," + + "created_time DATETIME NOT NULL," + + "creator_id BIGINT UNSIGNED NOT NULL," + + "assigned_staff_id BIGINT UNSIGNED NOT NULL DEFAULT 0," + + "summary VARCHAR(5000) NOT NULL," + + "channel_id BIGINT UNSIGNED NOT NULL UNIQUE," + + "INDEX(created_time, assigned_staff_id, channel_id))", + c); + MySqlCommand createTicketHistory = new MySqlCommand( + "CREATE TABLE IF NOT EXISTS ticket_history(" + + "id INT UNSIGNED NOT NULL PRIMARY KEY," + + "created_time DATETIME NOT NULL," + + "closed_time DATETIME NOT NULL," + + "creator_id BIGINT UNSIGNED NOT NULL," + + "assigned_staff_id BIGINT UNSIGNED NOT NULL DEFAULT 0," + + "summary VARCHAR(5000) NOT NULL," + + "channel_id BIGINT UNSIGNED NOT NULL UNIQUE," + + "INDEX(created_time, closed_time, channel_id))", + c); + MySqlCommand createBlacklisted = new MySqlCommand( + "CREATE TABLE IF NOT EXISTS blacklisted_users(" + + "user_id BIGINT UNSIGNED NOT NULL PRIMARY KEY," + + "time DATETIME NOT NULL," + + "moderator_id BIGINT UNSIGNED NOT NULL," + + "INDEX(user_id, time))", + c); + MySqlCommand createStaffList = new MySqlCommand( + "CREATE TABLE IF NOT EXISTS staff(" + + "user_id BIGINT UNSIGNED NOT NULL PRIMARY KEY," + + "name VARCHAR(256) NOT NULL," + + "active BOOLEAN NOT NULL DEFAULT true)", + c); + MySqlCommand createMessages = new MySqlCommand( + "CREATE TABLE IF NOT EXISTS messages(" + + "identifier VARCHAR(256) NOT NULL PRIMARY KEY," + + "user_id BIGINT UNSIGNED NOT NULL," + + "message VARCHAR(5000) NOT NULL)", + c); + c.Open(); + createTickets.ExecuteNonQuery(); + createBlacklisted.ExecuteNonQuery(); + createTicketHistory.ExecuteNonQuery(); + createStaffList.ExecuteNonQuery(); + createMessages.ExecuteNonQuery(); + } + } + public static bool IsOpenTicket(ulong channelID) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets WHERE channel_id=@channel_id", c); + selection.Parameters.AddWithValue("@channel_id", channelID); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if ticket exists in the database - if (!results.Read()) - { - return false; - } - results.Close(); - } - return true; - } - public static bool TryGetOpenTicket(ulong channelID, out Ticket ticket) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets WHERE channel_id=@channel_id", c); - selection.Parameters.AddWithValue("@channel_id", channelID); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + // Check if ticket exists in the database + if (!results.Read()) + { + return false; + } + results.Close(); + } + return true; + } + public static bool TryGetOpenTicket(ulong channelID, out Ticket ticket) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets WHERE channel_id=@channel_id", c); + selection.Parameters.AddWithValue("@channel_id", channelID); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if ticket exists in the database - if (!results.Read()) - { - ticket = null; - return false; - } + // Check if ticket exists in the database + if (!results.Read()) + { + ticket = null; + return false; + } - ticket = new Ticket(results); - results.Close(); - return true; - } - } - public static bool TryGetOpenTicketByID(uint id, out Ticket ticket) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets WHERE id=@id", c); - selection.Parameters.AddWithValue("@id", id); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + ticket = new Ticket(results); + results.Close(); + return true; + } + } + public static bool TryGetOpenTicketByID(uint id, out Ticket ticket) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets WHERE id=@id", c); + selection.Parameters.AddWithValue("@id", id); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if open ticket exists in the database - if (results.Read()) - { - ticket = new Ticket(results); - return true; - } + // Check if open ticket exists in the database + if (results.Read()) + { + ticket = new Ticket(results); + return true; + } - ticket = null; - return false; - } - } - public static bool TryGetClosedTicket(uint id, out Ticket ticket) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM ticket_history WHERE id=@id", c); - selection.Parameters.AddWithValue("@id", id); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + ticket = null; + return false; + } + } + public static bool TryGetClosedTicket(uint id, out Ticket ticket) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM ticket_history WHERE id=@id", c); + selection.Parameters.AddWithValue("@id", id); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if closed ticket exists in the database - if (results.Read()) - { - ticket = new Ticket(results); - return true; - } + // Check if closed ticket exists in the database + if (results.Read()) + { + ticket = new Ticket(results); + return true; + } - ticket = null; - return false; - } - } - public static bool TryGetOpenTickets(ulong userID, out List tickets) - { - tickets = null; - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets WHERE creator_id=@creator_id", c); - selection.Parameters.AddWithValue("@creator_id", userID); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + ticket = null; + return false; + } + } + public static bool TryGetOpenTickets(ulong userID, out List tickets) + { + tickets = null; + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets WHERE creator_id=@creator_id", c); + selection.Parameters.AddWithValue("@creator_id", userID); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - if (!results.Read()) - { - return false; - } + if (!results.Read()) + { + return false; + } - tickets = new List { new Ticket(results) }; - while (results.Read()) - { - tickets.Add(new Ticket(results)); - } - results.Close(); - return true; - } - } - public static bool TryGetOldestTickets(ulong userID, out List tickets, int listLimit) - { - tickets = null; - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets ORDER BY created_time ASC LIMIT @limit", c); - selection.Parameters.AddWithValue("@creator_id", userID); - selection.Parameters.AddWithValue("@limit", listLimit); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + tickets = new List { new Ticket(results) }; + while (results.Read()) + { + tickets.Add(new Ticket(results)); + } + results.Close(); + return true; + } + } + public static bool TryGetOldestTickets(ulong userID, out List tickets, int listLimit) + { + tickets = null; + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets ORDER BY created_time ASC LIMIT @limit", c); + selection.Parameters.AddWithValue("@creator_id", userID); + selection.Parameters.AddWithValue("@limit", listLimit); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - if (!results.Read()) - { - return false; - } + if (!results.Read()) + { + return false; + } - tickets = new List { new Ticket(results) }; - while (results.Read()) - { - tickets.Add(new Ticket(results)); - } - results.Close(); - return true; - } - } - public static bool TryGetClosedTickets(ulong userID, out List tickets) - { - tickets = null; - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM ticket_history WHERE creator_id=@creator_id", c); - selection.Parameters.AddWithValue("@creator_id", userID); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + tickets = new List { new Ticket(results) }; + while (results.Read()) + { + tickets.Add(new Ticket(results)); + } + results.Close(); + return true; + } + } + public static bool TryGetClosedTickets(ulong userID, out List tickets) + { + tickets = null; + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM ticket_history WHERE creator_id=@creator_id", c); + selection.Parameters.AddWithValue("@creator_id", userID); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - if (!results.Read()) - { - return false; - } + if (!results.Read()) + { + return false; + } - tickets = new List { new Ticket(results) }; - while (results.Read()) - { - tickets.Add(new Ticket(results)); - } - results.Close(); - return true; - } - } - public static bool TryGetAssignedTickets(ulong staffID, out List tickets) - { - tickets = null; - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets WHERE assigned_staff_id=@assigned_staff_id", c); - selection.Parameters.AddWithValue("@assigned_staff_id", staffID); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + tickets = new List { new Ticket(results) }; + while (results.Read()) + { + tickets.Add(new Ticket(results)); + } + results.Close(); + return true; + } + } + public static bool TryGetAssignedTickets(ulong staffID, out List tickets) + { + tickets = null; + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM tickets WHERE assigned_staff_id=@assigned_staff_id", c); + selection.Parameters.AddWithValue("@assigned_staff_id", staffID); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - if (!results.Read()) - { - return false; - } + if (!results.Read()) + { + return false; + } - tickets = new List { new Ticket(results) }; - while (results.Read()) - { - tickets.Add(new Ticket(results)); - } - results.Close(); - return true; - } - } - public static long NewTicket(ulong memberID, ulong staffID, ulong ticketID) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand cmd = new MySqlCommand( - @"INSERT INTO tickets (created_time, creator_id, assigned_staff_id, summary, channel_id) VALUES (UTC_TIMESTAMP(), @creator_id, @assigned_staff_id, @summary, @channel_id);", - c); - cmd.Parameters.AddWithValue("@creator_id", memberID); - cmd.Parameters.AddWithValue("@assigned_staff_id", staffID); - cmd.Parameters.AddWithValue("@summary", ""); - cmd.Parameters.AddWithValue("@channel_id", ticketID); - cmd.ExecuteNonQuery(); - return cmd.LastInsertedId; - } - } + tickets = new List { new Ticket(results) }; + while (results.Read()) + { + tickets.Add(new Ticket(results)); + } + results.Close(); + return true; + } + } + public static long NewTicket(ulong memberID, ulong staffID, ulong ticketID) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand cmd = new MySqlCommand( + @"INSERT INTO tickets (created_time, creator_id, assigned_staff_id, summary, channel_id) VALUES (UTC_TIMESTAMP(), @creator_id, @assigned_staff_id, @summary, @channel_id);", + c); + cmd.Parameters.AddWithValue("@creator_id", memberID); + cmd.Parameters.AddWithValue("@assigned_staff_id", staffID); + cmd.Parameters.AddWithValue("@summary", ""); + cmd.Parameters.AddWithValue("@channel_id", ticketID); + cmd.ExecuteNonQuery(); + return cmd.LastInsertedId; + } + } - public static void ArchiveTicket(Ticket ticket) - { - // Check if ticket already exists in the archive - if (TryGetClosedTicket(ticket.id, out Ticket _)) - { - using (MySqlConnection c = GetConnection()) - { - MySqlCommand deleteTicket = new MySqlCommand(@"DELETE FROM ticket_history WHERE id=@id OR channel_id=@channel_id", c); - deleteTicket.Parameters.AddWithValue("@id", ticket.id); - deleteTicket.Parameters.AddWithValue("@channel_id", ticket.channelID); + public static void ArchiveTicket(Ticket ticket) + { + // Check if ticket already exists in the archive + if (TryGetClosedTicket(ticket.id, out Ticket _)) + { + using (MySqlConnection c = GetConnection()) + { + MySqlCommand deleteTicket = new MySqlCommand(@"DELETE FROM ticket_history WHERE id=@id OR channel_id=@channel_id", c); + deleteTicket.Parameters.AddWithValue("@id", ticket.id); + deleteTicket.Parameters.AddWithValue("@channel_id", ticket.channelID); - c.Open(); - deleteTicket.Prepare(); - deleteTicket.ExecuteNonQuery(); - } - } + c.Open(); + deleteTicket.Prepare(); + deleteTicket.ExecuteNonQuery(); + } + } - using (MySqlConnection c = GetConnection()) - { - // Create an entry in the ticket history database - MySqlCommand archiveTicket = new MySqlCommand(@"INSERT INTO ticket_history (id, created_time, closed_time, creator_id, assigned_staff_id, summary, channel_id) VALUES (@id, @created_time, UTC_TIMESTAMP(), @creator_id, @assigned_staff_id, @summary, @channel_id);", c); - archiveTicket.Parameters.AddWithValue("@id", ticket.id); - archiveTicket.Parameters.AddWithValue("@created_time", ticket.createdTime); - archiveTicket.Parameters.AddWithValue("@creator_id", ticket.creatorID); - archiveTicket.Parameters.AddWithValue("@assigned_staff_id", ticket.assignedStaffID); - archiveTicket.Parameters.AddWithValue("@summary", ticket.summary); - archiveTicket.Parameters.AddWithValue("@channel_id", ticket.channelID); + using (MySqlConnection c = GetConnection()) + { + // Create an entry in the ticket history database + MySqlCommand archiveTicket = new MySqlCommand(@"INSERT INTO ticket_history (id, created_time, closed_time, creator_id, assigned_staff_id, summary, channel_id) VALUES (@id, @created_time, UTC_TIMESTAMP(), @creator_id, @assigned_staff_id, @summary, @channel_id);", c); + archiveTicket.Parameters.AddWithValue("@id", ticket.id); + archiveTicket.Parameters.AddWithValue("@created_time", ticket.createdTime); + archiveTicket.Parameters.AddWithValue("@creator_id", ticket.creatorID); + archiveTicket.Parameters.AddWithValue("@assigned_staff_id", ticket.assignedStaffID); + archiveTicket.Parameters.AddWithValue("@summary", ticket.summary); + archiveTicket.Parameters.AddWithValue("@channel_id", ticket.channelID); - c.Open(); - archiveTicket.Prepare(); - archiveTicket.ExecuteNonQuery(); - } - } + c.Open(); + archiveTicket.Prepare(); + archiveTicket.ExecuteNonQuery(); + } + } - public static void DeleteOpenTicket(uint ticketID) - { - using (MySqlConnection c = GetConnection()) - { - MySqlCommand deletion = new MySqlCommand(@"DELETE FROM tickets WHERE id=@id", c); - deletion.Parameters.AddWithValue("@id", ticketID); + public static void DeleteOpenTicket(uint ticketID) + { + using (MySqlConnection c = GetConnection()) + { + MySqlCommand deletion = new MySqlCommand(@"DELETE FROM tickets WHERE id=@id", c); + deletion.Parameters.AddWithValue("@id", ticketID); - c.Open(); - deletion.Prepare(); - deletion.ExecuteNonQuery(); - } - } + c.Open(); + deletion.Prepare(); + deletion.ExecuteNonQuery(); + } + } - public static bool IsBlacklisted(ulong userID) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM blacklisted_users WHERE user_id=@user_id", c); - selection.Parameters.AddWithValue("@user_id", userID); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + public static bool IsBlacklisted(ulong userID) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM blacklisted_users WHERE user_id=@user_id", c); + selection.Parameters.AddWithValue("@user_id", userID); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if user is blacklisted - if (results.Read()) - { - return true; - } - results.Close(); - } + // Check if user is blacklisted + if (results.Read()) + { + return true; + } + results.Close(); + } - return false; - } - public static bool Blacklist(ulong blacklistedID, ulong staffID) - { - using (MySqlConnection c = GetConnection()) - { - try - { - c.Open(); - MySqlCommand cmd = new MySqlCommand(@"INSERT INTO blacklisted_users (user_id,time,moderator_id) VALUES (@user_id, UTC_TIMESTAMP(), @moderator_id);", c); - cmd.Parameters.AddWithValue("@user_id", blacklistedID); - cmd.Parameters.AddWithValue("@moderator_id", staffID); - cmd.Prepare(); - return cmd.ExecuteNonQuery() > 0; - } - catch (MySqlException) - { - return false; - } - } - } - public static bool Unblacklist(ulong blacklistedID) - { - using (MySqlConnection c = GetConnection()) - { - try - { - c.Open(); - MySqlCommand cmd = new MySqlCommand(@"DELETE FROM blacklisted_users WHERE user_id=@user_id", c); - cmd.Parameters.AddWithValue("@user_id", blacklistedID); - cmd.Prepare(); - return cmd.ExecuteNonQuery() > 0; - } - catch (MySqlException) - { - return false; - } + return false; + } + public static bool Blacklist(ulong blacklistedID, ulong staffID) + { + using (MySqlConnection c = GetConnection()) + { + try + { + c.Open(); + MySqlCommand cmd = new MySqlCommand(@"INSERT INTO blacklisted_users (user_id,time,moderator_id) VALUES (@user_id, UTC_TIMESTAMP(), @moderator_id);", c); + cmd.Parameters.AddWithValue("@user_id", blacklistedID); + cmd.Parameters.AddWithValue("@moderator_id", staffID); + cmd.Prepare(); + return cmd.ExecuteNonQuery() > 0; + } + catch (MySqlException) + { + return false; + } + } + } + public static bool Unblacklist(ulong blacklistedID) + { + using (MySqlConnection c = GetConnection()) + { + try + { + c.Open(); + MySqlCommand cmd = new MySqlCommand(@"DELETE FROM blacklisted_users WHERE user_id=@user_id", c); + cmd.Parameters.AddWithValue("@user_id", blacklistedID); + cmd.Prepare(); + return cmd.ExecuteNonQuery() > 0; + } + catch (MySqlException) + { + return false; + } - } - } - public static bool AssignStaff(Ticket ticket, ulong staffID) - { - using (MySqlConnection c = GetConnection()) - { - try - { - c.Open(); - MySqlCommand update = new MySqlCommand(@"UPDATE tickets SET assigned_staff_id = @assigned_staff_id WHERE id = @id", c); - update.Parameters.AddWithValue("@assigned_staff_id", staffID); - update.Parameters.AddWithValue("@id", ticket.id); - update.Prepare(); - return update.ExecuteNonQuery() > 0; - } - catch (MySqlException) - { - return false; - } + } + } + public static bool AssignStaff(Ticket ticket, ulong staffID) + { + using (MySqlConnection c = GetConnection()) + { + try + { + c.Open(); + MySqlCommand update = new MySqlCommand(@"UPDATE tickets SET assigned_staff_id = @assigned_staff_id WHERE id = @id", c); + update.Parameters.AddWithValue("@assigned_staff_id", staffID); + update.Parameters.AddWithValue("@id", ticket.id); + update.Prepare(); + return update.ExecuteNonQuery() > 0; + } + catch (MySqlException) + { + return false; + } - } - } - public static bool UnassignStaff(Ticket ticket) - { - return AssignStaff(ticket, 0); - } - public static StaffMember GetRandomActiveStaff(ulong currentStaffID) - { - List staffMembers = GetActiveStaff(currentStaffID); - if (!staffMembers.Any()) - { - return null; - } + } + } + public static bool UnassignStaff(Ticket ticket) + { + return AssignStaff(ticket, 0); + } + public static StaffMember GetRandomActiveStaff(ulong currentStaffID) + { + List staffMembers = GetActiveStaff(currentStaffID); + if (!staffMembers.Any()) + { + return null; + } - return staffMembers[random.Next(staffMembers.Count)]; - } + return staffMembers[random.Next(staffMembers.Count)]; + } - public static List GetActiveStaff(ulong currentStaffID = 0) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM staff WHERE active = true AND user_id != @user_id", c); - selection.Parameters.AddWithValue("@user_id", currentStaffID); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + public static List GetActiveStaff(ulong currentStaffID = 0) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM staff WHERE active = true AND user_id != @user_id", c); + selection.Parameters.AddWithValue("@user_id", currentStaffID); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if staff exists in the database - if (!results.Read()) - { - return new List(); - } + // Check if staff exists in the database + if (!results.Read()) + { + return new List(); + } - List staffMembers = new List { new StaffMember(results) }; - while (results.Read()) - { - staffMembers.Add(new StaffMember(results)); - } - results.Close(); + List staffMembers = new List { new StaffMember(results) }; + while (results.Read()) + { + staffMembers.Add(new StaffMember(results)); + } + results.Close(); - return staffMembers; - } - } + return staffMembers; + } + } - public static List GetAllStaff(ulong currentStaffID = 0) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM staff WHERE user_id != @user_id", c); - selection.Parameters.AddWithValue("@user_id", currentStaffID); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + public static List GetAllStaff(ulong currentStaffID = 0) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM staff WHERE user_id != @user_id", c); + selection.Parameters.AddWithValue("@user_id", currentStaffID); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if staff exist in the database - if (!results.Read()) - { - return new List(); - } + // Check if staff exist in the database + if (!results.Read()) + { + return new List(); + } - List staffMembers = new List { new StaffMember(results) }; - while (results.Read()) - { - staffMembers.Add(new StaffMember(results)); - } - results.Close(); + List staffMembers = new List { new StaffMember(results) }; + while (results.Read()) + { + staffMembers.Add(new StaffMember(results)); + } + results.Close(); - return staffMembers; - } - } + return staffMembers; + } + } - public static bool IsStaff(ulong staffID) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM staff WHERE user_id=@user_id", c); - selection.Parameters.AddWithValue("@user_id", staffID); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + public static bool IsStaff(ulong staffID) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM staff WHERE user_id=@user_id", c); + selection.Parameters.AddWithValue("@user_id", staffID); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if ticket exists in the database - if (!results.Read()) - { - return false; - } - results.Close(); - return true; - } - } - public static bool TryGetStaff(ulong staffID, out StaffMember staffMember) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM staff WHERE user_id=@user_id", c); - selection.Parameters.AddWithValue("@user_id", staffID); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + // Check if ticket exists in the database + if (!results.Read()) + { + return false; + } + results.Close(); + return true; + } + } + public static bool TryGetStaff(ulong staffID, out StaffMember staffMember) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM staff WHERE user_id=@user_id", c); + selection.Parameters.AddWithValue("@user_id", staffID); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if ticket exists in the database - if (!results.Read()) - { - staffMember = null; - return false; - } - staffMember = new StaffMember(results); - results.Close(); - return true; - } - } + // Check if ticket exists in the database + if (!results.Read()) + { + staffMember = null; + return false; + } + staffMember = new StaffMember(results); + results.Close(); + return true; + } + } - public static List GetAllMessages() - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM messages", c); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + public static List GetAllMessages() + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM messages", c); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if messages exist in the database - if (!results.Read()) - { - return new List(); - } + // Check if messages exist in the database + if (!results.Read()) + { + return new List(); + } - List messages = new List { new Message(results) }; - while (results.Read()) - { - messages.Add(new Message(results)); - } - results.Close(); + List messages = new List { new Message(results) }; + while (results.Read()) + { + messages.Add(new Message(results)); + } + results.Close(); - return messages; - } - } + return messages; + } + } - public static bool TryGetMessage(string identifier, out Message message) - { - using (MySqlConnection c = GetConnection()) - { - c.Open(); - MySqlCommand selection = new MySqlCommand(@"SELECT * FROM messages WHERE identifier=@identifier", c); - selection.Parameters.AddWithValue("@identifier", identifier); - selection.Prepare(); - MySqlDataReader results = selection.ExecuteReader(); + public static bool TryGetMessage(string identifier, out Message message) + { + using (MySqlConnection c = GetConnection()) + { + c.Open(); + MySqlCommand selection = new MySqlCommand(@"SELECT * FROM messages WHERE identifier=@identifier", c); + selection.Parameters.AddWithValue("@identifier", identifier); + selection.Prepare(); + MySqlDataReader results = selection.ExecuteReader(); - // Check if ticket exists in the database - if (!results.Read()) - { - message = null; - return false; - } - message = new Message(results); - results.Close(); - return true; - } - } + // Check if ticket exists in the database + if (!results.Read()) + { + message = null; + return false; + } + message = new Message(results); + results.Close(); + return true; + } + } - public static bool AddMessage(string identifier, ulong userID, string message) - { - using (MySqlConnection c = GetConnection()) - { - try - { - c.Open(); - MySqlCommand cmd = new MySqlCommand(@"INSERT INTO messages (identifier,user_id,message) VALUES (@identifier, @user_id, @message);", c); - cmd.Parameters.AddWithValue("@identifier", identifier); - cmd.Parameters.AddWithValue("@user_id", userID); - cmd.Parameters.AddWithValue("@message", message); - cmd.Prepare(); - return cmd.ExecuteNonQuery() > 0; - } - catch (MySqlException) - { - return false; - } - } - } + public static bool AddMessage(string identifier, ulong userID, string message) + { + using (MySqlConnection c = GetConnection()) + { + try + { + c.Open(); + MySqlCommand cmd = new MySqlCommand(@"INSERT INTO messages (identifier,user_id,message) VALUES (@identifier, @user_id, @message);", c); + cmd.Parameters.AddWithValue("@identifier", identifier); + cmd.Parameters.AddWithValue("@user_id", userID); + cmd.Parameters.AddWithValue("@message", message); + cmd.Prepare(); + return cmd.ExecuteNonQuery() > 0; + } + catch (MySqlException) + { + return false; + } + } + } - public static bool RemoveMessage(string identifier) - { - using (MySqlConnection c = GetConnection()) - { - try - { - c.Open(); - MySqlCommand cmd = new MySqlCommand(@"DELETE FROM messages WHERE identifier=@identifier", c); - cmd.Parameters.AddWithValue("@identifier", identifier); - cmd.Prepare(); - return cmd.ExecuteNonQuery() > 0; - } - catch (MySqlException) - { - return false; - } + public static bool RemoveMessage(string identifier) + { + using (MySqlConnection c = GetConnection()) + { + try + { + c.Open(); + MySqlCommand cmd = new MySqlCommand(@"DELETE FROM messages WHERE identifier=@identifier", c); + cmd.Parameters.AddWithValue("@identifier", identifier); + cmd.Prepare(); + return cmd.ExecuteNonQuery() > 0; + } + catch (MySqlException) + { + return false; + } - } - } + } + } - public class Ticket - { - public uint id; - public DateTime createdTime; - public ulong creatorID; - public ulong assignedStaffID; - public string summary; - public ulong channelID; + public class Ticket + { + public uint id; + public DateTime createdTime; + public ulong creatorID; + public ulong assignedStaffID; + public string summary; + public ulong channelID; - public Ticket(MySqlDataReader reader) - { - id = reader.GetUInt32("id"); - createdTime = reader.GetDateTime("created_time"); - creatorID = reader.GetUInt64("creator_id"); - assignedStaffID = reader.GetUInt64("assigned_staff_id"); - summary = reader.GetString("summary"); - channelID = reader.GetUInt64("channel_id"); - } + public Ticket(MySqlDataReader reader) + { + this.id = reader.GetUInt32("id"); + this.createdTime = reader.GetDateTime("created_time"); + this.creatorID = reader.GetUInt64("creator_id"); + this.assignedStaffID = reader.GetUInt64("assigned_staff_id"); + this.summary = reader.GetString("summary"); + this.channelID = reader.GetUInt64("channel_id"); + } - public string FormattedCreatedTime() - { - return createdTime.ToString(Config.timestampFormat); - } - } - public class StaffMember - { - public ulong userID; - public string name; - public bool active; + public string FormattedCreatedTime() + { + return this.createdTime.ToString(Config.timestampFormat); + } + } + public class StaffMember + { + public ulong userID; + public string name; + public bool active; - public StaffMember(MySqlDataReader reader) - { - userID = reader.GetUInt64("user_id"); - name = reader.GetString("name"); - active = reader.GetBoolean("active"); - } - } + public StaffMember(MySqlDataReader reader) + { + this.userID = reader.GetUInt64("user_id"); + this.name = reader.GetString("name"); + this.active = reader.GetBoolean("active"); + } + } - public class Message - { - public string identifier; - public ulong userID; - public string message; + public class Message + { + public string identifier; + public ulong userID; + public string message; - public Message(MySqlDataReader reader) - { - identifier = reader.GetString("identifier"); - userID = reader.GetUInt64("user_id"); - message = reader.GetString("message"); - } - } - } -} + public Message(MySqlDataReader reader) + { + this.identifier = reader.GetString("identifier"); + this.userID = reader.GetUInt64("user_id"); + this.message = reader.GetString("message"); + } + } + } +} \ No newline at end of file diff --git a/SupportChild/EventHandler.cs b/SupportChild/EventHandler.cs index 295d32e..e5f61f8 100644 --- a/SupportChild/EventHandler.cs +++ b/SupportChild/EventHandler.cs @@ -12,296 +12,296 @@ using Microsoft.Extensions.Logging; namespace SupportChild { - internal class EventHandler - { - private DiscordClient discordClient; + internal class EventHandler + { + private DiscordClient discordClient; - //DateTime for the end of the cooldown - private static Dictionary reactionTicketCooldowns = new Dictionary(); + //DateTime for the end of the cooldown + private static Dictionary reactionTicketCooldowns = new Dictionary(); - public EventHandler(DiscordClient client) - { - discordClient = client; - } + public EventHandler(DiscordClient client) + { + this.discordClient = client; + } - internal Task OnReady(DiscordClient client, ReadyEventArgs e) - { - discordClient.Logger.Log(LogLevel.Information, "Client is ready to process events."); + internal Task OnReady(DiscordClient client, ReadyEventArgs e) + { + discordClient.Logger.Log(LogLevel.Information, "Client is ready to process events."); - // Checking activity type - if (!Enum.TryParse(Config.presenceType, true, out ActivityType activityType)) - { - Console.WriteLine("Presence type '" + Config.presenceType + "' invalid, using 'Playing' instead."); - activityType = ActivityType.Playing; - } + // Checking activity type + if (!Enum.TryParse(Config.presenceType, true, out ActivityType activityType)) + { + Console.WriteLine("Presence type '" + Config.presenceType + "' invalid, using 'Playing' instead."); + activityType = ActivityType.Playing; + } - discordClient.UpdateStatusAsync(new DiscordActivity(Config.presenceText, activityType), UserStatus.Online); - return Task.CompletedTask; - } + this.discordClient.UpdateStatusAsync(new DiscordActivity(Config.presenceText, activityType), UserStatus.Online); + return Task.CompletedTask; + } - internal Task OnGuildAvailable(DiscordClient client, GuildCreateEventArgs e) - { - discordClient.Logger.Log(LogLevel.Information, $"Guild available: {e.Guild.Name}"); + internal Task OnGuildAvailable(DiscordClient client, GuildCreateEventArgs e) + { + discordClient.Logger.Log(LogLevel.Information, $"Guild available: {e.Guild.Name}"); - IReadOnlyDictionary roles = e.Guild.Roles; + IReadOnlyDictionary roles = e.Guild.Roles; - foreach ((ulong roleID, DiscordRole role) in roles) - { - discordClient.Logger.Log(LogLevel.Information, role.Name.PadRight(40, '.') + roleID); - } - return Task.CompletedTask; - } + foreach ((ulong roleID, DiscordRole role) in roles) + { + discordClient.Logger.Log(LogLevel.Information, role.Name.PadRight(40, '.') + roleID); + } + return Task.CompletedTask; + } - internal Task OnClientError(DiscordClient client, ClientErrorEventArgs e) - { - discordClient.Logger.Log(LogLevel.Error, $"Exception occured: {e.Exception.GetType()}: {e.Exception}"); + internal Task OnClientError(DiscordClient client, ClientErrorEventArgs e) + { + discordClient.Logger.Log(LogLevel.Error, $"Exception occured: {e.Exception.GetType()}: {e.Exception}"); - return Task.CompletedTask; - } + return Task.CompletedTask; + } - internal async Task OnMessageCreated(DiscordClient client, MessageCreateEventArgs e) - { - if (e.Author.IsBot) - { - return; - } + internal async Task OnMessageCreated(DiscordClient client, MessageCreateEventArgs e) + { + if (e.Author.IsBot) + { + return; + } - // 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; - } + // 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; + } - // 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 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 - { - DiscordEmbed message = new DiscordEmbedBuilder - { - Color = DiscordColor.Green, - Description = "A ticket you are assigned to has been updated: " + e.Channel.Mention - }; + // 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 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 + { + DiscordEmbed message = new DiscordEmbedBuilder + { + Color = DiscordColor.Green, + Description = "A ticket you are assigned to has been updated: " + e.Channel.Mention + }; - DiscordMember staffMember = await e.Guild.GetMemberAsync(ticket.assignedStaffID); - await staffMember.SendMessageAsync(message); - } - catch (NotFoundException) { } - catch (UnauthorizedException) { } - } - } + DiscordMember staffMember = await e.Guild.GetMemberAsync(ticket.assignedStaffID); + await staffMember.SendMessageAsync(message); + } + catch (NotFoundException) { } + catch (UnauthorizedException) { } + } + } - internal Task OnCommandError(CommandsNextExtension commandSystem, CommandErrorEventArgs e) - { - switch (e.Exception) - { - case CommandNotFoundException _: - return Task.CompletedTask; - case ChecksFailedException _: - { - foreach (CheckBaseAttribute attr in ((ChecksFailedException)e.Exception).FailedChecks) - { - DiscordEmbed error = new DiscordEmbedBuilder - { - Color = DiscordColor.Red, - Description = ParseFailedCheck(attr) - }; - e.Context?.Channel?.SendMessageAsync(error); - } - return Task.CompletedTask; - } + internal Task OnCommandError(CommandsNextExtension commandSystem, CommandErrorEventArgs e) + { + switch (e.Exception) + { + case CommandNotFoundException _: + return Task.CompletedTask; + case ChecksFailedException _: + { + foreach (CheckBaseAttribute attr in ((ChecksFailedException)e.Exception).FailedChecks) + { + DiscordEmbed error = new DiscordEmbedBuilder + { + Color = DiscordColor.Red, + Description = this.ParseFailedCheck(attr) + }; + e.Context?.Channel?.SendMessageAsync(error); + } + return Task.CompletedTask; + } - default: - { - discordClient.Logger.Log(LogLevel.Error, $"Exception occured: {e.Exception.GetType()}: {e.Exception}"); - DiscordEmbed error = new DiscordEmbedBuilder - { - Color = DiscordColor.Red, - Description = "Internal error occured, please report this to the developer." - }; - e.Context?.Channel?.SendMessageAsync(error); - return Task.CompletedTask; - } - } - } + default: + { + discordClient.Logger.Log(LogLevel.Error, $"Exception occured: {e.Exception.GetType()}: {e.Exception}"); + DiscordEmbed error = new DiscordEmbedBuilder + { + Color = DiscordColor.Red, + Description = "Internal error occured, please report this to the developer." + }; + e.Context?.Channel?.SendMessageAsync(error); + return Task.CompletedTask; + } + } + } - internal async Task OnReactionAdded(DiscordClient client, MessageReactionAddEventArgs e) - { - if (e.Message.Id != Config.reactionMessage) return; + internal async Task OnReactionAdded(DiscordClient client, MessageReactionAddEventArgs e) + { + if (e.Message.Id != Config.reactionMessage) return; - DiscordGuild guild = e.Message.Channel.Guild; - DiscordMember member = await guild.GetMemberAsync(e.User.Id); + DiscordGuild guild = e.Message.Channel.Guild; + DiscordMember member = await guild.GetMemberAsync(e.User.Id); - if (!Config.HasPermission(member, "new") || Database.IsBlacklisted(member.Id)) return; - if (reactionTicketCooldowns.ContainsKey(member.Id)) - { - if (reactionTicketCooldowns[member.Id] > DateTime.Now) return; // cooldown has not expired - else reactionTicketCooldowns.Remove(member.Id); // cooldown exists but has expired, delete it - } + if (!Config.HasPermission(member, "new") || Database.IsBlacklisted(member.Id)) return; + if (reactionTicketCooldowns.ContainsKey(member.Id)) + { + if (reactionTicketCooldowns[member.Id] > DateTime.Now) return; // cooldown has not expired + else reactionTicketCooldowns.Remove(member.Id); // cooldown exists but has expired, delete it + } - DiscordChannel category = guild.GetChannel(Config.ticketCategory); - DiscordChannel ticketChannel = await guild.CreateChannelAsync("ticket", ChannelType.Text, category); + DiscordChannel category = guild.GetChannel(Config.ticketCategory); + DiscordChannel ticketChannel = await guild.CreateChannelAsync("ticket", ChannelType.Text, category); - if (ticketChannel == null) return; + if (ticketChannel == null) return; - ulong staffID = 0; - if (Config.randomAssignment) - { - staffID = Database.GetRandomActiveStaff(0)?.userID ?? 0; - } + ulong staffID = 0; + if (Config.randomAssignment) + { + staffID = Database.GetRandomActiveStaff(0)?.userID ?? 0; + } - long id = Database.NewTicket(member.Id, staffID, ticketChannel.Id); - reactionTicketCooldowns.Add(member.Id, DateTime.Now.AddSeconds(10)); // add a cooldown which expires in 10 seconds - string ticketID = id.ToString("00000"); + long id = Database.NewTicket(member.Id, staffID, ticketChannel.Id); + reactionTicketCooldowns.Add(member.Id, DateTime.Now.AddSeconds(10)); // add a cooldown which expires in 10 seconds + string ticketID = id.ToString("00000"); - await ticketChannel.ModifyAsync(model => model.Name = "ticket-" + ticketID); - await ticketChannel.AddOverwriteAsync(member, Permissions.AccessChannels, Permissions.None); - await ticketChannel.SendMessageAsync("Hello, " + member.Mention + "!\n" + Config.welcomeMessage); + await ticketChannel.ModifyAsync(model => model.Name = "ticket-" + ticketID); + await ticketChannel.AddOverwriteAsync(member, Permissions.AccessChannels, Permissions.None); + await ticketChannel.SendMessageAsync("Hello, " + member.Mention + "!\n" + Config.welcomeMessage); - // Remove user's reaction - await e.Message.DeleteReactionAsync(e.Emoji, e.User); + // Remove user's reaction + await e.Message.DeleteReactionAsync(e.Emoji, e.User); - // Refreshes the channel as changes were made to it above - ticketChannel = await SupportChild.GetClient().GetChannelAsync(ticketChannel.Id); + // Refreshes the channel as changes were made to it above + ticketChannel = await SupportChild.GetClient().GetChannelAsync(ticketChannel.Id); - if (staffID != 0) - { - DiscordEmbed assignmentMessage = new DiscordEmbedBuilder - { - Color = DiscordColor.Green, - Description = "Ticket was randomly assigned to <@" + staffID + ">." - }; - await ticketChannel.SendMessageAsync(assignmentMessage); + if (staffID != 0) + { + DiscordEmbed assignmentMessage = new DiscordEmbedBuilder + { + Color = DiscordColor.Green, + Description = "Ticket was randomly assigned to <@" + staffID + ">." + }; + await ticketChannel.SendMessageAsync(assignmentMessage); - if (Config.assignmentNotifications) - { - DiscordEmbed message = new DiscordEmbedBuilder - { - Color = DiscordColor.Green, - Description = "You have been randomly assigned to a newly opened support ticket: " + - ticketChannel.Mention - }; + if (Config.assignmentNotifications) + { + DiscordEmbed message = new DiscordEmbedBuilder + { + Color = DiscordColor.Green, + Description = "You have been randomly assigned to a newly opened support ticket: " + + ticketChannel.Mention + }; - try - { - DiscordMember staffMember = await guild.GetMemberAsync(staffID); - await staffMember.SendMessageAsync(message); - } - catch (NotFoundException) - { - } - catch (UnauthorizedException) - { - } - } - } + try + { + DiscordMember staffMember = await guild.GetMemberAsync(staffID); + await staffMember.SendMessageAsync(message); + } + catch (NotFoundException) + { + } + catch (UnauthorizedException) + { + } + } + } - // Log it if the log channel exists - DiscordChannel logChannel = guild.GetChannel(Config.logChannel); - if (logChannel != null) - { - DiscordEmbed logMessage = new DiscordEmbedBuilder - { - Color = DiscordColor.Green, - Description = "Ticket " + ticketChannel.Mention + " opened by " + member.Mention + ".\n", - Footer = new DiscordEmbedBuilder.EmbedFooter { Text = "Ticket " + ticketID } - }; - await logChannel.SendMessageAsync(logMessage); - } - } + // Log it if the log channel exists + DiscordChannel logChannel = guild.GetChannel(Config.logChannel); + if (logChannel != null) + { + DiscordEmbed logMessage = new DiscordEmbedBuilder + { + Color = DiscordColor.Green, + Description = "Ticket " + ticketChannel.Mention + " opened by " + member.Mention + ".\n", + Footer = new DiscordEmbedBuilder.EmbedFooter {Text = "Ticket " + ticketID} + }; + await logChannel.SendMessageAsync(logMessage); + } + } - internal async Task OnMemberAdded(DiscordClient client, GuildMemberAddEventArgs e) - { - if (!Database.TryGetOpenTickets(e.Member.Id, out List ownTickets)) - { - return; - } + internal async Task OnMemberAdded(DiscordClient client, GuildMemberAddEventArgs e) + { + if (!Database.TryGetOpenTickets(e.Member.Id, out List ownTickets)) + { + return; + } - foreach (Database.Ticket ticket in ownTickets) - { - try - { - DiscordChannel channel = await client.GetChannelAsync(ticket.channelID); - if (channel?.GuildId == e.Guild.Id) - { - await channel.AddOverwriteAsync(e.Member, Permissions.AccessChannels, Permissions.None); - DiscordEmbed message = new DiscordEmbedBuilder() - .WithColor(DiscordColor.Green) - .WithDescription("User '" + e.Member.Username + "#" + e.Member.Discriminator + "' has rejoined the server, and has been re-added to the ticket."); - await channel.SendMessageAsync(message); - } - } - catch (Exception) { } - } - } + foreach (Database.Ticket ticket in ownTickets) + { + try + { + DiscordChannel channel = await client.GetChannelAsync(ticket.channelID); + if (channel?.GuildId == e.Guild.Id) + { + await channel.AddOverwriteAsync(e.Member, Permissions.AccessChannels, Permissions.None); + DiscordEmbed message = new DiscordEmbedBuilder() + .WithColor(DiscordColor.Green) + .WithDescription("User '" + e.Member.Username + "#" + e.Member.Discriminator + "' has rejoined the server, and has been re-added to the ticket."); + await channel.SendMessageAsync(message); + } + } + catch (Exception) { } + } + } - internal async Task OnMemberRemoved(DiscordClient client, Guild​Member​Remove​Event​Args e) - { - if (Database.TryGetOpenTickets(e.Member.Id, out List ownTickets)) - { - foreach (Database.Ticket ticket in ownTickets) - { - try - { - DiscordChannel channel = await client.GetChannelAsync(ticket.channelID); - if (channel?.GuildId == e.Guild.Id) - { - DiscordEmbed message = new DiscordEmbedBuilder() - .WithColor(DiscordColor.Red) - .WithDescription("User '" + e.Member.Username + "#" + e.Member.Discriminator + "' has left the server."); - await channel.SendMessageAsync(message); - } - } - catch (Exception) { } - } - } + internal async Task OnMemberRemoved(DiscordClient client, Guild​Member​Remove​Event​Args e) + { + if (Database.TryGetOpenTickets(e.Member.Id, out List ownTickets)) + { + foreach(Database.Ticket ticket in ownTickets) + { + try + { + DiscordChannel channel = await client.GetChannelAsync(ticket.channelID); + if (channel?.GuildId == e.Guild.Id) + { + DiscordEmbed message = new DiscordEmbedBuilder() + .WithColor(DiscordColor.Red) + .WithDescription("User '" + e.Member.Username + "#" + e.Member.Discriminator + "' has left the server."); + await channel.SendMessageAsync(message); + } + } + catch (Exception) { } + } + } - if (Database.TryGetAssignedTickets(e.Member.Id, out List assignedTickets) && Config.logChannel != 0) - { - DiscordChannel logChannel = await client.GetChannelAsync(Config.logChannel); - if (logChannel != null) - { + if (Database.TryGetAssignedTickets(e.Member.Id, out List assignedTickets) && Config.logChannel != 0) + { + DiscordChannel logChannel = await client.GetChannelAsync(Config.logChannel); + if (logChannel != null) + { - foreach (Database.Ticket ticket in assignedTickets) - { - try - { - DiscordChannel channel = await client.GetChannelAsync(ticket.channelID); - if (channel?.GuildId == e.Guild.Id) - { - DiscordEmbed message = new DiscordEmbedBuilder() - .WithColor(DiscordColor.Red) - .WithDescription("Assigned staff member '" + e.Member.Username + "#" + e.Member.Discriminator + "' has left the server: <#" + channel.Id + ">"); - await logChannel.SendMessageAsync(message); - } - } - catch (Exception) { } - } - } - } - } + foreach (Database.Ticket ticket in assignedTickets) + { + try + { + DiscordChannel channel = await client.GetChannelAsync(ticket.channelID); + if (channel?.GuildId == e.Guild.Id) + { + DiscordEmbed message = new DiscordEmbedBuilder() + .WithColor(DiscordColor.Red) + .WithDescription("Assigned staff member '" + e.Member.Username + "#" + e.Member.Discriminator + "' has left the server: <#" + channel.Id + ">"); + await logChannel.SendMessageAsync(message); + } + } + catch (Exception) { } + } + } + } + } - private string ParseFailedCheck(CheckBaseAttribute attr) - { - switch (attr) - { - case CooldownAttribute _: - return "You cannot use do that so often!"; - case RequireOwnerAttribute _: - return "Only the server owner can use that command!"; - case RequirePermissionsAttribute _: - return "You don't have permission to do that!"; - case RequireRolesAttribute _: - return "You do not have a required role!"; - case RequireUserPermissionsAttribute _: - return "You don't have permission to do that!"; - case RequireNsfwAttribute _: - return "This command can only be used in an NSFW channel!"; - default: - return "Unknown Discord API error occured, please try again later."; - } - } - } -} + private string ParseFailedCheck(CheckBaseAttribute attr) + { + switch (attr) + { + case CooldownAttribute _: + return "You cannot use do that so often!"; + case RequireOwnerAttribute _: + return "Only the server owner can use that command!"; + case RequirePermissionsAttribute _: + return "You don't have permission to do that!"; + case RequireRolesAttribute _: + return "You do not have a required role!"; + case RequireUserPermissionsAttribute _: + return "You don't have permission to do that!"; + case RequireNsfwAttribute _: + return "This command can only be used in an NSFW channel!"; + default: + return "Unknown Discord API error occured, please try again later."; + } + } + } +} \ No newline at end of file diff --git a/SupportChild/default_config.yml b/SupportChild/default_config.yml index 4386e1d..8dcb6e8 100644 --- a/SupportChild/default_config.yml +++ b/SupportChild/default_config.yml @@ -1,84 +1,84 @@ -bot: - # Bot token. - token: "" - # Command prefix. - prefix: "-" - # Channel where ticket logs are posted (recommended) - log-channel: 000000000000000000 - # Category where the ticket will be created, it will have the same permissions of that ticket plus read permissions for the user opening the ticket (recommended) - ticket-category: 000000000000000000 - # A message which will open new tickets when users react to it (optional) - reaction-message: 000000000000000000 - # Message posted when a ticket is opened. - welcome-message: "Please describe your issue below, and include all information needed for us to help you." - # Decides what messages are shown in console - # Possible values are: Critical, Error, Warning, Information, Debug. - console-log-level: "Information" - # Format for timestamps in transcripts and google sheets if used - timestamp-format: "yyyy-MM-dd HH:mm" - # Whether or not staff members should be randomly assigned tickets when they are made. Individual staff members can opt out using the toggleactive command. - random-assignment: true - # If set to true the rasssign command will include staff members set as inactive if a specific role is specified in the command. - # This can be useful if you have admins set as inactive to not automatically recieve tickets and then have moderators elevate tickets when needed. - random-assign-role-override: true - # Sets the type of activity for the bot to display in its presence status - # Possible values are: Playing, Streaming, ListeningTo, Watching, Competing - presence-type: "ListeningTo" - # Sets the activity text shown in the bot's status - presence-text: "-new" +bot: + # Bot token. + token: "" + # Command prefix. + prefix: "-" + # Channel where ticket logs are posted (recommended) + log-channel: 000000000000000000 + # Category where the ticket will be created, it will have the same permissions of that ticket plus read permissions for the user opening the ticket (recommended) + ticket-category: 000000000000000000 + # A message which will open new tickets when users react to it (optional) + reaction-message: 000000000000000000 + # Message posted when a ticket is opened. + welcome-message: "Please describe your issue below, and include all information needed for us to help you." + # Decides what messages are shown in console + # Possible values are: Critical, Error, Warning, Information, Debug. + console-log-level: "Information" + # Format for timestamps in transcripts and google sheets if used + timestamp-format: "yyyy-MM-dd HH:mm" + # Whether or not staff members should be randomly assigned tickets when they are made. Individual staff members can opt out using the toggleactive command. + random-assignment: true + # If set to true the rasssign command will include staff members set as inactive if a specific role is specified in the command. + # This can be useful if you have admins set as inactive to not automatically recieve tickets and then have moderators elevate tickets when needed. + random-assign-role-override: true + # Sets the type of activity for the bot to display in its presence status + # Possible values are: Playing, Streaming, ListeningTo, Watching, Competing + presence-type: "ListeningTo" + # Sets the activity text shown in the bot's status + presence-text: "-new" notifications: - # Notifies the assigned staff member when a new message is posted in a ticket if the ticket has been silent for a configurable amount of time - # Other staff members and bots do not trigger this. - ticket-updated: true - # The above notification will only be sent if the ticket has been silent for more than this amount of days. Default is 0.5 days. - ticket-updated-delay: 0.5 - # Notifies staff when they are assigned to tickets - assignment: true - # Notifies the user opening the ticket that their ticket was closed and includes the transcript - closing: true + # Notifies the assigned staff member when a new message is posted in a ticket if the ticket has been silent for a configurable amount of time + # Other staff members and bots do not trigger this. + ticket-updated: true + # The above notification will only be sent if the ticket has been silent for more than this amount of days. Default is 0.5 days. + ticket-updated-delay: 0.5 + # Notifies staff when they are assigned to tickets + assignment: true + # Notifies the user opening the ticket that their ticket was closed and includes the transcript + closing: true database: - # Address and port of the mysql server - address: "127.0.0.1" - port: 3306 - # Name of the database to use - name: "supportbot" - # Username and password for authentication - user: "" - password: "" + # Address and port of the mysql server + address: "127.0.0.1" + port: 3306 + # Name of the database to use + name: "supportchild" + # Username and password for authentication + user: "" + password: "" # Set up which roles are allowed to use different commands. # Example: # new: [ 000000000000000000, 111111111111111111 ] # They are grouped into suggested command groups below for first time setup. permissions: - # Public commands - close: [] - list: [] - new: [] - say: [] - status: [] - summary: [] - transcript: [] - # Moderator commands - add: [] - addmessage: [] - assign: [] - blacklist: [] - listassigned: [] - listoldest: [] - listunassigned: [] - move: [] - rassign: [] - removemessage: [] - setsummary: [] - toggleactive: [] - unassign: [] - unblacklist: [] - # Admin commands - addstaff: [] - reload: [] - removestaff: [] - setticket: [] - unsetticket: [] \ No newline at end of file + # Public commands + close: [] + list: [] + new: [] + say: [] + status: [] + summary: [] + transcript: [] + # Moderator commands + add: [] + addmessage: [] + assign: [] + blacklist: [] + listassigned: [] + listoldest: [] + listunassigned: [] + move: [] + rassign: [] + removemessage: [] + setsummary: [] + toggleactive: [] + unassign: [] + unblacklist: [] + # Admin commands + addstaff: [] + reload: [] + removestaff: [] + setticket: [] + unsetticket: [] \ No newline at end of file