1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-17 00:23:24 +08:00

Merge pull request #34584 from Hiviexd/verify/refactor-verifier-context

Refactor `BeatmapVerifierContext`
This commit is contained in:
Dean Herbert
2025-08-14 02:28:57 +09:00
committed by GitHub
Unverified
47 changed files with 219 additions and 235 deletions
@@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var hitObjects = context.Beatmap.HitObjects;
var hitObjects = context.CurrentDifficulty.Playable.HitObjects;
(int expectedStartDelta, int expectedEndDelta) = spinner_delta_threshold[context.InterpretedDifficulty];
for (int i = 0; i < hitObjects.Count - 1; ++i)
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Checks
public override IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var diff = context.Beatmap.Difficulty;
var diff = context.CurrentDifficulty.Playable.Difficulty;
Issue? issue;
if (HasMoreThanOneDecimalPlace("Approach rate", diff.ApproachRate, out issue))
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var diff = context.Beatmap.Difficulty;
var diff = context.CurrentDifficulty.Playable.Difficulty;
if (diff.CircleSize < 4)
{
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Checks
public override IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var diff = context.Beatmap.Difficulty;
var diff = context.CurrentDifficulty.Playable.Difficulty;
Issue? issue;
if (HasMoreThanOneDecimalPlace("Overall difficulty", diff.OverallDifficulty, out issue))
@@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Checks
{
public override IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var hitObjects = context.Beatmap.HitObjects;
var hitObjects = context.CurrentDifficulty.Playable.HitObjects;
for (int i = 0; i < hitObjects.Count - 1; ++i)
{
@@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Checks
if (context.InterpretedDifficulty > DifficultyRating.Easy)
yield break;
var hitObjects = context.Beatmap.HitObjects;
var hitObjects = context.CurrentDifficulty.Playable.HitObjects;
for (int i = 0; i < hitObjects.Count - 1; ++i)
{
@@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
foreach (var hitobject in context.Beatmap.HitObjects)
foreach (var hitobject in context.CurrentDifficulty.Playable.HitObjects)
{
switch (hitobject)
{
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Checks
public override IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var diff = context.Beatmap.Difficulty;
var diff = context.CurrentDifficulty.Playable.Difficulty;
Issue? issue;
if (HasMoreThanOneDecimalPlace("Approach rate", diff.ApproachRate, out issue))
@@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Checks
yield break;
var prevObservedTimeDistances = new List<ObservedTimeDistance>();
var hitObjects = context.Beatmap.HitObjects;
var hitObjects = context.CurrentDifficulty.Playable.HitObjects;
for (int i = 0; i < hitObjects.Count - 1; ++i)
{
@@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Checks
if (context.InterpretedDifficulty > DifficultyRating.Easy)
yield break;
foreach (var hitObject in context.Beatmap.HitObjects)
foreach (var hitObject in context.CurrentDifficulty.Playable.HitObjects)
{
if (hitObject is Slider slider && slider.SpanDuration < span_duration_threshold)
yield return new IssueTemplateTooShort(this).Create(slider);
@@ -19,14 +19,14 @@ namespace osu.Game.Rulesets.Osu.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
double od = context.Beatmap.Difficulty.OverallDifficulty;
double od = context.CurrentDifficulty.Playable.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)
foreach (var hitObject in context.CurrentDifficulty.Playable.HitObjects)
{
if (!(hitObject is Spinner spinner))
continue;
@@ -211,12 +211,10 @@ namespace osu.Game.Rulesets.Taiko.Tests.Editor.Checks
private BeatmapVerifierContext createContextWithMultipleDifficulties(IBeatmap currentBeatmap, IBeatmap[] allDifficulties)
{
return new BeatmapVerifierContext(
currentBeatmap,
new TestWorkingBeatmap(currentBeatmap),
DifficultyRating.ExpertPlus,
beatmapInfo => allDifficulties.FirstOrDefault(b => b.BeatmapInfo.Equals(beatmapInfo))
);
var verifiedCurrentBeatmap = new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(currentBeatmap), currentBeatmap);
var verifiedOtherBeatmaps = allDifficulties.Select(b => new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(b), b)).ToList();
return new BeatmapVerifierContext(verifiedCurrentBeatmap, verifiedOtherBeatmaps, DifficultyRating.ExpertPlus);
}
}
}
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Edit.Checks
public override IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var diff = context.Beatmap.Difficulty;
var diff = context.CurrentDifficulty.Playable.Difficulty;
Issue? issue;
if (HasMoreThanOneDecimalPlace("Overall difficulty", diff.OverallDifficulty, out issue))
@@ -19,26 +19,23 @@ namespace osu.Game.Rulesets.Taiko.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var difficulties = context.BeatmapsetDifficulties;
if (difficulties.Count <= 1)
if (context.AllDifficulties.Count() <= 1)
yield break;
// Inconsistent bar line omission only matters for osu!taiko difficulties, so only check those
var taikoBeatmaps = difficulties.Where(b => b.BeatmapInfo.Ruleset.ShortName == "taiko").ToList();
var taikoBeatmaps = context.AllDifficulties.Where(b => b.Playable.BeatmapInfo.Ruleset.ShortName == "taiko").ToList();
if (taikoBeatmaps.Count <= 1)
yield break;
var referenceBeatmap = context.Beatmap;
var referenceBeatmap = context.CurrentDifficulty.Playable;
var referenceTimingPoints = referenceBeatmap.ControlPointInfo.TimingPoints;
foreach (var beatmap in taikoBeatmaps)
{
if (beatmap == referenceBeatmap)
continue;
var otherTaikoBeatmaps = taikoBeatmaps.Where(b => b.Playable != referenceBeatmap).ToList();
var timingPoints = beatmap.ControlPointInfo.TimingPoints;
foreach (var beatmap in otherTaikoBeatmaps)
{
var timingPoints = beatmap.Playable.ControlPointInfo.TimingPoints;
foreach (var referencePoint in referenceTimingPoints)
{
@@ -50,7 +47,7 @@ namespace osu.Game.Rulesets.Taiko.Edit.Checks
if (referencePoint.OmitFirstBarLine != matchingPoint.OmitFirstBarLine)
{
yield return new IssueTemplateInconsistentOmitFirstBarLine(this).Create(referencePoint.Time, beatmap.BeatmapInfo.DifficultyName);
yield return new IssueTemplateInconsistentOmitFirstBarLine(this).Create(referencePoint.Time, beatmap.Playable.BeatmapInfo.DifficultyName);
}
}
}
@@ -206,12 +206,10 @@ namespace osu.Game.Tests.Editing.Checks
private BeatmapVerifierContext createContextWithMultipleDifficulties(IBeatmap currentBeatmap, IBeatmap[] allDifficulties)
{
return new BeatmapVerifierContext(
currentBeatmap,
new TestWorkingBeatmap(currentBeatmap),
DifficultyRating.ExpertPlus,
beatmapInfo => allDifficulties.FirstOrDefault(b => b.BeatmapInfo.Equals(beatmapInfo))
);
var verifiedCurrentBeatmap = new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(currentBeatmap), currentBeatmap);
var verifiedOtherBeatmaps = allDifficulties.Select(b => new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(b), b)).ToList();
return new BeatmapVerifierContext(verifiedCurrentBeatmap, verifiedOtherBeatmaps, DifficultyRating.ExpertPlus);
}
}
}
@@ -263,12 +263,10 @@ namespace osu.Game.Tests.Editing.Checks
storyboard.GetLayer("Background").Add(new StoryboardSprite("test.png", Anchor.Centre, Vector2.Zero));
}
return new BeatmapVerifierContext(
currentBeatmap,
new TestWorkingBeatmap(currentBeatmap, storyboard),
DifficultyRating.ExpertPlus,
beatmapInfo => allDifficulties.FirstOrDefault(b => b.BeatmapInfo.Equals(beatmapInfo))
);
var verifiedCurrentBeatmap = new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(currentBeatmap, storyboard), currentBeatmap);
var verifiedOtherBeatmaps = allDifficulties.Select(b => new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(b, storyboard), b)).ToList();
return new BeatmapVerifierContext(verifiedCurrentBeatmap, verifiedOtherBeatmaps, DifficultyRating.ExpertPlus);
}
}
}
@@ -245,12 +245,10 @@ namespace osu.Game.Tests.Editing.Checks
private BeatmapVerifierContext createContext(IBeatmap currentBeatmap, IBeatmap[] allDifficulties)
{
return new BeatmapVerifierContext(
currentBeatmap,
new TestWorkingBeatmap(currentBeatmap),
DifficultyRating.ExpertPlus,
beatmapInfo => allDifficulties.FirstOrDefault(b => b.BeatmapInfo.Equals(beatmapInfo))
);
var verifiedCurrentBeatmap = new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(currentBeatmap), currentBeatmap);
var verifiedOtherBeatmaps = allDifficulties.Select(b => new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(b), b)).ToList();
return new BeatmapVerifierContext(verifiedCurrentBeatmap, verifiedOtherBeatmaps, DifficultyRating.ExpertPlus);
}
}
}
@@ -7,7 +7,6 @@ using System.Linq;
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Timing;
using osu.Game.Extensions;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks;
using osu.Game.Rulesets.Objects;
@@ -229,25 +228,13 @@ namespace osu.Game.Tests.Editing.Checks
private BeatmapVerifierContext createContextWithMultipleDifficulties(IBeatmap currentBeatmap, IEnumerable<IBeatmap> allDifficulties)
{
var beatmapSet = new BeatmapSetInfo();
var beatmapInfos = allDifficulties.Select(d => d.BeatmapInfo).ToList();
// Set up the beatmapset with all difficulties
beatmapSet.Beatmaps.AddRange(beatmapInfos);
currentBeatmap.BeatmapInfo.BeatmapSet = beatmapSet;
// Create a resolver that returns the appropriate working beatmap for each difficulty
var difficultyDict = allDifficulties.ToDictionary(d => d.BeatmapInfo, d => new TestWorkingBeatmap(d));
// Use the current beatmap's star rating to determine its difficulty rating
var difficultiesArray = allDifficulties.ToArray();
var currentDifficultyRating = StarDifficulty.GetDifficultyRating(currentBeatmap.BeatmapInfo.StarRating);
return new BeatmapVerifierContext(
currentBeatmap,
new TestWorkingBeatmap(currentBeatmap),
currentDifficultyRating,
beatmapInfo => difficultyDict.TryGetValue(beatmapInfo, out var workingBeatmap) ? workingBeatmap.Beatmap : null
);
var verifiedCurrentBeatmap = new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(currentBeatmap), currentBeatmap);
var verifiedOtherBeatmaps = difficultiesArray.Select(b => new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(b), b)).ToList();
return new BeatmapVerifierContext(verifiedCurrentBeatmap, verifiedOtherBeatmaps, currentDifficultyRating);
}
private class TestCheckLowestDiffDrainTime : CheckLowestDiffDrainTime
@@ -1,7 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System;
using System.Linq;
using NUnit.Framework;
using osu.Game.Beatmaps;
@@ -16,8 +16,6 @@ namespace osu.Game.Tests.Editing.Checks
{
private CheckPreviewTime check = null!;
private IBeatmap beatmap = null!;
[SetUp]
public void Setup()
{
@@ -27,62 +25,69 @@ namespace osu.Game.Tests.Editing.Checks
[Test]
public void TestPreviewTimeNotSet()
{
setNoPreviewTimeBeatmap();
var content = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
// single difficulty with no preview time
var current = createBeatmapWithPreviewPoint(-1, "Current");
var context = createContext(current, Array.Empty<IBeatmap>());
var issues = check.Run(content).ToList();
var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckPreviewTime.IssueTemplateHasNoPreviewTime);
}
[Test]
public void TestPreviewTimeconflict()
public void TestPreviewTimeConflict()
{
setPreviewTimeConflictBeatmap();
var beatmaps = createBeatmapSetWithPreviewPoint(
("Current", 10),
("Test1", 5),
("Test2", 10)
);
var content = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
var context = createContext(beatmaps[0], new[] { beatmaps[1], beatmaps[2] });
var issues = check.Run(content).ToList();
var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckPreviewTime.IssueTemplatePreviewTimeConflict);
Assert.That(issues.Single().Arguments.FirstOrDefault()?.ToString() == "Test1");
}
private void setNoPreviewTimeBeatmap()
private IBeatmap[] createBeatmapSetWithPreviewPoint(params (string name, int preview)[] entries)
{
beatmap = new Beatmap<HitObject>
var beatmapSet = new BeatmapSetInfo();
var beatmaps = new IBeatmap[entries.Length];
for (int i = 0; i < entries.Length; i++)
{
beatmaps[i] = createBeatmapWithPreviewPoint(entries[i].preview, entries[i].name);
beatmaps[i].BeatmapInfo.BeatmapSet = beatmapSet;
}
foreach (var b in beatmaps)
beatmapSet.Beatmaps.Add(b.BeatmapInfo);
return beatmaps;
}
private IBeatmap createBeatmapWithPreviewPoint(int previewTime, string difficultyName)
{
return new Beatmap<HitObject>
{
BeatmapInfo = new BeatmapInfo
{
Metadata = new BeatmapMetadata { PreviewTime = -1 },
DifficultyName = difficultyName,
Metadata = new BeatmapMetadata { PreviewTime = previewTime }
}
};
}
private void setPreviewTimeConflictBeatmap()
private BeatmapVerifierContext createContext(IBeatmap currentBeatmap, IBeatmap[] otherDifficulties)
{
beatmap = new Beatmap<HitObject>
{
BeatmapInfo = new BeatmapInfo
{
Metadata = new BeatmapMetadata { PreviewTime = 10 },
BeatmapSet = new BeatmapSetInfo(new List<BeatmapInfo>
{
new BeatmapInfo
{
DifficultyName = "Test1",
Metadata = new BeatmapMetadata { PreviewTime = 5 },
},
new BeatmapInfo
{
DifficultyName = "Test2",
Metadata = new BeatmapMetadata { PreviewTime = 10 },
},
})
}
};
var verifiedCurrentBeatmap = new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(currentBeatmap), currentBeatmap);
var verifiedOtherBeatmaps = otherDifficulties.Select(b => new BeatmapVerifierContext.VerifiedBeatmap(new TestWorkingBeatmap(b), b)).ToList();
return new BeatmapVerifierContext(verifiedCurrentBeatmap, verifiedOtherBeatmaps, DifficultyRating.ExpertPlus);
}
}
}
@@ -1,8 +1,8 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
namespace osu.Game.Rulesets.Edit
@@ -14,14 +14,16 @@ namespace osu.Game.Rulesets.Edit
public class BeatmapVerifierContext
{
/// <summary>
/// The playable beatmap instance of the current beatmap.
/// Collects the constituent parts of a beatmap being verified.
/// </summary>
public readonly IBeatmap Beatmap;
/// <summary>
/// The working beatmap instance of the current beatmap.
/// </summary>
public readonly IWorkingBeatmap WorkingBeatmap;
/// <param name="Working">
/// Use this to access beatmap resources like its track, storyboard, waveform, or similar.
/// </param>
/// <param name="Playable">
/// The <see cref="IBeatmap"/> in its actual playable state after beatmap conversion.
/// Use this to inspect the actual beatmap contents, like its hitobjects, timing points, breaks, etc.
/// </param>
public record VerifiedBeatmap(IWorkingBeatmap Working, IBeatmap Playable);
/// <summary>
/// The difficulty level which the current beatmap is considered to be.
@@ -29,43 +31,59 @@ namespace osu.Game.Rulesets.Edit
public DifficultyRating InterpretedDifficulty;
/// <summary>
/// All beatmap difficulties in the same beatmapset, including the current beatmap.
/// The current beatmap being checked.
/// </summary>
public readonly IReadOnlyList<IBeatmap> BeatmapsetDifficulties;
public readonly VerifiedBeatmap CurrentDifficulty;
// TODO: Refactor this to have a simple constructor that only stores data and move the beatmap resolution logic to a static factory method.
public BeatmapVerifierContext(IBeatmap beatmap, IWorkingBeatmap workingBeatmap, DifficultyRating difficultyRating = DifficultyRating.ExpertPlus, Func<BeatmapInfo, IBeatmap?>? beatmapResolver = null)
/// <summary>
/// Other beatmaps in the same beatmapset.
/// </summary>
public readonly IReadOnlyList<VerifiedBeatmap> OtherDifficulties;
/// <summary>
/// All beatmaps in the same beatmapset.
/// </summary>
public IEnumerable<VerifiedBeatmap> AllDifficulties => OtherDifficulties.Prepend(CurrentDifficulty);
public BeatmapVerifierContext(VerifiedBeatmap currentDifficulty, IReadOnlyList<VerifiedBeatmap> otherDifficulties, DifficultyRating difficultyRating)
{
Beatmap = beatmap;
WorkingBeatmap = workingBeatmap;
CurrentDifficulty = currentDifficulty;
InterpretedDifficulty = difficultyRating;
OtherDifficulties = otherDifficulties;
}
/// <summary>
/// Backwards-compatible constructor that allows creating a context from a single playable and working beatmap.
/// </summary>
public BeatmapVerifierContext(IBeatmap beatmap, IWorkingBeatmap workingBeatmap, DifficultyRating difficultyRating = DifficultyRating.ExpertPlus)
: this(new VerifiedBeatmap(workingBeatmap, beatmap), [], difficultyRating)
{
}
public static BeatmapVerifierContext Create(IBeatmap beatmap, IWorkingBeatmap workingBeatmap, DifficultyRating difficultyRating = DifficultyRating.ExpertPlus, BeatmapManager? beatmapManager = null)
{
var beatmapSet = beatmap.BeatmapInfo.BeatmapSet;
if (beatmapSet?.Beatmaps == null)
{
BeatmapsetDifficulties = new[] { beatmap };
return;
}
var current = new VerifiedBeatmap(workingBeatmap, beatmap);
var difficulties = new List<IBeatmap>();
if (beatmapSet?.Beatmaps == null || beatmapSet.Beatmaps.Count == 1)
return new BeatmapVerifierContext(current, [], difficultyRating);
foreach (var beatmapInfo in beatmapSet.Beatmaps)
var others = new List<VerifiedBeatmap>();
foreach (var info in beatmapSet.Beatmaps)
{
// Use the current beatmap if it matches this BeatmapInfo
if (beatmapInfo.Equals(beatmap.BeatmapInfo))
{
difficulties.Add(beatmap);
if (info.Equals(beatmap.BeatmapInfo))
continue;
}
// Try to resolve other difficulties using the provided resolver
var resolvedBeatmap = beatmapResolver?.Invoke(beatmapInfo);
if (resolvedBeatmap != null)
difficulties.Add(resolvedBeatmap);
var otherWorking = beatmapManager?.GetWorkingBeatmap(info);
var otherPlayable = otherWorking?.GetPlayableBeatmap(info.Ruleset);
if (otherWorking != null && otherPlayable != null)
others.Add(new VerifiedBeatmap(otherWorking, otherPlayable));
}
BeatmapsetDifficulties = difficulties;
return new BeatmapVerifierContext(current, others, difficultyRating);
}
}
}
@@ -27,10 +27,10 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;
var beatmapSet = context.CurrentDifficulty.Playable.BeatmapInfo.BeatmapSet;
var videoPaths = new List<string>();
foreach (var layer in context.WorkingBeatmap.Storyboard.Layers)
foreach (var layer in context.CurrentDifficulty.Working.Storyboard.Layers)
{
foreach (var element in layer.Elements)
{
@@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Edit.Checks
try
{
// We use TagLib here for platform invariance; BASS cannot detect audio presence on Linux.
using (Stream data = context.WorkingBeatmap.GetStream(storagePath))
using (Stream data = context.CurrentDifficulty.Working.GetStream(storagePath))
using (File tagFile = TagLibUtils.GetTagLibFile(filename, data))
{
if (tagFile.Properties.AudioChannels == 0)
@@ -29,11 +29,11 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
string audioFile = context.Beatmap.Metadata.AudioFile;
string audioFile = context.CurrentDifficulty.Playable.Metadata.AudioFile;
if (string.IsNullOrEmpty(audioFile))
yield break;
var track = context.WorkingBeatmap.Track;
var track = context.CurrentDifficulty.Working.Track;
if (track?.Bitrate == null || track.Bitrate.Value == 0)
yield return new IssueTemplateNoBitrate(this).Create();
@@ -33,11 +33,11 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
string backgroundFile = context.Beatmap.Metadata.BackgroundFile;
string backgroundFile = context.CurrentDifficulty.Playable.Metadata.BackgroundFile;
if (string.IsNullOrEmpty(backgroundFile))
yield break;
var texture = context.WorkingBeatmap.GetBackground();
var texture = context.CurrentDifficulty.Working.GetBackground();
if (texture == null)
yield break;
@@ -49,9 +49,9 @@ namespace osu.Game.Rulesets.Edit.Checks
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);
string? storagePath = context.CurrentDifficulty.Playable.BeatmapInfo.BeatmapSet?.GetPathForFile(backgroundFile);
using (Stream stream = context.WorkingBeatmap.GetStream(storagePath))
using (Stream stream = context.CurrentDifficulty.Working.GetStream(storagePath))
{
double filesizeMb = stream.Length / (1024d * 1024d);
+3 -3
View File
@@ -25,10 +25,10 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var startTimes = context.Beatmap.HitObjects.Select(ho => ho.StartTime).Order().ToList();
var endTimes = context.Beatmap.HitObjects.Select(ho => ho.GetEndTime()).Order().ToList();
var startTimes = context.CurrentDifficulty.Playable.HitObjects.Select(ho => ho.StartTime).Order().ToList();
var endTimes = context.CurrentDifficulty.Playable.HitObjects.Select(ho => ho.GetEndTime()).Order().ToList();
foreach (var breakPeriod in context.Beatmap.Breaks)
foreach (var breakPeriod in context.CurrentDifficulty.Playable.Breaks)
{
if (breakPeriod.Duration < BreakPeriod.MIN_BREAK_DURATION)
yield return new IssueTemplateTooShort(this).Create(breakPeriod.StartTime);
@@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Edit.Checks
public virtual IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var hitObjects = context.Beatmap.HitObjects;
var hitObjects = context.CurrentDifficulty.Playable.HitObjects;
for (int i = 0; i < hitObjects.Count - 1; ++i)
{
@@ -37,14 +37,14 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;
var beatmapSet = context.CurrentDifficulty.Playable.BeatmapInfo.BeatmapSet;
if (beatmapSet == null)
yield break;
foreach (var file in beatmapSet.Files)
{
using (Stream? stream = context.WorkingBeatmap.GetStream(file.File.GetStoragePath()))
using (Stream? stream = context.CurrentDifficulty.Working.GetStream(file.File.GetStoragePath()))
{
if (stream == null)
continue;
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
double drainTime = context.Beatmap.CalculateDrainLength();
double drainTime = context.CurrentDifficulty.Playable.CalculateDrainLength();
if (drainTime < min_drain_threshold)
yield return new IssueTemplateTooShort(this).Create((int)(drainTime / 1000));
@@ -48,16 +48,16 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
if (!context.Beatmap.HitObjects.Any())
if (!context.CurrentDifficulty.Playable.HitObjects.Any())
yield break;
mapHasHitsounds = false;
objectsWithoutHitsounds = 0;
lastHitsoundTime = context.Beatmap.HitObjects.First().StartTime;
lastHitsoundTime = context.CurrentDifficulty.Playable.HitObjects.First().StartTime;
var hitObjectsIncludingNested = new List<HitObject>();
foreach (var hitObject in context.Beatmap.HitObjects)
foreach (var hitObject in context.CurrentDifficulty.Playable.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)
@@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
string? filename = GetFilename(context.Beatmap);
string? filename = GetFilename(context.CurrentDifficulty.Playable);
if (string.IsNullOrEmpty(filename))
{
@@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Edit.Checks
}
// If the file is set, also make sure it still exists.
string? storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(filename);
string? storagePath = context.CurrentDifficulty.Playable.BeatmapInfo.BeatmapSet?.GetPathForFile(filename);
if (storagePath != null)
yield break;
@@ -23,8 +23,8 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;
var audioFile = beatmapSet?.GetFile(context.Beatmap.Metadata.AudioFile);
var beatmapSet = context.CurrentDifficulty.Playable.BeatmapInfo.BeatmapSet;
var audioFile = beatmapSet?.GetFile(context.CurrentDifficulty.Playable.Metadata.AudioFile);
if (beatmapSet == null) yield break;
@@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Edit.Checks
{
if (audioFile != null && ReferenceEquals(file.File, audioFile.File)) continue;
using (Stream data = context.WorkingBeatmap.GetStream(file.File.GetStoragePath()))
using (Stream data = context.CurrentDifficulty.Working.GetStream(file.File.GetStoragePath()))
{
if (data == null)
continue;
@@ -21,12 +21,10 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var difficulties = context.BeatmapsetDifficulties;
if (difficulties.Count <= 1)
if (context.AllDifficulties.Count() <= 1)
yield break;
var referenceBeatmap = context.Beatmap;
var referenceBeatmap = context.CurrentDifficulty.Playable;
var referenceMetadata = referenceBeatmap.Metadata;
// Define metadata fields to check
@@ -40,12 +38,9 @@ namespace osu.Game.Rulesets.Edit.Checks
("creator", m => m.Author.Username)
};
foreach (var beatmap in difficulties)
foreach (var beatmap in context.OtherDifficulties)
{
if (beatmap == referenceBeatmap)
continue;
var currentMetadata = beatmap.Metadata;
var currentMetadata = beatmap.Playable.Metadata;
// Check each metadata field for inconsistencies
foreach ((string fieldName, var fieldSelector) in fieldsToCheck)
@@ -58,7 +53,7 @@ namespace osu.Game.Rulesets.Edit.Checks
yield return new IssueTemplateInconsistentOtherFields(this).Create(
fieldName,
referenceBeatmap.BeatmapInfo.DifficultyName,
beatmap.BeatmapInfo.DifficultyName,
beatmap.Playable.BeatmapInfo.DifficultyName,
referenceField,
currentField
);
@@ -77,7 +72,7 @@ namespace osu.Game.Rulesets.Edit.Checks
{
yield return new IssueTemplateInconsistentTags(this).Create(
referenceBeatmap.BeatmapInfo.DifficultyName,
beatmap.BeatmapInfo.DifficultyName,
beatmap.Playable.BeatmapInfo.DifficultyName,
difference
);
}
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit.Checks.Components;
@@ -20,14 +21,12 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var difficulties = context.BeatmapsetDifficulties;
if (difficulties.Count <= 1)
if (context.AllDifficulties.Count() <= 1)
return [];
var referenceBeatmap = context.Beatmap;
var referenceBeatmap = context.CurrentDifficulty.Playable;
bool hasStoryboard = ResourcesCheckUtils.HasAnyStoryboardElementPresent(context.WorkingBeatmap);
bool hasStoryboard = ResourcesCheckUtils.HasAnyStoryboardElementPresent(context.CurrentDifficulty.Working);
var issues = new List<Issue>();
@@ -50,19 +49,16 @@ namespace osu.Game.Rulesets.Edit.Checks
{
var referenceValue = fieldSelector(referenceBeatmap);
foreach (var beatmap in difficulties)
foreach (var beatmap in context.OtherDifficulties)
{
if (beatmap == referenceBeatmap)
continue;
var currentValue = fieldSelector(beatmap);
var currentValue = fieldSelector(beatmap.Playable);
if (!EqualityComparer<T>.Default.Equals(currentValue, referenceValue))
{
issues.Add(new IssueTemplateInconsistentSetting(this, issueType).Create(
fieldName,
referenceBeatmap.BeatmapInfo.DifficultyName,
beatmap.BeatmapInfo.DifficultyName,
beatmap.Playable.BeatmapInfo.DifficultyName,
referenceValue.ToString() ?? string.Empty,
currentValue.ToString() ?? string.Empty
));
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Rulesets.Edit.Checks.Components;
namespace osu.Game.Rulesets.Edit.Checks
@@ -22,21 +23,16 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var difficulties = context.BeatmapsetDifficulties;
if (difficulties.Count <= 1)
if (context.AllDifficulties.Count() <= 1)
yield break;
// Use the current difficulty as reference
var referenceBeatmap = context.Beatmap;
var referenceBeatmap = context.CurrentDifficulty.Playable;
var referenceTimingPoints = referenceBeatmap.ControlPointInfo.TimingPoints;
foreach (var beatmap in difficulties)
foreach (var beatmap in context.OtherDifficulties)
{
if (beatmap == referenceBeatmap)
continue;
var timingPoints = beatmap.ControlPointInfo.TimingPoints;
var timingPoints = beatmap.Playable.ControlPointInfo.TimingPoints;
// Check each timing point in the reference against this difficulty
foreach (var referencePoint in referenceTimingPoints)
@@ -44,28 +40,30 @@ namespace osu.Game.Rulesets.Edit.Checks
var matchingPoint = TimingCheckUtils.FindMatchingTimingPoint(timingPoints, referencePoint.Time);
var exactMatchingPoint = TimingCheckUtils.FindExactMatchingTimingPoint(timingPoints, referencePoint.Time);
string currentDifficultyName = beatmap.Playable.BeatmapInfo.DifficultyName;
if (matchingPoint == null)
{
yield return new IssueTemplateMissingTimingPoint(this).Create(referencePoint.Time, beatmap.BeatmapInfo.DifficultyName);
yield return new IssueTemplateMissingTimingPoint(this).Create(referencePoint.Time, currentDifficultyName);
}
else
{
// Check for meter signature inconsistency
if (!referencePoint.TimeSignature.Equals(matchingPoint.TimeSignature))
{
yield return new IssueTemplateInconsistentMeter(this).Create(referencePoint.Time, beatmap.BeatmapInfo.DifficultyName);
yield return new IssueTemplateInconsistentMeter(this).Create(referencePoint.Time, currentDifficultyName);
}
// Check for BPM inconsistency
if (Math.Abs(referencePoint.BeatLength - matchingPoint.BeatLength) > TimingCheckUtils.TIME_OFFSET_TOLERANCE_MS)
{
yield return new IssueTemplateInconsistentBPM(this).Create(referencePoint.Time, beatmap.BeatmapInfo.DifficultyName);
yield return new IssueTemplateInconsistentBPM(this).Create(referencePoint.Time, currentDifficultyName);
}
// Check for exact timing match (decimal precision)
if (exactMatchingPoint == null)
{
yield return new IssueTemplateMissingTimingPointMinor(this).Create(referencePoint.Time, beatmap.BeatmapInfo.DifficultyName);
yield return new IssueTemplateMissingTimingPointMinor(this).Create(referencePoint.Time, currentDifficultyName);
}
}
}
@@ -78,11 +76,11 @@ namespace osu.Game.Rulesets.Edit.Checks
if (matchingReferencePoint == null)
{
yield return new IssueTemplateExtraTimingPoint(this).Create(timingPoint.Time, beatmap.BeatmapInfo.DifficultyName);
yield return new IssueTemplateExtraTimingPoint(this).Create(timingPoint.Time, beatmap.Playable.BeatmapInfo.DifficultyName);
}
else if (exactMatchingReferencePoint == null)
{
yield return new IssueTemplateMissingTimingPointMinor(this).Create(timingPoint.Time, beatmap.BeatmapInfo.DifficultyName);
yield return new IssueTemplateMissingTimingPointMinor(this).Create(timingPoint.Time, beatmap.Playable.BeatmapInfo.DifficultyName);
}
}
}
@@ -27,27 +27,28 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
IReadOnlyList<IBeatmap> difficulties = context.BeatmapsetDifficulties
.Where(d => d.BeatmapInfo.Ruleset.Equals(context.Beatmap.BeatmapInfo.Ruleset))
.ToList();
// Filter to only include difficulties with the same ruleset as the current one
var difficulties = context.AllDifficulties
.Where(d => d.Playable.BeatmapInfo.Ruleset.Equals(context.CurrentDifficulty.Playable.BeatmapInfo.Ruleset))
.ToList();
if (difficulties.Count == 0)
yield break;
var lowestDifficulty = difficulties.OrderBy(b => b.BeatmapInfo.StarRating).First();
var lowestDifficulty = difficulties.OrderBy(b => b.Playable.BeatmapInfo.StarRating).First();
// Get difficulty rating for the lowest difficulty
DifficultyRating lowestDifficultyRating = lowestDifficulty == context.Beatmap
DifficultyRating lowestDifficultyRating = lowestDifficulty.Playable == context.CurrentDifficulty.Playable
? context.InterpretedDifficulty
: StarDifficulty.GetDifficultyRating(lowestDifficulty.BeatmapInfo.StarRating);
: StarDifficulty.GetDifficultyRating(lowestDifficulty.Playable.BeatmapInfo.StarRating);
double drainTime = context.Beatmap.CalculateDrainLength();
double playTime = context.Beatmap.CalculatePlayableLength();
double drainTime = context.CurrentDifficulty.Playable.CalculateDrainLength();
double playTime = context.CurrentDifficulty.Playable.CalculatePlayableLength();
bool isHighestDifficulty = difficulties.OrderByDescending(b => b.BeatmapInfo.StarRating).First() == context.Beatmap;
bool isHighestDifficulty = difficulties.OrderByDescending(b => b.Playable.BeatmapInfo.StarRating).First() == context.CurrentDifficulty;
// Use play time unless it's the highest difficulty and has significant breaks
bool canUsePlayTime = !isHighestDifficulty || context.Beatmap.TotalBreakTime < break_time_leniency;
bool canUsePlayTime = !isHighestDifficulty || context.CurrentDifficulty.Playable.TotalBreakTime < break_time_leniency;
double effectiveTime = canUsePlayTime ? playTime : drainTime;
double thresholdReduction = canUsePlayTime ? 0 : break_time_leniency;
@@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var metadata = context.Beatmap.BeatmapInfo.Metadata;
var metadata = context.CurrentDifficulty.Playable.BeatmapInfo.Metadata;
string tags = metadata.Tags.ToLowerInvariant();
@@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
foreach (var hitObject in context.Beatmap.HitObjects)
foreach (var hitObject in context.CurrentDifficulty.Playable.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.
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit.Checks.Components;
namespace osu.Game.Rulesets.Edit.Checks
@@ -19,19 +18,15 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var diffList = context.Beatmap.BeatmapInfo.BeatmapSet?.Beatmaps ?? new List<BeatmapInfo>();
int previewTime = context.Beatmap.BeatmapInfo.Metadata.PreviewTime;
int previewTime = context.CurrentDifficulty.Playable.BeatmapInfo.Metadata.PreviewTime;
if (previewTime == -1)
yield return new IssueTemplateHasNoPreviewTime(this).Create();
foreach (var diff in diffList)
foreach (var beatmap in context.OtherDifficulties)
{
if (diff.Equals(context.Beatmap.BeatmapInfo))
continue;
if (diff.Metadata.PreviewTime != previewTime)
yield return new IssueTemplatePreviewTimeConflict(this).Create(diff.DifficultyName, previewTime, diff.Metadata.PreviewTime);
if (beatmap.Playable.BeatmapInfo.Metadata.PreviewTime != previewTime)
yield return new IssueTemplatePreviewTimeConflict(this).Create(beatmap.Playable.BeatmapInfo.DifficultyName, previewTime, beatmap.Playable.BeatmapInfo.Metadata.PreviewTime);
}
}
@@ -27,13 +27,13 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;
var audioFile = beatmapSet?.GetFile(context.Beatmap.Metadata.AudioFile);
var beatmapSet = context.CurrentDifficulty.Playable.BeatmapInfo.BeatmapSet;
var audioFile = beatmapSet?.GetFile(context.CurrentDifficulty.Playable.Metadata.AudioFile);
if (beatmapSet == null) yield break;
if (audioFile == null) yield break;
var audioFormat = AudioCheckUtils.GetAudioFormatFromFile(context, context.Beatmap.Metadata.AudioFile);
var audioFormat = AudioCheckUtils.GetAudioFormatFromFile(context, context.CurrentDifficulty.Playable.Metadata.AudioFile);
// If the format is not supported by BASS
if (audioFormat == 0)
@@ -31,8 +31,8 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
string romanisedTitle = context.Beatmap.Metadata.Title;
string unicodeTitle = context.Beatmap.Metadata.TitleUnicode;
string romanisedTitle = context.CurrentDifficulty.Playable.Metadata.Title;
string unicodeTitle = context.CurrentDifficulty.Playable.Metadata.TitleUnicode;
foreach (var check in markerChecks)
{
@@ -23,13 +23,13 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;
var beatmapSet = context.CurrentDifficulty.Playable.BeatmapInfo.BeatmapSet;
if (beatmapSet != null)
{
foreach (var file in beatmapSet.Files)
{
using (Stream data = context.WorkingBeatmap.GetStream(file.File.GetStoragePath()))
using (Stream data = context.CurrentDifficulty.Working.GetStream(file.File.GetStoragePath()))
{
if (data == null)
continue;
@@ -23,9 +23,9 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var controlPointInfo = context.Beatmap.ControlPointInfo;
var controlPointInfo = context.CurrentDifficulty.Playable.ControlPointInfo;
foreach (var hitobject in context.Beatmap.HitObjects)
foreach (var hitobject in context.CurrentDifficulty.Playable.HitObjects)
{
double startUnsnap = hitobject.StartTime - controlPointInfo.GetClosestSnappedTime(hitobject.StartTime);
string startPostfix = hitobject is IHasDuration ? "start" : "";
@@ -21,8 +21,8 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
double mappedLength = context.Beatmap.HitObjects.Any() ? context.Beatmap.GetLastObjectTime() : 0;
double trackLength = context.WorkingBeatmap.Track.Length;
double mappedLength = context.CurrentDifficulty.Playable.HitObjects.Any() ? context.CurrentDifficulty.Playable.GetLastObjectTime() : 0;
double trackLength = context.CurrentDifficulty.Working.Track.Length;
double mappedPercentage = Math.Round(mappedLength / trackLength * 100);
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Edit.Checks
{
double percentageLeft = Math.Abs(mappedPercentage - 100);
bool storyboardIsPresent = ResourcesCheckUtils.HasAnyStoryboardElementPresent(context.WorkingBeatmap);
bool storyboardIsPresent = ResourcesCheckUtils.HasAnyStoryboardElementPresent(context.CurrentDifficulty.Working);
if (storyboardIsPresent)
{
@@ -30,8 +30,8 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;
var videoPaths = getVideoPaths(context.WorkingBeatmap.Storyboard);
var beatmapSet = context.CurrentDifficulty.Playable.BeatmapInfo.BeatmapSet;
var videoPaths = getVideoPaths(context.CurrentDifficulty.Working.Storyboard);
foreach (string filename in videoPaths)
{
@@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Edit.Checks
try
{
using (Stream data = context.WorkingBeatmap.GetStream(storagePath))
using (Stream data = context.CurrentDifficulty.Working.GetStream(storagePath))
using (File tagFile = TagLibUtils.GetTagLibFile(filename, data))
{
int height = tagFile.Properties.VideoHeight;
@@ -19,13 +19,13 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;
var beatmapSet = context.CurrentDifficulty.Playable.BeatmapInfo.BeatmapSet;
if (beatmapSet != null)
{
foreach (var file in beatmapSet.Files)
{
using (Stream data = context.WorkingBeatmap.GetStream(file.File.GetStoragePath()))
using (Stream data = context.CurrentDifficulty.Working.GetStream(file.File.GetStoragePath()))
{
if (data?.Length == 0)
yield return new IssueTemplateZeroBytes(this).Create(file.Filename);
@@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Edit.Checks
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{
foreach (var hitObject in context.Beatmap.HitObjects)
foreach (var hitObject in context.CurrentDifficulty.Playable.HitObjects)
{
if (!(hitObject is IHasDuration hasDuration))
continue;
@@ -46,13 +46,13 @@ namespace osu.Game.Rulesets.Edit.Checks.Components
/// <returns>The ChannelType of the audio file, or <see cref="ChannelType.Unknown"/> if detection fails.</returns>
public static ChannelType GetAudioFormatFromFile(BeatmapVerifierContext context, string filename)
{
var beatmapSet = context.Beatmap.BeatmapInfo.BeatmapSet;
var beatmapSet = context.CurrentDifficulty.Playable.BeatmapInfo.BeatmapSet;
var audioFile = beatmapSet?.GetFile(filename);
if (beatmapSet == null || audioFile == null)
return ChannelType.Unknown;
using (Stream data = context.WorkingBeatmap.GetStream(audioFile.File.GetStoragePath()))
using (Stream data = context.CurrentDifficulty.Working.GetStream(audioFile.File.GetStoragePath()))
return GetAudioFormat(data);
}
}
+2 -2
View File
@@ -46,11 +46,11 @@ namespace osu.Game.Screens.Edit.Verify
generalVerifier = new BeatmapVerifier();
rulesetVerifier = beatmap.BeatmapInfo.Ruleset.CreateInstance().CreateBeatmapVerifier();
context = new BeatmapVerifierContext(
context = BeatmapVerifierContext.Create(
beatmap,
workingBeatmap.Value,
verify.InterpretedDifficulty.Value,
beatmapInfo => beatmapManager.GetWorkingBeatmap(beatmapInfo).GetPlayableBeatmap(beatmapInfo.Ruleset)
beatmapManager
);
verify.InterpretedDifficulty.BindValueChanged(difficulty => context.InterpretedDifficulty = difficulty.NewValue);