Exemplo n.º 1
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            double od = context.Beatmap.Difficulty.OverallDifficulty;

            // These are meant to reflect the duration necessary for auto to score at least 1000 points on the spinner.
            // It's difficult to eliminate warnings here, as auto achieving 1000 points depends on the approach angle on some spinners.
            double warningThreshold = 500 + (od < 5 ? (5 - od) * -21.8 : (od - 5) * 20); // Anything above this is always ok.
            double problemThreshold = 450 + (od < 5 ? (5 - od) * -17 : (od - 5) * 17);   // Anything below this is never ok.

            foreach (var hitObject in context.Beatmap.HitObjects)
            {
                if (!(hitObject is Spinner spinner))
                {
                    continue;
                }

                if (spinner.Duration < problemThreshold)
                {
                    yield return(new IssueTemplateTooShort(this).Create(spinner));
                }
                else if (spinner.Duration < warningThreshold)
                {
                    yield return(new IssueTemplateVeryShort(this).Create(spinner));
                }
            }
        }
Exemplo n.º 2
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            foreach (var hitobject in context.Beatmap.HitObjects)
            {
                switch (hitobject)
                {
                case Slider slider:
                {
                    foreach (var issue in sliderIssues(slider))
                    {
                        yield return(issue);
                    }

                    break;
                }

                case HitCircle circle:
                {
                    if (isOffscreen(circle.StackedPosition, circle.Radius))
                    {
                        yield return(new IssueTemplateOffscreenCircle(this).Create(circle));
                    }

                    break;
                }
                }
            }
        }
Exemplo n.º 3
0
        public void TestCirclesQuicklyChanging()
        {
            const float multiplier = 1.6f;

            var beatmap = new Beatmap <HitObject>
            {
                HitObjects = new List <HitObject>
                {
                    new HitCircle {
                        StartTime = 0, Position = new Vector2(0)
                    },
                    new HitCircle {
                        StartTime = 500, Position = new Vector2(50, 0)
                    },
                    new HitCircle {
                        StartTime = 1000, Position = new Vector2(50 + 50 * multiplier, 0)
                    },                                                                                   // Warning
                    new HitCircle {
                        StartTime = 1500, Position = new Vector2(50 + 50 * multiplier + 50 * multiplier * multiplier, 0)
                    }                                                                                                                  // Problem
                }
            };

            var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap), DifficultyRating.Easy);
            var issues  = check.Run(context).ToList();

            Assert.That(issues, Has.Count.EqualTo(2));
            Assert.That(issues.First().Template is CheckTimeDistanceEquality.IssueTemplateIrregularSpacingWarning);
            Assert.That(issues.Last().Template is CheckTimeDistanceEquality.IssueTemplateIrregularSpacingProblem);
        }
Exemplo n.º 4
0
        private void assertProblem(IBeatmap beatmap, int count = 1)
        {
            var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap), DifficultyRating.Easy);
            var issues  = check.Run(context).ToList();

            Assert.That(issues, Has.Count.EqualTo(count));
            Assert.That(issues.All(issue => issue.Template is CheckTimeDistanceEquality.IssueTemplateIrregularSpacingProblem));
        }
Exemplo n.º 5
0
        private void assertShouldNotOverlap(IBeatmap beatmap, int count = 1)
        {
            var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap), DifficultyRating.Easy);
            var issues  = check.Run(context).ToList();

            Assert.That(issues, Has.Count.EqualTo(count));
            Assert.That(issues.All(issue => issue.Template is CheckLowDiffOverlaps.IssueTemplateShouldNotOverlap));
        }
Exemplo n.º 6
0
        private void assertTooShortSpinnerEnd(IBeatmap beatmap, DifficultyRating difficultyRating)
        {
            var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap), difficultyRating);
            var issues  = check.Run(context).ToList();

            Assert.That(issues, Has.Count.EqualTo(1));
            Assert.That(issues.All(issue => issue.Template is CheckBananaShowerGap.IssueTemplateBananaShowerEndGap));
        }
