1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 21:02:55 +08:00

Merge branch 'refs/heads/db-refactor' into general-fixes

This commit is contained in:
Dean Herbert 2016-10-19 12:22:04 +09:00
commit 0e9a155be5
17 changed files with 253 additions and 221 deletions

2
.vscode/launch.json vendored
View File

@ -5,7 +5,7 @@
"name": "Launch",
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop.VisualTests/bin/Debug/osu!.exe",
"program": "${workspaceRoot}/osu.Desktop/bin/Debug/osu!.exe",
"args": [],
"cwd": "${workspaceRoot}",
"preLaunchTask": "",

View File

@ -5,6 +5,7 @@ using System.Linq;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO;
using osu.Game.Beatmaps;
using osu.Game.Database;
namespace osu.Desktop.Beatmaps.IO
{
@ -31,8 +32,7 @@ namespace osu.Desktop.Beatmaps.IO
using (var stream = new StreamReader(ReadFile(beatmaps[0])))
{
var decoder = BeatmapDecoder.GetDecoder(stream);
firstMap = new Beatmap();
decoder.Decode(stream, firstMap);
firstMap = decoder.Decode(stream);
}
}
@ -48,11 +48,12 @@ namespace osu.Desktop.Beatmaps.IO
public override BeatmapMetadata ReadMetadata()
{
return firstMap.Metadata;
return firstMap.BeatmapInfo.Metadata;
}
public override void Dispose()
{
// no-op
} }
}
}
}

View File

