- 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:
Kwoth
2021-06-19 06:08:09 +02:00
parent c127dcd1e3
commit d42705087e
141 changed files with 104 additions and 102 deletions

View File

@@ -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;

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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));
}
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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; }
}
}

View File

@@ -1,8 +0,0 @@
namespace NadekoBot.Core.Services.Database.Models
{
public class BanTemplate : DbEntity
{
public ulong GuildId { get; set; }
public string Text { get; set; }
}
}

View File

@@ -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
}
}

View File

@@ -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; }
}
}

View File

@@ -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();
//}
}
}

View File

@@ -1,8 +0,0 @@
namespace NadekoBot.Core.Services.Database.Models
{
public class CommandCooldown : DbEntity
{
public int Seconds { get; set; }
public string CommandName { get; set; }
}
}

View File

@@ -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,
};
}
}

View File

@@ -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; }
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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;
}
}

View File

@@ -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
{
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -1,7 +0,0 @@
namespace NadekoBot.Core.Services.Database.Models
{
public class FilteredWord : DbEntity
{
public string Word { get; set; }
}
}

View File

@@ -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());
}
}

View File

@@ -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();
}
}

View File

@@ -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; }
}
}

View File

@@ -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;
}
}

View File

@@ -1,8 +0,0 @@
namespace NadekoBot.Core.Services.Database.Models
{
public class IgnoredLogChannel : DbEntity
{
public LogSetting LogSetting { get; set; }
public ulong ChannelId { get; set; }
}
}

View File

@@ -1,8 +0,0 @@
namespace NadekoBot.Core.Services.Database.Models
{
public class IgnoredVoicePresenceChannel : DbEntity
{
public LogSetting LogSetting { get; set; }
public ulong ChannelId { get; set; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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>();
}
}

View File

@@ -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
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
}
}

View File

@@ -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; }
}
}

View File

@@ -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
}
}

View File

@@ -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; }
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 }
}

View File

@@ -1,8 +0,0 @@
namespace NadekoBot.Core.Services.Database.Models
{
public class VcRoleInfo : DbEntity
{
public ulong VoiceChannelId { get; set; }
public ulong RoleId { get; set; }
}
}

View File

@@ -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}";
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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
}
}

View File

@@ -1,8 +0,0 @@
namespace NadekoBot.Core.Services.Database.Models
{
public enum WarnExpireAction
{
Clear,
Delete
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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;
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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
}
}
}

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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;