public static async void EnqueueLogProcessing(DiscordClient client, DiscordChannel channel, DiscordMessage message, DiscordMember requester = null, bool checkExternalLinks = false)
        {
            try
            {
                if (!QueueLimiter.Wait(0))
                {
                    await channel.SendMessageAsync("Log processing is rate limited, try again a bit later").ConfigureAwait(false);

                    return;
                }

                bool           parsedLog = false;
                var            startTime = Stopwatch.StartNew();
                DiscordMessage botMsg    = null;
                try
                {
                    var possibleHandlers = sourceHandlers.Select(h => h.FindHandlerAsync(message, archiveHandlers).ConfigureAwait(false).GetAwaiter().GetResult()).ToList();
                    var source           = possibleHandlers.FirstOrDefault(h => h.source != null).source;
                    var fail             = possibleHandlers.FirstOrDefault(h => !string.IsNullOrEmpty(h.failReason)).failReason;
                    if (source != null)
                    {
                        Config.Log.Debug($">>>>>>> {message.Id % 100} Parsing log '{source.FileName}' from {message.Author.Username}#{message.Author.Discriminator} ({message.Author.Id}) using {source.GetType().Name} ({source.SourceFileSize} bytes)...");
                        var analyzingProgressEmbed = GetAnalyzingMsgEmbed(client);
                        botMsg = await channel.SendMessageAsync(embed : analyzingProgressEmbed.AddAuthor(client, message, source)).ConfigureAwait(false);

                        parsedLog = true;

                        LogParseState result = null;
                        using (var timeout = new CancellationTokenSource(Config.LogParsingTimeout))
                        {
                            using var combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, Config.Cts.Token);
                            var tries = 0;
                            do
                            {
                                result = await ParseLogAsync(
                                    source,
                                    async() => botMsg = await botMsg.UpdateOrCreateMessageAsync(channel, embed : analyzingProgressEmbed.AddAuthor(client, message, source)).ConfigureAwait(false),
                                    combinedTokenSource.Token
                                    ).ConfigureAwait(false);

                                tries++;
                            } while (result == null && !combinedTokenSource.IsCancellationRequested && tries < 3);
                        }
                        if (result == null)
                        {
                            botMsg = await botMsg.UpdateOrCreateMessageAsync(channel, embed : new DiscordEmbedBuilder
                            {
                                Description = "Log analysis failed, most likely cause is a truncated/invalid log.\n" +
                                              "Please run the game again and re-upload a new copy.",
                                Color = Config.Colors.LogResultFailed,
                            }
                                                                             .AddAuthor(client, message, source)
                                                                             .Build()
                                                                             ).ConfigureAwait(false);
                        }
                        else
                        {
                            result.ParsingTime = startTime.Elapsed;
                            try
                            {
                                if (result.Error == LogParseState.ErrorCode.PiracyDetected)
                                {
                                    var yarr = client.GetEmoji(":piratethink:", "☠");
                                    result.ReadBytes = 0;
                                    if (message.Author.IsWhitelisted(client, channel.Guild))
                                    {
                                        var piracyWarning = await result.AsEmbedAsync(client, message, source).ConfigureAwait(false);

                                        piracyWarning = piracyWarning.WithDescription("Please remove the log and issue warning to the original author of the log");
                                        botMsg        = await botMsg.UpdateOrCreateMessageAsync(channel, embed : piracyWarning).ConfigureAwait(false);

                                        await client.ReportAsync(yarr + " Pirated Release (whitelisted by role)", message, result.SelectedFilter?.String, result.SelectedFilterContext, ReportSeverity.Low).ConfigureAwait(false);
                                    }
                                    else
                                    {
                                        var severity = ReportSeverity.Low;
                                        try
                                        {
                                            await message.DeleteAsync("Piracy detected in log").ConfigureAwait(false);
                                        }
                                        catch (Exception e)
                                        {
                                            severity = ReportSeverity.High;
                                            Config.Log.Warn(e, $"Unable to delete message in {channel.Name}");
                                        }
                                        try
                                        {
                                            /*
                                             * botMsg = await botMsg.UpdateOrCreateMessageAsync(channel,
                                             *  $"{message.Author.Mention}, please read carefully:",
                                             *  embed: await result.AsEmbedAsync(client, message, source).ConfigureAwait(false)
                                             * ).ConfigureAwait(false);
                                             */
                                            botMsg = await botMsg.UpdateOrCreateMessageAsync(channel,
                                                                                             $"{message.Author.Mention}, please read carefully:\n" +
                                                                                             "🏴‍☠️ **Pirated content detected** 🏴‍☠️\n" +
                                                                                             "__You are being denied further support until you legally dump the game__.\n" +
                                                                                             "Please note that the RPCS3 community and its developers do not support piracy.\n" +
                                                                                             "Most of the issues with pirated dumps occur due to them being modified in some way " +
                                                                                             "that prevent them from working on RPCS3.\n" +
                                                                                             "If you need help obtaining valid working dump of the game you own, please read the quickstart guide at <https://rpcs3.net/quickstart>"
                                                                                             ).ConfigureAwait(false);
                                        }
                                        catch (Exception e)
                                        {
                                            Config.Log.Error(e, "Failed to send piracy warning");
                                        }
                                        try
                                        {
                                            await client.ReportAsync(yarr + " Pirated Release", message, result.SelectedFilter?.String, result.SelectedFilterContext, severity).ConfigureAwait(false);
                                        }
                                        catch (Exception e)
                                        {
                                            Config.Log.Error(e, "Failed to send piracy report");
                                        }
                                        if (!(message.Channel.IsPrivate || (message.Channel.Name?.Contains("spam") ?? true)))
                                        {
                                            await Warnings.AddAsync(client, message, message.Author.Id, message.Author.Username, client.CurrentUser, "Pirated Release", $"{result.SelectedFilter?.String} - {result.SelectedFilterContext?.Sanitize()}");
                                        }
                                    }
                                }
                                else
                                {
                                    if (result.SelectedFilter != null)
                                    {
                                        await ContentFilter.PerformFilterActions(client, message, result.SelectedFilter, FilterAction.IssueWarning | FilterAction.SendMessage, result.SelectedFilterContext).ConfigureAwait(false);
                                    }
                                    botMsg = await botMsg.UpdateOrCreateMessageAsync(channel,
                                                                                     requester == null?null : $"Analyzed log from {client.GetMember(channel.Guild, message.Author)?.GetUsernameWithNickname()} by request from {requester.Mention}:",
                                                                                     embed : await result.AsEmbedAsync(client, message, source).ConfigureAwait(false)
                                                                                     ).ConfigureAwait(false);
                                }
                            }
                            catch (Exception e)
                            {
                                Config.Log.Error(e, "Sending log results failed");
                            }
                        }
                        return;
                    }
                    else if (!string.IsNullOrEmpty(fail) &&
                             ("help".Equals(channel.Name, StringComparison.InvariantCultureIgnoreCase) || LimitedToSpamChannel.IsSpamChannel(channel)))
                    {
                        await channel.SendMessageAsync($"{message.Author.Mention} {fail}").ConfigureAwait(false);

                        return;
                    }

                    if (!"help".Equals(channel.Name, StringComparison.InvariantCultureIgnoreCase))
                    {
                        return;
                    }

                    var potentialLogExtension = message.Attachments.Select(a => Path.GetExtension(a.FileName).ToUpperInvariant().TrimStart('.')).FirstOrDefault();
                    switch (potentialLogExtension)
                    {
                    case "TXT":
                    {
                        await channel.SendMessageAsync($"{message.Author.Mention} Please upload the full RPCS3.log.gz (or RPCS3.log with a zip/rar icon) file after closing the emulator instead of copying the logs from RPCS3's interface, as it doesn't contain all the required information.").ConfigureAwait(false);

                        return;
                    }
                    }

                    if (string.IsNullOrEmpty(message.Content))
                    {
                        return;
                    }

                    var linkStart = message.Content.IndexOf("http");
                    if (linkStart > -1)
                    {
                        var link = message.Content[linkStart..].Split(linkSeparator, 2)[0];
                        if (link.Contains(".log", StringComparison.InvariantCultureIgnoreCase) || link.Contains("rpcs3.zip", StringComparison.CurrentCultureIgnoreCase))
                        {
                            await channel.SendMessageAsync("If you intended to upload a log file please re-upload it directly to discord").ConfigureAwait(false);
                        }
                    }