@ -26,9 +26,8 @@ namespace osu.Game.Tests.Beatmaps.Formats
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
Beatmap beatmap = new Beatmap();
decoder.Decode(new StreamReader(stream), beatmap);
var meta = beatmap.Metadata;
var beatmap = decoder.Decode(new StreamReader(stream));
var meta = beatmap.BeatmapInfo.Metadata;
Assert.AreEqual(241526, meta.BeatmapSetID);
Assert.AreEqual("Soleily", meta.Artist);
Assert.AreEqual("Soleily", meta.ArtistUnicode);
@ -49,16 +48,15 @@ namespace osu.Game.Tests.Beatmaps.Formats
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
Beatmap beatmap = new Beatmap();
decoder.Decode(new StreamReader(stream), beatmap);
Assert.AreEqual(0, beatmap.AudioLeadIn);
Assert.AreEqual(false, beatmap.Countdown);
Assert.AreEqual(SampleSet.Soft, beatmap.SampleSet);
Assert.AreEqual(0.7f, beatmap.StackLeniency);
Assert.AreEqual(false, beatmap.SpecialStyle);
Assert.AreEqual(PlayMode.Osu, beatmap.Mode);
Assert.AreEqual(false, beatmap.LetterboxInBreaks);
Assert.AreEqual(false, beatmap.WidescreenStoryboard);
var beatmapInfo = decoder.Decode(new StreamReader(stream)).BeatmapInfo;
Assert.AreEqual(0, beatmapInfo.AudioLeadIn);
Assert.AreEqual(false, beatmapInfo.Countdown);
Assert.AreEqual(SampleSet.Soft, beatmapInfo.SampleSet);
Assert.AreEqual(0.7f, beatmapInfo.StackLeniency);
Assert.AreEqual(false, beatmapInfo.SpecialStyle);
Assert.AreEqual(PlayMode.Osu, beatmapInfo.Mode);
Assert.AreEqual(false, beatmapInfo.LetterboxInBreaks);
Assert.AreEqual(false, beatmapInfo.WidescreenStoryboard);
}
}
@ -68,8 +66,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
Beatmap beatmap = new Beatmap();
decoder.Decode(new StreamReader(stream), beatmap);
var beatmap = decoder.Decode(new StreamReader(stream)).BeatmapInfo;
int[] expectedBookmarks =
{
11505, 22054, 32604, 43153, 53703, 64252, 74802, 85351,
@ -92,9 +89,8 @@ namespace osu.Game.Tests.Beatmaps.Formats
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
Beatmap beatmap = new Beatmap();
decoder.Decode(new StreamReader(stream), beatmap);
var difficulty = beatmap.BaseDifficulty;
var beatmap = decoder.Decode(new StreamReader(stream));
var difficulty = beatmap.BeatmapInfo.BaseDifficulty;
Assert.AreEqual(6.5f, difficulty.DrainRate);
Assert.AreEqual(4, difficulty.CircleSize);
Assert.AreEqual(8, difficulty.OverallDifficulty);
@ -110,8 +106,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
Beatmap beatmap = new Beatmap();
decoder.Decode(new StreamReader(stream), beatmap);
var beatmap = decoder.Decode(new StreamReader(stream));
Color4[] expected =
{
new Color4(142, 199, 255, 255),
@ -132,8 +127,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
Beatmap beatmap = new Beatmap();
decoder.Decode(new StreamReader(stream), beatmap);
var beatmap = decoder.Decode(new StreamReader(stream));
var slider = beatmap.HitObjects[0] as Slider;
Assert.IsNotNull(slider);
Assert.AreEqual(new Vector2(192, 168), slider.Position);

View File

@ -1,69 +1,20 @@
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.Linq;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Objects;
using osu.Game.Beatmaps.Samples;
using osu.Game.Beatmaps.Timing;
using osu.Game.GameModes.Play;
using osu.Game.Users;
using SQLite;
using osu.Game.Database;
namespace osu.Game.Beatmaps
{
public class Beatmap
{
[PrimaryKey]
public int BeatmapID { get; set; }
[NotNull, Indexed]
public int BeatmapSetID { get; set; }
[Indexed]
public int BeatmapMetadataID { get; set; }
public int BaseDifficultyID { get; set; }
[Ignore]
public BeatmapInfo BeatmapInfo { get; set; }
public List<HitObject> HitObjects { get; set; }
[Ignore]
public List<ControlPoint> ControlPoints { get; set; }
[Ignore]
public BeatmapMetadata Metadata { get; set; }
[Ignore]
public BaseDifficulty BaseDifficulty { get; set; }
[Ignore]
public List<Color4> ComboColors { get; set; }
// General
public int AudioLeadIn { get; set; }
public bool Countdown { get; set; }
public SampleSet SampleSet { get; set; }
public float StackLeniency { get; set; }
public bool SpecialStyle { get; set; }
public PlayMode Mode { get; set; }
public bool LetterboxInBreaks { get; set; }
public bool WidescreenStoryboard { get; set; }
// Editor
// This bookmarks stuff is necessary because DB doesn't know how to store int[]
public string StoredBookmarks { get; internal set; }
[Ignore]
public int[] Bookmarks
{
get
{
return StoredBookmarks.Split(',').Select(b => int.Parse(b)).ToArray();
}
set
{
StoredBookmarks = string.Join(",", value);
}
}
public double DistanceSpacing { get; set; }
public int BeatDivisor { get; set; }
public int GridSize { get; set; }
public double TimelineZoom { get; set; }
// Metadata
public string Version { get; set; }
}
}

View File

@ -1,28 +0,0 @@
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Game.Users;
using SQLite;
namespace osu.Game.Beatmaps
{
/// <summary>
/// A beatmap set contains multiple beatmap (difficulties).
/// </summary>
public class BeatmapSet
{
[PrimaryKey]
public int BeatmapSetID { get; set; }
[NotNull, Indexed]
public int BeatmapMetadataID { get; set; }
[Ignore]
public List<Beatmap> Beatmaps { get; protected set; } = new List<Beatmap>();
[Ignore]
public BeatmapMetadata Metadata { get; set; }
[Ignore]
public User Creator { get; set; }
public string Hash { get; set; }
public string Path { get; set; }
}
}

View File

@ -15,11 +15,12 @@ namespace osu.Game.Beatmaps.Formats
throw new IOException(@"Unknown file format");
return (BeatmapDecoder)Activator.CreateInstance(decoders[line]);
}
protected static void AddDecoder<T>(string magic) where T : BeatmapDecoder
protected static void AddDecoder<T>(string magic) where T : BeatmapDecoder
{
decoders[magic] = typeof(T);
}
public abstract void Decode(TextReader stream, Beatmap beatmap);
public abstract Beatmap Decode(TextReader stream);
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using OpenTK.Graphics;
using osu.Game.Database;
using osu.Game.Beatmaps.Events;
using osu.Game.Beatmaps.Objects;
using osu.Game.Beatmaps.Samples;
@ -38,37 +39,38 @@ namespace osu.Game.Beatmaps.Formats
private void handleGeneral(Beatmap beatmap, string key, string val)
{
var metadata = beatmap.BeatmapInfo.Metadata;
switch (key)
{
case @"AudioFilename":
beatmap.Metadata.AudioFile = val;
metadata.AudioFile = val;
break;
case @"AudioLeadIn":
beatmap.AudioLeadIn = int.Parse(val);
beatmap.BeatmapInfo.AudioLeadIn = int.Parse(val);
break;
case @"PreviewTime":
beatmap.Metadata.PreviewTime = int.Parse(val);
metadata.PreviewTime = int.Parse(val);
break;
case @"Countdown":
beatmap.Countdown = int.Parse(val) == 1;
beatmap.BeatmapInfo.Countdown = int.Parse(val) == 1;
break;
case @"SampleSet":
beatmap.SampleSet = (SampleSet)Enum.Parse(typeof(SampleSet), val);
beatmap.BeatmapInfo.SampleSet = (SampleSet)Enum.Parse(typeof(SampleSet), val);
break;
case @"StackLeniency":
beatmap.StackLeniency = float.Parse(val, NumberFormatInfo.InvariantInfo);
beatmap.BeatmapInfo.StackLeniency = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"Mode":
beatmap.Mode = (PlayMode)int.Parse(val);
beatmap.BeatmapInfo.Mode = (PlayMode)int.Parse(val);
break;
case @"LetterboxInBreaks":
beatmap.LetterboxInBreaks = int.Parse(val) == 1;
beatmap.BeatmapInfo.LetterboxInBreaks = int.Parse(val) == 1;
break;
case @"SpecialStyle":
beatmap.SpecialStyle = int.Parse(val) == 1;
beatmap.BeatmapInfo.SpecialStyle = int.Parse(val) == 1;
break;
case @"WidescreenStoryboard":
beatmap.WidescreenStoryboard = int.Parse(val) == 1;
beatmap.BeatmapInfo.WidescreenStoryboard = int.Parse(val) == 1;
break;
}
}
@ -78,82 +80,84 @@ namespace osu.Game.Beatmaps.Formats
switch (key)
{
case @"Bookmarks":
beatmap.StoredBookmarks = val;
beatmap.BeatmapInfo.StoredBookmarks = val;
break;
case @"DistanceSpacing":
beatmap.DistanceSpacing = double.Parse(val, NumberFormatInfo.InvariantInfo);
beatmap.BeatmapInfo.DistanceSpacing = double.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"BeatDivisor":
beatmap.BeatDivisor = int.Parse(val);
beatmap.BeatmapInfo.BeatDivisor = int.Parse(val);
break;
case @"GridSize":
beatmap.GridSize = int.Parse(val);
beatmap.BeatmapInfo.GridSize = int.Parse(val);
break;
case @"TimelineZoom":
beatmap.TimelineZoom = double.Parse(val, NumberFormatInfo.InvariantInfo);
beatmap.BeatmapInfo.TimelineZoom = double.Parse(val, NumberFormatInfo.InvariantInfo);
break;
}
}
private void handleMetadata(Beatmap beatmap, string key, string val)
{
var metadata = beatmap.BeatmapInfo.Metadata;
switch (key)
{
case @"Title":
beatmap.Metadata.Title = val;
metadata.Title = val;
break;
case @"TitleUnicode":
beatmap.Metadata.TitleUnicode = val;
metadata.TitleUnicode = val;
break;
case @"Artist":
beatmap.Metadata.Artist = val;
metadata.Artist = val;
break;
case @"ArtistUnicode":
beatmap.Metadata.ArtistUnicode = val;
metadata.ArtistUnicode = val;
break;
case @"Creator":
beatmap.Metadata.Author = val;
metadata.Author = val;
break;
case @"Version":
beatmap.Version = val;
beatmap.BeatmapInfo.Version = val;
break;
case @"Source":
beatmap.Metadata.Source = val;
beatmap.BeatmapInfo.Metadata.Source = val;
break;
case @"Tags":
beatmap.Metadata.Tags = val;
beatmap.BeatmapInfo.Metadata.Tags = val;
break;
case @"BeatmapID":
beatmap.BeatmapID = int.Parse(val);
beatmap.BeatmapInfo.BeatmapID = int.Parse(val);
break;
case @"BeatmapSetID":
beatmap.BeatmapSetID = int.Parse(val);
beatmap.Metadata.BeatmapSetID = int.Parse(val);
beatmap.BeatmapInfo.BeatmapSetID = int.Parse(val);
metadata.BeatmapSetID = int.Parse(val);
break;
}
}
private void handleDifficulty(Beatmap beatmap, string key, string val)
{
var difficulty = beatmap.BeatmapInfo.BaseDifficulty;
switch (key)
{
case @"HPDrainRate":
beatmap.BaseDifficulty.DrainRate = float.Parse(val, NumberFormatInfo.InvariantInfo);
difficulty.DrainRate = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"CircleSize":
beatmap.BaseDifficulty.CircleSize = float.Parse(val, NumberFormatInfo.InvariantInfo);
difficulty.CircleSize = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"OverallDifficulty":
beatmap.BaseDifficulty.OverallDifficulty = float.Parse(val, NumberFormatInfo.InvariantInfo);
difficulty.OverallDifficulty = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"ApproachRate":
beatmap.BaseDifficulty.ApproachRate = float.Parse(val, NumberFormatInfo.InvariantInfo);
difficulty.ApproachRate = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"SliderMultiplier":
beatmap.BaseDifficulty.SliderMultiplier = float.Parse(val, NumberFormatInfo.InvariantInfo);
difficulty.SliderMultiplier = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"SliderTickRate":
beatmap.BaseDifficulty.SliderTickRate = float.Parse(val, NumberFormatInfo.InvariantInfo);
difficulty.SliderTickRate = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
}
}
@ -176,7 +180,7 @@ namespace osu.Game.Beatmaps.Formats
type = (EventType)_type;
// TODO: Parse and store the rest of the event
if (type == EventType.Background)
beatmap.Metadata.BackgroundFile = split[2].Trim('"');
beatmap.BeatmapInfo.Metadata.BackgroundFile = split[2].Trim('"');
}
private void handleTimingPoints(Beatmap beatmap, string val)
@ -202,15 +206,15 @@ namespace osu.Game.Beatmaps.Formats
});
}
public override void Decode(TextReader stream, Beatmap beatmap)
public override Beatmap Decode(TextReader stream)
{
// We don't overwrite these two because they're DB bound
if (beatmap.Metadata == null) beatmap.Metadata = new BeatmapMetadata();
if (beatmap.BaseDifficulty == null) beatmap.BaseDifficulty = new BaseDifficulty();
// These are fine though
beatmap.HitObjects = new List<HitObject>();
beatmap.ControlPoints = new List<ControlPoint>();
beatmap.ComboColors = new List<Color4>();
var beatmap = new Beatmap
{
HitObjects = new List<HitObject>(),
ControlPoints = new List<ControlPoint>(),
ComboColors = new List<Color4>(),
BeatmapInfo = new BeatmapInfo(),
};
var section = Section.None;
string line;
@ -262,10 +266,12 @@ namespace osu.Game.Beatmaps.Formats
handleColours(beatmap, key, val);
break;
case Section.HitObjects:
beatmap.HitObjects.Add(HitObject.Parse(beatmap.Mode, val));
beatmap.HitObjects.Add(HitObject.Parse(beatmap.BeatmapInfo.Mode, val));
break;
}
}
return beatmap;
}
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using osu.Framework.Platform;
using osu.Game.Database;
namespace osu.Game.Beatmaps.IO
{

View File

@ -4,6 +4,7 @@ using System.Linq;
using System.Security.Cryptography;
using Ionic.Zip;
using osu.Game.Beatmaps.Formats;
using osu.Game.Database;
namespace osu.Game.Beatmaps.IO
{
@ -33,8 +34,7 @@ namespace osu.Game.Beatmaps.IO
using (var stream = new StreamReader(ReadFile(beatmaps[0])))
{
var decoder = BeatmapDecoder.GetDecoder(stream);
firstMap = new Beatmap();
decoder.Decode(stream, firstMap);
firstMap = decoder.Decode(stream);
}
}
@ -53,9 +53,10 @@ namespace osu.Game.Beatmaps.IO
public override BeatmapMetadata ReadMetadata()
{
return firstMap.Metadata;
return firstMap.BeatmapInfo.Metadata;
}
public override void Dispose()
public override void Dispose()
{
archive.Dispose();
}

View File

@ -1,7 +1,7 @@
using System;
using SQLite;
using SQLite.Net.Attributes;
namespace osu.Game.Beatmaps
namespace osu.Game.Database
{
public class BaseDifficulty
{

View File

@ -1,12 +1,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO;
using SQLite;
using SQLite.Net;
using SQLiteNetExtensions.Extensions;
namespace osu.Game.Database
{
@ -23,14 +25,18 @@ namespace osu.Game.Database
connection = storage.GetDatabase(@"beatmaps");
connection.CreateTable<BeatmapMetadata>();
connection.CreateTable<BaseDifficulty>();
connection.CreateTable<BeatmapSet>();
connection.CreateTable<Beatmap>();
connection.CreateTable<BeatmapSetInfo>();
connection.CreateTable<BeatmapInfo>();
}
}
public void AddBeatmap(string path)
public void ImportBeatmap(string path)
{
string hash = null;
ArchiveReader reader;
var reader = ArchiveReader.GetReader(storage, path);
var metadata = reader.ReadMetadata();
if (connection.Table<BeatmapSetInfo>().Count(b => b.BeatmapSetID == metadata.BeatmapSetID) != 0)
return; // TODO: Update this beatmap instead
if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader
{
using (var md5 = MD5.Create())
@ -41,60 +47,82 @@ namespace osu.Game.Database
var outputPath = Path.Combine(@"beatmaps", hash.Remove(1), hash.Remove(2), hash);
using (var output = storage.GetStream(outputPath, FileAccess.Write))
input.CopyTo(output);
reader = ArchiveReader.GetReader(storage, path = outputPath);
}
}
else
reader = ArchiveReader.GetReader(storage, path);
var metadata = reader.ReadMetadata();
if (connection.Table<BeatmapSet>().Count(b => b.BeatmapSetID == metadata.BeatmapSetID) != 0)
return; // TODO: Update this beatmap instead
string[] mapNames = reader.ReadBeatmaps();
var beatmapSet = new BeatmapSet
var beatmapSet = new BeatmapSetInfo
{
BeatmapSetID = metadata.BeatmapSetID,
Path = path,
Hash = hash,
};
var maps = new List<Beatmap>();
var maps = new List<BeatmapInfo>();
foreach (var name in mapNames)
{
using (var stream = new StreamReader(reader.ReadFile(name)))
{
var decoder = BeatmapDecoder.GetDecoder(stream);
Beatmap beatmap = new Beatmap();
decoder.Decode(stream, beatmap);
maps.Add(beatmap);
beatmap.BaseDifficultyID = connection.Insert(beatmap.BaseDifficulty);
Beatmap beatmap = decoder.Decode(stream);
beatmap.BeatmapInfo.Path = name;
// TODO: Diff beatmap metadata with set metadata and insert if necessary
beatmap.BeatmapInfo.Metadata = null;
maps.Add(beatmap.BeatmapInfo);
connection.Insert(beatmap.BeatmapInfo.BaseDifficulty);
connection.Insert(beatmap.BeatmapInfo);
connection.UpdateWithChildren(beatmap.BeatmapInfo);
}
}
beatmapSet.BeatmapMetadataID = connection.Insert(metadata);
connection.Insert(beatmapSet);
connection.InsertAll(maps);
beatmapSet.BeatmapMetadataID = connection.Insert(metadata);
connection.UpdateWithChildren(beatmapSet);
}
public ArchiveReader GetReader(BeatmapSet beatmapSet)
public ArchiveReader GetReader(BeatmapSetInfo beatmapSet)
{
return ArchiveReader.GetReader(storage, beatmapSet.Path);
}
/// <summary>
/// Given a BeatmapSet pulled from the database, loads the rest of its data from disk.
/// </summary> public void PopulateBeatmap(BeatmapSet beatmapSet)
public BeatmapSetInfo GetBeatmapSet(int id)
{
return Query<BeatmapSetInfo>().Where(s => s.BeatmapSetID == id).FirstOrDefault();
}
public Beatmap GetBeatmap(BeatmapInfo beatmapInfo)
{
var beatmapSet = Query<BeatmapSetInfo>()
.Where(s => s.BeatmapSetID == beatmapInfo.BeatmapSetID).FirstOrDefault();
if (beatmapSet == null)
throw new InvalidOperationException(
$@"Beatmap set {beatmapInfo.BeatmapSetID} is not in the local database.");
using (var reader = GetReader(beatmapSet))
using (var stream = new StreamReader(reader.ReadFile(beatmapInfo.Path)))
{
string[] mapNames = reader.ReadBeatmaps();
foreach (var name in mapNames)
{
using (var stream = new StreamReader(reader.ReadFile(name)))
{
var decoder = BeatmapDecoder.GetDecoder(stream);
Beatmap beatmap = new Beatmap();
decoder.Decode(stream, beatmap);
beatmapSet.Beatmaps.Add(beatmap);
}
}
var decoder = BeatmapDecoder.GetDecoder(stream);
return decoder.Decode(stream);
}
}
public TableQuery<T> Query<T>() where T : class
{
return connection.Table<T>();
}
readonly Type[] validTypes = new[]
{
typeof(BeatmapSetInfo),
typeof(BeatmapInfo),
typeof(BeatmapMetadata),
typeof(BaseDifficulty),
};
public void Update<T>(T record, bool cascade = true) where T : class
{
if (!validTypes.Any(t => t == typeof(T)))
throw new ArgumentException(nameof(T), "Must be a type managed by BeatmapDatabase");
if (cascade)
connection.UpdateWithChildren(record);
else
connection.Update(record);
}
}
}