Exemplo n.º 7
0
        private void assertOffscreenSlider(IBeatmap beatmap)
        {
            var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
            var issues  = check.Run(context).ToList();

            Assert.That(issues, Has.Count.EqualTo(1));
            Assert.That(issues.Single().Template is CheckOffscreenObjects.IssueTemplateOffscreenSlider);
        }
Exemplo n.º 8
0
        public void TestBackgroundSetAndNotInFiles()
        {
            beatmap.BeatmapInfo.BeatmapSet?.Files.Clear();

            var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
            var issues  = check.Run(context).ToList();

            Assert.That(issues, Has.Count.EqualTo(1));
            Assert.That(issues.Single().Template is CheckFilePresence.IssueTemplateDoesNotExist);
        }
Exemplo n.º 9
0
        public void TestBackgroundNotSet()
        {
            beatmap.Metadata.BackgroundFile = string.Empty;

            var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
            var issues  = check.Run(context).ToList();

            Assert.That(issues, Has.Count.EqualTo(1));
            Assert.That(issues.Single().Template is CheckFilePresence.IssueTemplateNoneSet);
        }
Exemplo n.º 10
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            // TODO: This should also apply to *lowest difficulty* Normals - they are skipped for now.
            if (context.InterpretedDifficulty > DifficultyRating.Easy)
            {
                yield break;
            }

            var hitObjects = context.Beatmap.HitObjects;

            for (int i = 0; i < hitObjects.Count - 1; ++i)
            {
                if (!(hitObjects[i] is OsuHitObject hitObject) || hitObject is Spinner)
                {
                    continue;
                }

                if (!(hitObjects[i + 1] is OsuHitObject nextHitObject) || nextHitObject is Spinner)
                {
                    continue;
                }

                double deltaTime = nextHitObject.StartTime - hitObject.GetEndTime();
                if (deltaTime >= hitObject.TimeFadeIn + hitObject.TimePreempt)
                {
                    // The objects are not visible at the same time (without mods), hence skipping.
                    continue;
                }

                float  distanceSq = (hitObject.StackedEndPosition - nextHitObject.StackedPosition).LengthSquared;
                double diameter   = (hitObject.Radius - overlap_leniency) * 2;
                double diameterSq = diameter * diameter;

                bool areOverlapping = distanceSq < diameterSq;

                // Slider ends do not need to be overlapped because of slider leniency.
                if (!areOverlapping && !(hitObject is Slider))
                {
                    if (deltaTime < should_overlap_threshold)
                    {
                        yield return(new IssueTemplateShouldOverlap(this).Create(deltaTime, hitObject, nextHitObject));
                    }
                    else if (deltaTime < should_probably_overlap_threshold)
                    {
                        yield return(new IssueTemplateShouldProbablyOverlap(this).Create(deltaTime, hitObject, nextHitObject));
                    }
                }

                if (areOverlapping && deltaTime > should_not_overlap_threshold)
                {
                    yield return(new IssueTemplateShouldNotOverlap(this).Create(deltaTime, hitObject, nextHitObject));
                }
            }
        }
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            var lyrics = context.Beatmap.HitObjects.OfType <Lyric>();

            foreach (var note in context.Beatmap.HitObjects.OfType <Note>())
            {
                if (note.ParentLyric == null || !lyrics.Contains(note.ParentLyric))
                {
                    yield return(new IssueTemplateInvalidParentLyric(this).Create(note));
                }
            }
        }
        private IEnumerable <Issue> run(HitObject lyric)
        {
            var beatmap = new Beatmap
            {
                HitObjects = new List <HitObject>
                {
                    lyric
                }
            };
            var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));

            return(check.Run(context));
        }
Exemplo n.º 13
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            if (context.InterpretedDifficulty > DifficultyRating.Easy)
            {
                yield break;
            }

            foreach (var hitObject in context.Beatmap.HitObjects)
            {
                if (hitObject is Slider slider && slider.SpanDuration < span_duration_threshold)
                {
                    yield return(new IssueTemplateTooShort(this).Create(slider));
                }
            }
        }
