public async Task <bool> CheckIfInTeamMatchAsync(ScanSide side, CancellationToken cancellationToken)
        {
            float      rotation = side == ScanSide.Left ? (float)29.7 : (float)-29.7;
            List <int> ids      = side == ScanSide.Right ? new List <int>()
            {
                11, 12
            } : new List <int> {
                4, 5
            };
            var    sb      = new StringBuilder();
            Finder finder  = new Finder();
            var    fileDic = new Dictionary <int, string>();
            var    logUtil = new LogUtil(@".\logTeam" + string.Join("&", ids) + ".txt");
            int    attempt = 0;

            while (attempt < 5)
            {
                lock (ImageProcessingHelper.GDILock)
                {
                    using (var bitmap = finder.AddNewTemplate(ids[1], true))
                    {
                        logUtil.Log("Capture Complete " + ids[1]);
                        _recognizer.Recognize(bitmap, rotation, sb, 5, true);
                    }
                }
                if (sb.ToString() == _recognizer.PickingText)
                {
                    break;
                }

                attempt++;
                await Task.Delay(500, cancellationToken);
            }
            if (attempt == 5)
            {
                logUtil.Log("Giving up team match capturing " + ids[0]);
                logUtil.Flush();
                return(false);
            }

            sb.Clear();
            lock (ImageProcessingHelper.GDILock)
            {
                using (var bitmap = finder.AddNewTemplate(ids[1], true))
                {
                    logUtil.Log("Second Capture Complete " + ids[1]);
                    _recognizer.Recognize(bitmap, rotation, sb, 5, true);
                }
            }
            logUtil.Log(sb.ToString());
            logUtil.Flush();
            return(sb.ToString() == _recognizer.PickingText);
        }
        private static bool CheckIsOverlap(ScanSide side, LogUtil logUtil, Bitmap bitmap)
        {
            logUtil.Log("Starting detect overlap");
            if (side == ScanSide.Right)
            {
                logUtil.Log("Starting right");
                var chartInfo = FrameFinder.CheckIfInChat(bitmap);
                logUtil.Log("Detect chat mode end");
                if (chartInfo == FrameFinder.ChatInfo.Partial ||
                    chartInfo == FrameFinder.ChatInfo.Full)
                {
                    logUtil.Log("Overlap detected");
                    return(true);
                }

                var hasFrame = FrameFinder.CheckIfInRightFrame(bitmap);
                logUtil.Log("Detect right frame end");
                if (hasFrame)
                {
                    logUtil.Log("Overlap detected");
                    return(true);
                }
            }
            else
            {
                logUtil.Log("Starting left");
                var hasFrame = FrameFinder.CheckIfInLeftFrame(bitmap);
                logUtil.Log("Detect left frame end");
                if (hasFrame)
                {
                    logUtil.Log("Overlap detected");
                    return(true);
                }
            }
            return(false);
        }
        public async Task ScanLabelAsync(List <int> ids, BpViewModel bpViewModel, ScanSide side, CancellationToken cancellationToken)
        {
            try
            {
                OcrAsyncChecker.CheckThread(OcrAsyncChecker.ScanLabelAsyncChecker);

                var finder = new Finder();

                float rotation = side == ScanSide.Left ? (float)29.7 : (float)-29.7;

                var bpVm       = new Dictionary <int, HeroSelectorViewModel>();
                var checkedDic = new Dictionary <int, bool>();
                foreach (var id in ids)
                {
                    var vm = bpViewModel.HeroSelectorViewModels.First(v => v.Id == id);
                    if (vm == null)
                    {
                        return;
                    }

                    bpVm[id] = vm;
                }

                for (var i = 0; i < ids.Count; ++i)
                {
                    checkedDic[i] = false;
                }

                var logUtil = new LogUtil(@".\logPick" + string.Join("&", ids) + ".txt");
                logUtil.Log("PickChecked");

                int  bpScreenFail = 0;
                bool warned       = false;
                bool awaitFlag    = false;
                while (checkedDic.Any(c => !c.Value))
                {
                    var sb        = new StringBuilder();
                    var sbConfirm = new StringBuilder();
                    var i         = checkedDic.FirstOrDefault(l => !l.Value).Key;

                    if (awaitFlag)
                    {
                        await Task.Delay(1000, cancellationToken).ConfigureAwait(false);

                        awaitFlag = false;
                    }

                    if (checkedDic.ContainsKey(i) && checkedDic[i])
                    {
                        continue;
                    }

                    if (bpVm[ids[i]].Selected)
                    {
                        checkedDic[i] = true;
                        continue;
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    if (SuspendScanning)
                    {
                        await Task.Delay(1000).ConfigureAwait(false);

                        continue;
                    }

                    logUtil.Log("Starting detect quit");
                    var processedResult = ProcessedResult.Fail;

                    int realPositionId = ids[i];

                    // first attempt
                    lock (ImageProcessingHelper.GDILock)
                    {
                        using (var bitmap = new ImageUtils().CaptureScreen())
                        {
                            if (!warned && bpViewModel.BpStatus.CurrentStep < 11 &&
                                StageFinder.ProcessStageInfo(bitmap).Step == -1)
                            {
                                bpScreenFail++;
                                if (bpScreenFail == 5)
                                {
                                    warned = true;
                                    bpViewModel.WarnNotInBp();
                                }
                            }
                            else
                            {
                                bpScreenFail = 0;
                            }

                            if (CheckIsOverlap(side, logUtil, bitmap))
                            {
                                awaitFlag = true;
                                continue;
                            }

                            sb.Clear();
                            sbConfirm.Clear();

                            foreach (var scanSideId in IdList[side].Where(id => !ProcessedPositions.ContainsKey(id)))
                            {
                                using (var bitMap = finder.AddNewTemplateBitmap(scanSideId, bitmap))
                                {
                                    logUtil.Log("Capture Complete " + scanSideId);
                                    processedResult = _recognizer.Recognize(bitMap, rotation, sb,
                                                                            _trustableThreashold);
                                    if (processedResult != ProcessedResult.Fail)
                                    {
                                        realPositionId = scanSideId;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    logUtil.Log("Checked " + ids[i] + " (" + sb + ")");

                    if (sb.ToString() == _recognizer.PickingText || string.IsNullOrEmpty(sb.ToString()) || processedResult == ProcessedResult.Fail)
                    {
                        continue;
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    if (SuspendScanning)
                    {
                        logUtil.Log("SuspendScanning delay 1000 " + ids[i]);
                        await Task.Delay(1000).ConfigureAwait(false);

                        continue;
                    }

                    // second attempt
                    FilePath tempscreenshotPath = null;
                    if (processedResult != ProcessedResult.Trustable)
                    {
                        logUtil.Log("Delay 500 " + ids[i]);
                        await Task.Delay(500).ConfigureAwait(false);

                        if (cancellationToken.IsCancellationRequested)
                        {
                            return;
                        }
                        if (SuspendScanning)
                        {
                            await Task.Delay(1000).ConfigureAwait(false);

                            continue;
                        }

                        lock (ImageProcessingHelper.GDILock)
                        {
                            tempscreenshotPath = finder.CaptureScreen();
                            using (var bitMap = finder.AddNewTemplateBitmap(realPositionId, tempscreenshotPath))
                            {
                                logUtil.Log("Capture Complete " + realPositionId);
                                _recognizer.Recognize(bitMap, rotation, sbConfirm,
                                                      _trustableThreashold);
                            }
                        }
                    }

                    logUtil.Log("Second checked " + ids[i] + " (" + sbConfirm.ToString() + ")");

                    if (SuspendScanning)
                    {
                        logUtil.Log("SuspendScanning delay 1000 " + ids[i]);
                        await Task.Delay(1000).ConfigureAwait(false);

                        continue;
                    }

                    if (bpVm[ids[i]].Selected)
                    {
                        logUtil.Log("Vm already selected delay 1000 " + ids[i]);
                        checkedDic[i] = true;
                        continue;
                    }

                    if (processedResult == ProcessedResult.Trustable)
                    {
                        bpScreenFail = 0;
                    }

                    if ((processedResult == ProcessedResult.Trustable || sb.ToString() == sbConfirm.ToString()) &&
                        !cancellationToken.IsCancellationRequested && CheckIfInFocus())
                    {
                        bpScreenFail = 0;
                        tempscreenshotPath?.DeleteIfExists();
                        var text  = sb.ToString();
                        var index = ids[checkedDic.First(l => !l.Value).Key];

                        if (ids.Contains(realPositionId) && !checkedDic[ids.IndexOf(realPositionId)])
                        {
                            index = realPositionId;
                        }

                        Execute.OnUIThread(() => { bpViewModel.ShowHeroSelector(index, text); });
                        ProcessedPositions[realPositionId] = true;
                        checkedDic[ids.IndexOf(index)]     = true;
                        logUtil.Log("Confirmed " + index + " " + text);
                    }
                }
                logUtil.Flush();
            }
            catch (Exception e)
            {
                File.WriteAllText(@".\error" + string.Join("&", ids) + ".txt", e.Message + e.StackTrace + e);
                throw;
            }
            finally
            {
                OcrAsyncChecker.CleanThread(OcrAsyncChecker.ScanLabelAsyncChecker);
            }
        }