Merge pull request #96 from peppy/general-fixes

General fixes
This commit is contained in:
Dean Herbert 2016-10-19 12:36:24 +09:00 committed by GitHub
commit 68799f93bb
31 changed files with 271 additions and 238 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": "",

@ -1 +1 @@
Subproject commit cda05b3a64162eb9d8e591ffe7f79d959c39eebc
Subproject commit 44a3b764f0095573eec45ee1f68265f837896fc3

View File

@ -5,6 +5,7 @@
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 @@ public LegacyFilesystemReader(string path)
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 @@ public override Stream ReadFile(string name)
public override BeatmapMetadata ReadMetadata()
{
return firstMap.Metadata;
return firstMap.BeatmapInfo.Metadata;
}
public override void Dispose()
{
// no-op
} }
}
}
}

View File

@ -26,9 +26,8 @@ public void TestDecodeMetadata()
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 @@ public void TestDecodeGeneral()
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 @@ public void TestDecodeEditor()
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 @@ public void TestDecodeDifficulty()
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 @@ public void TestDecodeColors()
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 @@ public void TestDecodeColors()
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 @@ public static BeatmapDecoder GetDecoder(TextReader stream)
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.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 @@ private enum Section
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 @@ private void handleEditor(Beatmap beatmap, string key, string val)
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 @@ private void handleEvents(Beatmap beatmap, string val)
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 @@ private void handleColours(Beatmap beatmap, string key, string val)
});
}
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 @@ public override void Decode(TextReader stream, Beatmap beatmap)
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.Security.Cryptography;
using Ionic.Zip;
using osu.Game.Beatmaps.Formats;
using osu.Game.Database;
namespace osu.Game.Beatmaps.IO
{
@ -33,8 +34,7 @@ public OszArchiveReader(Stream archiveStream)
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 @@ public override Stream ReadFile(string name)
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 @@ public BeatmapDatabase(BasicStorage storage)
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 @@ public BeatmapDatabase(BasicStorage storage)
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,66 @@
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();
Metadata = new BeatmapMetadata();
}
[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

@ -35,7 +35,7 @@ public override void Load(BaseGame game)
{
base.Load(game);
Content.Scale *= 1 + (x_movement_amount / Size.X) * 2;
Content.Scale *= 1 + (x_movement_amount / DrawSize.X) * 2;
}
protected override void OnEntering(GameMode last)

View File

@ -39,7 +39,7 @@ protected override void OnEntering(GameMode last)
popButton.Alpha = 1;
Content.Alpha = 0;
textContainer.Position = new Vector2(Size.X / 16, 0);
textContainer.Position = new Vector2(DrawSize.X / 16, 0);
box.ScaleTo(0.2f);
box.RotateTo(-20);
@ -55,7 +55,7 @@ protected override void OnEntering(GameMode last)
protected override bool OnExiting(GameMode next)
{
textContainer.MoveTo(new Vector2((Size.X / 16), 0), transition_time, EasingTypes.OutExpo);
textContainer.MoveTo(new Vector2((DrawSize.X / 16), 0), transition_time, EasingTypes.OutExpo);
Content.FadeOut(transition_time, EasingTypes.OutExpo);
return base.OnExiting(next);
@ -65,7 +65,7 @@ protected override void OnSuspending(GameMode next)
{
base.OnSuspending(next);
textContainer.MoveTo(new Vector2(-(Size.X / 16), 0), transition_time, EasingTypes.OutExpo);
textContainer.MoveTo(new Vector2(-(DrawSize.X / 16), 0), transition_time, EasingTypes.OutExpo);
Content.FadeOut(transition_time, EasingTypes.OutExpo);
}

View File

@ -210,7 +210,7 @@ public MenuState State
case MenuState.TopLevel:
buttonAreaBackground.ScaleTo(Vector2.One, 200, EasingTypes.Out);
osuLogo.MoveTo(buttonFlow.Position, 200, EasingTypes.In);
osuLogo.MoveTo(buttonFlow.DrawPosition, 200, EasingTypes.In);
osuLogo.ScaleTo(0.5f, 200, EasingTypes.In);
buttonArea.FadeIn(300);

View File

@ -24,7 +24,7 @@ public override Vector2 OriginPosition
if (CentreTarget == null)
return base.OriginPosition;
return CentreTarget.Position + CentreTarget.Size / 2;
return CentreTarget.DrawPosition + CentreTarget.DrawSize / 2;
}
}
}

