mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 11:37:28 +08:00
Merge pull request #19678 from peppy/fix-file-comparisons-many-places
Fix audio track not correctly advancing when changing between certain beatmaps
This commit is contained in:
commit
f9c6dc314b
@ -36,6 +36,23 @@ namespace osu.Game.Tests.NonVisual
|
||||
Assert.IsTrue(beatmapSetA.Beatmaps.Single().AudioEquals(beatmapSetB.Beatmaps.Single()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAudioEqualityCaseSensitivity()
|
||||
{
|
||||
var beatmapSetA = TestResources.CreateTestBeatmapSetInfo(1);
|
||||
var beatmapSetB = TestResources.CreateTestBeatmapSetInfo(1);
|
||||
|
||||
// empty by default so let's set it..
|
||||
beatmapSetA.Beatmaps.First().Metadata.AudioFile = "audio.mp3";
|
||||
beatmapSetB.Beatmaps.First().Metadata.AudioFile = "audio.mp3";
|
||||
|
||||
addAudioFile(beatmapSetA, "abc", "AuDiO.mP3");
|
||||
addAudioFile(beatmapSetB, "abc", "audio.mp3");
|
||||
|
||||
Assert.AreNotEqual(beatmapSetA, beatmapSetB);
|
||||
Assert.IsTrue(beatmapSetA.Beatmaps.Single().AudioEquals(beatmapSetB.Beatmaps.Single()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAudioEqualitySameHash()
|
||||
{
|
||||
|
@ -199,8 +199,8 @@ namespace osu.Game.Beatmaps
|
||||
Debug.Assert(x.BeatmapSet != null);
|
||||
Debug.Assert(y.BeatmapSet != null);
|
||||
|
||||
string? fileHashX = x.BeatmapSet.Files.FirstOrDefault(f => f.Filename == getFilename(x.Metadata))?.File.Hash;
|
||||
string? fileHashY = y.BeatmapSet.Files.FirstOrDefault(f => f.Filename == getFilename(y.Metadata))?.File.Hash;
|
||||
string? fileHashX = x.BeatmapSet.GetFile(getFilename(x.Metadata))?.File.Hash;
|
||||
string? fileHashY = y.BeatmapSet.GetFile(getFilename(y.Metadata))?.File.Hash;
|
||||
|
||||
return fileHashX == fileHashY;
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Localisation;
|
||||
|
||||
|
@ -300,7 +300,7 @@ namespace osu.Game.Beatmaps
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
// AddFile generally handles updating/replacing files, but this is a case where the filename may have also changed so let's delete for simplicity.
|
||||
var existingFileInfo = setInfo.Files.SingleOrDefault(f => string.Equals(f.Filename, beatmapInfo.Path, StringComparison.OrdinalIgnoreCase));
|
||||
var existingFileInfo = beatmapInfo.Path != null ? setInfo.GetFile(beatmapInfo.Path) : null;
|
||||
string targetFilename = createBeatmapFilenameFromMetadata(beatmapInfo);
|
||||
|
||||
// ensure that two difficulties from the set don't point at the same beatmap file.
|
||||
|
@ -84,13 +84,6 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the storage path for the file in this beatmapset with the given filename, if any exists, otherwise null.
|
||||
/// The path returned is relative to the user file storage.
|
||||
/// </summary>
|
||||
/// <param name="filename">The name of the file to get the storage path of.</param>
|
||||
public string? GetPathForFile(string filename) => Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath();
|
||||
|
||||
public bool Equals(BeatmapSetInfo? other)
|
||||
{
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
33
osu.Game/Beatmaps/BeatmapSetInfoExtensions.cs
Normal file
33
osu.Game/Beatmaps/BeatmapSetInfoExtensions.cs
Normal file
@ -0,0 +1,33 @@
|
||||
// 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.Linq;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Models;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
public static class BeatmapSetInfoExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the storage path for the file in this beatmapset with the given filename, if any exists, otherwise null.
|
||||
/// The path returned is relative to the user file storage.
|
||||
/// The lookup is case insensitive.
|
||||
/// </summary>
|
||||
/// <param name="model">The model to operate on.</param>
|
||||
/// <param name="filename">The name of the file to get the storage path of.</param>
|
||||
public static string? GetPathForFile(this IHasRealmFiles model, string filename) => model.GetFile(filename)?.File.GetStoragePath();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the file usage for the file in this beatmapset with the given filename, if any exists, otherwise null.
|
||||
/// The path returned is relative to the user file storage.
|
||||
/// The lookup is case insensitive.
|
||||
/// </summary>
|
||||
/// <param name="model">The model to operate on.</param>
|
||||
/// <param name="filename">The name of the file to get the storage path of.</param>
|
||||
public static RealmNamedFileUsage? GetFile(this IHasRealmFiles model, string filename) =>
|
||||
model.Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Models;
|
||||
|
||||
namespace osu.Game.Database
|
||||
@ -11,8 +12,16 @@ namespace osu.Game.Database
|
||||
/// </summary>
|
||||
public interface IHasRealmFiles
|
||||
{
|
||||
/// <summary>
|
||||
/// Available files in this model, with locally filenames.
|
||||
/// When performing lookups, consider using <see cref="BeatmapSetInfoExtensions.GetFile"/> or <see cref="BeatmapSetInfoExtensions.GetPathForFile"/> to do case-insensitive lookups.
|
||||
/// </summary>
|
||||
IList<RealmNamedFileUsage> Files { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A combined hash representing the model, based on the files it contains.
|
||||
/// Implementation specific.
|
||||
/// </summary>
|
||||
string Hash { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Models;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
@ -79,7 +80,7 @@ namespace osu.Game.Database
|
||||
/// </summary>
|
||||
public void AddFile(TModel item, Stream contents, string filename, Realm realm)
|
||||
{
|
||||
var existing = item.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase));
|
||||
var existing = item.GetFile(filename);
|
||||
|
||||
if (existing != null)
|
||||
{
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.IO.FileAbstraction;
|
||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||
using osu.Game.Storyboards;
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit.Checks
|
||||
|
@ -4,7 +4,6 @@
|
||||
#nullable disable
|
||||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
@ -78,7 +77,7 @@ namespace osu.Game.Screens.Edit.Setup
|
||||
|
||||
// remove the previous background for now.
|
||||
// in the future we probably want to check if this is being used elsewhere (other difficulties?)
|
||||
var oldFile = set.Files.FirstOrDefault(f => f.Filename == working.Value.Metadata.BackgroundFile);
|
||||
var oldFile = set.GetFile(working.Value.Metadata.BackgroundFile);
|
||||
|
||||
using (var stream = source.OpenRead())
|
||||
{
|
||||
@ -107,7 +106,7 @@ namespace osu.Game.Screens.Edit.Setup
|
||||
|
||||
// remove the previous audio track for now.
|
||||
// in the future we probably want to check if this is being used elsewhere (other difficulties?)
|
||||
var oldFile = set.Files.FirstOrDefault(f => f.Filename == working.Value.Metadata.AudioFile);
|
||||
var oldFile = set.GetFile(working.Value.Metadata.AudioFile);
|
||||
|
||||
using (var stream = source.OpenRead())
|
||||
{
|
||||
|
@ -10,6 +10,7 @@ using System.Threading;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO;
|
||||
@ -49,7 +50,7 @@ namespace osu.Game.Skinning
|
||||
|
||||
protected override void Populate(SkinInfo model, ArchiveReader? archive, Realm realm, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var skinInfoFile = model.Files.SingleOrDefault(f => f.Filename == skin_info_file);
|
||||
var skinInfoFile = model.GetFile(skin_info_file);
|
||||
|
||||
if (skinInfoFile != null)
|
||||
{
|
||||
@ -129,7 +130,7 @@ namespace osu.Game.Skinning
|
||||
authorLine,
|
||||
};
|
||||
|
||||
var existingFile = item.Files.SingleOrDefault(f => f.Filename.Equals(@"skin.ini", StringComparison.OrdinalIgnoreCase));
|
||||
var existingFile = item.GetFile(@"skin.ini");
|
||||
|
||||
if (existingFile == null)
|
||||
{
|
||||
@ -163,7 +164,7 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
Logger.Log($"Skin {item}'s skin.ini had issues and has been removed. Please report this and provide the problematic skin.", LoggingTarget.Database, LogLevel.Important);
|
||||
|
||||
var existingIni = item.Files.SingleOrDefault(f => f.Filename.Equals(@"skin.ini", StringComparison.OrdinalIgnoreCase));
|
||||
var existingIni = item.GetFile(@"skin.ini");
|
||||
if (existingIni != null)
|
||||
item.Files.Remove(existingIni);
|
||||
|
||||
@ -248,7 +249,7 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
string filename = @$"{drawableInfo.Key}.json";
|
||||
|
||||
var oldFile = s.Files.FirstOrDefault(f => f.Filename == filename);
|
||||
var oldFile = s.GetFile(filename);
|
||||
|
||||
if (oldFile != null)
|
||||
modelManager.ReplaceFile(oldFile, streamContent, s.Realm);
|
||||
|
@ -1,10 +1,6 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
@ -12,14 +8,14 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Graphics.Video;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Extensions;
|
||||
|
||||
namespace osu.Game.Storyboards.Drawables
|
||||
{
|
||||
public class DrawableStoryboardVideo : CompositeDrawable
|
||||
{
|
||||
public readonly StoryboardVideo Video;
|
||||
private Video video;
|
||||
|
||||
private Video? drawableVideo;
|
||||
|
||||
public override bool RemoveWhenNotAlive => false;
|
||||
|
||||
@ -33,7 +29,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(IBindable<WorkingBeatmap> beatmap, TextureStore textureStore)
|
||||
{
|
||||
string path = beatmap.Value.BeatmapSetInfo?.Files.FirstOrDefault(f => f.Filename.Equals(Video.Path, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath();
|
||||
string? path = beatmap.Value.BeatmapSetInfo?.GetPathForFile(Video.Path);
|
||||
|
||||
if (path == null)
|
||||
return;
|
||||
@ -43,7 +39,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
if (stream == null)
|
||||
return;
|
||||
|
||||
InternalChild = video = new Video(stream, false)
|
||||
InternalChild = drawableVideo = new Video(stream, false)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
FillMode = FillMode.Fill,
|
||||
@ -57,12 +53,12 @@ namespace osu.Game.Storyboards.Drawables
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
if (video == null) return;
|
||||
if (drawableVideo == null) return;
|
||||
|
||||
using (video.BeginAbsoluteSequence(Video.StartTime))
|
||||
using (drawableVideo.BeginAbsoluteSequence(Video.StartTime))
|
||||
{
|
||||
Schedule(() => video.PlaybackPosition = Time.Current - Video.StartTime);
|
||||
video.FadeIn(500);
|
||||
Schedule(() => drawableVideo.PlaybackPosition = Time.Current - Video.StartTime);
|
||||
drawableVideo.FadeIn(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Storyboards.Drawables;
|
||||
|
||||
@ -90,12 +86,12 @@ namespace osu.Game.Storyboards
|
||||
}
|
||||
}
|
||||
|
||||
public DrawableStoryboard CreateDrawable(IReadOnlyList<Mod> mods = null) =>
|
||||
public DrawableStoryboard CreateDrawable(IReadOnlyList<Mod>? mods = null) =>
|
||||
new DrawableStoryboard(this, mods);
|
||||
|
||||
public Texture GetTextureFromPath(string path, TextureStore textureStore)
|
||||
public Texture? GetTextureFromPath(string path, TextureStore textureStore)
|
||||
{
|
||||
string storyboardPath = BeatmapInfo.BeatmapSet?.Files.FirstOrDefault(f => f.Filename.Equals(path, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath();
|
||||
string? storyboardPath = BeatmapInfo.BeatmapSet?.GetPathForFile(path);
|
||||
|
||||
if (!string.IsNullOrEmpty(storyboardPath))
|
||||
return textureStore.Get(storyboardPath);
|
||||
|
Loading…
Reference in New Issue
Block a user