View File

@ -0,0 +1,65 @@
using System;
using System.Linq;
using osu.Game.Beatmaps.Samples;
using osu.Game.GameModes.Play;
using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes;
namespace osu.Game.Database
{
public class BeatmapInfo
{
public BeatmapInfo()
{
BaseDifficulty = new BaseDifficulty();
}
[PrimaryKey]
public int BeatmapID { get; set; }
[NotNull, Indexed]
public int BeatmapSetID { get; set; }
[ForeignKey(typeof(BeatmapMetadata))]
public int BeatmapMetadataID { get; set; }
[ForeignKey(typeof(BaseDifficulty)), NotNull]
public int BaseDifficultyID { get; set; }
[OneToOne]
public BeatmapMetadata Metadata { get; set; }
[OneToOne]
public BaseDifficulty BaseDifficulty { get; set; }
public string Path { get; set; }
// General
public int AudioLeadIn { get; set; }
public bool Countdown { get; set; }
public SampleSet SampleSet { get; set; }
public float StackLeniency { get; set; }
public bool SpecialStyle { get; set; }
public PlayMode Mode { get; set; }
public bool LetterboxInBreaks { get; set; }
public bool WidescreenStoryboard { get; set; }
// Editor
// This bookmarks stuff is necessary because DB doesn't know how to store int[]
public string StoredBookmarks { get; internal set; }
[Ignore]
public int[] Bookmarks
{
get
{
return StoredBookmarks.Split(',').Select(b => int.Parse(b)).ToArray();
}
set
{
StoredBookmarks = string.Join(",", value);
}
}
public double DistanceSpacing { get; set; }
public int BeatDivisor { get; set; }
public int GridSize { get; set; }
public double TimelineZoom { get; set; }
// Metadata
public string Version { get; set; }
}
}

