Merge branch 'refs/heads/ipc' (rewritten to remove large file commit; original PR at https://github.com/ppy/osu/pull/60)

This commit is contained in:
Dean Herbert 2016-10-13 12:20:58 +09:00
commit a6f7ccc080
32 changed files with 2165 additions and 43 deletions

@ -1 +1 @@
Subproject commit 7439250a63dd451f34dbc08ecf68a196cf8e479f Subproject commit 03730d016d5d5ebd8ebda003dcae3ca3c35536c4

@ -1 +1 @@
Subproject commit 6d9bbe6c838e4b89b69d5ad49b37b434aa62281e Subproject commit 0505cf0d3b317667dbc95346f57b67fdbcdb4dee

View File

@ -0,0 +1,57 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO;
using osu.Game.Beatmaps;
namespace osu.Desktop.Beatmaps.IO
{
/// <summary>
/// Reads an extracted legacy beatmap from disk.
/// </summary>
public class LegacyFilesystemReader : ArchiveReader
{
static LegacyFilesystemReader()
{
AddReader<LegacyFilesystemReader>((storage, path) => Directory.Exists(path));
}
private string basePath { get; set; }
private string[] beatmaps { get; set; }
private Beatmap firstMap { get; set; }
public LegacyFilesystemReader(string path)
{
basePath = path;
beatmaps = Directory.GetFiles(basePath, @"*.osu").Select(f => Path.GetFileName(f)).ToArray();
if (beatmaps.Length == 0)
throw new FileNotFoundException(@"This directory contains no beatmaps");
using (var stream = new StreamReader(ReadFile(beatmaps[0])))
{
var decoder = BeatmapDecoder.GetDecoder(stream);
firstMap = decoder.Decode(stream);
}
}
public override string[] ReadBeatmaps()
{
return beatmaps;
}
public override Stream ReadFile(string name)
{
return File.OpenRead(Path.Combine(basePath, name));
}
public override BeatmapMetadata ReadMetadata()
{
return firstMap.Metadata;
}
public override void Dispose()
{
// no-op
} }
}

View File

@ -11,10 +11,10 @@ namespace osu.Desktop
public static class Program public static class Program
{ {
[STAThread] [STAThread]
public static void Main() public static void Main(string[] args)
{ {
BasicGameHost host = Host.GetSuitableHost(@"osu"); BasicGameHost host = Host.GetSuitableHost(@"osu");
host.Add(new OsuGame()); host.Add(new OsuGame(args));
host.Run(); host.Run();
} }
} }

View File

@ -59,6 +59,7 @@
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>false</RunCodeAnalysis> <RunCodeAnalysis>false</RunCodeAnalysis>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<Commandlineparameters></Commandlineparameters>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType> <DebugType>none</DebugType>
@ -135,8 +136,13 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Beatmaps\IO\LegacyFilesystemReader.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<ItemGroup>
<Folder Include="Beatmaps\" />
<Folder Include="Beatmaps\IO\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -0,0 +1,143 @@
using System;
using System.IO;
using NUnit.Framework;
using OpenTK;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.Objects.Osu;
using osu.Game.Beatmaps.Samples;
using osu.Game.GameModes.Play;
using osu.Game.Tests.Resources;
namespace osu.Game.Tests.Beatmaps.Formats
{
[TestFixture]
public class OsuLegacyDecoderTest
{
[TestFixtureSetUp]
public void SetUp()
{
OsuLegacyDecoder.Register();
}
[Test]
public void TestDecodeMetadata()
{
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
var beatmap = decoder.Decode(new StreamReader(stream));
var meta = beatmap.Metadata;
Assert.AreEqual(241526, meta.BeatmapSetID);
Assert.AreEqual("Soleily", meta.Artist);
Assert.AreEqual("Soleily", meta.ArtistUnicode);
Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile);
Assert.AreEqual("Gamu", meta.Author);
Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile);
Assert.AreEqual(164471, meta.PreviewTime);
Assert.AreEqual(string.Empty, meta.Source);
Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags);
Assert.AreEqual("Renatus", meta.Title);
Assert.AreEqual("Renatus", meta.TitleUnicode);
}
}
[Test]
public void TestDecodeGeneral()
{
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
var beatmap = decoder.Decode(new StreamReader(stream));
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);
}
}
[Test]
public void TestDecodeEditor()
{
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
var beatmap = decoder.Decode(new StreamReader(stream));
int[] expectedBookmarks =
{
11505, 22054, 32604, 43153, 53703, 64252, 74802, 85351,
95901, 106450, 116999, 119637, 130186, 140735, 151285,
161834, 164471, 175020, 185570, 196119, 206669, 209306
};
Assert.AreEqual(expectedBookmarks.Length, beatmap.Bookmarks.Length);
for (int i = 0; i < expectedBookmarks.Length; i++)
Assert.AreEqual(expectedBookmarks[i], beatmap.Bookmarks[i]);
Assert.AreEqual(1.8, beatmap.DistanceSpacing);
Assert.AreEqual(4, beatmap.BeatDivisor);
Assert.AreEqual(4, beatmap.GridSize);
Assert.AreEqual(2, beatmap.TimelineZoom);
}
}
[Test]
public void TestDecodeDifficulty()
{
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
var beatmap = decoder.Decode(new StreamReader(stream));
var difficulty = beatmap.BaseDifficulty;
Assert.AreEqual(6.5f, difficulty.DrainRate);
Assert.AreEqual(4, difficulty.CircleSize);
Assert.AreEqual(8, difficulty.OverallDifficulty);
Assert.AreEqual(9, difficulty.ApproachRate);
Assert.AreEqual(1.8f, difficulty.SliderMultiplier);
Assert.AreEqual(2, difficulty.SliderTickRate);
}
}
[Test]
public void TestDecodeColors()
{
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
var beatmap = decoder.Decode(new StreamReader(stream));
Color4[] expected =
{
new Color4(142, 199, 255, 255),
new Color4(255, 128, 128, 255),
new Color4(128, 255, 255, 255),
new Color4(128, 255, 128, 255),
new Color4(255, 187, 255, 255),
new Color4(255, 177, 140, 255),
};
Assert.AreEqual(expected.Length, beatmap.ComboColors.Count);
for (int i = 0; i < expected.Length; i++)
Assert.AreEqual(expected[i], beatmap.ComboColors[i]);
}
}
[Test] public void TestDecodeHitObjects()
{
var decoder = new OsuLegacyDecoder();
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
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);
Assert.AreEqual(956, slider.StartTime);
Assert.AreEqual(SampleType.None, slider.Sample.Type);
var circle = beatmap.HitObjects[1] as Circle;
Assert.IsNotNull(circle);
Assert.AreEqual(new Vector2(304, 56), circle.Position);
Assert.AreEqual(1285, circle.StartTime);
Assert.AreEqual(SampleType.Clap, circle.Sample.Type);
}
}
}
}

