From 137fb3da5da0a2ed0290501e98391665cf7482ce Mon Sep 17 00:00:00 2001 From: SylveonDeko <59923820+SylveonDeko@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:44:46 -0400 Subject: [PATCH] Fix commandstats, add removemessagecount which can remove by user, channel, for the guild, per channel and user. Completely map out db and waste time thinking nativeaot would be a good idea, would not have worked anyway. --- .../Extensions/GuildConfigExtensions.cs | 2 - src/Mewdeko/Database/MewdekoContext.cs | 1071 +++++++++++++---- src/Mewdeko/Database/Models/GuildConfig.cs | 4 - src/Mewdeko/Database/Models/LogSetting.cs | 234 ---- .../Services/LogCommandService.cs | 8 - src/Mewdeko/Modules/OwnerOnly/OwnerOnly.cs | 36 +- .../Modules/Utility/MessageCountCommands.cs | 55 + .../Utility/Services/MessageCountService.cs | 67 ++ src/Mewdeko/Modules/Utility/Utility.cs | 44 +- src/Mewdeko/Program.cs | 2 +- src/Mewdeko/data/aliases.yml | 6 + .../data/strings/commands/commands.en-US.yml | 8 + .../strings/responses/responses.en-US.json | 13 + 13 files changed, 1005 insertions(+), 545 deletions(-) delete mode 100644 src/Mewdeko/Database/Models/LogSetting.cs diff --git a/src/Mewdeko/Database/Extensions/GuildConfigExtensions.cs b/src/Mewdeko/Database/Extensions/GuildConfigExtensions.cs index 297c2c480..f50073c25 100644 --- a/src/Mewdeko/Database/Extensions/GuildConfigExtensions.cs +++ b/src/Mewdeko/Database/Extensions/GuildConfigExtensions.cs @@ -194,8 +194,6 @@ public static IQueryable IncludeEverything(this DbSet { return config .AsQueryable() - .Include(gc => gc.LogSetting) - .ThenInclude(gc => gc.IgnoredChannels) .Include(gc => gc.Permissions) .Include(gc => gc.CommandCooldowns) .Include(gc => gc.GuildRepeaters) diff --git a/src/Mewdeko/Database/MewdekoContext.cs b/src/Mewdeko/Database/MewdekoContext.cs index 39627c2ba..685c9f982 100644 --- a/src/Mewdeko/Database/MewdekoContext.cs +++ b/src/Mewdeko/Database/MewdekoContext.cs @@ -25,11 +25,12 @@ public MewdekoContext(DbContextOptions options) : base(options) public DbSet GlobalUserBalances { get; set; } /// - /// Gets or sets invite counts + /// Gets or sets invite counts /// public DbSet InviteCounts { get; set; } + /// - /// Gets or sets invited by + /// Gets or sets invited by /// public DbSet InvitedBy { get; set; } @@ -129,7 +130,7 @@ public MewdekoContext(DbContextOptions options) : base(options) public DbSet AutoBanRoles { get; set; } /// - /// Logging settings for guilds + /// Logging settings for guilds /// public DbSet LoggingV2 { get; set; } @@ -313,11 +314,6 @@ public MewdekoContext(DbContextOptions options) : base(options) /// public DbSet CommandAliases { get; set; } - /// - /// Gets or sets the log settings. - /// - public DbSet LogSettings { get; set; } - /// /// Gets or sets the ignored log channels. /// @@ -424,12 +420,12 @@ public MewdekoContext(DbContextOptions options) : base(options) public DbSet WarningPunishments2 { get; set; } /// - /// gets or sets the local running instances, for dashboard management. + /// gets or sets the local running instances, for dashboard management. /// public DbSet BotInstances { get; set; } /// - /// Settings for invite counting + /// Settings for invite counting /// public DbSet InviteCountSettings { get; set; } @@ -442,7 +438,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); - if (creds.MigrateToPsql) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) @@ -461,406 +456,974 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) #region Afk var afkEntity = modelBuilder.Entity(); - afkEntity.Property(x => x.WasTimed) - .HasDefaultValue(false); + afkEntity.HasKey(x => x.Id); + afkEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + afkEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + afkEntity.Property(x => x.WasTimed).HasDefaultValue(false); + afkEntity.Property(x => x.Message).HasColumnType("text").IsRequired(false); + afkEntity.Property(x => x.When).HasColumnType("timestamp without time zone").IsRequired(false); + afkEntity.HasIndex(x => new + { + x.GuildId, x.UserId + }); #endregion - #region AntiProtection + #region AntiRaidSetting - modelBuilder.Entity() - .Property(x => x.AntiSpamSettingId) - .IsRequired(false); + var antiRaidSettingEntity = modelBuilder.Entity(); + antiRaidSettingEntity.HasKey(x => x.Id); + antiRaidSettingEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + antiRaidSettingEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + antiRaidSettingEntity.Property(x => x.UserThreshold).HasColumnType("integer"); + antiRaidSettingEntity.Property(x => x.Seconds).HasColumnType("integer"); + antiRaidSettingEntity.Property(x => x.PunishDuration).HasColumnType("integer"); + antiRaidSettingEntity.Property(x => x.Action).HasConversion(); #endregion - #region ChatTriggers + #region AntiSpamSetting - var chatTriggerEntity = modelBuilder.Entity(); - chatTriggerEntity.Property(x => x.IsRegex) - .HasDefaultValue(false); + var antiSpamSettingEntity = modelBuilder.Entity(); + antiSpamSettingEntity.HasKey(x => x.Id); + antiSpamSettingEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + antiSpamSettingEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + antiSpamSettingEntity.Property(x => x.MessageThreshold).HasColumnType("integer"); + antiSpamSettingEntity.Property(x => x.MuteTime).HasColumnType("integer"); + antiSpamSettingEntity.Property(x => x.RoleId).HasColumnType("numeric(20, 0)").IsRequired(false); + antiSpamSettingEntity.Property(x => x.Action).HasConversion(); - chatTriggerEntity.Property(x => x.OwnerOnly) - .HasDefaultValue(false); + #endregion - chatTriggerEntity.Property(x => x.AutoDeleteTrigger) - .HasDefaultValue(false); + #region AntiMassMentionSetting + + var antiMassMentionEntity = modelBuilder.Entity(); + antiMassMentionEntity.HasKey(x => x.Id); + antiMassMentionEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + antiMassMentionEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + antiMassMentionEntity.Property(x => x.MentionThreshold).HasColumnType("integer"); + antiMassMentionEntity.Property(x => x.MaxMentionsInTimeWindow).HasColumnType("integer"); + antiMassMentionEntity.Property(x => x.TimeWindowSeconds).HasColumnType("integer"); + antiMassMentionEntity.Property(x => x.MuteTime).HasColumnType("integer"); + antiMassMentionEntity.Property(x => x.RoleId).HasColumnType("numeric(20, 0)").IsRequired(false); + antiMassMentionEntity.Property(x => x.IgnoreBots).HasDefaultValue(true); + antiMassMentionEntity.Property(x => x.Action).HasConversion(); - chatTriggerEntity.Property(x => x.ReactToTrigger) - .HasDefaultValue(false); + #endregion - chatTriggerEntity.Property(x => x.NoRespond) - .HasDefaultValue(false); + #region AntiAltSetting - chatTriggerEntity.Property(x => x.DmResponse) - .HasDefaultValue(false); + var antiAltSettingEntity = modelBuilder.Entity(); + antiAltSettingEntity.HasKey(x => x.Id); + antiAltSettingEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + antiAltSettingEntity.Property(x => x.MinAge).HasColumnType("text").IsRequired(false); + antiAltSettingEntity.Property(x => x.Action).HasConversion(); + antiAltSettingEntity.Property(x => x.ActionDurationMinutes).HasColumnType("integer"); + antiAltSettingEntity.Property(x => x.RoleId).HasColumnType("numeric(20, 0)").IsRequired(false); - chatTriggerEntity.Property(x => x.ContainsAnywhere) - .HasDefaultValue(false); + #endregion - chatTriggerEntity.Property(x => x.AllowTarget) - .HasDefaultValue(false); + #region AutoBanRoles + + var autoBanRolesEntity = modelBuilder.Entity(); + autoBanRolesEntity.HasKey(x => x.Id); + autoBanRolesEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + autoBanRolesEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + autoBanRolesEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)"); + autoBanRolesEntity.Property(x => x.RoleId).HasColumnType("numeric(20, 0)"); #endregion - #region CommandStats + #region AutoCommand - var commandStatsEntity = modelBuilder.Entity(); + var autoCommandEntity = modelBuilder.Entity(); + autoCommandEntity.HasKey(x => x.Id); + autoCommandEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + autoCommandEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + autoCommandEntity.Property(x => x.CommandText).HasColumnType("text").IsRequired(false); + autoCommandEntity.Property(x => x.ChannelId).HasColumnType("numeric(20, 0)"); + autoCommandEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(false); + autoCommandEntity.Property(x => x.VoiceChannelId).HasColumnType("numeric(20, 0)").IsRequired(false); + autoCommandEntity.Property(x => x.Interval).HasColumnType("integer"); - commandStatsEntity.Property(x => x.IsSlash) - .HasDefaultValue(false); + #endregion - commandStatsEntity.Property(x => x.Trigger) - .HasDefaultValue(false); + #region BotReviews - commandStatsEntity.Property(x => x.Module) - .IsRequired(false); + var botReviewsEntity = modelBuilder.Entity(); + botReviewsEntity.HasKey(x => x.Id); + botReviewsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + botReviewsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + botReviewsEntity.Property(x => x.Username).HasColumnType("text"); + botReviewsEntity.Property(x => x.AvatarUrl).HasColumnType("text").HasDefaultValue(string.Empty); + botReviewsEntity.Property(x => x.Stars).HasColumnType("integer"); - commandStatsEntity.Property(x => x.Module) - .HasDefaultValue(""); + #endregion + + #region CommandCooldown + + var commandCooldownEntity = modelBuilder.Entity(); + commandCooldownEntity.HasKey(x => x.Id); + commandCooldownEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + commandCooldownEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + commandCooldownEntity.Property(x => x.CommandName).HasColumnType("text").IsRequired(false); #endregion - #region CommandAliases + #region CommandStats - modelBuilder.Entity() - .Property(x => x.GuildConfigId) - .IsRequired(false); + var commandStatsEntity = modelBuilder.Entity(); + commandStatsEntity.HasKey(x => x.Id); + commandStatsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + commandStatsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + commandStatsEntity.Property(x => x.NameOrId).HasColumnType("text").HasDefaultValue(""); + commandStatsEntity.Property(x => x.Module).HasColumnType("text").HasDefaultValue(""); + commandStatsEntity.Property(x => x.IsSlash).HasDefaultValue(false); + commandStatsEntity.Property(x => x.Trigger).HasDefaultValue(false); + commandStatsEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)"); + commandStatsEntity.Property(x => x.ChannelId).HasColumnType("numeric(20, 0)"); + commandStatsEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)"); #endregion - #region DelMsgOnCmdChannel + #region DiscordUser - var delMsgOnCmdChannelEntity = modelBuilder.Entity(); + var discordUserEntity = modelBuilder.Entity(); + discordUserEntity.HasKey(x => x.Id); + discordUserEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + discordUserEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + discordUserEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)"); + discordUserEntity.Property(x => x.Username).HasColumnType("text").IsRequired(false); + discordUserEntity.Property(x => x.Discriminator).HasColumnType("text").IsRequired(false); + discordUserEntity.Property(x => x.AvatarId).HasColumnType("text").IsRequired(false); + discordUserEntity.Property(x => x.TotalXp).HasColumnType("integer"); + discordUserEntity.Property(x => x.LastLevelUp).HasColumnType("timestamp without time zone").IsRequired(false); + discordUserEntity.Property(x => x.Birthday).HasColumnType("timestamp without time zone").IsRequired(false); + discordUserEntity.Property(x => x.ProfilePrivacy).HasConversion(); + + #endregion - delMsgOnCmdChannelEntity.Property(x => x.State) - .HasDefaultValue(true); + #region Highlights + + var highlightEntity = modelBuilder.Entity(); + highlightEntity.HasKey(x => x.Id); + highlightEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + highlightEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + highlightEntity.Property(x => x.Word).HasColumnType("text").IsRequired(false); + highlightEntity.HasIndex(x => new + { + x.GuildId, x.UserId + }); #endregion - #region QUOTES + #region HighlightSettings - var quoteEntity = modelBuilder.Entity(); - quoteEntity.HasIndex(x => x.GuildId); - quoteEntity.HasIndex(x => x.Keyword); + var highlightSettingsEntity = modelBuilder.Entity(); + highlightSettingsEntity.HasKey(x => x.Id); + highlightSettingsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + highlightSettingsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + highlightSettingsEntity.Property(x => x.IgnoredChannels).HasColumnType("text").IsRequired(false); + highlightSettingsEntity.Property(x => x.IgnoredUsers).HasColumnType("text").IsRequired(false); + highlightSettingsEntity.Property(x => x.HighlightsOn).HasDefaultValue(false); #endregion - #region GuildConfig + #region IgnoredLogChannel - modelBuilder.Entity() - .Property(x => x.GuildConfigId) - .IsRequired(false); + var ignoredLogChannelEntity = modelBuilder.Entity(); + ignoredLogChannelEntity.HasKey(x => x.Id); + ignoredLogChannelEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + ignoredLogChannelEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + ignoredLogChannelEntity.HasIndex(x => x.ChannelId); - var configEntity = modelBuilder.Entity(); - configEntity - .HasIndex(c => c.GuildId) - .IsUnique(); + #endregion - configEntity.HasOne(x => x.AntiSpamSetting) - .WithOne() - .HasForeignKey(x => x.GuildConfigId) - .OnDelete(DeleteBehavior.Cascade); + #region InviteCount - configEntity.HasOne(x => x.AntiRaidSetting) - .WithOne() - .HasForeignKey(x => x.GuildConfigId) - .OnDelete(DeleteBehavior.Cascade); + var inviteCountEntity = modelBuilder.Entity(); + inviteCountEntity.HasKey(x => x.Id); + inviteCountEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + inviteCountEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + inviteCountEntity.Property(x => x.Count).HasColumnType("integer"); - configEntity.Property(x => x.LogSettingId) - .IsRequired(false); + #endregion - modelBuilder.Entity() - .HasOne(x => x.AntiAltSetting) - .WithOne() - .HasForeignKey(x => x.GuildConfigId) - .OnDelete(DeleteBehavior.Cascade); + #region InviteCountSettings - modelBuilder.Entity() - .HasAlternateKey(x => new - { - x.GuildConfigId, x.Url - }); + var inviteCountSettingsEntity = modelBuilder.Entity(); + inviteCountSettingsEntity.HasKey(x => x.Id); + inviteCountSettingsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + inviteCountSettingsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + inviteCountSettingsEntity.Property(x => x.MinAccountAge).HasColumnType("interval"); - configEntity.HasIndex(x => x.WarnExpireHours) - .IsUnique(false); + #endregion - configEntity.Property(x => x.DeleteMessageOnCommand) - .HasDefaultValue(false); + #region InvitedBy - configEntity.Property(x => x.StatsOptOut) - .HasDefaultValue(false); + var invitedByEntity = modelBuilder.Entity(); + invitedByEntity.HasKey(x => x.Id); + invitedByEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + invitedByEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + invitedByEntity.HasIndex(x => new + { + x.UserId, x.InviterId, x.GuildId + }); - configEntity.Property(x => x.DmOnGiveawayWin) - .HasDefaultValue(true); + #endregion - configEntity.Property(x => x.SendDmGreetMessage) - .HasDefaultValue(false); + #region JoinLeaveLogs - configEntity.Property(x => x.SendChannelGreetMessage) - .HasDefaultValue(false); + var joinLeaveLogsEntity = modelBuilder.Entity(); + joinLeaveLogsEntity.HasKey(x => x.Id); + joinLeaveLogsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + joinLeaveLogsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + joinLeaveLogsEntity.Property(x => x.IsJoin).HasDefaultValue(true); + joinLeaveLogsEntity.HasIndex(x => new + { + x.GuildId, x.UserId + }); - configEntity.Property(x => x.SendChannelByeMessage) - .HasDefaultValue(false); + #endregion - configEntity.Property(x => x.StarboardAllowBots) - .HasDefaultValue(false); + #region LockdownChannelPermissions - configEntity.Property(x => x.StarboardRemoveOnDelete) - .HasDefaultValue(false); + var lockdownChannelPermissionsEntity = modelBuilder.Entity(); + lockdownChannelPermissionsEntity.HasKey(x => x.Id); + lockdownChannelPermissionsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + lockdownChannelPermissionsEntity.Property(x => x.AllowPermissions).HasColumnType("numeric(20, 0)"); + lockdownChannelPermissionsEntity.Property(x => x.DenyPermissions).HasColumnType("numeric(20, 0)"); - configEntity.Property(x => x.StarboardRemoveOnReactionsClear) - .HasDefaultValue(false); + #endregion - configEntity.Property(x => x.UseStarboardBlacklist) - .HasDefaultValue(true); + #region LoggingV2 - configEntity.Property(x => x.StarboardRemoveOnBelowThreshold) - .HasDefaultValue(true); + var loggingV2Entity = modelBuilder.Entity(); + loggingV2Entity.HasKey(x => x.Id); + loggingV2Entity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + loggingV2Entity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + loggingV2Entity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)"); + loggingV2Entity.HasIndex(x => x.GuildId); - configEntity.Property(x => x.ArchiveOnDeny) - .HasDefaultValue(false); + #endregion - configEntity.Property(x => x.ArchiveOnAccept) - .HasDefaultValue(false); + #region MessageCount - configEntity.Property(x => x.ArchiveOnImplement) - .HasDefaultValue(false); + var messageCountEntity = modelBuilder.Entity(); + messageCountEntity.HasKey(x => x.Id); + messageCountEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + messageCountEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + messageCountEntity.Property(x => x.Count).HasColumnType("numeric(20, 0)"); + messageCountEntity.Property(x => x.RecentTimestamps).HasColumnType("text"); - configEntity.Property(x => x.ArchiveOnConsider) - .HasDefaultValue(false); + #endregion - configEntity.Property(x => x.GBAction) - .HasDefaultValue(false); + #region MultiGreet + + var multiGreetEntity = modelBuilder.Entity(); + multiGreetEntity.HasKey(x => x.Id); + multiGreetEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + multiGreetEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + multiGreetEntity.Property(x => x.Message).HasColumnType("text").IsRequired(false); + multiGreetEntity.Property(x => x.GreetBots).HasDefaultValue(false); + multiGreetEntity.Property(x => x.DeleteTime).HasDefaultValue(1); + multiGreetEntity.Property(x => x.Disabled).HasDefaultValue(false); + multiGreetEntity.Property(x => x.WebhookUrl).HasColumnType("text").IsRequired(false); #endregion - #region HighlightSettings + #region MusicPlaylist - var highlightSettingsEntity = modelBuilder.Entity(); + var musicPlaylistEntity = modelBuilder.Entity(); + musicPlaylistEntity.HasKey(x => x.Id); + musicPlaylistEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + musicPlaylistEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + musicPlaylistEntity.Property(x => x.Name).HasColumnType("text").IsRequired(false); + musicPlaylistEntity.Property(x => x.Author).HasColumnType("text").IsRequired(false); + musicPlaylistEntity.HasMany(x => x.Songs).WithOne().OnDelete(DeleteBehavior.Cascade); + + #endregion + + #region MusicPlayerSettings - highlightSettingsEntity.Property(x => x.HighlightsOn) - .HasDefaultValue(false); + var musicPlayerSettingsEntity = modelBuilder.Entity(); + musicPlayerSettingsEntity.HasKey(x => x.Id); + musicPlayerSettingsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + musicPlayerSettingsEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)"); + musicPlayerSettingsEntity.Property(x => x.Volume).HasDefaultValue(100); + musicPlayerSettingsEntity.Property(x => x.AutoPlay).HasDefaultValue(0); + musicPlayerSettingsEntity.Property(x => x.PlayerRepeat).HasConversion(); #endregion - #region MultiGreets + #region MutedUserId - var multiGreetsEntity = modelBuilder.Entity(); + var mutedUserIdEntity = modelBuilder.Entity(); + mutedUserIdEntity.HasKey(x => x.Id); + mutedUserIdEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + mutedUserIdEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + mutedUserIdEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)"); + mutedUserIdEntity.Property(x => x.roles).HasColumnType("text").IsRequired(false); + mutedUserIdEntity.Property(x => x.GuildConfigId).HasColumnType("int").IsRequired(); - multiGreetsEntity.Property(x => x.GreetBots) - .HasDefaultValue(false); + #endregion - multiGreetsEntity.Property(x => x.DeleteTime) - .HasDefaultValue(1); + #region GlobalUserBalance - multiGreetsEntity.Property(x => x.Disabled) - .HasDefaultValue(false); + var globalUserBalanceEntity = modelBuilder.Entity(); + globalUserBalanceEntity.HasKey(x => x.Id); + globalUserBalanceEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + globalUserBalanceEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + globalUserBalanceEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + globalUserBalanceEntity.Property(x => x.Balance).HasColumnType("bigint").IsRequired(); + + #endregion - multiGreetsEntity.Property(x => x.WebhookUrl) - .HasDefaultValue(null); + #region GuildUserBalance + + var guildUserBalanceEntity = modelBuilder.Entity(); + guildUserBalanceEntity.HasKey(x => x.Id); + guildUserBalanceEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + guildUserBalanceEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + guildUserBalanceEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + guildUserBalanceEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + guildUserBalanceEntity.Property(x => x.Balance).HasColumnType("bigint").IsRequired(); #endregion - #region streamrole + #region TransactionHistory - configEntity.HasOne(x => x.StreamRole) - .WithOne() - .HasForeignKey(x => x.GuildConfigId) - .OnDelete(DeleteBehavior.Cascade); + var transactionHistoryEntity = modelBuilder.Entity(); + transactionHistoryEntity.HasKey(x => x.Id); + transactionHistoryEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + transactionHistoryEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + transactionHistoryEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + transactionHistoryEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(false); + transactionHistoryEntity.Property(x => x.Amount).HasColumnType("bigint").IsRequired(); + transactionHistoryEntity.Property(x => x.Description).HasColumnType("text").IsRequired(false); #endregion - #region Self Assignable Roles + #region NsfwBlacklistedTag - var selfassignableRolesEntity = modelBuilder.Entity(); + var nsfwBlacklistedTagEntity = modelBuilder.Entity(); + nsfwBlacklistedTagEntity.HasKey(x => x.Id); + nsfwBlacklistedTagEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + nsfwBlacklistedTagEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + nsfwBlacklistedTagEntity.Property(x => x.GuildConfigId).HasColumnType("int").IsRequired(); + nsfwBlacklistedTagEntity.Property(x => x.Tag).HasColumnType("text").IsRequired(false); - selfassignableRolesEntity - .HasIndex(s => new - { - s.GuildId, s.RoleId - }) - .IsUnique(); + #endregion + + #region OwnerOnly - selfassignableRolesEntity - .Property(x => x.Group) - .HasDefaultValue(0); + var ownerOnlyEntity = modelBuilder.Entity(); + ownerOnlyEntity.HasKey(x => x.Id); + ownerOnlyEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + ownerOnlyEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + ownerOnlyEntity.Property(x => x.Owners).HasColumnType("text").IsRequired(false); + ownerOnlyEntity.Property(x => x.GptTokensUsed).HasColumnType("int").IsRequired(); + ownerOnlyEntity.Property(x => x.CurrencyEmote).HasColumnType("text").IsRequired(false); + ownerOnlyEntity.Property(x => x.RewardAmount).HasColumnType("int").IsRequired(); + ownerOnlyEntity.Property(x => x.RewardTimeoutSeconds).HasColumnType("int").IsRequired(); #endregion #region Permission var permissionEntity = modelBuilder.Entity(); - permissionEntity - .HasOne(p => p.Next) - .WithOne(p => p.Previous) - .IsRequired(false); + permissionEntity.HasKey(x => x.Id); + permissionEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + permissionEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + permissionEntity.HasOne(p => p.Next).WithOne(p => p.Previous).IsRequired(false); + permissionEntity.Property(x => x.PrimaryTarget).HasColumnType("int").IsRequired(); + permissionEntity.Property(x => x.PrimaryTargetId).HasColumnType("numeric(20, 0)").IsRequired(); + permissionEntity.Property(x => x.SecondaryTarget).HasColumnType("int").IsRequired(); + permissionEntity.Property(x => x.SecondaryTargetName).HasColumnType("text").IsRequired(false); + permissionEntity.Property(x => x.State).HasColumnType("boolean").IsRequired(); #endregion - #region MusicPlaylists + #region PlaylistSong + + var playlistSongEntity = modelBuilder.Entity(); + playlistSongEntity.HasKey(x => x.Id); + playlistSongEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + playlistSongEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + playlistSongEntity.Property(x => x.MusicPlaylistId).HasColumnType("int").IsRequired(); + playlistSongEntity.Property(x => x.Provider).HasColumnType("text").IsRequired(false); + playlistSongEntity.Property(x => x.ProviderType).HasColumnType("int").IsRequired(); + playlistSongEntity.Property(x => x.Title).HasColumnType("text").IsRequired(false); + playlistSongEntity.Property(x => x.Uri).HasColumnType("text").IsRequired(false); + playlistSongEntity.Property(x => x.Query).HasColumnType("text").IsRequired(false); - var musicPlaylistEntity = modelBuilder.Entity(); + #endregion + + #region Polls - musicPlaylistEntity - .HasMany(p => p.Songs) - .WithOne() - .OnDelete(DeleteBehavior.Cascade); + var pollEntity = modelBuilder.Entity(); + pollEntity.HasKey(x => x.Id); + pollEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + pollEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + pollEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + pollEntity.Property(x => x.ChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + pollEntity.Property(x => x.Question).HasColumnType("text").IsRequired(false); + pollEntity.HasMany(x => x.Answers).WithOne().IsRequired(); + pollEntity.Property(x => x.PollType).HasColumnType("int").IsRequired(); + pollEntity.HasMany(x => x.Votes).WithOne().IsRequired(); #endregion - #region DiscordUser + #region PollAnswers + + var pollAnswerEntity = modelBuilder.Entity(); + pollAnswerEntity.HasKey(x => x.Id); + pollAnswerEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + pollAnswerEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + pollAnswerEntity.Property(x => x.Text).HasColumnType("text").IsRequired(false); + pollAnswerEntity.Property(x => x.Index).HasColumnType("int").IsRequired(); - var du = modelBuilder.Entity(); - du.HasAlternateKey(w => w.UserId); + #endregion - du.Property(x => x.LastLevelUp) - .HasDefaultValue(new DateTime(2017, 9, 21, 20, 53, 13, 305, DateTimeKind.Local)); + #region PollVote - du.HasIndex(x => x.TotalXp); - du.HasIndex(x => x.UserId); - du.Property(x => x.IsClubAdmin) - .HasDefaultValue(false); + var pollVoteEntity = modelBuilder.Entity(); + pollVoteEntity.HasKey(x => x.Id); + pollVoteEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + pollVoteEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + pollVoteEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + pollVoteEntity.Property(x => x.VoteIndex).HasColumnType("int").IsRequired(); + pollVoteEntity.Property(x => x.PollId).HasColumnType("int").IsRequired(); - du.Property(x => x.PronounsDisabled) - .HasDefaultValue(false); + #endregion - du.Property(x => x.StatsOptOut) - .HasDefaultValue(false); + #region PublishUserBlacklist - du.Property(x => x.IsDragon) - .HasDefaultValue(false); + var publishUserBlacklistEntity = modelBuilder.Entity(); + publishUserBlacklistEntity.HasKey(x => x.Id); + publishUserBlacklistEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + publishUserBlacklistEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + publishUserBlacklistEntity.Property(x => x.ChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + publishUserBlacklistEntity.Property(x => x.User).HasColumnType("numeric(20, 0)").IsRequired(); - du.Property(x => x.NotifyOnLevelUp) - .HasDefaultValue(XpNotificationLocation.None); + #endregion - du.Property(x => x.ProfilePrivacy) - .HasDefaultValue(Models.DiscordUser.ProfilePrivacyEnum.Public); + #region PublishWordBlacklist - du.Property(x => x.BirthdayDisplayMode) - .HasDefaultValue(Models.DiscordUser.BirthdayDisplayModeEnum.Default); + var publishWordBlacklistEntity = modelBuilder.Entity(); + publishWordBlacklistEntity.HasKey(x => x.Id); + publishWordBlacklistEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + publishWordBlacklistEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + publishWordBlacklistEntity.Property(x => x.ChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + publishWordBlacklistEntity.Property(x => x.Word).HasColumnType("text").IsRequired(false); #endregion - #region Warnings + #region Quote - var warn = modelBuilder.Entity(); - warn.HasIndex(x => x.GuildId); - warn.HasIndex(x => x.UserId); - warn.HasIndex(x => x.DateAdded); + var quoteEntity = modelBuilder.Entity(); + quoteEntity.HasKey(x => x.Id); + quoteEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + quoteEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + quoteEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + quoteEntity.Property(x => x.Keyword).HasColumnType("text").IsRequired(); + quoteEntity.Property(x => x.AuthorName).HasColumnType("text").IsRequired(); + quoteEntity.Property(x => x.AuthorId).HasColumnType("numeric(20, 0)").IsRequired(); + quoteEntity.Property(x => x.Text).HasColumnType("text").IsRequired(); + quoteEntity.Property(x => x.UseCount).HasColumnType("bigint").IsRequired(); #endregion - #region XpStats + #region ReactionRoleMessage - var xps = modelBuilder.Entity(); - xps - .HasIndex(x => new - { - x.UserId, x.GuildId - }) - .IsUnique(); + var reactionRoleMessageEntity = modelBuilder.Entity(); + reactionRoleMessageEntity.HasKey(x => x.Id); + reactionRoleMessageEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + reactionRoleMessageEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + reactionRoleMessageEntity.Property(x => x.GuildConfigId).HasColumnType("int").IsRequired(); + reactionRoleMessageEntity.Property(x => x.ChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + reactionRoleMessageEntity.Property(x => x.MessageId).HasColumnType("numeric(20, 0)").IsRequired(); + reactionRoleMessageEntity.HasMany(x => x.ReactionRoles).WithOne().IsRequired(); + reactionRoleMessageEntity.Property(x => x.Exclusive).HasColumnType("boolean").IsRequired(); + reactionRoleMessageEntity.Property(x => x.Index).HasColumnType("int").IsRequired(); + + #endregion - xps - .Property(x => x.LastLevelUp) - .HasDefaultValue(new DateTime(2017, 9, 21, 20, 53, 13, 307, DateTimeKind.Local)); + #region ReactionRole - xps.HasIndex(x => x.UserId); - xps.HasIndex(x => x.GuildId); - xps.HasIndex(x => x.Xp); - xps.HasIndex(x => x.AwardedXp); + var reactionRoleEntity = modelBuilder.Entity(); + reactionRoleEntity.HasKey(x => x.Id); + reactionRoleEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + reactionRoleEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + reactionRoleEntity.Property(x => x.EmoteName).HasColumnType("text").IsRequired(false); + reactionRoleEntity.Property(x => x.RoleId).HasColumnType("numeric(20, 0)").IsRequired(); + reactionRoleEntity.Property(x => x.ReactionRoleMessageId).HasColumnType("int").IsRequired(); #endregion - #region Music + #region Reminder - modelBuilder.Entity() - .HasIndex(x => x.GuildId) - .IsUnique(); + var reminderEntity = modelBuilder.Entity(); + reminderEntity.HasKey(x => x.Id); + reminderEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + reminderEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + reminderEntity.Property(x => x.When).HasColumnType("timestamp").IsRequired(); + reminderEntity.Property(x => x.ChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + reminderEntity.Property(x => x.ServerId).HasColumnType("numeric(20, 0)").IsRequired(); + reminderEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + reminderEntity.Property(x => x.Message).HasColumnType("text").IsRequired(false); + reminderEntity.Property(x => x.IsPrivate).HasDefaultValue(false).IsRequired(); - modelBuilder.Entity() - .Property(x => x.Volume) - .HasDefaultValue(100); + #endregion + + #region Repeater + + var repeaterEntity = modelBuilder.Entity(); + repeaterEntity.HasKey(x => x.Id); + repeaterEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + repeaterEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + repeaterEntity.Property(x => x.GuildConfigId).HasColumnType("int").IsRequired(); + repeaterEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + repeaterEntity.Property(x => x.ChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + repeaterEntity.Property(x => x.LastMessageId).HasColumnType("numeric(20, 0)").IsRequired(false); + repeaterEntity.Property(x => x.Message).HasColumnType("text").IsRequired(false); + repeaterEntity.Property(x => x.Interval).HasColumnType("text").IsRequired(false); + repeaterEntity.Property(x => x.StartTimeOfDay).HasColumnType("text").IsRequired(false); + repeaterEntity.Property(x => x.NoRedundant).HasDefaultValue(false).IsRequired(); #endregion - #region XpSettings + #region RoleConnectionAuthStorage - configEntity.HasOne(x => x.XpSettings) - .WithOne() - .HasForeignKey(x => x.GuildConfigId) - .OnDelete(DeleteBehavior.Cascade); + var roleConnectionAuthStorageEntity = modelBuilder.Entity(); + roleConnectionAuthStorageEntity.HasKey(x => x.Id); + roleConnectionAuthStorageEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + roleConnectionAuthStorageEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + roleConnectionAuthStorageEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + roleConnectionAuthStorageEntity.Property(x => x.Scopes).HasColumnType("text").IsRequired(false); + roleConnectionAuthStorageEntity.Property(x => x.Token).HasColumnType("text").IsRequired(false); + roleConnectionAuthStorageEntity.Property(x => x.RefreshToken).HasColumnType("text").IsRequired(false); + roleConnectionAuthStorageEntity.Property(x => x.ExpiresAt).HasColumnType("timestamp").IsRequired(); #endregion - #region XpRoleReward + #region RoleGreet + + var roleGreetEntity = modelBuilder.Entity(); + roleGreetEntity.HasKey(x => x.Id); + roleGreetEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + roleGreetEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + roleGreetEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + roleGreetEntity.Property(x => x.RoleId).HasColumnType("numeric(20, 0)").IsRequired(); + roleGreetEntity.Property(x => x.ChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + roleGreetEntity.Property(x => x.GreetBots).HasDefaultValue(false).IsRequired(); + roleGreetEntity.Property(x => x.Message).HasColumnType("text").IsRequired(false); + roleGreetEntity.Property(x => x.DeleteTime).HasColumnType("int").IsRequired(); + roleGreetEntity.Property(x => x.WebhookUrl).HasColumnType("text").IsRequired(false); + roleGreetEntity.Property(x => x.Disabled).HasDefaultValue(false).IsRequired(); - modelBuilder.Entity() - .HasIndex(x => new - { - x.XpSettingsId, x.Level - }) - .IsUnique(); + #endregion + + #region RoleMonitoringSettings + + var roleMonitoringSettingsEntity = modelBuilder.Entity(); + roleMonitoringSettingsEntity.HasKey(x => x.Id); + roleMonitoringSettingsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + roleMonitoringSettingsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + roleMonitoringSettingsEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + roleMonitoringSettingsEntity.Property(x => x.DefaultPunishmentAction).HasColumnType("int").IsRequired(); #endregion - #region Polls + #region RoleStateSettings - modelBuilder.Entity() - .HasIndex(x => x.GuildId) - .IsUnique(); + var roleStateSettingsEntity = modelBuilder.Entity(); + roleStateSettingsEntity.HasKey(x => x.Id); + roleStateSettingsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + roleStateSettingsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + roleStateSettingsEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + roleStateSettingsEntity.Property(x => x.Enabled).HasDefaultValue(false).IsRequired(); + roleStateSettingsEntity.Property(x => x.ClearOnBan).HasDefaultValue(false).IsRequired(); + roleStateSettingsEntity.Property(x => x.IgnoreBots).HasDefaultValue(true).IsRequired(); + roleStateSettingsEntity.Property(x => x.DeniedRoles).HasColumnType("text").IsRequired(false); + roleStateSettingsEntity.Property(x => x.DeniedUsers).HasColumnType("text").IsRequired(false); #endregion - #region Reminders + #region RotatingPlayingStatus - modelBuilder.Entity() - .HasIndex(x => x.When); + var rotatingPlayingStatusEntity = modelBuilder.Entity(); + rotatingPlayingStatusEntity.HasKey(x => x.Id); + rotatingPlayingStatusEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + rotatingPlayingStatusEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + rotatingPlayingStatusEntity.Property(x => x.Status).HasColumnType("text").IsRequired(false); + rotatingPlayingStatusEntity.Property(x => x.Type).HasColumnType("int").IsRequired(); #endregion - #region GroupName + #region SelfAssignedRole - modelBuilder.Entity() - .HasIndex(x => new - { - x.GuildConfigId, x.Number - }) - .IsUnique(); + var selfAssignedRoleEntity = modelBuilder.Entity(); + selfAssignedRoleEntity.HasKey(x => x.Id); + selfAssignedRoleEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + selfAssignedRoleEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + selfAssignedRoleEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + selfAssignedRoleEntity.Property(x => x.RoleId).HasColumnType("numeric(20, 0)").IsRequired(); + selfAssignedRoleEntity.Property(x => x.Group).HasColumnType("int").IsRequired(); + selfAssignedRoleEntity.Property(x => x.LevelRequirement).HasColumnType("int").IsRequired(); + + #endregion + + #region ServerRecoveryStore - configEntity.HasMany(x => x.SelfAssignableRoleGroupNames) - .WithOne() - .HasForeignKey(x => x.GuildConfigId) - .OnDelete(DeleteBehavior.Cascade); + var serverRecoveryStoreEntity = modelBuilder.Entity(); + serverRecoveryStoreEntity.HasKey(x => x.Id); + serverRecoveryStoreEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + serverRecoveryStoreEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + serverRecoveryStoreEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + serverRecoveryStoreEntity.Property(x => x.RecoveryKey).HasColumnType("text").IsRequired(false); + serverRecoveryStoreEntity.Property(x => x.TwoFactorKey).HasColumnType("text").IsRequired(false); #endregion - #region BanTemplate + #region StarboardPosts - modelBuilder.Entity() - .HasIndex(x => x.GuildId) - .IsUnique(); + var starboardPostsEntity = modelBuilder.Entity(); + starboardPostsEntity.HasKey(x => x.Id); + starboardPostsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + starboardPostsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + starboardPostsEntity.Property(x => x.MessageId).HasColumnType("numeric(20, 0)").IsRequired(); + starboardPostsEntity.Property(x => x.PostId).HasColumnType("numeric(20, 0)").IsRequired(); #endregion - #region Perm Override + #region Starboards + + var starboardsEntity = modelBuilder.Entity(); + starboardsEntity.HasKey(x => x.Id); + starboardsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + starboardsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + starboardsEntity.Property(x => x.Star).HasColumnType("text").HasDefaultValue("⭐").IsRequired(false); + starboardsEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + starboardsEntity.Property(x => x.StarboardChannel).HasColumnType("numeric(20, 0)").IsRequired(); + starboardsEntity.Property(x => x.StarboardThreshold).HasColumnType("int").HasDefaultValue(3).IsRequired(); + starboardsEntity.Property(x => x.RepostThreshold).HasColumnType("int").HasDefaultValue(5).IsRequired(); + starboardsEntity.Property(x => x.StarboardAllowBots).HasDefaultValue(true).IsRequired(); + starboardsEntity.Property(x => x.StarboardRemoveOnDelete).HasDefaultValue(false).IsRequired(); + starboardsEntity.Property(x => x.StarboardRemoveOnReactionsClear).HasDefaultValue(false).IsRequired(); + starboardsEntity.Property(x => x.StarboardRemoveOnBelowThreshold).HasDefaultValue(true).IsRequired(); + starboardsEntity.Property(x => x.UseStarboardBlacklist).HasDefaultValue(true).IsRequired(); + starboardsEntity.Property(x => x.StarboardCheckChannels).HasColumnType("text").HasDefaultValue("0") + .IsRequired(false); - modelBuilder.Entity() - .HasIndex(x => new - { - x.GuildId, x.Command - }) - .IsUnique(); + #endregion + + #region StatusRolesTable + + var statusRolesTableEntity = modelBuilder.Entity(); + statusRolesTableEntity.HasKey(x => x.Id); + statusRolesTableEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + statusRolesTableEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + statusRolesTableEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + statusRolesTableEntity.Property(x => x.Status).HasColumnType("text").IsRequired(false); + statusRolesTableEntity.Property(x => x.ToAdd).HasColumnType("text").IsRequired(false); + statusRolesTableEntity.Property(x => x.ToRemove).HasColumnType("text").IsRequired(false); + statusRolesTableEntity.Property(x => x.StatusEmbed).HasColumnType("text").IsRequired(false); + statusRolesTableEntity.Property(x => x.ReaddRemoved).HasDefaultValue(false).IsRequired(); + statusRolesTableEntity.Property(x => x.RemoveAdded).HasDefaultValue(true).IsRequired(); + statusRolesTableEntity.Property(x => x.StatusChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + + #endregion + + #region StreamRoleSettings + + var streamRoleSettingsEntity = modelBuilder.Entity(); + streamRoleSettingsEntity.HasKey(x => x.Id); + streamRoleSettingsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + streamRoleSettingsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + streamRoleSettingsEntity.Property(x => x.GuildConfigId).HasColumnType("int").IsRequired(); + streamRoleSettingsEntity.Property(x => x.Enabled).HasDefaultValue(false).IsRequired(); + streamRoleSettingsEntity.Property(x => x.AddRoleId).HasColumnType("numeric(20, 0)").IsRequired(); + streamRoleSettingsEntity.Property(x => x.FromRoleId).HasColumnType("numeric(20, 0)").IsRequired(); + streamRoleSettingsEntity.Property(x => x.Keyword).HasColumnType("text").IsRequired(false); + + #endregion + + #region StreamRoleBlacklistedUser + + var streamRoleBlacklistedUserEntity = modelBuilder.Entity(); + streamRoleBlacklistedUserEntity.HasKey(x => x.Id); + streamRoleBlacklistedUserEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + streamRoleBlacklistedUserEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + streamRoleBlacklistedUserEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + streamRoleBlacklistedUserEntity.Property(x => x.Username).HasColumnType("text").IsRequired(false); + streamRoleBlacklistedUserEntity.Property(x => x.StreamRoleSettingsId).HasColumnType("int").IsRequired(); + + #endregion + + #region StreamRoleWhitelistedUser + + var streamRoleWhitelistedUserEntity = modelBuilder.Entity(); + streamRoleWhitelistedUserEntity.HasKey(x => x.Id); + streamRoleWhitelistedUserEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + streamRoleWhitelistedUserEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + streamRoleWhitelistedUserEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + streamRoleWhitelistedUserEntity.Property(x => x.Username).HasColumnType("text").IsRequired(false); + streamRoleWhitelistedUserEntity.Property(x => x.StreamRoleSettingsId).HasColumnType("int").IsRequired(); + + #endregion + + #region SuggestionsModel + + var suggestionsModelEntity = modelBuilder.Entity(); + suggestionsModelEntity.HasKey(x => x.Id); + suggestionsModelEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + suggestionsModelEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + suggestionsModelEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + suggestionsModelEntity.Property(x => x.SuggestionId).HasColumnType("numeric(20, 0)").IsRequired(); + suggestionsModelEntity.Property(x => x.Suggestion).HasColumnType("text").IsRequired(false); + suggestionsModelEntity.Property(x => x.MessageId).HasColumnType("numeric(20, 0)").IsRequired(); + suggestionsModelEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + suggestionsModelEntity.Property(x => x.EmoteCount1).HasColumnType("int").HasDefaultValue(0).IsRequired(); + suggestionsModelEntity.Property(x => x.EmoteCount2).HasColumnType("int").HasDefaultValue(0).IsRequired(); + suggestionsModelEntity.Property(x => x.EmoteCount3).HasColumnType("int").HasDefaultValue(0).IsRequired(); + suggestionsModelEntity.Property(x => x.EmoteCount4).HasColumnType("int").HasDefaultValue(0).IsRequired(); + suggestionsModelEntity.Property(x => x.EmoteCount5).HasColumnType("int").HasDefaultValue(0).IsRequired(); + suggestionsModelEntity.Property(x => x.StateChangeUser).HasColumnType("numeric(20, 0)").HasDefaultValue(0) + .IsRequired(); + suggestionsModelEntity.Property(x => x.StateChangeCount).HasColumnType("numeric(20, 0)").HasDefaultValue(0) + .IsRequired(); + suggestionsModelEntity.Property(x => x.StateChangeMessageId).HasColumnType("numeric(20, 0)").HasDefaultValue(0) + .IsRequired(); + suggestionsModelEntity.Property(x => x.CurrentState).HasColumnType("int").HasDefaultValue(0).IsRequired(); + + #endregion + + #region SuggestThreads + + var suggestThreadsEntity = modelBuilder.Entity(); + suggestThreadsEntity.HasKey(x => x.Id); + suggestThreadsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + suggestThreadsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + suggestThreadsEntity.Property(x => x.MessageId).HasColumnType("numeric(20, 0)").IsRequired(); + suggestThreadsEntity.Property(x => x.ThreadChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + + #endregion + + #region SuggestVotes + + var suggestVotesEntity = modelBuilder.Entity(); + suggestVotesEntity.HasKey(x => x.Id); + suggestVotesEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + suggestVotesEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + suggestVotesEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + suggestVotesEntity.Property(x => x.MessageId).HasColumnType("numeric(20, 0)").IsRequired(); + suggestVotesEntity.Property(x => x.EmotePicked).HasColumnType("int").IsRequired(); + + #endregion + + #region TicketButton + + var ticketButtonEntity = modelBuilder.Entity(); + ticketButtonEntity.HasKey(x => x.Id); + ticketButtonEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + ticketButtonEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + ticketButtonEntity.Property(x => x.TicketPanelId).HasColumnType("int").IsRequired(); + ticketButtonEntity.Property(x => x.Label).HasColumnType("text").IsRequired(); + ticketButtonEntity.Property(x => x.Emoji).HasColumnType("text").IsRequired(); + ticketButtonEntity.Property(x => x.OpenMessage).HasColumnType("text").IsRequired(); + + #endregion + + #region TicketPanel + + var ticketPanelEntity = modelBuilder.Entity(); + ticketPanelEntity.HasKey(x => x.Id); + ticketPanelEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + ticketPanelEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + ticketPanelEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + ticketPanelEntity.Property(x => x.ChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + ticketPanelEntity.Property(x => x.MessageJson).HasColumnType("text").IsRequired(false).HasDefaultValue(""); + ticketPanelEntity.HasMany(x => x.Buttons).WithOne().HasForeignKey(x => x.TicketPanelId); + + #endregion + + #region UnbanTimer + + var unbanTimerEntity = modelBuilder.Entity(); + unbanTimerEntity.HasKey(x => x.Id); + unbanTimerEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + unbanTimerEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + unbanTimerEntity.Property(x => x.GuildConfigId).HasColumnType("int").IsRequired(); + unbanTimerEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + unbanTimerEntity.Property(x => x.UnbanAt).HasColumnType("timestamp without time zone").IsRequired(); + + #endregion + + #region UnmuteTimer + + var unmuteTimerEntity = modelBuilder.Entity(); + unmuteTimerEntity.HasKey(x => x.Id); + unmuteTimerEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + unmuteTimerEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + unmuteTimerEntity.Property(x => x.GuildConfigId).HasColumnType("int").IsRequired(false); + unmuteTimerEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + unmuteTimerEntity.Property(x => x.UnmuteAt).HasColumnType("timestamp without time zone").IsRequired(); + + #endregion + + #region UnroleTimer + + var unroleTimerEntity = modelBuilder.Entity(); + unroleTimerEntity.HasKey(x => x.Id); + unroleTimerEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + unroleTimerEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + unroleTimerEntity.Property(x => x.GuildConfigId).HasColumnType("int").IsRequired(); + unroleTimerEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + unroleTimerEntity.Property(x => x.RoleId).HasColumnType("numeric(20, 0)").IsRequired(); + unroleTimerEntity.Property(x => x.UnbanAt).HasColumnType("timestamp without time zone").IsRequired(); + + #endregion + + #region Usernames + + var usernamesEntity = modelBuilder.Entity(); + usernamesEntity.HasKey(x => x.Id); + usernamesEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + usernamesEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + usernamesEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + usernamesEntity.Property(x => x.Username).HasColumnType("text").IsRequired(false); + + #endregion + + #region UserRoleStates + + var userRoleStatesEntity = modelBuilder.Entity(); + userRoleStatesEntity.HasKey(x => x.Id); + userRoleStatesEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + userRoleStatesEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + userRoleStatesEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + userRoleStatesEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + userRoleStatesEntity.Property(x => x.UserName).HasColumnType("text").IsRequired(false); + userRoleStatesEntity.Property(x => x.SavedRoles).HasColumnType("text").IsRequired(false); + + #endregion + + #region UserXpStats + + var userXpStatsEntity = modelBuilder.Entity(); + userXpStatsEntity.HasKey(x => x.Id); + userXpStatsEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + userXpStatsEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + userXpStatsEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + userXpStatsEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + userXpStatsEntity.Property(x => x.Xp).HasColumnType("int").IsRequired(); + userXpStatsEntity.Property(x => x.AwardedXp).HasColumnType("int").IsRequired(); + userXpStatsEntity.Property(x => x.NotifyOnLevelUp).HasColumnType("int").IsRequired(); + userXpStatsEntity.Property(x => x.LastLevelUp).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP").IsRequired(); + + #endregion + + #region VcRoleInfo + + var vcRoleInfoEntity = modelBuilder.Entity(); + vcRoleInfoEntity.HasKey(x => x.Id); + vcRoleInfoEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + vcRoleInfoEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + vcRoleInfoEntity.Property(x => x.GuildConfigId).HasColumnType("int").IsRequired(); + vcRoleInfoEntity.Property(x => x.VoiceChannelId).HasColumnType("numeric(20, 0)").IsRequired(); + vcRoleInfoEntity.Property(x => x.RoleId).HasColumnType("numeric(20, 0)").IsRequired(); + + #endregion + + #region VoteRoles + + var voteRolesEntity = modelBuilder.Entity(); + voteRolesEntity.HasKey(x => x.Id); + voteRolesEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + voteRolesEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + voteRolesEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + voteRolesEntity.Property(x => x.RoleId).HasColumnType("numeric(20, 0)").IsRequired(); + voteRolesEntity.Property(x => x.Timer).HasColumnType("int").IsRequired(); #endregion - #region Tickets + #region Votes - modelBuilder.Entity() - .HasMany(p => p.Buttons) - .WithOne() - .HasForeignKey(b => b.TicketPanelId); + var votesEntity = modelBuilder.Entity(); + votesEntity.HasKey(x => x.Id); + votesEntity.Property(x => x.Id).HasColumnType("int").ValueGeneratedOnAdd(); + votesEntity.Property(x => x.DateAdded).IsRequired(false).HasColumnType("timestamp without time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + votesEntity.Property(x => x.GuildId).HasColumnType("numeric(20, 0)").IsRequired(); + votesEntity.Property(x => x.UserId).HasColumnType("numeric(20, 0)").IsRequired(); + votesEntity.Property(x => x.BotId).HasColumnType("numeric(20, 0)").IsRequired(); #endregion } diff --git a/src/Mewdeko/Database/Models/GuildConfig.cs b/src/Mewdeko/Database/Models/GuildConfig.cs index bc7287bb7..7abae9e99 100644 --- a/src/Mewdeko/Database/Models/GuildConfig.cs +++ b/src/Mewdeko/Database/Models/GuildConfig.cs @@ -651,10 +651,6 @@ public class GuildConfig : DbEntity /// public string? ChannelByeMessageText { get; set; } = "%user% has left!"; - /// - /// Gets or sets the log settings for the guild. - /// - public LogSetting LogSetting { get; set; } = new(); /// /// Gets or sets a value indicating whether to restrict self-assigned roles to be exclusive. diff --git a/src/Mewdeko/Database/Models/LogSetting.cs b/src/Mewdeko/Database/Models/LogSetting.cs deleted file mode 100644 index 4c9e40777..000000000 --- a/src/Mewdeko/Database/Models/LogSetting.cs +++ /dev/null @@ -1,234 +0,0 @@ -namespace Mewdeko.Database.Models; - -/// -/// Represents the logging settings for a guild. -/// -public class LogSetting : DbEntity -{ - /// - /// Gets or sets the channels that are ignored for logging. - /// - public HashSet IgnoredChannels { get; set; } = []; - - /// - /// Gets or sets the ID for logging other events. - /// - public ulong? LogOtherId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging updated messages. - /// - public ulong? MessageUpdatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging deleted messages. - /// - public ulong? MessageDeletedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging created threads. - /// - public ulong? ThreadCreatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging deleted threads. - /// - public ulong? ThreadDeletedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging updated threads. - /// - public ulong? ThreadUpdatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging updated usernames. - /// - public ulong? UsernameUpdatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging updated nicknames. - /// - public ulong? NicknameUpdatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging updated avatars. - /// - public ulong? AvatarUpdatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging user leave events. - /// - public ulong? UserLeftId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging user ban events. - /// - public ulong? UserBannedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging user unban events. - /// - public ulong? UserUnbannedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging updated user information. - /// - public ulong? UserUpdatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging user join events. - /// - public ulong? UserJoinedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging role additions to users. - /// - public ulong? UserRoleAddedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging role removals from users. - /// - public ulong? UserRoleRemovedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging user mute events. - /// - public ulong? UserMutedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging user presence. - /// - public ulong? LogUserPresenceId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging voice presence. - /// - public ulong? LogVoicePresenceId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging text-to-speech voice presence. - /// - public ulong? LogVoicePresenceTTSId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging server updates. - /// - public ulong? ServerUpdatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging role updates. - /// - public ulong? RoleUpdatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging role deletions. - /// - public ulong? RoleDeletedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging event creations. - /// - public ulong? EventCreatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging role creations. - /// - public ulong? RoleCreatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging channel creations. - /// - public ulong? ChannelCreatedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging channel destructions. - /// - public ulong? ChannelDestroyedId { get; set; } = 0; - - /// - /// Gets or sets the ID for logging channel updates. - /// - public ulong? ChannelUpdatedId { get; set; } = 0; - - /// - /// Gets or sets a value indicating whether logging is enabled. (DO NOT USE) - /// - public long IsLogging { get; set; } = 1; - - /// - /// Gets or sets the channel ID for logging. (DO NOT USE) - /// - public ulong ChannelId { get; set; } = 0; - - /// - /// Gets or sets a value indicating whether message updates are logged. (DO NOT USE) - /// - public long MessageUpdated { get; set; } = 1; - - /// - /// Gets or sets a value indicating whether message deletions are logged. (DO NOT USE) - /// - - - public long MessageDeleted { get; set; } = 1; - - /// - /// Gets or sets a value indicating whether user joins are logged. (DO NOT USE) - /// - public long UserJoined { get; set; } = 1; - - /// - /// Gets or sets a value indicating whether user leaves are logged. (DO NOT USE) - /// - public long UserLeft { get; set; } = 1; - - /// - /// Gets or sets a value indicating whether user bans are logged. (DO NOT USE) - /// - public long UserBanned { get; set; } = 1; - - /// - /// Gets or sets a value indicating whether user unbans are logged. (DO NOT USE) - /// - public long UserUnbanned { get; set; } = 1; - - /// - /// Gets or sets a value indicating whether user updates are logged. (DO NOT USE) - /// - public long UserUpdated { get; set; } = 1; - - /// - /// Gets or sets a value indicating whether channel creations are logged. (DO NOT USE) - /// - public long ChannelCreated { get; set; } = 1; - - /// - /// Gets or sets a value indicating whether channel destructions are logged. (DO NOT USE) - /// - public long ChannelDestroyed { get; set; } = 1; - - /// - /// Gets or sets a value indicating whether channel updates are logged. (DO NOT USE) - /// - public long ChannelUpdated { get; set; } = 1; - - /// - /// Gets or sets a value indicating whether user presence logging is enabled. (DO NOT USE) - /// - public long LogUserPresence { get; set; } = 0; - - /// - /// Gets or sets the channel ID for user presence logging. (DO NOT USE) - /// - public ulong UserPresenceChannelId { get; set; } = 0; - - /// - /// Gets or sets a value indicating whether voice presence logging is enabled. (DO NOT USE) - /// - public long LogVoicePresence { get; set; } = 0; - - /// - /// Gets or sets the channel ID for voice presence logging. (DO NOT USE) - /// - public ulong VoicePresenceChannelId { get; set; } = 0; -} \ No newline at end of file diff --git a/src/Mewdeko/Modules/Administration/Services/LogCommandService.cs b/src/Mewdeko/Modules/Administration/Services/LogCommandService.cs index 5cc844bcf..d2255ed12 100644 --- a/src/Mewdeko/Modules/Administration/Services/LogCommandService.cs +++ b/src/Mewdeko/Modules/Administration/Services/LogCommandService.cs @@ -262,14 +262,6 @@ public LogCommandService(DbContextProvider dbProvider, IDataCache cache, Discord public async Task OnReadyAsync() { await using var dbContext = await dbProvider.GetContextAsync(); - var guildIds = client.Guilds.Select(x => x.Id).ToList(); - var configs = await dbContext.GuildConfigs - .AsQueryable() - .Include(gc => gc.LogSetting) - .ThenInclude(ls => ls.IgnoredChannels) - .Where(x => guildIds.Contains(x.GuildId)) - .ToListAsyncEF(); - // Store the log settings in a concurrent dictionary for fast access GuildLogSettings = dbContext.LoggingV2 .ToDictionary(g => g.GuildId, g => g) diff --git a/src/Mewdeko/Modules/OwnerOnly/OwnerOnly.cs b/src/Mewdeko/Modules/OwnerOnly/OwnerOnly.cs index 3c91cdfa9..9f264dce2 100644 --- a/src/Mewdeko/Modules/OwnerOnly/OwnerOnly.cs +++ b/src/Mewdeko/Modules/OwnerOnly/OwnerOnly.cs @@ -338,46 +338,36 @@ async Task PageFactory(int page) [Aliases] public async Task CommandStats() { - await using var dbContext = await dbProvider.GetContextAsync(); + await using var context1 = await dbProvider.GetContextAsync(); + await using var context2 = await dbProvider.GetContextAsync(); + await using var context3 = await dbProvider.GetContextAsync(); + await using var context4 = await dbProvider.GetContextAsync(); - var commandStatsTable = dbContext.CommandStats; - var topCommandTask = commandStatsTable + var topCommandTask = context1.CommandStats .Where(x => !x.Trigger) .GroupBy(q => q.NameOrId) - .Select(g => new - { - g.Key, Count = g.Count() - }) + .Select(g => new { g.Key, Count = g.Count() }) .OrderByDescending(gc => gc.Count) .FirstOrDefaultAsyncLinqToDB(); - var topModuleTask = commandStatsTable + var topModuleTask = context2.CommandStats .Where(x => !x.Trigger) .GroupBy(q => q.Module) - .Select(g => new - { - g.Key, Count = g.Count() - }) + .Select(g => new { g.Key, Count = g.Count() }) .OrderByDescending(gc => gc.Count) .FirstOrDefaultAsyncLinqToDB(); - var topGuildTask = commandStatsTable + var topGuildTask = context3.CommandStats .Where(x => !x.Trigger) .GroupBy(q => q.GuildId) - .Select(g => new - { - g.Key, Count = g.Count() - }) + .Select(g => new { g.Key, Count = g.Count() }) .OrderByDescending(gc => gc.Count) .FirstOrDefaultAsyncLinqToDB(); - var topUserTask = commandStatsTable + var topUserTask = context4.CommandStats .Where(x => !x.Trigger) .GroupBy(q => q.UserId) - .Select(g => new - { - g.Key, Count = g.Count() - }) + .Select(g => new { g.Key, Count = g.Count() }) .OrderByDescending(gc => gc.Count) .FirstOrDefaultAsyncLinqToDB(); @@ -396,7 +386,7 @@ public async Task CommandStats() .AddField("Top Command", $"{topCommand.Key} was used {topCommand.Count} times!") .AddField("Top Module", $"{topModule.Key} was used {topModule.Count} times!") .AddField("Top User", $"{user} has used commands {topUser.Count} times!") - .AddField("Top Guild", $"{guild} has used commands {topGuild.Count} times!"); + .AddField("Top Guild", $"{guild?.Name ?? "Unknown"} has used commands {topGuild.Count} times!"); await ctx.Channel.SendMessageAsync(embed: eb.Build()); } diff --git a/src/Mewdeko/Modules/Utility/MessageCountCommands.cs b/src/Mewdeko/Modules/Utility/MessageCountCommands.cs index 6b3ae0734..f529ed129 100644 --- a/src/Mewdeko/Modules/Utility/MessageCountCommands.cs +++ b/src/Mewdeko/Modules/Utility/MessageCountCommands.cs @@ -389,6 +389,61 @@ await ctx.Channel.SendFileAsync(ms, "busiest_hours.png", } } + /// + /// Resets message counts for a user, channel, or both, with confirmation. + /// + /// Optional: The user to reset message counts for. + /// Optional: The channel to reset message counts in. + /// A task that represents the asynchronous operation. + [Cmd] + [Aliases] + [RequireContext(ContextType.Guild)] + [UserPerm(GuildPermission.ManageMessages)] + public async Task ResetMessageCounts(IUser? user = null, ITextChannel? channel = null) + { + var confirmMessage = (user, channel) switch + { + (null, null) => GetText("confirm_reset_message_count_guild"), + (not null, null) => GetText("confirm_reset_message_count_user", user.Mention), + (null, not null) => GetText("confirm_reset_message_count_channel", channel.Mention), + (not null, not null) => GetText("confirm_reset_message_count_user_channel", user.Mention, channel.Mention) + }; + + if (!await PromptUserConfirmAsync(confirmMessage, ctx.User.Id)) + return; + + var result = await Service.ResetCount(ctx.Guild.Id, user?.Id ?? 0, channel?.Id ?? 0); + + var responseMessage = (user, channel, result) switch + { + (null, null, true) => GetText("reset_message_count_success_guild"), + (not null, null, true) => GetText("reset_message_count_success_user", user.Mention), + (null, not null, true) => GetText("reset_message_count_success_channel", channel.Mention), + (not null, not null, true) => GetText("reset_message_count_success_user_channel", user.Mention, channel.Mention), + (null, null, false) => GetText("reset_message_count_fail_guild"), + (not null, null, false) => GetText("reset_message_count_fail_user", user.Mention), + (null, not null, false) => GetText("reset_message_count_fail_channel", channel.Mention), + (not null, not null, false) => GetText("reset_message_count_fail_user_channel", user.Mention, channel.Mention) + }; + + await (result ? ctx.Channel.SendConfirmAsync(responseMessage) : ctx.Channel.SendErrorAsync(responseMessage, Config)); + } + + /// + /// Overload for + /// + /// Optional: The channel to reset message counts in. + /// A task that represents the asynchronous operation. + [Cmd] + [Aliases] + [RequireContext(ContextType.Guild)] + [UserPerm(GuildPermission.ManageMessages)] + public async Task ResetMessageCounts(ITextChannel? channel) + { + await ResetMessageCounts(null, channel); + } + + private IEnumerable<(int Hour, int Count)> AdjustHoursToTimezone(IEnumerable<(int Hour, int Count)> utcHours, TimeZoneInfo timezone) { diff --git a/src/Mewdeko/Modules/Utility/Services/MessageCountService.cs b/src/Mewdeko/Modules/Utility/Services/MessageCountService.cs index 8e7d9303d..33a1f1e1b 100644 --- a/src/Mewdeko/Modules/Utility/Services/MessageCountService.cs +++ b/src/Mewdeko/Modules/Utility/Services/MessageCountService.cs @@ -367,4 +367,71 @@ private async Task UpdateDatabase() .OrderByDescending(x => x.Item2) .ToList(); } + + /// + /// Resets message counts for a specified guild, user, or channel. + /// Deletes all guild messages, all messages for a user in a guild, + /// all messages in a channel in a guild, or all messages from a channel from a user. + /// + /// The ID of the guild. + /// The ID of the user (optional, default is 0). + /// The ID of the channel (optional, default is 0). + /// + /// A task that represents the asynchronous operation. + /// The task result contains a boolean indicating whether message counts were found and removed. + /// + public async Task ResetCount(ulong guildId, ulong userId = 0, ulong channelId = 0) + { + var countsToRemove = new List<(ulong GuildId, ulong UserId, ulong ChannelId)>(); + var found = false; + + await using var db = await dbContext.GetContextAsync(); + + if (userId == 0 && channelId == 0) + { + countsToRemove = messageCounts.Keys.Where(x => x.GuildId == guildId).ToList(); + found = countsToRemove.Count!=0; + } + else if (channelId == 0) + { + countsToRemove = messageCounts.Keys.Where(x => x.GuildId == guildId && x.UserId == userId).ToList(); + found = countsToRemove.Count!=0; + } + else if (userId == 0) + { + countsToRemove = messageCounts.Keys.Where(x => x.GuildId == guildId && x.ChannelId == channelId).ToList(); + found = countsToRemove.Count!=0; + } + else + { + var key = (guildId, userId, channelId); + if (messageCounts.ContainsKey(key)) + { + countsToRemove.Add(key); + found = true; + } + } + + if (!found) return false; + + foreach (var key in countsToRemove) + { + messageCounts.TryRemove(key, out _); + } + + var dbMessageCounts = await db.MessageCounts + .Where(mc => mc.GuildId == guildId) + .ToListAsync(); + + var filteredDbCounts = dbMessageCounts + .Where(mc => countsToRemove.Any(key => + mc.GuildId == key.GuildId && mc.UserId == key.UserId && mc.ChannelId == key.ChannelId)) + .ToList(); + + if (filteredDbCounts.Count == 0) return true; + db.MessageCounts.RemoveRange(filteredDbCounts); + await db.SaveChangesAsync(); + + return true; + } } \ No newline at end of file diff --git a/src/Mewdeko/Modules/Utility/Utility.cs b/src/Mewdeko/Modules/Utility/Utility.cs index cb203210a..6860a6ba0 100644 --- a/src/Mewdeko/Modules/Utility/Utility.cs +++ b/src/Mewdeko/Modules/Utility/Utility.cs @@ -6,6 +6,7 @@ using Fergun.Interactive; using Fergun.Interactive.Pagination; using Humanizer; +using LinqToDB; using Mewdeko.Common.Attributes.TextCommands; using Mewdeko.Common.JsonSettings; using Mewdeko.Common.TypeReaders.Models; @@ -1866,28 +1867,33 @@ public async Task Stats() { await using var dbContext = await dbProvider.GetContextAsync(); - var time = DateTime.UtcNow.Subtract(TimeSpan.FromSeconds(5)); - var commandStats = dbContext.CommandStats.Count(x => x.DateAdded.Value >= time); - var users = new[] + var fiveSecondsAgo = DateTime.Now.AddSeconds(-5); + var commandStatsTask = dbContext.CommandStats + .Where(x => x.DateAdded >= fiveSecondsAgo) + .CountAsync(); + var userTasks = new[] { - await client.Rest.GetUserAsync(280835732728184843).ConfigureAwait(false), - await client.Rest.GetUserAsync(786375627892064257).ConfigureAwait(false) + client.Rest.GetUserAsync(280835732728184843), + client.Rest.GetUserAsync(786375627892064257) }; + + var users = await Task.WhenAll(userTasks); + var commandStats = await commandStatsTask; + await ctx.Channel.EmbedAsync( - new EmbedBuilder().WithOkColor() - .WithAuthor($"{client.CurrentUser.Username} v{StatsService.BotVersion}", - client.CurrentUser.GetAvatarUrl(), config.Data.SupportServer) - .AddField(GetText("authors"), - $"[{users[0]}](https://github.com/SylveonDeko)\n[{users[1]}](https://github.com/CottageDwellingCat)") - .AddField(GetText("commands_ran"), $"{commandStats}/5s") - .AddField(GetText("command_count"), cmdServ.Commands.DistinctBy(x => x.Name).Count()) - .AddField("Library", stats.Library) - .AddField(GetText("owner_ids"), string.Join("\n", creds.OwnerIds.Select(x => $"<@{x}>"))) - .AddField(GetText("shard"), $"#{client.GetShardFor(ctx.Guild).ShardId} / {creds.TotalShards}") - .AddField(GetText("memory"), $"{stats.Heap} MB") - .AddField(GetText("uptime"), stats.GetUptimeString("\n")) - .AddField("Servers", $"{client.Guilds.Count} Servers")) - .ConfigureAwait(false); + new EmbedBuilder().WithOkColor() + .WithAuthor($"{client.CurrentUser.Username} v{StatsService.BotVersion}", + client.CurrentUser.GetAvatarUrl(), config.Data.SupportServer) + .AddField(GetText("authors"), + $"[{users[0]}](https://github.com/SylveonDeko)\n[{users[1]}](https://github.com/CottageDwellingCat)") + .AddField(GetText("commands_ran"), $"{commandStats}/5s") + .AddField(GetText("command_count"), cmdServ.Commands.DistinctBy(x => x.Name).Count()) + .AddField("Library", stats.Library) + .AddField(GetText("owner_ids"), string.Join("\n", creds.OwnerIds.Select(x => $"<@{x}>"))) + .AddField(GetText("shard"), $"#{client.GetShardFor(ctx.Guild).ShardId} / {creds.TotalShards}") + .AddField(GetText("memory"), $"{stats.Heap} MB") + .AddField(GetText("uptime"), stats.GetUptimeString("\n")) + .AddField("Servers", $"{client.Guilds.Count} Servers")); } /// diff --git a/src/Mewdeko/Program.cs b/src/Mewdeko/Program.cs index c0895da29..bb44c51eb 100644 --- a/src/Mewdeko/Program.cs +++ b/src/Mewdeko/Program.cs @@ -179,7 +179,7 @@ private static void ConfigureServices(IServiceCollection services, BotCredential services .AddSingleton() .AddSingleton(credentials) - .AddDbContext() + //.AddDbContext() .AddPooledDbContextFactory(dbContextOptionsBuilder => dbContextOptionsBuilder .UseNpgsql(credentials.PsqlConnectionString, x => x.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery)) diff --git a/src/Mewdeko/data/aliases.yml b/src/Mewdeko/data/aliases.yml index de43b68a6..b1d260042 100644 --- a/src/Mewdeko/data/aliases.yml +++ b/src/Mewdeko/data/aliases.yml @@ -49,6 +49,12 @@ antimassmention: - amm - massmention - stopmassmention +resetmessagecounts: + - resetmessagecounts + - rmc + - resetmsgcounts + - resetmessages + - resetcounts antimassmentionignorebots: - antimassmentionignorebots - ammignorebots diff --git a/src/Mewdeko/data/strings/commands/commands.en-US.yml b/src/Mewdeko/data/strings/commands/commands.en-US.yml index f08e5a1b4..eed02d619 100644 --- a/src/Mewdeko/data/strings/commands/commands.en-US.yml +++ b/src/Mewdeko/data/strings/commands/commands.en-US.yml @@ -8,6 +8,14 @@ addstatusrole: args: - "status" desc: Adds a status to be configured with the rest of the statusrole commands +resetmessagecounts: + args: + - "" + - "@user" + - "#channel" + - "@user #channel" + desc: >- + Resets message counts for the entire server, for a user, for a channel, or for a user in a specific channel. gpingrole: args: - "roleid" diff --git a/src/Mewdeko/data/strings/responses/responses.en-US.json b/src/Mewdeko/data/strings/responses/responses.en-US.json index 4e3ada0ec..cb502ad84 100644 --- a/src/Mewdeko/data/strings/responses/responses.en-US.json +++ b/src/Mewdeko/data/strings/responses/responses.en-US.json @@ -12,9 +12,22 @@ "nameban_no_users_found": "No users found matching the specified name pattern.", "lockdown_perm_ban_missing": "Bot cannot ban members.", "instance_status": "Instance Status", + "confirm_reset_message_count_guild": "Are you sure you want to reset the message counts for this server?", + "confirm_reset_message_count_user": "Are you sure you want to reset the message counts for {0}?", + "confirm_reset_message_count_channel": "Are you sure you want to reset the message counts for {0}?", + "confirm_reset_message_count_user_channel": "Are you sure you want to reset the message counts for {0} in {1}?", + "reset_message_count_success_guild": "Successfully reset all message counts in this server.", + "reset_message_count_success_user": "Successfully reset message counts for {0}.", + "reset_message_count_success_channel": "Successfully reset message counts for {0}.", + "reset_message_count_success_user_channel": "Successfully reset message counts for {0} in {1}.", + "reset_message_count_fail_guild": "Failed to reset message counts in this server. Ensure message counting is enabled.", + "reset_message_count_fail_user": "Failed to reset message counts for {0}. Ensure they have recorded message counts.", + "reset_message_count_fail_channel": "Failed to reset message counts for {0}. No message counts were found for this channel.", + "reset_message_count_fail_user_channel": "Failed to reset message counts for {0} in {1}. No matching entries were found.", "instances_none": "No instances found. Please add one and try again.", "instance_not_found": "That instance was not found. Please remove and", "user_invite_count": "{0} has {1} invites.", + "reset_message_user": "Are you sure you want to reset the message count for {0}?", "instance_latency": "Instance Latency: {0}ms", "instance_added": "Instance Added", "instance_version": "Instance Version: {0}",