From 2d73f4bdfde4dd4adcd1d832928178eada46d260 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 30 Mar 2017 03:51:54 +0200 Subject: [PATCH] .warn command, needs testing --- ...0170330000613_warning-commands.Designer.cs | 1346 +++++++++++++++++ .../20170330000613_warning-commands.cs | 78 + .../NadekoSqliteContextModelSnapshot.cs | 55 + .../Modules/Administration/Administration.cs | 95 -- .../Commands/LocalizationCommands.cs | 21 +- .../Commands/UserPunishCommands.cs | 358 +++++ .../Resources/CommandStrings.Designer.cs | 135 ++ src/NadekoBot/Resources/CommandStrings.resx | 45 + .../Resources/ResponseStrings.Designer.cs | 117 ++ src/NadekoBot/Resources/ResponseStrings.resx | 39 + .../Services/Database/IUnitOfWork.cs | 1 + .../Services/Database/Models/GuildConfig.cs | 10 +- .../Services/Database/Models/Warning.cs | 12 + .../Services/Database/NadekoContext.cs | 5 + .../Repositories/IWarningsRepository.cs | 11 + .../Impl/GuildConfigRepository.cs | 33 +- .../Repositories/Impl/WarningsRepository.cs | 37 + src/NadekoBot/Services/Database/UnitOfWork.cs | 3 + 18 files changed, 2293 insertions(+), 108 deletions(-) create mode 100644 src/NadekoBot/Migrations/20170330000613_warning-commands.Designer.cs create mode 100644 src/NadekoBot/Migrations/20170330000613_warning-commands.cs create mode 100644 src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs create mode 100644 src/NadekoBot/Services/Database/Models/Warning.cs create mode 100644 src/NadekoBot/Services/Database/Repositories/IWarningsRepository.cs create mode 100644 src/NadekoBot/Services/Database/Repositories/Impl/WarningsRepository.cs diff --git a/src/NadekoBot/Migrations/20170330000613_warning-commands.Designer.cs b/src/NadekoBot/Migrations/20170330000613_warning-commands.Designer.cs new file mode 100644 index 00000000..28a99d1d --- /dev/null +++ b/src/NadekoBot/Migrations/20170330000613_warning-commands.Designer.cs @@ -0,0 +1,1346 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using NadekoBot.Services.Database; +using NadekoBot.Services.Database.Models; +using NadekoBot.Modules.Music.Classes; + +namespace NadekoBot.Migrations +{ + [DbContext(typeof(NadekoContext))] + [Migration("20170330000613_warning-commands")] + partial class warningcommands + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("ProductVersion", "1.1.0-rtm-22752"); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Action"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Seconds"); + + b.Property("UserThreshold"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId") + .IsUnique(); + + b.ToTable("AntiRaidSetting"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AntiSpamSettingId"); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.HasKey("Id"); + + b.HasIndex("AntiSpamSettingId"); + + b.ToTable("AntiSpamIgnore"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Action"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("MessageThreshold"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId") + .IsUnique(); + + b.ToTable("AntiSpamSetting"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("DateAdded"); + + b.Property("ItemId"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("BlacklistItem"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BetflipMultiplier"); + + b.Property("Betroll100Multiplier"); + + b.Property("Betroll67Multiplier"); + + b.Property("Betroll91Multiplier"); + + b.Property("BufferSize"); + + b.Property("CurrencyDropAmount"); + + b.Property("CurrencyGenerationChance"); + + b.Property("CurrencyGenerationCooldown"); + + b.Property("CurrencyName"); + + b.Property("CurrencyPluralName"); + + b.Property("CurrencySign"); + + b.Property("DMHelpString"); + + b.Property("DateAdded"); + + b.Property("ErrorColor"); + + b.Property("ForwardMessages"); + + b.Property("ForwardToAllOwners"); + + b.Property("HelpString"); + + b.Property("Locale"); + + b.Property("MigrationVersion"); + + b.Property("MinimumBetAmount"); + + b.Property("OkColor"); + + b.Property("RemindMessageFormat"); + + b.Property("RotatingStatuses"); + + b.Property("TriviaCurrencyReward"); + + b.HasKey("Id"); + + b.ToTable("BotConfig"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BaseDestroyed"); + + b.Property("CallUser"); + + b.Property("ClashWarId"); + + b.Property("DateAdded"); + + b.Property("SequenceNumber"); + + b.Property("Stars"); + + b.Property("TimeAdded"); + + b.HasKey("Id"); + + b.HasIndex("ClashWarId"); + + b.ToTable("ClashCallers"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.Property("EnemyClan"); + + b.Property("GuildId"); + + b.Property("Size"); + + b.Property("StartedAt"); + + b.Property("WarState"); + + b.HasKey("Id"); + + b.ToTable("ClashOfClans"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandAlias", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Mapping"); + + b.Property("Trigger"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("CommandAlias"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("CommandName"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Seconds"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("CommandCooldown"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandPrice", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("CommandName"); + + b.Property("DateAdded"); + + b.Property("Price"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.HasIndex("Price") + .IsUnique(); + + b.ToTable("CommandPrice"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ConvertUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("InternalTrigger"); + + b.Property("Modifier"); + + b.Property("UnitType"); + + b.HasKey("Id"); + + b.ToTable("ConversionUnits"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Currency", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("DateAdded"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("Currency"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("DateAdded"); + + b.Property("Reason"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.ToTable("CurrencyTransactions"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CustomReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AutoDeleteTrigger"); + + b.Property("DateAdded"); + + b.Property("DmResponse"); + + b.Property("GuildId"); + + b.Property("IsRegex"); + + b.Property("OwnerOnly"); + + b.Property("Response"); + + b.Property("Trigger"); + + b.HasKey("Id"); + + b.ToTable("CustomReactions"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.DiscordUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AvatarId"); + + b.Property("DateAdded"); + + b.Property("Discriminator"); + + b.Property("UserId"); + + b.Property("Username"); + + b.HasKey("Id"); + + b.HasAlternateKey("UserId"); + + b.ToTable("DiscordUser"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("DateAdded"); + + b.Property("Name"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("Donators"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("DateAdded"); + + b.Property("Text"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("EightBallResponses"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("GuildConfigId1"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.HasIndex("GuildConfigId1"); + + b.ToTable("FilterChannelId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Word"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("FilteredWord"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("GuildId"); + + b.Property("Type"); + + b.Property("Username"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("FollowedStream"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("GCChannelId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AutoAssignRoleId"); + + b.Property("AutoDeleteByeMessages"); + + b.Property("AutoDeleteByeMessagesTimer"); + + b.Property("AutoDeleteGreetMessages"); + + b.Property("AutoDeleteGreetMessagesTimer"); + + b.Property("AutoDeleteSelfAssignedRoleMessages"); + + b.Property("ByeMessageChannelId"); + + b.Property("ChannelByeMessageText"); + + b.Property("ChannelGreetMessageText"); + + b.Property("CleverbotEnabled"); + + b.Property("DateAdded"); + + b.Property("DefaultMusicVolume"); + + b.Property("DeleteMessageOnCommand"); + + b.Property("DmGreetMessageText"); + + b.Property("ExclusiveSelfAssignedRoles"); + + b.Property("FilterInvites"); + + b.Property("FilterWords"); + + b.Property("GreetMessageChannelId"); + + b.Property("GuildId"); + + b.Property("Locale"); + + b.Property("LogSettingId"); + + b.Property("MuteRoleName"); + + b.Property("PermissionRole"); + + b.Property("RootPermissionId"); + + b.Property("SendChannelByeMessage"); + + b.Property("SendChannelGreetMessage"); + + b.Property("SendDmGreetMessage"); + + b.Property("TimeZoneId"); + + b.Property("VerbosePermissions"); + + b.Property("VoicePlusTextEnabled"); + + b.Property("WarningsInitialized"); + + b.HasKey("Id"); + + b.HasIndex("GuildId") + .IsUnique(); + + b.HasIndex("LogSettingId"); + + b.HasIndex("RootPermissionId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildRepeater", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("GuildId"); + + b.Property("Interval"); + + b.Property("Message"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("GuildRepeater"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.Property("LogSettingId"); + + b.HasKey("Id"); + + b.HasIndex("LogSettingId"); + + b.ToTable("IgnoredLogChannels"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.Property("LogSettingId"); + + b.HasKey("Id"); + + b.HasIndex("LogSettingId"); + + b.ToTable("IgnoredVoicePresenceCHannels"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelCreated"); + + b.Property("ChannelCreatedId"); + + b.Property("ChannelDestroyed"); + + b.Property("ChannelDestroyedId"); + + b.Property("ChannelId"); + + b.Property("ChannelUpdated"); + + b.Property("ChannelUpdatedId"); + + b.Property("DateAdded"); + + b.Property("IsLogging"); + + b.Property("LogOtherId"); + + b.Property("LogUserPresence"); + + b.Property("LogUserPresenceId"); + + b.Property("LogVoicePresence"); + + b.Property("LogVoicePresenceId"); + + b.Property("LogVoicePresenceTTSId"); + + b.Property("MessageDeleted"); + + b.Property("MessageDeletedId"); + + b.Property("MessageUpdated"); + + b.Property("MessageUpdatedId"); + + b.Property("UserBanned"); + + b.Property("UserBannedId"); + + b.Property("UserJoined"); + + b.Property("UserJoinedId"); + + b.Property("UserLeft"); + + b.Property("UserLeftId"); + + b.Property("UserMutedId"); + + b.Property("UserPresenceChannelId"); + + b.Property("UserUnbanned"); + + b.Property("UserUnbannedId"); + + b.Property("UserUpdated"); + + b.Property("UserUpdatedId"); + + b.Property("VoicePresenceChannelId"); + + b.HasKey("Id"); + + b.ToTable("LogSettings"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("DateAdded"); + + b.Property("ModuleName"); + + b.Property("Prefix"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("ModulePrefixes"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Author"); + + b.Property("AuthorId"); + + b.Property("DateAdded"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.ToTable("MusicPlaylists"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("MutedUserId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("NextId"); + + b.Property("PrimaryTarget"); + + b.Property("PrimaryTargetId"); + + b.Property("SecondaryTarget"); + + b.Property("SecondaryTargetName"); + + b.Property("State"); + + b.HasKey("Id"); + + b.HasIndex("NextId") + .IsUnique(); + + b.ToTable("Permission"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Permissionv2", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Index"); + + b.Property("PrimaryTarget"); + + b.Property("PrimaryTargetId"); + + b.Property("SecondaryTarget"); + + b.Property("SecondaryTargetName"); + + b.Property("State"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("Permissionv2"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("DateAdded"); + + b.Property("Status"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("PlayingStatus"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("MusicPlaylistId"); + + b.Property("Provider"); + + b.Property("ProviderType"); + + b.Property("Query"); + + b.Property("Title"); + + b.Property("Uri"); + + b.HasKey("Id"); + + b.HasIndex("MusicPlaylistId"); + + b.ToTable("PlaylistSong"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuthorId"); + + b.Property("AuthorName") + .IsRequired(); + + b.Property("DateAdded"); + + b.Property("GuildId"); + + b.Property("Keyword") + .IsRequired(); + + b.Property("Text") + .IsRequired(); + + b.HasKey("Id"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("DateAdded"); + + b.Property("Icon"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("RaceAnimals"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.Property("IsPrivate"); + + b.Property("Message"); + + b.Property("ServerId"); + + b.Property("UserId"); + + b.Property("When"); + + b.HasKey("Id"); + + b.ToTable("Reminders"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildId", "RoleId") + .IsUnique(); + + b.ToTable("SelfAssignableRoles"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UnmuteAt"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("UnmuteTimer"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.UserPokeTypes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("UserId"); + + b.Property("type"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("PokeGame"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("RoleId"); + + b.Property("VoiceChannelId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("VcRoleInfo"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AffinityId"); + + b.Property("ClaimerId"); + + b.Property("DateAdded"); + + b.Property("Price"); + + b.Property("WaifuId"); + + b.HasKey("Id"); + + b.HasIndex("AffinityId"); + + b.HasIndex("ClaimerId"); + + b.HasIndex("WaifuId") + .IsUnique(); + + b.ToTable("WaifuInfo"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("NewId"); + + b.Property("OldId"); + + b.Property("UpdateType"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("NewId"); + + b.HasIndex("OldId"); + + b.HasIndex("UserId"); + + b.ToTable("WaifuUpdates"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Warning", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("Forgiven"); + + b.Property("ForgivenBy"); + + b.Property("GuildId"); + + b.Property("Moderator"); + + b.Property("Reason"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.ToTable("Warnings"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Count"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Punishment"); + + b.Property("Time"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("WarningPunishment"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig") + .WithOne("AntiRaidSetting") + .HasForeignKey("NadekoBot.Services.Database.Models.AntiRaidSetting", "GuildConfigId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b => + { + b.HasOne("NadekoBot.Services.Database.Models.AntiSpamSetting") + .WithMany("IgnoredChannels") + .HasForeignKey("AntiSpamSettingId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig") + .WithOne("AntiSpamSetting") + .HasForeignKey("NadekoBot.Services.Database.Models.AntiSpamSetting", "GuildConfigId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("Blacklist") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar") + .WithMany("Bases") + .HasForeignKey("ClashWarId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandAlias", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("CommandAliases") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("CommandCooldowns") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandPrice", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("CommandPrices") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("EightBallResponses") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FilterInvitesChannelIds") + .HasForeignKey("GuildConfigId"); + + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FilterWordsChannelIds") + .HasForeignKey("GuildConfigId1"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FilteredWords") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FollowedStreams") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("GenerateCurrencyChannelIds") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => + { + b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting") + .WithMany() + .HasForeignKey("LogSettingId"); + + b.HasOne("NadekoBot.Services.Database.Models.Permission", "RootPermission") + .WithMany() + .HasForeignKey("RootPermissionId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildRepeater", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("GuildRepeaters") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b => + { + b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting") + .WithMany("IgnoredChannels") + .HasForeignKey("LogSettingId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b => + { + b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting") + .WithMany("IgnoredVoicePresenceChannelIds") + .HasForeignKey("LogSettingId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("ModulePrefixes") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("MutedUsers") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b => + { + b.HasOne("NadekoBot.Services.Database.Models.Permission", "Next") + .WithOne("Previous") + .HasForeignKey("NadekoBot.Services.Database.Models.Permission", "NextId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Permissionv2", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("Permissions") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("RotatingStatusMessages") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b => + { + b.HasOne("NadekoBot.Services.Database.Models.MusicPlaylist") + .WithMany("Songs") + .HasForeignKey("MusicPlaylistId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("RaceAnimals") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("UnmuteTimers") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("VcRoleInfos") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b => + { + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Affinity") + .WithMany() + .HasForeignKey("AffinityId"); + + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Claimer") + .WithMany() + .HasForeignKey("ClaimerId"); + + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Waifu") + .WithOne() + .HasForeignKey("NadekoBot.Services.Database.Models.WaifuInfo", "WaifuId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b => + { + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "New") + .WithMany() + .HasForeignKey("NewId"); + + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Old") + .WithMany() + .HasForeignKey("OldId"); + + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("WarnPunishments") + .HasForeignKey("GuildConfigId"); + }); + } + } +} diff --git a/src/NadekoBot/Migrations/20170330000613_warning-commands.cs b/src/NadekoBot/Migrations/20170330000613_warning-commands.cs new file mode 100644 index 00000000..5fb96271 --- /dev/null +++ b/src/NadekoBot/Migrations/20170330000613_warning-commands.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class warningcommands : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "WarningsInitialized", + table: "GuildConfigs", + nullable: false, + defaultValue: false); + + migrationBuilder.CreateTable( + name: "Warnings", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + DateAdded = table.Column(nullable: true), + Forgiven = table.Column(nullable: false), + ForgivenBy = table.Column(nullable: true), + GuildId = table.Column(nullable: false), + Moderator = table.Column(nullable: true), + Reason = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Warnings", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "WarningPunishment", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Count = table.Column(nullable: false), + DateAdded = table.Column(nullable: true), + GuildConfigId = table.Column(nullable: true), + Punishment = table.Column(nullable: false), + Time = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_WarningPunishment", x => x.Id); + table.ForeignKey( + name: "FK_WarningPunishment_GuildConfigs_GuildConfigId", + column: x => x.GuildConfigId, + principalTable: "GuildConfigs", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_WarningPunishment_GuildConfigId", + table: "WarningPunishment", + column: "GuildConfigId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Warnings"); + + migrationBuilder.DropTable( + name: "WarningPunishment"); + + migrationBuilder.DropColumn( + name: "WarningsInitialized", + table: "GuildConfigs"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index 18195d44..97e9b393 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -559,6 +559,8 @@ namespace NadekoBot.Migrations b.Property("VoicePlusTextEnabled"); + b.Property("WarningsInitialized"); + b.HasKey("Id"); b.HasIndex("GuildId") @@ -1060,6 +1062,52 @@ namespace NadekoBot.Migrations b.ToTable("WaifuUpdates"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.Warning", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("Forgiven"); + + b.Property("ForgivenBy"); + + b.Property("GuildId"); + + b.Property("Moderator"); + + b.Property("Reason"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.ToTable("Warnings"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Count"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Punishment"); + + b.Property("Time"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("WarningPunishment"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b => { b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig") @@ -1285,6 +1333,13 @@ namespace NadekoBot.Migrations .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade); }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("WarnPunishments") + .HasForeignKey("GuildConfigId"); + }); } } } diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index 4eb9d28c..2f076ae3 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -218,101 +218,6 @@ namespace NadekoBot.Modules.Administration } } - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequireUserPermission(GuildPermission.BanMembers)] - [RequireBotPermission(GuildPermission.BanMembers)] - public async Task Ban(IGuildUser user, [Remainder] string msg = null) - { - if (Context.User.Id != user.Guild.OwnerId && (user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max())) - { - await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); - return; - } - if (!string.IsNullOrWhiteSpace(msg)) - { - try - { - await user.SendErrorAsync(GetText("bandm", Format.Bold(Context.Guild.Name), msg)); - } - catch - { - // ignored - } - } - - await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false); - await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() - .WithTitle("⛔️ " + GetText("banned_user")) - .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) - .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) - .ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequireUserPermission(GuildPermission.KickMembers)] - [RequireUserPermission(GuildPermission.ManageMessages)] - [RequireBotPermission(GuildPermission.BanMembers)] - public async Task Softban(IGuildUser user, [Remainder] string msg = null) - { - if (Context.User.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) - { - await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); - return; - } - - if (!string.IsNullOrWhiteSpace(msg)) - { - try - { - await user.SendErrorAsync(GetText("sbdm", Format.Bold(Context.Guild.Name), msg)); - } - catch - { - // ignored - } - } - - await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false); - try { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); } - catch { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); } - - await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() - .WithTitle("☣ " + GetText("sb_user")) - .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) - .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) - .ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequireUserPermission(GuildPermission.KickMembers)] - [RequireBotPermission(GuildPermission.KickMembers)] - public async Task Kick(IGuildUser user, [Remainder] string msg = null) - { - if (Context.Message.Author.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) - { - await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); - return; - } - if (!string.IsNullOrWhiteSpace(msg)) - { - try - { - await user.SendErrorAsync(GetText("kickdm", Format.Bold(Context.Guild.Name), msg)); - } - catch { } - } - - await user.KickAsync().ConfigureAwait(false); - await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() - .WithTitle(GetText("kicked_user")) - .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) - .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) - .ConfigureAwait(false); - } - [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequireUserPermission(GuildPermission.DeafenMembers)] diff --git a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs index b61b2722..bc4a0952 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs @@ -16,25 +16,26 @@ namespace NadekoBot.Modules.Administration [Group] public class LocalizationCommands : NadekoSubmodule { + //Română, România private ImmutableDictionary supportedLocales { get; } = new Dictionary() { - {"zh-TW", "Chinese (Traditional), China" }, - {"zh-CN", "Chinese (Simplified), China"}, + {"zh-TW", "繁體中文, 台灣" }, + {"zh-CN", "简体中文, 中华人民共和国"}, {"nl-NL", "Dutch, Netherlands"}, {"en-US", "English, United States"}, - {"fr-FR", "French, France"}, + {"fr-FR", "Français, France"}, {"de-DE", "German, Germany"}, {"he-IL", "Hebrew, Israel" }, - {"it-IT", "Italian, Italy" }, + {"it-IT", "Italiano, Italia" }, //{"ja-JP", "Japanese, Japan"}, - {"ko-KR", "Korean, Korea" }, + {"ko-KR", "Korean, South Korea" }, {"nb-NO", "Norwegian (bokmål), Norway"}, - {"pl-PL", "Polish, Poland" }, - {"pt-BR", "Portuguese, Brazil"}, + {"pl-PL", "Polski, Polska" }, + {"pt-BR", "Português Brasileiro, Brasil"}, {"ru-RU", "Russian, Russia"}, - {"sr-Cyrl-RS", "Serbian, Serbia - Cyrillic"}, - {"es-ES", "Spanish, Spain"}, - {"sv-SE", "Swedish, Sweden"}, + {"sr-Cyrl-RS", "Српски, Србија"}, + {"es-ES", "Español, España"}, + {"sv-SE", "Svenska, Sverige"}, {"tr-TR", "Turkish, Turkey" } }.ToImmutableDictionary(); diff --git a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs new file mode 100644 index 00000000..0f54037f --- /dev/null +++ b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs @@ -0,0 +1,358 @@ +using Discord; +using Discord.Commands; +using Discord.WebSocket; +using Microsoft.EntityFrameworkCore; +using NadekoBot.Attributes; +using NadekoBot.Extensions; +using NadekoBot.Services; +using NadekoBot.Services.Database.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Administration +{ + public partial class Administration + { + [Group] + public class UserPunishCommands : NadekoSubmodule + { + private async Task InternalWarn(IGuild guild, ulong userId, string modName, string reason) + { + if (string.IsNullOrWhiteSpace(reason)) + reason = "-"; + + var guildId = guild.Id; + + var warn = new Warning() + { + UserId = userId, + GuildId = guildId, + Forgiven = false, + Reason = reason, + Moderator = modName, + }; + + int warnings; + List ps; + using (var uow = DbHandler.UnitOfWork()) + { + ps = uow.GuildConfigs.For(guildId, set => set.Include(x => x.WarnPunishments)) + .WarnPunishments; + + uow.Warnings.Add(warn); + + warnings = uow.Warnings + .For(guildId, userId) + .Where(w => !w.Forgiven && w.UserId == userId) + .Count(); + + uow.Complete(); + } + + var p = ps.FirstOrDefault(x => x.Count == warnings); + + if (p != null) + { + var user = await guild.GetUserAsync(userId); + if (user == null) + return; + switch (p.Punishment) + { + case PunishmentAction.Mute: + await MuteCommands.TimedMute(user, TimeSpan.FromMinutes(p.Time)); + break; + case PunishmentAction.Kick: + await user.KickAsync().ConfigureAwait(false); + break; + case PunishmentAction.Ban: + await guild.AddBanAsync(user).ConfigureAwait(false); + break; + default: + break; + } + } + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public async Task Warn(IGuildUser user, [Remainder] string reason = null) + { + try + { + await (await user.CreateDMChannelAsync()).EmbedAsync(new EmbedBuilder().WithErrorColor() + .WithDescription(GetText("warned_on", Context.Guild.ToString())) + .AddField(efb => efb.WithName(GetText("moderator")).WithValue(Context.User.ToString())) + .AddField(efb => efb.WithName(GetText("reason")).WithValue(reason ?? "-"))) + .ConfigureAwait(false); + } + catch { } + await InternalWarn(Context.Guild, user.Id, Context.User.ToString(), reason).ConfigureAwait(false); + + await ReplyConfirmLocalized("user_warned", Format.Bold(user.ToString())).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public Task Warnlog(int page, IGuildUser user) + => Warnlog(page, user.Id); + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public Task Warnlog(IGuildUser user) + => Warnlog(user.Id); + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public Task Warnlog(int page, ulong userId) + => InternalWarnlog(userId, page - 1); + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public Task Warnlog(ulong userId) + => InternalWarnlog(userId, 0); + + private async Task InternalWarnlog(ulong userId, int page) + { + if (page < 0) + return; + Warning[] warnings; + using (var uow = DbHandler.UnitOfWork()) + { + warnings = uow.Warnings.For(Context.Guild.Id, userId); + } + + warnings = warnings.Skip(page * 9) + .Take(9) + .ToArray(); + + var embed = new EmbedBuilder().WithOkColor() + .WithTitle(GetText("warnlog_for", (Context.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString())) + .WithFooter(efb => efb.WithText(GetText("page", page + 1))); + + if (!warnings.Any()) + { + embed.WithDescription(GetText("warnings_none")); + } + else + { + foreach (var w in warnings) + { + var name = GetText("warned_on_by", w.DateAdded.Value.ToString("dd.MM.yyy"), w.DateAdded.Value.ToString("HH:mm"), w.Moderator); + if (w.Forgiven) + name = Format.Strikethrough(name) + GetText("warn_cleared_by", w.ForgivenBy); + + embed.AddField(x => x + .WithName(name) + .WithValue(w.Reason)); + } + } + + await Context.Channel.EmbedAsync(embed); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public Task Warnclear(IGuildUser user) + => Warnclear(user.Id); + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public async Task Warnclear(ulong userId) + { + using (var uow = DbHandler.UnitOfWork()) + { + await uow.Warnings.ForgiveAll(Context.Guild.Id, userId, Context.User.ToString()).ConfigureAwait(false); + uow.Complete(); + } + + await ReplyConfirmLocalized("warnings_cleared", + (Context.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString()).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public async Task WarnPunish(int number, PunishmentAction punish, int time = 0) + { + if (punish != PunishmentAction.Mute && time != 0) + return; + if (number <= 0) + return; + + using (var uow = DbHandler.UnitOfWork()) + { + var ps = uow.GuildConfigs.For(Context.Guild.Id).WarnPunishments; + var p = ps.FirstOrDefault(x => x.Count == number); + + if (p == null) + { + ps.Add(new WarningPunishment() + { + Count = number, + Punishment = punish, + Time = time, + }); + } + else + { + p.Count = number; + p.Punishment = punish; + p.Time = time; + uow._context.Update(p); + } + uow.Complete(); + } + + await ReplyConfirmLocalized("warn_punish_set", + Format.Bold(punish.ToString()), + Format.Bold(number.ToString())).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public async Task WarnPunish(int number) + { + if (number <= 0) + return; + + using (var uow = DbHandler.UnitOfWork()) + { + var ps = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.WarnPunishments)).WarnPunishments; + var p = ps.FirstOrDefault(x => x.Count == number); + + if (p != null) + { + uow._context.Remove(p); + uow.Complete(); + } + } + + await ReplyConfirmLocalized("warn_punish_rem", + Format.Bold(number.ToString())).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task WarnPunishList() + { + WarningPunishment[] ps; + using (var uow = DbHandler.UnitOfWork()) + { + ps = uow.GuildConfigs.For(Context.Guild.Id, gc => gc.Include(x => x.WarnPunishments)) + .WarnPunishments + .OrderBy(x => x.Count) + .ToArray(); + } + + await Context.Channel.SendConfirmAsync( + GetText("warn_punish_list"), + string.Join("\n", ps.Select(x => $"{x.Count} -> {x.Punishment}"))).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + [RequireBotPermission(GuildPermission.BanMembers)] + public async Task Ban(IGuildUser user, [Remainder] string msg = null) + { + if (Context.User.Id != user.Guild.OwnerId && (user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max())) + { + await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); + return; + } + if (!string.IsNullOrWhiteSpace(msg)) + { + try + { + await user.SendErrorAsync(GetText("bandm", Format.Bold(Context.Guild.Name), msg)); + } + catch + { + // ignored + } + } + + await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false); + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithTitle("⛔️ " + GetText("banned_user")) + .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) + .ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.KickMembers)] + [RequireUserPermission(GuildPermission.ManageMessages)] + [RequireBotPermission(GuildPermission.BanMembers)] + public async Task Softban(IGuildUser user, [Remainder] string msg = null) + { + if (Context.User.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) + { + await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); + return; + } + + if (!string.IsNullOrWhiteSpace(msg)) + { + try + { + await user.SendErrorAsync(GetText("sbdm", Format.Bold(Context.Guild.Name), msg)); + } + catch + { + // ignored + } + } + + await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false); + try { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); } + catch { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); } + + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithTitle("☣ " + GetText("sb_user")) + .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) + .ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.KickMembers)] + [RequireBotPermission(GuildPermission.KickMembers)] + public async Task Kick(IGuildUser user, [Remainder] string msg = null) + { + if (Context.Message.Author.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) + { + await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); + return; + } + if (!string.IsNullOrWhiteSpace(msg)) + { + try + { + await user.SendErrorAsync(GetText("kickdm", Format.Bold(Context.Guild.Name), msg)); + } + catch { } + } + + await user.KickAsync().ConfigureAwait(false); + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithTitle(GetText("kicked_user")) + .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) + .ConfigureAwait(false); + } + } + } +} diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index cc7550b6..bba6abe1 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -9104,6 +9104,141 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to warn. + /// + public static string warn_cmd { + get { + return ResourceManager.GetString("warn_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warns a user.. + /// + public static string warn_desc { + get { + return ResourceManager.GetString("warn_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}warn @b1nzy`. + /// + public static string warn_usage { + get { + return ResourceManager.GetString("warn_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to warnclear warnc. + /// + public static string warnclear_cmd { + get { + return ResourceManager.GetString("warnclear_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Clears all warnings from a certain user.. + /// + public static string warnclear_desc { + get { + return ResourceManager.GetString("warnclear_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}warnclear @PoorDude`. + /// + public static string warnclear_usage { + get { + return ResourceManager.GetString("warnclear_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to warnlog. + /// + public static string warnlog_cmd { + get { + return ResourceManager.GetString("warnlog_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to See a list of warnings of a certain user.. + /// + public static string warnlog_desc { + get { + return ResourceManager.GetString("warnlog_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}warnlog @b1nzy`. + /// + public static string warnlog_usage { + get { + return ResourceManager.GetString("warnlog_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to warnpunish warnp. + /// + public static string warnpunish_cmd { + get { + return ResourceManager.GetString("warnpunish_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sets a punishment for a certain number of warnings. Provide no punishment to remove.. + /// + public static string warnpunish_desc { + get { + return ResourceManager.GetString("warnpunish_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}warnpunish 5 Ban` or `{0}warnpunish 3`. + /// + public static string warnpunish_usage { + get { + return ResourceManager.GetString("warnpunish_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to warnpunishlist warnpl. + /// + public static string warnpunishlist_cmd { + get { + return ResourceManager.GetString("warnpunishlist_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lists punishments for warnings.. + /// + public static string warnpunishlist_desc { + get { + return ResourceManager.GetString("warnpunishlist_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}warnpunishlist`. + /// + public static string warnpunishlist_usage { + get { + return ResourceManager.GetString("warnpunishlist_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to weather we. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 790df4de..1f236f0a 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3222,4 +3222,49 @@ `{0}alias allin $bf 100 h` or `{0}alias "linux thingy" >loonix Spyware Windows` + + warnlog + + + See a list of warnings of a certain user. + + + `{0}warnlog @b1nzy` + + + warn + + + Warns a user. + + + `{0}warn @b1nzy` + + + warnclear warnc + + + Clears all warnings from a certain user. + + + `{0}warnclear @PoorDude` + + + warnpunishlist warnpl + + + Lists punishments for warnings. + + + `{0}warnpunishlist` + + + warnpunish warnp + + + Sets a punishment for a certain number of warnings. Provide no punishment to remove. + + + `{0}warnpunish 5 Ban` or `{0}warnpunish 3` + \ No newline at end of file diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 1b0cd969..b440fe8a 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -736,6 +736,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Moderator. + /// + public static string administration_moderator { + get { + return ResourceManager.GetString("administration_moderator", resourceCulture); + } + } + /// /// Looks up a localized string similar to {0} moved from {1} to {2}. /// @@ -907,6 +916,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to page {0}. + /// + public static string administration_page { + get { + return ResourceManager.GetString("administration_page", resourceCulture); + } + } + /// /// Looks up a localized string similar to Error. Most likely I don't have sufficient permissions.. /// @@ -1060,6 +1078,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Reason. + /// + public static string administration_reason { + get { + return ResourceManager.GetString("administration_reason", resourceCulture); + } + } + /// /// Looks up a localized string similar to Successfully removed role {0} from user {1}. /// @@ -1648,6 +1675,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to User {0} has been warned.. + /// + public static string administration_user_warned { + get { + return ResourceManager.GetString("administration_user_warned", resourceCulture); + } + } + /// /// Looks up a localized string similar to Username. /// @@ -1765,6 +1801,87 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to cleared by {0}. + /// + public static string administration_warn_cleared_by { + get { + return ResourceManager.GetString("administration_warn_cleared_by", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warning punishment list. + /// + public static string administration_warn_punish_list { + get { + return ResourceManager.GetString("administration_warn_punish_list", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Having {0} warnings will no longer trigger a punishment.. + /// + public static string administration_warn_punish_rem { + get { + return ResourceManager.GetString("administration_warn_punish_rem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to I will apply {0} punishment to users with {1} warnings.. + /// + public static string administration_warn_punish_set { + get { + return ResourceManager.GetString("administration_warn_punish_set", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warned on {0} server. + /// + public static string administration_warned_on { + get { + return ResourceManager.GetString("administration_warned_on", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to On {0} at {1} by {2}. + /// + public static string administration_warned_on_by { + get { + return ResourceManager.GetString("administration_warned_on_by", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All warnings have been cleared for {0}.. + /// + public static string administration_warnings_cleared { + get { + return ResourceManager.GetString("administration_warnings_cleared", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No warning on this page.. + /// + public static string administration_warnings_none { + get { + return ResourceManager.GetString("administration_warnings_none", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warnlog for {0}. + /// + public static string administration_warnlog_for { + get { + return ResourceManager.GetString("administration_warnlog_for", resourceCulture); + } + } + /// /// Looks up a localized string similar to User {0} from text chat. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 6f8446b9..f8523242 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2278,4 +2278,43 @@ Owner ID: {2} Competitive playtime + + Moderator + + + page {0} + + + Reason + + + User {0} has been warned. + + + Warned on {0} server + + + On {0} at {1} by {2} + + + All warnings have been cleared for {0}. + + + No warning on this page. + + + Warnlog for {0} + + + cleared by {0} + + + Warning punishment list + + + Having {0} warnings will no longer trigger a punishment. + + + I will apply {0} punishment to users with {1} warnings. + \ No newline at end of file diff --git a/src/NadekoBot/Services/Database/IUnitOfWork.cs b/src/NadekoBot/Services/Database/IUnitOfWork.cs index c1c9479e..52cb01cf 100644 --- a/src/NadekoBot/Services/Database/IUnitOfWork.cs +++ b/src/NadekoBot/Services/Database/IUnitOfWork.cs @@ -23,6 +23,7 @@ namespace NadekoBot.Services.Database IPokeGameRepository PokeGame { get; } IWaifuRepository Waifus { get; } IDiscordUserRepository DiscordUsers { get; } + IWarningsRepository Warnings { get; } int Complete(); Task CompleteAsync(); diff --git a/src/NadekoBot/Services/Database/Models/GuildConfig.cs b/src/NadekoBot/Services/Database/Models/GuildConfig.cs index 00693f16..4fe497c1 100644 --- a/src/NadekoBot/Services/Database/Models/GuildConfig.cs +++ b/src/NadekoBot/Services/Database/Models/GuildConfig.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using static NadekoBot.Modules.Administration.Administration; namespace NadekoBot.Services.Database.Models { @@ -72,10 +71,19 @@ namespace NadekoBot.Services.Database.Models public HashSet UnmuteTimers { get; set; } = new HashSet(); public HashSet VcRoleInfos { get; set; } public HashSet CommandAliases { get; set; } = new HashSet(); + public List WarnPunishments { get; set; } = new List(); + public bool WarningsInitialized { get; set; } //public List ProtectionIgnoredChannels { get; set; } = new List(); } + public class WarningPunishment : DbEntity + { + public int Count { get; set; } + public PunishmentAction Punishment { get; set; } + public int Time { get; set; } + } + public class CommandAlias : DbEntity { public string Trigger { get; set; } diff --git a/src/NadekoBot/Services/Database/Models/Warning.cs b/src/NadekoBot/Services/Database/Models/Warning.cs new file mode 100644 index 00000000..e5c8f4ff --- /dev/null +++ b/src/NadekoBot/Services/Database/Models/Warning.cs @@ -0,0 +1,12 @@ +namespace NadekoBot.Services.Database.Models +{ + public class Warning : DbEntity + { + public ulong GuildId { get; set; } + public ulong UserId { get; set; } + public string Reason { get; set; } + public bool Forgiven { get; set; } + public string ForgivenBy { get; set; } + public string Moderator { get; set; } + } +} diff --git a/src/NadekoBot/Services/Database/NadekoContext.cs b/src/NadekoBot/Services/Database/NadekoContext.cs index 4efb6150..a82cfde8 100644 --- a/src/NadekoBot/Services/Database/NadekoContext.cs +++ b/src/NadekoBot/Services/Database/NadekoContext.cs @@ -40,6 +40,7 @@ namespace NadekoBot.Services.Database public DbSet CurrencyTransactions { get; set; } public DbSet PokeGame { get; set; } public DbSet WaifuUpdates { get; set; } + public DbSet Warnings { get; set; } //logging public DbSet LogSettings { get; set; } @@ -272,6 +273,10 @@ namespace NadekoBot.Services.Database du.HasAlternateKey(w => w.UserId); #endregion + + #region Warnings + var warn = modelBuilder.Entity(); + #endregion } } } diff --git a/src/NadekoBot/Services/Database/Repositories/IWarningsRepository.cs b/src/NadekoBot/Services/Database/Repositories/IWarningsRepository.cs new file mode 100644 index 00000000..2b2e5ac4 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/IWarningsRepository.cs @@ -0,0 +1,11 @@ +using NadekoBot.Services.Database.Models; +using System.Threading.Tasks; + +namespace NadekoBot.Services.Database.Repositories +{ + public interface IWarningsRepository : IRepository + { + Warning[] For(ulong guildId, ulong userId); + Task ForgiveAll(ulong guildId, ulong userId, string mod); + } +} diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs index 7098888d..01a44677 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs @@ -12,6 +12,18 @@ namespace NadekoBot.Services.Database.Repositories.Impl { } + private List DefaultWarnPunishments => + new List() { + new WarningPunishment() { + Count = 3, + Punishment = PunishmentAction.Kick + }, + new WarningPunishment() { + Count = 5, + Punishment = PunishmentAction.Ban + } + }; + public IEnumerable GetAllGuildConfigs() => _set.Include(gc => gc.LogSetting) .ThenInclude(ls => ls.IgnoredChannels) @@ -64,10 +76,19 @@ namespace NadekoBot.Services.Database.Repositories.Impl _set.Add((config = new GuildConfig { GuildId = guildId, - Permissions = Permissionv2.GetDefaultPermlist + Permissions = Permissionv2.GetDefaultPermlist, + WarningsInitialized = true, + WarnPunishments = DefaultWarnPunishments, })); _context.SaveChanges(); } + + if (!config.WarningsInitialized) + { + config.WarningsInitialized = true; + config.WarnPunishments = DefaultWarnPunishments; + } + return config; } @@ -82,10 +103,18 @@ namespace NadekoBot.Services.Database.Repositories.Impl _set.Add((config = new GuildConfig { GuildId = guildId, - Permissions = Permissionv2.GetDefaultPermlist + Permissions = Permissionv2.GetDefaultPermlist, + WarningsInitialized = true, + WarnPunishments = DefaultWarnPunishments, })); _context.SaveChanges(); } + + if (!config.WarningsInitialized) + { + config.WarningsInitialized = true; + config.WarnPunishments = DefaultWarnPunishments; + } return config; } diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/WarningsRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/WarningsRepository.cs new file mode 100644 index 00000000..4bf4c293 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/Impl/WarningsRepository.cs @@ -0,0 +1,37 @@ +using NadekoBot.Services.Database.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace NadekoBot.Services.Database.Repositories.Impl +{ + public class WarningsRepository : Repository, IWarningsRepository + { + public WarningsRepository(DbContext context) : base(context) + { + } + + public Warning[] For(ulong guildId, ulong userId) + { + var query = _set.Where(x => x.GuildId == guildId && x.UserId == userId) + .OrderByDescending(x => x.DateAdded); + + return query.ToArray(); + } + + public async Task ForgiveAll(ulong guildId, ulong userId, string mod) + { + await _set.Where(x => x.GuildId == guildId && x.UserId == userId) + .ForEachAsync(x => + { + if (x.Forgiven != true) + { + x.Forgiven = true; + x.ForgivenBy = mod; + } + }) + .ConfigureAwait(false); + } + } +} diff --git a/src/NadekoBot/Services/Database/UnitOfWork.cs b/src/NadekoBot/Services/Database/UnitOfWork.cs index 032c0bb7..02e78a97 100644 --- a/src/NadekoBot/Services/Database/UnitOfWork.cs +++ b/src/NadekoBot/Services/Database/UnitOfWork.cs @@ -54,6 +54,9 @@ namespace NadekoBot.Services.Database private IDiscordUserRepository _discordUsers; public IDiscordUserRepository DiscordUsers => _discordUsers ?? (_discordUsers = new DiscordUserRepository(_context)); + private IWarningsRepository _warnings; + public IWarningsRepository Warnings => _warnings ?? (_warnings = new WarningsRepository(_context)); + public UnitOfWork(NadekoContext context) { _context = context;