View File

@ -2,9 +2,9 @@
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.GameModes.Play;
using SQLite;
using SQLite.Net.Attributes;
namespace osu.Game.Beatmaps
namespace osu.Game.Database
{
public class BeatmapMetadata
{

View File

@ -0,0 +1,19 @@
using System;
using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes;
namespace osu.Game.Database
{
public class BeatmapSetInfo
{
[PrimaryKey]
public int BeatmapSetID { get; set; }
[OneToOne]
public BeatmapMetadata Metadata { get; set; }
[NotNull, ForeignKey(typeof(BeatmapMetadata))]
public int BeatmapMetadataID { get; set; }
public string Hash { get; set; }
public string Path { get; set; }
}
}

View File

@ -74,7 +74,7 @@ namespace osu.Game
{
try
{
Beatmaps.AddBeatmap(message.Path);
Beatmaps.ImportBeatmap(message.Path);
// TODO: Switch to beatmap list and select the new song
}
catch (Exception ex)

View File

@ -43,26 +43,24 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="SQLitePCLRaw.core">
<HintPath>$(SolutionDir)\packages\SQLitePCLRaw.core.1.0.1\lib\net45\SQLitePCLRaw.core.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.provider.e_sqlite3">
<HintPath>$(SolutionDir)\packages\SQLitePCLRaw.provider.e_sqlite3.net45.1.0.1\lib\net45\SQLitePCLRaw.provider.e_sqlite3.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.batteries_green">
<HintPath>$(SolutionDir)\packages\SQLitePCLRaw.bundle_green.1.0.1\lib\net45\SQLitePCLRaw.batteries_green.dll</HintPath>
</Reference>
<Reference Include="SQLite-net">
<HintPath>$(SolutionDir)\packages\sqlite-net-pcl.1.2.0\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10\SQLite-net.dll</HintPath>
</Reference>
<Reference Include="DotNetZip">
<HintPath>$(SolutionDir)\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll</HintPath>
</Reference>
<Reference Include="SQLite.Net.Platform.Win32">
<HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.0.5\lib\net4\SQLite.Net.Platform.Win32.dll</HintPath>
</Reference>
<Reference Include="SQLite.Net">
<HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.dll</HintPath>
</Reference>
<Reference Include="SQLite.Net.Platform.Generic">
<HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.Platform.Generic.dll</HintPath>
</Reference>
<Reference Include="SQLiteNetExtensions">
<HintPath>$(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Beatmaps\Beatmap.cs" />
<Compile Include="Beatmaps\BeatmapSet.cs" />
<Compile Include="Beatmaps\BeatmapMetadata.cs" />
<Compile Include="Beatmaps\Objects\Catch\CatchConverter.cs" />
<Compile Include="Beatmaps\Objects\Catch\Drawable\DrawableFruit.cs" />
<Compile Include="Beatmaps\Objects\HitObject.cs" />
@ -168,9 +166,12 @@
<Compile Include="Beatmaps\Formats\BeatmapDecoder.cs" />
<Compile Include="Beatmaps\Formats\OsuLegacyDecoder.cs" />
<Compile Include="Beatmaps\IO\OszArchiveReader.cs" />
<Compile Include="Beatmaps\BaseDifficulty.cs" />
<Compile Include="Beatmaps\Events\EventType.cs" />
<Compile Include="VolumeMeter.cs" />
<Compile Include="Database\BeatmapSetInfo.cs" />
<Compile Include="Database\BeatmapMetadata.cs" />
<Compile Include="Database\BeatmapInfo.cs" />
<Compile Include="Database\BaseDifficulty.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\osu-framework\osu.Framework\osu.Framework.csproj">
@ -198,7 +199,4 @@
<Target Name="AfterBuild">
</Target>
-->
<Import Project="$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.v110_xp.1.0.1\build\SQLitePCLRaw.lib.e_sqlite3.v110_xp.targets" Condition="Exists('..\packages\SQLitePCLRaw.lib.e_sqlite3.v110_xp.1.0.1\build\SQLitePCLRaw.lib.e_sqlite3.v110_xp.targets')" />
<Import Project="$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.osx.1.0.1\build\SQLitePCLRaw.lib.e_sqlite3.osx.targets" Condition="Exists('..\packages\SQLitePCLRaw.lib.e_sqlite3.osx.1.0.1\build\SQLitePCLRaw.lib.e_sqlite3.osx.targets')" />
<Import Project="$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.linux.1.0.1\build\SQLitePCLRaw.lib.e_sqlite3.linux.targets" Condition="Exists('..\packages\SQLitePCLRaw.lib.e_sqlite3.linux.1.0.1\build\SQLitePCLRaw.lib.e_sqlite3.linux.targets')" />
</Project>
</Project>

View File

@ -7,11 +7,6 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
<package id="DotNetZip" version="1.10.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="ppy.OpenTK" version="1.1.2225.3" targetFramework="net45" />
<package id="sqlite-net-pcl" version="1.2.0" targetFramework="net45" />
<package id="SQLitePCLRaw.bundle_green" version="1.0.1" targetFramework="net45" />
<package id="SQLitePCLRaw.core" version="1.0.1" targetFramework="net45" />
<package id="SQLitePCLRaw.lib.e_sqlite3.linux" version="1.0.1" targetFramework="net45" />
<package id="SQLitePCLRaw.lib.e_sqlite3.osx" version="1.0.1" targetFramework="net45" />
<package id="SQLitePCLRaw.lib.e_sqlite3.v110_xp" version="1.0.1" targetFramework="net45" />
<package id="SQLitePCLRaw.provider.e_sqlite3.net45" version="1.0.1" targetFramework="net45" />
<package id="SQLite.Net-PCL" version="3.0.5" targetFramework="net45" />
<package id="SQLiteNetExtensions" version="1.3.0" targetFramework="net45" />
</packages>