Split dangerous commands into cleanup commands for each module they belong to

This commit is contained in:
Kwoth
2023-07-15 13:39:46 +00:00
parent 842a8a2f71
commit 8f62a46016
91 changed files with 616 additions and 501 deletions

View File

@@ -0,0 +1,25 @@
#nullable disable
namespace NadekoBot.Common;
public abstract class CleanupModuleBase : NadekoModule
{
protected async Task ConfirmActionInternalAsync(string name, Func<Task> action)
{
try
{
var embed = _eb.Create()
.WithTitle(GetText(strs.sql_confirm_exec))
.WithDescription(name);
if (!await PromptUserConfirmAsync(embed))
return;
await action();
await ctx.OkAsync();
}
catch (Exception ex)
{
await SendErrorAsync(ex.ToString());
}
}
}

View File

@@ -1,4 +1,5 @@
using NadekoBot.Db;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Db;
using NadekoBot.Db.Models;
// todo fix these namespaces. It should only be Nadeko.Bot.Db
using NadekoBot.Services.Database;
@@ -7,6 +8,6 @@ namespace NadekoBot.Extensions;
public static class DbExtensions
{
public static DiscordUser GetOrCreateUser(this NadekoBaseContext ctx, IUser original, Func<IQueryable<DiscordUser>, IQueryable<DiscordUser>>? includes = null)
public static DiscordUser GetOrCreateUser(this DbContext ctx, IUser original, Func<IQueryable<DiscordUser>, IQueryable<DiscordUser>>? includes = null)
=> ctx.GetOrCreateUser(original.Id, original.Username, original.Discriminator, original.AvatarId, includes);
}

View File

@@ -49,8 +49,10 @@ public abstract class NadekoModule : ModuleBase
//
public Task<IUserMessage> SendErrorAsync(string text, NadekoInteraction inter = null)
=> ctx.Channel.SendAsync(_eb, text, MsgType.Error, inter);
public Task<IUserMessage> SendConfirmAsync(string text, NadekoInteraction inter = null)
=> ctx.Channel.SendAsync(_eb, text, MsgType.Ok, inter);
public Task<IUserMessage> SendPendingAsync(string text, NadekoInteraction inter = null)
=> ctx.Channel.SendAsync(_eb, text, MsgType.Pending, inter);

View File

@@ -29,7 +29,7 @@ public static class GuildConfigExtensions
/// <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 NadekoBaseContext ctx, ulong guildId)
public static StreamRoleSettings GetStreamRoleSettings(this DbContext ctx, ulong guildId)
{
var conf = ctx.GuildConfigsForId(guildId,
set => set.Include(y => y.StreamRole)
@@ -120,7 +120,7 @@ public static class GuildConfigExtensions
// .First(x => x.GuildId == guildId);
}
public static LogSetting LogSettingsFor(this NadekoBaseContext ctx, ulong guildId)
public static LogSetting LogSettingsFor(this DbContext ctx, ulong guildId)
{
var logSetting = ctx.Set<LogSetting>()
.AsQueryable()
@@ -148,7 +148,7 @@ public static class GuildConfigExtensions
return query.ToList();
}
public static GuildConfig GcWithPermissionsFor(this NadekoBaseContext ctx, ulong guildId)
public static GuildConfig GcWithPermissionsFor(this DbContext ctx, ulong guildId)
{
var config = ctx.Set<GuildConfig>().AsQueryable()
.Where(gc => gc.GuildId == guildId)

View File

@@ -1,67 +0,0 @@
#nullable disable
namespace NadekoBot.Services.Database.Models;
// todo db required, nullable?
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; }
public ulong? RoleId { get; set; }
public HashSet<AntiSpamIgnore> IgnoredChannels { get; set; } = new();
}
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,
Warn,
TimeOut
}
public class AntiSpamIgnore : DbEntity
{
public ulong ChannelId { get; set; }
public override int GetHashCode()
=> ChannelId.GetHashCode();
public override bool Equals(object obj)
=> obj is AntiSpamIgnore inst ? inst.ChannelId == ChannelId : false;
}

View File

@@ -0,0 +1,15 @@
namespace NadekoBot.Services.Database.Models;
public enum PunishmentAction
{
Mute,
Kick,
Ban,
Softban,
RemoveRoles,
ChatMute,
VoiceMute,
AddRole,
Warn,
TimeOut
}

View File

@@ -0,0 +1,11 @@
namespace NadekoBot.Services.Database.Models;
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; }
}

View File

@@ -0,0 +1,20 @@
#nullable disable
namespace NadekoBot.Services.Database.Models;
// todo db required, nullable?
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; }
}

View File

@@ -0,0 +1,12 @@
namespace NadekoBot.Services.Database.Models;
public class AntiSpamIgnore : DbEntity
{
public ulong ChannelId { get; set; }
public override int GetHashCode()
=> ChannelId.GetHashCode();
public override bool Equals(object obj)
=> obj is AntiSpamIgnore inst ? inst.ChannelId == ChannelId : false;
}

View File

@@ -0,0 +1,13 @@
namespace NadekoBot.Services.Database.Models;
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; }
public ulong? RoleId { get; set; }
public HashSet<AntiSpamIgnore> IgnoredChannels { get; set; } = new();
}

View File