Exemplo n.º 14
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            foreach (var hitObject in context.Beatmap.HitObjects)
            {
                if (!(hitObject is IHasDuration hasDuration))
                {
                    continue;
                }

                if (hasDuration.Duration < leniency)
                {
                    yield return(new IssueTemplateZeroLength(this).Create(hitObject, hasDuration.Duration));
                }
            }
        }
Exemplo n.º 15
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;

            foreach (var file in beatmapSet.Files)
            {
                using (Stream data = context.WorkingBeatmap.GetStream(file.FileInfo.GetStoragePath()))
                {
                    if (data?.Length == 0)
                    {
                        yield return(new IssueTemplateZeroBytes(this).Create(file.Filename));
                    }
                }
            }
        }
Exemplo n.º 16
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            foreach (var lyric in context.Beatmap.HitObjects.OfType <Lyric>())
            {
                var invalidRubyTags = checkInvalidRubyTags(lyric);
                if (invalidRubyTags.Any())
                {
                    yield return(new IssueTemplateInvalidRuby(this).Create(lyric, invalidRubyTags));
                }

                var invalidRomajiTags = checkInvalidRomajiTags(lyric);
                if (invalidRomajiTags.Any())
                {
                    yield return(new IssueTemplateInvalidRomaji(this).Create(lyric, invalidRomajiTags));
                }
            }
        }
Exemplo n.º 17
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            if (!context.Beatmap.HitObjects.Any())
            {
                yield break;
            }

            mapHasHitsounds         = false;
            objectsWithoutHitsounds = 0;
            lastHitsoundTime        = context.Beatmap.HitObjects.First().StartTime;

            var hitObjectsIncludingNested = new List <HitObject>();

            foreach (var hitObject in context.Beatmap.HitObjects)
            {
                // Samples play on the end of objects. Some objects have nested objects to accomplish playing them elsewhere (e.g. slider head/repeat).
                foreach (var nestedHitObject in hitObject.NestedHitObjects)
                {
                    hitObjectsIncludingNested.Add(nestedHitObject);
                }

                hitObjectsIncludingNested.Add(hitObject);
            }

            var hitObjectsByEndTime = hitObjectsIncludingNested.OrderBy(o => o.GetEndTime()).ToList();
            int hitObjectCount      = hitObjectsByEndTime.Count;

            for (int i = 0; i < hitObjectCount; ++i)
            {
                var hitObject = hitObjectsByEndTime[i];

                // This is used to perform an update at the end so that the period after the last hitsounded object can be an issue.
                bool isLastObject = i == hitObjectCount - 1;

                foreach (var issue in applyHitsoundUpdate(hitObject, isLastObject))
                {
                    yield return(issue);
                }
            }

            if (!mapHasHitsounds)
            {
                yield return(new IssueTemplateNoHitsounds(this).Create());
            }
        }
Exemplo n.º 18
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            var languages = availableTranslateInBeatmap(context.Beatmap);

            if (languages == null || languages.Length == 0)
            {
                yield break;
            }

            var lyric = context.Beatmap.HitObjects.OfType <Lyric>().ToList();

            if (lyric.Count == 0)
            {
                yield break;
            }

            foreach (var language in languages)
            {
                var notTranslateLyrics = lyric.Where(x =>
                {
                    if (!x.Translates.ContainsKey(language))
                    {
                        return(true);
                    }

                    if (string.IsNullOrWhiteSpace(x.Translates[language]))
                    {
                        return(true);
                    }

                    return(false);
                });

                if (notTranslateLyrics.Count() == lyric.Count)
                {
                    yield return(new IssueTemplateMissingTranslate(this).Create(language));
                }
                else if (notTranslateLyrics.Any())
                {
                    yield return(new IssueTemplateMissingPartialTranslate(this).Create(language));
                }
            }
        }