View File

@ -0,0 +1,81 @@
using System;
using System.IO;
using NUnit.Framework;
using osu.Game.Beatmaps.IO;
using osu.Game.GameModes.Play;
using osu.Game.Tests.Resources;
namespace osu.Game.Tests.Beatmaps.IO
{
[TestFixture]
public class OszArchiveReaderTest
{
[TestFixtureSetUp]
public void SetUp()
{
OszArchiveReader.Register();
}
[Test]
public void TestReadBeatmaps()
{
using (var osz = Resource.OpenResource("Beatmaps.241526 Soleily - Renatus.osz"))
{
var reader = new OszArchiveReader(osz);
string[] expected =
{
"Soleily - Renatus (Deif) [Platter].osu",
"Soleily - Renatus (Deif) [Rain].osu",
"Soleily - Renatus (Deif) [Salad].osu",
"Soleily - Renatus (ExPew) [Another].osu",
"Soleily - Renatus (ExPew) [Hyper].osu",
"Soleily - Renatus (ExPew) [Normal].osu",
"Soleily - Renatus (Gamu) [Hard].osu",
"Soleily - Renatus (Gamu) [Insane].osu",
"Soleily - Renatus (Gamu) [Normal].osu",
"Soleily - Renatus (MMzz) [Futsuu].osu",
"Soleily - Renatus (MMzz) [Muzukashii].osu",
"Soleily - Renatus (MMzz) [Oni].osu"
};
var maps = reader.ReadBeatmaps();
foreach (var map in expected)
Assert.Contains(map, maps);
}
}
[Test]
public void TestReadMetadata()
{
using (var osz = Resource.OpenResource("Beatmaps.241526 Soleily - Renatus.osz"))
{
var reader = new OszArchiveReader(osz);
var meta = reader.ReadMetadata();
Assert.AreEqual(241526, meta.BeatmapSetID);
Assert.AreEqual("Soleily", meta.Artist);
Assert.AreEqual("Soleily", meta.ArtistUnicode);
Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile);
Assert.AreEqual("Deif", meta.Author);
Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile);
Assert.AreEqual(164471, meta.PreviewTime);
Assert.AreEqual(string.Empty, meta.Source);
Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags);
Assert.AreEqual("Renatus", meta.Title);
Assert.AreEqual("Renatus", meta.TitleUnicode);
}
}
[Test]
public void TestReadFile()
{
using (var osz = Resource.OpenResource("Beatmaps.241526 Soleily - Renatus.osz"))
{
var reader = new OszArchiveReader(osz);
using (var stream = new StreamReader(
reader.ReadFile("Soleily - Renatus (Deif) [Platter].osu")))
{
Assert.AreEqual("osu file format v13", stream.ReadLine().Trim());
}
}
}
}
}

View File

