mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-04 00:34:26 -05:00 
			
		
		
		
	- Database namespace is now NadekoBot.Db
- Db related code is now in src/NadekoBot/Db - Finished major part of the db refactor, but many optimizations are left to be made
This commit is contained in:
		@@ -17,6 +17,7 @@ using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using NadekoBot.Core.Common.Configs;
 | 
			
		||||
using NadekoBot.Core.Services.Impl;
 | 
			
		||||
using NadekoBot.Db;
 | 
			
		||||
using NadekoBot.Modules.Administration;
 | 
			
		||||
using Serilog;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,49 +0,0 @@
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Xp.Common
 | 
			
		||||
{
 | 
			
		||||
    public static class ClubExtensions
 | 
			
		||||
    {
 | 
			
		||||
        private static IQueryable<ClubInfo> Include(this DbSet<ClubInfo> clubs)
 | 
			
		||||
            => clubs.Include(x => x.Owner)
 | 
			
		||||
                .Include(x => x.Applicants)
 | 
			
		||||
                    .ThenInclude(x => x.User)
 | 
			
		||||
                .Include(x => x.Bans)
 | 
			
		||||
                    .ThenInclude(x => x.User)
 | 
			
		||||
                .Include(x => x.Users)
 | 
			
		||||
                .AsQueryable();
 | 
			
		||||
        public static ClubInfo GetByOwner(this DbSet<ClubInfo> clubs, ulong userId)
 | 
			
		||||
            => Include(clubs).FirstOrDefault(c => c.Owner.UserId == userId);
 | 
			
		||||
        
 | 
			
		||||
        public static ClubInfo GetByOwnerOrAdmin(this DbSet<ClubInfo> clubs, ulong userId)
 | 
			
		||||
            => Include(clubs).FirstOrDefault(c => c.Owner.UserId == userId
 | 
			
		||||
                                                                || c.Users.Any(u => u.UserId == userId && u.IsClubAdmin));
 | 
			
		||||
 | 
			
		||||
        public static ClubInfo GetByMember(this DbSet<ClubInfo> clubs, ulong userId)
 | 
			
		||||
            => Include(clubs).FirstOrDefault(c => c.Users.Any(u => u.UserId == userId));
 | 
			
		||||
 | 
			
		||||
        public static ClubInfo GetByName(this DbSet<ClubInfo> clubs, string name, int discrim)
 | 
			
		||||
            => Include(clubs).FirstOrDefault(c => c.Name.ToUpper() == name.ToUpper() && c.Discrim == discrim);
 | 
			
		||||
 | 
			
		||||
        public static int GetNextDiscrim(this DbSet<ClubInfo> clubs, string name)
 | 
			
		||||
            => Include(clubs)
 | 
			
		||||
                .Where(x => x.Name.ToUpper() == name.ToUpper())
 | 
			
		||||
                .Select(x => x.Discrim)
 | 
			
		||||
                .DefaultIfEmpty()
 | 
			
		||||
                .Max() + 1;
 | 
			
		||||
 | 
			
		||||
        public static List<ClubInfo> GetClubLeaderboardPage(this DbSet<ClubInfo> clubs, int page)
 | 
			
		||||
        {
 | 
			
		||||
            return clubs
 | 
			
		||||
                .AsNoTracking()
 | 
			
		||||
                .OrderByDescending(x => x.Xp)
 | 
			
		||||
                .Skip(page * 9)
 | 
			
		||||
                .Take(9)
 | 
			
		||||
                .ToList();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database
 | 
			
		||||
{
 | 
			
		||||
    public static class CurrencyTransactionExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static List<CurrencyTransaction> GetPageFor(this DbSet<CurrencyTransaction> set, ulong userId, int page)
 | 
			
		||||
        {
 | 
			
		||||
            return set.AsQueryable()
 | 
			
		||||
                .AsNoTracking()
 | 
			
		||||
                .Where(x => x.UserId == userId)
 | 
			
		||||
                .OrderByDescending(x => x.DateAdded)
 | 
			
		||||
                .Skip(15 * page)
 | 
			
		||||
                .Take(15)
 | 
			
		||||
                .ToList();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using LinqToDB;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
{
 | 
			
		||||
    public static class CustomReactionsExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static int ClearFromGuild(this DbSet<CustomReaction> crs, ulong guildId)
 | 
			
		||||
        {
 | 
			
		||||
            return crs.Delete(x => x.GuildId == guildId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<CustomReaction> ForId(this DbSet<CustomReaction> crs, ulong id)
 | 
			
		||||
        {
 | 
			
		||||
            return crs
 | 
			
		||||
                .AsNoTracking()
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .Where(x => x.GuildId == id)
 | 
			
		||||
                .ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static CustomReaction GetByGuildIdAndInput(this DbSet<CustomReaction> crs, ulong? guildId, string input)
 | 
			
		||||
        {
 | 
			
		||||
            return crs.FirstOrDefault(x => x.GuildId == guildId && x.Trigger.ToUpper() == input);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Db
 | 
			
		||||
{
 | 
			
		||||
    public static class DbExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static T GetById<T>(this DbSet<T> set, int id) where T: DbEntity
 | 
			
		||||
            => set.FirstOrDefault(x => x.Id == id);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,172 +0,0 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Discord;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System;
 | 
			
		||||
using NadekoBot.Core.Services.Database;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Repositories;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services
 | 
			
		||||
{
 | 
			
		||||
    public static class DiscordUserExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static void EnsureUserCreated(this NadekoContext ctx, ulong userId, string username, string discrim, string avatarId)
 | 
			
		||||
        {
 | 
			
		||||
            ctx.Database.ExecuteSqlInterpolated($@"
 | 
			
		||||
UPDATE OR IGNORE DiscordUser
 | 
			
		||||
SET Username={username},
 | 
			
		||||
    Discriminator={discrim},
 | 
			
		||||
    AvatarId={avatarId}
 | 
			
		||||
WHERE UserId={userId};
 | 
			
		||||
 | 
			
		||||
INSERT OR IGNORE INTO DiscordUser (UserId, Username, Discriminator, AvatarId)
 | 
			
		||||
VALUES ({userId}, {username}, {discrim}, {avatarId});
 | 
			
		||||
");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //temp is only used in updatecurrencystate, so that i don't overwrite real usernames/discrims with Unknown
 | 
			
		||||
        public static DiscordUser GetOrCreateUser(this NadekoContext ctx, ulong userId, string username, string discrim, string avatarId)
 | 
			
		||||
        {
 | 
			
		||||
            ctx.EnsureUserCreated(userId, username, discrim, avatarId);
 | 
			
		||||
            return ctx.DiscordUser
 | 
			
		||||
                .Include(x => x.Club)
 | 
			
		||||
                .First(u => u.UserId == userId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static DiscordUser GetOrCreateUser(this NadekoContext ctx, IUser original)
 | 
			
		||||
            => ctx.GetOrCreateUser(original.Id, original.Username, original.Discriminator, original.AvatarId);
 | 
			
		||||
 | 
			
		||||
        public static int GetUserGlobalRank(this DbSet<DiscordUser> users, ulong id)
 | 
			
		||||
        {
 | 
			
		||||
            return users.AsQueryable()
 | 
			
		||||
                .Where(x => x.TotalXp > (users
 | 
			
		||||
                    .AsQueryable()
 | 
			
		||||
                    .Where(y => y.UserId == id)
 | 
			
		||||
                    .Select(y => y.TotalXp)
 | 
			
		||||
                    .FirstOrDefault()))
 | 
			
		||||
                .Count() + 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static DiscordUser[] GetUsersXpLeaderboardFor(this DbSet<DiscordUser> users, int page)
 | 
			
		||||
        {
 | 
			
		||||
            return users.AsQueryable()
 | 
			
		||||
                .OrderByDescending(x => x.TotalXp)
 | 
			
		||||
                .Skip(page * 9)
 | 
			
		||||
                .Take(9)
 | 
			
		||||
                .AsEnumerable()
 | 
			
		||||
                .ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static List<DiscordUser> GetTopRichest(this DbSet<DiscordUser> users, ulong botId, int count, int page = 0)
 | 
			
		||||
        {
 | 
			
		||||
            return users.AsQueryable()
 | 
			
		||||
                .Where(c => c.CurrencyAmount > 0 && botId != c.UserId)
 | 
			
		||||
                .OrderByDescending(c => c.CurrencyAmount)
 | 
			
		||||
                .Skip(page * 9)
 | 
			
		||||
                .Take(count)
 | 
			
		||||
                .ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static List<DiscordUser> GetTopRichest(this DbSet<DiscordUser> users, ulong botId, int count)
 | 
			
		||||
        {
 | 
			
		||||
            return users.AsQueryable()
 | 
			
		||||
                .Where(c => c.CurrencyAmount > 0 && botId != c.UserId)
 | 
			
		||||
                .OrderByDescending(c => c.CurrencyAmount)
 | 
			
		||||
                .Take(count)
 | 
			
		||||
                .ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static long GetUserCurrency(this DbSet<DiscordUser> users, ulong userId) =>
 | 
			
		||||
            users.AsNoTracking()
 | 
			
		||||
                .FirstOrDefault(x => x.UserId == userId)
 | 
			
		||||
                ?.CurrencyAmount ?? 0;
 | 
			
		||||
 | 
			
		||||
        public static void RemoveFromMany(this DbSet<DiscordUser> users, IEnumerable<ulong> ids)
 | 
			
		||||
        {
 | 
			
		||||
            var items = users.AsQueryable().Where(x => ids.Contains(x.UserId));
 | 
			
		||||
            foreach (var item in items)
 | 
			
		||||
            {
 | 
			
		||||
                item.CurrencyAmount = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool TryUpdateCurrencyState(this NadekoContext ctx, ulong userId, string name, string discrim, string avatarId, long amount, bool allowNegative = false)
 | 
			
		||||
        {
 | 
			
		||||
            if (amount == 0)
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            // if remove - try to remove if he has more or equal than the amount
 | 
			
		||||
            // and return number of rows > 0 (was there a change)
 | 
			
		||||
            if (amount < 0 && !allowNegative)
 | 
			
		||||
            {
 | 
			
		||||
                var rows = ctx.Database.ExecuteSqlInterpolated($@"
 | 
			
		||||
UPDATE DiscordUser
 | 
			
		||||
SET CurrencyAmount=CurrencyAmount+{amount}
 | 
			
		||||
WHERE UserId={userId} AND CurrencyAmount>={-amount};");
 | 
			
		||||
                return rows > 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // if remove and negative is allowed, just remove without any condition
 | 
			
		||||
            if (amount < 0 && allowNegative)
 | 
			
		||||
            {
 | 
			
		||||
                var rows = ctx.Database.ExecuteSqlInterpolated($@"
 | 
			
		||||
UPDATE DiscordUser
 | 
			
		||||
SET CurrencyAmount=CurrencyAmount+{amount}
 | 
			
		||||
WHERE UserId={userId};");
 | 
			
		||||
                return rows > 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // if add - create a new user with default values if it doesn't exist
 | 
			
		||||
            // if it exists, sum current amount with the new one, if it doesn't
 | 
			
		||||
            // he just has the new amount
 | 
			
		||||
            var updatedUserData = !string.IsNullOrWhiteSpace(name);
 | 
			
		||||
            name = name ?? "Unknown";
 | 
			
		||||
            discrim = discrim ?? "????";
 | 
			
		||||
            avatarId = avatarId ?? "";
 | 
			
		||||
 | 
			
		||||
            // just update the amount, there is no new user data
 | 
			
		||||
            if (!updatedUserData)
 | 
			
		||||
            {
 | 
			
		||||
                ctx.Database.ExecuteSqlInterpolated($@"
 | 
			
		||||
UPDATE OR IGNORE DiscordUser
 | 
			
		||||
SET CurrencyAmount=CurrencyAmount+{amount}
 | 
			
		||||
WHERE UserId={userId};
 | 
			
		||||
 | 
			
		||||
INSERT OR IGNORE INTO DiscordUser (UserId, Username, Discriminator, AvatarId, CurrencyAmount)
 | 
			
		||||
VALUES ({userId}, {name}, {discrim}, {avatarId}, {amount});
 | 
			
		||||
");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                ctx.Database.ExecuteSqlInterpolated($@"
 | 
			
		||||
UPDATE OR IGNORE DiscordUser
 | 
			
		||||
SET CurrencyAmount=CurrencyAmount+{amount},
 | 
			
		||||
    Username={name},
 | 
			
		||||
    Discriminator={discrim},
 | 
			
		||||
    AvatarId={avatarId}
 | 
			
		||||
WHERE UserId={userId};
 | 
			
		||||
 | 
			
		||||
INSERT OR IGNORE INTO DiscordUser (UserId, Username, Discriminator, AvatarId, CurrencyAmount)
 | 
			
		||||
VALUES ({userId}, {name}, {discrim}, {avatarId}, {amount});
 | 
			
		||||
");
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static decimal GetTotalCurrency(this DbSet<DiscordUser> users)
 | 
			
		||||
        {
 | 
			
		||||
            return users
 | 
			
		||||
                .Sum(x => x.CurrencyAmount);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static decimal GetTopOnePercentCurrency(this DbSet<DiscordUser> users, ulong botId)
 | 
			
		||||
        {
 | 
			
		||||
            return users.AsQueryable()
 | 
			
		||||
                .Where(x => x.UserId != botId)
 | 
			
		||||
                .OrderByDescending(x => x.CurrencyAmount)
 | 
			
		||||
                .Take(users.Count() / 100 == 0 ? 1 : users.Count() / 100)
 | 
			
		||||
                .Sum(x => x.CurrencyAmount);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,240 +0,0 @@
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System;
 | 
			
		||||
using NadekoBot.Core.Services.Database;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Administration
 | 
			
		||||
{
 | 
			
		||||
    public static class GuildConfigExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public class GeneratingChannel
 | 
			
		||||
        {
 | 
			
		||||
            public ulong GuildId { get; set; }
 | 
			
		||||
            public ulong ChannelId { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets full stream role settings for the guild with the specified id.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="ctx">Db Context</param>
 | 
			
		||||
        /// <param name="guildId">Id of the guild to get stream role settings for.</param>
 | 
			
		||||
        /// <returns>Guild'p stream role settings</returns>
 | 
			
		||||
        public static StreamRoleSettings GetStreamRoleSettings(this NadekoContext ctx, ulong guildId)
 | 
			
		||||
        {
 | 
			
		||||
            var conf = ctx.GuildConfigsForId(guildId, set => set.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;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        private static List<WarningPunishment> DefaultWarnPunishments =>
 | 
			
		||||
            new List<WarningPunishment>() {
 | 
			
		||||
                new WarningPunishment() {
 | 
			
		||||
                    Count = 3,
 | 
			
		||||
                    Punishment = PunishmentAction.Kick
 | 
			
		||||
                },
 | 
			
		||||
                new WarningPunishment() {
 | 
			
		||||
                    Count = 5,
 | 
			
		||||
                    Punishment = PunishmentAction.Ban
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        private static IQueryable<GuildConfig> IncludeEverything(this DbSet<GuildConfig> configs)
 | 
			
		||||
        {
 | 
			
		||||
            return configs
 | 
			
		||||
                    .AsQueryable()
 | 
			
		||||
                    .Include(gc => gc.CommandCooldowns)
 | 
			
		||||
                    .Include(gc => gc.FollowedStreams)
 | 
			
		||||
                    .Include(gc => gc.StreamRole)
 | 
			
		||||
                    .Include(gc => gc.NsfwBlacklistedTags)
 | 
			
		||||
                    .Include(gc => gc.XpSettings)
 | 
			
		||||
                    .ThenInclude(x => x.ExclusionList)
 | 
			
		||||
                    .Include(gc => gc.DelMsgOnCmdChannels)
 | 
			
		||||
                    .Include(gc => gc.ReactionRoleMessages)
 | 
			
		||||
                    .ThenInclude(x => x.ReactionRoles)
 | 
			
		||||
                ;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<GuildConfig> GetAllGuildConfigs(this DbSet<GuildConfig> configs, List<ulong> availableGuilds)
 | 
			
		||||
            => configs
 | 
			
		||||
                .IncludeEverything()
 | 
			
		||||
                .AsNoTracking()
 | 
			
		||||
                .Where(x => availableGuilds.Contains(x.GuildId))
 | 
			
		||||
                .ToList();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets and creates if it doesn't exist a config for a guild.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="guildId">For which guild</param>
 | 
			
		||||
        /// <param name="includes">Use to manipulate the set however you want</param>
 | 
			
		||||
        /// <returns>Config for the guild</returns>
 | 
			
		||||
        public static GuildConfig GuildConfigsForId(this NadekoContext ctx, ulong guildId, Func<DbSet<GuildConfig>, IQueryable<GuildConfig>> includes = null)
 | 
			
		||||
        {
 | 
			
		||||
            GuildConfig config;
 | 
			
		||||
 | 
			
		||||
            if (includes == null)
 | 
			
		||||
            {
 | 
			
		||||
                config = ctx
 | 
			
		||||
                    .GuildConfigs
 | 
			
		||||
                    .IncludeEverything()
 | 
			
		||||
                    .FirstOrDefault(c => c.GuildId == guildId);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                var set = includes(ctx.GuildConfigs);
 | 
			
		||||
                config = set.FirstOrDefault(c => c.GuildId == guildId);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (config == null)
 | 
			
		||||
            {
 | 
			
		||||
                ctx.GuildConfigs.Add((config = new GuildConfig
 | 
			
		||||
                {
 | 
			
		||||
                    GuildId = guildId,
 | 
			
		||||
                    Permissions = Permissionv2.GetDefaultPermlist,
 | 
			
		||||
                    WarningsInitialized = true,
 | 
			
		||||
                    WarnPunishments = DefaultWarnPunishments,
 | 
			
		||||
                }));
 | 
			
		||||
                ctx.SaveChanges();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!config.WarningsInitialized)
 | 
			
		||||
            {
 | 
			
		||||
                config.WarningsInitialized = true;
 | 
			
		||||
                config.WarnPunishments = DefaultWarnPunishments;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return config;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static GuildConfig LogSettingsFor(this NadekoContext ctx, ulong guildId)
 | 
			
		||||
        {
 | 
			
		||||
            var config = ctx
 | 
			
		||||
                .GuildConfigs
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .Include(gc => gc.LogSetting)
 | 
			
		||||
                    .ThenInclude(gc => gc.IgnoredChannels)
 | 
			
		||||
                .FirstOrDefault(x => x.GuildId == guildId);
 | 
			
		||||
 | 
			
		||||
            if (config == null)
 | 
			
		||||
            {
 | 
			
		||||
                ctx.GuildConfigs.Add((config = new GuildConfig
 | 
			
		||||
                {
 | 
			
		||||
                    GuildId = guildId,
 | 
			
		||||
                    Permissions = Permissionv2.GetDefaultPermlist,
 | 
			
		||||
                    WarningsInitialized = true,
 | 
			
		||||
                    WarnPunishments = DefaultWarnPunishments,
 | 
			
		||||
                }));
 | 
			
		||||
                ctx.SaveChanges();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!config.WarningsInitialized)
 | 
			
		||||
            {
 | 
			
		||||
                config.WarningsInitialized = true;
 | 
			
		||||
                config.WarnPunishments = DefaultWarnPunishments;
 | 
			
		||||
            }
 | 
			
		||||
            return config;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<GuildConfig> Permissionsv2ForAll(this DbSet<GuildConfig> configs, List<ulong> include)
 | 
			
		||||
        {
 | 
			
		||||
            var query = configs.AsQueryable()
 | 
			
		||||
                .Where(x => include.Contains(x.GuildId))
 | 
			
		||||
                .Include(gc => gc.Permissions);
 | 
			
		||||
 | 
			
		||||
            return query.ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static GuildConfig GcWithPermissionsv2For(this NadekoContext ctx, ulong guildId)
 | 
			
		||||
        {
 | 
			
		||||
            var config = ctx
 | 
			
		||||
                .GuildConfigs
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .Where(gc => gc.GuildId == guildId)
 | 
			
		||||
                .Include(gc => gc.Permissions)
 | 
			
		||||
                .FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
            if (config == null) // if there is no guildconfig, create new one
 | 
			
		||||
            {
 | 
			
		||||
                ctx.GuildConfigs.Add((config = new GuildConfig
 | 
			
		||||
                {
 | 
			
		||||
                    GuildId = guildId,
 | 
			
		||||
                    Permissions = Permissionv2.GetDefaultPermlist
 | 
			
		||||
                }));
 | 
			
		||||
                ctx.SaveChanges();
 | 
			
		||||
            }
 | 
			
		||||
            else if (config.Permissions == null || !config.Permissions.Any()) // if no perms, add default ones
 | 
			
		||||
            {
 | 
			
		||||
                config.Permissions = Permissionv2.GetDefaultPermlist;
 | 
			
		||||
                ctx.SaveChanges();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return config;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<FollowedStream> GetFollowedStreams(this DbSet<GuildConfig> configs)
 | 
			
		||||
        {
 | 
			
		||||
            return configs
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .Include(x => x.FollowedStreams)
 | 
			
		||||
                .SelectMany(gc => gc.FollowedStreams)
 | 
			
		||||
                .ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<FollowedStream> GetFollowedStreams(this DbSet<GuildConfig> configs, List<ulong> included)
 | 
			
		||||
        {
 | 
			
		||||
            return configs.AsQueryable()
 | 
			
		||||
                .Where(gc => included.Contains(gc.GuildId))
 | 
			
		||||
                .Include(gc => gc.FollowedStreams)
 | 
			
		||||
                .SelectMany(gc => gc.FollowedStreams)
 | 
			
		||||
                .ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void SetCleverbotEnabled(this DbSet<GuildConfig> configs, ulong id, bool cleverbotEnabled)
 | 
			
		||||
        {
 | 
			
		||||
            var conf = configs.FirstOrDefault(gc => gc.GuildId == id);
 | 
			
		||||
 | 
			
		||||
            if (conf == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            conf.CleverbotEnabled = cleverbotEnabled;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static XpSettings XpSettingsFor(this NadekoContext ctx, ulong guildId)
 | 
			
		||||
        {
 | 
			
		||||
            var gc = ctx.GuildConfigsForId(guildId,
 | 
			
		||||
                set => set.Include(x => x.XpSettings)
 | 
			
		||||
                          .ThenInclude(x => x.RoleRewards)
 | 
			
		||||
                          .Include(x => x.XpSettings)
 | 
			
		||||
                          .ThenInclude(x => x.CurrencyRewards)
 | 
			
		||||
                          .Include(x => x.XpSettings)
 | 
			
		||||
                          .ThenInclude(x => x.ExclusionList));
 | 
			
		||||
 | 
			
		||||
            if (gc.XpSettings == null)
 | 
			
		||||
                gc.XpSettings = new XpSettings();
 | 
			
		||||
 | 
			
		||||
            return gc.XpSettings;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<GeneratingChannel> GetGeneratingChannels(this DbSet<GuildConfig> configs)
 | 
			
		||||
        {
 | 
			
		||||
            return configs
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .Include(x => x.GenerateCurrencyChannelIds)
 | 
			
		||||
                .Where(x => x.GenerateCurrencyChannelIds.Any())
 | 
			
		||||
                .SelectMany(x => x.GenerateCurrencyChannelIds)
 | 
			
		||||
                .Select(x => new GeneratingChannel()
 | 
			
		||||
                {
 | 
			
		||||
                    ChannelId = x.ChannelId,
 | 
			
		||||
                    GuildId = x.GuildConfig.GuildId
 | 
			
		||||
                })
 | 
			
		||||
                .ToArray();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Repositories.Impl
 | 
			
		||||
{
 | 
			
		||||
    public static class MusicPlayerSettingsExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static async Task<MusicPlayerSettings> ForGuildAsync(this DbSet<MusicPlayerSettings> settings, ulong guildId)
 | 
			
		||||
        {
 | 
			
		||||
            var toReturn = await settings
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .FirstOrDefaultAsync(x => x.GuildId == guildId);
 | 
			
		||||
 | 
			
		||||
            if (toReturn is null)
 | 
			
		||||
            {
 | 
			
		||||
                var newSettings = new MusicPlayerSettings()
 | 
			
		||||
                {
 | 
			
		||||
                    GuildId = guildId,
 | 
			
		||||
                    PlayerRepeat = PlayerRepeatType.Queue
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                await settings.AddAsync(newSettings);
 | 
			
		||||
                return newSettings;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return toReturn;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Music
 | 
			
		||||
{
 | 
			
		||||
    public static class MusicPlaylistExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static List<MusicPlaylist> GetPlaylistsOnPage(this DbSet<MusicPlaylist> playlists, int num)
 | 
			
		||||
        {
 | 
			
		||||
            if (num < 1)
 | 
			
		||||
                throw new IndexOutOfRangeException();
 | 
			
		||||
 | 
			
		||||
            return playlists
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .Skip((num - 1) * 20)
 | 
			
		||||
                .Take(20)
 | 
			
		||||
                .Include(pl => pl.Songs)
 | 
			
		||||
                .ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static MusicPlaylist GetWithSongs(this DbSet<MusicPlaylist> playlists, int id) => 
 | 
			
		||||
            playlists
 | 
			
		||||
                .Include(mpl => mpl.Songs)
 | 
			
		||||
                .FirstOrDefault(mpl => mpl.Id == id);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Core.Services.Database;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Common
 | 
			
		||||
{
 | 
			
		||||
    public static class PollExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static IEnumerable<Poll> GetAllPolls(this DbSet<Poll> polls)
 | 
			
		||||
        {
 | 
			
		||||
            return polls.Include(x => x.Answers)
 | 
			
		||||
                .Include(x => x.Votes)
 | 
			
		||||
                .ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void RemovePoll(this NadekoContext ctx, int id)
 | 
			
		||||
        {
 | 
			
		||||
            var p = ctx
 | 
			
		||||
                .Poll
 | 
			
		||||
                .Include(x => x.Answers)
 | 
			
		||||
                .Include(x => x.Votes)
 | 
			
		||||
                .FirstOrDefault(x => x.Id == id);
 | 
			
		||||
 | 
			
		||||
            if (p is null)
 | 
			
		||||
                return;
 | 
			
		||||
            
 | 
			
		||||
            if (p.Votes != null)
 | 
			
		||||
            {
 | 
			
		||||
                ctx.RemoveRange(p.Votes);
 | 
			
		||||
                p.Votes.Clear();
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            if (p.Answers != null)
 | 
			
		||||
            {
 | 
			
		||||
                ctx.RemoveRange(p.Answers);
 | 
			
		||||
                p.Answers.Clear();
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            ctx.Poll.Remove(p);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,53 +0,0 @@
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Common;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Repositories.Impl
 | 
			
		||||
{
 | 
			
		||||
    public static class QuoteExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static IEnumerable<Quote> GetGroup(this DbSet<Quote> quotes, ulong guildId, int page, OrderType order)
 | 
			
		||||
        {
 | 
			
		||||
            var q = quotes.AsQueryable().Where(x => x.GuildId == guildId);
 | 
			
		||||
            if (order == OrderType.Keyword)
 | 
			
		||||
                q = q.OrderBy(x => x.Keyword);
 | 
			
		||||
            else
 | 
			
		||||
                q = q.OrderBy(x => x.Id);
 | 
			
		||||
 | 
			
		||||
            return q.Skip(15 * page).Take(15).ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<Quote> GetRandomQuoteByKeywordAsync(this DbSet<Quote> quotes, ulong guildId, string keyword)
 | 
			
		||||
        {
 | 
			
		||||
            var rng = new NadekoRandom();
 | 
			
		||||
            return (await quotes.AsQueryable()
 | 
			
		||||
                .Where(q => q.GuildId == guildId && q.Keyword == keyword)
 | 
			
		||||
                .ToListAsync())
 | 
			
		||||
                .OrderBy(q => rng.Next())
 | 
			
		||||
                .FirstOrDefault();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<Quote> SearchQuoteKeywordTextAsync(this DbSet<Quote> quotes, ulong guildId, string keyword, string text)
 | 
			
		||||
        {
 | 
			
		||||
            var rngk = new NadekoRandom();
 | 
			
		||||
            return (await quotes.AsQueryable()
 | 
			
		||||
                .Where(q => q.GuildId == guildId
 | 
			
		||||
                            && q.Keyword == keyword
 | 
			
		||||
                            && EF.Functions.Like(q.Text.ToUpper(), $"%{text.ToUpper()}%")
 | 
			
		||||
                            // && q.Text.Contains(text, StringComparison.OrdinalIgnoreCase)
 | 
			
		||||
                            )
 | 
			
		||||
                .ToListAsync())
 | 
			
		||||
                .OrderBy(q => rngk.Next())
 | 
			
		||||
                .FirstOrDefault();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void RemoveAllByKeyword(this DbSet<Quote> quotes, ulong guildId, string keyword)
 | 
			
		||||
        {
 | 
			
		||||
            quotes.RemoveRange(quotes.AsQueryable().Where(x => x.GuildId == guildId && x.Keyword.ToUpper() == keyword));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Utility.Common
 | 
			
		||||
{
 | 
			
		||||
    public static class ReminderExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static IEnumerable<Reminder> GetIncludedReminders(this DbSet<Reminder> reminders, IEnumerable<ulong> guildIds) 
 | 
			
		||||
            => reminders.AsQueryable()
 | 
			
		||||
                .Where(x => guildIds.Contains(x.ServerId) || x.ServerId == 0)
 | 
			
		||||
                .ToList();
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<Reminder> RemindersFor(this DbSet<Reminder> reminders, ulong userId, int page)
 | 
			
		||||
            => reminders.AsQueryable()
 | 
			
		||||
                .Where(x => x.UserId == userId)
 | 
			
		||||
                .OrderBy(x => x.DateAdded)
 | 
			
		||||
                .Skip(page * 10)
 | 
			
		||||
                .Take(10);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,26 +0,0 @@
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Administration.Common
 | 
			
		||||
{
 | 
			
		||||
    public static class SelfAssignableRolesExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static bool DeleteByGuildAndRoleId(this DbSet<SelfAssignedRole> roles, ulong guildId, ulong roleId)
 | 
			
		||||
        {
 | 
			
		||||
            var role = roles.FirstOrDefault(s => s.GuildId == guildId && s.RoleId == roleId);
 | 
			
		||||
 | 
			
		||||
            if (role == null)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            roles.Remove(role);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<SelfAssignedRole> GetFromGuild(this DbSet<SelfAssignedRole> roles, ulong guildId) 
 | 
			
		||||
            =>  roles.AsQueryable()
 | 
			
		||||
                    .Where(s => s.GuildId == guildId)
 | 
			
		||||
                    .ToArray();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,86 +0,0 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using LinqToDB;
 | 
			
		||||
using NadekoBot.Core.Services.Database;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Xp.Common
 | 
			
		||||
{
 | 
			
		||||
    public static class UserXpExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static UserXpStats GetOrCreateUserXpStats(this NadekoContext ctx, ulong guildId, ulong userId)
 | 
			
		||||
        {
 | 
			
		||||
            var usr = ctx.UserXpStats.FirstOrDefault(x => x.UserId == userId && x.GuildId == guildId);
 | 
			
		||||
 | 
			
		||||
            if (usr == null)
 | 
			
		||||
            {
 | 
			
		||||
                ctx.Add(usr = new UserXpStats()
 | 
			
		||||
                {
 | 
			
		||||
                    Xp = 0,
 | 
			
		||||
                    UserId = userId,
 | 
			
		||||
                    NotifyOnLevelUp = XpNotificationLocation.None,
 | 
			
		||||
                    GuildId = guildId,
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return usr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static List<UserXpStats> GetUsersFor(this DbSet<UserXpStats> xps, ulong guildId, int page)
 | 
			
		||||
        {
 | 
			
		||||
            return xps
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .AsNoTracking()
 | 
			
		||||
                .Where(x => x.GuildId == guildId)
 | 
			
		||||
                .OrderByDescending(x => x.Xp + x.AwardedXp)
 | 
			
		||||
                .Skip(page * 9)
 | 
			
		||||
                .Take(9)
 | 
			
		||||
                .ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static List<UserXpStats> GetTopUserXps(this DbSet<UserXpStats> xps, ulong guildId, int count)
 | 
			
		||||
        {
 | 
			
		||||
            return xps
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .AsNoTracking()
 | 
			
		||||
                .Where(x => x.GuildId == guildId)
 | 
			
		||||
                .OrderByDescending(x => x.Xp + x.AwardedXp)
 | 
			
		||||
                .Take(count)
 | 
			
		||||
                .ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static int GetUserGuildRanking(this DbSet<UserXpStats> xps, ulong userId, ulong guildId)
 | 
			
		||||
        {
 | 
			
		||||
            //            @"SELECT COUNT(*) + 1
 | 
			
		||||
            //FROM UserXpStats
 | 
			
		||||
            //WHERE GuildId = @p1 AND ((Xp + AwardedXp) > (SELECT Xp + AwardedXp
 | 
			
		||||
            //	FROM UserXpStats
 | 
			
		||||
            //	WHERE UserId = @p2 AND GuildId = @p1
 | 
			
		||||
            //	LIMIT 1));";
 | 
			
		||||
 | 
			
		||||
            return xps
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .AsNoTracking()
 | 
			
		||||
                .Where(x => x.GuildId == guildId && ((x.Xp + x.AwardedXp) >
 | 
			
		||||
                    (xps.AsQueryable()
 | 
			
		||||
                        .Where(y => y.UserId == userId && y.GuildId == guildId)
 | 
			
		||||
                        .Select(y => y.Xp + y.AwardedXp)
 | 
			
		||||
                        .FirstOrDefault())
 | 
			
		||||
                ))
 | 
			
		||||
                .Count() + 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void ResetGuildUserXp(this DbSet<UserXpStats> xps, ulong userId, ulong guildId)
 | 
			
		||||
        {
 | 
			
		||||
            xps.Delete(x => x.UserId == userId && x.GuildId == guildId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void ResetGuildXp(this DbSet<UserXpStats> xps, ulong guildId)
 | 
			
		||||
        {
 | 
			
		||||
            xps.Delete(x => x.GuildId == guildId);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,177 +0,0 @@
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Core.Services.Database;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using NadekoBot.Migrations;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Gambling
 | 
			
		||||
{
 | 
			
		||||
    public class WaifuInfoStats
 | 
			
		||||
    {
 | 
			
		||||
        public string FullName { get; set; }
 | 
			
		||||
        public int Price { get; set; }
 | 
			
		||||
        public string ClaimerName { get; set; }
 | 
			
		||||
        public string AffinityName { get; set; }
 | 
			
		||||
        public int AffinityCount { get; set; }
 | 
			
		||||
        public int DivorceCount { get; set; }
 | 
			
		||||
        public int ClaimCount { get; set; }
 | 
			
		||||
        public List<WaifuItem> Items { get; set; }
 | 
			
		||||
        public List<string> Claims { get; set; }
 | 
			
		||||
        public List<string> Fans { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static class WaifuExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static WaifuInfo ByWaifuUserId(this DbSet<WaifuInfo> waifus, ulong userId, Func<DbSet<WaifuInfo>, IQueryable<WaifuInfo>> includes = null)
 | 
			
		||||
        {
 | 
			
		||||
            if (includes == null)
 | 
			
		||||
            {
 | 
			
		||||
                return waifus.Include(wi => wi.Waifu)
 | 
			
		||||
                            .Include(wi => wi.Affinity)
 | 
			
		||||
                            .Include(wi => wi.Claimer)
 | 
			
		||||
                            .Include(wi => wi.Items)
 | 
			
		||||
                            .FirstOrDefault(wi => wi.Waifu.UserId == userId);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return includes(waifus)
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .FirstOrDefault(wi => wi.Waifu.UserId == userId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<WaifuLbResult> GetTop(this DbSet<WaifuInfo> waifus, int count, int skip = 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (count < 0)
 | 
			
		||||
                throw new ArgumentOutOfRangeException(nameof(count));
 | 
			
		||||
            if (count == 0)
 | 
			
		||||
                return new List<WaifuLbResult>();
 | 
			
		||||
 | 
			
		||||
            return waifus.Include(wi => wi.Waifu)
 | 
			
		||||
                        .Include(wi => wi.Affinity)
 | 
			
		||||
                        .Include(wi => wi.Claimer)
 | 
			
		||||
                    .OrderByDescending(wi => wi.Price)
 | 
			
		||||
                    .Skip(skip)
 | 
			
		||||
                    .Take(count)
 | 
			
		||||
                    .Select(x => new WaifuLbResult
 | 
			
		||||
                    {
 | 
			
		||||
                        Affinity = x.Affinity == null ? null : x.Affinity.Username,
 | 
			
		||||
                        AffinityDiscrim = x.Affinity == null ? null : x.Affinity.Discriminator,
 | 
			
		||||
                        Claimer = x.Claimer == null ? null : x.Claimer.Username,
 | 
			
		||||
                        ClaimerDiscrim = x.Claimer == null ? null : x.Claimer.Discriminator,
 | 
			
		||||
                        Username = x.Waifu.Username,
 | 
			
		||||
                        Discrim = x.Waifu.Discriminator,
 | 
			
		||||
                        Price = x.Price,
 | 
			
		||||
                    })
 | 
			
		||||
                    .ToList();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static decimal GetTotalValue(this DbSet<WaifuInfo> waifus)
 | 
			
		||||
        {
 | 
			
		||||
            return waifus
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .Where(x => x.ClaimerId != null)
 | 
			
		||||
                .Sum(x => x.Price);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static int AffinityCount(this DbSet<WaifuUpdate> updates, ulong userId)
 | 
			
		||||
        {
 | 
			
		||||
            return updates
 | 
			
		||||
                .FromSqlInterpolated($@"SELECT 1 
 | 
			
		||||
FROM WaifuUpdates
 | 
			
		||||
WHERE UserId = (SELECT Id from DiscordUser WHERE UserId={userId}) AND 
 | 
			
		||||
    UpdateType = 0 AND 
 | 
			
		||||
    NewId IS NOT NULL")
 | 
			
		||||
                .Count();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static ulong GetWaifuUserId(this DbSet<WaifuInfo> waifus, ulong ownerId, string name)
 | 
			
		||||
        {
 | 
			
		||||
            return waifus
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .AsNoTracking()
 | 
			
		||||
                .Where(x => x.Claimer.UserId == ownerId
 | 
			
		||||
                            && x.Waifu.Username + "#" + x.Waifu.Discriminator == name)
 | 
			
		||||
                .Select(x => x.Waifu.UserId)
 | 
			
		||||
                .FirstOrDefault();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public static WaifuInfoStats GetWaifuInfo(this NadekoContext ctx, ulong userId)
 | 
			
		||||
        {
 | 
			
		||||
            ctx.Database.ExecuteSqlInterpolated($@"
 | 
			
		||||
INSERT OR IGNORE INTO WaifuInfo (AffinityId, ClaimerId, Price, WaifuId)
 | 
			
		||||
VALUES ({null}, {null}, {1}, (SELECT Id FROM DiscordUser WHERE UserId={userId}));");
 | 
			
		||||
 | 
			
		||||
            var toReturn = ctx.WaifuInfo
 | 
			
		||||
                .AsQueryable()
 | 
			
		||||
                .Where(w => w.WaifuId == ctx.Set<DiscordUser>()
 | 
			
		||||
                    .AsQueryable()
 | 
			
		||||
                    .Where(u => u.UserId == userId)
 | 
			
		||||
                    .Select(u => u.Id).FirstOrDefault())
 | 
			
		||||
                .Select(w => new WaifuInfoStats
 | 
			
		||||
                {
 | 
			
		||||
                    FullName = ctx.Set<DiscordUser>()
 | 
			
		||||
                        .AsQueryable()
 | 
			
		||||
                        .Where(u => u.UserId == userId)
 | 
			
		||||
                        .Select(u => u.Username + "#" + u.Discriminator)
 | 
			
		||||
                        .FirstOrDefault(),
 | 
			
		||||
 | 
			
		||||
                    AffinityCount = ctx.Set<WaifuUpdate>()
 | 
			
		||||
                        .AsQueryable()
 | 
			
		||||
                        .Count(x => x.UserId == w.WaifuId &&
 | 
			
		||||
                            x.UpdateType == WaifuUpdateType.AffinityChanged &&
 | 
			
		||||
                            x.NewId != null),
 | 
			
		||||
 | 
			
		||||
                    AffinityName = ctx.Set<DiscordUser>()
 | 
			
		||||
                        .AsQueryable()
 | 
			
		||||
                        .Where(u => u.Id == w.AffinityId)
 | 
			
		||||
                        .Select(u => u.Username + "#" + u.Discriminator)
 | 
			
		||||
                        .FirstOrDefault(),
 | 
			
		||||
 | 
			
		||||
                    ClaimCount = ctx.WaifuInfo
 | 
			
		||||
                        .AsQueryable()
 | 
			
		||||
                        .Count(x => x.ClaimerId == w.WaifuId),
 | 
			
		||||
 | 
			
		||||
                    ClaimerName = ctx.Set<DiscordUser>()
 | 
			
		||||
                        .AsQueryable()
 | 
			
		||||
                        .Where(u => u.Id == w.ClaimerId)
 | 
			
		||||
                        .Select(u => u.Username + "#" + u.Discriminator)
 | 
			
		||||
                        .FirstOrDefault(),
 | 
			
		||||
 | 
			
		||||
                    DivorceCount = ctx
 | 
			
		||||
                        .Set<WaifuUpdate>()
 | 
			
		||||
                        .AsQueryable()
 | 
			
		||||
                        .Count(x => x.OldId == w.WaifuId &&
 | 
			
		||||
                                    x.NewId == null &&
 | 
			
		||||
                                    x.UpdateType == WaifuUpdateType.Claimed),
 | 
			
		||||
 | 
			
		||||
                    Price = w.Price,
 | 
			
		||||
 | 
			
		||||
                    Claims = ctx.WaifuInfo
 | 
			
		||||
                        .AsQueryable()
 | 
			
		||||
                        .Include(x => x.Waifu)
 | 
			
		||||
                        .Where(x => x.ClaimerId == w.WaifuId)
 | 
			
		||||
                        .Select(x => x.Waifu.Username + "#" + x.Waifu.Discriminator)
 | 
			
		||||
                        .ToList(),
 | 
			
		||||
 | 
			
		||||
                    Fans = ctx.WaifuInfo
 | 
			
		||||
                        .AsQueryable()
 | 
			
		||||
                        .Include(x => x.Waifu)
 | 
			
		||||
                        .Where(x => x.AffinityId == w.WaifuId)
 | 
			
		||||
                        .Select(x => x.Waifu.Username + "#" + x.Waifu.Discriminator)
 | 
			
		||||
                        .ToList(),
 | 
			
		||||
                    
 | 
			
		||||
                    Items = w.Items,
 | 
			
		||||
                })
 | 
			
		||||
            .FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
            if (toReturn is null)
 | 
			
		||||
                return null;
 | 
			
		||||
            
 | 
			
		||||
            return toReturn;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,56 +0,0 @@
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Administration.Common
 | 
			
		||||
{
 | 
			
		||||
    public static class WarningExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static Warning[] ForId(this DbSet<Warning> warnings, ulong guildId, ulong userId)
 | 
			
		||||
        {
 | 
			
		||||
            var query = warnings.AsQueryable()
 | 
			
		||||
                .Where(x => x.GuildId == guildId && x.UserId == userId)
 | 
			
		||||
                .OrderByDescending(x => x.DateAdded);
 | 
			
		||||
 | 
			
		||||
            return query.ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool Forgive(this DbSet<Warning> warnings, ulong guildId, ulong userId, string mod, int index)
 | 
			
		||||
        {
 | 
			
		||||
            if (index < 0)
 | 
			
		||||
                throw new ArgumentOutOfRangeException(nameof(index));
 | 
			
		||||
 | 
			
		||||
            var warn = warnings.AsQueryable().Where(x => x.GuildId == guildId && x.UserId == userId)
 | 
			
		||||
                .OrderByDescending(x => x.DateAdded)
 | 
			
		||||
                .Skip(index)
 | 
			
		||||
                .FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
            if (warn == null || warn.Forgiven)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            warn.Forgiven = true;
 | 
			
		||||
            warn.ForgivenBy = mod;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task ForgiveAll(this DbSet<Warning> warnings, ulong guildId, ulong userId, string mod)
 | 
			
		||||
        {
 | 
			
		||||
            await warnings.AsQueryable().Where(x => x.GuildId == guildId && x.UserId == userId)
 | 
			
		||||
                .ForEachAsync(x =>
 | 
			
		||||
                {
 | 
			
		||||
                    if (x.Forgiven != true)
 | 
			
		||||
                    {
 | 
			
		||||
                        x.Forgiven = true;
 | 
			
		||||
                        x.ForgivenBy = mod;
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static Warning[] GetForGuild(this DbSet<Warning> warnings, ulong id)
 | 
			
		||||
        {
 | 
			
		||||
            return warnings.AsQueryable().Where(x => x.GuildId == id).ToArray();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,68 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class AntiRaidSetting : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int GuildConfigId { get; set; }
 | 
			
		||||
        public GuildConfig GuildConfig { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int UserThreshold { get; set; }
 | 
			
		||||
        public int Seconds { get; set; }
 | 
			
		||||
        public PunishmentAction Action { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Duration of the punishment, in minutes. This works only for supported Actions, like:
 | 
			
		||||
        /// Mute, Chatmute, Voicemute, etc...
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int PunishDuration { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class AntiSpamSetting : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int GuildConfigId { get; set; }
 | 
			
		||||
        public GuildConfig GuildConfig { get; set; }
 | 
			
		||||
 | 
			
		||||
        public PunishmentAction Action { get; set; }
 | 
			
		||||
        public int MessageThreshold { get; set; } = 3;
 | 
			
		||||
        public int MuteTime { get; set; } = 0;
 | 
			
		||||
        public ulong? RoleId { get; set; }
 | 
			
		||||
        public HashSet<AntiSpamIgnore> IgnoredChannels { get; set; } = new HashSet<AntiSpamIgnore>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class AntiAltSetting
 | 
			
		||||
    {
 | 
			
		||||
        public int Id { get; set; }
 | 
			
		||||
        public int GuildConfigId { get; set; }
 | 
			
		||||
        public TimeSpan MinAge { get; set; }
 | 
			
		||||
        public PunishmentAction Action { get; set; }
 | 
			
		||||
        public int ActionDurationMinutes { get; set; }
 | 
			
		||||
        public ulong? RoleId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum PunishmentAction
 | 
			
		||||
    {
 | 
			
		||||
        Mute,
 | 
			
		||||
        Kick,
 | 
			
		||||
        Ban,
 | 
			
		||||
        Softban,
 | 
			
		||||
        RemoveRoles,
 | 
			
		||||
        ChatMute,
 | 
			
		||||
        VoiceMute,
 | 
			
		||||
        AddRole
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class AntiSpamIgnore : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode() => ChannelId.GetHashCode();
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is AntiSpamIgnore inst
 | 
			
		||||
                ? inst.ChannelId == ChannelId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class AutoCommand : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public string CommandText { get; set; }
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public string ChannelName { get; set; }
 | 
			
		||||
        public ulong? GuildId { get; set; }
 | 
			
		||||
        public string GuildName { get; set; }
 | 
			
		||||
        public ulong? VoiceChannelId {get; set; }
 | 
			
		||||
        public string VoiceChannelName { get; set; }
 | 
			
		||||
        public int Interval { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class BanTemplate : DbEntity 
 | 
			
		||||
    {
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
        public string Text { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class BlacklistEntry : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong ItemId { get; set; }
 | 
			
		||||
        public BlacklistType Type { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum BlacklistType
 | 
			
		||||
    {
 | 
			
		||||
        Server,
 | 
			
		||||
        Channel,
 | 
			
		||||
        User
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,49 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.ComponentModel.DataAnnotations;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class ClubInfo : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        [MaxLength(20)]
 | 
			
		||||
        public string Name { get; set; }
 | 
			
		||||
        public int Discrim { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string ImageUrl { get; set; } = "";
 | 
			
		||||
        public int MinimumLevelReq { get; set; } = 5;
 | 
			
		||||
        public int Xp { get; set; } = 0;
 | 
			
		||||
        
 | 
			
		||||
        public int OwnerId { get; set; }
 | 
			
		||||
        public DiscordUser Owner { get; set; }
 | 
			
		||||
 | 
			
		||||
        public List<DiscordUser> Users { get; set; } = new List<DiscordUser>();
 | 
			
		||||
 | 
			
		||||
        public List<ClubApplicants> Applicants { get; set; } = new List<ClubApplicants>();
 | 
			
		||||
        public List<ClubBans> Bans { get; set; } = new List<ClubBans>();
 | 
			
		||||
        public string Description { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            return Name + "#" + Discrim;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ClubApplicants
 | 
			
		||||
    {
 | 
			
		||||
        public int ClubId { get; set; }
 | 
			
		||||
        public ClubInfo Club { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int UserId { get; set; }
 | 
			
		||||
        public DiscordUser User { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ClubBans
 | 
			
		||||
    {
 | 
			
		||||
        public int ClubId { get; set; }
 | 
			
		||||
        public ClubInfo Club { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int UserId { get; set; }
 | 
			
		||||
        public DiscordUser User { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class CommandAlias : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public string Trigger { get; set; }
 | 
			
		||||
        public string Mapping { get; set; }
 | 
			
		||||
 | 
			
		||||
        //// override object.Equals
 | 
			
		||||
        //public override bool Equals(object obj)
 | 
			
		||||
        //{
 | 
			
		||||
        //    if (obj == null || GetType() != obj.GetType())
 | 
			
		||||
        //    {
 | 
			
		||||
        //        return false;
 | 
			
		||||
        //    }
 | 
			
		||||
 | 
			
		||||
        //    return ((CommandAlias)obj).Trigger.Trim().ToLowerInvariant() == Trigger.Trim().ToLowerInvariant();
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        //// override object.GetHashCode
 | 
			
		||||
        //public override int GetHashCode()
 | 
			
		||||
        //{
 | 
			
		||||
        //    return Trigger.Trim().ToLowerInvariant().GetHashCode();
 | 
			
		||||
        //}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class CommandCooldown : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int Seconds { get; set; }
 | 
			
		||||
        public string CommandName { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class CurrencyTransaction : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public long Amount { get; set; }
 | 
			
		||||
        public string Reason { get; set; }
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public CurrencyTransaction Clone() => new CurrencyTransaction
 | 
			
		||||
        {
 | 
			
		||||
            Amount = Amount,
 | 
			
		||||
            Reason = Reason,
 | 
			
		||||
            UserId = UserId,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using System;
 | 
			
		||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class CustomReaction : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        #region Unused
 | 
			
		||||
        
 | 
			
		||||
        [Obsolete]
 | 
			
		||||
        [NotMapped]
 | 
			
		||||
        public Regex Regex { get; set; }
 | 
			
		||||
        [Obsolete]
 | 
			
		||||
        public ulong UseCount { get; set; }
 | 
			
		||||
        [Obsolete]
 | 
			
		||||
        public bool IsRegex { get; set; }
 | 
			
		||||
        [Obsolete]
 | 
			
		||||
        public bool OwnerOnly { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        #endregion
 | 
			
		||||
        
 | 
			
		||||
        public ulong? GuildId { get; set; }
 | 
			
		||||
        public string Response { get; set; }
 | 
			
		||||
        public string Trigger { get; set; }
 | 
			
		||||
 | 
			
		||||
        public bool AutoDeleteTrigger { get; set; }
 | 
			
		||||
        public bool DmResponse { get; set; }
 | 
			
		||||
        public bool ContainsAnywhere { get; set; }
 | 
			
		||||
        public bool AllowTarget { get; set; }
 | 
			
		||||
        public string Reactions { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string[] GetReactions() =>
 | 
			
		||||
            string.IsNullOrWhiteSpace(Reactions)
 | 
			
		||||
                ? Array.Empty<string>()
 | 
			
		||||
                : Reactions.Split("@@@");
 | 
			
		||||
        
 | 
			
		||||
        public bool IsGlobal() => GuildId is null || GuildId == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ReactionResponse : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public bool OwnerOnly { get; set; }
 | 
			
		||||
        public string Text { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.ComponentModel.DataAnnotations;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        [Key]
 | 
			
		||||
        public int Id { get; set; }
 | 
			
		||||
        public DateTime? DateAdded { get; set; } = DateTime.UtcNow;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class DelMsgOnCmdChannel : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public bool State { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return ChannelId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is DelMsgOnCmdChannel x
 | 
			
		||||
                && x.ChannelId == ChannelId;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class DiscordPermOverride : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public GuildPerm Perm { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        public ulong? GuildId { get; set; }
 | 
			
		||||
        public string Command { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class DiscordUser : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public string Username { get; set; }
 | 
			
		||||
        public string Discriminator { get; set; }
 | 
			
		||||
        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;
 | 
			
		||||
        public DateTime LastXpGain { get; set; } = DateTime.MinValue;
 | 
			
		||||
        public XpNotificationLocation NotifyOnLevelUp { get; set; }
 | 
			
		||||
 | 
			
		||||
        public long CurrencyAmount { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is DiscordUser du
 | 
			
		||||
                ? du.UserId == UserId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return UserId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ToString() => 
 | 
			
		||||
            Username + "#" + Discriminator;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class CurrencyEvent
 | 
			
		||||
    {
 | 
			
		||||
        public enum Type
 | 
			
		||||
        {
 | 
			
		||||
            Reaction,
 | 
			
		||||
            GameStatus,
 | 
			
		||||
            //NotRaid,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ulong ServerId { get; set; }
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public ulong MessageId { get; set; }
 | 
			
		||||
        public Type EventType { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Amount of currency that the user will be rewarded.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public long Amount { get; set; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Maximum amount of currency that can be handed out.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public long PotSize { get; set; }
 | 
			
		||||
        public List<AwardedUser> AwardedUsers { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Used as extra data storage for events which need it.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ulong ExtraId { get; set; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// May be used for some future event.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ulong ExtraId2 { get; set; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// May be used for some future event.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string ExtraString { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class AwardedUser
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class FeedSub : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int GuildConfigId { get; set; }
 | 
			
		||||
        public GuildConfig GuildConfig { get; set; }
 | 
			
		||||
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public string Url { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return Url.GetHashCode(StringComparison.InvariantCulture) ^ GuildConfigId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is FeedSub s
 | 
			
		||||
                && s.Url.ToLower() == Url.ToLower()
 | 
			
		||||
                && s.GuildConfigId == GuildConfigId;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class FilterChannelId : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is FilterChannelId f
 | 
			
		||||
                ? f.ChannelId == ChannelId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return ChannelId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class FilterLinksChannelId : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is FilterLinksChannelId f
 | 
			
		||||
                ? f.ChannelId == ChannelId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return ChannelId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class FilteredWord : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public string Word { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,50 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using NadekoBot.Modules.Searches.Common;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class FollowedStream : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public string Username { get; set; }
 | 
			
		||||
        public FType Type { get; set; }
 | 
			
		||||
        public string Message { get; set; }
 | 
			
		||||
 | 
			
		||||
        public enum FType
 | 
			
		||||
        {
 | 
			
		||||
            Twitch = 0,
 | 
			
		||||
            [Obsolete("No longer supported.")]
 | 
			
		||||
            Smashcast = 1,
 | 
			
		||||
            [Obsolete("No longer supported.")]
 | 
			
		||||
            Mixer = 2,
 | 
			
		||||
            Picarto = 3,
 | 
			
		||||
            Youtube = 4,
 | 
			
		||||
            Facebook = 5,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected bool Equals(FollowedStream other)
 | 
			
		||||
        {
 | 
			
		||||
            return ChannelId == other.ChannelId 
 | 
			
		||||
                   && Username.Trim().ToUpperInvariant() == other.Username.Trim().ToUpperInvariant() 
 | 
			
		||||
                   && Type == other.Type;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return HashCode.Combine(ChannelId, Username, (int) Type);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            if (ReferenceEquals(null, obj)) return false;
 | 
			
		||||
            if (ReferenceEquals(this, obj)) return true;
 | 
			
		||||
            if (obj.GetType() != this.GetType()) return false;
 | 
			
		||||
            return Equals((FollowedStream) obj);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public StreamDataKey CreateKey() =>
 | 
			
		||||
            new StreamDataKey(Type, Username.ToLower());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class GCChannelId : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public GuildConfig GuildConfig { get; set; }
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is GCChannelId gc
 | 
			
		||||
                ? gc.ChannelId == ChannelId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode() =>
 | 
			
		||||
            this.ChannelId.GetHashCode();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class GroupName : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int GuildConfigId { get; set; }
 | 
			
		||||
        public GuildConfig GuildConfig { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int Number { get; set; }
 | 
			
		||||
        public string Name { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,110 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using NadekoBot.Common.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class GuildConfig : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string Prefix { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
        public bool DeleteMessageOnCommand { get; set; }
 | 
			
		||||
        public HashSet<DelMsgOnCmdChannel> DelMsgOnCmdChannels { get; set; } = new HashSet<DelMsgOnCmdChannel>();
 | 
			
		||||
        [Obsolete("Use autoassignroleids")]
 | 
			
		||||
        public ulong AutoAssignRoleId { get; set; }
 | 
			
		||||
        public string AutoAssignRoleIds { get; set; }
 | 
			
		||||
        //greet stuff
 | 
			
		||||
        public bool AutoDeleteGreetMessages { get; set; } //unused
 | 
			
		||||
        public bool AutoDeleteByeMessages { get; set; } // unused
 | 
			
		||||
        public int AutoDeleteGreetMessagesTimer { get; set; } = 30;
 | 
			
		||||
        public int AutoDeleteByeMessagesTimer { get; set; } = 30;
 | 
			
		||||
 | 
			
		||||
        public ulong GreetMessageChannelId { get; set; }
 | 
			
		||||
        public ulong ByeMessageChannelId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public bool SendDmGreetMessage { get; set; }
 | 
			
		||||
        public string DmGreetMessageText { get; set; } = "Welcome to the %server% server, %user%!";
 | 
			
		||||
 | 
			
		||||
        public bool SendChannelGreetMessage { get; set; }
 | 
			
		||||
        public string ChannelGreetMessageText { get; set; } = "Welcome to the %server% server, %user%!";
 | 
			
		||||
 | 
			
		||||
        public bool SendChannelByeMessage { get; set; }
 | 
			
		||||
        public string ChannelByeMessageText { get; set; } = "%user% has left!";
 | 
			
		||||
 | 
			
		||||
        public LogSetting LogSetting { get; set; } = new LogSetting();
 | 
			
		||||
 | 
			
		||||
        //self assignable roles
 | 
			
		||||
        public bool ExclusiveSelfAssignedRoles { get; set; }
 | 
			
		||||
        public bool AutoDeleteSelfAssignedRoleMessages { get; set; }
 | 
			
		||||
        public float DefaultMusicVolume { get; set; } = 1.0f;
 | 
			
		||||
        public bool VoicePlusTextEnabled { get; set; }
 | 
			
		||||
 | 
			
		||||
        //stream notifications
 | 
			
		||||
        public HashSet<FollowedStream> FollowedStreams { get; set; } = new HashSet<FollowedStream>();
 | 
			
		||||
 | 
			
		||||
        //currencyGeneration
 | 
			
		||||
        public HashSet<GCChannelId> GenerateCurrencyChannelIds { get; set; } = new HashSet<GCChannelId>();
 | 
			
		||||
 | 
			
		||||
        //permissions
 | 
			
		||||
        public Permission RootPermission { get; set; } = null;
 | 
			
		||||
        public List<Permissionv2> Permissions { get; set; }
 | 
			
		||||
        public bool VerbosePermissions { get; set; } = true;
 | 
			
		||||
        public string PermissionRole { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
        public HashSet<CommandCooldown> CommandCooldowns { get; set; } = new HashSet<CommandCooldown>();
 | 
			
		||||
 | 
			
		||||
        //filtering
 | 
			
		||||
        public bool FilterInvites { get; set; }
 | 
			
		||||
        public bool FilterLinks { get; set; }
 | 
			
		||||
        public HashSet<FilterChannelId> FilterInvitesChannelIds { get; set; } = new HashSet<FilterChannelId>();
 | 
			
		||||
        public HashSet<FilterLinksChannelId> FilterLinksChannelIds { get; set; } = new HashSet<FilterLinksChannelId>();
 | 
			
		||||
 | 
			
		||||
        //public bool FilterLinks { get; set; }
 | 
			
		||||
        //public HashSet<FilterLinksChannelId> FilterLinksChannels { get; set; } = new HashSet<FilterLinksChannelId>();
 | 
			
		||||
 | 
			
		||||
        public bool FilterWords { get; set; }
 | 
			
		||||
        public HashSet<FilteredWord> FilteredWords { get; set; } = new HashSet<FilteredWord>();
 | 
			
		||||
        public HashSet<FilterChannelId> FilterWordsChannelIds { get; set; } = new HashSet<FilterChannelId>();
 | 
			
		||||
 | 
			
		||||
        public HashSet<MutedUserId> MutedUsers { get; set; } = new HashSet<MutedUserId>();
 | 
			
		||||
 | 
			
		||||
        public string MuteRoleName { get; set; }
 | 
			
		||||
        public bool CleverbotEnabled { get; set; }
 | 
			
		||||
 | 
			
		||||
        public AntiRaidSetting AntiRaidSetting { get; set; }
 | 
			
		||||
        public AntiSpamSetting AntiSpamSetting { get; set; }
 | 
			
		||||
        public AntiAltSetting AntiAltSetting { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string Locale { get; set; } = null;
 | 
			
		||||
        public string TimeZoneId { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
        public HashSet<UnmuteTimer> UnmuteTimers { get; set; } = new HashSet<UnmuteTimer>();
 | 
			
		||||
        public HashSet<UnbanTimer> UnbanTimer { get; set; } = new HashSet<UnbanTimer>();
 | 
			
		||||
        public HashSet<UnroleTimer> UnroleTimer { get; set; } = new HashSet<UnroleTimer>();
 | 
			
		||||
        public HashSet<VcRoleInfo> VcRoleInfos { get; set; }
 | 
			
		||||
        public HashSet<CommandAlias> CommandAliases { get; set; } = new HashSet<CommandAlias>();
 | 
			
		||||
        public List<WarningPunishment> WarnPunishments { get; set; } = new List<WarningPunishment>();
 | 
			
		||||
        public bool WarningsInitialized { get; set; }
 | 
			
		||||
        public HashSet<SlowmodeIgnoredUser> SlowmodeIgnoredUsers { get; set; }
 | 
			
		||||
        public HashSet<SlowmodeIgnoredRole> SlowmodeIgnoredRoles { get; set; }
 | 
			
		||||
        public HashSet<NsfwBlacklitedTag> NsfwBlacklistedTags { get; set; } = new HashSet<NsfwBlacklitedTag>();
 | 
			
		||||
 | 
			
		||||
        public List<ShopEntry> ShopEntries { get; set; }
 | 
			
		||||
        public ulong? GameVoiceChannel { get; set; } = null;
 | 
			
		||||
        public bool VerboseErrors { get; set; } = false;
 | 
			
		||||
 | 
			
		||||
        public StreamRoleSettings StreamRole { get; set; }
 | 
			
		||||
 | 
			
		||||
        public XpSettings XpSettings { get; set; }
 | 
			
		||||
        public List<FeedSub> FeedSubs { get; set; } = new List<FeedSub>();
 | 
			
		||||
        public bool AutoDcFromVc { get; set; }
 | 
			
		||||
        public IndexedCollection<ReactionRoleMessage> ReactionRoleMessages { get; set; } = new IndexedCollection<ReactionRoleMessage>();
 | 
			
		||||
        public bool NotifyStreamOffline { get; set; }
 | 
			
		||||
        public List<GroupName> SelfAssignableRoleGroupNames { get; set; }
 | 
			
		||||
        public int WarnExpireHours { get; set; } = 0;
 | 
			
		||||
        public WarnExpireAction WarnExpireAction { get; set; } = WarnExpireAction.Clear;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class IgnoredLogChannel : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public LogSetting LogSetting { get; set; }
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class IgnoredVoicePresenceChannel : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public LogSetting LogSetting { get; set; }
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,105 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    public class LogSetting : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public HashSet<IgnoredLogChannel> IgnoredChannels { get; set; } = new HashSet<IgnoredLogChannel>();
 | 
			
		||||
        public HashSet<IgnoredVoicePresenceChannel> IgnoredVoicePresenceChannelIds { get; set; } = new HashSet<IgnoredVoicePresenceChannel>();
 | 
			
		||||
 | 
			
		||||
        public ulong? LogOtherId { get; set; } = null;
 | 
			
		||||
        public ulong? MessageUpdatedId { get; set; } = null;
 | 
			
		||||
        public ulong? MessageDeletedId { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
        public ulong? UserJoinedId { get; set; } = null;
 | 
			
		||||
        public ulong? UserLeftId { get; set; } = null;
 | 
			
		||||
        public ulong? UserBannedId { get; set; } = null;
 | 
			
		||||
        public ulong? UserUnbannedId { get; set; } = null;
 | 
			
		||||
        public ulong? UserUpdatedId { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
        public ulong? ChannelCreatedId { get; set; } = null;
 | 
			
		||||
        public ulong? ChannelDestroyedId { get; set; } = null;
 | 
			
		||||
        public ulong? ChannelUpdatedId { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
        public ulong? UserMutedId { get; set; }
 | 
			
		||||
 | 
			
		||||
        //userpresence
 | 
			
		||||
        public ulong? LogUserPresenceId { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
        //voicepresence
 | 
			
		||||
 | 
			
		||||
        public ulong? LogVoicePresenceId { get; set; } = null;
 | 
			
		||||
        public ulong? LogVoicePresenceTTSId { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //-------------------DO NOT USE----------------
 | 
			
		||||
        // these old fields are here because sqlite doesn't support drop column operation
 | 
			
		||||
        // will be removed after bot moves to another database provider
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool IsLogging { get; set; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool MessageUpdated { get; set; } = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool MessageDeleted { get; set; } = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool UserJoined { get; set; } = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool UserLeft { get; set; } = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool UserBanned { get; set; } = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool UserUnbanned { get; set; } = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool UserUpdated { get; set; } = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool ChannelCreated { get; set; } = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool ChannelDestroyed { get; set; } = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool ChannelUpdated { get; set; } = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool LogUserPresence { get; set; } = false;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ulong UserPresenceChannelId { get; set; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool LogVoicePresence { get; set; } = false;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// DON'T USE
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ulong VoicePresenceChannelId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class MusicPlaylist : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public string Name { get; set; }
 | 
			
		||||
        public string Author { get; set; }
 | 
			
		||||
        public ulong AuthorId { get; set; }
 | 
			
		||||
        public List<PlaylistSong> Songs { get; set; } = new List<PlaylistSong>();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,56 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class MusicPlayerSettings
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Auto generated Id 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int Id { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Id of the guild
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Queue repeat type
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public PlayerRepeatType PlayerRepeat { get; set; } = PlayerRepeatType.Queue;
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Channel id the bot will always try to send track related messages to
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ulong? MusicChannelId { get; set; } = null;
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Default volume player will be created with
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int Volume { get; set; } = 100;
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Whether the bot should auto disconnect from the voice channel once the queue is done
 | 
			
		||||
        /// This only has effect if 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool AutoDisconnect { get; set; } = false;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Selected quality preset for the music player 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public QualityPreset QualityPreset { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public enum QualityPreset
 | 
			
		||||
    {
 | 
			
		||||
        Highest,
 | 
			
		||||
        High,
 | 
			
		||||
        Medium,
 | 
			
		||||
        Low
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum PlayerRepeatType
 | 
			
		||||
    {
 | 
			
		||||
        None,
 | 
			
		||||
        Track,
 | 
			
		||||
        Queue
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class MutedUserId : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return UserId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is MutedUserId mui
 | 
			
		||||
                ? mui.UserId == UserId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class NsfwBlacklitedTag : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public string Tag { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return Tag.GetHashCode(StringComparison.InvariantCulture);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is NsfwBlacklitedTag x
 | 
			
		||||
                ? x.Tag == Tag
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,85 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    [DebuggerDisplay("{global::NadekoBot.Modules.Permissions.PermissionExtensions.GetCommand(this)}", Target = typeof(Permission))]
 | 
			
		||||
    public class Permission : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public Permission Previous { get; set; } = null;
 | 
			
		||||
        public Permission Next { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
        public PrimaryPermissionType PrimaryTarget { get; set; }
 | 
			
		||||
        public ulong PrimaryTargetId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public SecondaryPermissionType SecondaryTarget { get; set; }
 | 
			
		||||
        public string SecondaryTargetName { get; set; }
 | 
			
		||||
 | 
			
		||||
        public bool State { get; set; }
 | 
			
		||||
 | 
			
		||||
        public Permissionv2 Tov2() =>
 | 
			
		||||
            new Permissionv2()
 | 
			
		||||
            {
 | 
			
		||||
                PrimaryTarget = PrimaryTarget,
 | 
			
		||||
                PrimaryTargetId = PrimaryTargetId,
 | 
			
		||||
                SecondaryTarget = SecondaryTarget,
 | 
			
		||||
                SecondaryTargetName = SecondaryTargetName,
 | 
			
		||||
                State = State,
 | 
			
		||||
            };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface IIndexed
 | 
			
		||||
    {
 | 
			
		||||
        int Index { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [DebuggerDisplay("{PrimaryTarget}{SecondaryTarget} {SecondaryTargetName} {State} {PrimaryTargetId}")]
 | 
			
		||||
    public class Permissionv2 : DbEntity, IIndexed
 | 
			
		||||
    {
 | 
			
		||||
        public int? GuildConfigId { get; set; }
 | 
			
		||||
        public int Index { get; set; }
 | 
			
		||||
 | 
			
		||||
        public PrimaryPermissionType PrimaryTarget { get; set; }
 | 
			
		||||
        public ulong PrimaryTargetId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public SecondaryPermissionType SecondaryTarget { get; set; }
 | 
			
		||||
        public string SecondaryTargetName { get; set; }
 | 
			
		||||
 | 
			
		||||
        public bool IsCustomCommand { get; set; }
 | 
			
		||||
 | 
			
		||||
        public bool State { get; set; }
 | 
			
		||||
 | 
			
		||||
        [NotMapped]
 | 
			
		||||
        public static Permissionv2 AllowAllPerm => new Permissionv2()
 | 
			
		||||
        {
 | 
			
		||||
            PrimaryTarget = PrimaryPermissionType.Server,
 | 
			
		||||
            PrimaryTargetId = 0,
 | 
			
		||||
            SecondaryTarget = SecondaryPermissionType.AllModules,
 | 
			
		||||
            SecondaryTargetName = "*",
 | 
			
		||||
            State = true,
 | 
			
		||||
            Index = 0,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        public static List<Permissionv2> GetDefaultPermlist =>
 | 
			
		||||
            new List<Permissionv2>
 | 
			
		||||
            {
 | 
			
		||||
                AllowAllPerm
 | 
			
		||||
            };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum PrimaryPermissionType
 | 
			
		||||
    {
 | 
			
		||||
        User,
 | 
			
		||||
        Channel,
 | 
			
		||||
        Role,
 | 
			
		||||
        Server
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum SecondaryPermissionType
 | 
			
		||||
    {
 | 
			
		||||
        Module,
 | 
			
		||||
        Command,
 | 
			
		||||
        AllModules
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class PlantedCurrency : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public long Amount { get; set; }
 | 
			
		||||
        public string Password { get; set; }
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public ulong MessageId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class PlaylistSong : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public string Provider { get; set; }
 | 
			
		||||
        public MusicType ProviderType { get; set; }
 | 
			
		||||
        public string Title { get; set; }
 | 
			
		||||
        public string Uri { get; set; }
 | 
			
		||||
        public string Query { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum MusicType
 | 
			
		||||
    {
 | 
			
		||||
        Radio,
 | 
			
		||||
        YouTube,
 | 
			
		||||
        Local,
 | 
			
		||||
        Soundcloud
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
using NadekoBot.Common.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class Poll : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public string Question { get; set; }
 | 
			
		||||
        public IndexedCollection<PollAnswer> Answers { get; set; }
 | 
			
		||||
        public HashSet<PollVote> Votes { get; set; } = new HashSet<PollVote>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class PollAnswer : DbEntity, IIndexed
 | 
			
		||||
    {
 | 
			
		||||
        public int Index { get; set; }
 | 
			
		||||
        public string Text { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class PollVote : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public int VoteIndex { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return UserId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is PollVote p
 | 
			
		||||
                ? p.UserId == UserId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
using System.ComponentModel.DataAnnotations;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class Quote : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
        [Required]
 | 
			
		||||
        public string Keyword { get; set; }
 | 
			
		||||
        [Required]
 | 
			
		||||
        public string AuthorName { get; set; }
 | 
			
		||||
        public ulong AuthorId { get; set; }
 | 
			
		||||
        [Required]
 | 
			
		||||
        public string Text { get; set; }
 | 
			
		||||
        public ulong UseCount { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public enum OrderType
 | 
			
		||||
    {
 | 
			
		||||
        Id = -1,
 | 
			
		||||
        Keyword = -2
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class ReactionRoleMessage : DbEntity, IIndexed
 | 
			
		||||
    {
 | 
			
		||||
        public int Index { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int GuildConfigId { get; set; }
 | 
			
		||||
        public GuildConfig GuildConfig { get; set; }
 | 
			
		||||
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public ulong MessageId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public List<ReactionRole> ReactionRoles { get; set; }
 | 
			
		||||
        public bool Exclusive { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ReactionRole : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public string EmoteName { get; set; }
 | 
			
		||||
        public ulong RoleId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class Reminder : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public DateTime When { get; set; }
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public ulong ServerId { get; set; }
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public string Message { get; set; }
 | 
			
		||||
        public bool IsPrivate { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class Repeater
 | 
			
		||||
    {
 | 
			
		||||
        public int Id { get; set; }
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public ulong? LastMessageId { get; set; }
 | 
			
		||||
        public string Message { get; set; }
 | 
			
		||||
        public TimeSpan Interval { get; set; }
 | 
			
		||||
        public TimeSpan? StartTimeOfDay { get; set; }
 | 
			
		||||
        public bool NoRedundant { get; set; }
 | 
			
		||||
        public DateTime DateAdded { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class RewardedUser : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public string PatreonUserId { get; set; }
 | 
			
		||||
        public int AmountRewardedThisMonth { get; set; }
 | 
			
		||||
        public DateTime LastReward { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class RotatingPlayingStatus : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public string Status { get; set; }
 | 
			
		||||
        public ActivityType Type { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class SelfAssignedRole : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
        public ulong RoleId { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        public int Group { get; set; }
 | 
			
		||||
        public int LevelRequirement { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public enum ShopEntryType
 | 
			
		||||
    {
 | 
			
		||||
        Role,
 | 
			
		||||
        List,
 | 
			
		||||
        //Infinite_List,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ShopEntry : DbEntity, IIndexed
 | 
			
		||||
    {
 | 
			
		||||
        public int Index { get; set; }
 | 
			
		||||
        public int Price { get; set; }
 | 
			
		||||
        public string Name { get; set; }
 | 
			
		||||
        public ulong AuthorId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public ShopEntryType Type { get; set; }
 | 
			
		||||
 | 
			
		||||
        //role
 | 
			
		||||
        public string RoleName { get; set; }
 | 
			
		||||
        public ulong RoleId { get; set; }
 | 
			
		||||
 | 
			
		||||
        //list
 | 
			
		||||
        public HashSet<ShopEntryItem> Items { get; set; } = new HashSet<ShopEntryItem>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ShopEntryItem : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public string Text { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            if (obj == null || GetType() != obj.GetType())
 | 
			
		||||
            {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            return ((ShopEntryItem)obj).Text == Text;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode() =>
 | 
			
		||||
            Text.GetHashCode(StringComparison.InvariantCulture);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class SlowmodeIgnoredRole : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong RoleId { get; set; }
 | 
			
		||||
 | 
			
		||||
        // override object.Equals
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            if (obj == null || GetType() != obj.GetType())
 | 
			
		||||
            {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return ((SlowmodeIgnoredRole)obj).RoleId == RoleId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // override object.GetHashCode
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return RoleId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class SlowmodeIgnoredUser : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
 | 
			
		||||
        // override object.Equals
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            if (obj == null || GetType() != obj.GetType())
 | 
			
		||||
            {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return ((SlowmodeIgnoredUser)obj).UserId == UserId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // override object.GetHashCode
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return UserId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Used to set stakes for gambling games which don't reward right away -
 | 
			
		||||
    /// like blackjack. If the bot is restarted mid game, users will get their funds back
 | 
			
		||||
    /// when the bot is back up.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class Stake : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public long Amount { get; set; }
 | 
			
		||||
        public string Source { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,78 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class StreamRoleSettings : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int GuildConfigId { get; set; }
 | 
			
		||||
        public GuildConfig GuildConfig { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Whether the feature is enabled in the guild.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool Enabled { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Id of the role to give to the users in the role 'FromRole' when they start streaming
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ulong AddRoleId { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Id of the role whose users are eligible to get the 'AddRole'
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ulong FromRoleId { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If set, feature will only apply to users who have this keyword in their streaming status.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string Keyword { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// A collection of whitelisted users' IDs. Whitelisted users don't require 'keyword' in
 | 
			
		||||
        /// order to get the stream role.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public HashSet<StreamRoleWhitelistedUser> Whitelist { get; set; } = new HashSet<StreamRoleWhitelistedUser>();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// A collection of blacklisted users' IDs. Blacklisted useres will never get the stream role.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public HashSet<StreamRoleBlacklistedUser> Blacklist { get; set; } = new HashSet<StreamRoleBlacklistedUser>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class StreamRoleBlacklistedUser : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public string Username { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            if (!(obj is StreamRoleBlacklistedUser x))
 | 
			
		||||
                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)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is StreamRoleWhitelistedUser x
 | 
			
		||||
                ? x.UserId == UserId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return UserId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class UnbanTimer : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public DateTime UnbanAt { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode() =>
 | 
			
		||||
            UserId.GetHashCode();
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is UnbanTimer ut
 | 
			
		||||
                ? ut.UserId == UserId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class UnmuteTimer : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public DateTime UnmuteAt { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode() =>
 | 
			
		||||
            UserId.GetHashCode();
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is UnmuteTimer ut
 | 
			
		||||
                ? ut.UserId == UserId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class UnroleTimer : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public ulong RoleId { get; set; }
 | 
			
		||||
        public DateTime UnbanAt { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode() =>
 | 
			
		||||
            UserId.GetHashCode() ^ RoleId.GetHashCode();
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is UnroleTimer ut
 | 
			
		||||
                ? ut.UserId == UserId && ut.RoleId == RoleId
 | 
			
		||||
                : false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class UserXpStats : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
        public int Xp { get; set; }
 | 
			
		||||
        public int AwardedXp { get; set; }
 | 
			
		||||
        public XpNotificationLocation NotifyOnLevelUp { get; set; }
 | 
			
		||||
        public DateTime LastLevelUp { get; set; } = DateTime.UtcNow;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum XpNotificationLocation { None, Dm, Channel }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class VcRoleInfo : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong VoiceChannelId { get; set; }
 | 
			
		||||
        public ulong RoleId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,90 +0,0 @@
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using NadekoBot.Modules.Gambling.Common;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class WaifuInfo : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int WaifuId { get; set; }
 | 
			
		||||
        public DiscordUser Waifu { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int? ClaimerId { get; set; }
 | 
			
		||||
        public DiscordUser Claimer { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int? AffinityId { get; set; }
 | 
			
		||||
        public DiscordUser Affinity { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int Price { get; set; }
 | 
			
		||||
        public List<WaifuItem> Items { get; set; } = new List<WaifuItem>();
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            var claimer = "no one";
 | 
			
		||||
            var status = "";
 | 
			
		||||
 | 
			
		||||
            var waifuUsername = Waifu.Username.TrimTo(20);
 | 
			
		||||
            var claimerUsername = Claimer?.Username.TrimTo(20);
 | 
			
		||||
 | 
			
		||||
            if (ClaimerId != null)
 | 
			
		||||
            {
 | 
			
		||||
                claimer = $"{ claimerUsername }#{Claimer.Discriminator}";
 | 
			
		||||
            }
 | 
			
		||||
            if (AffinityId == null)
 | 
			
		||||
            {
 | 
			
		||||
                status = $"... but {waifuUsername}'s heart is empty";
 | 
			
		||||
            }
 | 
			
		||||
            else if (AffinityId == ClaimerId)
 | 
			
		||||
            {
 | 
			
		||||
                status = $"... and {waifuUsername} likes {claimerUsername} too <3";
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                status = $"... but {waifuUsername}'s heart belongs to {Affinity.Username.TrimTo(20)}#{Affinity.Discriminator}";
 | 
			
		||||
            }
 | 
			
		||||
            return $"**{waifuUsername}#{Waifu.Discriminator}** - claimed by **{claimer}**\n\t{status}";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class WaifuLbResult
 | 
			
		||||
    {
 | 
			
		||||
        public string Username { get; set; }
 | 
			
		||||
        public string Discrim { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string Claimer { get; set; }
 | 
			
		||||
        public string ClaimerDiscrim { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string Affinity { get; set; }
 | 
			
		||||
        public string AffinityDiscrim { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int Price { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            var claimer = "no one";
 | 
			
		||||
            var status = "";
 | 
			
		||||
 | 
			
		||||
            var waifuUsername = Username.TrimTo(20);
 | 
			
		||||
            var claimerUsername = Claimer?.TrimTo(20);
 | 
			
		||||
 | 
			
		||||
            if (Claimer != null)
 | 
			
		||||
            {
 | 
			
		||||
                claimer = $"{ claimerUsername }#{ClaimerDiscrim}";
 | 
			
		||||
            }
 | 
			
		||||
            if (Affinity == null)
 | 
			
		||||
            {
 | 
			
		||||
                status = $"... but {waifuUsername}'s heart is empty";
 | 
			
		||||
            }
 | 
			
		||||
            else if (Affinity + AffinityDiscrim == Claimer + ClaimerDiscrim)
 | 
			
		||||
            {
 | 
			
		||||
                status = $"... and {waifuUsername} likes {claimerUsername} too <3";
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                status = $"... but {waifuUsername}'s heart belongs to {Affinity.TrimTo(20)}#{AffinityDiscrim}";
 | 
			
		||||
            }
 | 
			
		||||
            return $"**{waifuUsername}#{Discrim}** - claimed by **{claimer}**\n\t{status}";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class WaifuItem : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int? WaifuInfoId { get; set; }
 | 
			
		||||
        public string ItemEmoji { get; set; }
 | 
			
		||||
        public string Name { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        [Obsolete]
 | 
			
		||||
        public int Price { get; set; }
 | 
			
		||||
        [Obsolete]
 | 
			
		||||
        public int Item { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class WaifuUpdate : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int UserId { get; set; }
 | 
			
		||||
        public DiscordUser User { get; set; }
 | 
			
		||||
        public WaifuUpdateType UpdateType { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int? OldId { get; set; }
 | 
			
		||||
        public DiscordUser Old { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int? NewId { get; set; }
 | 
			
		||||
        public DiscordUser New { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum WaifuUpdateType
 | 
			
		||||
    {
 | 
			
		||||
        AffinityChanged,
 | 
			
		||||
        Claimed
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public enum WarnExpireAction
 | 
			
		||||
    {
 | 
			
		||||
        Clear,
 | 
			
		||||
        Delete
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class Warning : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong GuildId { get; set; }
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public string Reason { get; set; }
 | 
			
		||||
        public bool Forgiven { get; set; }
 | 
			
		||||
        public string ForgivenBy { get; set; }
 | 
			
		||||
        public string Moderator { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class WarningPunishment : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int Count { get; set; }
 | 
			
		||||
        public PunishmentAction Punishment { get; set; }
 | 
			
		||||
        public int Time { get; set; }
 | 
			
		||||
        public ulong? RoleId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,78 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class XpSettings : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int GuildConfigId { get; set; }
 | 
			
		||||
        public GuildConfig GuildConfig { get; set; }
 | 
			
		||||
 | 
			
		||||
        public HashSet<XpRoleReward> RoleRewards { get; set; } = new HashSet<XpRoleReward>();
 | 
			
		||||
        public HashSet<XpCurrencyReward> CurrencyRewards { get; set; } = new HashSet<XpCurrencyReward>();
 | 
			
		||||
        public bool XpRoleRewardExclusive { get; set; }
 | 
			
		||||
        public string NotifyMessage { get; set; } = "Congratulations {0}! You have reached level {1}!";
 | 
			
		||||
        public HashSet<ExcludedItem> ExclusionList { get; set; } = new HashSet<ExcludedItem>();
 | 
			
		||||
        public bool ServerExcluded { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum ExcludedItemType { Channel, Role }
 | 
			
		||||
 | 
			
		||||
    public class XpRoleReward : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int XpSettingsId { get; set; }
 | 
			
		||||
        public XpSettings XpSettings { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int Level { get; set; }
 | 
			
		||||
        public ulong RoleId { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Whether the role should be removed (true) or added (false)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool Remove { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return Level.GetHashCode() ^ XpSettingsId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is XpRoleReward xrr && xrr.Level == Level && xrr.XpSettingsId == XpSettingsId;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class XpCurrencyReward : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int XpSettingsId { get; set; }
 | 
			
		||||
        public XpSettings XpSettings { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int Level { get; set; }
 | 
			
		||||
        public int Amount { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return Level.GetHashCode() ^ XpSettingsId.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is XpCurrencyReward xrr && xrr.Level == Level && xrr.XpSettingsId == XpSettingsId;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ExcludedItem : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong ItemId { get; set; }
 | 
			
		||||
        public ExcludedItemType ItemType { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return ItemId.GetHashCode() ^ ItemType.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            return obj is ExcludedItem ei && ei.ItemId == ItemId && ei.ItemType == ItemType;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Core.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class YtFollowedChannel : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong ChannelId { get; set; }
 | 
			
		||||
        public string YtChannelId { get; set; }
 | 
			
		||||
        public string UploadMessage { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,332 +0,0 @@
 | 
			
		||||
using Microsoft.Data.Sqlite;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Design;
 | 
			
		||||
using NadekoBot.Core.Services.Database.Models;
 | 
			
		||||
using NadekoBot.Core.Services.Impl;
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Database
 | 
			
		||||
{
 | 
			
		||||
    public class NadekoContextFactory : IDesignTimeDbContextFactory<NadekoContext>
 | 
			
		||||
    {
 | 
			
		||||
        public NadekoContext CreateDbContext(string[] args)
 | 
			
		||||
        {
 | 
			
		||||
            LogSetup.SetupLogger(-2);
 | 
			
		||||
            var optionsBuilder = new DbContextOptionsBuilder<NadekoContext>();
 | 
			
		||||
            IBotCredentials creds = new BotCredentials();
 | 
			
		||||
            var builder = new SqliteConnectionStringBuilder(creds.Db.ConnectionString);
 | 
			
		||||
            builder.DataSource = Path.Combine(AppContext.BaseDirectory, builder.DataSource);
 | 
			
		||||
            optionsBuilder.UseSqlite(builder.ToString());
 | 
			
		||||
            var ctx = new NadekoContext(optionsBuilder.Options);
 | 
			
		||||
            ctx.Database.SetCommandTimeout(60);
 | 
			
		||||
            return ctx;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class NadekoContext : DbContext
 | 
			
		||||
    {
 | 
			
		||||
        public DbSet<GuildConfig> GuildConfigs { get; set; }
 | 
			
		||||
 | 
			
		||||
        public DbSet<Quote> Quotes { get; set; }
 | 
			
		||||
        public DbSet<Reminder> Reminders { get; set; }
 | 
			
		||||
        public DbSet<SelfAssignedRole> SelfAssignableRoles { get; set; }
 | 
			
		||||
        public DbSet<MusicPlaylist> MusicPlaylists { get; set; }
 | 
			
		||||
        public DbSet<CustomReaction> CustomReactions { get; set; }
 | 
			
		||||
        public DbSet<CurrencyTransaction> CurrencyTransactions { get; set; }
 | 
			
		||||
        public DbSet<WaifuUpdate> WaifuUpdates { get; set; }
 | 
			
		||||
        public DbSet<Warning> Warnings { get; set; }
 | 
			
		||||
        public DbSet<UserXpStats> UserXpStats { get; set; }
 | 
			
		||||
        public DbSet<ClubInfo> Clubs { get; set; }
 | 
			
		||||
 | 
			
		||||
        //logging
 | 
			
		||||
        public DbSet<LogSetting> LogSettings { get; set; }
 | 
			
		||||
        public DbSet<IgnoredLogChannel> IgnoredLogChannels { get; set; }
 | 
			
		||||
        public DbSet<IgnoredVoicePresenceChannel> IgnoredVoicePresenceCHannels { get; set; }
 | 
			
		||||
 | 
			
		||||
        public DbSet<RotatingPlayingStatus> RotatingStatus { get; set; }
 | 
			
		||||
        public DbSet<BlacklistEntry> Blacklist { get; set; }
 | 
			
		||||
        public DbSet<AutoCommand> AutoCommands { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        public DbSet<RewardedUser> RewardedUsers { get; set; }
 | 
			
		||||
        public DbSet<Stake> Stakes { get; set; }
 | 
			
		||||
        public DbSet<PlantedCurrency> PlantedCurrency { get; set; }
 | 
			
		||||
        public DbSet<BanTemplate> BanTemplates { get; set; }
 | 
			
		||||
        public DbSet<DiscordPermOverride> DiscordPermOverrides { get; set; }
 | 
			
		||||
        public DbSet<DiscordUser> DiscordUser { get; set; }
 | 
			
		||||
        public DbSet<MusicPlayerSettings> MusicPlayerSettings { get; set; }
 | 
			
		||||
        public DbSet<Repeater> Repeaters { get; set; }
 | 
			
		||||
        public DbSet<Poll> Poll { get; set; }
 | 
			
		||||
        public DbSet<WaifuInfo> WaifuInfo { get; set; }
 | 
			
		||||
 | 
			
		||||
        public NadekoContext(DbContextOptions<NadekoContext> options) : base(options)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
#if DEBUG
 | 
			
		||||
        public static readonly LoggerFactory _debugLoggerFactory = 
 | 
			
		||||
            new LoggerFactory(new[] { 
 | 
			
		||||
                new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() 
 | 
			
		||||
            });
 | 
			
		||||
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
 | 
			
		||||
        {      
 | 
			
		||||
            optionsBuilder.UseLoggerFactory(_debugLoggerFactory);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        protected override void OnModelCreating(ModelBuilder modelBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            #region QUOTES
 | 
			
		||||
 | 
			
		||||
            var quoteEntity = modelBuilder.Entity<Quote>();
 | 
			
		||||
            quoteEntity.HasIndex(x => x.GuildId);
 | 
			
		||||
            quoteEntity.HasIndex(x => x.Keyword);
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region GuildConfig
 | 
			
		||||
 | 
			
		||||
            var configEntity = modelBuilder.Entity<GuildConfig>();
 | 
			
		||||
            configEntity
 | 
			
		||||
                .HasIndex(c => c.GuildId)
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<AntiSpamSetting>()
 | 
			
		||||
                .HasOne(x => x.GuildConfig)
 | 
			
		||||
                .WithOne(x => x.AntiSpamSetting);
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<AntiRaidSetting>()
 | 
			
		||||
                .HasOne(x => x.GuildConfig)
 | 
			
		||||
                .WithOne(x => x.AntiRaidSetting);
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<GuildConfig>()
 | 
			
		||||
                .HasOne(x => x.AntiAltSetting)
 | 
			
		||||
                .WithOne()
 | 
			
		||||
                .HasForeignKey<AntiAltSetting>(x => x.GuildConfigId)
 | 
			
		||||
                .OnDelete(DeleteBehavior.Cascade);
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<FeedSub>()
 | 
			
		||||
                .HasAlternateKey(x => new { x.GuildConfigId, x.Url });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<PlantedCurrency>()
 | 
			
		||||
                .HasIndex(x => x.MessageId)
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<PlantedCurrency>()
 | 
			
		||||
                .HasIndex(x => x.ChannelId);
 | 
			
		||||
 | 
			
		||||
            configEntity.HasIndex(x => x.WarnExpireHours)
 | 
			
		||||
                .IsUnique(false);
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region streamrole
 | 
			
		||||
            modelBuilder.Entity<StreamRoleSettings>()
 | 
			
		||||
                .HasOne(x => x.GuildConfig)
 | 
			
		||||
                .WithOne(x => x.StreamRole);
 | 
			
		||||
            #endregion
 | 
			
		||||
            
 | 
			
		||||
            #region Self Assignable Roles
 | 
			
		||||
 | 
			
		||||
            var selfassignableRolesEntity = modelBuilder.Entity<SelfAssignedRole>();
 | 
			
		||||
 | 
			
		||||
            selfassignableRolesEntity
 | 
			
		||||
                .HasIndex(s => new { s.GuildId, s.RoleId })
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
 | 
			
		||||
            selfassignableRolesEntity
 | 
			
		||||
                .Property(x => x.Group)
 | 
			
		||||
                .HasDefaultValue(0);
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region Permission
 | 
			
		||||
            var permissionEntity = modelBuilder.Entity<Permission>();
 | 
			
		||||
            permissionEntity
 | 
			
		||||
                .HasOne(p => p.Next)
 | 
			
		||||
                .WithOne(p => p.Previous)
 | 
			
		||||
                .IsRequired(false);
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region MusicPlaylists
 | 
			
		||||
            var musicPlaylistEntity = modelBuilder.Entity<MusicPlaylist>();
 | 
			
		||||
 | 
			
		||||
            musicPlaylistEntity
 | 
			
		||||
                .HasMany(p => p.Songs)
 | 
			
		||||
                .WithOne()
 | 
			
		||||
                .OnDelete(DeleteBehavior.Cascade);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region Waifus
 | 
			
		||||
 | 
			
		||||
            var wi = modelBuilder.Entity<WaifuInfo>();
 | 
			
		||||
            wi.HasOne(x => x.Waifu)
 | 
			
		||||
                .WithOne();
 | 
			
		||||
 | 
			
		||||
            wi.HasIndex(x => x.Price);
 | 
			
		||||
            wi.HasIndex(x => x.ClaimerId);
 | 
			
		||||
            // wi.HasMany(x => x.Items)
 | 
			
		||||
            //     .WithOne()
 | 
			
		||||
            //     .OnDelete(DeleteBehavior.Cascade);
 | 
			
		||||
 | 
			
		||||
            var wu = modelBuilder.Entity<WaifuUpdate>();
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region DiscordUser
 | 
			
		||||
 | 
			
		||||
            var du = modelBuilder.Entity<DiscordUser>();
 | 
			
		||||
            du.HasAlternateKey(w => w.UserId);
 | 
			
		||||
            du.HasOne(x => x.Club)
 | 
			
		||||
               .WithMany(x => x.Users)
 | 
			
		||||
               .IsRequired(false);
 | 
			
		||||
 | 
			
		||||
            du.Property(x => x.LastLevelUp)
 | 
			
		||||
                .HasDefaultValue(new DateTime(2017, 9, 21, 20, 53, 13, 305, DateTimeKind.Local));
 | 
			
		||||
 | 
			
		||||
            du.HasIndex(x => x.TotalXp);
 | 
			
		||||
            du.HasIndex(x => x.CurrencyAmount);
 | 
			
		||||
            du.HasIndex(x => x.UserId);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region Warnings
 | 
			
		||||
            var warn = modelBuilder.Entity<Warning>();
 | 
			
		||||
            warn.HasIndex(x => x.GuildId);
 | 
			
		||||
            warn.HasIndex(x => x.UserId);
 | 
			
		||||
            warn.HasIndex(x => x.DateAdded);
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region PatreonRewards
 | 
			
		||||
            var pr = modelBuilder.Entity<RewardedUser>();
 | 
			
		||||
            pr.HasIndex(x => x.PatreonUserId)
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region XpStats
 | 
			
		||||
            var xps = modelBuilder.Entity<UserXpStats>();
 | 
			
		||||
            xps
 | 
			
		||||
                .HasIndex(x => new { x.UserId, x.GuildId })
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
 | 
			
		||||
            xps
 | 
			
		||||
                .Property(x => x.LastLevelUp)
 | 
			
		||||
                .HasDefaultValue(new DateTime(2017, 9, 21, 20, 53, 13, 307, DateTimeKind.Local));
 | 
			
		||||
 | 
			
		||||
            xps.HasIndex(x => x.UserId);
 | 
			
		||||
            xps.HasIndex(x => x.GuildId);
 | 
			
		||||
            xps.HasIndex(x => x.Xp);
 | 
			
		||||
            xps.HasIndex(x => x.AwardedXp);
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region XpSettings
 | 
			
		||||
            modelBuilder.Entity<XpSettings>()
 | 
			
		||||
                .HasOne(x => x.GuildConfig)
 | 
			
		||||
                .WithOne(x => x.XpSettings);
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region XpRoleReward
 | 
			
		||||
            modelBuilder.Entity<XpRoleReward>()
 | 
			
		||||
                .HasIndex(x => new { x.XpSettingsId, x.Level })
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region Club
 | 
			
		||||
            var ci = modelBuilder.Entity<ClubInfo>();
 | 
			
		||||
            ci.HasOne(x => x.Owner)
 | 
			
		||||
              .WithOne()
 | 
			
		||||
              .HasForeignKey<ClubInfo>(x => x.OwnerId);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            ci.HasAlternateKey(x => new { x.Name, x.Discrim });
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region ClubManytoMany
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<ClubApplicants>()
 | 
			
		||||
                .HasKey(t => new { t.ClubId, t.UserId });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<ClubApplicants>()
 | 
			
		||||
                .HasOne(pt => pt.User)
 | 
			
		||||
                .WithMany();
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<ClubApplicants>()
 | 
			
		||||
                .HasOne(pt => pt.Club)
 | 
			
		||||
                .WithMany(x => x.Applicants);
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<ClubBans>()
 | 
			
		||||
                .HasKey(t => new { t.ClubId, t.UserId });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<ClubBans>()
 | 
			
		||||
                .HasOne(pt => pt.User)
 | 
			
		||||
                .WithMany();
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<ClubBans>()
 | 
			
		||||
                .HasOne(pt => pt.Club)
 | 
			
		||||
                .WithMany(x => x.Bans);
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region Polls
 | 
			
		||||
            modelBuilder.Entity<Poll>()
 | 
			
		||||
                .HasIndex(x => x.GuildId)
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region CurrencyTransactions
 | 
			
		||||
            modelBuilder.Entity<CurrencyTransaction>()
 | 
			
		||||
                .HasIndex(x => x.UserId)
 | 
			
		||||
                .IsUnique(false);
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region Reminders
 | 
			
		||||
            modelBuilder.Entity<Reminder>()
 | 
			
		||||
                .HasIndex(x => x.When);
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region  GroupName
 | 
			
		||||
            modelBuilder.Entity<GroupName>()
 | 
			
		||||
                .HasIndex(x => new { x.GuildConfigId, x.Number })
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<GroupName>()
 | 
			
		||||
                .HasOne(x => x.GuildConfig)
 | 
			
		||||
                .WithMany(x => x.SelfAssignableRoleGroupNames)
 | 
			
		||||
                .IsRequired();
 | 
			
		||||
            #endregion
 | 
			
		||||
            
 | 
			
		||||
            #region BanTemplate
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<BanTemplate>()
 | 
			
		||||
                .HasIndex(x => x.GuildId)
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
            
 | 
			
		||||
            #region Perm Override
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<DiscordPermOverride>()
 | 
			
		||||
                .HasIndex(x => new {x.GuildId, x.Command})
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
            
 | 
			
		||||
            #region Music
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<MusicPlayerSettings>()
 | 
			
		||||
                .HasIndex(x => x.GuildId)
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity<MusicPlayerSettings>()
 | 
			
		||||
                .Property(x => x.Volume)
 | 
			
		||||
                .HasDefaultValue(100);
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -4,7 +4,7 @@ using NadekoBot.Core.Services.Database;
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using NadekoBot.Db;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using NadekoBot.Db;
 | 
			
		||||
using NadekoBot.Modules.Administration;
 | 
			
		||||
using Serilog;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using NadekoBot.Db;
 | 
			
		||||
using NadekoBot.Modules.Gambling.Services;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ using Discord;
 | 
			
		||||
using NadekoBot.Common;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using NadekoBot.Db;
 | 
			
		||||
using NadekoBot.Modules.Administration;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Core.Services.Impl
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@ using LinqToDB.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Common.ModuleBehaviors;
 | 
			
		||||
using NadekoBot.Core.Common;
 | 
			
		||||
using NadekoBot.Core.Common.Configs;
 | 
			
		||||
using NadekoBot.Db;
 | 
			
		||||
using NadekoBot.Modules.Administration;
 | 
			
		||||
using NadekoBot.Modules.Gambling.Services;
 | 
			
		||||
using NadekoBot.Modules.Administration.Services;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user