@@ -118,7 +118,7 @@ public sealed class AutoAssignRoleService : INService
{
await using var uow = _db.GetDbContext();
await uow.GuildConfigs.AsNoTracking()
await uow.Set<GuildConfig>().AsNoTracking()
.Where(x => x.GuildId == guildId)
.UpdateAsync(_ => new()
{

View File

@@ -10,26 +10,6 @@ namespace NadekoBot.Modules.Administration
[OwnerOnly]
public partial class DangerousCommands : NadekoModule<DangerousCommandsService>
{
private async Task ConfirmActionInternalAsync(string name, Func<Task> action)
{
try
{
var embed = _eb.Create()
.WithTitle(GetText(strs.sql_confirm_exec))
.WithDescription(name);
if (!await PromptUserConfirmAsync(embed))
return;
await action();
await ctx.OkAsync();
}
catch (Exception ex)
{
await SendErrorAsync(ex.ToString());
}
}
[Cmd]
[OwnerOnly]
public Task SqlSelect([Leftover] string sql)
@@ -76,36 +56,6 @@ namespace NadekoBot.Modules.Administration
}
}
[Cmd]
[OwnerOnly]
public Task DeleteWaifus()
=> ConfirmActionInternalAsync("Delete Waifus", () => _service.DeleteWaifus());
[Cmd]
[OwnerOnly]
public async Task DeleteWaifu(IUser user)
=> await DeleteWaifu(user.Id);
[Cmd]
[OwnerOnly]
public Task DeleteWaifu(ulong userId)
=> ConfirmActionInternalAsync($"Delete Waifu {userId}", () => _service.DeleteWaifu(userId));
[Cmd]
[OwnerOnly]
public Task DeleteCurrency()
=> ConfirmActionInternalAsync("Delete Currency", () => _service.DeleteCurrency());
[Cmd]
[OwnerOnly]
public Task DeletePlaylists()
=> ConfirmActionInternalAsync("Delete Playlists", () => _service.DeletePlaylists());
[Cmd]
[OwnerOnly]
public Task DeleteXp()
=> ConfirmActionInternalAsync("Delete Xp", () => _service.DeleteXp());
[Cmd]
[OwnerOnly]
public async Task PurgeUser(ulong userId)

View File

@@ -14,74 +14,6 @@ public class DangerousCommandsService : INService
public DangerousCommandsService(DbService db)
=> _db = db;
public async Task DeleteXp()
{
await using var ctx = _db.GetDbContext();
await ctx.DiscordUser.UpdateAsync(_ => new DiscordUser()
{
ClubId = null,
// IsClubAdmin = false,
TotalXp = 0
});
await ctx.UserXpStats.DeleteAsync();
await ctx.ClubApplicants.DeleteAsync();
await ctx.ClubBans.DeleteAsync();
await ctx.Clubs.DeleteAsync();
await ctx.SaveChangesAsync();
}
public async Task DeleteWaifus()
{
await using var ctx = _db.GetDbContext();
await ctx.WaifuUpdates.DeleteAsync();
await ctx.WaifuItem.DeleteAsync();
await ctx.WaifuInfo.DeleteAsync();
await ctx.SaveChangesAsync();
}
public async Task DeleteWaifu(ulong userId)
{
await using var ctx = _db.GetDbContext();
await ctx.WaifuUpdates
.Where(x => x.User.UserId == userId)
.DeleteAsync();
await ctx.WaifuItem
.Where(x => x.WaifuInfo.Waifu.UserId == userId)
.DeleteAsync();
await ctx.WaifuInfo
.Where(x => x.Claimer.UserId == userId)
.UpdateAsync(old => new WaifuInfo()
{
ClaimerId = null,
});
await ctx.WaifuInfo
.Where(x => x.Waifu.UserId == userId)
.DeleteAsync();
await ctx.SaveChangesAsync();
}
public async Task DeletePlaylists()
{
await using var ctx = _db.GetDbContext();
await ctx.MusicPlaylists.DeleteAsync();
await ctx.SaveChangesAsync();
}
public async Task DeleteCurrency()
{
await using var ctx = _db.GetDbContext();
await ctx.DiscordUser.UpdateAsync(_ => new DiscordUser()
{
CurrencyAmount = 0
});
await ctx.CurrencyTransactions.DeleteAsync();
await ctx.PlantedCurrency.DeleteAsync();
await ctx.BankUsers.DeleteAsync();
await ctx.SaveChangesAsync();
}
public async Task<int> ExecuteSql(string sql)
{
int res;
@@ -130,7 +62,7 @@ public class DangerousCommandsService : INService
if (wi is not null)
{
// remove updates which have new or old as this waifu
await uow.WaifuUpdates.DeleteAsync(wu => wu.New.UserId == userId || wu.Old.UserId == userId);
await uow.Set<WaifuUpdate>().DeleteAsync(wu => wu.New.UserId == userId || wu.Old.UserId == userId);
// delete all items this waifu owns
await uow.Set<WaifuItem>().DeleteAsync(x => x.WaifuInfoId == wi.Id);
@@ -155,13 +87,13 @@ public class DangerousCommandsService : INService
}
// delete guild xp
await uow.UserXpStats.DeleteAsync(x => x.UserId == userId);
await uow.Set<UserXpStats>().DeleteAsync(x => x.UserId == userId);
// delete currency transactions
await uow.Set<CurrencyTransaction>().DeleteAsync(x => x.UserId == userId);
// delete user, currency, and clubs go away with it
await uow.DiscordUser.DeleteAsync(u => u.UserId == userId);
await uow.Set<DiscordUser>().DeleteAsync(u => u.UserId == userId);
}
public class SelectResult

View File

@@ -33,14 +33,14 @@ public sealed class SomethingOnlyChannelService : IExecOnMessage
_db = db;
using var uow = _db.GetDbContext();
_imageOnly = uow.ImageOnlyChannels
_imageOnly = uow.Set<ImageOnlyChannel>()
.Where(x => x.Type == OnlyChannelType.Image)
.ToList()
.GroupBy(x => x.GuildId)
.ToDictionary(x => x.Key, x => new ConcurrentHashSet<ulong>(x.Select(y => y.ChannelId)))
.ToConcurrent();
_linkOnly = uow.ImageOnlyChannels
_linkOnly = uow.Set<ImageOnlyChannel>()
.Where(x => x.Type == OnlyChannelType.Link)
.ToList()
.GroupBy(x => x.GuildId)
@@ -85,12 +85,12 @@ public sealed class SomethingOnlyChannelService : IExecOnMessage
await using var uow = _db.GetDbContext();
if (forceDisable || (_imageOnly.TryGetValue(guildId, out var channels) && channels.TryRemove(channelId)))
{
await uow.ImageOnlyChannels.DeleteAsync(x => x.ChannelId == channelId && x.Type == OnlyChannelType.Image);
await uow.Set<ImageOnlyChannel>().DeleteAsync(x => x.ChannelId == channelId && x.Type == OnlyChannelType.Image);
}
else
{
await uow.ImageOnlyChannels.DeleteAsync(x => x.ChannelId == channelId);
uow.ImageOnlyChannels.Add(new()
await uow.Set<ImageOnlyChannel>().DeleteAsync(x => x.ChannelId == channelId);
uow.Set<ImageOnlyChannel>().Add(new()
{
GuildId = guildId,
ChannelId = channelId,
@@ -115,12 +115,12 @@ public sealed class SomethingOnlyChannelService : IExecOnMessage
await using var uow = _db.GetDbContext();
if (forceDisable || (_linkOnly.TryGetValue(guildId, out var channels) && channels.TryRemove(channelId)))
{
await uow.ImageOnlyChannels.DeleteAsync(x => x.ChannelId == channelId && x.Type == OnlyChannelType.Link);
await uow.Set<ImageOnlyChannel>().DeleteAsync(x => x.ChannelId == channelId && x.Type == OnlyChannelType.Link);
}
else
{
await uow.ImageOnlyChannels.DeleteAsync(x => x.ChannelId == channelId);
uow.ImageOnlyChannels.Add(new()
await uow.Set<ImageOnlyChannel>().DeleteAsync(x => x.ChannelId == channelId);
uow.Set<ImageOnlyChannel>().Add(new()
{
GuildId = guildId,
ChannelId = channelId,

View File

@@ -13,6 +13,7 @@
<ItemGroup>
<ProjectReference Include="..\Nadeko.Bot.Common\Nadeko.Bot.Common.csproj" />
<ProjectReference Include="..\Nadeko.Bot.Modules.Gambling\Nadeko.Bot.Modules.Gambling.csproj" />
</ItemGroup>
</Project>

View File

@@ -46,7 +46,7 @@ public sealed class PlayingRotateService : INService, IReadyExecutor
IReadOnlyList<RotatingPlayingStatus> rotatingStatuses;
await using (var uow = _db.GetDbContext())
{
rotatingStatuses = uow.RotatingStatus.AsNoTracking().OrderBy(x => x.Id).ToList();
rotatingStatuses = uow.Set<RotatingPlayingStatus>().AsNoTracking().OrderBy(x => x.Id).ToList();
}
if (rotatingStatuses.Count == 0)
@@ -72,7 +72,7 @@ public sealed class PlayingRotateService : INService, IReadyExecutor
throw new ArgumentOutOfRangeException(nameof(index));
await using var uow = _db.GetDbContext();
var toRemove = await uow.RotatingStatus.AsQueryable().AsNoTracking().Skip(index).FirstOrDefaultAsync();
var toRemove = await uow.Set<RotatingPlayingStatus>().AsQueryable().AsNoTracking().Skip(index).FirstOrDefaultAsync();
if (toRemove is null)
return null;
@@ -104,6 +104,6 @@ public sealed class PlayingRotateService : INService, IReadyExecutor
public IReadOnlyList<RotatingPlayingStatus> GetRotatingStatuses()
{
using var uow = _db.GetDbContext();
return uow.RotatingStatus.AsNoTracking().ToList();
return uow.Set<RotatingPlayingStatus>().AsNoTracking().ToList();
}
}

View File

@@ -83,7 +83,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
{
await using var uow = _db.GetDbContext();
autoCommands = uow.AutoCommands.AsNoTracking()
autoCommands = uow.Set<AutoCommand>().AsNoTracking()
.Where(x => x.Interval >= 5)
.AsEnumerable()
.GroupBy(x => x.GuildId)
@@ -91,7 +91,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
y => y.ToDictionary(x => x.Id, TimerFromAutoCommand).ToConcurrent())
.ToConcurrent();
var startupCommands = uow.AutoCommands.AsNoTracking().Where(x => x.Interval == 0);
var startupCommands = uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval == 0);
foreach (var cmd in startupCommands)
{
try
@@ -136,7 +136,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
{
using (var uow = _db.GetDbContext())
{
uow.AutoCommands.Add(cmd);
uow.Set<AutoCommand>().Add(cmd);
uow.SaveChanges();
}
@@ -156,13 +156,13 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
public IEnumerable<AutoCommand> GetStartupCommands()
{
using var uow = _db.GetDbContext();
return uow.AutoCommands.AsNoTracking().Where(x => x.Interval == 0).OrderBy(x => x.Id).ToList();
return uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval == 0).OrderBy(x => x.Id).ToList();
}
public IEnumerable<AutoCommand> GetAutoCommands()
{
using var uow = _db.GetDbContext();
return uow.AutoCommands.AsNoTracking().Where(x => x.Interval >= 5).OrderBy(x => x.Id).ToList();
return uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval >= 5).OrderBy(x => x.Id).ToList();
}
private async Task LoadOwnerChannels()
@@ -264,7 +264,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
public bool RemoveStartupCommand(int index, out AutoCommand cmd)
{
using var uow = _db.GetDbContext();
cmd = uow.AutoCommands.AsNoTracking().Where(x => x.Interval == 0).Skip(index).FirstOrDefault();
cmd = uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval == 0).Skip(index).FirstOrDefault();
if (cmd is not null)
{
@@ -279,7 +279,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
public bool RemoveAutoCommand(int index, out AutoCommand cmd)
{
using var uow = _db.GetDbContext();
cmd = uow.AutoCommands.AsNoTracking().Where(x => x.Interval >= 5).Skip(index).FirstOrDefault();
cmd = uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval >= 5).Skip(index).FirstOrDefault();
if (cmd is not null)
{
@@ -323,9 +323,9 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
public void ClearStartupCommands()
{
using var uow = _db.GetDbContext();
var toRemove = uow.AutoCommands.AsNoTracking().Where(x => x.Interval == 0);
var toRemove = uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval == 0);
uow.AutoCommands.RemoveRange(toRemove);
uow.Set<AutoCommand>().RemoveRange(toRemove);
uow.SaveChanges();
}

View File

@@ -32,11 +32,11 @@ public class SelfAssignedRolesService : INService
public bool AddNew(ulong guildId, IRole role, int group)
{
using var uow = _db.GetDbContext();
var roles = uow.SelfAssignableRoles.GetFromGuild(guildId);
var roles = uow.Set<SelfAssignedRole>().GetFromGuild(guildId);
if (roles.Any(s => s.RoleId == role.Id && s.GuildId == role.Guild.Id))
return false;
uow.SelfAssignableRoles.Add(new()
uow.Set<SelfAssignedRole>().Add(new()
{
Group = group,
RoleId = role.Id,
@@ -166,7 +166,7 @@ public class SelfAssignedRolesService : INService
{
bool success;
using var uow = _db.GetDbContext();
success = uow.SelfAssignableRoles.DeleteByGuildAndRoleId(guildId, roleId);
success = uow.Set<SelfAssignedRole>().DeleteByGuildAndRoleId(guildId, roleId);
uow.SaveChanges();
return success;
}
@@ -177,7 +177,7 @@ public class SelfAssignedRolesService : INService
var gc = uow.GuildConfigsForId(guildId, set => set);
var autoDelete = gc.AutoDeleteSelfAssignedRoleMessages;
var exclusive = gc.ExclusiveSelfAssignedRoles;
var roles = uow.SelfAssignableRoles.GetFromGuild(guildId);
var roles = uow.Set<SelfAssignedRole>().GetFromGuild(guildId);
return (autoDelete, exclusive, roles);
}
@@ -185,7 +185,7 @@ public class SelfAssignedRolesService : INService
public bool SetLevelReq(ulong guildId, IRole role, int level)
{
using var uow = _db.GetDbContext();
var roles = uow.SelfAssignableRoles.GetFromGuild(guildId);
var roles = uow.Set<SelfAssignedRole>().GetFromGuild(guildId);
var sar = roles.FirstOrDefault(x => x.RoleId == role.Id);
if (sar is not null)
{
@@ -222,10 +222,10 @@ public class SelfAssignedRolesService : INService
var gc = uow.GuildConfigsForId(guild.Id, set => set.Include(x => x.SelfAssignableRoleGroupNames));
exclusive = gc.ExclusiveSelfAssignedRoles;
groupNames = gc.SelfAssignableRoleGroupNames.ToDictionary(x => x.Number, x => x.Name);
var roleModels = uow.SelfAssignableRoles.GetFromGuild(guild.Id);
var roleModels = uow.Set<SelfAssignedRole>().GetFromGuild(guild.Id);
roles = roleModels.Select(x => (Model: x, Role: guild.GetRole(x.RoleId)))
.ToList();
uow.SelfAssignableRoles.RemoveRange(roles.Where(x => x.Role is null).Select(x => x.Model).ToArray());
uow.Set<SelfAssignedRole>().RemoveRange(roles.Where(x => x.Role is null).Select(x => x.Model).ToArray());
uow.SaveChanges();
}

View File

@@ -52,7 +52,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
using (var uow = db.GetDbContext())
{
var guildIds = client.Guilds.Select(x => x.Id).ToList();
var configs = uow.LogSettings.AsQueryable()
var configs = uow.Set<LogSetting>().AsQueryable()
.AsNoTracking()
.Where(x => guildIds.Contains(x.GuildId))
.Include(ls => ls.LogIgnores)

View File

@@ -87,11 +87,11 @@ public class UserPunishService : INService, IReadyExecutor
{
ps = uow.GuildConfigsForId(guildId, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
previousCount = uow.Warnings.ForId(guildId, userId)
previousCount = uow.Set<Warning>().ForId(guildId, userId)
.Where(w => !w.Forgiven && w.UserId == userId)
.Sum(x => x.Weight);
uow.Warnings.Add(warn);
uow.Set<Warning>().Add(warn);
await uow.SaveChangesAsync();
}
@@ -241,14 +241,14 @@ public class UserPunishService : INService, IReadyExecutor
public async Task CheckAllWarnExpiresAsync()
{
await using var uow = _db.GetDbContext();
var cleared = await uow.Warnings
.Where(x => uow.GuildConfigs
var cleared = await uow.Set<Warning>()
.Where(x => uow.Set<GuildConfig>()
.Any(y => y.GuildId == x.GuildId
&& y.WarnExpireHours > 0
&& y.WarnExpireAction == WarnExpireAction.Clear)
&& x.Forgiven == false
&& x.DateAdded
< DateTime.UtcNow.AddHours(-uow.GuildConfigs
< DateTime.UtcNow.AddHours(-uow.Set<GuildConfig>()
.Where(y => x.GuildId == y.GuildId)
.Select(y => y.WarnExpireHours)
.First()))
@@ -258,13 +258,13 @@ public class UserPunishService : INService, IReadyExecutor
ForgivenBy = "expiry"
});
var deleted = await uow.Warnings
.Where(x => uow.GuildConfigs
var deleted = await uow.Set<Warning>()
.Where(x => uow.Set<GuildConfig>()
.Any(y => y.GuildId == x.GuildId
&& y.WarnExpireHours > 0
&& y.WarnExpireAction == WarnExpireAction.Delete)
&& x.DateAdded
< DateTime.UtcNow.AddHours(-uow.GuildConfigs
< DateTime.UtcNow.AddHours(-uow.Set<GuildConfig>()
.Where(y => x.GuildId == y.GuildId)
.Select(y => y.WarnExpireHours)
.First()))
@@ -290,7 +290,7 @@ public class UserPunishService : INService, IReadyExecutor
if (config.WarnExpireAction == WarnExpireAction.Clear)
{
await uow.Warnings
await uow.Set<Warning>()
.Where(x => x.GuildId == guildId
&& x.Forgiven == false
&& x.DateAdded < DateTime.UtcNow.AddHours(-config.WarnExpireHours))
@@ -302,7 +302,7 @@ public class UserPunishService : INService, IReadyExecutor
}
else if (config.WarnExpireAction == WarnExpireAction.Delete)
{
await uow.Warnings
await uow.Set<Warning>()
.Where(x => x.GuildId == guildId
&& x.DateAdded < DateTime.UtcNow.AddHours(-config.WarnExpireHours))
.DeleteAsync();
@@ -339,13 +339,13 @@ public class UserPunishService : INService, IReadyExecutor
public IGrouping<ulong, Warning>[] WarnlogAll(ulong gid)
{
using var uow = _db.GetDbContext();
return uow.Warnings.GetForGuild(gid).GroupBy(x => x.UserId).ToArray();
return uow.Set<Warning>().GetForGuild(gid).GroupBy(x => x.UserId).ToArray();
}
public Warning[] UserWarnings(ulong gid, ulong userId)
{
using var uow = _db.GetDbContext();
return uow.Warnings.ForId(gid, userId);
return uow.Set<Warning>().ForId(gid, userId);
}
public async Task<bool> WarnClearAsync(
@@ -357,9 +357,9 @@ public class UserPunishService : INService, IReadyExecutor
var toReturn = true;
await using var uow = _db.GetDbContext();
if (index == 0)
await uow.Warnings.ForgiveAll(guildId, userId, moderator);
await uow.Set<Warning>().ForgiveAll(guildId, userId, moderator);
else
toReturn = uow.Warnings.Forgive(guildId, userId, moderator, index - 1);
toReturn = uow.Set<Warning>().Forgive(guildId, userId, moderator, index - 1);
await uow.SaveChangesAsync();
return toReturn;
}
@@ -463,14 +463,14 @@ public class UserPunishService : INService, IReadyExecutor
public string GetBanTemplate(ulong guildId)
{
using var uow = _db.GetDbContext();
var template = uow.BanTemplates.AsQueryable().FirstOrDefault(x => x.GuildId == guildId);
var template = uow.Set<BanTemplate>().AsQueryable().FirstOrDefault(x => x.GuildId == guildId);
return template?.Text;
}
public void SetBanTemplate(ulong guildId, string text)
{
using var uow = _db.GetDbContext();
var template = uow.BanTemplates.AsQueryable().FirstOrDefault(x => x.GuildId == guildId);
var template = uow.Set<BanTemplate>().AsQueryable().FirstOrDefault(x => x.GuildId == guildId);
if (text is null)
{
@@ -481,7 +481,7 @@ public class UserPunishService : INService, IReadyExecutor
}
else if (template is null)
{
uow.BanTemplates.Add(new()
uow.Set<BanTemplate>().Add(new()
{
GuildId = guildId,
Text = text
@@ -496,7 +496,7 @@ public class UserPunishService : INService, IReadyExecutor
public async Task SetBanPruneAsync(ulong guildId, int? pruneDays)
{
await using var ctx = _db.GetDbContext();
await ctx.BanTemplates
await ctx.Set<BanTemplate>()
.ToLinqToDBTable()
.InsertOrUpdateAsync(() => new()
{
@@ -518,7 +518,7 @@ public class UserPunishService : INService, IReadyExecutor
public async Task<int?> GetBanPruneAsync(ulong guildId)
{
await using var ctx = _db.GetDbContext();
return await ctx.BanTemplates
return await ctx.Set<BanTemplate>()
.Where(x => x.GuildId == guildId)
.Select(x => x.PruneDays)
.FirstOrDefaultAsyncLinqToDB();

View File

@@ -110,7 +110,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
private async Task ReloadInternal(IReadOnlyList<ulong> allGuildIds)
{
await using var uow = _db.GetDbContext();
var guildItems = await uow.Expressions.AsNoTracking()
var guildItems = await uow.Set<NadekoExpression>().AsNoTracking()
.Where(x => allGuildIds.Contains(x.GuildId.Value))
.ToListAsync();
@@ -124,14 +124,14 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
.ToArray())
.ToConcurrent();
_disabledGlobalExpressionGuilds = new(await uow.GuildConfigs
_disabledGlobalExpressionGuilds = new(await uow.Set<GuildConfig>()
.Where(x => x.DisableGlobalExpressions)
.Select(x => x.GuildId)
.ToListAsyncLinqToDB());
lock (_gexprWriteLock)
{
var globalItems = uow.Expressions.AsNoTracking()
var globalItems = uow.Set<NadekoExpression>().AsNoTracking()
.Where(x => x.GuildId == null || x.GuildId == 0)
.AsEnumerable()
.Select(x =>
@@ -344,7 +344,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
{
NadekoExpression expr;
await using var uow = _db.GetDbContext();
expr = uow.Expressions.GetById(id);
expr = uow.Set<NadekoExpression>().GetById(id);
if (expr is null)
return;
@@ -459,7 +459,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
NadekoExpression expr;
await using (var uow = _db.GetDbContext())
{
expr = uow.Expressions.GetById(id);
expr = uow.Set<NadekoExpression>().GetById(id);
if (expr is null)
return;
@@ -477,7 +477,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
NadekoExpression expr;
await using (var uow = _db.GetDbContext())
{
expr = uow.Expressions.GetById(id);
expr = uow.Set<NadekoExpression>().GetById(id);
if (expr is null || expr.GuildId != guildId)
return (false, false);
@@ -501,7 +501,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
public NadekoExpression GetExpression(ulong? guildId, int id)
{
using var uow = _db.GetDbContext();
var expr = uow.Expressions.GetById(id);
var expr = uow.Set<NadekoExpression>().GetById(id);
if (expr is null || expr.GuildId != guildId)
return null;
@@ -511,7 +511,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
public int DeleteAllExpressions(ulong guildId)
{
using var uow = _db.GetDbContext();
var count = uow.Expressions.ClearFromGuild(guildId);
var count = uow.Set<NadekoExpression>().ClearFromGuild(guildId);
uow.SaveChanges();
newguildExpressions.TryRemove(guildId, out _);
@@ -569,7 +569,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
foreach (var entry in data)
{
var trigger = entry.Key;
await uow.Expressions.AddRangeAsync(entry.Value.Where(expr => !string.IsNullOrWhiteSpace(expr.Res))
await uow.Set<NadekoExpression>().AddRangeAsync(entry.Value.Where(expr => !string.IsNullOrWhiteSpace(expr.Res))
.Select(expr => new NadekoExpression
{
GuildId = guildId,
@@ -658,7 +658,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
private async Task OnJoinedGuild(GuildConfig gc)
{
await using var uow = _db.GetDbContext();
var exprs = await uow.Expressions.AsNoTracking().Where(x => x.GuildId == gc.GuildId).ToArrayAsync();
var exprs = await uow.Set<NadekoExpression>().AsNoTracking().Where(x => x.GuildId == gc.GuildId).ToArrayAsync();
newguildExpressions[gc.GuildId] = exprs;
}
@@ -682,7 +682,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
await using (var uow = _db.GetDbContext())
{
uow.Expressions.Add(expr);
uow.Set<NadekoExpression>().Add(expr);
await uow.SaveChangesAsync();
}
@@ -694,7 +694,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
public async Task<NadekoExpression> EditAsync(ulong? guildId, int id, string message)
{
await using var uow = _db.GetDbContext();
var expr = uow.Expressions.GetById(id);
var expr = uow.Set<NadekoExpression>().GetById(id);
if (expr is null || expr.GuildId != guildId)
return null;
@@ -720,14 +720,14 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
public async Task<NadekoExpression> DeleteAsync(ulong? guildId, int id)
{
await using var uow = _db.GetDbContext();
var toDelete = uow.Expressions.GetById(id);
var toDelete = uow.Set<NadekoExpression>().GetById(id);
if (toDelete is null)
return null;
if ((toDelete.IsGlobal() && guildId is null) || guildId == toDelete.GuildId)
{
uow.Expressions.Remove(toDelete);
uow.Set<NadekoExpression>().Remove(toDelete);
await uow.SaveChangesAsync();
await DeleteInternalAsync(guildId, id);
return toDelete;

View File

@@ -45,7 +45,7 @@ public sealed class BankService : IBankService, INService
throw new ArgumentOutOfRangeException(nameof(amount));
await using var ctx = _db.GetDbContext();
var rows = await ctx.BankUsers
var rows = await ctx.Set<BankUser>()
.ToLinqToDBTable()
.Where(x => x.UserId == userId && x.Balance >= amount)
.UpdateAsync((old) => new()
@@ -65,7 +65,7 @@ public sealed class BankService : IBankService, INService
return false;
await using var ctx = _db.GetDbContext();
await ctx.BankUsers
await ctx.Set<BankUser>()
.ToLinqToDBTable()
.InsertOrUpdateAsync(() => new()
{
@@ -90,7 +90,7 @@ public sealed class BankService : IBankService, INService
throw new ArgumentOutOfRangeException(nameof(amount));
await using var ctx = _db.GetDbContext();
var rows = await ctx.BankUsers
var rows = await ctx.Set<BankUser>()
.ToLinqToDBTable()
.Where(x => x.UserId == userId && x.Balance >= amount)
.UpdateAsync((old) => new()
@@ -110,7 +110,7 @@ public sealed class BankService : IBankService, INService
public async Task<long> GetBalanceAsync(ulong userId)
{
await using var ctx = _db.GetDbContext();
return (await ctx.BankUsers
return (await ctx.Set<BankUser>()
.ToLinqToDBTable()
.FirstOrDefaultAsync(x => x.UserId == userId))
?.Balance

View File

@@ -0,0 +1,39 @@
using Nadeko.Bot.Modules.Gambling.Gambling._Common;
namespace NadekoBot.Modules.Gambling;
public partial class Gambling
{
[Group]
public class CleanupCommands : CleanupModuleBase
{
private readonly IGamblingCleanupService _gcs;
public CleanupCommands(IGamblingCleanupService gcs)
{
_gcs = gcs;
}
[Cmd]
[OwnerOnly]
public Task DeleteWaifus()
=> ConfirmActionInternalAsync("Delete Waifus", () => _gcs.DeleteWaifus());
[Cmd]
[OwnerOnly]
public async Task DeleteWaifu(IUser user)
=> await DeleteWaifu(user.Id);
[Cmd]
[OwnerOnly]
public Task DeleteWaifu(ulong userId)
=> ConfirmActionInternalAsync($"Delete Waifu {userId}", () => _gcs.DeleteWaifu(userId));
[Cmd]
[OwnerOnly]
public Task DeleteCurrency()
=> ConfirmActionInternalAsync("Delete Currency", () => _gcs.DeleteCurrency());
}
}

View File

@@ -290,7 +290,7 @@ public partial class Gambling : GamblingModule<GamblingService>
List<CurrencyTransaction> trs;
await using (var uow = _db.GetDbContext())
{
trs = await uow.CurrencyTransactions.GetPageFor(userId, page);
trs = await uow.Set<CurrencyTransaction>().GetPageFor(userId, page);
}
var embed = _eb.Create()
@@ -332,7 +332,7 @@ public partial class Gambling : GamblingModule<GamblingService>
int intId = id;
await using var uow = _db.GetDbContext();
var tr = await uow.CurrencyTransactions.ToLinqToDBTable()
var tr = await uow.Set<CurrencyTransaction>().ToLinqToDBTable()
.Where(x => x.Id == intId && x.UserId == ctx.User.Id)
.FirstOrDefaultAsync();
@@ -739,7 +739,7 @@ public partial class Gambling : GamblingModule<GamblingService>
{
await using (var uow = _db.GetDbContext())
{
cleanRichest = uow.DiscordUser.GetTopRichest(_client.CurrentUser.Id, 10_000);
cleanRichest = uow.Set<DiscordUser>().GetTopRichest(_client.CurrentUser.Id, 10_000);
}
await ctx.Channel.TriggerTypingAsync();
@@ -751,7 +751,7 @@ public partial class Gambling : GamblingModule<GamblingService>
else
{
await using var uow = _db.GetDbContext();
cleanRichest = uow.DiscordUser.GetTopRichest(_client.CurrentUser.Id, 9, page).ToList();
cleanRichest = uow.Set<DiscordUser>().GetTopRichest(_client.CurrentUser.Id, 9, page).ToList();
}
await ctx.SendPaginatedConfirmAsync(page,
@@ -763,7 +763,7 @@ public partial class Gambling : GamblingModule<GamblingService>
if (!opts.Clean)
{
using var uow = _db.GetDbContext();
toSend = uow.DiscordUser.GetTopRichest(_client.CurrentUser.Id, 9, curPage);
toSend = uow.Set<DiscordUser>().GetTopRichest(_client.CurrentUser.Id, 9, curPage);
}
else
{

View File

@@ -6,6 +6,7 @@ using NadekoBot.Db;
using NadekoBot.Db.Models;
using NadekoBot.Modules.Gambling.Common;
using NadekoBot.Modules.Gambling.Common.Connect4;
using NadekoBot.Services.Database.Models;
namespace NadekoBot.Modules.Gambling.Services;
@@ -52,7 +53,7 @@ public class GamblingService : INService, IReadyExecutor
var now = DateTime.UtcNow;
var days = TimeSpan.FromDays(lifetime);
await using var uow = _db.GetDbContext();
await uow.CurrencyTransactions
await uow.Set<CurrencyTransaction>()
.DeleteAsync(ct => ct.DateAdded == null || now - ct.DateAdded < days);
}
catch (Exception ex)
@@ -104,7 +105,7 @@ public class GamblingService : INService, IReadyExecutor
maxDecay = int.MaxValue;
var decay = (double)config.Decay.Percent;
await uow.DiscordUser
await uow.Set<DiscordUser>()
.Where(x => x.CurrencyAmount > config.Decay.MinThreshold && x.UserId != _client.CurrentUser.Id)
.UpdateAsync(old => new()
{
@@ -135,11 +136,11 @@ public class GamblingService : INService, IReadyExecutor
async () =>
{
await using var uow = _db.GetDbContext();
var cash = uow.DiscordUser.GetTotalCurrency();
var onePercent = uow.DiscordUser.GetTopOnePercentCurrency(_client.CurrentUser.Id);
decimal planted = uow.PlantedCurrency.AsQueryable().Sum(x => x.Amount);
var waifus = uow.WaifuInfo.GetTotalValue();
var bot = await uow.DiscordUser.GetUserCurrencyAsync(_client.CurrentUser.Id);
var cash = uow.Set<DiscordUser>().GetTotalCurrency();
var onePercent = uow.Set<DiscordUser>().GetTopOnePercentCurrency(_client.CurrentUser.Id);
decimal planted = uow.Set<PlantedCurrency>().AsQueryable().Sum(x => x.Amount);
var waifus = uow.Set<WaifuInfo>().GetTotalValue();
var bot = await uow.Set<DiscordUser>().GetUserCurrencyAsync(_client.CurrentUser.Id);
decimal bank = await uow.GetTable<BankUser>()
.SumAsyncLinqToDB(x => x.Balance);

View File

@@ -100,7 +100,7 @@ public class PlantPickService : INService, IExecNoCommand
public IEnumerable<GuildConfigExtensions.GeneratingChannel> GetAllGeneratingChannels()
{
using var uow = _db.GetDbContext();
var chs = uow.GuildConfigs.GetGeneratingChannels();
var chs = uow.Set<GuildConfig>().GetGeneratingChannels();
return chs;
}
@@ -259,7 +259,7 @@ public class PlantPickService : INService, IExecNoCommand
pass = pass?.Trim().TrimTo(10, true).ToUpperInvariant();
// gets all plants in this channel with the same password
var entries = uow.PlantedCurrency.AsQueryable()
var entries = uow.Set<PlantedCurrency>().AsQueryable()
.Where(x => x.ChannelId == ch.Id && pass == x.Password)
.ToList();
// sum how much currency that is, and get all of the message ids (so that i can delete them)
@@ -371,7 +371,7 @@ public class PlantPickService : INService, IExecNoCommand
string pass)
{
await using var uow = _db.GetDbContext();
uow.PlantedCurrency.Add(new()
uow.Set<PlantedCurrency>().Add(new()
{
Amount = amount,
GuildId = gid,

View File

@@ -13,7 +13,7 @@ public class ShopService : IShopService, INService
public ShopService(DbService db)
=> _db = db;
private IndexedCollection<ShopEntry> GetEntriesInternal(NadekoContext uow, ulong guildId)
private IndexedCollection<ShopEntry> GetEntriesInternal(DbContext uow, ulong guildId)
=> uow.GuildConfigsForId(guildId, set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items))
.ShopEntries.ToIndexed();

View File

@@ -44,7 +44,7 @@ public class WaifuService : INService, IReadyExecutor
var settings = _gss.Data;
await using var uow = _db.GetDbContext();
var waifu = uow.WaifuInfo.ByWaifuUserId(waifuId);
var waifu = uow.Set<WaifuInfo>().ByWaifuUserId(waifuId);
var ownerUser = uow.GetOrCreateUser(owner);
// owner has to be the owner of the waifu
@@ -85,14 +85,14 @@ public class WaifuService : INService, IReadyExecutor
{
var settings = _gss.Data;
using var uow = _db.GetDbContext();
var waifu = uow.WaifuInfo.ByWaifuUserId(user.Id);
var waifu = uow.Set<WaifuInfo>().ByWaifuUserId(user.Id);
if (waifu is null)
return settings.Waifu.MinPrice;
var divorces = uow.WaifuUpdates.Count(x
var divorces = uow.Set<WaifuUpdate>().Count(x
=> x.Old != null && x.Old.UserId == user.Id && x.UpdateType == WaifuUpdateType.Claimed && x.New == null);
var affs = uow.WaifuUpdates.AsQueryable()
var affs = uow.Set<WaifuUpdate>().AsQueryable()
.Where(w => w.User.UserId == user.Id
&& w.UpdateType == WaifuUpdateType.AffinityChanged
&& w.New != null)
@@ -111,22 +111,22 @@ public class WaifuService : INService, IReadyExecutor
if (!await _cs.RemoveAsync(user.Id, price, new("waifu", "reset")))
return false;
var affs = uow.WaifuUpdates.AsQueryable()
var affs = uow.Set<WaifuUpdate>().AsQueryable()
.Where(w => w.User.UserId == user.Id
&& w.UpdateType == WaifuUpdateType.AffinityChanged
&& w.New != null);
var divorces = uow.WaifuUpdates.AsQueryable()
var divorces = uow.Set<WaifuUpdate>().AsQueryable()
.Where(x => x.Old != null
&& x.Old.UserId == user.Id
&& x.UpdateType == WaifuUpdateType.Claimed
&& x.New == null);
//reset changes of heart to 0
uow.WaifuUpdates.RemoveRange(affs);
uow.Set<WaifuUpdate>().RemoveRange(affs);
//reset divorces to 0
uow.WaifuUpdates.RemoveRange(divorces);
var waifu = uow.WaifuInfo.ByWaifuUserId(user.Id);
uow.Set<WaifuUpdate>().RemoveRange(divorces);
var waifu = uow.Set<WaifuInfo>().ByWaifuUserId(user.Id);
//reset price, remove items
//remove owner, remove affinity
waifu.Price = 50;
@@ -149,7 +149,7 @@ public class WaifuService : INService, IReadyExecutor
bool isAffinity;
await using (var uow = _db.GetDbContext())
{
w = uow.WaifuInfo.ByWaifuUserId(target.Id);
w = uow.Set<WaifuInfo>().ByWaifuUserId(target.Id);
isAffinity = w?.Affinity?.UserId == user.Id;
if (w is null)
{
@@ -159,14 +159,14 @@ public class WaifuService : INService, IReadyExecutor
result = WaifuClaimResult.NotEnoughFunds;
else
{
uow.WaifuInfo.Add(w = new()
uow.Set<WaifuInfo>().Add(w = new()
{
Waifu = waifu,
Claimer = claimer,
Affinity = null,
Price = amount
});
uow.WaifuUpdates.Add(new()
uow.Set<WaifuUpdate>().Add(new()
{
User = waifu,
Old = null,
@@ -187,7 +187,7 @@ public class WaifuService : INService, IReadyExecutor
w.Price = amount + (amount / 4);
result = WaifuClaimResult.Success;
uow.WaifuUpdates.Add(new()
uow.Set<WaifuUpdate>().Add(new()
{
User = w.Waifu,
Old = oldClaimer,
@@ -207,7 +207,7 @@ public class WaifuService : INService, IReadyExecutor
w.Price = amount;
result = WaifuClaimResult.Success;
uow.WaifuUpdates.Add(new()
uow.Set<WaifuUpdate>().Add(new()
{
User = w.Waifu,
Old = oldClaimer,
@@ -233,7 +233,7 @@ public class WaifuService : INService, IReadyExecutor
TimeSpan? remaining = null;
await using (var uow = _db.GetDbContext())
{
var w = uow.WaifuInfo.ByWaifuUserId(user.Id);
var w = uow.Set<WaifuInfo>().ByWaifuUserId(user.Id);
var newAff = target is null ? null : uow.GetOrCreateUser(target);
if (w?.Affinity?.UserId == target?.Id)
{
@@ -249,7 +249,7 @@ public class WaifuService : INService, IReadyExecutor
else if (w is null)
{
var thisUser = uow.GetOrCreateUser(user);
uow.WaifuInfo.Add(new()
uow.Set<WaifuInfo>().Add(new()
{
Affinity = newAff,
Waifu = thisUser,
@@ -258,7 +258,7 @@ public class WaifuService : INService, IReadyExecutor
});
success = true;
uow.WaifuUpdates.Add(new()
uow.Set<WaifuUpdate>().Add(new()
{
User = thisUser,
Old = null,
@@ -273,7 +273,7 @@ public class WaifuService : INService, IReadyExecutor
w.Affinity = newAff;
success = true;
uow.WaifuUpdates.Add(new()
uow.Set<WaifuUpdate>().Add(new()
{
User = w.Waifu,
Old = oldAff,
@@ -291,13 +291,13 @@ public class WaifuService : INService, IReadyExecutor
public IEnumerable<WaifuLbResult> GetTopWaifusAtPage(int page)
{
using var uow = _db.GetDbContext();
return uow.WaifuInfo.GetTop(9, page * 9);
return uow.Set<WaifuInfo>().GetTop(9, page * 9);
}
public ulong GetWaifuUserId(ulong ownerId, string name)
{
using var uow = _db.GetDbContext();
return uow.WaifuInfo.GetWaifuUserId(ownerId, name);
return uow.Set<WaifuInfo>().GetWaifuUserId(ownerId, name);
}
private static TypedKey<long> GetDivorceKey(ulong userId)
@@ -314,7 +314,7 @@ public class WaifuService : INService, IReadyExecutor
WaifuInfo w;
await using (var uow = _db.GetDbContext())
{
w = uow.WaifuInfo.ByWaifuUserId(targetId);
w = uow.Set<WaifuInfo>().ByWaifuUserId(targetId);
if (w?.Claimer is null || w.Claimer.UserId != user.Id)
result = DivorceResult.NotYourWife;
else
@@ -344,7 +344,7 @@ public class WaifuService : INService, IReadyExecutor
var oldClaimer = w.Claimer;
w.Claimer = null;
uow.WaifuUpdates.Add(new()
uow.Set<WaifuUpdate>().Add(new()
{
User = w.Waifu,
Old = oldClaimer,
@@ -365,10 +365,10 @@ public class WaifuService : INService, IReadyExecutor
return false;
await using var uow = _db.GetDbContext();
var w = uow.WaifuInfo.ByWaifuUserId(giftedWaifu.Id, set => set.Include(x => x.Items).Include(x => x.Claimer));
var w = uow.Set<WaifuInfo>().ByWaifuUserId(giftedWaifu.Id, set => set.Include(x => x.Items).Include(x => x.Claimer));
if (w is null)
{
uow.WaifuInfo.Add(w = new()
uow.Set<WaifuInfo>().Add(w = new()
{
Affinity = null,
Claimer = null,

View File

@@ -17,17 +17,3 @@ public class WaifuInfo : DbEntity
public long Price { get; set; }
public List<WaifuItem> Items { get; set; } = new();
}
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 long Price { get; set; }
}

View File

@@ -8,18 +8,6 @@ using NadekoBot.Services.Database.Models;
namespace NadekoBot.Db;
public class WaifuInfoStats
{
public int WaifuId { get; init; }
public string FullName { get; init; }
public long Price { get; init; }
public string ClaimerName { get; init; }
public string AffinityName { get; init; }
public int AffinityCount { get; init; }
public int DivorceCount { get; init; }
public int ClaimCount { get; init; }
}
public static class WaifuExtensions
{
public static WaifuInfo ByWaifuUserId(

View File

@@ -0,0 +1,14 @@
#nullable disable
namespace NadekoBot.Db;
public class WaifuInfoStats
{
public int WaifuId { get; init; }
public string FullName { get; init; }
public long Price { get; init; }
public string ClaimerName { get; init; }
public string AffinityName { get; init; }
public int AffinityCount { get; init; }
public int DivorceCount { get; init; }
public int ClaimCount { get; init; }
}

View File

@@ -0,0 +1,16 @@
#nullable disable
namespace NadekoBot.Services.Database.Models;
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 long Price { get; set; }
}

View File

@@ -15,9 +15,3 @@ public class WaifuUpdate : DbEntity
public int? NewId { get; set; }
public DiscordUser New { get; set; }
}
public enum WaifuUpdateType
{
AffinityChanged,
Claimed
}

View File

@@ -0,0 +1,8 @@
#nullable disable
namespace NadekoBot.Services.Database.Models;
public enum WaifuUpdateType
{
AffinityChanged,
Claimed
}

View File

@@ -0,0 +1,67 @@
using LinqToDB;
using NadekoBot.Db.Models;
using NadekoBot.Services.Database.Models;
namespace Nadeko.Bot.Modules.Gambling.Gambling._Common;
public interface IGamblingCleanupService
{
Task DeleteWaifus();
Task DeleteWaifu(ulong userId);
Task DeleteCurrency();
}
public class GamblingCleanupService : IGamblingCleanupService
{
private readonly DbService _db;
public GamblingCleanupService(DbService db)
{
_db = db;
}
public async Task DeleteWaifus()
{
await using var ctx = _db.GetDbContext();
await ctx.Set<WaifuInfo>().DeleteAsync();
await ctx.Set<WaifuItem>().DeleteAsync();
await ctx.Set<WaifuUpdate>().DeleteAsync();
await ctx.SaveChangesAsync();
}
public async Task DeleteWaifu(ulong userId)
{
await using var ctx = _db.GetDbContext();
await ctx.Set<WaifuUpdate>()
.Where(x => x.User.UserId == userId)
.DeleteAsync();
await ctx.Set<WaifuItem>()
.Where(x => x.WaifuInfo.Waifu.UserId == userId)
.DeleteAsync();
await ctx.Set<WaifuInfo>()
.Where(x => x.Claimer.UserId == userId)
.UpdateAsync(old => new WaifuInfo()
{
ClaimerId = null,
});
await ctx.Set<WaifuInfo>()
.Where(x => x.Waifu.UserId == userId)
.DeleteAsync();
await ctx.SaveChangesAsync();
}
public async Task DeleteCurrency()
{
await using var uow = _db.GetDbContext();
await uow.Set<DiscordUser>().UpdateAsync(_ => new DiscordUser()
{
CurrencyAmount = 0
});
await uow.Set<CurrencyTransaction>().DeleteAsync();
await uow.Set<PlantedCurrency>().DeleteAsync();
await uow.Set<BankUser>().DeleteAsync();
await uow.SaveChangesAsync();
}
}

View File

@@ -1,5 +1,6 @@
using System.Text.RegularExpressions;
using NadekoBot.Db;
using NadekoBot.Db.Models;
using NadekoBot.Modules.Gambling.Services;
using NCalc;
using OneOf;
@@ -69,7 +70,7 @@ public class BaseShmartInputAmountReader
protected virtual async Task<long> Cur(ICommandContext ctx)
{
await using var uow = _db.GetDbContext();
return await uow.DiscordUser.GetUserCurrencyAsync(ctx.User.Id);
return await uow.Set<DiscordUser>().GetUserCurrencyAsync(ctx.User.Id);
}
protected virtual async Task<long> Max(ICommandContext ctx)

View File

@@ -1,6 +1,7 @@
#nullable disable
using NadekoBot.Db;
using NadekoBot.Modules.Games.Services;
using NadekoBot.Services.Database.Models;
namespace NadekoBot.Modules.Games;
@@ -25,7 +26,7 @@ public partial class Games
{
await using (var uow = _db.GetDbContext())
{
uow.GuildConfigs.SetCleverbotEnabled(ctx.Guild.Id, false);
uow.Set<GuildConfig>().SetCleverbotEnabled(ctx.Guild.Id, false);
await uow.SaveChangesAsync();
}
@@ -37,7 +38,7 @@ public partial class Games
await using (var uow = _db.GetDbContext())
{
uow.GuildConfigs.SetCleverbotEnabled(ctx.Guild.Id, true);
uow.Set<GuildConfig>().SetCleverbotEnabled(ctx.Guild.Id, true);
await uow.SaveChangesAsync();
}

View File

@@ -18,4 +18,5 @@
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0"/>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
using LinqToDB;
using NadekoBot.Services.Database.Models;
namespace NadekoBot.Modules.Music;
public sealed partial class Music
{
public class CleanupCommands : NadekoModule
{
private readonly DbService _db;
public CleanupCommands(DbService db)
{
_db = db;
}
public async Task DeletePlaylists()
{
await using var uow = _db.GetDbContext();
await uow.Set<MusicPlaylist>().DeleteAsync();
await uow.SaveChangesAsync();
}
}
}

View File

@@ -18,4 +18,5 @@
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0"/>
</ItemGroup>
</Project>

View File

@@ -46,7 +46,7 @@ public sealed partial class Music
await using (var uow = _db.GetDbContext())
{
playlists = uow.MusicPlaylists.GetPlaylistsOnPage(num);
playlists = uow.Set<MusicPlaylist>().GetPlaylistsOnPage(num);
}
var embed = _eb.Create(ctx)
@@ -66,13 +66,13 @@ public sealed partial class Music
try
{
await using var uow = _db.GetDbContext();
var pl = uow.MusicPlaylists.FirstOrDefault(x => x.Id == id);
var pl = uow.Set<MusicPlaylist>().FirstOrDefault(x => x.Id == id);
if (pl is not null)
{
if (_creds.IsOwner(ctx.User) || pl.AuthorId == ctx.User.Id)
{
uow.MusicPlaylists.Remove(pl);
uow.Set<MusicPlaylist>().Remove(pl);
await uow.SaveChangesAsync();
success = true;
}
@@ -99,7 +99,7 @@ public sealed partial class Music
MusicPlaylist mpl;
await using (var uow = _db.GetDbContext())
{
mpl = uow.MusicPlaylists.GetWithSongs(id);
mpl = uow.Set<MusicPlaylist>().GetWithSongs(id);
}
await ctx.SendPaginatedConfirmAsync(page,
@@ -146,7 +146,7 @@ public sealed partial class Music
AuthorId = ctx.User.Id,
Songs = songs.ToList()
};
uow.MusicPlaylists.Add(playlist);
uow.Set<MusicPlaylist>().Add(playlist);
await uow.SaveChangesAsync();
}
@@ -195,7 +195,7 @@ public sealed partial class Music
MusicPlaylist mpl;
await using (var uow = _db.GetDbContext())
{
mpl = uow.MusicPlaylists.GetWithSongs(id);
mpl = uow.Set<MusicPlaylist>().GetWithSongs(id);
}
if (mpl is null)

View File

@@ -331,7 +331,7 @@ public sealed class MusicService : IMusicService
return settings;
await using var uow = _db.GetDbContext();
var toReturn = _settings[guildId] = await uow.MusicPlayerSettings.ForGuildAsync(guildId);
var toReturn = _settings[guildId] = await uow.Set<MusicPlayerSettings>().ForGuildAsync(guildId);
await uow.SaveChangesAsync();
return toReturn;
@@ -343,7 +343,7 @@ public sealed class MusicService : IMusicService
TState state)
{
await using var uow = _db.GetDbContext();
var ms = await uow.MusicPlayerSettings.ForGuildAsync(guildId);
var ms = await uow.Set<MusicPlayerSettings>().ForGuildAsync(guildId);
action(ms, state);
await uow.SaveChangesAsync();
_settings[guildId] = ms;
@@ -431,7 +431,7 @@ public sealed class MusicService : IMusicService
public async Task<QualityPreset> GetMusicQualityAsync(ulong guildId)
{
await using var uow = _db.GetDbContext();
var settings = await uow.MusicPlayerSettings.ForGuildAsync(guildId);
var settings = await uow.Set<MusicPlayerSettings>().ForGuildAsync(guildId);
return settings.QualityPreset;
}

View File

@@ -32,7 +32,7 @@ public class PermissionService : IExecPreCommand, INService
_eb = eb;
using var uow = _db.GetDbContext();
foreach (var x in uow.GuildConfigs.PermissionsForAll(client.Guilds.ToArray().Select(x => x.Id).ToList()))
foreach (var x in uow.Set<GuildConfig>().PermissionsForAll(client.Guilds.ToArray().Select(x => x.Id).ToList()))
{
Cache.TryAdd(x.GuildId,
new()

View File

@@ -30,7 +30,8 @@ public class FeedsService : INService
using (var uow = db.GetDbContext())
{
var guildConfigIds = bot.AllGuildConfigs.Select(x => x.Id).ToList();
_subs = uow.GuildConfigs.AsQueryable()
_subs = uow.Set<GuildConfig>()
.AsQueryable()
.Where(x => guildConfigIds.Contains(x.Id))
.Include(x => x.FeedSubs)
.ToList()

View File

@@ -321,7 +321,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
{
using (var uow = _db.GetDbContext())
{
var gc = uow.GuildConfigs.AsQueryable()
var gc = uow.Set<GuildConfig>().AsQueryable()
.Include(x => x.FollowedStreams)
.FirstOrDefault(x => x.GuildId == guildConfig.GuildId);

View File

@@ -36,7 +36,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
await using (var ctx = _db.GetDbContext())
{
var guilds = _bot.AllGuildConfigs.Select(x => x.GuildId).ToList();
cs = await ctx.AutoTranslateChannels.Include(x => x.Users)
cs = await ctx.Set<AutoTranslateChannel>().Include(x => x.Users)
.Where(x => guilds.Contains(x.GuildId))
.ToListAsyncEF();
}
@@ -108,12 +108,12 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
{
await using var ctx = _db.GetDbContext();
var old = await ctx.AutoTranslateChannels.ToLinqToDBTable()
var old = await ctx.Set<AutoTranslateChannel>().ToLinqToDBTable()
.FirstOrDefaultAsyncLinqToDB(x => x.ChannelId == channelId);
if (old is null)
{
ctx.AutoTranslateChannels.Add(new()
ctx.Set<AutoTranslateChannel>().Add(new()
{
GuildId = guildId,
ChannelId = channelId,
@@ -138,7 +138,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
return true;
}
await ctx.AutoTranslateChannels.ToLinqToDBTable().DeleteAsync(x => x.ChannelId == channelId);
await ctx.Set<AutoTranslateChannel>().ToLinqToDBTable().DeleteAsync(x => x.ChannelId == channelId);
await ctx.SaveChangesAsync();
_atcs.TryRemove(channelId, out _);
@@ -168,7 +168,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
return null;
await using var ctx = _db.GetDbContext();
var ch = await ctx.AutoTranslateChannels.GetByChannelId(channelId);
var ch = await ctx.Set<AutoTranslateChannel>().GetByChannelId(channelId);
if (ch is null)
return null;
@@ -210,7 +210,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
public async Task<bool> UnregisterUser(ulong channelId, ulong userId)
{
await using var ctx = _db.GetDbContext();
var rows = await ctx.AutoTranslateUsers.ToLinqToDBTable()
var rows = await ctx.Set<AutoTranslateUser>().ToLinqToDBTable()
.DeleteAsync(x => x.UserId == userId && x.Channel.ChannelId == channelId);
if (_users.TryGetValue(channelId, out var inner))

View File

@@ -62,7 +62,7 @@ public partial class Utility
IEnumerable<Quote> quotes;
await using (var uow = _db.GetDbContext())
{
quotes = uow.Quotes.GetGroup(ctx.Guild.Id, page, order);
quotes = uow.Set<Quote>().GetGroup(ctx.Guild.Id, page, order);
}
if (quotes.Any())
@@ -88,7 +88,7 @@ public partial class Utility
Quote quote;
await using (var uow = _db.GetDbContext())
{
quote = await uow.Quotes.GetRandomQuoteByKeywordAsync(ctx.Guild.Id, keyword);
quote = await uow.Set<Quote>().GetRandomQuoteByKeywordAsync(ctx.Guild.Id, keyword);
//if (quote is not null)
//{
// quote.UseCount += 1;
@@ -114,7 +114,7 @@ public partial class Utility
Quote? quote;
await using (var uow = _db.GetDbContext())
{
quote = uow.Quotes.GetById(id);
quote = uow.Set<Quote>().GetById(id);
if (quote?.GuildId != ctx.Guild.Id)
quote = null;
}
@@ -148,7 +148,7 @@ public partial class Utility
Quote quote;
await using (var uow = _db.GetDbContext())
{
quote = await uow.Quotes.SearchQuoteKeywordTextAsync(ctx.Guild.Id, keyword, textOrAuthor);
quote = await uow.Set<Quote>().SearchQuoteKeywordTextAsync(ctx.Guild.Id, keyword, textOrAuthor);
}
if (quote is null)
@@ -185,7 +185,7 @@ public partial class Utility
await using (var uow = _db.GetDbContext())
{
quote = uow.Quotes.GetById(id);
quote = uow.Set<Quote>().GetById(id);
}
if (quote is null || quote.GuildId != ctx.Guild.Id)
@@ -216,7 +216,7 @@ public partial class Utility
Quote q;
await using (var uow = _db.GetDbContext())
{
uow.Quotes.Add(q = new()
uow.Set<Quote>().Add(q = new()
{
AuthorId = ctx.Message.Author.Id,
AuthorName = ctx.Message.Author.Username,
@@ -240,13 +240,13 @@ public partial class Utility
string response;
await using (var uow = _db.GetDbContext())
{
var q = uow.Quotes.GetById(id);
var q = uow.Set<Quote>().GetById(id);
if (q?.GuildId != ctx.Guild.Id || (!hasManageMessages && q.AuthorId != ctx.Message.Author.Id))
response = GetText(strs.quotes_remove_none);
else
{
uow.Quotes.Remove(q);
uow.Set<Quote>().Remove(q);
await uow.SaveChangesAsync();
success = true;
response = GetText(strs.quote_deleted(id));
@@ -293,7 +293,7 @@ public partial class Utility
await using (var uow = _db.GetDbContext())
{
uow.Quotes.RemoveAllByKeyword(ctx.Guild.Id, keyword.ToUpperInvariant());
uow.Set<Quote>().RemoveAllByKeyword(ctx.Guild.Id, keyword.ToUpperInvariant());
await uow.SaveChangesAsync();
}
@@ -309,7 +309,7 @@ public partial class Utility
IEnumerable<Quote> quotes;
await using (var uow = _db.GetDbContext())
{
quotes = uow.Quotes.GetForGuild(ctx.Guild.Id).ToList();
quotes = uow.Set<Quote>().GetForGuild(ctx.Guild.Id).ToList();
}
var exprsDict = quotes.GroupBy(x => x.Keyword)
@@ -381,7 +381,7 @@ public partial class Utility
foreach (var entry in data)
{
var keyword = entry.Key;
await uow.Quotes.AddRangeAsync(entry.Value.Where(quote => !string.IsNullOrWhiteSpace(quote.Txt))
await uow.Set<Quote>().AddRangeAsync(entry.Value.Where(quote => !string.IsNullOrWhiteSpace(quote.Txt))
.Select(quote => new Quote
{
GuildId = guildId,

View File

@@ -102,9 +102,9 @@ public partial class Utility
await using (var uow = _db.GetDbContext())
{
if (isServer)
rems = uow.Reminders.RemindersForServer(ctx.Guild.Id, page).ToList();
rems = uow.Set<Reminder>().RemindersForServer(ctx.Guild.Id, page).ToList();
else
rems = uow.Reminders.RemindersFor(ctx.User.Id, page).ToList();
rems = uow.Set<Reminder>().RemindersFor(ctx.User.Id, page).ToList();
}
if (rems.Any())
@@ -150,14 +150,14 @@ public partial class Utility
await using (var uow = _db.GetDbContext())
{
var rems = isServer
? uow.Reminders.RemindersForServer(ctx.Guild.Id, index / 10).ToList()
: uow.Reminders.RemindersFor(ctx.User.Id, index / 10).ToList();
? uow.Set<Reminder>().RemindersForServer(ctx.Guild.Id, index / 10).ToList()
: uow.Set<Reminder>().RemindersFor(ctx.User.Id, index / 10).ToList();
var pageIndex = index % 10;
if (rems.Count > pageIndex)
{
rem = rems[pageIndex];
uow.Reminders.Remove(rem);
uow.Set<Reminder>().Remove(rem);
uow.SaveChanges();
}
}
@@ -198,7 +198,7 @@ public partial class Utility
await using (var uow = _db.GetDbContext())
{
uow.Reminders.Add(rem);
uow.Set<Reminder>().Add(rem);
await uow.SaveChangesAsync();
}

View File

@@ -79,7 +79,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService
private async Task RemoveReminders(IEnumerable<int> reminders)
{
await using var uow = _db.GetDbContext();
await uow.Reminders
await uow.Set<Reminder>()
.ToLinqToDBTable()
.DeleteAsync(x => reminders.Contains(x.Id));
@@ -89,7 +89,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService
private async Task<List<Reminder>> GetRemindersBeforeAsync(DateTime now)
{
await using var uow = _db.GetDbContext();
return await uow.Reminders
return await uow.Set<Reminder>()
.ToLinqToDBTable()
.Where(x => Linq2DbExpressions.GuildOnShard(x.ServerId, _creds.TotalShards, _client.ShardId)
&& x.When < now)
@@ -245,7 +245,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService
};
await using var ctx = _db.GetDbContext();
await ctx.Reminders
await ctx.Set<Reminder>()
.AddAsync(rem);
await ctx.SaveChangesAsync();
}

View File

@@ -122,7 +122,7 @@ public sealed class RepeaterService : IReadyExecutor, INService
{
await using var uow = _db.GetDbContext();
var toTrigger = await uow.Repeaters.AsNoTracking()
var toTrigger = await uow.Set<Repeater>().AsNoTracking()
.Where(x => x.GuildId == guildId)
.Skip(index)
.FirstOrDefaultAsyncEF();
@@ -276,7 +276,7 @@ public sealed class RepeaterService : IReadyExecutor, INService
_noRedundant.TryRemove(r.Id);
await using var uow = _db.GetDbContext();
await uow.Repeaters.DeleteAsync(x => x.Id == r.Id);
await uow.Set<Repeater>().DeleteAsync(x => x.Id == r.Id);
await uow.SaveChangesAsync();
}
@@ -297,7 +297,7 @@ public sealed class RepeaterService : IReadyExecutor, INService
private async Task SetRepeaterLastMessageInternal(int repeaterId, ulong lastMsgId)
{
await using var uow = _db.GetDbContext();
await uow.Repeaters.AsQueryable()
await uow.Set<Repeater>().AsQueryable()
.Where(x => x.Id == repeaterId)
.UpdateAsync(rep => new()
{
@@ -327,8 +327,8 @@ public sealed class RepeaterService : IReadyExecutor, INService
await using var uow = _db.GetDbContext();
if (await uow.Repeaters.CountAsyncEF(x => x.GuildId == guildId) < MAX_REPEATERS)
uow.Repeaters.Add(rep);
if (await uow.Set<Repeater>().CountAsyncEF(x => x.GuildId == guildId) < MAX_REPEATERS)
uow.Set<Repeater>().Add(rep);
else
return null;
@@ -347,7 +347,7 @@ public sealed class RepeaterService : IReadyExecutor, INService
throw new ArgumentOutOfRangeException(nameof(index));
await using var uow = _db.GetDbContext();
var toRemove = await uow.Repeaters.AsNoTracking()
var toRemove = await uow.Set<Repeater>().AsNoTracking()
.Where(x => x.GuildId == guildId)
.Skip(index)
.FirstOrDefaultAsyncEF();
@@ -362,7 +362,7 @@ public sealed class RepeaterService : IReadyExecutor, INService
return null;
_noRedundant.TryRemove(toRemove.Id);
uow.Repeaters.Remove(toRemove);
uow.Set<Repeater>().Remove(toRemove);
await uow.SaveChangesAsync();
return removed;
}
@@ -378,7 +378,7 @@ public sealed class RepeaterService : IReadyExecutor, INService
public async Task<bool?> ToggleRedundantAsync(ulong guildId, int index)
{
await using var uow = _db.GetDbContext();
var toToggle = await uow.Repeaters.AsQueryable()
var toToggle = await uow.Set<Repeater>().AsQueryable()
.Where(x => x.GuildId == guildId)
.Skip(index)
.FirstOrDefaultAsyncEF();
@@ -399,7 +399,7 @@ public sealed class RepeaterService : IReadyExecutor, INService
public async Task<bool?> ToggleSkipNextAsync(ulong guildId, int index)
{
await using var ctx = _db.GetDbContext();
var toSkip = await ctx.Repeaters
var toSkip = await ctx.Set<Repeater>()
.Where(x => x.GuildId == guildId)
.Skip(index)
.FirstOrDefaultAsyncEF();

View File

@@ -0,0 +1,19 @@
namespace NadekoBot.Modules.Xp;
public sealed partial class Xp
{
public class CleanupCommands : CleanupModuleBase
{
private readonly IXpCleanupService _service;
public CleanupCommands(IXpCleanupService service)
{
_service = service;
}
[Cmd]
[OwnerOnly]
public Task DeleteXp()
=> ConfirmActionInternalAsync("Delete Xp", () => _service.DeleteXp());
}
}

View File

@@ -34,7 +34,7 @@ public class ClubService : INService, IClubService
if (du.ClubId is not null)
return ClubCreateResult.AlreadyInAClub;
if (await uow.Clubs.AnyAsyncEF(x => x.Name == clubName))
if (await uow.Set<ClubInfo>().AnyAsyncEF(x => x.Name == clubName))
return ClubCreateResult.NameTaken;
du.IsClubAdmin = true;
@@ -43,7 +43,7 @@ public class ClubService : INService, IClubService
Name = clubName,
Owner = du
};
uow.Clubs.Add(du.Club);
uow.Set<ClubInfo>().Add(du.Club);
await uow.SaveChangesAsync();
await uow.GetTable<ClubApplicants>()
@@ -55,7 +55,7 @@ public class ClubService : INService, IClubService
public OneOf<ClubInfo, ClubTransferError> TransferClub(IUser from, IUser newOwner)
{
using var uow = _db.GetDbContext();
var club = uow.Clubs.GetByOwner(@from.Id);
var club = uow.Set<ClubInfo>().GetByOwner(@from.Id);
var newOwnerUser = uow.GetOrCreateUser(newOwner);
if (club is null || club.Owner.UserId != from.Id)
@@ -77,7 +77,7 @@ public class ClubService : INService, IClubService
return ToggleAdminResult.CantTargetThyself;
await using var uow = _db.GetDbContext();
var club = uow.Clubs.GetByOwner(owner.Id);
var club = uow.Set<ClubInfo>().GetByOwner(owner.Id);
var adminUser = uow.GetOrCreateUser(toAdmin);
if (club is null)
@@ -94,7 +94,7 @@ public class ClubService : INService, IClubService
public ClubInfo GetClubByMember(IUser user)
{
using var uow = _db.GetDbContext();
var member = uow.Clubs.GetByMember(user.Id);
var member = uow.Set<ClubInfo>().GetByMember(user.Id);
return member;
}
@@ -113,7 +113,7 @@ public class ClubService : INService, IClubService
}
await using var uow = _db.GetDbContext();
var club = uow.Clubs.GetByOwner(ownerUserId);
var club = uow.Set<ClubInfo>().GetByOwner(ownerUserId);
if (club is null)
return SetClubIconResult.NotOwner;
@@ -127,7 +127,7 @@ public class ClubService : INService, IClubService
public bool GetClubByName(string clubName, out ClubInfo club)
{
using var uow = _db.GetDbContext();
club = uow.Clubs.GetByName(clubName);
club = uow.Set<ClubInfo>().GetByName(clubName);
return club is not null;
}
@@ -165,7 +165,7 @@ public class ClubService : INService, IClubService
{
discordUser = null;
using var uow = _db.GetDbContext();
var club = uow.Clubs.GetByOwnerOrAdmin(clubOwnerUserId);
var club = uow.Set<ClubInfo>().GetByOwnerOrAdmin(clubOwnerUserId);
if (club is null)
return ClubAcceptResult.NotOwnerOrAdmin;
@@ -190,7 +190,7 @@ public class ClubService : INService, IClubService
public ClubInfo GetClubWithBansAndApplications(ulong ownerUserId)
{
using var uow = _db.GetDbContext();
return uow.Clubs.GetByOwnerOrAdmin(ownerUserId);
return uow.Set<ClubInfo>().GetByOwnerOrAdmin(ownerUserId);
}
public ClubLeaveResult LeaveClub(IUser user)
@@ -211,7 +211,7 @@ public class ClubService : INService, IClubService
public bool SetDescription(ulong userId, string desc)
{
using var uow = _db.GetDbContext();
var club = uow.Clubs.GetByOwner(userId);
var club = uow.Set<ClubInfo>().GetByOwner(userId);
if (club is null)
return false;
@@ -224,11 +224,11 @@ public class ClubService : INService, IClubService
public bool Disband(ulong userId, out ClubInfo club)
{
using var uow = _db.GetDbContext();
club = uow.Clubs.GetByOwner(userId);
club = uow.Set<ClubInfo>().GetByOwner(userId);
if (club is null)
return false;
uow.Clubs.Remove(club);
uow.Set<ClubInfo>().Remove(club);
uow.SaveChanges();
return true;
}
@@ -236,7 +236,7 @@ public class ClubService : INService, IClubService
public ClubBanResult Ban(ulong bannerId, string userName, out ClubInfo club)
{
using var uow = _db.GetDbContext();
club = uow.Clubs.GetByOwnerOrAdmin(bannerId);
club = uow.Set<ClubInfo>().GetByOwnerOrAdmin(bannerId);
if (club is null)
return ClubBanResult.NotOwnerOrAdmin;
@@ -270,7 +270,7 @@ public class ClubService : INService, IClubService
public ClubUnbanResult UnBan(ulong ownerUserId, string userName, out ClubInfo club)
{
using var uow = _db.GetDbContext();
club = uow.Clubs.GetByOwnerOrAdmin(ownerUserId);
club = uow.Set<ClubInfo>().GetByOwnerOrAdmin(ownerUserId);
if (club is null)
return ClubUnbanResult.NotOwnerOrAdmin;
@@ -288,7 +288,7 @@ public class ClubService : INService, IClubService
public ClubKickResult Kick(ulong kickerId, string userName, out ClubInfo club)
{
using var uow = _db.GetDbContext();
club = uow.Clubs.GetByOwnerOrAdmin(kickerId);
club = uow.Set<ClubInfo>().GetByOwnerOrAdmin(kickerId);
if (club is null)
return ClubKickResult.NotOwnerOrAdmin;
@@ -314,6 +314,6 @@ public class ClubService : INService, IClubService
throw new ArgumentOutOfRangeException(nameof(page));
using var uow = _db.GetDbContext();
return uow.Clubs.GetClubLeaderboardPage(page);
return uow.Set<ClubInfo>().GetClubLeaderboardPage(page);
}
}

View File

@@ -189,7 +189,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
// group by xp amount and update the same amounts at the same time
foreach (var group in globalToAdd.GroupBy(x => x.Value.XpAmount, x => x.Key))
{
var items = await ctx.DiscordUser
var items = await ctx.Set<DiscordUser>()
.Where(x => group.Contains(x.UserId))
.UpdateWithOutputAsync(old => new()
{
@@ -197,7 +197,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
},
(_, n) => n);
await ctx.Clubs
await ctx.Set<ClubInfo>()
.Where(x => x.Members.Any(m => group.Contains(m.UserId)))
.UpdateAsync(old => new()
{
@@ -212,7 +212,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
foreach (var group in toAdd.GroupBy(x => x.Value.XpAmount, x => x.Key))
{
var items = await ctx
.UserXpStats
.Set<UserXpStats>()
.Where(x => x.GuildId == guildId)
.Where(x => group.Contains(x.UserId))
.UpdateWithOutputAsync(old => new()
@@ -227,7 +227,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
foreach (var userId in missingUserIds)
{
await ctx
.UserXpStats
.Set<UserXpStats>()
.ToLinqToDBTable()
.InsertOrUpdateAsync(() => new UserXpStats()
{
@@ -250,7 +250,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
if (missingUserIds.Length > 0)
{
var missingItems = await ctx.UserXpStats
var missingItems = await ctx.Set<UserXpStats>()
.ToLinqToDBTable()
.Where(x => missingUserIds.Contains(x.UserId))
.ToArrayAsyncLinqToDB();
@@ -559,19 +559,19 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
public List<UserXpStats> GetUserXps(ulong guildId, int page)
{
using var uow = _db.GetDbContext();
return uow.UserXpStats.GetUsersFor(guildId, page);
return uow.Set<UserXpStats>().GetUsersFor(guildId, page);
}
public List<UserXpStats> GetTopUserXps(ulong guildId, int count)
{
using var uow = _db.GetDbContext();
return uow.UserXpStats.GetTopUserXps(guildId, count);
return uow.Set<UserXpStats>().GetTopUserXps(guildId, count);
}
public DiscordUser[] GetUserXps(int page)
{
using var uow = _db.GetDbContext();
return uow.DiscordUser.GetUsersXpLeaderboardFor(page);
return uow.Set<DiscordUser>().GetUsersXpLeaderboardFor(page);
}
public async Task ChangeNotificationType(ulong userId, ulong guildId, XpNotificationLocation type)
@@ -876,8 +876,8 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
await using var uow = _db.GetDbContext();
var du = uow.GetOrCreateUser(user, set => set.Include(x => x.Club));
var totalXp = du.TotalXp;
var globalRank = uow.DiscordUser.GetUserGlobalRank(user.Id);
var guildRank = uow.UserXpStats.GetUserGuildRanking(user.Id, user.GuildId);
var globalRank = uow.Set<DiscordUser>().GetUserGlobalRank(user.Id);
var guildRank = uow.Set<UserXpStats>().GetUserGuildRanking(user.Id, user.GuildId);
var stats = uow.GetOrCreateUserXpStats(user.GuildId, user.Id);
await uow.SaveChangesAsync();
@@ -1396,14 +1396,14 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
public void XpReset(ulong guildId, ulong userId)
{
using var uow = _db.GetDbContext();
uow.UserXpStats.ResetGuildUserXp(userId, guildId);
uow.Set<UserXpStats>().ResetGuildUserXp(userId, guildId);
uow.SaveChanges();
}
public void XpReset(ulong guildId)
{
using var uow = _db.GetDbContext();
uow.UserXpStats.ResetGuildXp(guildId);
uow.Set<UserXpStats>().ResetGuildXp(guildId);
uow.SaveChanges();
}

View File

@@ -0,0 +1,6 @@
namespace NadekoBot.Modules.Xp;
public interface IXpCleanupService
{
Task DeleteXp();
}

View File

@@ -0,0 +1,32 @@
using LinqToDB;
using NadekoBot.Db.Models;
using NadekoBot.Services.Database.Models;
namespace NadekoBot.Modules.Xp;
public sealed class XpCleanupService : IXpCleanupService
{
private readonly DbService _db;
public XpCleanupService(DbService db)
{
_db = db;
}
public async Task DeleteXp()
{
await using var uow = _db.GetDbContext();
await uow.Set<DiscordUser>().UpdateAsync(_ => new DiscordUser()
{
ClubId = null,
// IsClubAdmin = false,
TotalXp = 0
});
await uow.Set<UserXpStats>().DeleteAsync();
await uow.Set<ClubApplicants>().DeleteAsync();
await uow.Set<ClubBans>().DeleteAsync();
await uow.Set<ClubInfo>().DeleteAsync();
await uow.SaveChangesAsync();
}
}

View File

@@ -14,6 +14,7 @@ using NadekoBot.Modules.Permissions;
using NadekoBot.Modules.Searches;
using NadekoBot.Modules.Utility;
using NadekoBot.Modules.Xp;
using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
using Ninject;
using Ninject.Planning;
@@ -56,7 +57,7 @@ public sealed class Bot : IBot
_credsProvider = new BotCredsProvider(totalShards, credPath);
_creds = _credsProvider.GetCreds();
_db = new(_credsProvider);
_db = new NadekoDbService(_credsProvider);
var messageCacheSize =
#if GLOBAL_NADEKO
@@ -120,7 +121,7 @@ public sealed class Bot : IBot
using (var uow = _db.GetDbContext())
{
uow.EnsureUserCreated(bot.Id, bot.Username, bot.Discriminator, bot.AvatarId);
AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs(startingGuildIdList).ToImmutableArray();
AllGuildConfigs = uow.Set<GuildConfig>().GetAllGuildConfigs(startingGuildIdList).ToImmutableArray();
}
var svcs = new StandardKernel(new NinjectSettings()