View File

@ -24,7 +24,7 @@ public partial class OsuLogo : AutoSizeContainer
public Action Action;
public float SizeForFlow => logo == null ? 0 : logo.Size.X * logo.Scale.X * logoBounceContainer.Scale.X * 0.8f;
public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * 0.8f;
private Sprite ripple;

View File

@ -41,7 +41,7 @@ public override void Load(BaseGame game)
protected override void Update()
{
base.Update();
BackgroundSprite.Scale = new Vector2(Math.Max(Size.X / BackgroundSprite.Size.X, Size.Y / BackgroundSprite.Size.Y));
BackgroundSprite.Scale = new Vector2(Math.Max(DrawSize.X / BackgroundSprite.DrawSize.X, DrawSize.Y / BackgroundSprite.DrawSize.Y));
}
}
}

View File

@ -34,7 +34,7 @@ public override void Load(BaseGame game)
protected override bool OnMouseMove(InputState state)
{
content.Position = (state.Mouse.Position - Size / 2) * ParallaxAmount;
content.Position = (state.Mouse.Position - DrawSize / 2) * ParallaxAmount;
return base.OnMouseMove(state);
}

View File

@ -20,7 +20,7 @@ public RatioAdjust()
protected override void Update()
{
base.Update();
Vector2 parent = Parent.Size;
Vector2 parent = Parent.DrawSize;
Scale = new Vector2(Math.Min(parent.Y / 768f, parent.X / 1024f));
Size = new Vector2(1 / Scale.X);

View File

@ -107,8 +107,8 @@ public override void Load(BaseGame game)
};
//Set this manually because an element with Alpha=0 won't take it size to AutoSizeContainer,
//so the size can be changing between buttonSprite and glowSprite.
Height = buttonSprite.Height;
Width = buttonSprite.Width;
Height = buttonSprite.DrawHeight;
Width = buttonSprite.DrawWidth;
}
private void updateGlowSprite(bool show)

View File

@ -74,7 +74,7 @@ public override void Load(BaseGame 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

@ -144,7 +144,7 @@ protected override void PopIn()
protected override void PopOut()
{
MoveToY(-Size.Y, transition_length, EasingTypes.InQuint);
MoveToY(-DrawSize.Y, transition_length, EasingTypes.InQuint);
FadeOut(transition_length, EasingTypes.InQuint);
}
}

View File

@ -35,7 +35,7 @@ protected override void PopIn()
protected override void PopOut()
{
MoveToY(-Size.Y, transition_time, EasingTypes.InQuint);
MoveToY(-DrawSize.Y, transition_time, EasingTypes.InQuint);
FadeOut(transition_time, EasingTypes.InQuint);
}

View File

@ -121,7 +121,7 @@ protected override void Update()
base.Update();
//todo: find a way to avoid using this (autosize needs to be able to ignore certain drawables.. in this case the tooltip)
Size = new Vector2(WIDTH + (DrawableText.IsVisible ? DrawableText.Size.X : 0), 1);
Size = new Vector2(WIDTH + (DrawableText.IsVisible ? DrawableText.DrawSize.X : 0), 1);
}
protected override bool OnClick(InputState state)

View File

@ -96,7 +96,7 @@ protected override void UpdateLayout()
base.UpdateLayout();
if (!activeMode.EnsureValid())
activeMode.Refresh(() => modeButtonLine.MoveToX(activeButton.Position.X + activeButton.Size.X / 2 + padding, 200, EasingTypes.OutQuint));
activeMode.Refresh(() => modeButtonLine.MoveToX(activeButton.DrawPosition.X + activeButton.DrawSize.X / 2 + padding, 200, EasingTypes.OutQuint));
}
}
}

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>