@ -0,0 +1,25 @@
<configuration>
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
<dllmap os="linux" dll="libXi" target="libXi.so.6"/>
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
<!-- XQuartz compatibility (X11 on Mac) -->
<dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
<dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
<dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
<dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
<dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
<dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
</configuration>

View File

@ -0,0 +1,17 @@
using System;
using System.IO;
using System.Reflection;
namespace osu.Game.Tests.Resources
{
public static class Resource
{
public static Stream OpenResource(string name)
{
return Assembly.GetExecutingAssembly().GetManifestResourceStream(
$@"osu.Game.Tests.Resources.{name}") ??
Assembly.LoadFrom("osu.Game.Resources.dll").GetManifestResourceStream(
$@"osu.Game.Resources.{name}");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{54377672-20B1-40AF-8087-5CF73BF3953A}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>osu.Game.Tests</RootNamespace>
<AssemblyName>osu.Game.Tests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="nunit.framework">
<HintPath>$(SolutionDir)\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="OpenTK">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.1.1.2225.3\lib\net20\OpenTK.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="OpenTK.dll.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D}</Project>
<Name>osu.Game</Name>
</ProjectReference>
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj">
<Project>{D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}</Project>
<Name>osu.Game.Resources</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
<Folder Include="Beatmaps\" />
<Folder Include="Beatmaps\IO\" />
<Folder Include="Beatmaps\Formats\" />
</ItemGroup>
<ItemGroup>
<Compile Include="Beatmaps\IO\OszArchiveReaderTest.cs" />
<Compile Include="Resources\Resource.cs" />
<Compile Include="Beatmaps\Formats\OsuLegacyDecoderTest.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Soleily - Renatus %28Gamu%29 [Insane].osu" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="2.6.4" targetFramework="net45" />
<package id="ppy.OpenTK" version="1.1.2225.3" targetFramework="net45" />
</packages>

View File

@ -0,0 +1,18 @@
using System;
using SQLite;
namespace osu.Game.Beatmaps
{
public class BaseDifficulty
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public float DrainRate { get; set; }
public float CircleSize { get; set; }
public float OverallDifficulty { get; set; }
public float ApproachRate { get; set; }
public float SliderMultiplier { get; set; }
public float SliderTickRate { get; set; }
}
}

View File

@ -2,19 +2,68 @@
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Objects; using osu.Game.Beatmaps.Objects;
using osu.Game.Beatmaps.Samples;
using osu.Game.Beatmaps.Timing; using osu.Game.Beatmaps.Timing;
using osu.Game.GameModes.Play;
using osu.Game.Users; using osu.Game.Users;
using SQLite;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
{ {
public class Beatmap public class Beatmap
{ {
public List<HitObject> HitObjects; [PrimaryKey]
public int BeatmapID { get; set; }
public List<ControlPoint> ControlPoints; [NotNull, Indexed]
public int BeatmapSetID { get; set; }
public string Difficulty; [Indexed]
public User Creator; public int BeatmapMetadataID { get; set; }
public int BaseDifficultyID { get; set; }
[Ignore]
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

@ -0,0 +1,26 @@
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.GameModes.Play;
using SQLite;
namespace osu.Game.Beatmaps
{
public class BeatmapMetadata
{
[PrimaryKey]
public int ID { get; set; }
public int BeatmapSetID { get; set; }
public string Title { get; set; }
public string TitleUnicode { get; set; }
public string Artist { get; set; }
public string ArtistUnicode { get; set; }
public string Author { get; set; }
public string Source { get; set; }
public string Tags { get; set; }
public int PreviewTime { get; set; }
public string AudioFile { get; set; }
public string BackgroundFile { get; set; }
}
}

View File

@ -3,6 +3,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Users; using osu.Game.Users;
using SQLite;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
{ {
@ -11,10 +12,15 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
public class BeatmapSet public class BeatmapSet
{ {
[PrimaryKey]
public int BeatmapSetID { get; set; }
[NotNull, Indexed]
public int BeatmapMetadataID { get; set; }
[Ignore]
public List<Beatmap> Beatmaps { get; protected set; } public List<Beatmap> Beatmaps { get; protected set; }
[Ignore]
public Metadata Metadata; public BeatmapMetadata Metadata { get; set; }
[Ignore]
public User Creator; public User Creator { get; set; }
} }
} }

View File

@ -0,0 +1,14 @@
using System;
namespace osu.Game.Beatmaps.Events
{
public enum EventType
{
Background = 0,
Video = 1,
Break = 2,
Colour = 3,
Sprite = 4,
Sample = 5,
Animation = 6
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace osu.Game.Beatmaps.Formats
{
public abstract class BeatmapDecoder
{
private static Dictionary<string, Type> decoders { get; } = new Dictionary<string, Type>();
public static BeatmapDecoder GetDecoder(TextReader stream)
{
var line = stream.ReadLine().Trim();
if (!decoders.ContainsKey(line))
throw new IOException(@"Unknown file format");
return (BeatmapDecoder)Activator.CreateInstance(decoders[line]);
}
protected static void AddDecoder<T>(string magic) where T : BeatmapDecoder
{
decoders[magic] = typeof(T);
}
public abstract Beatmap Decode(TextReader stream);
}
}

View File

@ -0,0 +1,272 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Events;
using osu.Game.Beatmaps.Objects;
using osu.Game.Beatmaps.Samples;
using osu.Game.Beatmaps.Timing;
using osu.Game.GameModes.Play;
namespace osu.Game.Beatmaps.Formats
{
public class OsuLegacyDecoder : BeatmapDecoder
{
public static void Register()
{
AddDecoder<OsuLegacyDecoder>(@"osu file format v14");
AddDecoder<OsuLegacyDecoder>(@"osu file format v13");
AddDecoder<OsuLegacyDecoder>(@"osu file format v12");
AddDecoder<OsuLegacyDecoder>(@"osu file format v11");
AddDecoder<OsuLegacyDecoder>(@"osu file format v10");
// TODO: Not sure how far back to go, or differences between versions
}
private enum Section
{
None,
General,
Editor,
Metadata,
Difficulty,
Events,
TimingPoints,
Colours,
HitObjects,
}
private void handleGeneral(Beatmap beatmap, string key, string val)
{
switch (key)
{
case @"AudioFilename":
beatmap.Metadata.AudioFile = val;
break;
case @"AudioLeadIn":
beatmap.AudioLeadIn = int.Parse(val);
break;
case @"PreviewTime":
beatmap.Metadata.PreviewTime = int.Parse(val);
break;
case @"Countdown":
beatmap.Countdown = int.Parse(val) == 1;
break;
case @"SampleSet":
beatmap.SampleSet = (SampleSet)Enum.Parse(typeof(SampleSet), val);
break;
case @"StackLeniency":
beatmap.StackLeniency = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"Mode":
beatmap.Mode = (PlayMode)int.Parse(val);
break;
case @"LetterboxInBreaks":
beatmap.LetterboxInBreaks = int.Parse(val) == 1;
break;
case @"SpecialStyle":
beatmap.SpecialStyle = int.Parse(val) == 1;
break;
case @"WidescreenStoryboard":
beatmap.WidescreenStoryboard = int.Parse(val) == 1;
break;
}
}
private void handleEditor(Beatmap beatmap, string key, string val)
{
switch (key)
{
case @"Bookmarks":
beatmap.StoredBookmarks = val;
break;
case @"DistanceSpacing":
beatmap.DistanceSpacing = double.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"BeatDivisor":
beatmap.BeatDivisor = int.Parse(val);
break;
case @"GridSize":
beatmap.GridSize = int.Parse(val);
break;
case @"TimelineZoom":
beatmap.TimelineZoom = double.Parse(val, NumberFormatInfo.InvariantInfo);
break;
}
}
private void handleMetadata(Beatmap beatmap, string key, string val)
{
switch (key)
{
case @"Title":
beatmap.Metadata.Title = val;
break;
case @"TitleUnicode":
beatmap.Metadata.TitleUnicode = val;
break;
case @"Artist":
beatmap.Metadata.Artist = val;
break;
case @"ArtistUnicode":
beatmap.Metadata.ArtistUnicode = val;
break;
case @"Creator":
beatmap.Metadata.Author = val;
break;
case @"Version":
beatmap.Version = val;
break;
case @"Source":
beatmap.Metadata.Source = val;
break;
case @"Tags":
beatmap.Metadata.Tags = val;
break;
case @"BeatmapID":
beatmap.BeatmapID = int.Parse(val);
break;
case @"BeatmapSetID":
beatmap.BeatmapSetID = int.Parse(val);
beatmap.Metadata.BeatmapSetID = int.Parse(val);
break;
}
}
private void handleDifficulty(Beatmap beatmap, string key, string val)
{
switch (key)
{
case @"HPDrainRate":
beatmap.BaseDifficulty.DrainRate = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"CircleSize":
beatmap.BaseDifficulty.CircleSize = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"OverallDifficulty":
beatmap.BaseDifficulty.OverallDifficulty = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"ApproachRate":
beatmap.BaseDifficulty.ApproachRate = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"SliderMultiplier":
beatmap.BaseDifficulty.SliderMultiplier = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"SliderTickRate":
beatmap.BaseDifficulty.SliderTickRate = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
}
}
private void handleEvents(Beatmap beatmap, string val)
{
if (val.StartsWith(@"//"))
return;
if (val.StartsWith(@" "))
return; // TODO
string[] split = val.Split(',');
EventType type;
int _type;
if (!int.TryParse(split[0], out _type))
{
if (!Enum.TryParse(split[0], out type))
throw new InvalidDataException($@"Unknown event type {split[0]}");
}
else
type = (EventType)_type;
// TODO: Parse and store the rest of the event
if (type == EventType.Background)
beatmap.Metadata.BackgroundFile = split[2].Trim('"');
}
private void handleTimingPoints(Beatmap beatmap, string val)
{
// TODO
}
private void handleColours(Beatmap beatmap, string key, string val)
{
string[] split = val.Split(',');
if (split.Length != 3)
throw new InvalidOperationException($@"Color specified in incorrect format (should be R,G,B): {val}");
byte r, g, b;
if (!byte.TryParse(split[0], out r) || !byte.TryParse(split[1], out g) || !byte.TryParse(split[2], out b))
throw new InvalidOperationException($@"Color must be specified with 8-bit integer components");
// Note: the combo index specified in the beatmap is discarded
beatmap.ComboColors.Add(new Color4
{
R = r / 255f,
G = g / 255f,
B = b / 255f,
A = 1f,
});
}
public override Beatmap Decode(TextReader stream)
{
var beatmap = new Beatmap
{
Metadata = new BeatmapMetadata(),
BaseDifficulty = new BaseDifficulty(),
HitObjects = new List<HitObject>(),
ControlPoints = new List<ControlPoint>(),
ComboColors = new List<Color4>(),
};
var section = Section.None;
string line;
while (true)
{
line = stream.ReadLine();
if (line == null)
break;
line = line.Trim();
if (string.IsNullOrEmpty(line))
continue;
if (line.StartsWith(@"osu file format v"))
continue;
if (line.StartsWith(@"[") && line.EndsWith(@"]"))
{
if (!Enum.TryParse(line.Substring(1, line.Length - 2), out section))
throw new InvalidDataException($@"Unknown osu section {line}");
continue;
}
string val = line, key = null;
if (section != Section.Events && section != Section.TimingPoints && section != Section.HitObjects)
{
key = val.Remove(val.IndexOf(':')).Trim();
val = val.Substring(val.IndexOf(':') + 1).Trim();
}
switch (section)
{
case Section.General:
handleGeneral(beatmap, key, val);
break;
case Section.Editor:
handleEditor(beatmap, key, val);
break;
case Section.Metadata:
handleMetadata(beatmap, key, val);
break;
case Section.Difficulty:
handleDifficulty(beatmap, key, val);
break;
case Section.Events:
handleEvents(beatmap, val);
break;
case Section.TimingPoints:
handleTimingPoints(beatmap, val);
break;
case Section.Colours:
handleColours(beatmap, key, val);
break;
case Section.HitObjects:
beatmap.HitObjects.Add(HitObject.Parse(beatmap.Mode, val));
break;
}
}
return beatmap;
}
}
}

View File

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.IO;
using osu.Framework.Platform;
namespace osu.Game.Beatmaps.IO
{
public abstract class ArchiveReader : IDisposable
{
private class Reader
{
public Func<BasicStorage, string, bool> Test { get; set; }
public Type Type { get; set; }
}
private static List<Reader> readers { get; } = new List<Reader>();
public static ArchiveReader GetReader(BasicStorage storage, string path)
{
foreach (var reader in readers)
{
if (reader.Test(storage, path))
return (ArchiveReader)Activator.CreateInstance(reader.Type, storage.GetStream(path));
}
throw new IOException(@"Unknown file format");
}
protected static void AddReader<T>(Func<BasicStorage, string, bool> test) where T : ArchiveReader
{
readers.Add(new Reader { Test = test, Type = typeof(T) });
}
/// <summary>
/// Reads the beatmap metadata from this archive.
/// </summary>
public abstract BeatmapMetadata ReadMetadata();
/// <summary>
/// Gets a list of beatmap file names.
/// </summary>
public abstract string[] ReadBeatmaps();
/// <summary>
/// Opens a stream for reading a specific file from this archive.
/// </summary>
public abstract Stream ReadFile(string name);
public abstract void Dispose();
}
}

View File

@ -0,0 +1,61 @@
using System;
using System.IO;
using System.Linq;
using Ionic.Zip;
using osu.Game.Beatmaps.Formats;
namespace osu.Game.Beatmaps.IO
{
public sealed class OszArchiveReader : ArchiveReader
{
public static void Register()
{
AddReader<OszArchiveReader>((storage, path) =>
{
using (var stream = storage.GetStream(path))
return ZipFile.IsZipFile(stream, false);
});
OsuLegacyDecoder.Register();
}
private ZipFile archive { get; set; }
private string[] beatmaps { get; set; }
private Beatmap firstMap { get; set; }
public OszArchiveReader(Stream archiveStream)
{
archive = ZipFile.Read(archiveStream);
beatmaps = archive.Entries.Where(e => e.FileName.EndsWith(@".osu"))
.Select(e => e.FileName).ToArray();
if (beatmaps.Length == 0)
throw new FileNotFoundException(@"This directory contains no beatmaps");
using (var stream = new StreamReader(ReadFile(beatmaps[0])))
{
var decoder = BeatmapDecoder.GetDecoder(stream);
firstMap = decoder.Decode(stream);
}
}
public override string[] ReadBeatmaps()
{
return beatmaps;
}
public override Stream ReadFile(string name)
{
ZipEntry entry = archive.Entries.SingleOrDefault(e => e.FileName == name);
if (entry == null)
throw new FileNotFoundException();
return entry.OpenReader();
}
public override BeatmapMetadata ReadMetadata()
{
return firstMap.Metadata;
}
public override void Dispose()
{
archive.Dispose();
}
}
}

View File

@ -1,11 +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
namespace osu.Game.Beatmaps
{
public class Metadata
{
public string Artist;
public string Title;
}
}

View File

@ -1,7 +1,9 @@
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>. //Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps.Objects.Osu;
using osu.Game.Beatmaps.Samples; using osu.Game.Beatmaps.Samples;
using osu.Game.GameModes.Play;
namespace osu.Game.Beatmaps.Objects namespace osu.Game.Beatmaps.Objects
{ {
@ -16,5 +18,17 @@ namespace osu.Game.Beatmaps.Objects
public double Duration => (EndTime ?? StartTime) - StartTime; public double Duration => (EndTime ?? StartTime) - StartTime;
public HitSampleInfo Sample; public HitSampleInfo Sample;
public static HitObject Parse(PlayMode mode, string val)
{
//TODO: move to modular HitObjectParser system rather than static parsing. (https://github.com/ppy/osu/pull/60/files#r83135780)
switch (mode)
{
case PlayMode.Osu:
return OsuBaseHit.Parse(val);
default:
return null;
}
}
} }
} }

View File

@ -1,12 +1,59 @@
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>. //Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using OpenTK; using OpenTK;
using osu.Game.Beatmaps.Samples;
namespace osu.Game.Beatmaps.Objects.Osu namespace osu.Game.Beatmaps.Objects.Osu
{ {
public abstract class OsuBaseHit : HitObject public abstract class OsuBaseHit : HitObject
{ {
public Vector2 Position; public Vector2 Position { get; set; }
public bool NewCombo { get; set; }
[Flags]
private enum HitObjectType
{
Circle = 1,
Slider = 2,
NewCombo = 4,
CircleNewCombo = 5,
SliderNewCombo = 6,
Spinner = 8,
ColourHax = 122,
Hold = 128,
ManiaLong = 128,
}
public static OsuBaseHit Parse(string val)
{
string[] split = val.Split(',');
var type = (HitObjectType)int.Parse(split[3]);
bool combo = type.HasFlag(HitObjectType.NewCombo);
type &= (HitObjectType)0xF;
type &= ~HitObjectType.NewCombo;
OsuBaseHit result;
switch (type)
{
case HitObjectType.Circle:
result = new Circle();
break;
case HitObjectType.Slider:
result = new Slider();
break;
case HitObjectType.Spinner:
result = new Spinner();
break;
default:
throw new InvalidOperationException($@"Unknown hit object type {type}");
}
result.Position = new Vector2(int.Parse(split[0]), int.Parse(split[1]));
result.StartTime = double.Parse(split[2]);
result.Sample = new HitSampleInfo { Type = (SampleType)int.Parse(split[4]) };
result.NewCombo = combo;
// TODO: "addition" field
return result;
}
} }
} }

View File

@ -3,7 +3,7 @@
namespace osu.Game.Beatmaps.Objects.Osu namespace osu.Game.Beatmaps.Objects.Osu
{ {
public class Spinner public class Spinner : OsuBaseHit
{ {
} }
} }

View File

@ -5,6 +5,6 @@ namespace osu.Game.Beatmaps.Samples
{ {
public class HitSampleInfo : SampleInfo public class HitSampleInfo : SampleInfo
{ {
SampleType Type; public SampleType Type { get; set; }
} }
} }

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.IO;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO;
using SQLite;
namespace osu.Game.Database
{
public class BeatmapDatabase
{
private static SQLiteConnection connection { get; set; }
public BeatmapDatabase(BasicStorage storage)
{
if (connection == null)
{
connection = storage.GetDatabase(@"beatmaps");
connection.CreateTable<BeatmapMetadata>();
connection.CreateTable<BaseDifficulty>();
connection.CreateTable<BeatmapSet>();
connection.CreateTable<Beatmap>();
}
}
public void AddBeatmap(ArchiveReader input)
{
var metadata = input.ReadMetadata();
if (connection.Table<BeatmapSet>().Count(b => b.BeatmapSetID == metadata.BeatmapSetID) != 0)
return;
string[] mapNames = input.ReadBeatmaps();
var beatmapSet = new BeatmapSet { BeatmapSetID = metadata.BeatmapSetID };
var maps = new List<Beatmap>();
foreach (var name in mapNames)
{
using (var stream = new StreamReader(input.ReadFile(name)))
{
var decoder = BeatmapDecoder.GetDecoder(stream);
var beatmap = decoder.Decode(stream);
maps.Add(beatmap);
beatmap.BaseDifficultyID = connection.Insert(beatmap.BaseDifficulty);
}
}
beatmapSet.BeatmapMetadataID = connection.Insert(metadata);
connection.Insert(beatmapSet);
connection.InsertAll(maps);
}
}
}

View File

@ -20,17 +20,31 @@ using osu.Framework;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Game.Input; using osu.Game.Input;
using OpenTK.Input; using OpenTK.Input;
using System.IO;
using osu.Game.Beatmaps.IO;
namespace osu.Game namespace osu.Game
{ {
public class OsuGame : OsuGameBase public class OsuGame : OsuGameBase
{ {
private class ImportBeatmap
{
public string Path;
}
public Toolbar Toolbar; public Toolbar Toolbar;
public ChatConsole Chat; public ChatConsole Chat;
public MainMenu MainMenu => intro?.ChildGameMode as MainMenu; public MainMenu MainMenu => intro?.ChildGameMode as MainMenu;
private Intro intro; private Intro intro;
private string[] args;
private IpcChannel<ImportBeatmap> BeatmapIPC;
public Bindable<PlayMode> PlayMode; public Bindable<PlayMode> PlayMode;
public OsuGame(string[] args)
{
this.args = args;
}
public override void SetHost(BasicGameHost host) public override void SetHost(BasicGameHost host)
{ {
@ -41,6 +55,35 @@ namespace osu.Game
public override void Load(BaseGame game) public override void Load(BaseGame game)
{ {
BeatmapIPC = new IpcChannel<ImportBeatmap>(Host);
if (!Host.IsPrimaryInstance)
{
if (args.Length == 1 && File.Exists(args[0]))
{
BeatmapIPC.SendMessage(new ImportBeatmap { Path = args[0] }).Wait();
Console.WriteLine(@"Sent file to running instance");
}
else
Console.WriteLine(@"osu! does not support multiple running instances.");
Environment.Exit(0);
}
BeatmapIPC.MessageReceived += message =>
{
try
{
var reader = ArchiveReader.GetReader(Host.Storage, message.Path);
Beatmaps.AddBeatmap(reader);
// TODO: Switch to beatmap list and select the new song
}
catch (Exception ex)
{
// TODO: Show the user some info?
Console.WriteLine($@"Failed to import beatmap: {ex}");
}
};
base.Load(game); base.Load(game);
//attach our bindables to the audio subsystem. //attach our bindables to the audio subsystem.

View File

@ -5,7 +5,9 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
using osu.Game.Beatmaps.IO;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Graphics.Cursor; using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.Processing; using osu.Game.Graphics.Processing;
using osu.Game.Online.API; using osu.Game.Online.API;
@ -16,6 +18,7 @@ namespace osu.Game
public class OsuGameBase : BaseGame public class OsuGameBase : BaseGame
{ {
internal OsuConfigManager Config = new OsuConfigManager(); internal OsuConfigManager Config = new OsuConfigManager();
internal BeatmapDatabase Beatmaps { get; private set; }
protected override string MainResourceFile => @"osu.Game.Resources.dll"; protected override string MainResourceFile => @"osu.Game.Resources.dll";
@ -32,6 +35,9 @@ namespace osu.Game
{ {
base.Load(game); base.Load(game);
OszArchiveReader.Register();
Beatmaps = new BeatmapDatabase(Host.Storage);
//this completely overrides the framework default. will need to change once we make a proper FontStore. //this completely overrides the framework default. will need to change once we make a proper FontStore.
Fonts = new TextureStore() { ScaleAdjust = 0.01f }; Fonts = new TextureStore() { ScaleAdjust = 0.01f };
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Regular")); Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Regular"));

View File

@ -34,20 +34,35 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>$(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="OpenTK, Version=1.2.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL"> <Reference Include="OpenTK, Version=1.2.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\packages\ppy.OpenTK.1.1.2225.3\lib\net20\OpenTK.dll</HintPath> <HintPath>$(SolutionDir)\packages\ppy.OpenTK.1.1.2225.3\lib\net20\OpenTK.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <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>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Beatmaps\Beatmap.cs" /> <Compile Include="Beatmaps\Beatmap.cs" />
<Compile Include="Beatmaps\BeatmapSet.cs" /> <Compile Include="Beatmaps\BeatmapSet.cs" />
<Compile Include="Beatmaps\Metadata.cs" /> <Compile Include="Beatmaps\BeatmapMetadata.cs" />
<Compile Include="Beatmaps\Objects\HitObject.cs" /> <Compile Include="Beatmaps\Objects\HitObject.cs" />
<Compile Include="Beatmaps\Objects\Catch\CatchBaseHit.cs" /> <Compile Include="Beatmaps\Objects\Catch\CatchBaseHit.cs" />
<Compile Include="Beatmaps\Objects\Catch\Droplet.cs" /> <Compile Include="Beatmaps\Objects\Catch\Droplet.cs" />
@ -148,13 +163,20 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Users\User.cs" /> <Compile Include="Users\User.cs" />
<Compile Include="VolumeControl.cs" /> <Compile Include="VolumeControl.cs" />
<Compile Include="Database\BeatmapDatabase.cs" />
<Compile Include="Beatmaps\IO\ArchiveReader.cs" />
<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" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj"> <ProjectReference Include="$(SolutionDir)\osu-framework\osu.Framework\osu.Framework.csproj">
<Project>{c76bf5b3-985e-4d39-95fe-97c9c879b83a}</Project> <Project>{c76bf5b3-985e-4d39-95fe-97c9c879b83a}</Project>
<Name>osu.Framework</Name> <Name>osu.Framework</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj"> <ProjectReference Include="$(SolutionDir)\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj">
<Project>{d9a367c9-4c1a-489f-9b05-a0cea2b53b58}</Project> <Project>{d9a367c9-4c1a-489f-9b05-a0cea2b53b58}</Project>
<Name>osu.Game.Resources</Name> <Name>osu.Game.Resources</Name>
</ProjectReference> </ProjectReference>
@ -166,6 +188,12 @@
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<ItemGroup>
<Folder Include="Database\" />
<Folder Include="Beatmaps\Formats\" />
<Folder Include="Beatmaps\IO\" />
<Folder Include="Beatmaps\Events\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
@ -174,4 +202,7 @@
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
</Project> <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>

View File

@ -1,9 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>. Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
--> -->
<packages> <packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" /> <package id="DotNetZip" version="1.10.1" targetFramework="net45" />
<package id="ppy.OpenTK" version="1.1.2225.3" targetFramework="net45" /> <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
</packages> <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" />
</packages>

10
osu.sln
View File

@ -19,11 +19,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework.Desktop", "os
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Desktop.VisualTests", "osu.Desktop.VisualTests\osu.Desktop.VisualTests.csproj", "{69051C69-12AE-4E7D-A3E6-460D2E282312}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Desktop.VisualTests", "osu.Desktop.VisualTests\osu.Desktop.VisualTests.csproj", "{69051C69-12AE-4E7D-A3E6-460D2E282312}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Tests", "osu.Game.Tests\osu.Game.Tests.csproj", "{54377672-20B1-40AF-8087-5CF73BF3953A}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Deploy|Any CPU = Deploy|Any CPU Deploy|Any CPU = Deploy|Any CPU
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
Deploy|Any CPU = Deploy|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@ -56,6 +59,12 @@ Global
{69051C69-12AE-4E7D-A3E6-460D2E282312}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU {69051C69-12AE-4E7D-A3E6-460D2E282312}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
{69051C69-12AE-4E7D-A3E6-460D2E282312}.Release|Any CPU.ActiveCfg = Release|Any CPU {69051C69-12AE-4E7D-A3E6-460D2E282312}.Release|Any CPU.ActiveCfg = Release|Any CPU
{69051C69-12AE-4E7D-A3E6-460D2E282312}.Release|Any CPU.Build.0 = Release|Any CPU {69051C69-12AE-4E7D-A3E6-460D2E282312}.Release|Any CPU.Build.0 = Release|Any CPU
{54377672-20B1-40AF-8087-5CF73BF3953A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54377672-20B1-40AF-8087-5CF73BF3953A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54377672-20B1-40AF-8087-5CF73BF3953A}.Deploy|Any CPU.ActiveCfg = Release|Any CPU
{54377672-20B1-40AF-8087-5CF73BF3953A}.Deploy|Any CPU.Build.0 = Release|Any CPU
{54377672-20B1-40AF-8087-5CF73BF3953A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54377672-20B1-40AF-8087-5CF73BF3953A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -67,6 +76,7 @@ Global
{D9A367C9-4C1A-489F-9B05-A0CEA2B53B58} = {0D37A2AD-80A4-464F-A1DE-1560B70F1CE3} {D9A367C9-4C1A-489F-9B05-A0CEA2B53B58} = {0D37A2AD-80A4-464F-A1DE-1560B70F1CE3}
{65DC628F-A640-4111-AB35-3A5652BC1E17} = {7A75DFA2-DE65-4458-98AF-26AF96FFD6DC} {65DC628F-A640-4111-AB35-3A5652BC1E17} = {7A75DFA2-DE65-4458-98AF-26AF96FFD6DC}
{69051C69-12AE-4E7D-A3E6-460D2E282312} = {0D37A2AD-80A4-464F-A1DE-1560B70F1CE3} {69051C69-12AE-4E7D-A3E6-460D2E282312} = {0D37A2AD-80A4-464F-A1DE-1560B70F1CE3}
{54377672-20B1-40AF-8087-5CF73BF3953A} = {0D37A2AD-80A4-464F-A1DE-1560B70F1CE3}
EndGlobalSection EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0 Policies = $0