diff --git a/bot.csproj b/bot.csproj index 8c94810..e69c23d 100644 --- a/bot.csproj +++ b/bot.csproj @@ -12,6 +12,12 @@ + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/commands/napiszar.cs b/commands/napiszar.cs new file mode 100644 index 0000000..0447649 --- /dev/null +++ b/commands/napiszar.cs @@ -0,0 +1,25 @@ +using DSharpPlus.CommandsNext; +using DSharpPlus.CommandsNext.Attributes; +using System.Threading.Tasks; +using T3k3rg0.Helpers; + +namespace T3k3rg0.Commands +{ + public class Napiszar : BaseCommandModule + { + [Command("napiszar")] + [Description("Elküld egy napiszart.")] + public async Task GetNapiszar(CommandContext ctx) + { + if (NapiszarService.HasUsedToday(ctx.User.Id)) + { + await ctx.RespondAsync("Ma már megkaptad a szarodat"); + return; + } + + string napiszar = NapiszarService.GetRandomSzar(); + NapiszarService.LogUsage(ctx.User.Id); + await ctx.RespondAsync(napiszar); + } + } +} diff --git a/commands/reactionrolemanager.cs b/commands/reactionrolemanager.cs index 06feab1..8058f20 100644 --- a/commands/reactionrolemanager.cs +++ b/commands/reactionrolemanager.cs @@ -2,6 +2,7 @@ using DSharpPlus.CommandsNext; using DSharpPlus.CommandsNext.Attributes; using DSharpPlus.Entities; using System.Threading.Tasks; +using System.Text; using T3k3rg0.Helpers; namespace T3k3rg0.Commands @@ -11,56 +12,66 @@ namespace T3k3rg0.Commands [Command("addreactionrole")] [Description("Hozzáad egy új reaction role-t ! reactionrole <üzenet> <@szerep>")] [HasAdminRole] - public async Task AddReactionRole(CommandContext ctx, string channelInput, string messageInput, string emojiInput, DiscordRole role) + public async Task AddReactionRole(CommandContext ctx, string messageLink, DiscordEmoji emoji, DiscordRole role) { - var channel = await IdExtractor.ExtractChannelId(channelInput, ctx.Client); - if (channel == null) + var channel = await IdExtractor.ExtractChannelId(messageLink, ctx.Client); + if (channel is null) + { return; + } - var message = await IdExtractor.ExtractMessageId(messageInput, channel); - if (message == null) - return; - - var emoji = await EmojiExtractor.ExtractAsync(emojiInput, ctx.Client); - if (emoji == null) - return; - - bool inserted = ReactionRoleStorage.TryAddReactionRole(message.Id, emoji.ToString(), role.Id); - if (!inserted) + var message = await IdExtractor.ExtractMessageId(messageLink, channel); + if (message is null) + { return; + } + ReactionRoleService.AddReactionRole(message.Id, emoji.ToString(), role.Id); await message.CreateReactionAsync(emoji); } + [Command("removereactionrole")] - [Description("Eltávolít egy meglévő reaction role-t ! removereactionrole <üzenet> ")] + [Description("Eltávolít egy meglévő reaction role-t ! removereactionrole ")] [HasAdminRole] - public async Task RemoveReactionRole(CommandContext ctx, string channelInput, string messageInput, string emojiInput) + public async Task RemoveReactionRole(CommandContext ctx, int id) { - var channel = await IdExtractor.ExtractChannelId(channelInput, ctx.Client); - if (channel == null) + var result = await ReactionRoleService.RemoveReactionRoleByIdAsync(id); + + if (!result.Success) { + await ctx.RespondAsync(result.Message ?? "❌ Ismeretlen hiba történt."); return; } - var message = await IdExtractor.ExtractMessageId(messageInput, channel); - if (message == null) + await ctx.RespondAsync(result.Message ?? $"✅ A(z) {id}. reakció szerepkör törölve."); + } + [Command("listreactionrole")] + [Description("Felsorolja a reaction role párosításokat.")] + [HasAdminRole] + public async Task ListReactionRoles(CommandContext ctx) + { + // Lekérjük az összes reakció alapú szerepkört az adatbázisból + var allRoles = ReactionRoleService.GetAllReactionRoles(); + + if (allRoles.Count == 0) { + await ctx.RespondAsync("❌ Nincs reakció alapú szerepkör a szerveren."); return; } - var emoji = await EmojiExtractor.ExtractAsync(emojiInput, ctx.Client); - if (emoji == null) + var sb = new StringBuilder(); + sb.AppendLine("📜 Reakció alapú szerepkörök:"); + + // Az összes szerepkör kiírása sorszámozva + int index = 1; + foreach (var role in allRoles) { - return; + var roleObj = ctx.Guild.GetRole(role.RoleId); // Az adott szerepkör lekérése + sb.AppendLine($"{index}. Üzenet ID: {role.MessageId}, Emoji: {role.Emoji}, Szerepkör: {roleObj?.Name ?? "Nincs név"}"); + index++; // Növeljük a sorszámot } - bool removed = ReactionRoleStorage.TryRemoveReactionRole(message.Id, emoji.ToString()); - if (!removed) - { - return; - } - - await message.DeleteOwnReactionAsync(emoji); + await ctx.RespondAsync(sb.ToString()); } } } diff --git a/helpers/dbcontext.cs b/helpers/dbcontext.cs new file mode 100644 index 0000000..14555cf --- /dev/null +++ b/helpers/dbcontext.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.EntityFrameworkCore; +using T3k3rg0.Helpers.Models; + +namespace T3k3rg0.Helpers.Data +{ + public static class DbPaths + { + public static readonly string napiszarDbPath = Environment.GetEnvironmentVariable("DB_NAPISZAR_LOC"); + public static readonly string rolesDbPath = Environment.GetEnvironmentVariable("DB_ROLES_LOC"); + } + + public class NapiszarDbContext : DbContext + { + public DbSet Joslatok { get; set; } + public DbSet DailyUsages { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite($"Data Source={DbPaths.napiszarDbPath}"); + } + } + + public class RolesDbContext : DbContext + { + public DbSet ReactionRoles { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasKey(r => new { r.MessageId, r.Emoji }); + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite($"Data Source={DbPaths.rolesDbPath}"); + } + } +} + diff --git a/helpers/dbmodels.cs b/helpers/dbmodels.cs new file mode 100644 index 0000000..95bc98f --- /dev/null +++ b/helpers/dbmodels.cs @@ -0,0 +1,42 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace T3k3rg0.Helpers.Models +{ + [Table("joslatok")] + public class Joslat + { + [Key] + [Column("id")] + public int Id { get; set; } + + [Column("szoveg")] + public string Szoveg { get; set; } + } + + [Table("daily_usage")] + public class DailyUsage + { + [Key] + [Column("user_id")] + public long UserId { get; set; } + + [Column("last_used")] + public DateTime LastUsed { get; set; } + } + + [Table("reaction_roles")] + public class ReactionRole + { + [Key, Column("message_id", Order = 0)] + public ulong MessageId { get; set; } + + [Key, Column("emoji", Order = 1)] + public string Emoji { get; set; } + + [Column("role_id")] + public ulong RoleId { get; set; } + } +} + diff --git a/helpers/napiszarservice.cs b/helpers/napiszarservice.cs new file mode 100644 index 0000000..48bf085 --- /dev/null +++ b/helpers/napiszarservice.cs @@ -0,0 +1,65 @@ +using System; +using System.Linq; +using T3k3rg0.Helpers.Data; +using T3k3rg0.Helpers.Models; + +namespace T3k3rg0.Helpers +{ + public static class NapiszarService + { + private static readonly TimeZoneInfo HungarianTimeZone = + TimeZoneInfo.FindSystemTimeZoneById("Europe/Budapest"); + + public static string GetRandomSzar() + { + using var db = new NapiszarDbContext(); + var count = db.Joslatok.Count(); + + if (count == 0) + return "Nincs elérhető szar"; + + var rnd = new Random(); + var skip = rnd.Next(count); + + var szar = db.Joslatok.Skip(skip).FirstOrDefault(); + return szar?.Szoveg ?? "Valami szar hiba történt"; + } + + public static bool HasUsedToday(ulong userId) + { + using var db = new NapiszarDbContext(); + + var usage = db.DailyUsages.FirstOrDefault(u => u.UserId == (long)userId); + if (usage == null) + return false; + + var today = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, HungarianTimeZone).Date; + return usage.LastUsed.Date == today; + } + + public static void LogUsage(ulong userId) + { + using var db = new NapiszarDbContext(); + + var today = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, HungarianTimeZone); + + var existing = db.DailyUsages.FirstOrDefault(u => u.UserId == (long)userId); + if (existing == null) + { + db.DailyUsages.Add(new DailyUsage + { + UserId = (long)userId, + LastUsed = today + }); + } + else + { + existing.LastUsed = today; + db.DailyUsages.Update(existing); + } + + db.SaveChanges(); + } + } +} + diff --git a/helpers/reactionroleservice.cs b/helpers/reactionroleservice.cs new file mode 100644 index 0000000..9a55f66 --- /dev/null +++ b/helpers/reactionroleservice.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using T3k3rg0.Helpers.Data; +using T3k3rg0.Helpers.Models; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; + +namespace T3k3rg0.Helpers +{ + public static class ReactionRoleService + { + public static ulong? GetRoleId(ulong messageId, string emoji) + { + using var db = new RolesDbContext(); + var entry = db.ReactionRoles + .FirstOrDefault(r => r.MessageId == messageId && r.Emoji == emoji); + + return entry?.RoleId; + } + + public static List<(string Emoji, ulong RoleId)> GetAllRolesForMessage(ulong messageId) + { + using var db = new RolesDbContext(); + return db.ReactionRoles + .Where(r => r.MessageId == messageId) + .ToList() + .Select(r => (r.Emoji, r.RoleId)) + .ToList(); + } + + public static void AddReactionRole(ulong messageId, string emoji, ulong roleId) + { + using var db = new RolesDbContext(); + db.ReactionRoles.Add(new ReactionRole + { + MessageId = messageId, + Emoji = emoji, + RoleId = roleId + }); + db.SaveChanges(); + } + + public static void RemoveReactionRole(ulong messageId, string emoji) + { + using var db = new RolesDbContext(); + var entry = db.ReactionRoles + .FirstOrDefault(r => r.MessageId == messageId && r.Emoji == emoji); + + if (entry != null) + { + db.ReactionRoles.Remove(entry); + db.SaveChanges(); + } + } + + public static List GetAllReactionRoles() + { + using var db = new RolesDbContext(); + return db.ReactionRoles.ToList(); // Minden rekord lekérése az adatbázisból + } + public static async Task> GetAllReactionRolesAsync() + { + await using var db = new RolesDbContext(); + return await db.ReactionRoles + .OrderBy(r => r.MessageId) + .ThenBy(r => r.Emoji) + .ToListAsync(); + } + + public static async Task<(bool Success, string? Message, string? Emoji, ulong? RoleId)> RemoveReactionRoleByIdAsync(int id) + { + try + { + await using var db = new RolesDbContext(); + + var allRoles = (await db.ReactionRoles.ToListAsync()) + .OrderBy(r => r.MessageId) + .ThenBy(r => r.Emoji) + .ToList(); + + if (id < 1 || id > allRoles.Count) + return (false, "❌ Érvénytelen ID.", null, null); + + var toRemove = allRoles[id - 1]; + db.ReactionRoles.Remove(toRemove); + await db.SaveChangesAsync(); + + return (true, null, toRemove.Emoji, toRemove.RoleId); + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + return (false, "❌ Hiba történt az eltávolítás során.", null, null); + } + } + } +} + diff --git a/helpers/reactionrolestorage.cs b/helpers/reactionrolestorage.cs deleted file mode 100644 index dae5288..0000000 --- a/helpers/reactionrolestorage.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Microsoft.Data.Sqlite; -using System; - -namespace T3k3rg0.Helpers -{ - public static class ReactionRoleStorage - { - private static readonly string DbPath = Environment.GetEnvironmentVariable("DB_ROLES_LOC"); - - public static ulong? GetRoleId(ulong messageId, string emojiRaw) - { - using var conn = new SqliteConnection($"Data Source={DbPath}"); - conn.Open(); - - using var cmd = conn.CreateCommand(); - cmd.CommandText = @" - SELECT role_id FROM reaction_roles - WHERE message_id = @msg AND emoji = @emoji"; - cmd.Parameters.AddWithValue("@msg", (long)messageId); - cmd.Parameters.AddWithValue("@emoji", emojiRaw); - - using var reader = cmd.ExecuteReader(); - if (reader.Read()) - { - return (ulong)(long)reader["role_id"]; - } - - return null; - } - - public static bool TryAddReactionRole(ulong messageId, string emojiRaw, ulong roleId) - { - using var conn = new SqliteConnection($"Data Source={DbPath}"); - conn.Open(); - - using var cmd = conn.CreateCommand(); - cmd.CommandText = @" - INSERT OR IGNORE INTO reaction_roles (message_id, emoji, role_id) - VALUES (@msg, @emoji, @role)"; - cmd.Parameters.AddWithValue("@msg", (long)messageId); - cmd.Parameters.AddWithValue("@emoji", emojiRaw); - cmd.Parameters.AddWithValue("@role", (long)roleId); - - int rowsAffected = cmd.ExecuteNonQuery(); - return rowsAffected > 0; - } - - public static bool TryRemoveReactionRole(ulong messageId, string emojiRaw) - { - using var conn = new SqliteConnection($"Data Source={DbPath}"); - conn.Open(); - - using var cmd = conn.CreateCommand(); - cmd.CommandText = @" - DELETE FROM reaction_roles - WHERE message_id = @msg AND emoji = @emoji"; - cmd.Parameters.AddWithValue("@msg", (long)messageId); - cmd.Parameters.AddWithValue("@emoji", emojiRaw); - - int rowsAffected = cmd.ExecuteNonQuery(); - return rowsAffected > 0; - } - } -} - diff --git a/program.cs b/program.cs index f4aa47b..9166407 100644 --- a/program.cs +++ b/program.cs @@ -34,6 +34,7 @@ namespace T3k3rg0 commands.RegisterCommands(); commands.RegisterCommands(); commands.RegisterCommands(); + commands.RegisterCommands(); ReactionRoleHandler.Register(discord); await discord.ConnectAsync();