diff --git a/Models/ReactionRoleModels.cs b/Models/ReactionRoleModels.cs new file mode 100644 index 0000000..6aa9f5a --- /dev/null +++ b/Models/ReactionRoleModels.cs @@ -0,0 +1,13 @@ +namespace Reactor.Models +{ + public class ReactionMessage + { + public long Id { get; set; } + public long PlanetId { get; set; } + public long ChannelId { get; set; } + public long MessageId { get; set; } + public int DeleteDelaySeconds { get; set; } = 5; + + public Dictionary Reactions { get; set; } = new(); + } +} \ No newline at end of file diff --git a/Services/BotService.cs b/Services/BotService.cs index 8c22ed7..fd6f93c 100644 --- a/Services/BotService.cs +++ b/Services/BotService.cs @@ -30,6 +30,8 @@ namespace Reactor.Services //Initialize the Database await DatabaseService.InitializeAsync(); + await ReactionRoleService.LoadAllAsync(); + Console.WriteLine($"Loaded {ReactionRoleService.Messages.Count} reaction messages into memory."); //Initialize the Planets await PlanetService.InitializePlanetsAsync(client, channelCache, initializedPlanets); diff --git a/Services/DatabaseService.cs b/Services/DatabaseService.cs index ae69190..771d3a9 100644 --- a/Services/DatabaseService.cs +++ b/Services/DatabaseService.cs @@ -1,4 +1,3 @@ -using System.Linq.Expressions; using Microsoft.Data.Sqlite; namespace Reactor.Services diff --git a/Services/ReactionRoleService.cs b/Services/ReactionRoleService.cs new file mode 100644 index 0000000..4573511 --- /dev/null +++ b/Services/ReactionRoleService.cs @@ -0,0 +1,81 @@ +using Microsoft.Data.Sqlite; +using Reactor.Models; + +namespace Reactor.Services +{ + public static class ReactionRoleService + { + private static readonly string _connectionString = "Data source=reactor.db"; + + //Memory Cache + public static Dictionary Messages { get; private set; } = new(); + + //Load all messages and reaction role mappings + public static async Task LoadAllAsync() + { + Messages.Clear(); + + using var connection = new SqliteConnection(_connectionString); + await connection.OpenAsync(); + + //Load messages + var cmdMsg = connection.CreateCommand(); + cmdMsg.CommandText = "SELECT Id, PlanetId, ChannelId, MessageId, DeleteDelaySeconds FROM ReactionMessages"; + using var readerMsg = await cmdMsg.ExecuteReaderAsync(); + var tempMessages = new Dictionary(); + + while (await readerMsg.ReadAsync()) + { + var msg = new ReactionMessage + { + Id = readerMsg.GetInt64(0), + PlanetId = readerMsg.GetInt64(1), + ChannelId = readerMsg.GetInt64(2), + MessageId = readerMsg.GetInt64(3), + DeleteDelaySeconds = readerMsg.GetInt32(4), + Reactions = new Dictionary() + }; + tempMessages[msg.Id] = msg; + } + + //Load reaction role mappings + var cmdRoles = connection.CreateCommand(); + cmdRoles.CommandText = "SELECT ReactionMessageId, Emoji, RoleId FROM ReactionRoles"; + using var readerRoles = await cmdRoles.ExecuteReaderAsync(); + while (await readerRoles.ReadAsync()) + { + var msgId = readerRoles.GetInt64(0); + var emoji = readerRoles.GetString(1); + var roleId = readerRoles.GetInt64(2); + + if (tempMessages.ContainsKey(msgId)) + { + tempMessages[msgId].Reactions[emoji] = roleId; + } + } + + //Build lookup by MessageId + Messages = tempMessages.Values.ToDictionary(m => m.MessageId, m => m); + } + + public static async Task AddReactionAsync(long messageId, string emoji, long roleId) + { + if (!Messages.TryGetValue(messageId, out var msg)) + return; + + using var connection = new SqliteConnection(_connectionString); + await connection.OpenAsync(); + + var cmd = connection.CreateCommand(); + cmd.CommandText = "INSERT INTO ReactionRoles (ReactionMessageId, Emoji, RoleId) VALUES (@msgId, @emoji, @roleId)"; + cmd.Parameters.AddWithValue("@msgId", msg.Id); + cmd.Parameters.AddWithValue("@emoji", emoji); + cmd.Parameters.AddWithValue("@roleId", roleId); + + await cmd.ExecuteNonQueryAsync(); + + //Update Cache + msg.Reactions[emoji] = roleId; + } + } +} \ No newline at end of file