1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 21:02:54 +08:00

Move hashing functionality to ArchiveModelManager

This commit is contained in:
Dean Herbert 2018-11-28 19:16:05 +09:00
parent 0384f3549f
commit ab2b2493a1
3 changed files with 33 additions and 23 deletions

View File

@ -63,6 +63,8 @@ namespace osu.Game.Beatmaps
public override string[] HandledExtensions => new[] { ".osz" };
protected override string[] HashableFileTypes => new[] { ".osu" };
protected override string ImportFromStablePath => "Songs";
private readonly RulesetStore rulesets;
@ -129,9 +131,6 @@ namespace osu.Game.Beatmaps
beatmaps.ForEach(b => b.OnlineBeatmapID = null);
}
protected override BeatmapSetInfo CheckForExisting(BeatmapSetInfo model) =>
beatmaps.ConsumableItems.FirstOrDefault(b => b.Hash == model.Hash);
/// <summary>
/// Downloads a beatmap.
/// This will post notifications tracking progress.
@ -307,20 +306,6 @@ namespace osu.Game.Beatmaps
/// <returns>Results from the provided query.</returns>
public IQueryable<BeatmapInfo> QueryBeatmaps(Expression<Func<BeatmapInfo, bool>> query) => beatmaps.Beatmaps.AsNoTracking().Where(query);
/// <summary>
/// Create a SHA-2 hash from the provided archive based on contained beatmap (.osu) file content.
/// </summary>
private string computeBeatmapSetHash(ArchiveReader reader)
{
// for now, concatenate all .osu files in the set to create a unique hash.
MemoryStream hashable = new MemoryStream();
foreach (string file in reader.Filenames.Where(f => f.EndsWith(".osu")))
using (Stream s = reader.GetStream(file))
s.CopyTo(hashable);
return hashable.ComputeSHA2Hash();
}
protected override BeatmapSetInfo CreateModel(ArchiveReader reader)
{
// let's make sure there are actually .osu files to import.
@ -339,7 +324,6 @@ namespace osu.Game.Beatmaps
{
OnlineBeatmapSetID = beatmap.BeatmapInfo.BeatmapSet?.OnlineBeatmapSetID,
Beatmaps = new List<BeatmapInfo>(),
Hash = computeBeatmapSetHash(reader),
Metadata = beatmap.Metadata,
};
}

View File

@ -8,6 +8,7 @@ using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using osu.Framework.Extensions;
using osu.Framework.IO.File;
using osu.Framework.Logging;
using osu.Framework.Platform;
@ -203,7 +204,12 @@ namespace osu.Game.Database
try
{
var model = CreateModel(archive);
return model == null ? null : Import(model, archive);
if (model == null) return null;
model.Hash = computeBeatmapSetHash(archive);
return Import(model, archive);
}
catch (Exception e)
{
@ -212,6 +218,27 @@ namespace osu.Game.Database
}
}
/// <summary>
/// Any file extensions which should be included in hash creation.
/// Generally should include all file types which determine the file's uniqueness.
/// Large files should be avoided if possible.
/// </summary>
protected abstract string[] HashableFileTypes { get; }
/// <summary>
/// Create a SHA-2 hash from the provided archive based on contained beatmap (.osu) file content.
/// </summary>
private string computeBeatmapSetHash(ArchiveReader reader)
{
// for now, concatenate all .osu files in the set to create a unique hash.
MemoryStream hashable = new MemoryStream();
foreach (string file in reader.Filenames.Where(f => f.EndsWith(".osu")))
using (Stream s = reader.GetStream(file))
s.CopyTo(hashable);
return hashable.ComputeSHA2Hash();
}
/// <summary>
/// Import an item from a <see cref="TModel"/>.
/// </summary>
@ -477,7 +504,7 @@ namespace osu.Game.Database
/// </summary>
/// <param name="model">The new model proposed for import. Note that <see cref="Populate"/> has not yet been run on this model.</param>
/// <returns>An existing model which matches the criteria to skip importing, else null.</returns>
protected virtual TModel CheckForExisting(TModel model) => null;
protected virtual TModel CheckForExisting(TModel model) => ModelStore.ConsumableItems.FirstOrDefault(b => b.Hash == model.Hash);
private DbSet<TModel> queryModel() => ContextFactory.Get().Set<TModel>();

View File

@ -26,6 +26,8 @@ namespace osu.Game.Skinning
public override string[] HandledExtensions => new[] { ".osk" };
protected override string[] HashableFileTypes => new[] { ".ini" };
protected override string ImportFromStablePath => "Skins";
public SkinManager(Storage storage, DatabaseContextFactory contextFactory, IIpcHost importHost, AudioManager audio)
@ -67,9 +69,6 @@ namespace osu.Game.Skinning
/// <returns>A list of available <see cref="SkinInfo"/>.</returns>
public List<SkinInfo> GetAllUserSkins() => ModelStore.ConsumableItems.Where(s => !s.DeletePending).ToList();
protected override SkinInfo CheckForExisting(SkinInfo model)
=> ModelStore.ConsumableItems.FirstOrDefault(s => s.Name == model.Name && s.Creator == model.Creator);
protected override SkinInfo CreateModel(ArchiveReader archive) => new SkinInfo { Name = archive.Name };
protected override void Populate(SkinInfo model, ArchiveReader archive)