using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using DeukBot4.Database; using DeukBot4.MessageHandlers.CommandHandler.RequestStructure; using DeukBot4.MessageHandlers.Permissions; using DeukBot4.Utilities; using Discord; using Npgsql; namespace DeukBot4.MessageHandlers.CommandHandler { public static class TagStorage { public class ServerTags { private readonly Dictionary Tags = new Dictionary(); private ulong ServerId { get; } public ServerTags(ulong serverId) { ServerId = serverId; } public ServerTags(ulong serverId, Dictionary tags) :this(serverId) { Tags = tags; } private static string CleanKey(string key) { return key.ToLowerInvariant(); } public static readonly string[] ReservedTags = new[] {"create", "delete", "remove"}; public (bool success, string result) AddTag(string key, string value) { var parsedTag = CleanKey(key); if (ReservedTags.Contains(parsedTag)) { return (false, $"You can't use keyword {parsedTag}, that's a reserved tag"); } if (Tags.ContainsKey(parsedTag)) { return (false, "A tag with that name already exists"); } Tags.Add(parsedTag, value); using (var db = new DatabaseConnection()) { using (var command = new NpgsqlCommand()) { command.Connection = db; command.CommandText = "INSERT INTO tags (server_id, key, value) VALUES (@id, @key, @value)"; command.Parameters.AddWithValue("@id", ServerId.ToLong()); command.Parameters.AddWithValue("@key", parsedTag); command.Parameters.AddWithValue("@value", value); command.ExecuteNonQuery(); } } return (true, ""); } public (bool success, string result) RemoveTag(string key) { var parsedTag = CleanKey(key); if (!Tags.ContainsKey(parsedTag)) { return (false, "No tag with that name exists"); } Tags.Remove(parsedTag); using (var db = new DatabaseConnection()) { using (var command = new NpgsqlCommand()) { command.Connection = db; command.CommandText = "DELETE FROM tags WHERE server_id = @id AND key = @key"; command.Parameters.AddWithValue("@id", ServerId.ToLong()); command.Parameters.AddWithValue("@key", parsedTag); var res = command.ExecuteNonQuery(); } } return (true, ""); } public string GetTag(string key) { var parsedTag = CleanKey(key); if (!Tags.TryGetValue(parsedTag, out var value)) { return "No tag by that name exists"; } return value; } public List TagList() { return Tags.Keys.OrderBy(x => x).ToList(); } } private static readonly Dictionary ServerCache = new Dictionary(); public static void BuildTags() { using (var conn = new DatabaseConnection()) { using (var command = new NpgsqlCommand()) { command.Connection = conn; command.CommandText = "SELECT server_id, key, value FROM tags"; var reader = command.ExecuteReader(); var res = new Dictionary>(); while (reader.Read()) { var id = reader.GetInt64(0).ToUlong(); var key = reader.GetString(1); var value = reader.GetString(2); if (!res.TryGetValue(id, out var dic)) { dic = new Dictionary(); res.Add(id, dic); } dic.Add(key, value); } foreach (var dic in res) { ServerCache.Add(dic.Key, new ServerTags(dic.Key, dic.Value)); } } } } public static async Task AddTag(CommandRequest cmd) { var channel = cmd.OriginalMessage.Channel as IGuildChannel; if (channel == null) return; var serverId = channel.GuildId; if (!ServerCache.TryGetValue(serverId, out var serverTags)) { serverTags = new ServerTags(serverId); ServerCache.Add(serverId, serverTags); } var key = cmd.Parameters[0].AsString(); var value = cmd.Parameters[1].AsString(); var result = serverTags.AddTag(key, value); if (!result.success) { cmd.SendSimpleEmbed("Tag Creation", "Something went wrong: " + result.result); } else { cmd.SendSimpleEmbed("Tag Creation","Success! Added tag with key: " + key); } } public static async Task RemoveTag(CommandRequest cmd) { var channel = cmd.OriginalMessage.Channel as IGuildChannel; if (channel == null) return; var serverId = channel.GuildId; if (!ServerCache.TryGetValue(serverId, out var serverTags)) { serverTags = new ServerTags(serverId); ServerCache.Add(serverId, serverTags); } var key = cmd.Parameters[0].AsString(); var result = serverTags.RemoveTag(key); if (!result.success) { cmd.SendSimpleEmbed("Tag Deletion","Something went wrong: " + result.result); } else { cmd.SendSimpleEmbed("Tag Deletion","Success! Removed tag with key: " + key); } } public static async Task GetTag(CommandRequest cmd) { var channel = cmd.OriginalMessage.Channel as IGuildChannel; if (channel == null) return; var serverId = channel.GuildId; if (!ServerCache.TryGetValue(serverId, out var serverTags)) { serverTags = new ServerTags(serverId); ServerCache.Add(serverId, serverTags); } var split = cmd.Parameters[0].AsString().Split(" "); var first = split[0].ToLowerInvariant(); if (first == "create") { var perms = await PermissionValidator.GetUserPermissionLevel(cmd.OriginalMessage); if (perms < PermissionLevel.Helper) return; var keyword = split[1]; var rest = split.Skip(2).ToArray().Join(" "); var result = serverTags.AddTag(keyword, rest); if (!result.success) { cmd.SendSimpleEmbed("Tag Creation", "Something went wrong: " + result.result); } else { cmd.SendSimpleEmbed("Tag Creation","Success! Added tag with key: " + keyword); } return; } if (first == "remove" || first == "delete") { var perms = await PermissionValidator.GetUserPermissionLevel(cmd.OriginalMessage); if (perms < PermissionLevel.Helper) return; var keyword = split[1]; var result = serverTags.RemoveTag(keyword); if (!result.success) { cmd.SendSimpleEmbed("Tag Deletion","Something went wrong: " + result.result); } else { cmd.SendSimpleEmbed("Tag Deletion","Success! Removed tag with key: " + keyword); } return; } cmd.SendMessageAsync(serverTags.GetTag(first)); } public static async Task GetTags(CommandRequest cmd) { var channel = cmd.OriginalMessage.Channel as IGuildChannel; if (channel == null) return; var serverId = channel.GuildId; if (!ServerCache.TryGetValue(serverId, out var serverTags)) { return; } var tags = serverTags.TagList(); var eb = EmbedFactory.GetStandardEmbedBuilder(); eb.Title = "This Server Has The Following Tags"; eb.Description = tags.Join("\n"); cmd.OriginalMessage.Channel.SendMessageAsync("", embed: eb.Build()); } } }