mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 19:03:08 +08:00
Move hashing functionality to ArchiveModelManager
This commit is contained in:
parent
0384f3549f
commit
ab2b2493a1
@ -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,
|
||||
};
|
||||
}
|
||||
|
@ -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>();
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user