Exemplo n.º 19
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            foreach (var lyric in context.Beatmap.HitObjects.OfType <Lyric>())
            {
                var invalidLyricTime = checkInvalidLyricTime(lyric);
                if (invalidLyricTime.Any())
                {
                    yield return(new IssueTemplateInvalidLyricTime(this).Create(lyric, invalidLyricTime));
                }

                var invalidTimeTags     = checkInvalidTimeTags(lyric);
                var missingStartTimeTag = checkMissingStartTimeTag(lyric);
                var missingEndTimeTag   = checkMissingEndTimeTag(lyric);
                if (invalidTimeTags.Any() || missingStartTimeTag || missingEndTimeTag)
                {
                    yield return(new IssueTemplateInvalidTimeTag(this).Create(lyric, invalidTimeTags, missingStartTimeTag, missingEndTimeTag));
                }
            }
        }
Exemplo n.º 20
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            string backgroundFile = context.Beatmap.Metadata?.BackgroundFile;

            if (backgroundFile == null)
            {
                yield break;
            }

            var texture = context.WorkingBeatmap.Background;

            if (texture == null)
            {
                yield break;
            }

            if (texture.Width > max_width || texture.Height > max_height)
            {
                yield return(new IssueTemplateTooHighResolution(this).Create(texture.Width, texture.Height));
            }

            if (texture.Width < min_width || texture.Height < min_height)
            {
                yield return(new IssueTemplateTooLowResolution(this).Create(texture.Width, texture.Height));
            }
            else if (texture.Width < low_width || texture.Height < low_height)
            {
                yield return(new IssueTemplateLowResolution(this).Create(texture.Width, texture.Height));
            }

            string storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(backgroundFile);

            using (Stream stream = context.WorkingBeatmap.GetStream(storagePath))
            {
                double filesizeMb = stream.Length / (1024d * 1024d);

                if (filesizeMb > max_filesize_mb)
                {
                    yield return(new IssueTemplateTooUncompressed(this).Create(filesizeMb));
                }
            }
        }
Exemplo n.º 21
0
        private void load(OverlayColourProvider colours)
        {
            generalVerifier = new BeatmapVerifier();
            rulesetVerifier = beatmap.BeatmapInfo.Ruleset.CreateInstance().CreateBeatmapVerifier();

            context = new BeatmapVerifierContext(beatmap, workingBeatmap.Value, verify.InterpretedDifficulty.Value);
            verify.InterpretedDifficulty.BindValueChanged(difficulty => context.InterpretedDifficulty = difficulty.NewValue);

            RelativeSizeAxes = Axes.Both;

            InternalChildren = new Drawable[]
            {
                new Box
                {
                    Colour           = colours.Background3,
                    RelativeSizeAxes = Axes.Both,
                },
                new OsuScrollContainer
                {
                    RelativeSizeAxes = Axes.Both,
                    Child            = table = new IssueTable(),
                },
                new FillFlowContainer
                {
                    AutoSizeAxes = Axes.Both,
                    Anchor       = Anchor.BottomRight,
                    Origin       = Anchor.BottomRight,
                    Margin       = new MarginPadding(20),
                    Children     = new Drawable[]
                    {
                        new RoundedButton
                        {
                            Text   = "Refresh",
                            Action = refresh,
                            Size   = new Vector2(120, 40),
                            Anchor = Anchor.BottomRight,
                            Origin = Anchor.BottomRight,
                        },
                    }
                },
            };
        }
