Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix conflicting Hash and Online IDs on beatmap import #2673

Merged
merged 5 commits into from
May 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions osu.Desktop/osu.Desktop.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
<StartupObject>osu.Desktop.Program</StartupObject>
</PropertyGroup>
<ItemGroup Label="Project References">
<!-- This can be removed after .NET Core SDK version 2.1.300; see https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet -->
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.3" />
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
Expand All @@ -36,4 +38,8 @@
<ItemGroup Label="Resources">
<EmbeddedResource Include="lazer.ico" />
</ItemGroup>
<ItemGroup>
<!-- This can be removed after .NET Core SDK version 2.1.300; see https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet -->
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>
</Project>
15 changes: 12 additions & 3 deletions osu.Game/Beatmaps/BeatmapManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, R

protected override void Populate(BeatmapSetInfo model, ArchiveReader archive)
{
model.Beatmaps = createBeatmapDifficulties(archive);
model.Beatmaps = createBeatmapDifficulties(model, archive);

// remove metadata from difficulties where it matches the set
foreach (BeatmapInfo b in model.Beatmaps)
Expand All @@ -107,6 +107,7 @@ protected override BeatmapSetInfo CheckForExisting(BeatmapSetInfo model)
{
Delete(existingOnlineId);
beatmaps.PurgeDeletable(s => s.ID == existingOnlineId.ID);
Logger.Log($"Found existing beatmap set with same OnlineBeatmapSetID ({model.OnlineBeatmapSetID}). It has been purged.", LoggingTarget.Database);
}
}

Expand Down Expand Up @@ -303,7 +304,7 @@ protected override BeatmapSetInfo CreateModel(ArchiveReader reader)
{
// let's make sure there are actually .osu files to import.
string mapName = reader.Filenames.FirstOrDefault(f => f.EndsWith(".osu"));
if (string.IsNullOrEmpty(mapName)) throw new InvalidOperationException("No beatmap files found in the map folder.");
if (string.IsNullOrEmpty(mapName)) throw new InvalidOperationException("No beatmap files found in this beatmap archive.");

BeatmapMetadata metadata;
using (var stream = new StreamReader(reader.GetStream(mapName)))
Expand All @@ -321,7 +322,7 @@ protected override BeatmapSetInfo CreateModel(ArchiveReader reader)
/// <summary>
/// Create all required <see cref="BeatmapInfo"/>s for the provided archive.
/// </summary>
private List<BeatmapInfo> createBeatmapDifficulties(ArchiveReader reader)
private List<BeatmapInfo> createBeatmapDifficulties(BeatmapSetInfo model, ArchiveReader reader)
{
var beatmapInfos = new List<BeatmapInfo>();

Expand All @@ -341,6 +342,14 @@ private List<BeatmapInfo> createBeatmapDifficulties(ArchiveReader reader)
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();

// ensure we have the same online set ID as the set itself.
beatmap.BeatmapInfo.OnlineBeatmapSetID = model.OnlineBeatmapSetID;
beatmap.BeatmapInfo.Metadata.OnlineBeatmapSetID = model.OnlineBeatmapSetID;

// check that no existing beatmap exists that is imported with the same online beatmap ID. if so, give it precedence.
if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue && QueryBeatmap(b => b.OnlineBeatmapID.Value == beatmap.BeatmapInfo.OnlineBeatmapID.Value) != null)
beatmap.BeatmapInfo.OnlineBeatmapID = null;

RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);

beatmap.BeatmapInfo.Ruleset = ruleset;
Expand Down
8 changes: 7 additions & 1 deletion osu.Game/Database/ArchiveModelManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,11 @@ public TModel Import(ArchiveReader archive)

var existing = CheckForExisting(item);

if (existing != null) return existing;
if (existing != null)
{
Logger.Log($"Found existing {typeof(TModel)} for {archive.Name} (ID {existing.ID}). Skipping import.", LoggingTarget.Database);
return existing;
}

item.Files = createFileInfos(archive, Files);

Expand All @@ -205,6 +209,8 @@ public TModel Import(ArchiveReader archive)
throw;
}
}

Logger.Log($"Import of {archive.Name} successfully completed!", LoggingTarget.Database);
}
catch (Exception e)
{
Expand Down
4 changes: 2 additions & 2 deletions osu.Game/Database/OsuDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<BeatmapInfo>().HasIndex(b => b.OnlineBeatmapID).IsUnique();
modelBuilder.Entity<BeatmapInfo>().HasIndex(b => b.MD5Hash).IsUnique();
modelBuilder.Entity<BeatmapInfo>().HasIndex(b => b.Hash).IsUnique();
modelBuilder.Entity<BeatmapInfo>().HasIndex(b => b.MD5Hash);
modelBuilder.Entity<BeatmapInfo>().HasIndex(b => b.Hash);

modelBuilder.Entity<BeatmapSetInfo>().HasIndex(b => b.OnlineBeatmapSetID).IsUnique();
modelBuilder.Entity<BeatmapSetInfo>().HasIndex(b => b.DeletePending);
Expand Down
Loading