diff --git a/src/NadekoBot/Common/TypeReaders/AddRemove.cs b/src/NadekoBot/Common/TypeReaders/AddRemove.cs new file mode 100644 index 00000000..6bd3ea7c --- /dev/null +++ b/src/NadekoBot/Common/TypeReaders/AddRemove.cs @@ -0,0 +1,9 @@ +namespace NadekoBot.Common.TypeReaders +{ + public enum AddRemove + { + Add = 0, + Rem = 1, + Rm = 1, + } +} diff --git a/src/NadekoBot/Migrations/20170719023924_streamrole-kw-bl-wl.Designer.cs b/src/NadekoBot/Migrations/20170719023924_streamrole-kw-bl-wl.Designer.cs new file mode 100644 index 00000000..222865ec --- /dev/null +++ b/src/NadekoBot/Migrations/20170719023924_streamrole-kw-bl-wl.Designer.cs @@ -0,0 +1,1655 @@ +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; + +namespace NadekoBot.Migrations +{ + [DbContext(typeof(NadekoContext))] + [Migration("20170719023924_streamrole-kw-bl-wl")] + partial class streamrolekwblwl + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("ProductVersion", "1.1.1"); + + 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.BlockedCmdOrMdl", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("BotConfigId1"); + + b.Property("DateAdded"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.HasIndex("BotConfigId1"); + + b.ToTable("BlockedCmdOrMdl"); + }); + + 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("CurrencyDropAmountMax"); + + b.Property("CurrencyGenerationChance"); + + b.Property("CurrencyGenerationCooldown"); + + b.Property("CurrencyName"); + + b.Property("CurrencyPluralName"); + + b.Property("CurrencySign"); + + b.Property("CustomReactionsStartWith"); + + b.Property("DMHelpString"); + + b.Property("DateAdded"); + + b.Property("DefaultPrefix"); + + 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("PermissionVersion"); + + 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("GameVoiceChannel"); + + b.Property("GreetMessageChannelId"); + + b.Property("GuildId"); + + b.Property("Locale"); + + b.Property("LogSettingId"); + + b.Property("MuteRoleName"); + + b.Property("PermissionRole"); + + b.Property("Prefix"); + + b.Property("RootPermissionId"); + + b.Property("SendChannelByeMessage"); + + b.Property("SendChannelGreetMessage"); + + b.Property("SendDmGreetMessage"); + + b.Property("TimeZoneId"); + + b.Property("VerboseErrors"); + + 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.Property("StartTimeOfDay"); + + 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.RewardedUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AmountRewardedThisMonth"); + + b.Property("DateAdded"); + + b.Property("LastReward"); + + b.Property("PatreonUserId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("RewardedUsers"); + }); + + 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.ShopEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuthorId"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Index"); + + b.Property("Name"); + + b.Property("Price"); + + b.Property("RoleId"); + + b.Property("RoleName"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("ShopEntry"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("ShopEntryId"); + + b.Property("Text"); + + b.HasKey("Id"); + + b.HasIndex("ShopEntryId"); + + b.ToTable("ShopEntryItem"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredRole"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredUser"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.StartupCommand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("ChannelId"); + + b.Property("ChannelName"); + + b.Property("CommandText"); + + b.Property("DateAdded"); + + b.Property("GuildId"); + + b.Property("GuildName"); + + b.Property("Index"); + + b.Property("VoiceChannelId"); + + b.Property("VoiceChannelName"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("StartupCommand"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("StreamRoleSettingsId"); + + b.Property("UserId"); + + b.Property("Username"); + + b.HasKey("Id"); + + b.HasIndex("StreamRoleSettingsId"); + + b.ToTable("StreamRoleBlacklistedUser"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddRoleId"); + + b.Property("DateAdded"); + + b.Property("Enabled"); + + b.Property("FromRoleId"); + + b.Property("GuildConfigId"); + + b.Property("Keyword"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId") + .IsUnique(); + + b.ToTable("StreamRoleSettings"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("StreamRoleSettingsId"); + + b.Property("UserId"); + + b.Property("Username"); + + b.HasKey("Id"); + + b.HasIndex("StreamRoleSettingsId"); + + b.ToTable("StreamRoleWhitelistedUser"); + }); + + 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.BlockedCmdOrMdl", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("BlockedCommands") + .HasForeignKey("BotConfigId"); + + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("BlockedModules") + .HasForeignKey("BotConfigId1"); + }); + + 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.ShopEntry", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("ShopEntries") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ShopEntry") + .WithMany("Items") + .HasForeignKey("ShopEntryId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredRoles") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredUsers") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.StartupCommand", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("StartupCommands") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.StreamRoleSettings") + .WithMany("Blacklist") + .HasForeignKey("StreamRoleSettingsId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig") + .WithOne("StreamRole") + .HasForeignKey("NadekoBot.Services.Database.Models.StreamRoleSettings", "GuildConfigId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.StreamRoleSettings") + .WithMany("Whitelist") + .HasForeignKey("StreamRoleSettingsId"); + }); + + 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/20170719023924_streamrole-kw-bl-wl.cs b/src/NadekoBot/Migrations/20170719023924_streamrole-kw-bl-wl.cs new file mode 100644 index 00000000..d2ed14f1 --- /dev/null +++ b/src/NadekoBot/Migrations/20170719023924_streamrole-kw-bl-wl.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class streamrolekwblwl : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Enabled", + table: "StreamRoleSettings", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Keyword", + table: "StreamRoleSettings", + nullable: true); + + migrationBuilder.CreateTable( + name: "StreamRoleBlacklistedUser", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + DateAdded = table.Column(nullable: true), + StreamRoleSettingsId = table.Column(nullable: true), + UserId = table.Column(nullable: false), + Username = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_StreamRoleBlacklistedUser", x => x.Id); + table.ForeignKey( + name: "FK_StreamRoleBlacklistedUser_StreamRoleSettings_StreamRoleSettingsId", + column: x => x.StreamRoleSettingsId, + principalTable: "StreamRoleSettings", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "StreamRoleWhitelistedUser", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + DateAdded = table.Column(nullable: true), + StreamRoleSettingsId = table.Column(nullable: true), + UserId = table.Column(nullable: false), + Username = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_StreamRoleWhitelistedUser", x => x.Id); + table.ForeignKey( + name: "FK_StreamRoleWhitelistedUser_StreamRoleSettings_StreamRoleSettingsId", + column: x => x.StreamRoleSettingsId, + principalTable: "StreamRoleSettings", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_StreamRoleBlacklistedUser_StreamRoleSettingsId", + table: "StreamRoleBlacklistedUser", + column: "StreamRoleSettingsId"); + + migrationBuilder.CreateIndex( + name: "IX_StreamRoleWhitelistedUser_StreamRoleSettingsId", + table: "StreamRoleWhitelistedUser", + column: "StreamRoleSettingsId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "StreamRoleBlacklistedUser"); + + migrationBuilder.DropTable( + name: "StreamRoleWhitelistedUser"); + + migrationBuilder.DropColumn( + name: "Enabled", + table: "StreamRoleSettings"); + + migrationBuilder.DropColumn( + name: "Keyword", + table: "StreamRoleSettings"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index 42fa008a..6b57437a 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -1126,6 +1126,26 @@ namespace NadekoBot.Migrations b.ToTable("StartupCommand"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("StreamRoleSettingsId"); + + b.Property("UserId"); + + b.Property("Username"); + + b.HasKey("Id"); + + b.HasIndex("StreamRoleSettingsId"); + + b.ToTable("StreamRoleBlacklistedUser"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b => { b.Property("Id") @@ -1135,10 +1155,14 @@ namespace NadekoBot.Migrations b.Property("DateAdded"); + b.Property("Enabled"); + b.Property("FromRoleId"); b.Property("GuildConfigId"); + b.Property("Keyword"); + b.HasKey("Id"); b.HasIndex("GuildConfigId") @@ -1147,6 +1171,26 @@ namespace NadekoBot.Migrations b.ToTable("StreamRoleSettings"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("StreamRoleSettingsId"); + + b.Property("UserId"); + + b.Property("Username"); + + b.HasKey("Id"); + + b.HasIndex("StreamRoleSettingsId"); + + b.ToTable("StreamRoleWhitelistedUser"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => { b.Property("Id") @@ -1531,6 +1575,13 @@ namespace NadekoBot.Migrations .HasForeignKey("BotConfigId"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.StreamRoleSettings") + .WithMany("Blacklist") + .HasForeignKey("StreamRoleSettingsId"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b => { b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig") @@ -1539,6 +1590,13 @@ namespace NadekoBot.Migrations .OnDelete(DeleteBehavior.Cascade); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.StreamRoleSettings") + .WithMany("Whitelist") + .HasForeignKey("StreamRoleSettingsId"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => { b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") diff --git a/src/NadekoBot/Modules/Permissions/BlacklistCommands.cs b/src/NadekoBot/Modules/Permissions/BlacklistCommands.cs index 655209af..377631e0 100644 --- a/src/NadekoBot/Modules/Permissions/BlacklistCommands.cs +++ b/src/NadekoBot/Modules/Permissions/BlacklistCommands.cs @@ -2,24 +2,18 @@ using Discord.Commands; using NadekoBot.Services; using NadekoBot.Services.Database.Models; -using System.Collections.Concurrent; using System.Linq; using System.Threading.Tasks; using NadekoBot.Common.Attributes; using NadekoBot.Common.Collections; using NadekoBot.Modules.Games.Common.Trivia; using NadekoBot.Modules.Permissions.Services; +using NadekoBot.Common.TypeReaders; namespace NadekoBot.Modules.Permissions { public partial class Permissions { - public enum AddRemove - { - Add, - Rem - } - [Group] public class BlacklistCommands : NadekoSubmodule { diff --git a/src/NadekoBot/Modules/Utility/Common/Exceptions/StreamRoleNotFoundException.cs b/src/NadekoBot/Modules/Utility/Common/Exceptions/StreamRoleNotFoundException.cs new file mode 100644 index 00000000..ca73e920 --- /dev/null +++ b/src/NadekoBot/Modules/Utility/Common/Exceptions/StreamRoleNotFoundException.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Utility.Common.Exceptions +{ + public class StreamRoleNotFoundException : Exception + { + public StreamRoleNotFoundException() : base("Stream role wasn't found.") + { + } + } +} diff --git a/src/NadekoBot/Modules/Utility/Common/Exceptions/StreamRolePermissionException.cs b/src/NadekoBot/Modules/Utility/Common/Exceptions/StreamRolePermissionException.cs new file mode 100644 index 00000000..a921f3ce --- /dev/null +++ b/src/NadekoBot/Modules/Utility/Common/Exceptions/StreamRolePermissionException.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Utility.Common.Exceptions +{ + public class StreamRolePermissionException : Exception + { + public StreamRolePermissionException() : base("Stream role was unable to be applied.") + { + } + } +} diff --git a/src/NadekoBot/Modules/Utility/Common/StreamRoleListType.cs b/src/NadekoBot/Modules/Utility/Common/StreamRoleListType.cs new file mode 100644 index 00000000..4281744b --- /dev/null +++ b/src/NadekoBot/Modules/Utility/Common/StreamRoleListType.cs @@ -0,0 +1,8 @@ +namespace NadekoBot.Modules.Utility.Common +{ + public enum StreamRoleListType + { + Whitelist, + Blacklist, + } +} diff --git a/src/NadekoBot/Modules/Utility/Extensions/StreamRoleExtensions.cs b/src/NadekoBot/Modules/Utility/Extensions/StreamRoleExtensions.cs new file mode 100644 index 00000000..eaf16e84 --- /dev/null +++ b/src/NadekoBot/Modules/Utility/Extensions/StreamRoleExtensions.cs @@ -0,0 +1,27 @@ +using Microsoft.EntityFrameworkCore; +using NadekoBot.Services.Database.Models; +using NadekoBot.Services.Database.Repositories; + +namespace NadekoBot.Modules.Utility.Extensions +{ + public static class StreamRoleExtensions + { + /// + /// Gets full stream role settings for the guild with the specified id. + /// + /// + /// Id of the guild to get stream role settings for. + /// + public static StreamRoleSettings GetStreamRoleSettings(this IGuildConfigRepository gc, ulong guildId) + { + var conf = gc.For(guildId, x => x.Include(y => y.StreamRole) + .Include(y => y.StreamRole.Whitelist) + .Include(y => y.StreamRole.Blacklist)); + + if (conf.StreamRole == null) + conf.StreamRole = new StreamRoleSettings(); + + return conf.StreamRole; + } + } +} diff --git a/src/NadekoBot/Modules/Utility/Services/StreamRoleService.cs b/src/NadekoBot/Modules/Utility/Services/StreamRoleService.cs index 6e759d93..48fc53f0 100644 --- a/src/NadekoBot/Modules/Utility/Services/StreamRoleService.cs +++ b/src/NadekoBot/Modules/Utility/Services/StreamRoleService.cs @@ -5,11 +5,15 @@ using System.Linq; using System.Threading.Tasks; using Discord; using Discord.WebSocket; -using Microsoft.EntityFrameworkCore; using NadekoBot.Extensions; using NadekoBot.Services; using NadekoBot.Services.Database.Models; using NLog; +using NadekoBot.Modules.Utility.Extensions; +using NadekoBot.Common.TypeReaders; +using NadekoBot.Modules.Utility.Common; +using NadekoBot.Modules.Utility.Common.Exceptions; +using Discord.Net; namespace NadekoBot.Modules.Utility.Services { @@ -27,8 +31,8 @@ namespace NadekoBot.Modules.Utility.Services this._log = LogManager.GetCurrentClassLogger(); guildSettings = gcs.ToDictionary(x => x.GuildId, x => x.StreamRole) - .Where(x => x.Value.FromRoleId != 0 && x.Value.AddRoleId != 0) - .ToConcurrent(); + .Where(x => x.Value != null && x.Value.Enabled) + .ToConcurrent(); client.GuildMemberUpdated += Client_GuildMemberUpdated; } @@ -38,53 +42,12 @@ namespace NadekoBot.Modules.Utility.Services var _ = Task.Run(async () => { //if user wasn't streaming or didn't have a game status at all - // and has a game status now - // and that status is a streaming status - // and we are supposed to give him a role - if ((!before.Game.HasValue || before.Game.Value.StreamType == StreamType.NotStreaming) && - after.Game.HasValue && - after.Game.Value.StreamType != StreamType.NotStreaming + if ((!before.Game.HasValue || before.Game.Value.StreamType == StreamType.NotStreaming) && guildSettings.TryGetValue(after.Guild.Id, out var setting)) { - IRole fromRole; - IRole addRole; - try - { - //get needed roles - fromRole = after.Guild.GetRole(setting.FromRoleId); - if (fromRole == null) - throw new InvalidOperationException(); - addRole = after.Guild.GetRole(setting.AddRoleId); - if (addRole == null) - throw new InvalidOperationException(); - } - catch (Exception ex) - { - StopStreamRole(before.Guild.Id); - _log.Warn("Error getting Stream Role(s). Disabling stream role feature."); - _log.Error(ex); - return; - } - - try - { - //check if user is in the fromrole - if (after.Roles.Contains(fromRole)) - { - //check if he doesn't have addrole already, to avoid errors - if(!after.Roles.Contains(addRole)) - await after.AddRoleAsync(addRole).ConfigureAwait(false); - //schedule him for the role removal when he stops streaming - toRemove.TryAdd((addRole.Guild.Id, after.Id), addRole.Id); - } - } - catch (Exception ex) - { - _log.Warn("Failed adding stream role."); - _log.Error(ex); - } + await TryApplyRole(after, setting).ConfigureAwait(false); } - + // try removing a role that was given to the user // if user had a game status // and he was streaming @@ -110,47 +73,210 @@ namespace NadekoBot.Modules.Utility.Services _log.Warn("Failed removing the stream role from the user who stopped streaming."); _log.Error(ex); } - } + } }); return Task.CompletedTask; } - public void SetStreamRole(IRole fromRole, IRole addRole) + private async Task TryApplyRole(IGuildUser user, StreamRoleSettings setting) { + // if the user has a game status now + // and that status is a streaming status + // and the feature is enabled + // and he's not blacklisted + // and keyword is either not set, or the game contains the keyword required, or he's whitelisted + if (user.Game.HasValue && + user.Game.Value.StreamType != StreamType.NotStreaming + && setting.Enabled + && !setting.Blacklist.Any(x => x.UserId == user.Id) + && (string.IsNullOrWhiteSpace(setting.Keyword) + || user.Game.Value.Name.Contains(setting.Keyword) + || setting.Whitelist.Any(x => x.UserId == user.Id))) + { + IRole fromRole; + IRole addRole; + + //get needed roles + fromRole = user.Guild.GetRole(setting.FromRoleId); + if (fromRole == null) + throw new StreamRoleNotFoundException(); + addRole = user.Guild.GetRole(setting.AddRoleId); + if (addRole == null) + throw new StreamRoleNotFoundException(); + + try + { + //check if user is in the fromrole + if (user.RoleIds.Contains(setting.FromRoleId)) + { + //check if he doesn't have addrole already, to avoid errors + if (!user.RoleIds.Contains(setting.AddRoleId)) + await user.AddRoleAsync(addRole).ConfigureAwait(false); + //schedule him for the role removal when he stops streaming + toRemove.TryAdd((addRole.Guild.Id, user.Id), addRole.Id); + } + } + catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.Forbidden) + { + StopStreamRole(user.Guild.Id); + _log.Warn("Error adding stream role(s). Disabling stream role feature."); + _log.Error(ex); + throw new StreamRolePermissionException(); + } + catch (Exception ex) + { + _log.Warn("Failed adding stream role."); + _log.Error(ex); + } + } + } + + /// + /// Adds or removes a user from a blacklist or a whitelist in the specified guild. + /// + /// Id of the guild + /// Add or rem action + /// User's Id + /// User's name#discrim + /// Whether the operation was successful + public async Task ApplyListAction(StreamRoleListType listType, ulong guildId, AddRemove action, ulong userId, string userName) + { + userName.ThrowIfNull(nameof(userName)); + + bool success; + using (var uow = _db.UnitOfWork) + { + var streamRoleSettings = uow.GuildConfigs.GetStreamRoleSettings(guildId); + + if (listType == StreamRoleListType.Whitelist) + { + var userObj = new StreamRoleWhitelistedUser() + { + UserId = userId, + Username = userName, + }; + + if (action == AddRemove.Rem) + success = streamRoleSettings.Whitelist.Remove(userObj); + else + success = streamRoleSettings.Whitelist.Add(userObj); + } + else + { + var userObj = new StreamRoleBlacklistedUser() + { + UserId = userId, + Username = userName, + }; + + if (action == AddRemove.Rem) + success = streamRoleSettings.Blacklist.Remove(userObj); + else + success = streamRoleSettings.Blacklist.Add(userObj); + } + + await uow.CompleteAsync().ConfigureAwait(false); + } + return success; + } + + /// + /// Sets keyword on a guild and updates the cache. + /// + /// Guild Id + /// Keyword to set + /// The keyword set + public string SetKeyword(ulong guildId, string keyword) + { + keyword = keyword?.Trim()?.ToLowerInvariant(); + + using (var uow = _db.UnitOfWork) + { + var streamRoleSettings = uow.GuildConfigs.GetStreamRoleSettings(guildId); + + streamRoleSettings.Keyword = keyword; + UpdateCache(guildId, streamRoleSettings); + uow.Complete(); + + return streamRoleSettings.Keyword; + } + + } + + /// + /// Gets the currently set keyword on a guild. + /// + /// Guild Id + /// The keyword set + public string GetKeyword(ulong guildId) + { + if (guildSettings.TryGetValue(guildId, out var outSetting)) + return outSetting.Keyword; + StreamRoleSettings setting; using (var uow = _db.UnitOfWork) { - var gc = uow.GuildConfigs.For(fromRole.Guild.Id, x => x.Include(y => y.StreamRole)); - - if (gc.StreamRole == null) - gc.StreamRole = new StreamRoleSettings() - { - AddRoleId = addRole.Id, - FromRoleId = fromRole.Id - }; - else - { - gc.StreamRole.AddRoleId = addRole.Id; - gc.StreamRole.FromRoleId = fromRole.Id; - } - setting = gc.StreamRole; - uow.Complete(); + setting = uow.GuildConfigs.GetStreamRoleSettings(guildId); } - guildSettings.AddOrUpdate(fromRole.Guild.Id, (key) => setting, (key, old) => setting); + UpdateCache(guildId, setting); + + return setting.Keyword; } + /// + /// Sets the role to monitor, and a role to which to add to + /// the user who starts streaming in the monitored role. + /// + /// Role to monitor + /// Role to add to the user + public async Task SetStreamRole(IRole fromRole, IRole addRole) + { + fromRole.ThrowIfNull(nameof(fromRole)); + addRole.ThrowIfNull(nameof(addRole)); + + StreamRoleSettings setting; + using (var uow = _db.UnitOfWork) + { + var streamRoleSettings = uow.GuildConfigs.GetStreamRoleSettings(fromRole.Guild.Id); + + streamRoleSettings.Enabled = true; + streamRoleSettings.AddRoleId = addRole.Id; + streamRoleSettings.FromRoleId = fromRole.Id; + + setting = streamRoleSettings; + await uow.CompleteAsync().ConfigureAwait(false); + } + + UpdateCache(fromRole.Guild.Id, setting); + + foreach (var usr in await fromRole.Guild.GetUsersAsync(CacheMode.CacheOnly).ConfigureAwait(false)) + { + await TryApplyRole(usr, setting).ConfigureAwait(false); + await Task.Delay(500).ConfigureAwait(false); + } + } + + /// + /// Stops the stream role feature on the specified guild. + /// + /// Guild's Id public void StopStreamRole(ulong guildId) { using (var uow = _db.UnitOfWork) { - var gc = uow.GuildConfigs.For(guildId, x => x.Include(y => y.StreamRole)); - gc.StreamRole = null; + var streamRoleSettings = uow.GuildConfigs.GetStreamRoleSettings(guildId); + streamRoleSettings.Enabled = false; uow.Complete(); } guildSettings.TryRemove(guildId, out _); } + + private void UpdateCache(ulong guildId, StreamRoleSettings setting) + { + guildSettings.AddOrUpdate(guildId, (key) => setting, (key, old) => setting); + } } } diff --git a/src/NadekoBot/Modules/Utility/StreamRoleCommands.cs b/src/NadekoBot/Modules/Utility/StreamRoleCommands.cs index 7f2c7872..8237dce0 100644 --- a/src/NadekoBot/Modules/Utility/StreamRoleCommands.cs +++ b/src/NadekoBot/Modules/Utility/StreamRoleCommands.cs @@ -3,6 +3,8 @@ using Discord.Commands; using System.Threading.Tasks; using NadekoBot.Common.Attributes; using NadekoBot.Modules.Utility.Services; +using NadekoBot.Common.TypeReaders; +using NadekoBot.Modules.Utility.Common; namespace NadekoBot.Modules.Utility { @@ -16,7 +18,7 @@ namespace NadekoBot.Modules.Utility [RequireContext(ContextType.Guild)] public async Task StreamRole(IRole fromRole, IRole addRole) { - this._service.SetStreamRole(fromRole, addRole); + await this._service.SetStreamRole(fromRole, addRole).ConfigureAwait(false); await ReplyConfirmLocalized("stream_role_enabled", Format.Bold(fromRole.ToString()), Format.Bold(addRole.ToString())).ConfigureAwait(false); } @@ -30,6 +32,62 @@ namespace NadekoBot.Modules.Utility this._service.StopStreamRole(Context.Guild.Id); await ReplyConfirmLocalized("stream_role_disabled").ConfigureAwait(false); } + + [NadekoCommand, Usage, Description, Aliases] + [RequireBotPermission(GuildPermission.ManageRoles)] + [RequireUserPermission(GuildPermission.ManageRoles)] + [RequireContext(ContextType.Guild)] + public async Task StreamRoleKeyword([Remainder]string keyword = null) + { + string kw = this._service.SetKeyword(Context.Guild.Id, keyword); + + if(string.IsNullOrWhiteSpace(keyword)) + await ReplyConfirmLocalized("stream_role_kw_reset").ConfigureAwait(false); + else + await ReplyConfirmLocalized("stream_role_kw_set", Format.Bold(kw)).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireBotPermission(GuildPermission.ManageRoles)] + [RequireUserPermission(GuildPermission.ManageRoles)] + [RequireContext(ContextType.Guild)] + public async Task StreamRoleBlacklist(AddRemove action, [Remainder] IGuildUser user) + { + var success = await this._service.ApplyListAction(StreamRoleListType.Blacklist, Context.Guild.Id, action, user.Id, user.ToString()) + .ConfigureAwait(false); + + if(action == AddRemove.Add) + if(success) + await ReplyConfirmLocalized("stream_role_bl_add", Format.Bold(user.ToString())).ConfigureAwait(false); + else + await ReplyConfirmLocalized("stream_role_bl_add_fail", Format.Bold(user.ToString())).ConfigureAwait(false); + else + if (success) + await ReplyConfirmLocalized("stream_role_bl_rem", Format.Bold(user.ToString())).ConfigureAwait(false); + else + await ReplyErrorLocalized("stream_role_bl_rem_fail", Format.Bold(user.ToString())).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireBotPermission(GuildPermission.ManageRoles)] + [RequireUserPermission(GuildPermission.ManageRoles)] + [RequireContext(ContextType.Guild)] + public async Task StreamRoleWhitelist(AddRemove action, [Remainder] IGuildUser user) + { + var success = await this._service.ApplyListAction(StreamRoleListType.Whitelist, Context.Guild.Id, action, user.Id, user.ToString()) + .ConfigureAwait(false); + + if (action == AddRemove.Add) + if(success) + await ReplyConfirmLocalized("stream_role_wl_add", Format.Bold(user.ToString())).ConfigureAwait(false); + else + await ReplyConfirmLocalized("stream_role_wl_add_fail", Format.Bold(user.ToString())).ConfigureAwait(false); + else + if (success) + await ReplyConfirmLocalized("stream_role_wl_rem", Format.Bold(user.ToString())).ConfigureAwait(false); + else + await ReplyErrorLocalized("stream_role_wl_rem_fail", Format.Bold(user.ToString())).ConfigureAwait(false); + } } } } \ No newline at end of file diff --git a/src/NadekoBot/NadekoBot.csproj b/src/NadekoBot/NadekoBot.csproj index 810fa907..6d719b32 100644 --- a/src/NadekoBot/NadekoBot.csproj +++ b/src/NadekoBot/NadekoBot.csproj @@ -91,4 +91,8 @@ + + + + diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 53e5b1a9..e1635531 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3546,4 +3546,31 @@ Toggles whether the bot should print command errors when a command is incorrectly used. + + streamrolekw srkw + + + `{0}srkw` or `{0}srkw PUBG` + + + Sets keyword which is required in the stream's title in order for the streamrole to apply. Provide no keyword in order to reset. + + + streamrolebl srbl + + + `{0}srbl add @b1nzy#1234` or `{0}srbl rem @b1nzy#1234` + + + Adds or removes a blacklisted user. Blacklisted users will never receive the stream role. + + + streamrolewl srwl + + + `{0}srwl add @b1nzy#1234` or `{0}srwl rem @b1nzy#1234` + + + Adds or removes a whitelisted user. Whitelisted users will receive the stream role even if they don't have the specified keyword in their stream title. + diff --git a/src/NadekoBot/Services/Database/Models/GuildConfig.cs b/src/NadekoBot/Services/Database/Models/GuildConfig.cs index 6222712b..83498097 100644 --- a/src/NadekoBot/Services/Database/Models/GuildConfig.cs +++ b/src/NadekoBot/Services/Database/Models/GuildConfig.cs @@ -83,7 +83,7 @@ namespace NadekoBot.Services.Database.Models public ulong? GameVoiceChannel { get; set; } = null; public bool VerboseErrors { get; set; } = false; - public StreamRoleSettings StreamRole { get; set; } = new StreamRoleSettings(); + public StreamRoleSettings StreamRole { get; set; } //public List ProtectionIgnoredChannels { get; set; } = new List(); } diff --git a/src/NadekoBot/Services/Database/Models/StreamRoleSettings.cs b/src/NadekoBot/Services/Database/Models/StreamRoleSettings.cs index f73abeac..05449039 100644 --- a/src/NadekoBot/Services/Database/Models/StreamRoleSettings.cs +++ b/src/NadekoBot/Services/Database/Models/StreamRoleSettings.cs @@ -11,13 +11,77 @@ namespace NadekoBot.Services.Database.Models public int GuildConfigId { get; set; } public GuildConfig GuildConfig { get; set; } + /// + /// Whether the feature is enabled in the guild. + /// + public bool Enabled { get; set; } + /// /// Id of the role to give to the users in the role 'FromRole' when they start streaming /// public ulong AddRoleId { get; set; } + /// /// Id of the role whose users are eligible to get the 'AddRole' /// public ulong FromRoleId { get; set; } + + /// + /// If set, feature will only apply to users who have this keyword in their streaming status. + /// + public string Keyword { get; set; } + + /// + /// A collection of whitelisted users' IDs. Whitelisted users don't require 'keyword' in + /// order to get the stream role. + /// + public HashSet Whitelist { get; set; } = new HashSet(); + + /// + /// A collection of blacklisted users' IDs. Blacklisted useres will never get the stream role. + /// + public HashSet Blacklist { get; set; } = new HashSet(); + } + + public class StreamRoleBlacklistedUser : DbEntity + { + public ulong UserId { get; set; } + public string Username { get; set; } + + public override bool Equals(object obj) + { + var x = obj as StreamRoleBlacklistedUser; + + if (x == null) + return false; + + return x.UserId == UserId; + } + + public override int GetHashCode() + { + return UserId.GetHashCode(); + } + } + + public class StreamRoleWhitelistedUser : DbEntity + { + public ulong UserId { get; set; } + public string Username { get; set; } + + public override bool Equals(object obj) + { + var x = obj as StreamRoleWhitelistedUser; + + if (x == null) + return false; + + return x.UserId == UserId; + } + + public override int GetHashCode() + { + return UserId.GetHashCode(); + } } } diff --git a/src/NadekoBot/_strings/ResponseStrings.en-US.json b/src/NadekoBot/_strings/ResponseStrings.en-US.json index bfaa9248..3ca43151 100644 --- a/src/NadekoBot/_strings/ResponseStrings.en-US.json +++ b/src/NadekoBot/_strings/ResponseStrings.en-US.json @@ -610,6 +610,16 @@ "searches_yodify_error": "Failed to yodify your sentence.", "utility_stream_role_enabled": "When a user from {0} role starts streaming, I will give them {1} role.", "utility_stream_role_disabled": "Stream role feature has been disabled.", + "utility_stream_role_kw_set": "Streamers now require {0} keyword in order to receive the role.", + "utility_stream_role_kw_reset": "Stream role keyword reset.", + "utility_stream_role_bl_add": "User {0} will never receive the stream role.", + "utility_stream_role_bl_add_fail": "User {0} is already blacklisted.", + "utility_stream_role_bl_rem": "User {0} is no longer blacklisted.", + "utility_stream_role_bl_rem_fail": "User {0} is not blacklisted.", + "utility_stream_role_wl_add": "User {0} will receive the stream role even if they don't have the keyword in the stream title.", + "utility_stream_role_wl_add_fail": "User {0} is already whitelisted.", + "utility_stream_role_wl_rem": "User {0} is no longer whitelisted.", + "utility_stream_role_wl_rem_fail": "User {0} is not whitelisted.", "utiliity_joined": "Joined", "utility_activity_line": "`{0}.` {1} [{2:F2}/s] - {3} total", "utility_activity_page": "Activity page #{0}",