Exemplo n.º 22
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;

            if (beatmapSet != null)
            {
                foreach (var file in beatmapSet.Files)
                {
                    using (Stream data = context.WorkingBeatmap.GetStream(file.File.GetStoragePath()))
                    {
                        if (data == null)
                        {
                            continue;
                        }

                        var fileCallbacks = new FileCallbacks(new DataStreamFileProcedures(data));
                        int decodeStream  = Bass.CreateStream(StreamSystem.NoBuffer, BassFlags.Decode | BassFlags.Prescan, fileCallbacks.Callbacks, fileCallbacks.Handle);

                        if (decodeStream == 0)
                        {
                            // If the file is not likely to be properly parsed by Bass, we don't produce Error issues about it.
                            // Image files and audio files devoid of audio data both fail, for example, but neither would be issues in this check.
                            if (hasAudioExtension(file.Filename) && probablyHasAudioData(data))
                            {
                                yield return(new IssueTemplateBadFormat(this).Create(file.Filename));
                            }

                            continue;
                        }

                        long   length = Bass.ChannelGetLength(decodeStream);
                        double ms     = Bass.ChannelBytes2Seconds(decodeStream, length) * 1000;

                        // Extremely short audio files do not play on some soundcards, resulting in nothing being heard in-game for some users.
                        if (ms > 0 && ms < ms_threshold)
                        {
                            yield return(new IssueTemplateTooShort(this).Create(file.Filename, ms));
                        }
                    }
                }
            }
        }
Exemplo n.º 23
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            foreach (var hitObject in context.Beatmap.HitObjects)
            {
                // Worth keeping in mind: The samples of an object always play at its end time.
                // Objects like spinners have no sound at its start because of this, while hold notes have nested objects to accomplish this.
                foreach (var nestedHitObject in hitObject.NestedHitObjects)
                {
                    foreach (var issue in getVolumeIssues(hitObject, nestedHitObject))
                    {
                        yield return(issue);
                    }
                }

                foreach (var issue in getVolumeIssues(hitObject))
                {
                    yield return(issue);
                }
            }
        }
Exemplo n.º 24
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            string filename = GetFilename(context.Beatmap);

            if (string.IsNullOrEmpty(filename))
            {
                yield return(new IssueTemplateNoneSet(this).Create(TypeOfFile));

                yield break;
            }

            // If the file is set, also make sure it still exists.
            string storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(filename);

            if (storagePath != null)
            {
                yield break;
            }

            yield return(new IssueTemplateDoesNotExist(this).Create(TypeOfFile, filename));
        }
Exemplo n.º 25
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            var hitObjects = context.Beatmap.HitObjects;

            for (int i = 0; i < hitObjects.Count - 1; ++i)
            {
                var hitobject = hitObjects[i];

                for (int j = i + 1; j < hitObjects.Count; ++j)
                {
                    var nextHitobject = hitObjects[j];

                    // Accounts for rulesets with hitobjects separated by columns, such as Mania.
                    // In these cases we only care about concurrent objects within the same column.
                    if ((hitobject as IHasColumn)?.Column != (nextHitobject as IHasColumn)?.Column)
                    {
                        continue;
                    }

                    // Two hitobjects cannot be concurrent without also being concurrent with all objects in between.
                    // So if the next object is not concurrent, then we know no future objects will be either.
                    if (!areConcurrent(hitobject, nextHitobject))
                    {
                        break;
                    }

                    if (hitobject.GetType() == nextHitobject.GetType())
                    {
                        yield return(new IssueTemplateConcurrentSame(this).Create(hitobject, nextHitobject));
                    }
                    else
                    {
                        yield return(new IssueTemplateConcurrentDifferent(this).Create(hitobject, nextHitobject));
                    }
                }
            }
        }
Exemplo n.º 26
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            var controlPointInfo = context.Beatmap.ControlPointInfo;

            foreach (var hitobject in context.Beatmap.HitObjects)
            {
                double startUnsnap  = hitobject.StartTime - controlPointInfo.GetClosestSnappedTime(hitobject.StartTime);
                string startPostfix = hitobject is IHasDuration ? "start" : "";
                foreach (var issue in getUnsnapIssues(hitobject, startUnsnap, hitobject.StartTime, startPostfix))
                {
                    yield return(issue);
                }

                if (hitobject is IHasRepeats hasRepeats)
                {
                    for (int repeatIndex = 0; repeatIndex < hasRepeats.RepeatCount; ++repeatIndex)
                    {
                        double spanDuration = hasRepeats.Duration / (hasRepeats.RepeatCount + 1);
                        double repeatTime   = hitobject.StartTime + spanDuration * (repeatIndex + 1);
                        double repeatUnsnap = repeatTime - controlPointInfo.GetClosestSnappedTime(repeatTime);
                        foreach (var issue in getUnsnapIssues(hitobject, repeatUnsnap, repeatTime, "repeat"))
                        {
                            yield return(issue);
                        }
                    }
                }

                if (hitobject is IHasDuration hasDuration)
                {
                    double endUnsnap = hasDuration.EndTime - controlPointInfo.GetClosestSnappedTime(hasDuration.EndTime);
                    foreach (var issue in getUnsnapIssues(hitobject, endUnsnap, hasDuration.EndTime, "end"))
                    {
                        yield return(issue);
                    }
                }
            }
        }
