Skip to content

Commit 69bcef8

Browse files
authored
Merge pull request #34893 from bdach/ignore-osu-files-in-subdirs
Ignore `.osu` files not placed at top level of beatmap archive on import
2 parents c292172 + 79f7f0e commit 69bcef8

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

osu.Game.Tests/Database/BeatmapImporterTests.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,49 @@ public void TestImportWithDuplicateHashes()
10181018
});
10191019
}
10201020

1021+
[Test]
1022+
public void TestBeatmapFilesInNestedDirectoriesAreIgnored()
1023+
{
1024+
RunTestWithRealmAsync(async (realm, storage) =>
1025+
{
1026+
var importer = new BeatmapImporter(storage, realm);
1027+
using var store = new RealmRulesetStore(realm, storage);
1028+
1029+
string? temp = TestResources.GetTestBeatmapForImport();
1030+
1031+
string extractedFolder = $"{temp}_extracted";
1032+
Directory.CreateDirectory(extractedFolder);
1033+
1034+
try
1035+
{
1036+
using (var zip = ZipArchive.Open(temp))
1037+
zip.WriteToDirectory(extractedFolder);
1038+
1039+
var subdirectory = Directory.CreateDirectory(Path.Combine(extractedFolder, "subdir"));
1040+
string modifiedCopyPath = Path.Combine(subdirectory.FullName, "duplicate.osu");
1041+
File.Copy(Directory.GetFiles(extractedFolder, "*.osu").First(), modifiedCopyPath);
1042+
1043+
using (var stream = File.OpenWrite(modifiedCopyPath))
1044+
using (var textWriter = new StreamWriter(stream))
1045+
await textWriter.WriteLineAsync("# adding a comment so that the hashes are different");
1046+
1047+
using (var zip = ZipArchive.Create())
1048+
{
1049+
zip.AddAllFromDirectory(extractedFolder);
1050+
zip.SaveTo(temp, new ZipWriterOptions(CompressionType.Deflate));
1051+
}
1052+
1053+
await importer.Import(temp);
1054+
1055+
EnsureLoaded(realm.Realm);
1056+
}
1057+
finally
1058+
{
1059+
Directory.Delete(extractedFolder, true);
1060+
}
1061+
});
1062+
}
1063+
10211064
[Test]
10221065
public void TestImportNestedStructure()
10231066
{

osu.Game/Beatmaps/BeatmapImporter.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,11 @@ private List<BeatmapInfo> createBeatmapDifficulties(BeatmapSetInfo beatmapSet, R
367367
{
368368
var beatmaps = new List<BeatmapInfo>();
369369

370-
foreach (var file in beatmapSet.Files.Where(f => f.Filename.EndsWith(".osu", StringComparison.OrdinalIgnoreCase)))
370+
// stable appears to ignore `.osu` files which are not placed at the top level of the beatmap archive.
371+
// the logic that achieves this is very difficult to make sense of, but appears to be located somewhere around
372+
// https://github.com/peppy/osu-stable-reference/blob/67795dba3c308e7d0493b296149dcb073ca47ecb/osu!/GameplayElements/Beatmaps/BeatmapManager.cs#L207-L208
373+
// only testing the `/` path separator character is sufficient as `RealmNamedFileUsage`s are normalised to use the front slash unix path separator convention
374+
foreach (var file in beatmapSet.Files.Where(f => !f.Filename.Contains('/') && f.Filename.EndsWith(@".osu", StringComparison.OrdinalIgnoreCase)))
371375
{
372376
using (var memoryStream = new MemoryStream(Files.Store.Get(file.File.GetStoragePath()))) // we need a memory stream so we can seek
373377
{

0 commit comments

Comments
 (0)