1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-22 19:41:06 +08:00

Merge pull request #32315 from bdach/copy-db-data-more-granularly

Apply more granular copying from database when retrieving working beatmap
This commit is contained in:
Dean Herbert
2025-03-11 18:20:14 +09:00
committed by GitHub
Unverified
10 changed files with 52 additions and 13 deletions
@@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
{
public abstract partial class CatchPlacementBlueprintTestScene : PlacementBlueprintTestScene
{
protected sealed override Ruleset CreateRuleset() => new CatchRuleset();
protected const double TIME_SNAP = 100;
protected DrawableCatchHitObject LastObject;
@@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
{
public abstract partial class ManiaPlacementBlueprintTestScene : PlacementBlueprintTestScene
{
protected sealed override Ruleset CreateRuleset() => new ManiaRuleset();
private readonly Column column;
[Cached(typeof(IReadOnlyList<Mod>))]
@@ -13,6 +13,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
{
public partial class TestSceneHitCirclePlacementBlueprint : PlacementBlueprintTestScene
{
protected sealed override Ruleset CreateRuleset() => new OsuRuleset();
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHitCircle((HitCircle)hitObject);
protected override HitObjectPlacementBlueprint CreateBlueprint() => new HitCirclePlacementBlueprint();
}
@@ -23,6 +23,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
{
public partial class TestSceneSliderPlacementBlueprint : PlacementBlueprintTestScene
{
protected sealed override Ruleset CreateRuleset() => new OsuRuleset();
[SetUp]
public void Setup() => Schedule(() =>
{
@@ -13,6 +13,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
{
public partial class TestSceneSpinnerPlacementBlueprint : PlacementBlueprintTestScene
{
protected sealed override Ruleset CreateRuleset() => new OsuRuleset();
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSpinner((Spinner)hitObject);
protected override HitObjectPlacementBlueprint CreateBlueprint() => new SpinnerPlacementBlueprint();
@@ -1,15 +1,28 @@
// 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.Linq;
using osu.Framework.Localisation;
using osu.Game.Online.API;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Screens.Select;
namespace osu.Game.Beatmaps
{
public static class BeatmapInfoExtensions
{
/// <summary>
/// Given an <see cref="IBeatmap"/>, update length, BPM and object counts.
/// </summary>
public static void UpdateStatisticsFromBeatmap(this BeatmapInfo beatmapInfo, IBeatmap beatmap)
{
beatmapInfo.Length = beatmap.CalculatePlayableLength();
beatmapInfo.BPM = 60000 / beatmap.GetMostCommonBeatLength();
beatmapInfo.EndTimeObjectCount = beatmap.HitObjects.Count(h => h is IHasDuration);
beatmapInfo.TotalObjectCount = beatmap.HitObjects.Count;
}
/// <summary>
/// A user-presentable display title representing this beatmap.
/// </summary>
+2 -5
View File
@@ -51,7 +51,7 @@ namespace osu.Game.Beatmaps
if (lookupScope != MetadataLookupScope.None)
metadataLookup.Update(beatmapSet, lookupScope == MetadataLookupScope.OnlineFirst);
foreach (var beatmap in beatmapSet.Beatmaps)
foreach (BeatmapInfo beatmap in beatmapSet.Beatmaps)
{
difficultyCache.Invalidate(beatmap);
@@ -63,10 +63,7 @@ namespace osu.Game.Beatmaps
var calculator = ruleset.CreateDifficultyCalculator(working);
beatmap.StarRating = calculator.Calculate().StarRating;
beatmap.Length = working.Beatmap.CalculatePlayableLength();
beatmap.BPM = 60000 / working.Beatmap.GetMostCommonBeatLength();
beatmap.EndTimeObjectCount = working.Beatmap.HitObjects.Count(h => h is IHasDuration);
beatmap.TotalObjectCount = working.Beatmap.HitObjects.Count;
beatmap.UpdateStatisticsFromBeatmap(working.Beatmap);
}
// And invalidate again afterwards as re-fetching the most up-to-date database metadata will be required.
+12 -5
View File
@@ -235,11 +235,18 @@ namespace osu.Game.Beatmaps
// Todo: Handle cancellation during beatmap parsing
var b = GetBeatmap() ?? new Beatmap();
// The original beatmap version needs to be preserved as the database doesn't contain it
BeatmapInfo.BeatmapVersion = b.BeatmapInfo.BeatmapVersion;
// Use the database-backed info for more up-to-date values (beatmap id, ranked status, etc)
b.BeatmapInfo = BeatmapInfo;
// Copy across values of key properties for which the database-backed model has data that the decoded beatmap isn't going to.
b.BeatmapInfo.ID = BeatmapInfo.ID;
b.BeatmapInfo.UserSettings = BeatmapInfo.UserSettings;
b.BeatmapInfo.BeatmapSet = BeatmapInfo.BeatmapSet;
b.BeatmapInfo.Status = BeatmapInfo.Status;
b.BeatmapInfo.OnlineID = BeatmapInfo.OnlineID;
b.BeatmapInfo.OnlineMD5Hash = BeatmapInfo.OnlineMD5Hash;
b.BeatmapInfo.LastLocalUpdate = BeatmapInfo.LastLocalUpdate;
b.BeatmapInfo.LastOnlineUpdate = BeatmapInfo.LastOnlineUpdate;
b.BeatmapInfo.LastPlayed = BeatmapInfo.LastPlayed;
b.BeatmapInfo.EditorTimestamp = BeatmapInfo.EditorTimestamp;
b.BeatmapInfo.StarRating = BeatmapInfo.StarRating; // this could be recomputed in the decoding process but it's a bit annoying to do.
return b;
}, loadCancellationSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+13 -2
View File
@@ -152,14 +152,25 @@ namespace osu.Game.Beatmaps
return null;
}
if (stream.ComputeMD5Hash() != BeatmapInfo.MD5Hash)
string streamMD5 = stream.ComputeMD5Hash();
string streamSHA2 = stream.ComputeSHA2Hash();
if (streamMD5 != BeatmapInfo.MD5Hash)
{
Logger.Log($"Beatmap failed to load (file {BeatmapInfo.Path} does not have the expected hash).", level: LogLevel.Error);
return null;
}
using (var reader = new LineBufferedReader(stream))
return Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
{
var beatmap = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
beatmap.BeatmapInfo.MD5Hash = streamMD5;
beatmap.BeatmapInfo.Hash = streamSHA2;
beatmap.BeatmapInfo.UpdateStatisticsFromBeatmap(beatmap);
return beatmap;
}
}
catch (Exception e)
{
@@ -51,7 +51,9 @@ namespace osu.Game.Tests.Visual
protected virtual IBeatmap GetPlayableBeatmap()
{
var playable = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset);
var rulesetInfo = CreateRuleset()!.RulesetInfo;
var playable = Beatmap.Value.GetPlayableBeatmap(rulesetInfo);
playable.BeatmapInfo.Ruleset = rulesetInfo;
playable.Difficulty.CircleSize = 2;
return playable;
}