mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-03 16:24:27 -05:00 
			
		
		
		
	Split dangerous commands into cleanup commands for each module they belong to
This commit is contained in:
		@@ -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()
 | 
			
		||||
                 {
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
                                .Where(w => !w.Forgiven && w.UserId == userId)
 | 
			
		||||
                                .Sum(x => x.Weight);
 | 
			
		||||
            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();
 | 
			
		||||
        }
 | 
			
		||||
@@ -99,9 +99,9 @@ public class UserPunishService : INService, IReadyExecutor
 | 
			
		||||
        _ = OnUserWarned(warn);
 | 
			
		||||
 | 
			
		||||
        var totalCount = previousCount + weight;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        var p = ps.Where(x => x.Count > previousCount && x.Count <= totalCount)
 | 
			
		||||
                  .MaxBy(x => x.Count);
 | 
			
		||||
            .MaxBy(x => x.Count);
 | 
			
		||||
 | 
			
		||||
        if (p is not null)
 | 
			
		||||
        {
 | 
			
		||||
@@ -241,34 +241,34 @@ public class UserPunishService : INService, IReadyExecutor
 | 
			
		||||
    public async Task CheckAllWarnExpiresAsync()
 | 
			
		||||
    {
 | 
			
		||||
        await using var uow = _db.GetDbContext();
 | 
			
		||||
        var cleared = await uow.Warnings
 | 
			
		||||
                               .Where(x => uow.GuildConfigs
 | 
			
		||||
                                                 .Any(y => y.GuildId == x.GuildId
 | 
			
		||||
                                                           && y.WarnExpireHours > 0
 | 
			
		||||
                                                           && y.WarnExpireAction == WarnExpireAction.Clear)
 | 
			
		||||
                                           && x.Forgiven == false 
 | 
			
		||||
                                           && x.DateAdded
 | 
			
		||||
                                           < DateTime.UtcNow.AddHours(-uow.GuildConfigs
 | 
			
		||||
                                                                          .Where(y => x.GuildId == y.GuildId)
 | 
			
		||||
                                                                          .Select(y => y.WarnExpireHours)
 | 
			
		||||
                                                                          .First()))
 | 
			
		||||
                               .UpdateAsync(_ => new()
 | 
			
		||||
                               {
 | 
			
		||||
                                   Forgiven = true,
 | 
			
		||||
                                   ForgivenBy = "expiry"
 | 
			
		||||
                               });
 | 
			
		||||
        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.Set<GuildConfig>()
 | 
			
		||||
                            .Where(y => x.GuildId == y.GuildId)
 | 
			
		||||
                            .Select(y => y.WarnExpireHours)
 | 
			
		||||
                            .First()))
 | 
			
		||||
            .UpdateAsync(_ => new()
 | 
			
		||||
            {
 | 
			
		||||
                Forgiven = true,
 | 
			
		||||
                ForgivenBy = "expiry"
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        var deleted = await uow.Warnings
 | 
			
		||||
                               .Where(x => uow.GuildConfigs
 | 
			
		||||
                                              .Any(y => y.GuildId == x.GuildId
 | 
			
		||||
                                                        && y.WarnExpireHours > 0
 | 
			
		||||
                                                        && y.WarnExpireAction == WarnExpireAction.Delete)
 | 
			
		||||
                                           && x.DateAdded
 | 
			
		||||
                                           < DateTime.UtcNow.AddHours(-uow.GuildConfigs
 | 
			
		||||
                                                                          .Where(y => x.GuildId == y.GuildId)
 | 
			
		||||
                                                                          .Select(y => y.WarnExpireHours)
 | 
			
		||||
                                                                          .First()))
 | 
			
		||||
                               .DeleteAsync();
 | 
			
		||||
        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.Set<GuildConfig>()
 | 
			
		||||
                            .Where(y => x.GuildId == y.GuildId)
 | 
			
		||||
                            .Select(y => y.WarnExpireHours)
 | 
			
		||||
                            .First()))
 | 
			
		||||
            .DeleteAsync();
 | 
			
		||||
 | 
			
		||||
        if (cleared > 0 || deleted > 0)
 | 
			
		||||
        {
 | 
			
		||||
@@ -290,22 +290,22 @@ public class UserPunishService : INService, IReadyExecutor
 | 
			
		||||
 | 
			
		||||
        if (config.WarnExpireAction == WarnExpireAction.Clear)
 | 
			
		||||
        {
 | 
			
		||||
            await uow.Warnings
 | 
			
		||||
                     .Where(x => x.GuildId == guildId
 | 
			
		||||
                                 && x.Forgiven == false
 | 
			
		||||
                                 && x.DateAdded < DateTime.UtcNow.AddHours(-config.WarnExpireHours))
 | 
			
		||||
                     .UpdateAsync(_ => new()
 | 
			
		||||
                     {
 | 
			
		||||
                         Forgiven = true,
 | 
			
		||||
                         ForgivenBy = "expiry"
 | 
			
		||||
                     });
 | 
			
		||||
            await uow.Set<Warning>()
 | 
			
		||||
                .Where(x => x.GuildId == guildId
 | 
			
		||||
                            && x.Forgiven == false
 | 
			
		||||
                            && x.DateAdded < DateTime.UtcNow.AddHours(-config.WarnExpireHours))
 | 
			
		||||
                .UpdateAsync(_ => new()
 | 
			
		||||
                {
 | 
			
		||||
                    Forgiven = true,
 | 
			
		||||
                    ForgivenBy = "expiry"
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
        else if (config.WarnExpireAction == WarnExpireAction.Delete)
 | 
			
		||||
        {
 | 
			
		||||
            await uow.Warnings
 | 
			
		||||
                     .Where(x => x.GuildId == guildId
 | 
			
		||||
                                 && x.DateAdded < DateTime.UtcNow.AddHours(-config.WarnExpireHours))
 | 
			
		||||
                     .DeleteAsync();
 | 
			
		||||
            await uow.Set<Warning>()
 | 
			
		||||
                .Where(x => x.GuildId == guildId
 | 
			
		||||
                            && x.DateAdded < DateTime.UtcNow.AddHours(-config.WarnExpireHours))
 | 
			
		||||
                .DeleteAsync();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await uow.SaveChangesAsync();
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
@@ -423,8 +423,8 @@ public class UserPunishService : INService, IReadyExecutor
 | 
			
		||||
    {
 | 
			
		||||
        using var uow = _db.GetDbContext();
 | 
			
		||||
        return uow.GuildConfigsForId(guildId, gc => gc.Include(x => x.WarnPunishments))
 | 
			
		||||
                  .WarnPunishments.OrderBy(x => x.Count)
 | 
			
		||||
                  .ToArray();
 | 
			
		||||
            .WarnPunishments.OrderBy(x => x.Count)
 | 
			
		||||
            .ToArray();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public (IReadOnlyCollection<(string Original, ulong? Id, string Reason)> Bans, int Missing) MassKill(
 | 
			
		||||
@@ -434,20 +434,20 @@ public class UserPunishService : INService, IReadyExecutor
 | 
			
		||||
        var gusers = guild.Users;
 | 
			
		||||
        //get user objects and reasons
 | 
			
		||||
        var bans = people.Split("\n")
 | 
			
		||||
                         .Select(x =>
 | 
			
		||||
                         {
 | 
			
		||||
                             var split = x.Trim().Split(" ");
 | 
			
		||||
            .Select(x =>
 | 
			
		||||
            {
 | 
			
		||||
                var split = x.Trim().Split(" ");
 | 
			
		||||
 | 
			
		||||
                             var reason = string.Join(" ", split.Skip(1));
 | 
			
		||||
                var reason = string.Join(" ", split.Skip(1));
 | 
			
		||||
 | 
			
		||||
                             if (ulong.TryParse(split[0], out var id))
 | 
			
		||||
                                 return (Original: split[0], Id: id, Reason: reason);
 | 
			
		||||
                if (ulong.TryParse(split[0], out var id))
 | 
			
		||||
                    return (Original: split[0], Id: id, Reason: reason);
 | 
			
		||||
 | 
			
		||||
                             return (Original: split[0],
 | 
			
		||||
                                 gusers.FirstOrDefault(u => u.ToString().ToLowerInvariant() == x)?.Id,
 | 
			
		||||
                                 Reason: reason);
 | 
			
		||||
                         })
 | 
			
		||||
                         .ToArray();
 | 
			
		||||
                return (Original: split[0],
 | 
			
		||||
                    gusers.FirstOrDefault(u => u.ToString().ToLowerInvariant() == x)?.Id,
 | 
			
		||||
                    Reason: reason);
 | 
			
		||||
            })
 | 
			
		||||
            .ToArray();
 | 
			
		||||
 | 
			
		||||
        //if user is null, means that person couldn't be found
 | 
			
		||||
        var missing = bans.Count(x => !x.Id.HasValue);
 | 
			
		||||
@@ -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();
 | 
			
		||||
@@ -552,19 +552,19 @@ public class UserPunishService : INService, IReadyExecutor
 | 
			
		||||
        banReason = string.IsNullOrWhiteSpace(banReason) ? "-" : banReason;
 | 
			
		||||
 | 
			
		||||
        var replacer = new ReplacementBuilder().WithServer(client, guild)
 | 
			
		||||
                                               .WithOverride("%ban.mod%", () => moderator.ToString())
 | 
			
		||||
                                               .WithOverride("%ban.mod.fullname%", () => moderator.ToString())
 | 
			
		||||
                                               .WithOverride("%ban.mod.name%", () => moderator.Username)
 | 
			
		||||
                                               .WithOverride("%ban.mod.discrim%", () => moderator.Discriminator)
 | 
			
		||||
                                               .WithOverride("%ban.user%", () => target.ToString())
 | 
			
		||||
                                               .WithOverride("%ban.user.fullname%", () => target.ToString())
 | 
			
		||||
                                               .WithOverride("%ban.user.name%", () => target.Username)
 | 
			
		||||
                                               .WithOverride("%ban.user.discrim%", () => target.Discriminator)
 | 
			
		||||
                                               .WithOverride("%reason%", () => banReason)
 | 
			
		||||
                                               .WithOverride("%ban.reason%", () => banReason)
 | 
			
		||||
                                               .WithOverride("%ban.duration%",
 | 
			
		||||
                                                   () => duration?.ToString(@"d\.hh\:mm") ?? "perma")
 | 
			
		||||
                                               .Build();
 | 
			
		||||
            .WithOverride("%ban.mod%", () => moderator.ToString())
 | 
			
		||||
            .WithOverride("%ban.mod.fullname%", () => moderator.ToString())
 | 
			
		||||
            .WithOverride("%ban.mod.name%", () => moderator.Username)
 | 
			
		||||
            .WithOverride("%ban.mod.discrim%", () => moderator.Discriminator)
 | 
			
		||||
            .WithOverride("%ban.user%", () => target.ToString())
 | 
			
		||||
            .WithOverride("%ban.user.fullname%", () => target.ToString())
 | 
			
		||||
            .WithOverride("%ban.user.name%", () => target.Username)
 | 
			
		||||
            .WithOverride("%ban.user.discrim%", () => target.Discriminator)
 | 
			
		||||
            .WithOverride("%reason%", () => banReason)
 | 
			
		||||
            .WithOverride("%ban.reason%", () => banReason)
 | 
			
		||||
            .WithOverride("%ban.duration%",
 | 
			
		||||
                () => duration?.ToString(@"d\.hh\:mm") ?? "perma")
 | 
			
		||||
            .Build();
 | 
			
		||||
 | 
			
		||||
        // if template isn't set, use the old message style
 | 
			
		||||
        if (string.IsNullOrWhiteSpace(template))
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user