diff --git a/src/NadekoBot/Migrations/20170915034808_club-admins.Designer.cs b/src/NadekoBot/Migrations/20170915034808_club-admins.Designer.cs new file mode 100644 index 00000000..d7b4c4d9 --- /dev/null +++ b/src/NadekoBot/Migrations/20170915034808_club-admins.Designer.cs @@ -0,0 +1,1951 @@ +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("20170915034808_club-admins")] + partial class clubadmins + { + 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.Property("MuteTime"); + + 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.Property("XpMinutesTimeout") + .ValueGeneratedOnAdd() + .HasDefaultValue(5); + + b.Property("XpPerMessage") + .ValueGeneratedOnAdd() + .HasDefaultValue(3); + + 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.ClubApplicants", b => + { + b.Property("ClubId"); + + b.Property("UserId"); + + b.HasKey("ClubId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("ClubApplicants"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClubBans", b => + { + b.Property("ClubId"); + + b.Property("UserId"); + + b.HasKey("ClubId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("ClubBans"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClubInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("Discrim"); + + b.Property("ImageUrl"); + + b.Property("MinimumLevelReq"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(20); + + b.Property("OwnerId"); + + b.Property("Xp"); + + b.HasKey("Id"); + + b.HasAlternateKey("Name", "Discrim"); + + b.HasIndex("OwnerId") + .IsUnique(); + + b.ToTable("Clubs"); + }); + + 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("ContainsAnywhere"); + + 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("ClubId"); + + b.Property("DateAdded"); + + b.Property("Discriminator"); + + b.Property("IsClubAdmin"); + + b.Property("LastLevelUp") + .ValueGeneratedOnAdd() + .HasDefaultValue(new DateTime(2017, 9, 15, 5, 48, 8, 660, DateTimeKind.Local)); + + b.Property("LastXpGain"); + + b.Property("NotifyOnLevelUp"); + + b.Property("TotalXp"); + + b.Property("UserId"); + + b.Property("Username"); + + b.HasKey("Id"); + + b.HasAlternateKey("UserId"); + + b.HasIndex("ClubId"); + + 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.ExcludedItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("ItemId"); + + b.Property("ItemType"); + + b.Property("XpSettingsId"); + + b.HasKey("Id"); + + b.HasIndex("XpSettingsId"); + + b.ToTable("ExcludedItem"); + }); + + 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.NsfwBlacklitedTag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Tag"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("NsfwBlacklitedTag"); + }); + + 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.UserXpStats", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AwardedXp"); + + b.Property("DateAdded"); + + b.Property("GuildId"); + + b.Property("LastLevelUp") + .ValueGeneratedOnAdd() + .HasDefaultValue(new DateTime(2017, 9, 15, 5, 48, 8, 665, DateTimeKind.Local)); + + b.Property("NotifyOnLevelUp"); + + b.Property("UserId"); + + b.Property("Xp"); + + b.HasKey("Id"); + + b.HasIndex("UserId", "GuildId") + .IsUnique(); + + b.ToTable("UserXpStats"); + }); + + 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.WaifuItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("Item"); + + b.Property("ItemEmoji"); + + b.Property("Price"); + + b.Property("WaifuInfoId"); + + b.HasKey("Id"); + + b.HasIndex("WaifuInfoId"); + + b.ToTable("WaifuItem"); + }); + + 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.XpRoleReward", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("Level"); + + b.Property("RoleId"); + + b.Property("XpSettingsId"); + + b.HasKey("Id"); + + b.HasAlternateKey("Level"); + + b.HasIndex("XpSettingsId"); + + b.ToTable("XpRoleReward"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.XpSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("NotifyMessage"); + + b.Property("ServerExcluded"); + + b.Property("XpRoleRewardExclusive"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId") + .IsUnique(); + + b.ToTable("XpSettings"); + }); + + 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.ClubApplicants", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ClubInfo", "Club") + .WithMany("Applicants") + .HasForeignKey("ClubId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClubBans", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ClubInfo", "Club") + .WithMany("Bans") + .HasForeignKey("ClubId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClubInfo", b => + { + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Owner") + .WithOne() + .HasForeignKey("NadekoBot.Services.Database.Models.ClubInfo", "OwnerId") + .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.DiscordUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ClubInfo", "Club") + .WithMany("Users") + .HasForeignKey("ClubId"); + }); + + 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.ExcludedItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.XpSettings") + .WithMany("ExclusionList") + .HasForeignKey("XpSettingsId"); + }); + + 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.NsfwBlacklitedTag", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("NsfwBlacklistedTags") + .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.WaifuItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.WaifuInfo") + .WithMany("Items") + .HasForeignKey("WaifuInfoId"); + }); + + 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"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.XpRoleReward", b => + { + b.HasOne("NadekoBot.Services.Database.Models.XpSettings") + .WithMany("RoleRewards") + .HasForeignKey("XpSettingsId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.XpSettings", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig") + .WithOne("XpSettings") + .HasForeignKey("NadekoBot.Services.Database.Models.XpSettings", "GuildConfigId") + .OnDelete(DeleteBehavior.Cascade); + }); + } + } +} diff --git a/src/NadekoBot/Migrations/20170915034808_club-admins.cs b/src/NadekoBot/Migrations/20170915034808_club-admins.cs new file mode 100644 index 00000000..b1c0d3e6 --- /dev/null +++ b/src/NadekoBot/Migrations/20170915034808_club-admins.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class clubadmins : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IsClubAdmin", + table: "DiscordUser", + nullable: false, + defaultValue: false); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsClubAdmin", + table: "DiscordUser"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index 5f522e7b..cb6b041e 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -462,9 +462,11 @@ namespace NadekoBot.Migrations b.Property("Discriminator"); + b.Property("IsClubAdmin"); + b.Property("LastLevelUp") .ValueGeneratedOnAdd() - .HasDefaultValue(new DateTime(2017, 9, 13, 4, 26, 53, 906, DateTimeKind.Local)); + .HasDefaultValue(new DateTime(2017, 9, 15, 5, 48, 8, 660, DateTimeKind.Local)); b.Property("LastXpGain"); @@ -1364,7 +1366,7 @@ namespace NadekoBot.Migrations b.Property("LastLevelUp") .ValueGeneratedOnAdd() - .HasDefaultValue(new DateTime(2017, 9, 13, 4, 26, 53, 910, DateTimeKind.Local)); + .HasDefaultValue(new DateTime(2017, 9, 15, 5, 48, 8, 665, DateTimeKind.Local)); b.Property("NotifyOnLevelUp"); diff --git a/src/NadekoBot/Modules/Music/Common/SongBuffer.cs b/src/NadekoBot/Modules/Music/Common/SongBuffer.cs index 8f76be79..2193877f 100644 --- a/src/NadekoBot/Modules/Music/Common/SongBuffer.cs +++ b/src/NadekoBot/Modules/Music/Common/SongBuffer.cs @@ -3,7 +3,6 @@ using System; using System.Diagnostics; using System.IO; using System.Threading; -using System.Threading.Tasks; namespace NadekoBot.Modules.Music.Common { @@ -18,27 +17,16 @@ namespace NadekoBot.Modules.Music.Common public string SongUri { get; private set; } - //private volatile bool restart = false; - public SongBuffer(string songUri, string skipTo, bool isLocal) { _log = LogManager.GetCurrentClassLogger(); - //_log.Warn(songUri); this.SongUri = songUri; this._isLocal = isLocal; try { this.p = StartFFmpegProcess(SongUri, 0); - var t = Task.Run(() => - { - this.p.BeginErrorReadLine(); - this.p.ErrorDataReceived += P_ErrorDataReceived; - this.p.WaitForExit(); - }); - this._outStream = this.p.StandardOutput.BaseStream; - } catch (System.ComponentModel.Win32Exception) { @@ -68,113 +56,14 @@ Check the guides for your platform on how to setup ffmpeg correctly: Arguments = args, UseShellExecute = false, RedirectStandardOutput = true, - RedirectStandardError = true, + RedirectStandardError = false, CreateNoWindow = true, }); } - private void P_ErrorDataReceived(object sender, DataReceivedEventArgs e) - { - if (string.IsNullOrWhiteSpace(e.Data)) - return; - _log.Error(">>> " + e.Data); - if (e.Data?.Contains("Error in the pull function") == true) - { - _log.Error("Ignore this."); - //restart = true; - } - } - private readonly object locker = new object(); private readonly bool _isLocal; - public Task StartBuffering(CancellationToken cancelToken) - { - var toReturn = new TaskCompletionSource(); - var _ = Task.Run(() => - { - try - { - - ////int maxLoopsPerSec = 25; - //var sw = Stopwatch.StartNew(); - ////var delay = 1000 / maxLoopsPerSec; - //int currentLoops = 0; - //int _bytesSent = 0; - //try - //{ - // //do - // //{ - // // if (restart) - // // { - // // var cur = _bytesSent / 3840 / (1000 / 20.0f); - // // _log.Info("Restarting"); - // // try { this.p.StandardOutput.Dispose(); } catch { } - // // try { this.p.Dispose(); } catch { } - // // this.p = StartFFmpegProcess(SongUri, cur); - // // } - // // restart = false; - // ++currentLoops; - // byte[] buffer = new byte[readSize]; - // int bytesRead = 1; - // while (!cancelToken.IsCancellationRequested && !this.p.HasExited) - // { - // bytesRead = await p.StandardOutput.BaseStream.ReadAsync(buffer, 0, readSize, cancelToken).ConfigureAwait(false); - // _bytesSent += bytesRead; - // if (bytesRead == 0) - // break; - // bool written; - // do - // { - // lock (locker) - // written = _outStream.Write(buffer, 0, bytesRead); - // if (!written) - // await Task.Delay(2000, cancelToken); - // } - // while (!written && !cancelToken.IsCancellationRequested); - // lock (locker) - // if (_outStream.Length > 200_000 || bytesRead == 0) - // if (toReturn.TrySetResult(true)) - // _log.Info("Prebuffering finished in {0}", sw.Elapsed.TotalSeconds.ToString("F2")); - - // //_log.Info(_outStream.Length); - // await Task.Delay(10); - // } - // //if (cancelToken.IsCancellationRequested) - // // _log.Info("Song canceled"); - // //else if (p.HasExited) - // // _log.Info("Song buffered completely (FFmpeg exited)"); - // //else if (bytesRead == 0) - // // _log.Info("Nothing read"); - // //} - // //while (restart && !cancelToken.IsCancellationRequested); - //return Task.CompletedTask; - toReturn.TrySetResult(true); - } - catch (System.ComponentModel.Win32Exception) - { - _log.Error(@"You have not properly installed or configured FFMPEG. -Please install and configure FFMPEG to play music. -Check the guides for your platform on how to setup ffmpeg correctly: - Windows Guide: https://goo.gl/OjKk8F - Linux Guide: https://goo.gl/ShjCUo"); - } - catch (OperationCanceledException) { } - catch (InvalidOperationException) { } // when ffmpeg is disposed - catch (Exception ex) - { - _log.Info(ex); - } - finally - { - if (toReturn.TrySetResult(false)) - _log.Info("Prebuffering failed"); - } - }, cancelToken); - - return toReturn.Task; - } - public int Read(byte[] b, int offset, int toRead) { lock (locker) @@ -203,215 +92,4 @@ Check the guides for your platform on how to setup ffmpeg correctly: this.p.Dispose(); } } -} - -//namespace NadekoBot.Services.Music -//{ -// /// -// /// Create a buffer for a song file. It will create multiples files to ensure, that radio don't fill up disk space. -// /// It also help for large music by deleting files that are already seen. -// /// -// class SongBuffer : Stream -// { -// public SongBuffer(MusicPlayer musicPlayer, string basename, SongInfo songInfo, int skipTo, int maxFileSize) -// { -// MusicPlayer = musicPlayer; -// Basename = basename; -// SongInfo = songInfo; -// SkipTo = skipTo; -// MaxFileSize = maxFileSize; -// CurrentFileStream = new FileStream(this.GetNextFile(), FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write); -// _log = LogManager.GetCurrentClassLogger(); -// } - -// MusicPlayer MusicPlayer { get; } - -// private string Basename { get; } - -// private SongInfo SongInfo { get; } - -// private int SkipTo { get; } - -// private int MaxFileSize { get; } = 2.MiB(); - -// private long FileNumber = -1; - -// private long NextFileToRead = 0; - -// public bool BufferingCompleted { get; private set; } = false; - -// private ulong CurrentBufferSize = 0; - -// private FileStream CurrentFileStream; -// private Logger _log; - -// public Task BufferSong(CancellationToken cancelToken) => -// Task.Run(async () => -// { -// Process p = null; -// FileStream outStream = null; -// try -// { -// p = Process.Start(new ProcessStartInfo -// { -// FileName = "ffmpeg", -// Arguments = $"-ss {SkipTo} -i {SongInfo.Uri} -f s16le -ar 48000 -vn -ac 2 pipe:1 -loglevel quiet", -// UseShellExecute = false, -// RedirectStandardOutput = true, -// RedirectStandardError = false, -// CreateNoWindow = true, -// }); - -// byte[] buffer = new byte[81920]; -// int currentFileSize = 0; -// ulong prebufferSize = 100ul.MiB(); - -// outStream = new FileStream(Basename + "-" + ++FileNumber, FileMode.Append, FileAccess.Write, FileShare.Read); -// while (!p.HasExited) //Also fix low bandwidth -// { -// int bytesRead = await p.StandardOutput.BaseStream.ReadAsync(buffer, 0, buffer.Length, cancelToken).ConfigureAwait(false); -// if (currentFileSize >= MaxFileSize) -// { -// try -// { -// outStream.Dispose(); -// } -// catch { } -// outStream = new FileStream(Basename + "-" + ++FileNumber, FileMode.Append, FileAccess.Write, FileShare.Read); -// currentFileSize = bytesRead; -// } -// else -// { -// currentFileSize += bytesRead; -// } -// CurrentBufferSize += Convert.ToUInt64(bytesRead); -// await outStream.WriteAsync(buffer, 0, bytesRead, cancelToken).ConfigureAwait(false); -// while (CurrentBufferSize > prebufferSize) -// await Task.Delay(100, cancelToken); -// } -// BufferingCompleted = true; -// } -// catch (System.ComponentModel.Win32Exception) -// { -// var oldclr = Console.ForegroundColor; -// Console.ForegroundColor = ConsoleColor.Red; -// Console.WriteLine(@"You have not properly installed or configured FFMPEG. -//Please install and configure FFMPEG to play music. -//Check the guides for your platform on how to setup ffmpeg correctly: -// Windows Guide: https://goo.gl/OjKk8F -// Linux Guide: https://goo.gl/ShjCUo"); -// Console.ForegroundColor = oldclr; -// } -// catch (Exception ex) -// { -// Console.WriteLine($"Buffering stopped: {ex.Message}"); -// } -// finally -// { -// if (outStream != null) -// outStream.Dispose(); -// if (p != null) -// { -// try -// { -// p.Kill(); -// } -// catch { } -// p.Dispose(); -// } -// } -// }); - -// /// -// /// Return the next file to read, and delete the old one -// /// -// /// Name of the file to read -// private string GetNextFile() -// { -// string filename = Basename + "-" + NextFileToRead; - -// if (NextFileToRead != 0) -// { -// try -// { -// CurrentBufferSize -= Convert.ToUInt64(new FileInfo(Basename + "-" + (NextFileToRead - 1)).Length); -// File.Delete(Basename + "-" + (NextFileToRead - 1)); -// } -// catch { } -// } -// NextFileToRead++; -// return filename; -// } - -// private bool IsNextFileReady() -// { -// return NextFileToRead <= FileNumber; -// } - -// private void CleanFiles() -// { -// for (long i = NextFileToRead - 1; i <= FileNumber; i++) -// { -// try -// { -// File.Delete(Basename + "-" + i); -// } -// catch { } -// } -// } - -// //Stream part - -// public override bool CanRead => true; - -// public override bool CanSeek => false; - -// public override bool CanWrite => false; - -// public override long Length => (long)CurrentBufferSize; - -// public override long Position { get; set; } = 0; - -// public override void Flush() { } - -// public override int Read(byte[] buffer, int offset, int count) -// { -// int read = CurrentFileStream.Read(buffer, offset, count); -// if (read < count) -// { -// if (!BufferingCompleted || IsNextFileReady()) -// { -// CurrentFileStream.Dispose(); -// CurrentFileStream = new FileStream(GetNextFile(), FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write); -// read += CurrentFileStream.Read(buffer, read + offset, count - read); -// } -// if (read < count) -// Array.Clear(buffer, read, count - read); -// } -// return read; -// } - -// public override long Seek(long offset, SeekOrigin origin) -// { -// throw new NotImplementedException(); -// } - -// public override void SetLength(long value) -// { -// throw new NotImplementedException(); -// } - -// public override void Write(byte[] buffer, int offset, int count) -// { -// throw new NotImplementedException(); -// } - -// public new void Dispose() -// { -// CurrentFileStream.Dispose(); -// MusicPlayer.SongCancelSource.Cancel(); -// CleanFiles(); -// base.Dispose(); -// } -// } -//} \ No newline at end of file +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/NSFW/NSFW.cs b/src/NadekoBot/Modules/NSFW/NSFW.cs index 5e3591db..1ca27691 100644 --- a/src/NadekoBot/Modules/NSFW/NSFW.cs +++ b/src/NadekoBot/Modules/NSFW/NSFW.cs @@ -16,9 +16,13 @@ using NadekoBot.Modules.NSFW.Exceptions; namespace NadekoBot.Modules.NSFW { + // thanks to halitalf for adding autoboob and autobutt features :D public class NSFW : NadekoTopLevelModule { private static readonly ConcurrentDictionary _autoHentaiTimers = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary _autoBoobTimers = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary _autoButtTimers = new ConcurrentDictionary(); + private static readonly ConcurrentHashSet _hentaiBombBlacklist = new ConcurrentHashSet(); private async Task InternalHentai(IMessageChannel channel, string tag, bool noError) @@ -49,10 +53,34 @@ namespace NadekoBot.Modules.NSFW .WithDescription($"[{GetText("tag")}: {tag}]({img})")) .ConfigureAwait(false); } + private async Task InternalBoobs(IMessageChannel Channel) + { + try + { + JToken obj; + obj = JArray.Parse(await _service.Http.GetStringAsync($"http://api.oboobs.ru/boobs/{new NadekoRandom().Next(0, 10330)}").ConfigureAwait(false))[0]; + await Channel.SendMessageAsync($"http://media.oboobs.ru/{obj["preview"]}").ConfigureAwait(false); + } + catch (Exception ex) + { + await Channel.SendErrorAsync(ex.Message).ConfigureAwait(false); + } + } + + private async Task InternalButts(IMessageChannel Channel) + { + try + { + JToken obj; + obj = JArray.Parse(await _service.Http.GetStringAsync($"http://api.obutts.ru/butts/{new NadekoRandom().Next(0, 4335)}").ConfigureAwait(false))[0]; + await Channel.SendMessageAsync($"http://media.obutts.ru/{obj["preview"]}").ConfigureAwait(false); + } + catch (Exception ex) + { + await Channel.SendErrorAsync(ex.Message).ConfigureAwait(false); + } + } - [NadekoCommand, Usage, Description, Aliases] - public Task Hentai([Remainder] string tag = null) => - InternalHentai(Context.Channel, tag, false); #if !GLOBAL_NADEKO [NadekoCommand, Usage, Description, Aliases] [RequireUserPermission(ChannelPermission.ManageMessages)] @@ -65,7 +93,7 @@ namespace NadekoBot.Modules.NSFW if (!_autoHentaiTimers.TryRemove(Context.Channel.Id, out t)) return; t.Change(Timeout.Infinite, Timeout.Infinite); //proper way to disable the timer - await ReplyConfirmLocalized("autohentai_stopped").ConfigureAwait(false); + await ReplyConfirmLocalized("stopped").ConfigureAwait(false); return; } @@ -99,8 +127,90 @@ namespace NadekoBot.Modules.NSFW interval, string.Join(", ", tagsArr)).ConfigureAwait(false); } + + [NadekoCommand, Usage, Description, Aliases] + [RequireUserPermission(ChannelPermission.ManageMessages)] + public async Task AutoBoobs(int interval = 0) + { + Timer t; + + if (interval == 0) + { + if (!_autoBoobTimers.TryRemove(Context.Channel.Id, out t)) return; + + t.Change(Timeout.Infinite, Timeout.Infinite); //proper way to disable the timer + await ReplyConfirmLocalized("stopped").ConfigureAwait(false); + return; + } + + if (interval < 20) + return; + + t = new Timer(async (state) => + { + try + { + await InternalBoobs(Context.Channel).ConfigureAwait(false); + } + catch + { + // ignored + } + }, null, interval * 1000, interval * 1000); + + _autoBoobTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) => + { + old.Change(Timeout.Infinite, Timeout.Infinite); + return t; + }); + + await ReplyConfirmLocalized("started", interval).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireUserPermission(ChannelPermission.ManageMessages)] + public async Task AutoButts(int interval = 0) + { + Timer t; + + if (interval == 0) + { + if (!_autoButtTimers.TryRemove(Context.Channel.Id, out t)) return; + + t.Change(Timeout.Infinite, Timeout.Infinite); //proper way to disable the timer + await ReplyConfirmLocalized("stopped").ConfigureAwait(false); + return; + } + + if (interval < 20) + return; + + t = new Timer(async (state) => + { + try + { + await InternalButts(Context.Channel).ConfigureAwait(false); + } + catch + { + // ignored + } + }, null, interval * 1000, interval * 1000); + + _autoButtTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) => + { + old.Change(Timeout.Infinite, Timeout.Infinite); + return t; + }); + + await ReplyConfirmLocalized("started", interval).ConfigureAwait(false); + } #endif + [NadekoCommand, Usage, Description, Aliases] + public Task Hentai([Remainder] string tag = null) => + InternalHentai(Context.Channel, tag, false); + [NadekoCommand, Usage, Description, Aliases] public async Task HentaiBomb([Remainder] string tag = null) { @@ -199,7 +309,7 @@ namespace NadekoBot.Modules.NSFW tag = tag.Trim().ToLowerInvariant(); var added = _service.ToggleBlacklistedTag(Context.Guild.Id, tag); - if(added) + if (added) await ReplyConfirmLocalized("blacklisted_tag_add", tag).ConfigureAwait(false); else await ReplyConfirmLocalized("blacklisted_tag_remove", tag).ConfigureAwait(false); diff --git a/src/NadekoBot/Modules/Xp/Club.cs b/src/NadekoBot/Modules/Xp/Club.cs index 8c4ce4c5..06fd5336 100644 --- a/src/NadekoBot/Modules/Xp/Club.cs +++ b/src/NadekoBot/Modules/Xp/Club.cs @@ -26,6 +26,27 @@ namespace NadekoBot.Modules.Xp _client = client; } + [NadekoCommand, Usage, Description, Aliases] + public async Task ClubAdmin([Remainder]IUser toAdmin) + { + bool admin; + try + { + admin = _service.ToggleAdmin(Context.User, toAdmin); + } + catch (InvalidOperationException) + { + await ReplyErrorLocalized("club_admin_error").ConfigureAwait(false); + return; + } + + if(admin) + await ReplyConfirmLocalized("club_admin_add", Format.Bold(toAdmin.ToString())).ConfigureAwait(false); + else + await ReplyConfirmLocalized("club_admin_remove", Format.Bold(toAdmin.ToString())).ConfigureAwait(false); + + } + [NadekoCommand, Usage, Description, Aliases] public async Task ClubCreate([Remainder]string clubName) { @@ -97,7 +118,14 @@ namespace NadekoBot.Modules.Xp .AddField("Level Req.", club.MinimumLevelReq.ToString(), true) .AddField("Members", string.Join("\n", club.Users .Skip(page * 10) - .Take(10)), false); + .Take(10) + .OrderByDescending(x => x.IsClubAdmin) + .Select(x => + { + if (x.IsClubAdmin) + return x.ToString() + "⭐"; + return x.ToString(); + })), false); if (Uri.IsWellFormedUriString(club.ImageUrl, UriKind.Absolute)) return embed.WithThumbnailUrl(club.ImageUrl); @@ -112,7 +140,7 @@ namespace NadekoBot.Modules.Xp if (--page < 0) return Task.CompletedTask; - var club = _service.GetBansAndApplications(Context.User.Id); + var club = _service.GetClubWithBansAndApplications(Context.User.Id); if (club == null) return ReplyErrorLocalized("club_not_exists"); @@ -143,11 +171,11 @@ namespace NadekoBot.Modules.Xp if (--page < 0) return Task.CompletedTask; - var club = _service.GetBansAndApplications(Context.User.Id); + var club = _service.GetClubWithBansAndApplications(Context.User.Id); if (club == null) return ReplyErrorLocalized("club_not_exists"); - var bans = club + var apps = club .Applicants .Select(x => x.User) .ToArray(); @@ -155,7 +183,7 @@ namespace NadekoBot.Modules.Xp return Context.Channel.SendPaginatedConfirmAsync(_client, page, curPage => { - var toShow = string.Join("\n", bans + var toShow = string.Join("\n", apps .Skip(page * 10) .Take(10) .Select(x => x.ToString())); @@ -164,7 +192,7 @@ namespace NadekoBot.Modules.Xp .WithTitle(GetText("club_apps_for", club.ToString())) .WithDescription(toShow); - }, bans.Length / 10); + }, apps.Length / 10); } [NadekoCommand, Usage, Description, Aliases] diff --git a/src/NadekoBot/Modules/Xp/Services/ClubService.cs b/src/NadekoBot/Modules/Xp/Services/ClubService.cs index f8d08f66..362067eb 100644 --- a/src/NadekoBot/Modules/Xp/Services/ClubService.cs +++ b/src/NadekoBot/Modules/Xp/Services/ClubService.cs @@ -27,10 +27,11 @@ namespace NadekoBot.Modules.Xp.Services { var du = uow.DiscordUsers.GetOrCreate(user); uow._context.SaveChanges(); - var xp = new LevelStats(uow.Xp.GetTotalUserXp(user.Id)); + var xp = new LevelStats(du.TotalXp); if (xp.Level >= 5 && du.Club == null) { + du.IsClubAdmin = true; du.Club = new ClubInfo() { Name = clubName, @@ -52,6 +53,27 @@ namespace NadekoBot.Modules.Xp.Services return true; } + public bool ToggleAdmin(IUser owner, IUser toAdmin) + { + bool newState; + using (var uow = _db.UnitOfWork) + { + var club = uow.Clubs.GetByOwner(owner.Id); + var adminUser = uow.DiscordUsers.GetOrCreate(toAdmin); + + if (club.OwnerId == adminUser.Id) + return true; + + if (club == null || club.Owner.UserId != owner.Id || + !club.Users.Contains(adminUser)) + throw new InvalidOperationException(); + + newState = adminUser.IsClubAdmin = !adminUser.IsClubAdmin; + uow.Complete(); + } + return newState; + } + public ClubInfo GetClubByMember(IUser user) { using (var uow = _db.UnitOfWork) @@ -107,7 +129,7 @@ namespace NadekoBot.Modules.Xp.Services uow._context.SaveChanges(); if (du.Club != null - || new LevelStats(uow.Xp.GetTotalUserXp(user.Id)).Level < club.MinimumLevelReq + || new LevelStats(du.TotalXp).Level < club.MinimumLevelReq || club.Bans.Any(x => x.UserId == du.Id) || club.Applicants.Any(x => x.UserId == du.Id)) { @@ -134,11 +156,7 @@ namespace NadekoBot.Modules.Xp.Services discordUser = null; using (var uow = _db.UnitOfWork) { - var club = uow.Clubs.GetByOwner(clubOwnerUserId, - set => set.Include(x => x.Applicants) - .ThenInclude(x => x.Club) - .Include(x => x.Applicants) - .ThenInclude(x => x.User)); + var club = uow.Clubs.GetByOwnerOrAdmin(clubOwnerUserId); if (club == null) return false; @@ -147,6 +165,7 @@ namespace NadekoBot.Modules.Xp.Services return false; applicant.User.Club = club; + applicant.User.IsClubAdmin = false; club.Applicants.Remove(applicant); //remove that user's all other applications @@ -159,15 +178,11 @@ namespace NadekoBot.Modules.Xp.Services return true; } - public ClubInfo GetBansAndApplications(ulong ownerUserId) + public ClubInfo GetClubWithBansAndApplications(ulong ownerUserId) { using (var uow = _db.UnitOfWork) { - return uow.Clubs.GetByOwner(ownerUserId, - x => x.Include(y => y.Bans) - .ThenInclude(y => y.User) - .Include(y => y.Applicants) - .ThenInclude(y => y.User)); + return uow.Clubs.GetByOwnerOrAdmin(ownerUserId); } } @@ -180,6 +195,7 @@ namespace NadekoBot.Modules.Xp.Services return false; du.Club = null; + du.IsClubAdmin = false; uow.Complete(); } return true; @@ -221,9 +237,7 @@ namespace NadekoBot.Modules.Xp.Services { using (var uow = _db.UnitOfWork) { - club = uow.Clubs.GetByOwner(ownerUserId, - set => set.Include(x => x.Applicants) - .ThenInclude(x => x.User)); + club = uow.Clubs.GetByOwnerOrAdmin(ownerUserId); if (club == null) return false; @@ -256,9 +270,7 @@ namespace NadekoBot.Modules.Xp.Services { using (var uow = _db.UnitOfWork) { - club = uow.Clubs.GetByOwner(ownerUserId, - set => set.Include(x => x.Bans) - .ThenInclude(x => x.User)); + club = uow.Clubs.GetByOwnerOrAdmin(ownerUserId); if (club == null) return false; @@ -277,7 +289,7 @@ namespace NadekoBot.Modules.Xp.Services { using (var uow = _db.UnitOfWork) { - club = uow.Clubs.GetByOwner(ownerUserId); + club = uow.Clubs.GetByOwnerOrAdmin(ownerUserId); if (club == null) return false; diff --git a/src/NadekoBot/Modules/Xp/Services/XpService.cs b/src/NadekoBot/Modules/Xp/Services/XpService.cs index 537953e2..09fa7ec9 100644 --- a/src/NadekoBot/Modules/Xp/Services/XpService.cs +++ b/src/NadekoBot/Modules/Xp/Services/XpService.cs @@ -144,7 +144,7 @@ namespace NadekoBot.Modules.Xp.Services du.LastXpGain = DateTime.UtcNow; - var globalXp = uow.Xp.GetTotalUserXp(item.Key.User.Id); + var globalXp = du.TotalXp; var oldGlobalLevelData = new LevelStats(globalXp); var newGlobalLevelData = new LevelStats(globalXp + xp); @@ -403,17 +403,6 @@ namespace NadekoBot.Modules.Xp.Services return _rewardedUsers.Add(userId); } - public LevelStats GetGlobalUserStats(ulong userId) - { - int totalXp; - using (var uow = _db.UnitOfWork) - { - totalXp = uow.Xp.GetTotalUserXp(userId); - } - - return new LevelStats(totalXp); - } - public FullUserStats GetUserStats(IGuildUser user) { DiscordUser du; diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 587d643e..957e8059 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3780,4 +3780,31 @@ Clears nsfw cache. + + clubadmin + + + `{0}clubadmin` + + + Assigns (or unassigns) staff role to the member of the club. Admins can ban, kick and accept applications. + + + autoboobs + + + Posts a boobs every X seconds. 20 seconds minimum. Provide no arguments to disable. + + + `{0}autoboobs 30` or `{0}autoboobs` + + + autobutts + + + Posts a butts every X seconds. 20 seconds minimum. Provide no arguments to disable. + + + `{0}autobutts 30` or `{0}autobutts` + diff --git a/src/NadekoBot/Services/Database/Models/DiscordUser.cs b/src/NadekoBot/Services/Database/Models/DiscordUser.cs index 77a573b6..654408e2 100644 --- a/src/NadekoBot/Services/Database/Models/DiscordUser.cs +++ b/src/NadekoBot/Services/Database/Models/DiscordUser.cs @@ -10,6 +10,7 @@ namespace NadekoBot.Services.Database.Models public string AvatarId { get; set; } public ClubInfo Club { get; set; } + public bool IsClubAdmin { get; set; } public int TotalXp { get; set; } public DateTime LastLevelUp { get; set; } = DateTime.UtcNow; diff --git a/src/NadekoBot/Services/Database/NadekoContext.cs b/src/NadekoBot/Services/Database/NadekoContext.cs index 5c04c816..0df96909 100644 --- a/src/NadekoBot/Services/Database/NadekoContext.cs +++ b/src/NadekoBot/Services/Database/NadekoContext.cs @@ -329,7 +329,7 @@ namespace NadekoBot.Services.Database #region ClubManytoMany modelBuilder.Entity() - .HasKey(t => new { t.ClubId, t.UserId }); + .HasKey(t => new { t.ClubId, t.UserId }); modelBuilder.Entity() .HasOne(pt => pt.User) @@ -340,7 +340,7 @@ namespace NadekoBot.Services.Database .WithMany(x => x.Applicants); modelBuilder.Entity() - .HasKey(t => new { t.ClubId, t.UserId }); + .HasKey(t => new { t.ClubId, t.UserId }); modelBuilder.Entity() .HasOne(pt => pt.User) diff --git a/src/NadekoBot/Services/Database/Repositories/IClubRepository.cs b/src/NadekoBot/Services/Database/Repositories/IClubRepository.cs index 086d638b..66ad3d92 100644 --- a/src/NadekoBot/Services/Database/Repositories/IClubRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/IClubRepository.cs @@ -10,6 +10,7 @@ namespace NadekoBot.Services.Database.Repositories int GetNextDiscrim(string clubName); ClubInfo GetByName(string v, int discrim, Func, IQueryable> func = null); ClubInfo GetByOwner(ulong userId, Func, IQueryable> func = null); + ClubInfo GetByOwnerOrAdmin(ulong userId); ClubInfo GetByMember(ulong userId, Func, IQueryable> func = null); ClubInfo[] GetClubLeaderboardPage(int page); } diff --git a/src/NadekoBot/Services/Database/Repositories/IXpRepository.cs b/src/NadekoBot/Services/Database/Repositories/IXpRepository.cs index 10345d5d..f62394d7 100644 --- a/src/NadekoBot/Services/Database/Repositories/IXpRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/IXpRepository.cs @@ -5,7 +5,6 @@ namespace NadekoBot.Services.Database.Repositories public interface IXpRepository : IRepository { UserXpStats GetOrCreateUser(ulong guildId, ulong userId); - int GetTotalUserXp(ulong userId); int GetUserGuildRanking(ulong userId, ulong guildId); UserXpStats[] GetUsersFor(ulong guildId, int page); } diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/ClubRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/ClubRepository.cs index eb09e8b0..7eabbb1c 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/ClubRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/ClubRepository.cs @@ -24,6 +24,30 @@ namespace NadekoBot.Services.Database.Repositories.Impl return func(_set).FirstOrDefault(x => x.Owner.UserId == userId); } + public ClubInfo GetByOwnerOrAdmin(ulong userId) + { + return _set + .Include(x => x.Bans) + .ThenInclude(x => x.User) + .Include(x => x.Applicants) + .ThenInclude(x => x.User) + .Include(x => x.Owner) + .FirstOrDefault(x => x.Owner.UserId == userId) ?? + _context.Set() + .Include(x => x.Club) + .ThenInclude(x => x.Users) + .Include(x => x.Club) + .ThenInclude(x => x.Bans) + .ThenInclude(x => x.User) + .Include(x => x.Club) + .ThenInclude(x => x.Applicants) + .ThenInclude(x => x.User) + .Include(x => x.Club) + .ThenInclude(x => x.Owner) + .FirstOrDefault(x => x.UserId == userId && x.IsClubAdmin) + ?.Club; + } + public ClubInfo GetByName(string name, int discrim, Func, IQueryable> func = null) { if (func == null) diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/XpRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/XpRepository.cs index cc026b6a..b411cdad 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/XpRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/XpRepository.cs @@ -29,11 +29,6 @@ namespace NadekoBot.Services.Database.Repositories.Impl return usr; } - public int GetTotalUserXp(ulong userId) - { - return _set.Where(x => x.UserId == userId).Sum(x => x.Xp); - } - public UserXpStats[] GetUsersFor(ulong guildId, int page) { return _set.Where(x => x.GuildId == guildId) diff --git a/src/NadekoBot/_strings/ResponseStrings.en-US.json b/src/NadekoBot/_strings/ResponseStrings.en-US.json index 1ee47eed..ebd9c435 100644 --- a/src/NadekoBot/_strings/ResponseStrings.en-US.json +++ b/src/NadekoBot/_strings/ResponseStrings.en-US.json @@ -13,7 +13,6 @@ "customreactions_stats_not_found": "No stats for that trigger found, no action taken.", "customreactions_trigger": "Trigger", "customreactions_redacted_too_long": "Redecated because it's too long.", - "nsfw_autohentai_stopped": "Autohentai stopped.", "nsfw_not_found": "No results found.", "nsfw_blacklisted_tag_list": "List of blacklisted tags:", "nsfw_blacklisted_tag": "One or more tags you've used are blacklisted", @@ -868,5 +867,10 @@ "xp_club_icon_set": "New club icon set.", "xp_club_bans_for": "Bans for {0} club", "xp_club_apps_for": "Applicants for {0} club", - "xp_club_leaderboard": "Club leaderboard - page {0}" + "xp_club_leaderboard": "Club leaderboard - page {0}", + "xp_club_admin_add": "{0} is now a club admin.", + "xp_club_admin_remove": "{0} is no longer club admin.", + "xp_club_admin_error": "Error. You are either not the owner of the club, or that user is not in your club.", + "nsfw_started": "Started. Reposting every {0}s.", + "nsfw_stopped": "Stopped reposting." } \ No newline at end of file