Merge remote tracking branch 'upstream/master' into archive-reader

This commit is contained in:
Alex Amadori
2017-03-07 08:41:44 +01:00
213 changed files with 2518 additions and 886 deletions

View File

@ -6,7 +6,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Cryptography;
using osu.Framework.Extensions;
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
@ -20,19 +20,20 @@ namespace osu.Game.Database
{
public class BeatmapDatabase
{
private SQLiteConnection connection { get; set; }
private SQLiteConnection connection { get; }
private Storage storage;
public event Action<BeatmapSetInfo> BeatmapSetAdded;
public event Action<BeatmapSetInfo> BeatmapSetRemoved;
private BeatmapImporter ipc;
// ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised)
private BeatmapIPCChannel ipc;
public BeatmapDatabase(Storage storage, GameHost importHost = null)
public BeatmapDatabase(Storage storage, IIpcHost importHost = null)
{
this.storage = storage;
if (importHost != null)
ipc = new BeatmapImporter(importHost, this);
ipc = new BeatmapIPCChannel(importHost, this);
if (connection == null)
{
@ -73,7 +74,7 @@ namespace osu.Game.Database
}
catch (Exception e)
{
Logger.Error(e, $@"Could not delete beatmap {b.ToString()}");
Logger.Error(e, $@"Could not delete beatmap {b}");
}
}
@ -149,9 +150,9 @@ namespace osu.Game.Database
catch (Exception e)
{
e = e.InnerException ?? e;
Logger.Error(e, $@"Could not import beatmap set");
Logger.Error(e, @"Could not import beatmap set");
}
// Batch commit with multiple sets to database
Import(sets);
}
@ -162,7 +163,7 @@ namespace osu.Game.Database
/// <param name="path">Location on disk</param>
public void Import(string path)
{
Import(new [] { path });
Import(new[] { path });
}
/// <summary>
@ -181,10 +182,9 @@ namespace osu.Game.Database
if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader
{
using (var md5 = MD5.Create())
using (var input = storage.GetStream(path))
{
hash = BitConverter.ToString(md5.ComputeHash(input)).Replace("-", "").ToLowerInvariant();
hash = input.GetMd5Hash();
input.Seek(0, SeekOrigin.Begin);
path = Path.Combine(@"beatmaps", hash.Remove(1), hash.Remove(2), hash);
if (!storage.Exists(path))
@ -216,22 +216,29 @@ namespace osu.Game.Database
Metadata = metadata
};
using (var reader = BeatmapArchiveReader.GetBeatmapArchiveReader(storage, path))
using (var archive = BeatmapArchiveReader.GetBeatmapArchiveReader(storage, path))
{
string[] mapNames = reader.BeatmapFilenames;
string[] mapNames = archive.BeatmapFilenames;
foreach (var name in mapNames)
using (var stream = new StreamReader(reader.GetStream(name)))
using (var raw = archive.GetStream(name))
using (var ms = new MemoryStream()) //we need a memory stream so we can seek and shit
using (var sr = new StreamReader(ms))
{
var decoder = BeatmapDecoder.GetDecoder(stream);
Beatmap beatmap = decoder.Decode(stream);
raw.CopyTo(ms);
ms.Position = 0;
var decoder = BeatmapDecoder.GetDecoder(sr);
Beatmap beatmap = decoder.Decode(sr);
beatmap.BeatmapInfo.Path = name;
beatmap.BeatmapInfo.Hash = ms.GetMd5Hash();
// TODO: Diff beatmap metadata with set metadata and leave it here if necessary
beatmap.BeatmapInfo.Metadata = null;
beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo);
}
beatmapSet.StoryboardFile = reader.StoryboardFilename;
beatmapSet.StoryboardFile = archive.StoryboardFilename;
}
return beatmapSet;
@ -318,8 +325,7 @@ namespace osu.Game.Database
return item;
}
readonly Type[] validTypes = new[]
{
private readonly Type[] validTypes = {
typeof(BeatmapSetInfo),
typeof(BeatmapInfo),
typeof(BeatmapMetadata),
@ -329,7 +335,7 @@ namespace osu.Game.Database
public void Update<T>(T record, bool cascade = true) where T : class
{
if (validTypes.All(t => t != typeof(T)))
throw new ArgumentException(nameof(T), "Must be a type managed by BeatmapDatabase");
throw new ArgumentException("Must be a type managed by BeatmapDatabase", nameof(T));
if (cascade)
connection.UpdateWithChildren(record);
else