Exemplo n.º 27
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            var audioFile = context.Beatmap.Metadata?.AudioFile;

            if (audioFile == null)
            {
                yield break;
            }

            var track = context.WorkingBeatmap.Track;

            if (track?.Bitrate == null || track.Bitrate.Value == 0)
            {
                yield return(new IssueTemplateNoBitrate(this).Create());
            }
            else if (track.Bitrate.Value > max_bitrate)
            {
                yield return(new IssueTemplateTooHighBitrate(this).Create(track.Bitrate.Value));
            }
            else if (track.Bitrate.Value < min_bitrate)
            {
                yield return(new IssueTemplateTooLowBitrate(this).Create(track.Bitrate.Value));
            }
        }
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            foreach (var lyric in context.Beatmap.HitObjects.OfType <Lyric>())
            {
                if (lyric.Language == null)
                {
                    yield return(new IssueTemplateNotFillLanguage(this).Create(lyric));
                }

                // todo : check lyric layout.

                if (string.IsNullOrWhiteSpace(lyric.Text))
                {
                    yield return(new IssueTemplateNoText(this).Create(lyric));
                }

                if (lyric.Singers == null || lyric.Singers.Length == 0)
                {
                    yield return(new IssueTemplateNoSinger(this).Create(lyric));
                }

                // todo : check is singer in singer list.
            }
        }
Exemplo n.º 29
0
        public IEnumerable <Issue> Run(BeatmapVerifierContext context)
        {
            var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;
            var videoPaths = new List <string>();

            foreach (var layer in context.WorkingBeatmap.Storyboard.Layers)
            {
                foreach (var element in layer.Elements)
                {
                    if (!(element is StoryboardVideo video))
                    {
                        continue;
                    }

                    // Ensures we don't check the same video file multiple times in case of multiple elements using it.
                    if (!videoPaths.Contains(video.Path))
                    {
                        videoPaths.Add(video.Path);
                    }
                }
            }

            foreach (var filename in videoPaths)
            {
                string storagePath = beatmapSet.GetPathForFile(filename);

                if (storagePath == null)
                {
                    // There's an element in the storyboard that requires this resource, so it being missing is worth warning about.
                    yield return(new IssueTemplateMissingFile(this).Create(filename));

                    continue;
                }

                Issue issue;

                try
                {
                    // We use TagLib here for platform invariance; BASS cannot detect audio presence on Linux.
                    using (Stream data = context.WorkingBeatmap.GetStream(storagePath))
                        using (File tagFile = File.Create(new StreamFileAbstraction(filename, data)))
                        {
                            if (tagFile.Properties.AudioChannels == 0)
                            {
                                continue;
                            }
                        }

                    issue = new IssueTemplateHasAudioTrack(this).Create(filename);
                }
                catch (CorruptFileException)
                {
                    issue = new IssueTemplateFileError(this).Create(filename, "Corrupt file");
                }
                catch (UnsupportedFormatException)
                {
                    issue = new IssueTemplateFileError(this).Create(filename, "Unsupported format");
                }

                yield return(issue);
            }
        }
Exemplo n.º 30
0
 public IEnumerable <Issue> Run(BeatmapVerifierContext context) => checks.SelectMany(check => check.Run(context));