diff --git a/osu.Game/Skinning/DefaultLegacySkin.cs b/osu.Game/Skinning/DefaultLegacySkin.cs index 95e9a19c99..2332e6e160 100644 --- a/osu.Game/Skinning/DefaultLegacySkin.cs +++ b/osu.Game/Skinning/DefaultLegacySkin.cs @@ -25,7 +25,7 @@ namespace osu.Game.Skinning resources, // A default legacy skin may still have a skin.ini if it is modified by the user. // We must specify the stream directly as we are redirecting storage to the osu-resources location for other files. - new LegacySkinResourceStore(skin, resources.Files).GetStream("skin.ini") + new LegacyDatabasedSkinResourceStore(skin, resources.Files).GetStream("skin.ini") ) { Configuration.CustomColours["SliderBall"] = new Color4(2, 170, 255, 255); @@ -42,7 +42,7 @@ namespace osu.Game.Skinning public static SkinInfo Info { get; } = new SkinInfo { - ID = SkinInfo.CLASSIC_SKIN, // this is temporary until database storage is decided upon. + ID = osu.Game.Skinning.SkinInfo.CLASSIC_SKIN, // this is temporary until database storage is decided upon. Name = "osu!classic", Creator = "team osu!", InstantiationInfo = typeof(DefaultLegacySkin).GetInvariantInstantiationInfo() diff --git a/osu.Game/Skinning/DefaultSkin.cs b/osu.Game/Skinning/DefaultSkin.cs index c377f16f8b..8d3a83f589 100644 --- a/osu.Game/Skinning/DefaultSkin.cs +++ b/osu.Game/Skinning/DefaultSkin.cs @@ -26,7 +26,7 @@ namespace osu.Game.Skinning private readonly IStorageResourceProvider resources; public DefaultSkin(IStorageResourceProvider resources) - : this(SkinInfo.Default, resources) + : this(osu.Game.Skinning.SkinInfo.Default, resources) { } diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index 0599334b46..d44d3dce49 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -77,6 +77,6 @@ namespace osu.Game.Skinning } private static SkinInfo createSkinInfo(BeatmapInfo beatmapInfo) => - new SkinInfo { Name = beatmapInfo.ToString(), Creator = beatmapInfo.Metadata?.Author.Username }; + new SkinInfo { Name = beatmapInfo.ToString(), Creator = beatmapInfo.Metadata?.Author.Username ?? string.Empty }; } } diff --git a/osu.Game/Skinning/LegacyDatabasedSkinResourceStore.cs b/osu.Game/Skinning/LegacyDatabasedSkinResourceStore.cs new file mode 100644 index 0000000000..ab820a13ab --- /dev/null +++ b/osu.Game/Skinning/LegacyDatabasedSkinResourceStore.cs @@ -0,0 +1,49 @@ +// Copyright (c) ppy Pty Ltd . 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.Framework.Extensions; +using osu.Framework.IO.Stores; +using osu.Game.Database; +using osu.Game.Extensions; +using Realms; + +namespace osu.Game.Skinning +{ + public class LegacyDatabasedSkinResourceStore : ResourceStore + { + private readonly ILive source; + + public LegacyDatabasedSkinResourceStore(SkinInfo source, IResourceStore underlyingStore) + : base(underlyingStore) + { + this.source = source.ToLive(); + } + + protected override IEnumerable GetFilenames(string name) + { + foreach (string filename in base.GetFilenames(name)) + { + string path = getPathForFile(filename.ToStandardisedPath()); + if (path != null) + yield return path; + } + } + + private string getPathForFile(string filename) => + source.PerformRead(s => + { + if (s.IsManaged) + { + // avoid enumerating all files if this is a managed realm instance. + return s.Files.Filter(@"Filename ==[c] $0", filename).FirstOrDefault()?.File.GetStoragePath(); + } + + return s.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath(); + }); + + public override IEnumerable GetAvailableResources() => source.PerformRead(s => s.Files.Select(f => f.Filename)); + } +} diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 64f920de85..e677e2c01b 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -51,7 +51,7 @@ namespace osu.Game.Skinning [UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)] public LegacySkin(SkinInfo skin, IStorageResourceProvider resources) - : this(skin, new LegacySkinResourceStore(skin, resources.Files), resources, "skin.ini") + : this(skin, new LegacyDatabasedSkinResourceStore(skin, resources.Files), resources, "skin.ini") { } diff --git a/osu.Game/Skinning/LegacySkinResourceStore.cs b/osu.Game/Skinning/LegacySkinResourceStore.cs index 71efc949b8..2487a469c8 100644 --- a/osu.Game/Skinning/LegacySkinResourceStore.cs +++ b/osu.Game/Skinning/LegacySkinResourceStore.cs @@ -13,9 +13,9 @@ namespace osu.Game.Skinning { public class LegacySkinResourceStore : ResourceStore { - private readonly IHasRealmFiles source; + private readonly IHasNamedFiles source; - public LegacySkinResourceStore(IHasRealmFiles source, IResourceStore underlyingStore) + public LegacySkinResourceStore(IHasNamedFiles source, IResourceStore underlyingStore) : base(underlyingStore) { this.source = source; @@ -32,7 +32,7 @@ namespace osu.Game.Skinning } private string getPathForFile(string filename) => - source.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.GetStoragePath(); + source.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath(); public override IEnumerable GetAvailableResources() => source.Files.Select(f => f.Filename); }