Exemplo n.º 1
0
        private async void ToggleSearch(object sender, EventArgs e)
        {
            if (_searchCancelToken != null)
            {
                _searchCancelToken.Cancel();
                _searchCancelToken = null;
                return;
            }

            var levelPattern = LevPatternBox.Text;
            var errorFiles   = new List <string>();

            bool searchForFastestReplays;
            bool searchForAllReplays;
            var  clickedButton = (Button)sender;

            if (clickedButton.Equals(SearchButton))
            {
                searchForAllReplays     = fastestSlowestSelect.SelectedOption == 2;
                searchForFastestReplays = fastestSlowestSelect.SelectedOption == 0;
            }
            else
            {
                searchForAllReplays     = true;
                searchForFastestReplays = false;
            }

            var searchOnlyMissingLev = clickedButton.Equals(ReplaysWithoutLevFileButton);
            var searchOnlyWrongLev   = clickedButton.Equals(ReplaysIncorrectLevButton);

            if (!Utils.RecDirectoryExists())
            {
                Utils.ShowError(Constants.RecDirNotFound);
                return;
            }

            var p1Apples = Range <int> .FromNumericBoxes(TextBox1, TextBox14);

            var p2Apples = Range <int> .FromNumericBoxes(TextBox3, TextBox16);

            var p1Turns = Range <int> .FromNumericBoxes(TextBox2, TextBox23);

            var p2Turns = Range <int> .FromNumericBoxes(TextBox10, TextBox15);

            var p1Gt = Range <int> .FromNumericBoxes(TextBox11, TextBox24);

            var p2Gt = Range <int> .FromNumericBoxes(TextBox12, TextBox13);

            var p1Sv = Range <int> .FromNumericBoxes(TextBox4, TextBox21);

            var p2Sv = Range <int> .FromNumericBoxes(TextBox9, TextBox22);

            var p1Rv = Range <int> .FromNumericBoxes(TextBox6, TextBox19);

            var p2Rv = Range <int> .FromNumericBoxes(TextBox7, TextBox20);

            var p1Lv = Range <int> .FromNumericBoxes(TextBox8, TextBox17);

            var p2Lv = Range <int> .FromNumericBoxes(TextBox5, TextBox18);

            Range <double> time;

            try
            {
                time = Utils.GetTimeRange(TimeMinBox.Text, TimeMaxBox.Text);
            }
            catch (Exception)
            {
                Utils.ShowError("Time bound is in wrong format. Make sure it is 9 characters long.");
                return;
            }

            var size = new Range <int>((int)minFileSizeBox.Value * 1024, (int)maxFileSizeBox.Value * 1024);

            Regex levFilenameMatcher;

            try
            {
                levFilenameMatcher = new Regex(levelPattern, RegexOptions.IgnoreCase);
            }
            catch (Exception)
            {
                levFilenameMatcher = new Regex(string.Empty);
            }

            var searchParams = new ReplaySearchParameters
            {
                InternalRec        = SearchParameters.GetBoolOptionFromTriSelect(intExtSelect),
                AcrossLev          = SearchParameters.GetBoolOptionFromTriSelect(elmaAcrossSelect),
                Date               = new Range <DateTime>(minDateTime.Value, maxDateTime.Value),
                Finished           = SearchParameters.GetBoolOptionFromTriSelect(finishedSelect),
                LevExists          = BoolOption.Dontcare,
                WrongLev           = BoolOption.Dontcare,
                LevFilenameMatcher = levFilenameMatcher,
                MultiPlayer        = SearchParameters.GetBoolOptionFromTriSelect(singleMultiSelect),
                Size               = size,
                Time               = time,
                P1Bounds           =
                    new ReplaySearchParameters.PlayerBounds
                {
                    Apples        = p1Apples,
                    GroundTouches = p1Gt,
                    LeftVolts     = p1Lv,
                    RightVolts    = p1Rv,
                    SuperVolts    = p1Sv,
                    Turns         = p1Turns
                },
                P2Bounds =
                    new ReplaySearchParameters.PlayerBounds
                {
                    Apples        = p2Apples,
                    GroundTouches = p2Gt,
                    LeftVolts     = p2Lv,
                    RightVolts    = p2Rv,
                    SuperVolts    = p2Sv,
                    Turns         = p2Turns
                }
            };

            if (searchOnlyMissingLev)
            {
                searchParams.ResetOptions();
                searchParams.LevExists = BoolOption.False;
            }

            if (searchOnlyWrongLev)
            {
                searchParams.ResetOptions();
                searchParams.WrongLev = BoolOption.True;
            }

            var allFiles = Directory.GetFiles(Global.AppSettings.General.ReplayDirectory, "*.rec",
                                              Global.AppSettings.ReplayManager.RecDirSearchOption);
            var replayFiles = searchOnlyMissingLev || searchOnlyWrongLev
                ? allFiles.ToList()
                : Utils.FilterByRegex(allFiles, SearchPattern).ToList();

            ObjectList.ClearObjects();
            var oldButtonText = clickedButton.Text;

            _searchCancelToken              = new CancellationTokenSource();
            DuplicateButton.Enabled         = false;
            DuplicateFilenameButton.Enabled = false;
            ConfigButton.Enabled            = false;
            clickedButton.Text              = "Stop";
            var foundReplays = new List <Replay>();

            ToolStripProgressBar1.Maximum = replayFiles.Count;

            var recsByLevel     = new Dictionary <string, List <Replay> >();
            var token           = _searchCancelToken.Token;
            var progressHandler = new Progress <(int progress, int levels, int recs, int phase)>(value =>
            {
                var(progressValue, levels, recs, phase) = value;
                ToolStripProgressBar1.Value             = progressValue;
                if (searchForAllReplays)
                {
                    statusLabel.Text = $"Found {recs} replays so far";
                }
                else
                {
                    statusLabel.Text = phase == 1 ? $"Phase 1: {levels} levels" : $"Phase 2: {recs} replays";
                }
            });
            var progress = (IProgress <(int progress, int levels, int recs, int phase)>)progressHandler;
            var iter     = 0;

            try
            {
                await Task.Run(() =>
                {
                    foreach (var replayFile in replayFiles)
                    {
                        iter++;
                        Replay srp;
                        try
                        {
                            srp = new Replay(replayFile);
                        }
                        catch (ArgumentException)
                        {
                            errorFiles.Add(replayFile);
                            continue;
                        }

                        if (searchParams.Matches(srp))
                        {
                            if (!searchForAllReplays)
                            {
                                var key = srp.LevelFilename.ToLower() + srp.IsMulti;
                                recsByLevel.TryGetValue(key, out var recs);
                                if (recs == null)
                                {
                                    recs             = new List <Replay>();
                                    recsByLevel[key] = recs;
                                }

                                recs.Add(srp);
                            }
                            else
                            {
                                foundReplays.Add(srp);
                            }
                        }

                        if (iter % 10 == 0)
                        {
                            progress.Report((iter, recsByLevel.Count, foundReplays.Count, 1));
                        }
                        token.ThrowIfCancellationRequested();
                    }
                }, token);
            }
            catch (OperationCanceledException)
            {
                Finalize();
                return;
            }

            if (!searchForAllReplays)
            {
                ToolStripProgressBar1.Maximum = recsByLevel.Count;
                iter = 0;
                try
                {
                    await Task.Run(() =>
                    {
                        foreach (var rbl in recsByLevel)
                        {
                            iter++;
                            var matchedReplay = rbl.Value[0];
                            foreach (var z in rbl.Value.Where(z => !z.WrongLevelVersion))
                            {
                                if (searchForFastestReplays)
                                {
                                    if (!matchedReplay.Finished && z.Finished)
                                    {
                                        matchedReplay = z;
                                    }
                                    else if (matchedReplay.Finished && z.Finished && z.Time < matchedReplay.Time)
                                    {
                                        matchedReplay = z;
                                    }
                                    else if (!matchedReplay.Finished && !z.Finished &&
                                             z.Player1.Apples > matchedReplay.Player1.Apples)
                                    {
                                        matchedReplay = z;
                                    }
                                }
                                else
                                {
                                    if (matchedReplay.Finished && !z.Finished)
                                    {
                                        matchedReplay = z;
                                    }
                                    else if (matchedReplay.Finished && z.Finished && z.Time > matchedReplay.Time)
                                    {
                                        matchedReplay = z;
                                    }
                                    else if (!matchedReplay.Finished && !z.Finished &&
                                             (z.Player1.Apples < matchedReplay.Player1.Apples ||
                                              matchedReplay.Time > z.Time))
                                    {
                                        matchedReplay = z;
                                    }
                                }
                            }

                            if (searchForFastestReplays || rbl.Value.Count > 1)
                            {
                                foundReplays.Add(matchedReplay);
                            }
                            if (iter % 10 == 0)
                            {
                                progress.Report((iter, recsByLevel.Count, foundReplays.Count, 2));
                            }
                            token.ThrowIfCancellationRequested();
                        }
                    }, token);
                }
                catch (OperationCanceledException)
                {
                }
            }

            Finalize();

            void Finalize()
            {
                ObjectList.SetObjects(foundReplays);
                statusLabel.Text                = "Ready";
                ToolStripProgressBar1.Value     = 0;
                _searchCancelToken              = null;
                DuplicateButton.Enabled         = true;
                DuplicateFilenameButton.Enabled = true;
                ConfigButton.Enabled            = true;
                clickedButton.Text              = oldButtonText;
                DisplaySelectionInfo();
                if (errorFiles.Count > 0)
                {
                    using (var ef = new ErrorForm(errorFiles))
                    {
                        ef.ShowDialog();
                    }
                }
            }
        }