diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index 21e4948972..20bf42345f 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -48,11 +48,12 @@ namespace osu.Game.Tests.Skins.IO }); [Test] - public Task TestEmptyImportFails() => runSkinTest(osu => + public Task TestEmptyImportImportsWithFilename() => runSkinTest(async osu => { - Assert.ThrowsAsync(() => loadSkinIntoOsu(osu, new ZipArchiveReader(createEmptyOsk(), "test skin.osk"))); + var import1 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createEmptyOsk(), "test skin.osk")); - return Task.CompletedTask; + // When the import filename matches it shouldn't be appended. + assertCorrectMetadata(import1, "test skin", "Unknown", osu); }); #endregion diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 63a5da79a7..0bc4c40459 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -322,22 +322,22 @@ namespace osu.Game.Database .OrderBy(f => f.Filename) .ToArray(); - if (hashableFiles.Length == 0) - throw new InvalidOperationException("Attempted to hash an archive with no files"); - - // for now, concatenate all hashable files in the set to create a unique hash. - MemoryStream hashable = new MemoryStream(); - - foreach (TFileModel file in hashableFiles) + if (hashableFiles.Length > 0) { - using (Stream s = Files.Store.GetStream(file.FileInfo.StoragePath)) - s.CopyTo(hashable); + // for now, concatenate all hashable files in the set to create a unique hash. + MemoryStream hashable = new MemoryStream(); + + foreach (TFileModel file in hashableFiles) + { + using (Stream s = Files.Store.GetStream(file.FileInfo.StoragePath)) + s.CopyTo(hashable); + } + + if (hashable.Length > 0) + return hashable.ComputeSHA2Hash(); } - if (hashable.Length > 0) - return hashable.ComputeSHA2Hash(); - - return item.Hash; + return generateFallbackHash(); } /// @@ -707,10 +707,10 @@ namespace osu.Game.Database s.CopyTo(hashable); } - if (hashable.Length == 0) - throw new InvalidOperationException("Attempted to hash an archive with no files"); + if (hashable.Length > 0) + return hashable.ComputeSHA2Hash(); - return hashable.ComputeSHA2Hash(); + return generateFallbackHash(); } /// @@ -923,6 +923,14 @@ namespace osu.Game.Database #endregion + private static string generateFallbackHash() + { + // if a hash could no be generated from file content, presume a unique / new import. + // therefore, let's use a guaranteed unique hash. + // this doesn't follow the SHA2 hashing schema intentionally, so such entries on the data store can be identified. + return Guid.NewGuid().ToString(); + } + private string getValidFilename(string filename) { foreach (char c in Path.GetInvalidFileNameChars()) diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index afa411a15b..304e48e854 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -157,10 +157,6 @@ namespace osu.Game.Skinning protected override string ComputeHash(SkinInfo item, ArchiveReader reader = null) { - // we will be adding a hashable file below, but this is only useful if there are any other files in the skin. - if (item.Files.Count == 0) - throw new InvalidOperationException("Attempted to hash an archive with no files"); - var instance = GetSkin(item); // This function can be run on fresh import or save. The logic here ensures a skin.ini file is in a good state for both operations.