mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-04 08:34:27 -05:00 
			
		
		
		
	Using pattern matching for nulls where applicable, discarded unused lambda parameters, cleaned up some classes. Unignored ServerLog commands which was mistakenly ignored due to a .gitignore rule
This commit is contained in:
		@@ -315,7 +315,7 @@ public sealed class Bot
 | 
			
		||||
 | 
			
		||||
    private Task Client_Log(LogMessage arg)
 | 
			
		||||
    {
 | 
			
		||||
        if (arg.Exception != null)
 | 
			
		||||
        if (arg.Exception is not null)
 | 
			
		||||
            Log.Warning(arg.Exception, "{ErrorSource} | {ErrorMessage}", arg.Source, arg.Message);
 | 
			
		||||
        else
 | 
			
		||||
            Log.Warning("{ErrorSource} | {ErrorMessage}", arg.Source, arg.Message);
 | 
			
		||||
 
 | 
			
		||||
@@ -342,7 +342,7 @@ public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ICollection<T
 | 
			
		||||
        // The Volatile.Read ensures that the load of the fields of 'n' doesn't move before the load from buckets[i].
 | 
			
		||||
        var current = Volatile.Read(ref tables.Buckets[bucketNo]);
 | 
			
		||||
 | 
			
		||||
        while (current != null)
 | 
			
		||||
        while (current is not null)
 | 
			
		||||
        {
 | 
			
		||||
            if (hashcode == current.Hashcode && _comparer.Equals(current.Item, item))
 | 
			
		||||
                return true;
 | 
			
		||||
@@ -410,7 +410,7 @@ public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ICollection<T
 | 
			
		||||
            // The Volatile.Read ensures that the load of the fields of 'current' doesn't move before the load from buckets[i].
 | 
			
		||||
            var current = Volatile.Read(ref buckets[i]);
 | 
			
		||||
 | 
			
		||||
            while (current != null)
 | 
			
		||||
            while (current is not null)
 | 
			
		||||
            {
 | 
			
		||||
                yield return current.Item;
 | 
			
		||||
                current = current.Next;
 | 
			
		||||
@@ -454,7 +454,7 @@ public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ICollection<T
 | 
			
		||||
                if (tables != _tables) continue;
 | 
			
		||||
 | 
			
		||||
                Node previous = null;
 | 
			
		||||
                for (var current = tables.Buckets[bucketNo]; current != null; current = current.Next)
 | 
			
		||||
                for (var current = tables.Buckets[bucketNo]; current is not null; current = current.Next)
 | 
			
		||||
                {
 | 
			
		||||
                    Debug.Assert((previous is null && current == tables.Buckets[bucketNo]) || previous.Next == current);
 | 
			
		||||
 | 
			
		||||
@@ -504,7 +504,7 @@ public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ICollection<T
 | 
			
		||||
 | 
			
		||||
                // Try to find this item in the bucket
 | 
			
		||||
                Node previous = null;
 | 
			
		||||
                for (var current = tables.Buckets[bucketNo]; current != null; current = current.Next)
 | 
			
		||||
                for (var current = tables.Buckets[bucketNo]; current is not null; current = current.Next)
 | 
			
		||||
                {
 | 
			
		||||
                    Debug.Assert((previous is null && current == tables.Buckets[bucketNo]) || previous.Next == current);
 | 
			
		||||
                    if (hashcode == current.Hashcode && _comparer.Equals(current.Item, item))
 | 
			
		||||
@@ -656,7 +656,7 @@ public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ICollection<T
 | 
			
		||||
            for (var i = 0; i < tables.Buckets.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                var current = tables.Buckets[i];
 | 
			
		||||
                while (current != null)
 | 
			
		||||
                while (current is not null)
 | 
			
		||||
                {
 | 
			
		||||
                    var next = current.Next;
 | 
			
		||||
                    GetBucketAndLockNo(current.Hashcode,
 | 
			
		||||
@@ -741,7 +741,7 @@ public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ICollection<T
 | 
			
		||||
    {
 | 
			
		||||
        var buckets = _tables.Buckets;
 | 
			
		||||
        for (var i = 0; i < buckets.Length; i++)
 | 
			
		||||
        for (var current = buckets[i]; current != null; current = current.Next)
 | 
			
		||||
        for (var current = buckets[i]; current is not null; current = current.Next)
 | 
			
		||||
        {
 | 
			
		||||
            array[index] = current.Item;
 | 
			
		||||
            index++; //this should never flow, CopyToItems is only called when there's no overflow risk
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ public static class OptionsParser
 | 
			
		||||
            x.HelpWriter = null;
 | 
			
		||||
        });
 | 
			
		||||
        var res = p.ParseArguments<T>(args);
 | 
			
		||||
        options = res.MapResult(x => x, x => options);
 | 
			
		||||
        options = res.MapResult(x => x, _ => options);
 | 
			
		||||
        options.NormalizeOptions();
 | 
			
		||||
        return (options, res.Tag == ParserResultType.Parsed);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ public class ReplacementBuilder
 | 
			
		||||
            () =>
 | 
			
		||||
            {
 | 
			
		||||
                var to = TimeZoneInfo.Local;
 | 
			
		||||
                if (g != null)
 | 
			
		||||
                if (g is not null)
 | 
			
		||||
                    if (GuildTimezoneService.AllServices.TryGetValue(client.CurrentUser.Id, out var tz))
 | 
			
		||||
                        to = tz.GetTimeZoneOrDefault(g.Id) ?? TimeZoneInfo.Local;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,13 +50,13 @@ public class Replacer
 | 
			
		||||
            Image = Replace(embedData.Image),
 | 
			
		||||
            Url = Replace(embedData.Url)
 | 
			
		||||
        };
 | 
			
		||||
        if (embedData.Author != null)
 | 
			
		||||
        if (embedData.Author is not null)
 | 
			
		||||
            newEmbedData.Author = new()
 | 
			
		||||
            {
 | 
			
		||||
                Name = Replace(embedData.Author.Name), IconUrl = Replace(embedData.Author.IconUrl)
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        if (embedData.Fields != null)
 | 
			
		||||
        if (embedData.Fields is not null)
 | 
			
		||||
        {
 | 
			
		||||
            var fields = new List<SmartTextEmbedField>();
 | 
			
		||||
            foreach (var f in embedData.Fields)
 | 
			
		||||
@@ -71,7 +71,7 @@ public class Replacer
 | 
			
		||||
            newEmbedData.Fields = fields.ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (embedData.Footer != null)
 | 
			
		||||
        if (embedData.Footer is not null)
 | 
			
		||||
            newEmbedData.Footer = new()
 | 
			
		||||
            {
 | 
			
		||||
                Text = Replace(embedData.Footer.Text), IconUrl = Replace(embedData.Footer.IconUrl)
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ public sealed record SmartEmbedText : SmartText
 | 
			
		||||
           || !string.IsNullOrWhiteSpace(Url)
 | 
			
		||||
           || !string.IsNullOrWhiteSpace(Thumbnail)
 | 
			
		||||
           || !string.IsNullOrWhiteSpace(Image)
 | 
			
		||||
           || (Footer != null
 | 
			
		||||
           || (Footer is not null
 | 
			
		||||
               && (!string.IsNullOrWhiteSpace(Footer.Text) || !string.IsNullOrWhiteSpace(Footer.IconUrl)))
 | 
			
		||||
           || Fields is { Length: > 0 };
 | 
			
		||||
 | 
			
		||||
@@ -62,10 +62,10 @@ public sealed record SmartEmbedText : SmartText
 | 
			
		||||
        if (!string.IsNullOrWhiteSpace(Description))
 | 
			
		||||
            embed.WithDescription(Description);
 | 
			
		||||
 | 
			
		||||
        if (Url != null && Uri.IsWellFormedUriString(Url, UriKind.Absolute))
 | 
			
		||||
        if (Url is not null && Uri.IsWellFormedUriString(Url, UriKind.Absolute))
 | 
			
		||||
            embed.WithUrl(Url);
 | 
			
		||||
 | 
			
		||||
        if (Footer != null)
 | 
			
		||||
        if (Footer is not null)
 | 
			
		||||
            embed.WithFooter(efb =>
 | 
			
		||||
            {
 | 
			
		||||
                efb.WithText(Footer.Text);
 | 
			
		||||
@@ -73,13 +73,13 @@ public sealed record SmartEmbedText : SmartText
 | 
			
		||||
                    efb.WithIconUrl(Footer.IconUrl);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        if (Thumbnail != null && Uri.IsWellFormedUriString(Thumbnail, UriKind.Absolute))
 | 
			
		||||
        if (Thumbnail is not null && Uri.IsWellFormedUriString(Thumbnail, UriKind.Absolute))
 | 
			
		||||
            embed.WithThumbnailUrl(Thumbnail);
 | 
			
		||||
 | 
			
		||||
        if (Image != null && Uri.IsWellFormedUriString(Image, UriKind.Absolute))
 | 
			
		||||
        if (Image is not null && Uri.IsWellFormedUriString(Image, UriKind.Absolute))
 | 
			
		||||
            embed.WithImageUrl(Image);
 | 
			
		||||
 | 
			
		||||
        if (Author != null && !string.IsNullOrWhiteSpace(Author.Name))
 | 
			
		||||
        if (Author is not null && !string.IsNullOrWhiteSpace(Author.Name))
 | 
			
		||||
        {
 | 
			
		||||
            if (!Uri.IsWellFormedUriString(Author.IconUrl, UriKind.Absolute))
 | 
			
		||||
                Author.IconUrl = null;
 | 
			
		||||
@@ -89,7 +89,7 @@ public sealed record SmartEmbedText : SmartText
 | 
			
		||||
            embed.WithAuthor(Author.Name, Author.IconUrl, Author.Url);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (Fields != null)
 | 
			
		||||
        if (Fields is not null)
 | 
			
		||||
            foreach (var f in Fields)
 | 
			
		||||
                if (!string.IsNullOrWhiteSpace(f.Name) && !string.IsNullOrWhiteSpace(f.Value))
 | 
			
		||||
                    embed.AddField(f.Name, f.Value, f.Inline);
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ public sealed class GuildTypeReader : NadekoTypeReader<IGuild>
 | 
			
		||||
                    ?? //by id
 | 
			
		||||
                    guilds.FirstOrDefault(g => g.Name.Trim().ToUpperInvariant() == input); //by name
 | 
			
		||||
 | 
			
		||||
        if (guild != null)
 | 
			
		||||
        if (guild is not null)
 | 
			
		||||
            return Task.FromResult(TypeReaderResult.FromSuccess(guild));
 | 
			
		||||
 | 
			
		||||
        return Task.FromResult(
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ public class CommentGatheringTypeInspector : TypeInspectorSkeleton
 | 
			
		||||
        public IObjectDescriptor Read(object target)
 | 
			
		||||
        {
 | 
			
		||||
            var comment = baseDescriptor.GetCustomAttribute<CommentAttribute>();
 | 
			
		||||
            return comment != null
 | 
			
		||||
            return comment is not null
 | 
			
		||||
                ? new CommentsObjectDescriptor(baseDescriptor.Read(target), comment.Comment)
 | 
			
		||||
                : baseDescriptor.Read(target);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -17,13 +17,13 @@ public static class PollExtensions
 | 
			
		||||
        if (p is null)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (p.Votes != null)
 | 
			
		||||
        if (p.Votes is not null)
 | 
			
		||||
        {
 | 
			
		||||
            ctx.RemoveRange(p.Votes);
 | 
			
		||||
            p.Votes.Clear();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (p.Answers != null)
 | 
			
		||||
        if (p.Answers is not null)
 | 
			
		||||
        {
 | 
			
		||||
            ctx.RemoveRange(p.Answers);
 | 
			
		||||
            p.Answers.Clear();
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ public static class QuoteExtensions
 | 
			
		||||
    {
 | 
			
		||||
        var rng = new NadekoRandom();
 | 
			
		||||
        return (await quotes.AsQueryable().Where(q => q.GuildId == guildId && q.Keyword == keyword).ToListAsync())
 | 
			
		||||
               .OrderBy(q => rng.Next())
 | 
			
		||||
               .OrderBy(_ => rng.Next())
 | 
			
		||||
               .FirstOrDefault();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -48,7 +48,7 @@ public static class QuoteExtensions
 | 
			
		||||
                                        && EF.Functions.Like(q.Text.ToUpper(), $"%{text.ToUpper()}%")
 | 
			
		||||
                                // && q.Text.Contains(text, StringComparison.OrdinalIgnoreCase)
 | 
			
		||||
                            )
 | 
			
		||||
                            .ToListAsync()).OrderBy(q => rngk.Next())
 | 
			
		||||
                            .ToListAsync()).OrderBy(_ => rngk.Next())
 | 
			
		||||
                                           .FirstOrDefault();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ public class WaifuInfo : DbEntity
 | 
			
		||||
        var waifuUsername = Waifu.Username.TrimTo(20);
 | 
			
		||||
        var claimerUsername = Claimer?.Username.TrimTo(20);
 | 
			
		||||
 | 
			
		||||
        if (ClaimerId != null) claimer = $"{claimerUsername}#{Claimer.Discriminator}";
 | 
			
		||||
        if (ClaimerId is not null) claimer = $"{claimerUsername}#{Claimer.Discriminator}";
 | 
			
		||||
        if (AffinityId is null)
 | 
			
		||||
            status = $"... but {waifuUsername}'s heart is empty";
 | 
			
		||||
        else if (AffinityId == ClaimerId)
 | 
			
		||||
@@ -58,7 +58,7 @@ public class WaifuLbResult
 | 
			
		||||
        var waifuUsername = Username.TrimTo(20);
 | 
			
		||||
        var claimerUsername = Claimer?.TrimTo(20);
 | 
			
		||||
 | 
			
		||||
        if (Claimer != null) claimer = $"{claimerUsername}#{ClaimerDiscrim}";
 | 
			
		||||
        if (Claimer is not null) claimer = $"{claimerUsername}#{ClaimerDiscrim}";
 | 
			
		||||
        if (Affinity is null)
 | 
			
		||||
            status = $"... but {waifuUsername}'s heart is empty";
 | 
			
		||||
        else if (Affinity + AffinityDiscrim == Claimer + ClaimerDiscrim)
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ public class GameVoiceChannelService : INService
 | 
			
		||||
        _db = db;
 | 
			
		||||
        _client = client;
 | 
			
		||||
 | 
			
		||||
        GameVoiceChannels = new(bot.AllGuildConfigs.Where(gc => gc.GameVoiceChannel != null)
 | 
			
		||||
        GameVoiceChannels = new(bot.AllGuildConfigs.Where(gc => gc.GameVoiceChannel is not null)
 | 
			
		||||
                                   .Select(gc => gc.GameVoiceChannel.Value));
 | 
			
		||||
 | 
			
		||||
        _client.UserVoiceStateUpdated += Client_UserVoiceStateUpdated;
 | 
			
		||||
@@ -62,7 +62,7 @@ public class GameVoiceChannelService : INService
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (gc.GameVoiceChannel != null)
 | 
			
		||||
            if (gc.GameVoiceChannel is not null)
 | 
			
		||||
                GameVoiceChannels.TryRemove(gc.GameVoiceChannel.Value);
 | 
			
		||||
            GameVoiceChannels.Add(vchId);
 | 
			
		||||
            id = gc.GameVoiceChannel = vchId;
 | 
			
		||||
 
 | 
			
		||||
@@ -240,7 +240,7 @@ public class GreetService : INService
 | 
			
		||||
                if (conf.SendChannelGreetMessage)
 | 
			
		||||
                {
 | 
			
		||||
                    var channel = await user.Guild.GetTextChannelAsync(conf.GreetMessageChannelId);
 | 
			
		||||
                    if (channel != null)
 | 
			
		||||
                    if (channel is not null)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (GroupGreets)
 | 
			
		||||
                        {
 | 
			
		||||
 
 | 
			
		||||
@@ -176,7 +176,7 @@ public class MuteService : INService
 | 
			
		||||
        await using var uow = _db.GetDbContext();
 | 
			
		||||
        var config = uow.GuildConfigsForId(guildId, set => set);
 | 
			
		||||
        config.MuteRoleName = name;
 | 
			
		||||
        GuildMuteRoles.AddOrUpdate(guildId, name, (id, old) => name);
 | 
			
		||||
        GuildMuteRoles.AddOrUpdate(guildId, name, (_, _) => name);
 | 
			
		||||
        await uow.SaveChangesAsync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -243,7 +243,7 @@ public class MuteService : INService
 | 
			
		||||
                    set => set.Include(gc => gc.MutedUsers).Include(gc => gc.UnmuteTimers));
 | 
			
		||||
                var match = new MutedUserId { UserId = usrId };
 | 
			
		||||
                var toRemove = config.MutedUsers.FirstOrDefault(x => x.Equals(match));
 | 
			
		||||
                if (toRemove != null) uow.Remove(toRemove);
 | 
			
		||||
                if (toRemove is not null) uow.Remove(toRemove);
 | 
			
		||||
                if (MutedUsers.TryGetValue(guildId, out var muted))
 | 
			
		||||
                    muted.TryRemove(usrId);
 | 
			
		||||
 | 
			
		||||
@@ -252,7 +252,7 @@ public class MuteService : INService
 | 
			
		||||
                await uow.SaveChangesAsync();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (usr != null)
 | 
			
		||||
            if (usr is not null)
 | 
			
		||||
            {
 | 
			
		||||
                try { await usr.ModifyAsync(x => x.Mute = false); }
 | 
			
		||||
                catch { }
 | 
			
		||||
@@ -405,7 +405,7 @@ public class MuteService : INService
 | 
			
		||||
                        RemoveTimerFromDb(guildId, userId, type);
 | 
			
		||||
                        StopTimer(guildId, userId, type);
 | 
			
		||||
                        var guild = _client.GetGuild(guildId); // load the guild
 | 
			
		||||
                        if (guild != null) await guild.RemoveBanAsync(userId);
 | 
			
		||||
                        if (guild is not null) await guild.RemoveBanAsync(userId);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception ex)
 | 
			
		||||
                    {
 | 
			
		||||
@@ -419,7 +419,7 @@ public class MuteService : INService
 | 
			
		||||
                        var guild = _client.GetGuild(guildId);
 | 
			
		||||
                        var user = guild?.GetUser(userId);
 | 
			
		||||
                        var role = guild.GetRole(roleId.Value);
 | 
			
		||||
                        if (guild != null && user != null && user.Roles.Contains(role))
 | 
			
		||||
                        if (guild is not null && user is not null && user.Roles.Contains(role))
 | 
			
		||||
                            await user.RemoveRoleAsync(role);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception ex)
 | 
			
		||||
@@ -444,8 +444,8 @@ public class MuteService : INService
 | 
			
		||||
 | 
			
		||||
        //add it, or stop the old one and add this one
 | 
			
		||||
        userUnTimers.AddOrUpdate((userId, type),
 | 
			
		||||
            key => toAdd,
 | 
			
		||||
            (key, old) =>
 | 
			
		||||
            _ => toAdd,
 | 
			
		||||
            (_, old) =>
 | 
			
		||||
            {
 | 
			
		||||
                old.Change(Timeout.Infinite, Timeout.Infinite);
 | 
			
		||||
                return toAdd;
 | 
			
		||||
@@ -475,7 +475,7 @@ public class MuteService : INService
 | 
			
		||||
            toDelete = config.UnbanTimer.FirstOrDefault(x => x.UserId == userId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (toDelete != null) uow.Remove(toDelete);
 | 
			
		||||
        if (toDelete is not null) uow.Remove(toDelete);
 | 
			
		||||
        uow.SaveChanges();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -219,10 +219,10 @@ public partial class Administration
 | 
			
		||||
 | 
			
		||||
            var embed = _eb.Create().WithOkColor().WithTitle(GetText(strs.prot_active));
 | 
			
		||||
 | 
			
		||||
            if (spam != null)
 | 
			
		||||
            if (spam is not null)
 | 
			
		||||
                embed.AddField("Anti-Spam", GetAntiSpamString(spam).TrimTo(1024), true);
 | 
			
		||||
 | 
			
		||||
            if (raid != null)
 | 
			
		||||
            if (raid is not null)
 | 
			
		||||
                embed.AddField("Anti-Raid", GetAntiRaidString(raid).TrimTo(1024), true);
 | 
			
		||||
 | 
			
		||||
            if (alt is not null)
 | 
			
		||||
 
 | 
			
		||||
@@ -122,13 +122,13 @@ public class ProtectionService : INService
 | 
			
		||||
        var raid = gc.AntiRaidSetting;
 | 
			
		||||
        var spam = gc.AntiSpamSetting;
 | 
			
		||||
 | 
			
		||||
        if (raid != null)
 | 
			
		||||
        if (raid is not null)
 | 
			
		||||
        {
 | 
			
		||||
            var raidStats = new AntiRaidStats { AntiRaidSettings = raid };
 | 
			
		||||
            _antiRaidGuilds[gc.GuildId] = raidStats;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (spam != null)
 | 
			
		||||
        if (spam is not null)
 | 
			
		||||
            _antiSpamGuilds[gc.GuildId] = new() { AntiSpamSettings = spam };
 | 
			
		||||
 | 
			
		||||
        var alt = gc.AntiAltSetting;
 | 
			
		||||
@@ -212,8 +212,8 @@ public class ProtectionService : INService
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                var stats = spamSettings.UserStats.AddOrUpdate(msg.Author.Id,
 | 
			
		||||
                    id => new(msg),
 | 
			
		||||
                    (id, old) =>
 | 
			
		||||
                    _ => new(msg),
 | 
			
		||||
                    (_, old) =>
 | 
			
		||||
                    {
 | 
			
		||||
                        old.ApplyNextMessage(msg);
 | 
			
		||||
                        return old;
 | 
			
		||||
@@ -292,7 +292,7 @@ public class ProtectionService : INService
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        _antiRaidGuilds.AddOrUpdate(guildId, stats, (key, old) => stats);
 | 
			
		||||
        _antiRaidGuilds.AddOrUpdate(guildId, stats, (_, _) => stats);
 | 
			
		||||
 | 
			
		||||
        await using var uow = _db.GetDbContext();
 | 
			
		||||
        var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiRaidSetting));
 | 
			
		||||
@@ -362,7 +362,7 @@ public class ProtectionService : INService
 | 
			
		||||
 | 
			
		||||
        stats = _antiSpamGuilds.AddOrUpdate(guildId,
 | 
			
		||||
            stats,
 | 
			
		||||
            (key, old) =>
 | 
			
		||||
            (_, old) =>
 | 
			
		||||
            {
 | 
			
		||||
                stats.AntiSpamSettings.IgnoredChannels = old.AntiSpamSettings.IgnoredChannels;
 | 
			
		||||
                return stats;
 | 
			
		||||
@@ -371,7 +371,7 @@ public class ProtectionService : INService
 | 
			
		||||
        await using var uow = _db.GetDbContext();
 | 
			
		||||
        var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiSpamSetting));
 | 
			
		||||
 | 
			
		||||
        if (gc.AntiSpamSetting != null)
 | 
			
		||||
        if (gc.AntiSpamSetting is not null)
 | 
			
		||||
        {
 | 
			
		||||
            gc.AntiSpamSetting.Action = stats.AntiSpamSettings.Action;
 | 
			
		||||
            gc.AntiSpamSetting.MessageThreshold = stats.AntiSpamSettings.MessageThreshold;
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ public partial class Administration
 | 
			
		||||
            if (parameter is "-s" or "--safe")
 | 
			
		||||
                await _service.PruneWhere((ITextChannel)ctx.Channel, count, x => !x.IsPinned);
 | 
			
		||||
            else
 | 
			
		||||
                await _service.PruneWhere((ITextChannel)ctx.Channel, count, x => true);
 | 
			
		||||
                await _service.PruneWhere((ITextChannel)ctx.Channel, count, _ => true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //prune @user [x]
 | 
			
		||||
 
 | 
			
		||||
@@ -46,7 +46,7 @@ public partial class Administration
 | 
			
		||||
                                     var emote = x.Last().ToIEmote();
 | 
			
		||||
                                     return new { role, emote };
 | 
			
		||||
                                 })
 | 
			
		||||
                                 .Where(x => x != null)
 | 
			
		||||
                                 .Where(x => x is not null)
 | 
			
		||||
                                 .WhenAll();
 | 
			
		||||
 | 
			
		||||
            if (!all.Any())
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@ public class RoleCommandsService : INService
 | 
			
		||||
            var reactionRole = conf.ReactionRoles.FirstOrDefault(x
 | 
			
		||||
                => x.EmoteName == reaction.Emote.Name || x.EmoteName == reaction.Emote.ToString());
 | 
			
		||||
 | 
			
		||||
            if (reactionRole != null)
 | 
			
		||||
            if (reactionRole is not null)
 | 
			
		||||
            {
 | 
			
		||||
                if (!conf.Exclusive)
 | 
			
		||||
                {
 | 
			
		||||
@@ -125,7 +125,7 @@ public class RoleCommandsService : INService
 | 
			
		||||
                var reactionRole = conf.ReactionRoles.FirstOrDefault(x
 | 
			
		||||
                    => x.EmoteName == reaction.Emote.Name || x.EmoteName == reaction.Emote.ToString());
 | 
			
		||||
 | 
			
		||||
                if (reactionRole != null)
 | 
			
		||||
                if (reactionRole is not null)
 | 
			
		||||
                {
 | 
			
		||||
                    var role = gusr.Guild.GetRole(reactionRole.RoleId);
 | 
			
		||||
                    if (role is null)
 | 
			
		||||
@@ -181,7 +181,7 @@ public class RoleCommandsService : INService
 | 
			
		||||
    {
 | 
			
		||||
        var toAdd = user.Guild.GetRole(dbRero.RoleId);
 | 
			
		||||
 | 
			
		||||
        return toAdd != null && !user.Roles.Contains(toAdd) ? user.AddRoleAsync(toAdd) : Task.CompletedTask;
 | 
			
		||||
        return toAdd is not null && !user.Roles.Contains(toAdd) ? user.AddRoleAsync(toAdd) : Task.CompletedTask;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -208,7 +208,7 @@ public class RoleCommandsService : INService
 | 
			
		||||
        var roleIds = dbReroMsg.ReactionRoles.Select(x => x.RoleId)
 | 
			
		||||
                               .Where(x => x != dbRero.RoleId)
 | 
			
		||||
                               .Select(x => user.Guild.GetRole(x))
 | 
			
		||||
                               .Where(x => x != null);
 | 
			
		||||
                               .Where(x => x is not null);
 | 
			
		||||
 | 
			
		||||
        var removeReactionsTask = RemoveOldReactionsAsync(reactionMessage, user, reaction, cToken);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -147,8 +147,8 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
 | 
			
		||||
        {
 | 
			
		||||
            var autos = _autoCommands.GetOrAdd(cmd.GuildId, new ConcurrentDictionary<int, Timer>());
 | 
			
		||||
            autos.AddOrUpdate(cmd.Id,
 | 
			
		||||
                key => TimerFromAutoCommand(cmd),
 | 
			
		||||
                (key, old) =>
 | 
			
		||||
                _ => TimerFromAutoCommand(cmd),
 | 
			
		||||
                (_, old) =>
 | 
			
		||||
                {
 | 
			
		||||
                    old.Change(Timeout.Infinite, Timeout.Infinite);
 | 
			
		||||
                    return TimerFromAutoCommand(cmd);
 | 
			
		||||
@@ -179,7 +179,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
 | 
			
		||||
            return user.CreateDMChannelAsync();
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        ownerChannels = channels.Where(x => x != null)
 | 
			
		||||
        ownerChannels = channels.Where(x => x is not null)
 | 
			
		||||
                                .ToDictionary(x => x.Recipient.Id, x => x)
 | 
			
		||||
                                .ToImmutableDictionary();
 | 
			
		||||
 | 
			
		||||
@@ -244,7 +244,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
 | 
			
		||||
        using var uow = _db.GetDbContext();
 | 
			
		||||
        cmd = uow.AutoCommands.AsNoTracking().Where(x => x.Interval == 0).Skip(index).FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
        if (cmd != null)
 | 
			
		||||
        if (cmd is not null)
 | 
			
		||||
        {
 | 
			
		||||
            uow.Remove(cmd);
 | 
			
		||||
            uow.SaveChanges();
 | 
			
		||||
@@ -259,7 +259,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
 | 
			
		||||
        using var uow = _db.GetDbContext();
 | 
			
		||||
        cmd = uow.AutoCommands.AsNoTracking().Where(x => x.Interval >= 5).Skip(index).FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
        if (cmd != null)
 | 
			
		||||
        if (cmd is not null)
 | 
			
		||||
        {
 | 
			
		||||
            uow.Remove(cmd);
 | 
			
		||||
            if (_autoCommands.TryGetValue(cmd.GuildId, out var autos))
 | 
			
		||||
 
 | 
			
		||||
@@ -77,7 +77,7 @@ public class SelfAssignedRolesService : INService
 | 
			
		||||
            foreach (var roleId in sameRoles)
 | 
			
		||||
            {
 | 
			
		||||
                var sameRole = guildUser.Guild.GetRole(roleId);
 | 
			
		||||
                if (sameRole != null)
 | 
			
		||||
                if (sameRole is not null)
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        await guildUser.RemoveRoleAsync(sameRole);
 | 
			
		||||
@@ -111,7 +111,7 @@ public class SelfAssignedRolesService : INService
 | 
			
		||||
 | 
			
		||||
        if (string.IsNullOrWhiteSpace(name))
 | 
			
		||||
        {
 | 
			
		||||
            if (toUpdate != null)
 | 
			
		||||
            if (toUpdate is not null)
 | 
			
		||||
                gc.SelfAssignableRoleGroupNames.Remove(toUpdate);
 | 
			
		||||
        }
 | 
			
		||||
        else if (toUpdate is null)
 | 
			
		||||
@@ -174,7 +174,7 @@ public class SelfAssignedRolesService : INService
 | 
			
		||||
        using var uow = _db.GetDbContext();
 | 
			
		||||
        var roles = uow.SelfAssignableRoles.GetFromGuild(guildId);
 | 
			
		||||
        var sar = roles.FirstOrDefault(x => x.RoleId == role.Id);
 | 
			
		||||
        if (sar != null)
 | 
			
		||||
        if (sar is not null)
 | 
			
		||||
        {
 | 
			
		||||
            sar.LevelRequirement = level;
 | 
			
		||||
            uow.SaveChanges();
 | 
			
		||||
@@ -216,6 +216,6 @@ public class SelfAssignedRolesService : INService
 | 
			
		||||
            uow.SaveChanges();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return (exclusive, roles.Where(x => x.Role != null), groupNames);
 | 
			
		||||
        return (exclusive, roles.Where(x => x.Role is not null), groupNames);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,22 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Administration;
 | 
			
		||||
 | 
			
		||||
public sealed class DummyLogCommandService : ILogCommandService
 | 
			
		||||
{
 | 
			
		||||
    public void AddDeleteIgnore(ulong xId)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Task LogServer(ulong guildId, ulong channelId, bool actionValue)
 | 
			
		||||
        => Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
    public bool LogIgnore(ulong guildId, ulong itemId, IgnoredItemType itemType)
 | 
			
		||||
        => false;
 | 
			
		||||
 | 
			
		||||
    public LogSetting? GetGuildLogSettings(ulong guildId)
 | 
			
		||||
        => default;
 | 
			
		||||
 | 
			
		||||
    public bool Log(ulong guildId, ulong? channelId, LogType type)
 | 
			
		||||
        => false;
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,157 @@
 | 
			
		||||
using NadekoBot.Common.TypeReaders.Models;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Administration;
 | 
			
		||||
 | 
			
		||||
public partial class Administration
 | 
			
		||||
{
 | 
			
		||||
    [Group]
 | 
			
		||||
    [NoPublicBot]
 | 
			
		||||
    public partial class LogCommands : NadekoSubmodule<ILogCommandService>
 | 
			
		||||
    {
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [UserPerm(GuildPerm.Administrator)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async partial Task LogServer(PermissionAction action)
 | 
			
		||||
        {
 | 
			
		||||
            await _service.LogServer(ctx.Guild.Id, ctx.Channel.Id, action.Value);
 | 
			
		||||
            if (action.Value)
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(strs.log_all);
 | 
			
		||||
            else
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(strs.log_disabled);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [UserPerm(GuildPerm.Administrator)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async partial Task LogIgnore()
 | 
			
		||||
        {
 | 
			
		||||
            var settings = _service.GetGuildLogSettings(ctx.Guild.Id);
 | 
			
		||||
 | 
			
		||||
            var chs = settings?.LogIgnores.Where(x => x.ItemType == IgnoredItemType.Channel).ToList()
 | 
			
		||||
                      ?? new List<IgnoredLogItem>();
 | 
			
		||||
            var usrs = settings?.LogIgnores.Where(x => x.ItemType == IgnoredItemType.User).ToList()
 | 
			
		||||
                       ?? new List<IgnoredLogItem>();
 | 
			
		||||
 | 
			
		||||
            var eb = _eb.Create(ctx)
 | 
			
		||||
                        .WithOkColor()
 | 
			
		||||
                        .AddField(GetText(strs.log_ignored_channels),
 | 
			
		||||
                            chs.Count == 0
 | 
			
		||||
                                ? "-"
 | 
			
		||||
                                : string.Join('\n', chs.Select(x => $"{x.LogItemId} | <#{x.LogItemId}>")))
 | 
			
		||||
                        .AddField(GetText(strs.log_ignored_users),
 | 
			
		||||
                            usrs.Count == 0
 | 
			
		||||
                                ? "-"
 | 
			
		||||
                                : string.Join('\n', usrs.Select(x => $"{x.LogItemId} | <@{x.LogItemId}>")));
 | 
			
		||||
 | 
			
		||||
            await ctx.Channel.EmbedAsync(eb);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [UserPerm(GuildPerm.Administrator)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async partial Task LogIgnore([Leftover] ITextChannel target)
 | 
			
		||||
        {
 | 
			
		||||
            var removed = _service.LogIgnore(ctx.Guild.Id, target.Id, IgnoredItemType.Channel);
 | 
			
		||||
 | 
			
		||||
            if (!removed)
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(
 | 
			
		||||
                    strs.log_ignore_chan(Format.Bold(target.Mention + "(" + target.Id + ")")));
 | 
			
		||||
            else
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(
 | 
			
		||||
                    strs.log_not_ignore_chan(Format.Bold(target.Mention + "(" + target.Id + ")")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [UserPerm(GuildPerm.Administrator)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async partial Task LogIgnore([Leftover] IUser target)
 | 
			
		||||
        {
 | 
			
		||||
            var removed = _service.LogIgnore(ctx.Guild.Id, target.Id, IgnoredItemType.User);
 | 
			
		||||
 | 
			
		||||
            if (!removed)
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(
 | 
			
		||||
                    strs.log_ignore_user(Format.Bold(target.Mention + "(" + target.Id + ")")));
 | 
			
		||||
            else
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(
 | 
			
		||||
                    strs.log_not_ignore_user(Format.Bold(target.Mention + "(" + target.Id + ")")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [UserPerm(GuildPerm.Administrator)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async partial Task LogEvents()
 | 
			
		||||
        {
 | 
			
		||||
            var logSetting = _service.GetGuildLogSettings(ctx.Guild.Id);
 | 
			
		||||
            var str = string.Join("\n",
 | 
			
		||||
                Enum.GetNames(typeof(LogType))
 | 
			
		||||
                    .Select(x =>
 | 
			
		||||
                    {
 | 
			
		||||
                        var val = logSetting is null ? null : GetLogProperty(logSetting, Enum.Parse<LogType>(x));
 | 
			
		||||
                        if (val is not null)
 | 
			
		||||
                            return $"{Format.Bold(x)} <#{val}>";
 | 
			
		||||
                        return Format.Bold(x);
 | 
			
		||||
                    }));
 | 
			
		||||
 | 
			
		||||
            await SendConfirmAsync(Format.Bold(GetText(strs.log_events)) + "\n" + str);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static ulong? GetLogProperty(LogSetting l, LogType type)
 | 
			
		||||
        {
 | 
			
		||||
            switch (type)
 | 
			
		||||
            {
 | 
			
		||||
                case LogType.Other:
 | 
			
		||||
                    return l.LogOtherId;
 | 
			
		||||
                case LogType.MessageUpdated:
 | 
			
		||||
                    return l.MessageUpdatedId;
 | 
			
		||||
                case LogType.MessageDeleted:
 | 
			
		||||
                    return l.MessageDeletedId;
 | 
			
		||||
                case LogType.UserJoined:
 | 
			
		||||
                    return l.UserJoinedId;
 | 
			
		||||
                case LogType.UserLeft:
 | 
			
		||||
                    return l.UserLeftId;
 | 
			
		||||
                case LogType.UserBanned:
 | 
			
		||||
                    return l.UserBannedId;
 | 
			
		||||
                case LogType.UserUnbanned:
 | 
			
		||||
                    return l.UserUnbannedId;
 | 
			
		||||
                case LogType.UserUpdated:
 | 
			
		||||
                    return l.UserUpdatedId;
 | 
			
		||||
                case LogType.ChannelCreated:
 | 
			
		||||
                    return l.ChannelCreatedId;
 | 
			
		||||
                case LogType.ChannelDestroyed:
 | 
			
		||||
                    return l.ChannelDestroyedId;
 | 
			
		||||
                case LogType.ChannelUpdated:
 | 
			
		||||
                    return l.ChannelUpdatedId;
 | 
			
		||||
                case LogType.UserPresence:
 | 
			
		||||
                    return l.LogUserPresenceId;
 | 
			
		||||
                case LogType.VoicePresence:
 | 
			
		||||
                    return l.LogVoicePresenceId;
 | 
			
		||||
                case LogType.VoicePresenceTTS:
 | 
			
		||||
                    return l.LogVoicePresenceTTSId;
 | 
			
		||||
                case LogType.UserMuted:
 | 
			
		||||
                    return l.UserMutedId;
 | 
			
		||||
                default:
 | 
			
		||||
                    return null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [UserPerm(GuildPerm.Administrator)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async partial Task Log(LogType type)
 | 
			
		||||
        {
 | 
			
		||||
            var val = _service.Log(ctx.Guild.Id, ctx.Channel.Id, type);
 | 
			
		||||
 | 
			
		||||
            if (val)
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(strs.log(Format.Bold(type.ToString())));
 | 
			
		||||
            else
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(strs.log_stop(Format.Bold(type.ToString())));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -13,12 +13,12 @@ public class GuildTimezoneService : INService
 | 
			
		||||
    public GuildTimezoneService(DiscordSocketClient client, Bot bot, DbService db)
 | 
			
		||||
    {
 | 
			
		||||
        _timezones = bot.AllGuildConfigs.Select(GetTimzezoneTuple)
 | 
			
		||||
                        .Where(x => x.Timezone != null)
 | 
			
		||||
                        .Where(x => x.Timezone is not null)
 | 
			
		||||
                        .ToDictionary(x => x.GuildId, x => x.Timezone)
 | 
			
		||||
                        .ToConcurrent();
 | 
			
		||||
 | 
			
		||||
        var curUser = client.CurrentUser;
 | 
			
		||||
        if (curUser != null)
 | 
			
		||||
        if (curUser is not null)
 | 
			
		||||
            AllServices.TryAdd(curUser.Id, this);
 | 
			
		||||
        _db = db;
 | 
			
		||||
 | 
			
		||||
@@ -28,7 +28,7 @@ public class GuildTimezoneService : INService
 | 
			
		||||
    private Task Bot_JoinedGuild(GuildConfig arg)
 | 
			
		||||
    {
 | 
			
		||||
        var (guildId, tz) = GetTimzezoneTuple(arg);
 | 
			
		||||
        if (tz != null)
 | 
			
		||||
        if (tz is not null)
 | 
			
		||||
            _timezones.TryAdd(guildId, tz);
 | 
			
		||||
        return Task.CompletedTask;
 | 
			
		||||
    }
 | 
			
		||||
@@ -69,7 +69,7 @@ public class GuildTimezoneService : INService
 | 
			
		||||
        if (tz is null)
 | 
			
		||||
            _timezones.TryRemove(guildId, out tz);
 | 
			
		||||
        else
 | 
			
		||||
            _timezones.AddOrUpdate(guildId, tz, (key, old) => tz);
 | 
			
		||||
            _timezones.AddOrUpdate(guildId, tz, (_, _) => tz);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TimeZoneInfo GetTimeZoneOrUtc(ulong guildId)
 | 
			
		||||
 
 | 
			
		||||
@@ -392,12 +392,12 @@ public partial class Administration
 | 
			
		||||
 | 
			
		||||
            var guildUser = await ((DiscordSocketClient)Context.Client).Rest.GetGuildUserAsync(ctx.Guild.Id, user.Id);
 | 
			
		||||
 | 
			
		||||
            if (guildUser != null && !await CheckRoleHierarchy(guildUser))
 | 
			
		||||
            if (guildUser is not null && !await CheckRoleHierarchy(guildUser))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            var dmFailed = false;
 | 
			
		||||
 | 
			
		||||
            if (guildUser != null)
 | 
			
		||||
            if (guildUser is not null)
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    var defaultMessage = GetText(strs.bandm(Format.Bold(ctx.Guild.Name), msg));
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ public class UserPunishService : INService
 | 
			
		||||
 | 
			
		||||
        var p = ps.FirstOrDefault(x => x.Count == warnings);
 | 
			
		||||
 | 
			
		||||
        if (p != null)
 | 
			
		||||
        if (p is not null)
 | 
			
		||||
        {
 | 
			
		||||
            var user = await guild.GetUserAsync(userId);
 | 
			
		||||
            if (user is null)
 | 
			
		||||
@@ -305,9 +305,9 @@ WHERE GuildId={guildId}
 | 
			
		||||
        IRole role = null)
 | 
			
		||||
    {
 | 
			
		||||
        // these 3 don't make sense with time
 | 
			
		||||
        if (punish is PunishmentAction.Softban or PunishmentAction.Kick or PunishmentAction.RemoveRoles && time != null)
 | 
			
		||||
        if (punish is PunishmentAction.Softban or PunishmentAction.Kick or PunishmentAction.RemoveRoles && time is not null)
 | 
			
		||||
            return false;
 | 
			
		||||
        if (number <= 0 || (time != null && time.Time > TimeSpan.FromDays(49)))
 | 
			
		||||
        if (number <= 0 || (time is not null && time.Time > TimeSpan.FromDays(49)))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        using var uow = _db.GetDbContext();
 | 
			
		||||
@@ -336,7 +336,7 @@ WHERE GuildId={guildId}
 | 
			
		||||
        var ps = uow.GuildConfigsForId(guildId, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
 | 
			
		||||
        var p = ps.FirstOrDefault(x => x.Count == number);
 | 
			
		||||
 | 
			
		||||
        if (p != null)
 | 
			
		||||
        if (p is not null)
 | 
			
		||||
        {
 | 
			
		||||
            uow.Remove(p);
 | 
			
		||||
            uow.SaveChanges();
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +137,7 @@ public class VcRoleService : INService
 | 
			
		||||
        using var uow = _db.GetDbContext();
 | 
			
		||||
        var conf = uow.GuildConfigsForId(guildId, set => set.Include(x => x.VcRoleInfos));
 | 
			
		||||
        var toDelete = conf.VcRoleInfos.FirstOrDefault(x => x.VoiceChannelId == vcId); // remove old one
 | 
			
		||||
        if (toDelete != null) uow.Remove(toDelete);
 | 
			
		||||
        if (toDelete is not null) uow.Remove(toDelete);
 | 
			
		||||
        conf.VcRoleInfos.Add(new() { VoiceChannelId = vcId, RoleId = role.Id }); // add new one
 | 
			
		||||
        uow.SaveChanges();
 | 
			
		||||
    }
 | 
			
		||||
@@ -178,10 +178,10 @@ public class VcRoleService : INService
 | 
			
		||||
                    if (VcRoles.TryGetValue(guildId, out var guildVcRoles))
 | 
			
		||||
                    {
 | 
			
		||||
                        //remove old
 | 
			
		||||
                        if (oldVc != null && guildVcRoles.TryGetValue(oldVc.Id, out var role))
 | 
			
		||||
                        if (oldVc is not null && guildVcRoles.TryGetValue(oldVc.Id, out var role))
 | 
			
		||||
                            Assign(false, gusr, role);
 | 
			
		||||
                        //add new
 | 
			
		||||
                        if (newVc != null && guildVcRoles.TryGetValue(newVc.Id, out role)) Assign(true, gusr, role);
 | 
			
		||||
                        if (newVc is not null && guildVcRoles.TryGetValue(newVc.Id, out role)) Assign(true, gusr, role);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ public partial class CustomReactions : NadekoModule<CustomReactionsService>
 | 
			
		||||
 | 
			
		||||
    private bool AdminInGuildOrOwnerInDm()
 | 
			
		||||
        => (ctx.Guild is null && _creds.IsOwner(ctx.User))
 | 
			
		||||
           || (ctx.Guild != null && ((IGuildUser)ctx.User).GuildPermissions.Administrator);
 | 
			
		||||
           || (ctx.Guild is not null && ((IGuildUser)ctx.User).GuildPermissions.Administrator);
 | 
			
		||||
 | 
			
		||||
    [Cmd]
 | 
			
		||||
    public async partial Task AddCustReact(string key, [Leftover] string message)
 | 
			
		||||
@@ -55,14 +55,14 @@ public partial class CustomReactions : NadekoModule<CustomReactionsService>
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if ((channel is null && !_creds.IsOwner(ctx.User))
 | 
			
		||||
            || (channel != null && !((IGuildUser)ctx.User).GuildPermissions.Administrator))
 | 
			
		||||
            || (channel is not null && !((IGuildUser)ctx.User).GuildPermissions.Administrator))
 | 
			
		||||
        {
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.insuff_perms);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var cr = await _service.EditAsync(ctx.Guild?.Id, id, message);
 | 
			
		||||
        if (cr != null)
 | 
			
		||||
        if (cr is not null)
 | 
			
		||||
            await ctx.Channel.EmbedAsync(_eb.Create()
 | 
			
		||||
                                            .WithOkColor()
 | 
			
		||||
                                            .WithTitle(GetText(strs.edited_cust_react))
 | 
			
		||||
@@ -140,7 +140,7 @@ public partial class CustomReactions : NadekoModule<CustomReactionsService>
 | 
			
		||||
 | 
			
		||||
        var cr = await _service.DeleteAsync(ctx.Guild?.Id, id);
 | 
			
		||||
 | 
			
		||||
        if (cr != null)
 | 
			
		||||
        if (cr is not null)
 | 
			
		||||
            await ctx.Channel.EmbedAsync(_eb.Create()
 | 
			
		||||
                                            .WithOkColor()
 | 
			
		||||
                                            .WithTitle(GetText(strs.deleted))
 | 
			
		||||
 
 | 
			
		||||
@@ -351,7 +351,7 @@ public sealed class CustomReactionsService : IEarlyBehavior, IReadyExecutor
 | 
			
		||||
        if (maybeGuildId is { } guildId)
 | 
			
		||||
            _newGuildReactions.AddOrUpdate(guildId,
 | 
			
		||||
                new[] { cr },
 | 
			
		||||
                (key, old) =>
 | 
			
		||||
                (_, old) =>
 | 
			
		||||
                {
 | 
			
		||||
                    var newArray = old.ToArray();
 | 
			
		||||
                    for (var i = 0; i < newArray.Length; i++)
 | 
			
		||||
@@ -375,7 +375,7 @@ public sealed class CustomReactionsService : IEarlyBehavior, IReadyExecutor
 | 
			
		||||
        cr.Trigger = cr.Trigger.Replace(MentionPh, _client.CurrentUser.Mention);
 | 
			
		||||
 | 
			
		||||
        if (maybeGuildId is { } guildId)
 | 
			
		||||
            _newGuildReactions.AddOrUpdate(guildId, new[] { cr }, (key, old) => old.With(cr));
 | 
			
		||||
            _newGuildReactions.AddOrUpdate(guildId, new[] { cr }, (_, old) => old.With(cr));
 | 
			
		||||
        else
 | 
			
		||||
            return _pubSub.Pub(_gcrAddedKey, cr);
 | 
			
		||||
 | 
			
		||||
@@ -492,7 +492,7 @@ public sealed class CustomReactionsService : IEarlyBehavior, IReadyExecutor
 | 
			
		||||
    {
 | 
			
		||||
        using var uow = _db.GetDbContext();
 | 
			
		||||
        var cr = uow.CustomReactions.GetByGuildIdAndInput(guildId, input);
 | 
			
		||||
        return cr != null;
 | 
			
		||||
        return cr is not null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public string ExportCrs(ulong? guildId)
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ public partial class Gambling
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                if (_msg != null)
 | 
			
		||||
                if (_msg is not null)
 | 
			
		||||
                {
 | 
			
		||||
                    var _ = _msg.DeleteAsync();
 | 
			
		||||
                }
 | 
			
		||||
@@ -97,7 +97,7 @@ public partial class Gambling
 | 
			
		||||
                               .WithTitle("BlackJack")
 | 
			
		||||
                               .AddField($"{dealerIcon} Dealer's Hand | Value: {bj.Dealer.GetHandValue()}", cStr);
 | 
			
		||||
 | 
			
		||||
                if (bj.CurrentUser != null) embed.WithFooter($"Player to make a choice: {bj.CurrentUser.DiscordUser}");
 | 
			
		||||
                if (bj.CurrentUser is not null) embed.WithFooter($"Player to make a choice: {bj.CurrentUser.DiscordUser}");
 | 
			
		||||
 | 
			
		||||
                foreach (var p in bj.Players)
 | 
			
		||||
                {
 | 
			
		||||
 
 | 
			
		||||
@@ -140,7 +140,7 @@ public class Blackjack
 | 
			
		||||
    {
 | 
			
		||||
        var cu = CurrentUser;
 | 
			
		||||
 | 
			
		||||
        if (cu != null && cu.DiscordUser == u)
 | 
			
		||||
        if (cu is not null && cu.DiscordUser == u)
 | 
			
		||||
            return await Stand(cu);
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
@@ -221,7 +221,7 @@ public class Blackjack
 | 
			
		||||
    {
 | 
			
		||||
        var cu = CurrentUser;
 | 
			
		||||
 | 
			
		||||
        if (cu != null && cu.DiscordUser == u)
 | 
			
		||||
        if (cu is not null && cu.DiscordUser == u)
 | 
			
		||||
            return await Double(cu);
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
@@ -268,7 +268,7 @@ public class Blackjack
 | 
			
		||||
    {
 | 
			
		||||
        var cu = CurrentUser;
 | 
			
		||||
 | 
			
		||||
        if (cu != null && cu.DiscordUser == u)
 | 
			
		||||
        if (cu is not null && cu.DiscordUser == u)
 | 
			
		||||
            return await Hit(cu);
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
 
 | 
			
		||||
@@ -78,8 +78,8 @@ public class GameStatusEvent : ICurrencyEvent
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            await _cs.AddBulkAsync(toAward,
 | 
			
		||||
                toAward.Select(x => "GameStatus Event"),
 | 
			
		||||
                toAward.Select(x => _amount),
 | 
			
		||||
                toAward.Select(_ => "GameStatus Event"),
 | 
			
		||||
                toAward.Select(_ => _amount),
 | 
			
		||||
                true);
 | 
			
		||||
 | 
			
		||||
            if (_isPotLimited)
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ public class ReactionEvent : ICurrencyEvent
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            await _cs.AddBulkAsync(toAward, toAward.Select(x => "Reaction Event"), toAward.Select(x => _amount), true);
 | 
			
		||||
            await _cs.AddBulkAsync(toAward, toAward.Select(_ => "Reaction Event"), toAward.Select(_ => _amount), true);
 | 
			
		||||
 | 
			
		||||
            if (_isPotLimited)
 | 
			
		||||
                await _msg.ModifyAsync(m =>
 | 
			
		||||
 
 | 
			
		||||
@@ -133,7 +133,7 @@ public sealed class Connect4Game : IDisposable
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            CurrentPhase = Phase.P1Move; //start the game
 | 
			
		||||
            _playerTimeoutTimer = new(async state =>
 | 
			
		||||
            _playerTimeoutTimer = new(async _ =>
 | 
			
		||||
                {
 | 
			
		||||
                    await _locker.WaitAsync();
 | 
			
		||||
                    try
 | 
			
		||||
@@ -347,7 +347,7 @@ public sealed class Connect4Game : IDisposable
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (winId != null)
 | 
			
		||||
        if (winId is not null)
 | 
			
		||||
            _cs.AddAsync(winId.Value, "Connnect4-win", (long)(_options.Bet * 1.98), true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ public partial class Gambling
 | 
			
		||||
 | 
			
		||||
            var res = await _service.JoinOrCreateGame(ctx.Channel.Id, ctx.User, amount, mixed, OnEnded);
 | 
			
		||||
 | 
			
		||||
            if (res.Item1 != null)
 | 
			
		||||
            if (res.Item1 is not null)
 | 
			
		||||
            {
 | 
			
		||||
                await SendConfirmAsync(GetText(strs.rafflecur(res.Item1.GameType.ToString())),
 | 
			
		||||
                    string.Join("\n", res.Item1.Users.Select(x => $"{x.DiscordUser} ({x.Amount})")),
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ public partial class Gambling
 | 
			
		||||
            if (num is < 1 or > 10)
 | 
			
		||||
                throw new ArgumentOutOfRangeException(nameof(num));
 | 
			
		||||
 | 
			
		||||
            var cards = guildId is null ? new() : _allDecks.GetOrAdd(ctx.Guild, s => new());
 | 
			
		||||
            var cards = guildId is null ? new() : _allDecks.GetOrAdd(ctx.Guild, _ => new());
 | 
			
		||||
            var images = new List<Image<Rgba32>>();
 | 
			
		||||
            var cardObjects = new List<Deck.Card>();
 | 
			
		||||
            for (var i = 0; i < num; i++)
 | 
			
		||||
@@ -53,7 +53,7 @@ public partial class Gambling
 | 
			
		||||
            if (cardObjects.Count == 5)
 | 
			
		||||
                toSend += $" drew `{Deck.GetHandValue(cardObjects)}`";
 | 
			
		||||
 | 
			
		||||
            if (guildId != null)
 | 
			
		||||
            if (guildId is not null)
 | 
			
		||||
                toSend += "\n" + GetText(strs.cards_left(Format.Bold(cards.CardPool.Count.ToString())));
 | 
			
		||||
 | 
			
		||||
            return (img.ToStream(), toSend);
 | 
			
		||||
@@ -97,8 +97,8 @@ public partial class Gambling
 | 
			
		||||
            //var channel = (ITextChannel)ctx.Channel;
 | 
			
		||||
 | 
			
		||||
            _allDecks.AddOrUpdate(ctx.Guild,
 | 
			
		||||
                g => new(),
 | 
			
		||||
                (g, c) =>
 | 
			
		||||
                _ => new(),
 | 
			
		||||
                (_, c) =>
 | 
			
		||||
                {
 | 
			
		||||
                    c.Restart();
 | 
			
		||||
                    return c;
 | 
			
		||||
 
 | 
			
		||||
@@ -110,7 +110,7 @@ public partial class Gambling : GamblingModule<GamblingService>
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TimeSpan? rem;
 | 
			
		||||
        if ((rem = _cache.AddTimelyClaim(ctx.User.Id, period)) != null)
 | 
			
		||||
        if ((rem = _cache.AddTimelyClaim(ctx.User.Id, period)) is not null)
 | 
			
		||||
        {
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.timely_already_claimed(rem?.ToString(@"dd\d\ hh\h\ mm\m\ ss\s")));
 | 
			
		||||
            return;
 | 
			
		||||
@@ -308,8 +308,8 @@ public partial class Gambling : GamblingModule<GamblingService>
 | 
			
		||||
        var users = (await ctx.Guild.GetUsersAsync()).Where(u => u.GetRoles().Contains(role)).ToList();
 | 
			
		||||
 | 
			
		||||
        await _cs.AddBulkAsync(users.Select(x => x.Id),
 | 
			
		||||
            users.Select(x => $"Awarded by bot owner to **{role.Name}** role. ({ctx.User.Username}/{ctx.User.Id})"),
 | 
			
		||||
            users.Select(x => amount),
 | 
			
		||||
            users.Select(_ => $"Awarded by bot owner to **{role.Name}** role. ({ctx.User.Username}/{ctx.User.Id})"),
 | 
			
		||||
            users.Select(_ => amount),
 | 
			
		||||
            true);
 | 
			
		||||
 | 
			
		||||
        await ReplyConfirmLocalizedAsync(strs.mass_award(n(amount),
 | 
			
		||||
@@ -326,8 +326,8 @@ public partial class Gambling : GamblingModule<GamblingService>
 | 
			
		||||
        var users = (await role.GetMembersAsync()).ToList();
 | 
			
		||||
 | 
			
		||||
        await _cs.RemoveBulkAsync(users.Select(x => x.Id),
 | 
			
		||||
            users.Select(x => $"Taken by bot owner from **{role.Name}** role. ({ctx.User.Username}/{ctx.User.Id})"),
 | 
			
		||||
            users.Select(x => amount),
 | 
			
		||||
            users.Select(_ => $"Taken by bot owner from **{role.Name}** role. ({ctx.User.Username}/{ctx.User.Id})"),
 | 
			
		||||
            users.Select(_ => amount),
 | 
			
		||||
            true);
 | 
			
		||||
 | 
			
		||||
        await ReplyConfirmLocalizedAsync(strs.mass_take(n(amount),
 | 
			
		||||
@@ -532,7 +532,7 @@ public partial class Gambling : GamblingModule<GamblingService>
 | 
			
		||||
            await _tracker.EnsureUsersDownloadedAsync(ctx.Guild);
 | 
			
		||||
 | 
			
		||||
            var sg = (SocketGuild)ctx.Guild;
 | 
			
		||||
            cleanRichest = cleanRichest.Where(x => sg.GetUser(x.UserId) != null).ToList();
 | 
			
		||||
            cleanRichest = cleanRichest.Where(x => sg.GetUser(x.UserId) is not null).ToList();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -89,7 +89,7 @@ public partial class Gambling
 | 
			
		||||
            var enabledIn = _service.GetAllGeneratingChannels();
 | 
			
		||||
 | 
			
		||||
            return ctx.SendPaginatedConfirmAsync(page,
 | 
			
		||||
                cur =>
 | 
			
		||||
                _ =>
 | 
			
		||||
                {
 | 
			
		||||
                    var items = enabledIn.Skip(page * 9).Take(9);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,7 @@ public class PlantPickService : INService
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            var toDelete = guildConfig.GenerateCurrencyChannelIds.FirstOrDefault(x => x.Equals(toAdd));
 | 
			
		||||
            if (toDelete != null) uow.Remove(toDelete);
 | 
			
		||||
            if (toDelete is not null) uow.Remove(toDelete);
 | 
			
		||||
            _generationChannels.TryRemove(cid);
 | 
			
		||||
            enabled = false;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -66,7 +66,7 @@ public class VoteRewardService : INService, IReadyExecutor
 | 
			
		||||
 | 
			
		||||
                        await _currencyService.AddBulkAsync(ids,
 | 
			
		||||
                            data.Select(_ => "top.gg vote reward"),
 | 
			
		||||
                            data.Select(x => _gamb.Data.VoteReward),
 | 
			
		||||
                            data.Select(_ => _gamb.Data.VoteReward),
 | 
			
		||||
                            true);
 | 
			
		||||
 | 
			
		||||
                        Log.Information("Rewarding {Count} top.gg voters", ids.Count());
 | 
			
		||||
@@ -95,7 +95,7 @@ public class VoteRewardService : INService, IReadyExecutor
 | 
			
		||||
 | 
			
		||||
                        await _currencyService.AddBulkAsync(ids,
 | 
			
		||||
                            data.Select(_ => "discords.com vote reward"),
 | 
			
		||||
                            data.Select(x => _gamb.Data.VoteReward),
 | 
			
		||||
                            data.Select(_ => _gamb.Data.VoteReward),
 | 
			
		||||
                            true);
 | 
			
		||||
 | 
			
		||||
                        Log.Information("Rewarding {Count} discords.com voters", ids.Count());
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,7 @@ public class WaifuService : INService
 | 
			
		||||
 | 
			
		||||
        //wives stay though
 | 
			
		||||
 | 
			
		||||
        uow.SaveChanges();
 | 
			
		||||
        await uow.SaveChangesAsync();
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -236,7 +236,7 @@ public class WaifuService : INService
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (w.Affinity != null)
 | 
			
		||||
                if (w.Affinity is not null)
 | 
			
		||||
                    oldAff = w.Affinity;
 | 
			
		||||
                w.Affinity = newAff;
 | 
			
		||||
                success = true;
 | 
			
		||||
@@ -270,11 +270,10 @@ public class WaifuService : INService
 | 
			
		||||
        DivorceResult result;
 | 
			
		||||
        TimeSpan? remaining = null;
 | 
			
		||||
        long amount = 0;
 | 
			
		||||
        WaifuInfo w = null;
 | 
			
		||||
        WaifuInfo w;
 | 
			
		||||
        await using (var uow = _db.GetDbContext())
 | 
			
		||||
        {
 | 
			
		||||
            w = uow.WaifuInfo.ByWaifuUserId(targetId);
 | 
			
		||||
            var now = DateTime.UtcNow;
 | 
			
		||||
            if (w?.Claimer is null || w.Claimer.UserId != user.Id)
 | 
			
		||||
            {
 | 
			
		||||
                result = DivorceResult.NotYourWife;
 | 
			
		||||
@@ -373,7 +372,7 @@ public class WaifuService : INService
 | 
			
		||||
    public WaifuInfoStats GetFullWaifuInfoAsync(IGuildUser target)
 | 
			
		||||
    {
 | 
			
		||||
        using var uow = _db.GetDbContext();
 | 
			
		||||
        var du = uow.GetOrCreateUser(target);
 | 
			
		||||
        _ = uow.GetOrCreateUser(target);
 | 
			
		||||
 | 
			
		||||
        return GetFullWaifuInfoAsync(target.Id);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -181,7 +181,7 @@ public partial class Gambling
 | 
			
		||||
                                                                                      .ThenInclude(x => x.Items))
 | 
			
		||||
                                                                              .ShopEntries);
 | 
			
		||||
                            entry = entries.ElementAtOrDefault(index);
 | 
			
		||||
                            if (entry != null)
 | 
			
		||||
                            if (entry is not null)
 | 
			
		||||
                                if (entry.Items.Add(item))
 | 
			
		||||
                                    uow.SaveChanges();
 | 
			
		||||
                        }
 | 
			
		||||
@@ -281,7 +281,7 @@ public partial class Gambling
 | 
			
		||||
                                                                          .ThenInclude(x => x.Items))
 | 
			
		||||
                                                                  .ShopEntries);
 | 
			
		||||
                entry = entries.ElementAtOrDefault(index);
 | 
			
		||||
                if (entry != null && (rightType = entry.Type == ShopEntryType.List))
 | 
			
		||||
                if (entry is not null && (rightType = entry.Type == ShopEntryType.List))
 | 
			
		||||
                    if (added = entry.Items.Add(item))
 | 
			
		||||
                        uow.SaveChanges();
 | 
			
		||||
            }
 | 
			
		||||
@@ -312,7 +312,7 @@ public partial class Gambling
 | 
			
		||||
 | 
			
		||||
                var entries = new IndexedCollection<ShopEntry>(config.ShopEntries);
 | 
			
		||||
                removed = entries.ElementAtOrDefault(index);
 | 
			
		||||
                if (removed != null)
 | 
			
		||||
                if (removed is not null)
 | 
			
		||||
                {
 | 
			
		||||
                    uow.RemoveRange(removed.Items);
 | 
			
		||||
                    uow.Remove(removed);
 | 
			
		||||
 
 | 
			
		||||
@@ -159,7 +159,7 @@ public partial class Gambling
 | 
			
		||||
            var (oldAff, sucess, remaining) = await _service.ChangeAffinityAsync(ctx.User, u);
 | 
			
		||||
            if (!sucess)
 | 
			
		||||
            {
 | 
			
		||||
                if (remaining != null)
 | 
			
		||||
                if (remaining is not null)
 | 
			
		||||
                    await ReplyErrorLocalizedAsync(strs.waifu_affinity_cooldown(
 | 
			
		||||
                        Format.Bold(((int)remaining?.TotalHours).ToString()),
 | 
			
		||||
                        Format.Bold(remaining?.Minutes.ToString())));
 | 
			
		||||
 
 | 
			
		||||
@@ -66,7 +66,7 @@ public sealed class NunchiGame : IDisposable
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _killTimer = new(async state =>
 | 
			
		||||
            _killTimer = new(async _ =>
 | 
			
		||||
                {
 | 
			
		||||
                    await _locker.WaitAsync();
 | 
			
		||||
                    try
 | 
			
		||||
@@ -151,7 +151,7 @@ public sealed class NunchiGame : IDisposable
 | 
			
		||||
        _killTimer.Change(_killTimeout, _killTimeout);
 | 
			
		||||
        CurrentNumber = new NadekoRandom().Next(0, 100); // reset the counter
 | 
			
		||||
        _passed.Clear(); // reset all users who passed (new round starts)
 | 
			
		||||
        if (failure != null)
 | 
			
		||||
        if (failure is not null)
 | 
			
		||||
            _participants.Remove(failure.Value); // remove the dude who failed from the list of players
 | 
			
		||||
 | 
			
		||||
        var __ = OnRoundEnded?.Invoke(this, failure);
 | 
			
		||||
 
 | 
			
		||||
@@ -140,14 +140,14 @@ public class TicTacToe
 | 
			
		||||
                        return;
 | 
			
		||||
 | 
			
		||||
                    _phase = Phase.Ended;
 | 
			
		||||
                    if (_users[1] != null)
 | 
			
		||||
                    if (_users[1] is not null)
 | 
			
		||||
                    {
 | 
			
		||||
                        _winner = _users[_curUserIndex ^= 1];
 | 
			
		||||
                        var del = _previousMessage?.DeleteAsync();
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            await _channel.EmbedAsync(GetEmbed(GetText(strs.ttt_time_expired)));
 | 
			
		||||
                            if (del != null)
 | 
			
		||||
                            if (del is not null)
 | 
			
		||||
                                await del;
 | 
			
		||||
                        }
 | 
			
		||||
                        catch { }
 | 
			
		||||
@@ -266,7 +266,7 @@ public class TicTacToe
 | 
			
		||||
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            if (del2 != null) await del2;
 | 
			
		||||
                            if (del2 is not null) await del2;
 | 
			
		||||
                        }
 | 
			
		||||
                        catch { }
 | 
			
		||||
                    });
 | 
			
		||||
 
 | 
			
		||||
@@ -220,7 +220,7 @@ public class TriviaGame
 | 
			
		||||
                        && CurrentQuestion.IsAnswerCorrect(umsg.Content)
 | 
			
		||||
                        && !_triviaCancelSource.IsCancellationRequested)
 | 
			
		||||
                    {
 | 
			
		||||
                        Users.AddOrUpdate(guildUser, 1, (gu, old) => ++old);
 | 
			
		||||
                        Users.AddOrUpdate(guildUser, 1, (_, old) => ++old);
 | 
			
		||||
                        guess = true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ public partial class Games
 | 
			
		||||
 | 
			
		||||
        public IEmbedBuilder GetStats(Poll poll, string title)
 | 
			
		||||
        {
 | 
			
		||||
            var results = poll.Votes.GroupBy(kvp => kvp.VoteIndex).ToDictionary(x => x.Key, x => x.Sum(kvp => 1));
 | 
			
		||||
            var results = poll.Votes.GroupBy(kvp => kvp.VoteIndex).ToDictionary(x => x.Key, x => x.Sum(_ => 1));
 | 
			
		||||
 | 
			
		||||
            var totalVotesCast = results.Sum(x => x.Value);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ public class ChatterBotService : IEarlyBehavior
 | 
			
		||||
 | 
			
		||||
        ChatterBotGuilds = new(bot.AllGuildConfigs.Where(gc => gc.CleverbotEnabled)
 | 
			
		||||
                                  .ToDictionary(gc => gc.GuildId,
 | 
			
		||||
                                      gc => new Lazy<IChatterBotSession>(() => CreateSession(), true)));
 | 
			
		||||
                                      _ => new Lazy<IChatterBotSession>(() => CreateSession(), true)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public IChatterBotSession CreateSession()
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ public partial class Games
 | 
			
		||||
            var channel = (ITextChannel)ctx.Channel;
 | 
			
		||||
 | 
			
		||||
            var game = _service.RunningContests.GetOrAdd(ctx.Guild.Id,
 | 
			
		||||
                id => new(_games, _client, channel, Prefix, options, _eb));
 | 
			
		||||
                _ => new(_games, _client, channel, Prefix, options, _eb));
 | 
			
		||||
 | 
			
		||||
            if (game.IsActive)
 | 
			
		||||
                await SendErrorAsync($"Contest already running in {game.Channel.Mention} channel.");
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ public partial class Games
 | 
			
		||||
                _service.TicTacToeGames.Add(channel.Id, game);
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(strs.ttt_created);
 | 
			
		||||
 | 
			
		||||
                game.OnEnded += g =>
 | 
			
		||||
                game.OnEnded += _ =>
 | 
			
		||||
                {
 | 
			
		||||
                    _service.TicTacToeGames.Remove(channel.Id);
 | 
			
		||||
                    _sem.Dispose();
 | 
			
		||||
 
 | 
			
		||||
@@ -219,7 +219,7 @@ public partial class Help : NadekoModule<HelpService>
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var cnt = 0;
 | 
			
		||||
        var groups = cmdsWithGroup.GroupBy(x => cnt++ / 48).ToArray();
 | 
			
		||||
        var groups = cmdsWithGroup.GroupBy(_ => cnt++ / 48).ToArray();
 | 
			
		||||
        var embed = _eb.Create().WithOkColor();
 | 
			
		||||
        foreach (var g in groups)
 | 
			
		||||
        {
 | 
			
		||||
@@ -259,7 +259,7 @@ public partial class Help : NadekoModule<HelpService>
 | 
			
		||||
    {
 | 
			
		||||
        var prefixless =
 | 
			
		||||
            _cmds.Commands.FirstOrDefault(x => x.Aliases.Any(cmdName => cmdName.ToLowerInvariant() == fail));
 | 
			
		||||
        if (prefixless != null)
 | 
			
		||||
        if (prefixless is not null)
 | 
			
		||||
        {
 | 
			
		||||
            await H(prefixless);
 | 
			
		||||
            return;
 | 
			
		||||
@@ -316,7 +316,7 @@ public partial class Help : NadekoModule<HelpService>
 | 
			
		||||
                                         var opt = ((NadekoOptionsAttribute)com.Attributes.FirstOrDefault(x
 | 
			
		||||
                                                 => x is NadekoOptionsAttribute))
 | 
			
		||||
                                             ?.OptionType;
 | 
			
		||||
                                         if (opt != null) optHelpStr = HelpService.GetCommandOptionHelpList(opt);
 | 
			
		||||
                                         if (opt is not null) optHelpStr = HelpService.GetCommandOptionHelpList(opt);
 | 
			
		||||
 | 
			
		||||
                                         return new CommandJsonObject
 | 
			
		||||
                                         {
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@ public class HelpService : ILateExecutor, INService
 | 
			
		||||
 | 
			
		||||
        var str = $"**`{prefix + com.Aliases.First()}`**";
 | 
			
		||||
        var alias = com.Aliases.Skip(1).FirstOrDefault();
 | 
			
		||||
        if (alias != null)
 | 
			
		||||
        if (alias is not null)
 | 
			
		||||
            str += $" **/ `{prefix + alias}`**";
 | 
			
		||||
        var em = _eb.Create().AddField(str, $"{com.RealSummary(_strings, guild?.Id, prefix)}", true);
 | 
			
		||||
 | 
			
		||||
@@ -75,7 +75,7 @@ public class HelpService : ILateExecutor, INService
 | 
			
		||||
          .WithOkColor();
 | 
			
		||||
 | 
			
		||||
        var opt = ((NadekoOptionsAttribute)com.Attributes.FirstOrDefault(x => x is NadekoOptionsAttribute))?.OptionType;
 | 
			
		||||
        if (opt != null)
 | 
			
		||||
        if (opt is not null)
 | 
			
		||||
        {
 | 
			
		||||
            var hs = GetCommandOptionHelp(opt);
 | 
			
		||||
            if (!string.IsNullOrWhiteSpace(hs))
 | 
			
		||||
@@ -96,7 +96,7 @@ public class HelpService : ILateExecutor, INService
 | 
			
		||||
    {
 | 
			
		||||
        var strs = opt.GetProperties()
 | 
			
		||||
                      .Select(x => x.GetCustomAttributes(true).FirstOrDefault(a => a is OptionAttribute))
 | 
			
		||||
                      .Where(x => x != null)
 | 
			
		||||
                      .Where(x => x is not null)
 | 
			
		||||
                      .Cast<OptionAttribute>()
 | 
			
		||||
                      .Select(x =>
 | 
			
		||||
                      {
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,7 @@ public sealed partial class Music
 | 
			
		||||
                await using var uow = _db.GetDbContext();
 | 
			
		||||
                var pl = uow.MusicPlaylists.FirstOrDefault(x => x.Id == id);
 | 
			
		||||
 | 
			
		||||
                if (pl != null)
 | 
			
		||||
                if (pl is not null)
 | 
			
		||||
                    if (_creds.IsOwner(ctx.User) || pl.AuthorId == ctx.User.Id)
 | 
			
		||||
                    {
 | 
			
		||||
                        uow.MusicPlaylists.Remove(pl);
 | 
			
		||||
@@ -212,7 +212,7 @@ public sealed partial class Music
 | 
			
		||||
                await mp.EnqueueManyAsync(mpl.Songs.Select(x => (x.Query, (MusicPlatform)x.ProviderType)),
 | 
			
		||||
                    ctx.User.ToString());
 | 
			
		||||
 | 
			
		||||
                if (msg != null) await msg.ModifyAsync(m => m.Content = GetText(strs.playlist_queue_complete));
 | 
			
		||||
                if (msg is not null) await msg.ModifyAsync(m => m.Content = GetText(strs.playlist_queue_complete));
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -176,7 +176,7 @@ public sealed class AyuVoiceStateService : INService
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var current = _voiceProxies.AddOrUpdate(guildId,
 | 
			
		||||
                gid => new VoiceProxy(CreateVoiceGatewayLocal()),
 | 
			
		||||
                _ => new VoiceProxy(CreateVoiceGatewayLocal()),
 | 
			
		||||
                (gid, currentProxy) =>
 | 
			
		||||
                {
 | 
			
		||||
                    _ = currentProxy.StopGateway();
 | 
			
		||||
 
 | 
			
		||||
@@ -214,7 +214,7 @@ public sealed class MusicService : IMusicService
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Func<IMusicPlayer, Task> OnQueueStopped(ulong guildId)
 | 
			
		||||
        => mp =>
 | 
			
		||||
        => _ =>
 | 
			
		||||
        {
 | 
			
		||||
            if (_settings.TryGetValue(guildId, out var settings))
 | 
			
		||||
                if (settings.AutoDisconnect)
 | 
			
		||||
@@ -355,7 +355,7 @@ public sealed class MusicService : IMusicService
 | 
			
		||||
            },
 | 
			
		||||
            channelId);
 | 
			
		||||
 | 
			
		||||
        _outputChannels.AddOrUpdate(guildId, (channel, channel), (key, old) => (old.Default, channel));
 | 
			
		||||
        _outputChannels.AddOrUpdate(guildId, (channel, channel), (_, old) => (old.Default, channel));
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ public partial class NSFW : NadekoModule<ISearchImagesService>
 | 
			
		||||
        if (interval < 20)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        t = new(async state =>
 | 
			
		||||
        t = new(async _ =>
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
@@ -101,7 +101,7 @@ public partial class NSFW : NadekoModule<ISearchImagesService>
 | 
			
		||||
 | 
			
		||||
        _service.AutoHentaiTimers.AddOrUpdate(ctx.Channel.Id,
 | 
			
		||||
            t,
 | 
			
		||||
            (key, old) =>
 | 
			
		||||
            (_, old) =>
 | 
			
		||||
            {
 | 
			
		||||
                old.Change(Timeout.Infinite, Timeout.Infinite);
 | 
			
		||||
                return t;
 | 
			
		||||
@@ -130,7 +130,7 @@ public partial class NSFW : NadekoModule<ISearchImagesService>
 | 
			
		||||
        if (interval < 20)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        t = new(async state =>
 | 
			
		||||
        t = new(async _ =>
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
@@ -147,7 +147,7 @@ public partial class NSFW : NadekoModule<ISearchImagesService>
 | 
			
		||||
 | 
			
		||||
        _service.AutoBoobTimers.AddOrUpdate(ctx.Channel.Id,
 | 
			
		||||
            t,
 | 
			
		||||
            (key, old) =>
 | 
			
		||||
            (_, old) =>
 | 
			
		||||
            {
 | 
			
		||||
                old.Change(Timeout.Infinite, Timeout.Infinite);
 | 
			
		||||
                return t;
 | 
			
		||||
@@ -176,7 +176,7 @@ public partial class NSFW : NadekoModule<ISearchImagesService>
 | 
			
		||||
        if (interval < 20)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        t = new(async state =>
 | 
			
		||||
        t = new(async _ =>
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
@@ -193,7 +193,7 @@ public partial class NSFW : NadekoModule<ISearchImagesService>
 | 
			
		||||
 | 
			
		||||
        _service.AutoButtTimers.AddOrUpdate(ctx.Channel.Id,
 | 
			
		||||
            t,
 | 
			
		||||
            (key, old) =>
 | 
			
		||||
            (_, old) =>
 | 
			
		||||
            {
 | 
			
		||||
                old.Change(Timeout.Infinite, Timeout.Infinite);
 | 
			
		||||
                return t;
 | 
			
		||||
@@ -222,7 +222,7 @@ public partial class NSFW : NadekoModule<ISearchImagesService>
 | 
			
		||||
                _service.Konachan(ctx.Guild?.Id, true, tags),
 | 
			
		||||
                _service.Gelbooru(ctx.Guild?.Id, true, tags));
 | 
			
		||||
 | 
			
		||||
            var linksEnum = images.Where(l => l != null).ToArray();
 | 
			
		||||
            var linksEnum = images.Where(l => l is not null).ToArray();
 | 
			
		||||
            if (!linksEnum.Any())
 | 
			
		||||
            {
 | 
			
		||||
                await ReplyErrorLocalizedAsync(strs.no_results);
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@ public partial class Permissions
 | 
			
		||||
                var localSet = CommandCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CommandCooldown>());
 | 
			
		||||
 | 
			
		||||
                var toDelete = config.CommandCooldowns.FirstOrDefault(cc => cc.CommandName == name);
 | 
			
		||||
                if (toDelete != null)
 | 
			
		||||
                if (toDelete is not null)
 | 
			
		||||
                    uow.Set<CommandCooldown>().Remove(toDelete);
 | 
			
		||||
                localSet.RemoveWhere(cc => cc.CommandName == name);
 | 
			
		||||
                if (secs != 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ public partial class Permissions : NadekoModule<PermissionService>
 | 
			
		||||
    [Priority(0)]
 | 
			
		||||
    public async partial Task PermRole([Leftover] IRole role = null)
 | 
			
		||||
    {
 | 
			
		||||
        if (role != null && role == role.Guild.EveryoneRole)
 | 
			
		||||
        if (role is not null && role == role.Guild.EveryoneRole)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (role is null)
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ public sealed class BlacklistService : IEarlyBehavior
 | 
			
		||||
    {
 | 
			
		||||
        foreach (var bl in _blacklist)
 | 
			
		||||
        {
 | 
			
		||||
            if (guild != null && bl.Type == BlacklistType.Server && bl.ItemId == guild.Id)
 | 
			
		||||
            if (guild is not null && bl.Type == BlacklistType.Server && bl.ItemId == guild.Id)
 | 
			
		||||
            {
 | 
			
		||||
                Log.Information("Blocked input from blacklisted guild: {GuildName} [{GuildId}]", guild.Name, guild.Id);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,10 +22,10 @@ public class CmdCdService : ILateBlocker, INService
 | 
			
		||||
 | 
			
		||||
        var cmdcds = CommandCooldowns.GetOrAdd(guild.Id, new ConcurrentHashSet<CommandCooldown>());
 | 
			
		||||
        CommandCooldown cdRule;
 | 
			
		||||
        if ((cdRule = cmdcds.FirstOrDefault(cc => cc.CommandName == commandName)) != null)
 | 
			
		||||
        if ((cdRule = cmdcds.FirstOrDefault(cc => cc.CommandName == commandName)) is not null)
 | 
			
		||||
        {
 | 
			
		||||
            var activeCdsForGuild = ActiveCooldowns.GetOrAdd(guild.Id, new ConcurrentHashSet<ActiveCooldown>());
 | 
			
		||||
            if (activeCdsForGuild.FirstOrDefault(ac => ac.UserId == user.Id && ac.Command == commandName) != null)
 | 
			
		||||
            if (activeCdsForGuild.FirstOrDefault(ac => ac.UserId == user.Id && ac.Command == commandName) is not null)
 | 
			
		||||
                return Task.FromResult(true);
 | 
			
		||||
 | 
			
		||||
            activeCdsForGuild.Add(new() { UserId = user.Id, Command = commandName });
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,7 @@ public class PermissionService : ILateBlocker, INService
 | 
			
		||||
                PermRole = config.PermissionRole,
 | 
			
		||||
                Verbose = config.VerbosePermissions
 | 
			
		||||
            },
 | 
			
		||||
            (id, old) =>
 | 
			
		||||
            (_, old) =>
 | 
			
		||||
            {
 | 
			
		||||
                old.Permissions = new(config.Permissions);
 | 
			
		||||
                old.PermRole = config.PermissionRole;
 | 
			
		||||
 
 | 
			
		||||
@@ -700,7 +700,7 @@ public partial class Searches : NadekoModule<SearchesService>
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (obj.Error != null || obj.Verses is null || obj.Verses.Length == 0)
 | 
			
		||||
        if (obj.Error is not null || obj.Verses is null || obj.Verses.Length == 0)
 | 
			
		||||
        {
 | 
			
		||||
            await SendErrorAsync(obj.Error ?? "No verse found.");
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -72,13 +72,13 @@ public class AnimeSearchService : INService
 | 
			
		||||
 | 
			
		||||
                var genres = document.QuerySelector("div#seriesgenre")
 | 
			
		||||
                                     .Children.Select(x => x as IHtmlAnchorElement)
 | 
			
		||||
                                     .Where(x => x != null)
 | 
			
		||||
                                     .Where(x => x is not null)
 | 
			
		||||
                                     .Select(x => $"[{x.InnerHtml}]({x.Href})")
 | 
			
		||||
                                     .ToArray();
 | 
			
		||||
 | 
			
		||||
                var authors = document.QuerySelector("div#showauthors")
 | 
			
		||||
                                      .Children.Select(x => x as IHtmlAnchorElement)
 | 
			
		||||
                                      .Where(x => x != null)
 | 
			
		||||
                                      .Where(x => x is not null)
 | 
			
		||||
                                      .Select(x => $"[{x.InnerHtml}]({x.Href})")
 | 
			
		||||
                                      .ToArray();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@ public class CryptoService : INService
 | 
			
		||||
            crypto = nearest?.Elem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (nearest != null) return (null, crypto);
 | 
			
		||||
        if (nearest is not null) return (null, crypto);
 | 
			
		||||
 | 
			
		||||
        return (crypto, null);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -108,10 +108,10 @@ public class FeedsService : INService
 | 
			
		||||
                                previewElement = afi.Element.Elements()
 | 
			
		||||
                                                    .FirstOrDefault(x => x.Name.LocalName == "thumbnail");
 | 
			
		||||
 | 
			
		||||
                            if (previewElement != null)
 | 
			
		||||
                            if (previewElement is not null)
 | 
			
		||||
                            {
 | 
			
		||||
                                var urlAttribute = previewElement.Attribute("url");
 | 
			
		||||
                                if (urlAttribute != null
 | 
			
		||||
                                if (urlAttribute is not null
 | 
			
		||||
                                    && !string.IsNullOrWhiteSpace(urlAttribute.Value)
 | 
			
		||||
                                    && Uri.IsWellFormedUriString(urlAttribute.Value, UriKind.Absolute))
 | 
			
		||||
                                {
 | 
			
		||||
@@ -129,10 +129,10 @@ public class FeedsService : INService
 | 
			
		||||
                            embed.WithDescription(desc.TrimTo(2048));
 | 
			
		||||
 | 
			
		||||
                        //send the created embed to all subscribed channels
 | 
			
		||||
                        var feedSendTasks = kvp.Value.Where(x => x.GuildConfig != null)
 | 
			
		||||
                        var feedSendTasks = kvp.Value.Where(x => x.GuildConfig is not null)
 | 
			
		||||
                                               .Select(x => _client.GetGuild(x.GuildConfig.GuildId)
 | 
			
		||||
                                                                   ?.GetTextChannel(x.ChannelId))
 | 
			
		||||
                                               .Where(x => x != null)
 | 
			
		||||
                                               .Where(x => x is not null)
 | 
			
		||||
                                               .Select(x => x.EmbedAsync(embed));
 | 
			
		||||
 | 
			
		||||
                        allSendTasks.Add(feedSendTasks.WhenAll());
 | 
			
		||||
@@ -174,7 +174,7 @@ public class FeedsService : INService
 | 
			
		||||
        foreach (var feed in gc.FeedSubs)
 | 
			
		||||
            _subs.AddOrUpdate(feed.Url.ToLower(),
 | 
			
		||||
                new HashSet<FeedSub> { feed },
 | 
			
		||||
                (k, old) =>
 | 
			
		||||
                (_, old) =>
 | 
			
		||||
                {
 | 
			
		||||
                    old.Add(feed);
 | 
			
		||||
                    return old;
 | 
			
		||||
@@ -198,7 +198,7 @@ public class FeedsService : INService
 | 
			
		||||
        var toRemove = items[index];
 | 
			
		||||
        _subs.AddOrUpdate(toRemove.Url.ToLower(),
 | 
			
		||||
            new HashSet<FeedSub>(),
 | 
			
		||||
            (key, old) =>
 | 
			
		||||
            (_, old) =>
 | 
			
		||||
            {
 | 
			
		||||
                old.Remove(toRemove);
 | 
			
		||||
                return old;
 | 
			
		||||
 
 | 
			
		||||
@@ -549,7 +549,7 @@ public class SearchesService : INService
 | 
			
		||||
 | 
			
		||||
                               return new GoogleSearchResult(name, href, txt);
 | 
			
		||||
                           })
 | 
			
		||||
                           .Where(x => x != null)
 | 
			
		||||
                           .Where(x => x is not null)
 | 
			
		||||
                           .ToList();
 | 
			
		||||
 | 
			
		||||
        return new(results.AsReadOnly(), fullQueryLink, totalResults);
 | 
			
		||||
@@ -596,7 +596,7 @@ public class SearchesService : INService
 | 
			
		||||
 | 
			
		||||
                               return new GoogleSearchResult(name, href, txt);
 | 
			
		||||
                           })
 | 
			
		||||
                           .Where(x => x != null)
 | 
			
		||||
                           .Where(x => x is not null)
 | 
			
		||||
                           .ToList();
 | 
			
		||||
 | 
			
		||||
        return new(results.AsReadOnly(), fullQueryLink, "0");
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@ public partial class Utility
 | 
			
		||||
                    var config = uow.GuildConfigsForId(ctx.Guild.Id, set => set.Include(x => x.CommandAliases));
 | 
			
		||||
                    var toAdd = new CommandAlias { Mapping = mapping, Trigger = trigger };
 | 
			
		||||
                    var tr = config.CommandAliases.FirstOrDefault(x => x.Trigger == trigger);
 | 
			
		||||
                    if (tr != null)
 | 
			
		||||
                    if (tr is not null)
 | 
			
		||||
                        uow.Set<CommandAlias>().Remove(tr);
 | 
			
		||||
                    uow.SaveChanges();
 | 
			
		||||
                }
 | 
			
		||||
@@ -91,7 +91,7 @@ public partial class Utility
 | 
			
		||||
                        uow.SaveChanges();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    map.AddOrUpdate(trigger, mapping, (key, old) => mapping);
 | 
			
		||||
                    map.AddOrUpdate(trigger, mapping, (_, _) => mapping);
 | 
			
		||||
                    return map;
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -103,7 +103,7 @@ public partial class Utility
 | 
			
		||||
                 .WithOkColor();
 | 
			
		||||
 | 
			
		||||
            var av = user.RealAvatarUrl();
 | 
			
		||||
            if (av != null && av.IsAbsoluteUri)
 | 
			
		||||
            if (av is not null && av.IsAbsoluteUri)
 | 
			
		||||
                embed.WithThumbnailUrl(av.ToString());
 | 
			
		||||
            await ctx.Channel.EmbedAsync(embed);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -83,7 +83,7 @@ public partial class Utility
 | 
			
		||||
            await using (var uow = _db.GetDbContext())
 | 
			
		||||
            {
 | 
			
		||||
                quote = await uow.Quotes.GetRandomQuoteByKeywordAsync(ctx.Guild.Id, keyword);
 | 
			
		||||
                //if (quote != null)
 | 
			
		||||
                //if (quote is not null)
 | 
			
		||||
                //{
 | 
			
		||||
                //    quote.UseCount += 1;
 | 
			
		||||
                //    uow.Complete();
 | 
			
		||||
 
 | 
			
		||||
@@ -181,7 +181,7 @@ public partial class Utility
 | 
			
		||||
            if (ts > TimeSpan.FromDays(60))
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            if (ctx.Guild != null)
 | 
			
		||||
            if (ctx.Guild is not null)
 | 
			
		||||
            {
 | 
			
		||||
                var perms = ((IGuildUser)ctx.User).GetPermissions((IGuildChannel)ctx.Channel);
 | 
			
		||||
                if (!perms.MentionEveryone) message = message.SanitizeAllMentions();
 | 
			
		||||
 
 | 
			
		||||
@@ -102,7 +102,7 @@ public partial class Utility
 | 
			
		||||
                interval?.Time ?? (startTimeOfDay is null ? TimeSpan.FromMinutes(5) : TimeSpan.FromDays(1));
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(message)
 | 
			
		||||
                || (interval != null
 | 
			
		||||
                || (interval is not null
 | 
			
		||||
                    && (interval.Time > TimeSpan.FromMinutes(25000) || interval.Time < TimeSpan.FromMinutes(1))))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@ public class CommandMapService : IInputTransformer, INService
 | 
			
		||||
        if (guild is null || string.IsNullOrWhiteSpace(input))
 | 
			
		||||
            return input;
 | 
			
		||||
 | 
			
		||||
        if (guild != null)
 | 
			
		||||
        if (guild is not null)
 | 
			
		||||
            if (AliasMaps.TryGetValue(guild.Id, out var maps))
 | 
			
		||||
            {
 | 
			
		||||
                var keys = maps.Keys.OrderByDescending(x => x.Length);
 | 
			
		||||
 
 | 
			
		||||
@@ -212,7 +212,7 @@ where ((guildid >> 22) % {_creds.TotalShards}) == {_client.ShardId};")
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var lastMsgInChannel = await channel.GetMessagesAsync(2).Flatten().FirstAsync();
 | 
			
		||||
                if (lastMsgInChannel != null && lastMsgInChannel.Id == repeater.LastMessageId)
 | 
			
		||||
                if (lastMsgInChannel is not null && lastMsgInChannel.Id == repeater.LastMessageId)
 | 
			
		||||
                    return;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
@@ -228,7 +228,7 @@ where ((guildid >> 22) % {_creds.TotalShards}) == {_client.ShardId};")
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var oldMsg = await channel.GetMessageAsync(lastMessageId);
 | 
			
		||||
                if (oldMsg != null) await oldMsg.DeleteAsync();
 | 
			
		||||
                if (oldMsg is not null) await oldMsg.DeleteAsync();
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ public sealed class RunningRepeater
 | 
			
		||||
 | 
			
		||||
    private DateTime CalculateInitialExecution()
 | 
			
		||||
    {
 | 
			
		||||
        if (Repeater.StartTimeOfDay != null)
 | 
			
		||||
        if (Repeater.StartTimeOfDay is not null)
 | 
			
		||||
        {
 | 
			
		||||
            // if there was a start time of day
 | 
			
		||||
            // calculate whats the next time of day repeat should trigger at
 | 
			
		||||
 
 | 
			
		||||
@@ -77,7 +77,7 @@ public class StreamRoleService : INService
 | 
			
		||||
                if (action == AddRemove.Rem)
 | 
			
		||||
                {
 | 
			
		||||
                    var toDelete = streamRoleSettings.Whitelist.FirstOrDefault(x => x.Equals(userObj));
 | 
			
		||||
                    if (toDelete != null)
 | 
			
		||||
                    if (toDelete is not null)
 | 
			
		||||
                    {
 | 
			
		||||
                        uow.Remove(toDelete);
 | 
			
		||||
                        success = true;
 | 
			
		||||
@@ -95,7 +95,7 @@ public class StreamRoleService : INService
 | 
			
		||||
                if (action == AddRemove.Rem)
 | 
			
		||||
                {
 | 
			
		||||
                    var toRemove = streamRoleSettings.Blacklist.FirstOrDefault(x => x.Equals(userObj));
 | 
			
		||||
                    if (toRemove != null)
 | 
			
		||||
                    if (toRemove is not null)
 | 
			
		||||
                    {
 | 
			
		||||
                        success = true;
 | 
			
		||||
                        success = streamRoleSettings.Blacklist.Remove(toRemove);
 | 
			
		||||
@@ -299,5 +299,5 @@ public class StreamRoleService : INService
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void UpdateCache(ulong guildId, StreamRoleSettings setting)
 | 
			
		||||
        => guildSettings.AddOrUpdate(guildId, key => setting, (key, old) => setting);
 | 
			
		||||
        => guildSettings.AddOrUpdate(guildId, _ => setting, (_, _) => setting);
 | 
			
		||||
}
 | 
			
		||||
@@ -90,7 +90,7 @@ public partial class Utility : NadekoModule
 | 
			
		||||
                                                  .Where(u => u.Activities.FirstOrDefault()?.Name?.ToUpperInvariant()
 | 
			
		||||
                                                              == game)
 | 
			
		||||
                                                  .Select(u => u.Username)
 | 
			
		||||
                                                  .OrderBy(x => rng.Next())
 | 
			
		||||
                                                  .OrderBy(_ => rng.Next())
 | 
			
		||||
                                                  .Take(60)
 | 
			
		||||
                                                  .ToArray());
 | 
			
		||||
 | 
			
		||||
@@ -100,7 +100,7 @@ public partial class Utility : NadekoModule
 | 
			
		||||
        else
 | 
			
		||||
            await SendConfirmAsync("```css\n"
 | 
			
		||||
                                   + string.Join("\n",
 | 
			
		||||
                                       arr.GroupBy(item => i++ / 2)
 | 
			
		||||
                                       arr.GroupBy(_ => i++ / 2)
 | 
			
		||||
                                          .Select(ig => string.Concat(ig.Select(el => $"• {el,-27}"))))
 | 
			
		||||
                                   + "\n```");
 | 
			
		||||
    }
 | 
			
		||||
@@ -198,7 +198,7 @@ public partial class Utility : NadekoModule
 | 
			
		||||
        if (page is < 1 or > 100)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (target != null)
 | 
			
		||||
        if (target is not null)
 | 
			
		||||
        {
 | 
			
		||||
            var roles = target.GetRoles()
 | 
			
		||||
                              .Except(new[] { guild.EveryoneRole })
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ public partial class Xp
 | 
			
		||||
        {
 | 
			
		||||
            var club = _service.TransferClub(ctx.User, newOwner);
 | 
			
		||||
 | 
			
		||||
            if (club != null)
 | 
			
		||||
            if (club is not null)
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(strs.club_transfered(Format.Bold(club.Name),
 | 
			
		||||
                    Format.Bold(newOwner.ToString())));
 | 
			
		||||
            else
 | 
			
		||||
@@ -66,7 +66,7 @@ public partial class Xp
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        public async partial Task ClubIcon([Leftover] string url = null)
 | 
			
		||||
        {
 | 
			
		||||
            if ((!Uri.IsWellFormedUriString(url, UriKind.Absolute) && url != null)
 | 
			
		||||
            if ((!Uri.IsWellFormedUriString(url, UriKind.Absolute) && url is not null)
 | 
			
		||||
                || !await _service.SetClubIcon(ctx.User.Id, url is null ? null : new Uri(url)))
 | 
			
		||||
            {
 | 
			
		||||
                await ReplyErrorLocalizedAsync(strs.club_icon_error);
 | 
			
		||||
@@ -166,7 +166,7 @@ public partial class Xp
 | 
			
		||||
            var bans = club.Bans.Select(x => x.User).ToArray();
 | 
			
		||||
 | 
			
		||||
            return ctx.SendPaginatedConfirmAsync(page,
 | 
			
		||||
                curPage =>
 | 
			
		||||
                _ =>
 | 
			
		||||
                {
 | 
			
		||||
                    var toShow = string.Join("\n", bans.Skip(page * 10).Take(10).Select(x => x.ToString()));
 | 
			
		||||
 | 
			
		||||
@@ -193,7 +193,7 @@ public partial class Xp
 | 
			
		||||
            var apps = club.Applicants.Select(x => x.User).ToArray();
 | 
			
		||||
 | 
			
		||||
            return ctx.SendPaginatedConfirmAsync(page,
 | 
			
		||||
                curPage =>
 | 
			
		||||
                _ =>
 | 
			
		||||
                {
 | 
			
		||||
                    var toShow = string.Join("\n", apps.Skip(page * 10).Take(10).Select(x => x.ToString()));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,7 @@ public class ClubService : INService
 | 
			
		||||
 | 
			
		||||
    public async Task<bool> SetClubIcon(ulong ownerUserId, Uri url)
 | 
			
		||||
    {
 | 
			
		||||
        if (url != null)
 | 
			
		||||
        if (url is not null)
 | 
			
		||||
        {
 | 
			
		||||
            using var http = _httpFactory.CreateClient();
 | 
			
		||||
            using var temp = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
 | 
			
		||||
@@ -134,7 +134,7 @@ public class ClubService : INService
 | 
			
		||||
        var du = uow.GetOrCreateUser(user);
 | 
			
		||||
        uow.SaveChanges();
 | 
			
		||||
 | 
			
		||||
        if (du.Club != null
 | 
			
		||||
        if (du.Club is not null
 | 
			
		||||
            || new LevelStats(du.TotalXp).Level < club.MinimumLevelReq
 | 
			
		||||
            || club.Bans.Any(x => x.UserId == du.Id)
 | 
			
		||||
            || club.Applicants.Any(x => x.UserId == du.Id))
 | 
			
		||||
@@ -258,7 +258,7 @@ public class ClubService : INService
 | 
			
		||||
        club.Users.Remove(usr);
 | 
			
		||||
 | 
			
		||||
        var app = club.Applicants.FirstOrDefault(x => x.UserId == usr.Id);
 | 
			
		||||
        if (app != null)
 | 
			
		||||
        if (app is not null)
 | 
			
		||||
            club.Applicants.Remove(app);
 | 
			
		||||
 | 
			
		||||
        uow.SaveChanges();
 | 
			
		||||
@@ -299,7 +299,7 @@ public class ClubService : INService
 | 
			
		||||
 | 
			
		||||
        club.Users.Remove(usr);
 | 
			
		||||
        var app = club.Applicants.FirstOrDefault(x => x.UserId == usr.Id);
 | 
			
		||||
        if (app != null)
 | 
			
		||||
        if (app is not null)
 | 
			
		||||
            club.Applicants.Remove(app);
 | 
			
		||||
        uow.SaveChanges();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -90,7 +90,7 @@ public class XpService : INService
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
        //load settings
 | 
			
		||||
        var allGuildConfigs = bot.AllGuildConfigs.Where(x => x.XpSettings != null).ToList();
 | 
			
		||||
        var allGuildConfigs = bot.AllGuildConfigs.Where(x => x.XpSettings is not null).ToList();
 | 
			
		||||
 | 
			
		||||
        _excludedChannels = allGuildConfigs.ToDictionary(x => x.GuildId,
 | 
			
		||||
                                               x => new ConcurrentHashSet<ulong>(x.XpSettings.ExclusionList
 | 
			
		||||
@@ -156,7 +156,7 @@ public class XpService : INService
 | 
			
		||||
                        var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
 | 
			
		||||
                        usr.Xp += xp;
 | 
			
		||||
                        du.TotalXp += xp;
 | 
			
		||||
                        if (du.Club != null) du.Club.Xp += xp;
 | 
			
		||||
                        if (du.Club is not null) du.Club.Xp += xp;
 | 
			
		||||
                        var newGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
 | 
			
		||||
 | 
			
		||||
                        if (oldGlobalLevelData.Level < newGlobalLevelData.Level)
 | 
			
		||||
@@ -194,7 +194,7 @@ public class XpService : INService
 | 
			
		||||
                            for (var i = oldGuildLevelData.Level + 1; i <= newGuildLevelData.Level; i++)
 | 
			
		||||
                            {
 | 
			
		||||
                                var rrew = rrews.FirstOrDefault(x => x.Level == i);
 | 
			
		||||
                                if (rrew != null)
 | 
			
		||||
                                if (rrew is not null)
 | 
			
		||||
                                {
 | 
			
		||||
                                    var role = first.User.Guild.GetRole(rrew.RoleId);
 | 
			
		||||
                                    if (role is not null)
 | 
			
		||||
@@ -208,7 +208,7 @@ public class XpService : INService
 | 
			
		||||
 | 
			
		||||
                                //get currency reward for this level
 | 
			
		||||
                                var crew = crews.FirstOrDefault(x => x.Level == i);
 | 
			
		||||
                                if (crew != null)
 | 
			
		||||
                                if (crew is not null)
 | 
			
		||||
                                    //give the user the reward if it exists
 | 
			
		||||
                                    await _cs.AddAsync(item.Key.User.Id, "Level-up Reward", crew.Amount);
 | 
			
		||||
                            }
 | 
			
		||||
@@ -228,7 +228,7 @@ public class XpService : INService
 | 
			
		||||
                                                      Format.Bold(x.Level.ToString()),
 | 
			
		||||
                                                      Format.Bold(x.Guild.ToString() ?? "-")),
 | 
			
		||||
                                                  x.Guild.Id));
 | 
			
		||||
                                      else if (x.MessageChannel != null) // channel
 | 
			
		||||
                                      else if (x.MessageChannel is not null) // channel
 | 
			
		||||
                                          await x.MessageChannel.SendConfirmAsync(_eb,
 | 
			
		||||
                                              _strings.GetText(strs.level_up_channel(x.User.Mention,
 | 
			
		||||
                                                      Format.Bold(x.Level.ToString())),
 | 
			
		||||
@@ -289,7 +289,7 @@ public class XpService : INService
 | 
			
		||||
        if (amount <= 0)
 | 
			
		||||
        {
 | 
			
		||||
            var toRemove = settings.CurrencyRewards.FirstOrDefault(x => x.Level == level);
 | 
			
		||||
            if (toRemove != null)
 | 
			
		||||
            if (toRemove is not null)
 | 
			
		||||
            {
 | 
			
		||||
                uow.Remove(toRemove);
 | 
			
		||||
                settings.CurrencyRewards.Remove(toRemove);
 | 
			
		||||
@@ -299,7 +299,7 @@ public class XpService : INService
 | 
			
		||||
        {
 | 
			
		||||
            var rew = settings.CurrencyRewards.FirstOrDefault(x => x.Level == level);
 | 
			
		||||
 | 
			
		||||
            if (rew != null)
 | 
			
		||||
            if (rew is not null)
 | 
			
		||||
                rew.Amount = amount;
 | 
			
		||||
            else
 | 
			
		||||
                settings.CurrencyRewards.Add(new() { Level = level, Amount = amount });
 | 
			
		||||
@@ -326,7 +326,7 @@ public class XpService : INService
 | 
			
		||||
        var settings = uow.XpSettingsFor(guildId);
 | 
			
		||||
 | 
			
		||||
        var toRemove = settings.RoleRewards.FirstOrDefault(x => x.Level == level);
 | 
			
		||||
        if (toRemove != null)
 | 
			
		||||
        if (toRemove is not null)
 | 
			
		||||
        {
 | 
			
		||||
            uow.Remove(toRemove);
 | 
			
		||||
            settings.RoleRewards.Remove(toRemove);
 | 
			
		||||
@@ -347,7 +347,7 @@ public class XpService : INService
 | 
			
		||||
 | 
			
		||||
        var rew = settings.RoleRewards.FirstOrDefault(x => x.Level == level);
 | 
			
		||||
 | 
			
		||||
        if (rew != null)
 | 
			
		||||
        if (rew is not null)
 | 
			
		||||
        {
 | 
			
		||||
            rew.RoleId = roleId;
 | 
			
		||||
            rew.Remove = remove;
 | 
			
		||||
@@ -424,9 +424,9 @@ public class XpService : INService
 | 
			
		||||
 | 
			
		||||
        var _ = Task.Run(() =>
 | 
			
		||||
        {
 | 
			
		||||
            if (before.VoiceChannel != null) ScanChannelForVoiceXp(before.VoiceChannel);
 | 
			
		||||
            if (before.VoiceChannel is not null) ScanChannelForVoiceXp(before.VoiceChannel);
 | 
			
		||||
 | 
			
		||||
            if (after.VoiceChannel != null && after.VoiceChannel != before.VoiceChannel)
 | 
			
		||||
            if (after.VoiceChannel is not null && after.VoiceChannel != before.VoiceChannel)
 | 
			
		||||
                ScanChannelForVoiceXp(after.VoiceChannel);
 | 
			
		||||
            else if (after.VoiceChannel is null)
 | 
			
		||||
                // In this case, the user left the channel and the previous for loops didn't catch
 | 
			
		||||
@@ -634,7 +634,7 @@ public class XpService : INService
 | 
			
		||||
        roles.TryRemove(rId);
 | 
			
		||||
 | 
			
		||||
        var toDelete = xpSetting.ExclusionList.FirstOrDefault(x => x.Equals(excludeObj));
 | 
			
		||||
        if (toDelete != null)
 | 
			
		||||
        if (toDelete is not null)
 | 
			
		||||
        {
 | 
			
		||||
            uow.Remove(toDelete);
 | 
			
		||||
            uow.SaveChanges();
 | 
			
		||||
@@ -822,7 +822,7 @@ public class XpService : INService
 | 
			
		||||
                        new(_template.User.TimeOnLevel.Guild.Pos.X, _template.User.TimeOnLevel.Guild.Pos.Y)));
 | 
			
		||||
            //avatar
 | 
			
		||||
 | 
			
		||||
            if (stats.User.AvatarId != null && _template.User.Icon.Show)
 | 
			
		||||
            if (stats.User.AvatarId is not null && _template.User.Icon.Show)
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    var avatarUrl = stats.User.RealAvatarUrl();
 | 
			
		||||
 
 | 
			
		||||
@@ -247,13 +247,13 @@ public partial class Xp : NadekoModule<XpService>
 | 
			
		||||
        var serverExcluded = _service.IsServerExcluded(ctx.Guild.Id);
 | 
			
		||||
        var roles = _service.GetExcludedRoles(ctx.Guild.Id)
 | 
			
		||||
                            .Select(x => ctx.Guild.GetRole(x))
 | 
			
		||||
                            .Where(x => x != null)
 | 
			
		||||
                            .Where(x => x is not null)
 | 
			
		||||
                            .Select(x => $"`role`   {x.Mention}")
 | 
			
		||||
                            .ToList();
 | 
			
		||||
 | 
			
		||||
        var chans = (await _service.GetExcludedChannels(ctx.Guild.Id)
 | 
			
		||||
                                   .Select(x => ctx.Guild.GetChannelAsync(x))
 | 
			
		||||
                                   .WhenAll()).Where(x => x != null)
 | 
			
		||||
                                   .WhenAll()).Where(x => x is not null)
 | 
			
		||||
                                              .Select(x => $"`channel` <#{x.Id}>")
 | 
			
		||||
                                              .ToList();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,7 @@ public class CommandHandler : INService
 | 
			
		||||
            GLOBAL_COMMANDS_COOLDOWN,
 | 
			
		||||
            GLOBAL_COMMANDS_COOLDOWN);
 | 
			
		||||
 | 
			
		||||
        _prefixes = bot.AllGuildConfigs.Where(x => x.Prefix != null)
 | 
			
		||||
        _prefixes = bot.AllGuildConfigs.Where(x => x.Prefix is not null)
 | 
			
		||||
                       .ToDictionary(x => x.GuildId, x => x.Prefix)
 | 
			
		||||
                       .ToConcurrent();
 | 
			
		||||
    }
 | 
			
		||||
@@ -111,7 +111,7 @@ public class CommandHandler : INService
 | 
			
		||||
 | 
			
		||||
    public async Task ExecuteExternal(ulong? guildId, ulong channelId, string commandText)
 | 
			
		||||
    {
 | 
			
		||||
        if (guildId != null)
 | 
			
		||||
        if (guildId is not null)
 | 
			
		||||
        {
 | 
			
		||||
            var guild = _client.GetGuild(guildId.Value);
 | 
			
		||||
            if (guild?.GetChannel(channelId) is not SocketTextChannel channel)
 | 
			
		||||
@@ -210,7 +210,7 @@ public class CommandHandler : INService
 | 
			
		||||
            {
 | 
			
		||||
#if !GLOBAL_NADEKO
 | 
			
		||||
                // track how many messagges each user is sending
 | 
			
		||||
                UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++old);
 | 
			
		||||
                UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (_, old) => ++old);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
                var channel = msg.Channel;
 | 
			
		||||
@@ -221,7 +221,7 @@ public class CommandHandler : INService
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                Log.Warning(ex, "Error in CommandHandler");
 | 
			
		||||
                if (ex.InnerException != null)
 | 
			
		||||
                if (ex.InnerException is not null)
 | 
			
		||||
                    Log.Warning(ex.InnerException, "Inner Exception of the error in CommandHandler");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
@@ -260,10 +260,10 @@ public class CommandHandler : INService
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (error != null)
 | 
			
		||||
            if (error is not null)
 | 
			
		||||
            {
 | 
			
		||||
                LogErroredExecution(error, usrMsg, channel as ITextChannel, blockTime, startTime);
 | 
			
		||||
                if (guild != null)
 | 
			
		||||
                if (guild is not null)
 | 
			
		||||
                    await CommandErrored(info, channel as ITextChannel, error);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -384,7 +384,7 @@ public class CommandHandler : INService
 | 
			
		||||
        var chosenOverload = successfulParses[0];
 | 
			
		||||
        var execResult = (ExecuteResult)await chosenOverload.Key.ExecuteAsync(context, chosenOverload.Value, services);
 | 
			
		||||
 | 
			
		||||
        if (execResult.Exception != null
 | 
			
		||||
        if (execResult.Exception is not null
 | 
			
		||||
            && (execResult.Exception is not HttpException he
 | 
			
		||||
                || he.DiscordCode != DiscordErrorCode.InsufficientPermissions))
 | 
			
		||||
            Log.Warning(execResult.Exception, "Command Error");
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ public class Localization : ILocalization, INService
 | 
			
		||||
 | 
			
		||||
                                                        return cultureInfo;
 | 
			
		||||
                                                    })
 | 
			
		||||
                                                .Where(x => x.Value != null));
 | 
			
		||||
                                                .Where(x => x.Value is not null));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void SetGuildCulture(IGuild guild, CultureInfo ci)
 | 
			
		||||
@@ -61,7 +61,7 @@ public class Localization : ILocalization, INService
 | 
			
		||||
            uow.SaveChanges();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        GuildCultureInfos.AddOrUpdate(guildId, ci, (id, old) => ci);
 | 
			
		||||
        GuildCultureInfos.AddOrUpdate(guildId, ci, (_, _) => ci);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void RemoveGuildCulture(IGuild guild)
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ public class RedisCache : IDataCache
 | 
			
		||||
    {
 | 
			
		||||
        var _db = Redis.GetDatabase();
 | 
			
		||||
        byte[] x = await _db.StringGetAsync("image_" + key);
 | 
			
		||||
        return (x != null, x);
 | 
			
		||||
        return (x is not null, x);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Task SetImageDataAsync(Uri key, byte[] data)
 | 
			
		||||
@@ -51,7 +51,7 @@ public class RedisCache : IDataCache
 | 
			
		||||
    {
 | 
			
		||||
        var _db = Redis.GetDatabase();
 | 
			
		||||
        string x = await _db.StringGetAsync("anime_" + key);
 | 
			
		||||
        return (x != null, x);
 | 
			
		||||
        return (x is not null, x);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Task SetAnimeDataAsync(string key, string data)
 | 
			
		||||
@@ -64,7 +64,7 @@ public class RedisCache : IDataCache
 | 
			
		||||
    {
 | 
			
		||||
        var _db = Redis.GetDatabase();
 | 
			
		||||
        string x = await _db.StringGetAsync("novel_" + key);
 | 
			
		||||
        return (x != null, x);
 | 
			
		||||
        return (x is not null, x);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Task SetNovelDataAsync(string key, string data)
 | 
			
		||||
@@ -156,7 +156,7 @@ public class RedisCache : IDataCache
 | 
			
		||||
    public bool TryGetEconomy(out string data)
 | 
			
		||||
    {
 | 
			
		||||
        var _db = Redis.GetDatabase();
 | 
			
		||||
        if ((data = _db.StringGet($"{_redisKey}_economy")) != null) return true;
 | 
			
		||||
        if ((data = _db.StringGet($"{_redisKey}_economy")) is not null) return true;
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -132,7 +132,7 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        _botlistTimer = new(async state =>
 | 
			
		||||
        _botlistTimer = new(async _ =>
 | 
			
		||||
            {
 | 
			
		||||
                if (string.IsNullOrWhiteSpace(_creds.BotListToken))
 | 
			
		||||
                    return;
 | 
			
		||||
 
 | 
			
		||||
@@ -67,7 +67,7 @@ public class YtdlOperation
 | 
			
		||||
        process.Start();
 | 
			
		||||
 | 
			
		||||
        string line;
 | 
			
		||||
        while ((line = await process.StandardOutput.ReadLineAsync()) != null)
 | 
			
		||||
        while ((line = await process.StandardOutput.ReadLineAsync()) is not null)
 | 
			
		||||
            yield return line;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -139,7 +139,7 @@ public static class Extensions
 | 
			
		||||
 | 
			
		||||
    public static IEmbedBuilder AddPaginatedFooter(this IEmbedBuilder embed, int curPage, int? lastPage)
 | 
			
		||||
    {
 | 
			
		||||
        if (lastPage != null)
 | 
			
		||||
        if (lastPage is not null)
 | 
			
		||||
            return embed.WithFooter($"{curPage + 1} / {lastPage + 1}");
 | 
			
		||||
        return embed.WithFooter(curPage.ToString());
 | 
			
		||||
    }
 | 
			
		||||
@@ -196,7 +196,7 @@ public static class Extensions
 | 
			
		||||
        Task.Run(async () =>
 | 
			
		||||
        {
 | 
			
		||||
            await Task.Delay(seconds * 1000);
 | 
			
		||||
            if (logService != null) logService.AddDeleteIgnore(msg.Id);
 | 
			
		||||
            if (logService is not null) logService.AddDeleteIgnore(msg.Id);
 | 
			
		||||
 | 
			
		||||
            try { await msg.DeleteAsync(); }
 | 
			
		||||
            catch { }
 | 
			
		||||
@@ -206,7 +206,7 @@ public static class Extensions
 | 
			
		||||
 | 
			
		||||
    public static ModuleInfo GetTopLevelModule(this ModuleInfo module)
 | 
			
		||||
    {
 | 
			
		||||
        while (module.Parent != null) module = module.Parent;
 | 
			
		||||
        while (module.Parent is not null) module = module.Parent;
 | 
			
		||||
 | 
			
		||||
        return module;
 | 
			
		||||
    }
 | 
			
		||||
@@ -269,7 +269,7 @@ public static class Extensions
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IEnumerable<IRole> GetRoles(this IGuildUser user)
 | 
			
		||||
        => user.RoleIds.Select(r => user.Guild.GetRole(r)).Where(r => r != null);
 | 
			
		||||
        => user.RoleIds.Select(r => user.Guild.GetRole(r)).Where(r => r is not null);
 | 
			
		||||
 | 
			
		||||
    public static bool IsImage(this HttpResponseMessage msg)
 | 
			
		||||
        => IsImage(msg, out _);
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ public static class MessageChannelExtensions
 | 
			
		||||
    {
 | 
			
		||||
        var embed = eb.Create().WithErrorColor().WithDescription(error).WithTitle(title);
 | 
			
		||||
 | 
			
		||||
        if (url != null && Uri.IsWellFormedUriString(url, UriKind.Absolute))
 | 
			
		||||
        if (url is not null && Uri.IsWellFormedUriString(url, UriKind.Absolute))
 | 
			
		||||
            embed.WithUrl(url);
 | 
			
		||||
 | 
			
		||||
        if (!string.IsNullOrWhiteSpace(footer))
 | 
			
		||||
@@ -65,7 +65,7 @@ public static class MessageChannelExtensions
 | 
			
		||||
    {
 | 
			
		||||
        var embed = eb.Create().WithOkColor().WithDescription(text).WithTitle(title);
 | 
			
		||||
 | 
			
		||||
        if (url != null && Uri.IsWellFormedUriString(url, UriKind.Absolute))
 | 
			
		||||
        if (url is not null && Uri.IsWellFormedUriString(url, UriKind.Absolute))
 | 
			
		||||
            embed.WithUrl(url);
 | 
			
		||||
 | 
			
		||||
        if (!string.IsNullOrWhiteSpace(footer))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using NadekoBot.Common.Yml;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user