mirror of
https://github.com/ppy/osu.git
synced 2025-01-07 18:33:04 +08:00
Merge branch 'master' into online-beatmap-set-overlay
This commit is contained in:
commit
b83596b44d
@ -1 +1 @@
|
|||||||
Subproject commit e1352a8b0b5d1ba8acd9335a56c714d2ccc2f6a6
|
Subproject commit 5f3a7fe4d0537820a33b817a41623b4b22a3ec59
|
146
osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs
Normal file
146
osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Game.Audio;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Beatmaps.Formats
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class OsuLegacyDecoderTest
|
||||||
|
{
|
||||||
|
[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.BeatmapInfo.Metadata;
|
||||||
|
Assert.AreEqual(241526, meta.OnlineBeatmapSetID);
|
||||||
|
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 beatmapInfo = decoder.Decode(new StreamReader(stream)).BeatmapInfo;
|
||||||
|
Assert.AreEqual(0, beatmapInfo.AudioLeadIn);
|
||||||
|
Assert.AreEqual(false, beatmapInfo.Countdown);
|
||||||
|
Assert.AreEqual(0.7f, beatmapInfo.StackLeniency);
|
||||||
|
Assert.AreEqual(false, beatmapInfo.SpecialStyle);
|
||||||
|
Assert.IsTrue(beatmapInfo.RulesetID == 0);
|
||||||
|
Assert.AreEqual(false, beatmapInfo.LetterboxInBreaks);
|
||||||
|
Assert.AreEqual(false, beatmapInfo.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)).BeatmapInfo;
|
||||||
|
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.BeatmapInfo.Difficulty;
|
||||||
|
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 curveData = beatmap.HitObjects[0] as IHasCurve;
|
||||||
|
var positionData = beatmap.HitObjects[0] as IHasPosition;
|
||||||
|
|
||||||
|
Assert.IsNotNull(positionData);
|
||||||
|
Assert.IsNotNull(curveData);
|
||||||
|
Assert.AreEqual(new Vector2(192, 168), positionData.Position);
|
||||||
|
Assert.AreEqual(956, beatmap.HitObjects[0].StartTime);
|
||||||
|
Assert.IsTrue(beatmap.HitObjects[0].Samples.Any(s => s.Name == SampleInfo.HIT_NORMAL));
|
||||||
|
|
||||||
|
positionData = beatmap.HitObjects[1] as IHasPosition;
|
||||||
|
|
||||||
|
Assert.IsNotNull(positionData);
|
||||||
|
Assert.AreEqual(new Vector2(304, 56), positionData.Position);
|
||||||
|
Assert.AreEqual(1285, beatmap.HitObjects[1].StartTime);
|
||||||
|
Assert.IsTrue(beatmap.HitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
164
osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
Normal file
164
osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Game.IPC;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Beatmaps.IO
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class ImportBeatmapTest
|
||||||
|
{
|
||||||
|
private const string osz_path = @"../../../osu-resources/osu.Game.Resources/Beatmaps/241526 Soleily - Renatus.osz";
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestImportWhenClosed()
|
||||||
|
{
|
||||||
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
|
using (HeadlessGameHost host = new HeadlessGameHost())
|
||||||
|
{
|
||||||
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
|
var temp = prepareTempCopy(osz_path);
|
||||||
|
|
||||||
|
Assert.IsTrue(File.Exists(temp));
|
||||||
|
|
||||||
|
osu.Dependencies.Get<BeatmapManager>().Import(temp);
|
||||||
|
|
||||||
|
ensureLoaded(osu);
|
||||||
|
|
||||||
|
Assert.IsFalse(File.Exists(temp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestImportOverIPC()
|
||||||
|
{
|
||||||
|
using (HeadlessGameHost host = new HeadlessGameHost("host", true))
|
||||||
|
using (HeadlessGameHost client = new HeadlessGameHost("client", true))
|
||||||
|
{
|
||||||
|
Assert.IsTrue(host.IsPrimaryInstance);
|
||||||
|
Assert.IsTrue(!client.IsPrimaryInstance);
|
||||||
|
|
||||||
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
|
var temp = prepareTempCopy(osz_path);
|
||||||
|
|
||||||
|
Assert.IsTrue(File.Exists(temp));
|
||||||
|
|
||||||
|
var importer = new BeatmapIPCChannel(client);
|
||||||
|
if (!importer.ImportAsync(temp).Wait(10000))
|
||||||
|
Assert.Fail(@"IPC took too long to send");
|
||||||
|
|
||||||
|
ensureLoaded(osu);
|
||||||
|
|
||||||
|
Assert.IsFalse(File.Exists(temp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestImportWhenFileOpen()
|
||||||
|
{
|
||||||
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
|
using (HeadlessGameHost host = new HeadlessGameHost())
|
||||||
|
{
|
||||||
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
|
var temp = prepareTempCopy(osz_path);
|
||||||
|
|
||||||
|
Assert.IsTrue(File.Exists(temp), "Temporary file copy never substantiated");
|
||||||
|
|
||||||
|
using (File.OpenRead(temp))
|
||||||
|
osu.Dependencies.Get<BeatmapManager>().Import(temp);
|
||||||
|
|
||||||
|
ensureLoaded(osu);
|
||||||
|
|
||||||
|
File.Delete(temp);
|
||||||
|
|
||||||
|
Assert.IsFalse(File.Exists(temp), "We likely held a read lock on the file when we shouldn't");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string prepareTempCopy(string path)
|
||||||
|
{
|
||||||
|
var temp = Path.GetTempFileName();
|
||||||
|
return new FileInfo(path).CopyTo(temp, true).FullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OsuGameBase loadOsu(GameHost host)
|
||||||
|
{
|
||||||
|
host.Storage.DeleteDatabase(@"client");
|
||||||
|
|
||||||
|
var osu = new OsuGameBase();
|
||||||
|
Task.Run(() => host.Run(osu));
|
||||||
|
|
||||||
|
while (!osu.IsLoaded)
|
||||||
|
Thread.Sleep(1);
|
||||||
|
|
||||||
|
return osu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureLoaded(OsuGameBase osu, int timeout = 60000)
|
||||||
|
{
|
||||||
|
IEnumerable<BeatmapSetInfo> resultSets = null;
|
||||||
|
|
||||||
|
var store = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
|
Action waitAction = () =>
|
||||||
|
{
|
||||||
|
while (!(resultSets = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526)).Any())
|
||||||
|
Thread.Sleep(50);
|
||||||
|
};
|
||||||
|
|
||||||
|
Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout),
|
||||||
|
@"BeatmapSet did not import to the database in allocated time.");
|
||||||
|
|
||||||
|
//ensure we were stored to beatmap database backing...
|
||||||
|
|
||||||
|
Assert.IsTrue(resultSets.Count() == 1, $@"Incorrect result count found ({resultSets.Count()} but should be 1).");
|
||||||
|
|
||||||
|
IEnumerable<BeatmapInfo> resultBeatmaps = null;
|
||||||
|
|
||||||
|
//if we don't re-check here, the set will be inserted but the beatmaps won't be present yet.
|
||||||
|
waitAction = () =>
|
||||||
|
{
|
||||||
|
while ((resultBeatmaps = store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() != 12)
|
||||||
|
Thread.Sleep(50);
|
||||||
|
};
|
||||||
|
|
||||||
|
Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout),
|
||||||
|
@"Beatmaps did not import to the database in allocated time");
|
||||||
|
|
||||||
|
var set = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526).First();
|
||||||
|
|
||||||
|
Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count(),
|
||||||
|
$@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count}).");
|
||||||
|
|
||||||
|
foreach (BeatmapInfo b in resultBeatmaps)
|
||||||
|
Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID));
|
||||||
|
|
||||||
|
Assert.IsTrue(set.Beatmaps.Count > 0);
|
||||||
|
|
||||||
|
var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.Beatmap;
|
||||||
|
Assert.IsTrue(beatmap?.HitObjects.Count > 0);
|
||||||
|
|
||||||
|
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.Beatmap;
|
||||||
|
Assert.IsTrue(beatmap?.HitObjects.Count > 0);
|
||||||
|
|
||||||
|
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.Beatmap;
|
||||||
|
Assert.IsTrue(beatmap?.HitObjects.Count > 0);
|
||||||
|
|
||||||
|
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap;
|
||||||
|
Assert.IsTrue(beatmap?.HitObjects.Count > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
83
osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs
Normal file
83
osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.IO;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Beatmaps.IO
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class OszArchiveReaderTest
|
||||||
|
{
|
||||||
|
[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.Filenames.ToArray();
|
||||||
|
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);
|
||||||
|
|
||||||
|
BeatmapMetadata meta;
|
||||||
|
using (var stream = new StreamReader(reader.GetStream("Soleily - Renatus (Deif) [Platter].osu")))
|
||||||
|
meta = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;
|
||||||
|
|
||||||
|
Assert.AreEqual(241526, meta.OnlineBeatmapSetID);
|
||||||
|
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.GetStream("Soleily - Renatus (Deif) [Platter].osu")))
|
||||||
|
{
|
||||||
|
Assert.AreEqual("osu file format v13", stream.ReadLine()?.Trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
osu.Game.Tests/OpenTK.dll.config
Normal file
25
osu.Game.Tests/OpenTK.dll.config
Normal 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>
|
20
osu.Game.Tests/Resources/Resource.cs
Normal file
20
osu.Game.Tests/Resources/Resource.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Resources
|
||||||
|
{
|
||||||
|
public static class Resource
|
||||||
|
{
|
||||||
|
public static Stream OpenResource(string name)
|
||||||
|
{
|
||||||
|
var localPath = Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path));
|
||||||
|
|
||||||
|
return Assembly.GetExecutingAssembly().GetManifestResourceStream($@"osu.Game.Tests.Resources.{name}") ??
|
||||||
|
Assembly.LoadFrom(Path.Combine(localPath, @"osu.Game.Resources.dll")).GetManifestResourceStream($@"osu.Game.Resources.{name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1002
osu.Game.Tests/Resources/Soleily - Renatus (Gamu) [Insane].osu
Normal file
1002
osu.Game.Tests/Resources/Soleily - Renatus (Gamu) [Insane].osu
Normal file
File diff suppressed because it is too large
Load Diff
11
osu.Game.Tests/app.config
Normal file
11
osu.Game.Tests/app.config
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<runtime>
|
||||||
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
|
</configuration>
|
103
osu.Game.Tests/osu.Game.Tests.csproj
Normal file
103
osu.Game.Tests/osu.Game.Tests.csproj
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?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.6.1</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>
|
||||||
|
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||||
|
<LangVersion>6</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release</OutputPath>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<ConsolePause>false</ConsolePause>
|
||||||
|
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="nunit.framework, Version=3.8.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||||
|
<HintPath>$(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
||||||
|
<HintPath>$(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="SQLite.Net">
|
||||||
|
<HintPath>$(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="SQLite.Net.Platform.Win32">
|
||||||
|
<HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net4\SQLite.Net.Platform.Win32.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="SQLite.Net.Platform.Generic">
|
||||||
|
<HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\osu.licenseheader">
|
||||||
|
<Link>osu.licenseheader</Link>
|
||||||
|
</None>
|
||||||
|
<None Include="app.config" />
|
||||||
|
<None Include="packages.config" />
|
||||||
|
<None Include="OpenTK.dll.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
|
||||||
|
<Project>{c76bf5b3-985e-4d39-95fe-97c9c879b83a}</Project>
|
||||||
|
<Name>osu.Framework</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj">
|
||||||
|
<Project>{c92a607b-1fdd-4954-9f92-03ff547d9080}</Project>
|
||||||
|
<Name>osu.Game.Rulesets.Osu</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj">
|
||||||
|
<Project>{58f6c80c-1253-4a0e-a465-b8c85ebeadf3}</Project>
|
||||||
|
<Name>osu.Game.Rulesets.Catch</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj">
|
||||||
|
<Project>{48f4582b-7687-4621-9cbe-5c24197cb536}</Project>
|
||||||
|
<Name>osu.Game.Rulesets.Mania</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj">
|
||||||
|
<Project>{f167e17a-7de6-4af5-b920-a5112296c695}</Project>
|
||||||
|
<Name>osu.Game.Rulesets.Taiko</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<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>
|
||||||
|
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Beatmaps\IO\OszArchiveReaderTest.cs" />
|
||||||
|
<Compile Include="Beatmaps\IO\ImportBeatmapTest.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>
|
11
osu.Game.Tests/packages.config
Normal file
11
osu.Game.Tests/packages.config
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
-->
|
||||||
|
<packages>
|
||||||
|
<package id="NUnit" version="3.8.1" targetFramework="net461" />
|
||||||
|
<package id="OpenTK" version="3.0.0-git00009" targetFramework="net461" />
|
||||||
|
<package id="SQLite.Net.Core-PCL" version="3.1.1" targetFramework="net45" />
|
||||||
|
<package id="SQLite.Net-PCL" version="3.1.1" targetFramework="net45" />
|
||||||
|
</packages>
|
@ -54,6 +54,8 @@ namespace osu.Game.Configuration
|
|||||||
// Graphics
|
// Graphics
|
||||||
Set(OsuSetting.ShowFpsDisplay, false);
|
Set(OsuSetting.ShowFpsDisplay, false);
|
||||||
|
|
||||||
|
Set(OsuSetting.CursorRotation, true);
|
||||||
|
|
||||||
Set(OsuSetting.MenuParallax, true);
|
Set(OsuSetting.MenuParallax, true);
|
||||||
|
|
||||||
Set(OsuSetting.SnakingInSliders, true);
|
Set(OsuSetting.SnakingInSliders, true);
|
||||||
@ -96,6 +98,7 @@ namespace osu.Game.Configuration
|
|||||||
AudioOffset,
|
AudioOffset,
|
||||||
MenuMusic,
|
MenuMusic,
|
||||||
MenuVoice,
|
MenuVoice,
|
||||||
|
CursorRotation,
|
||||||
MenuParallax,
|
MenuParallax,
|
||||||
BeatmapDetailTab,
|
BeatmapDetailTab,
|
||||||
Username,
|
Username,
|
||||||
|
@ -20,13 +20,14 @@ namespace osu.Game.Graphics.Cursor
|
|||||||
{
|
{
|
||||||
protected override Drawable CreateCursor() => new Cursor();
|
protected override Drawable CreateCursor() => new Cursor();
|
||||||
|
|
||||||
|
private Bindable<bool> cursorRotate;
|
||||||
private bool dragging;
|
private bool dragging;
|
||||||
|
|
||||||
private bool startRotation;
|
private bool startRotation;
|
||||||
|
|
||||||
protected override bool OnMouseMove(InputState state)
|
protected override bool OnMouseMove(InputState state)
|
||||||
{
|
{
|
||||||
if (dragging)
|
if (cursorRotate && dragging)
|
||||||
{
|
{
|
||||||
Debug.Assert(state.Mouse.PositionMouseDown != null);
|
Debug.Assert(state.Mouse.PositionMouseDown != null);
|
||||||
|
|
||||||
@ -102,6 +103,12 @@ namespace osu.Game.Graphics.Cursor
|
|||||||
ActiveCursor.ScaleTo(0, 500, Easing.In);
|
ActiveCursor.ScaleTo(0, 500, Easing.In);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuConfigManager config)
|
||||||
|
{
|
||||||
|
cursorRotate = config.GetBindable<bool>(OsuSetting.CursorRotation);
|
||||||
|
}
|
||||||
|
|
||||||
public class Cursor : Container
|
public class Cursor : Container
|
||||||
{
|
{
|
||||||
private Container cursorContainer;
|
private Container cursorContainer;
|
||||||
|
@ -49,7 +49,7 @@ namespace osu.Game.IO.Legacy
|
|||||||
int len = ReadInt32();
|
int len = ReadInt32();
|
||||||
if (len > 0) return ReadBytes(len);
|
if (len > 0) return ReadBytes(len);
|
||||||
if (len < 0) return null;
|
if (len < 0) return null;
|
||||||
return new byte[0];
|
return Array.Empty<byte>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Reads a char array from the buffer, handling nulls and the array length. </summary>
|
/// <summary> Reads a char array from the buffer, handling nulls and the array length. </summary>
|
||||||
@ -58,7 +58,7 @@ namespace osu.Game.IO.Legacy
|
|||||||
int len = ReadInt32();
|
int len = ReadInt32();
|
||||||
if (len > 0) return ReadChars(len);
|
if (len > 0) return ReadChars(len);
|
||||||
if (len < 0) return null;
|
if (len < 0) return null;
|
||||||
return new char[0];
|
return Array.Empty<char>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Reads a DateTime from the buffer. </summary>
|
/// <summary> Reads a DateTime from the buffer. </summary>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// 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 System;
|
||||||
using osu.Framework.Extensions;
|
|
||||||
using osu.Framework.IO.Network;
|
using osu.Framework.IO.Network;
|
||||||
|
|
||||||
namespace osu.Game.Online.API
|
namespace osu.Game.Online.API
|
||||||
@ -70,13 +69,11 @@ namespace osu.Game.Online.API
|
|||||||
|
|
||||||
protected virtual string Uri => $@"{API.Endpoint}/api/v2/{Target}";
|
protected virtual string Uri => $@"{API.Endpoint}/api/v2/{Target}";
|
||||||
|
|
||||||
private double remainingTime => Math.Max(0, Timeout - (DateTime.Now.TotalMilliseconds() - (startTime ?? 0)));
|
private double remainingTime => Math.Max(0, Timeout - (DateTimeOffset.UtcNow - (startTime ?? DateTimeOffset.MinValue)).TotalMilliseconds);
|
||||||
|
|
||||||
public bool ExceededTimeout => remainingTime == 0;
|
public bool ExceededTimeout => remainingTime == 0;
|
||||||
|
|
||||||
private double? startTime;
|
private DateTimeOffset? startTime;
|
||||||
|
|
||||||
public double StartTime => startTime ?? -1;
|
|
||||||
|
|
||||||
protected APIAccess API;
|
protected APIAccess API;
|
||||||
protected WebRequest WebRequest;
|
protected WebRequest WebRequest;
|
||||||
@ -96,7 +93,7 @@ namespace osu.Game.Online.API
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (startTime == null)
|
if (startTime == null)
|
||||||
startTime = DateTime.Now.TotalMilliseconds();
|
startTime = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
if (remainingTime <= 0)
|
if (remainingTime <= 0)
|
||||||
throw new TimeoutException(@"API request timeout hit");
|
throw new TimeoutException(@"API request timeout hit");
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Extensions;
|
|
||||||
|
|
||||||
namespace osu.Game.Online.API
|
namespace osu.Game.Online.API
|
||||||
{
|
{
|
||||||
@ -22,12 +21,12 @@ namespace osu.Game.Online.API
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return AccessTokenExpiry - DateTime.Now.ToUnixTimestamp();
|
return AccessTokenExpiry - DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
AccessTokenExpiry = DateTime.Now.AddSeconds(value).ToUnixTimestamp();
|
AccessTokenExpiry = DateTimeOffset.Now.AddSeconds(value).ToUnixTimeSeconds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ namespace osu.Game.Online.API.Requests
|
|||||||
{
|
{
|
||||||
private readonly BeatmapInfo beatmap;
|
private readonly BeatmapInfo beatmap;
|
||||||
|
|
||||||
private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={beatmap.Path}";
|
private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={System.Uri.EscapeUriString(beatmap.Path)}";
|
||||||
|
|
||||||
public GetBeatmapDetailsRequest(BeatmapInfo beatmap)
|
public GetBeatmapDetailsRequest(BeatmapInfo beatmap)
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,7 @@ namespace osu.Game.Online.API.Requests
|
|||||||
req.Method = HttpMethod.POST;
|
req.Method = HttpMethod.POST;
|
||||||
req.AddParameter(@"target_type", message.TargetType.GetDescription());
|
req.AddParameter(@"target_type", message.TargetType.GetDescription());
|
||||||
req.AddParameter(@"target_id", message.TargetId.ToString());
|
req.AddParameter(@"target_id", message.TargetId.ToString());
|
||||||
|
req.AddParameter(@"is_action", message.IsAction.ToString().ToLower());
|
||||||
req.AddParameter(@"message", message.Content);
|
req.AddParameter(@"message", message.Content);
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
|
@ -1,25 +1,13 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 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 osu.Game.Users;
|
|
||||||
|
|
||||||
namespace osu.Game.Online.Chat
|
namespace osu.Game.Online.Chat
|
||||||
{
|
{
|
||||||
public class ErrorMessage : Message
|
public class ErrorMessage : InfoMessage
|
||||||
{
|
{
|
||||||
private static int errorId = -1;
|
public ErrorMessage(string message) : base(message)
|
||||||
|
|
||||||
public ErrorMessage(string message) : base(errorId--)
|
|
||||||
{
|
{
|
||||||
Timestamp = DateTimeOffset.Now;
|
Sender.Colour = @"ff0000";
|
||||||
Content = message;
|
|
||||||
|
|
||||||
Sender = new User
|
|
||||||
{
|
|
||||||
Username = @"system",
|
|
||||||
Colour = @"ff0000",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
25
osu.Game/Online/Chat/InfoMessage.cs
Normal file
25
osu.Game/Online/Chat/InfoMessage.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.Chat
|
||||||
|
{
|
||||||
|
public class InfoMessage : Message
|
||||||
|
{
|
||||||
|
private static int infoID = -1;
|
||||||
|
|
||||||
|
public InfoMessage(string message) : base(infoID--)
|
||||||
|
{
|
||||||
|
Timestamp = DateTimeOffset.Now;
|
||||||
|
Content = message;
|
||||||
|
|
||||||
|
Sender = new User
|
||||||
|
{
|
||||||
|
Username = @"system",
|
||||||
|
Colour = @"0000ff",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,9 @@ namespace osu.Game.Online.Chat
|
|||||||
[JsonProperty(@"target_id")]
|
[JsonProperty(@"target_id")]
|
||||||
public int TargetId;
|
public int TargetId;
|
||||||
|
|
||||||
|
[JsonProperty(@"is_action")]
|
||||||
|
public bool IsAction;
|
||||||
|
|
||||||
[JsonProperty(@"timestamp")]
|
[JsonProperty(@"timestamp")]
|
||||||
public DateTimeOffset Timestamp;
|
public DateTimeOffset Timestamp;
|
||||||
|
|
||||||
|
@ -82,6 +82,13 @@ namespace osu.Game
|
|||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
||||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||||
|
|
||||||
|
private SQLiteConnection createConnection()
|
||||||
|
{
|
||||||
|
var conn = Host.Storage.GetDatabase(@"client");
|
||||||
|
conn.BusyTimeout = new TimeSpan(TimeSpan.TicksPerSecond * 10);
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
private SQLiteConnection connection;
|
private SQLiteConnection connection;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -90,8 +97,7 @@ namespace osu.Game
|
|||||||
dependencies.Cache(this);
|
dependencies.Cache(this);
|
||||||
dependencies.Cache(LocalConfig);
|
dependencies.Cache(LocalConfig);
|
||||||
|
|
||||||
connection = Host.Storage.GetDatabase(@"client");
|
connection = createConnection();
|
||||||
|
|
||||||
connection.CreateTable<StoreVersion>();
|
connection.CreateTable<StoreVersion>();
|
||||||
|
|
||||||
dependencies.Cache(API = new APIAccess
|
dependencies.Cache(API = new APIAccess
|
||||||
|
@ -63,6 +63,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
|
|
||||||
private const float padding = 15;
|
private const float padding = 15;
|
||||||
private const float message_padding = 200;
|
private const float message_padding = 200;
|
||||||
|
private const float action_padding = 3;
|
||||||
private const float text_size = 20;
|
private const float text_size = 20;
|
||||||
|
|
||||||
private Color4 customUsernameColour;
|
private Color4 customUsernameColour;
|
||||||
@ -194,6 +195,8 @@ namespace osu.Game.Overlays.Chat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if (message.IsAction && senderHasBackground)
|
||||||
|
contentFlow.Colour = OsuColour.FromHex(message.Sender.Colour);
|
||||||
|
|
||||||
updateMessageContent();
|
updateMessageContent();
|
||||||
FinishTransforms(true);
|
FinishTransforms(true);
|
||||||
@ -206,7 +209,17 @@ namespace osu.Game.Overlays.Chat
|
|||||||
|
|
||||||
timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}";
|
timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}";
|
||||||
username.Text = $@"{message.Sender.Username}" + (senderHasBackground ? "" : ":");
|
username.Text = $@"{message.Sender.Username}" + (senderHasBackground ? "" : ":");
|
||||||
|
|
||||||
|
if (message.IsAction)
|
||||||
|
{
|
||||||
|
contentFlow.Clear();
|
||||||
|
contentFlow.AddText("[", sprite => sprite.Padding = new MarginPadding { Right = action_padding });
|
||||||
|
contentFlow.AddText(message.Content, sprite => sprite.Font = @"Exo2.0-MediumItalic");
|
||||||
|
contentFlow.AddText("]", sprite => sprite.Padding = new MarginPadding { Left = action_padding });
|
||||||
|
}
|
||||||
|
else
|
||||||
contentFlow.Text = message.Content;
|
contentFlow.Text = message.Content;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MessageSender : ClickableContainer, IHasContextMenu
|
private class MessageSender : ClickableContainer, IHasContextMenu
|
||||||
|
@ -465,7 +465,7 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
textbox.Text = string.Empty;
|
textbox.Text = string.Empty;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(postText))
|
if (string.IsNullOrWhiteSpace(postText))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var target = currentChannel;
|
var target = currentChannel;
|
||||||
@ -478,19 +478,45 @@ namespace osu.Game.Overlays
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isAction = false;
|
||||||
|
|
||||||
if (postText[0] == '/')
|
if (postText[0] == '/')
|
||||||
{
|
{
|
||||||
// TODO: handle commands
|
string[] parameters = postText.Substring(1).Split(new[] { ' ' }, 2);
|
||||||
target.AddNewMessages(new ErrorMessage("Chat commands are not supported yet!"));
|
string command = parameters[0];
|
||||||
|
string content = parameters.Length == 2 ? parameters[1] : string.Empty;
|
||||||
|
|
||||||
|
switch (command)
|
||||||
|
{
|
||||||
|
case "me":
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(content))
|
||||||
|
{
|
||||||
|
currentChannel.AddNewMessages(new ErrorMessage("Usage: /me [action]"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isAction = true;
|
||||||
|
postText = content;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "help":
|
||||||
|
currentChannel.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action]"));
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
currentChannel.AddNewMessages(new ErrorMessage($@"""/{command}"" is not supported! For a list of supported commands see /help"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var message = new LocalEchoMessage
|
var message = new LocalEchoMessage
|
||||||
{
|
{
|
||||||
Sender = api.LocalUser.Value,
|
Sender = api.LocalUser.Value,
|
||||||
Timestamp = DateTimeOffset.Now,
|
Timestamp = DateTimeOffset.Now,
|
||||||
TargetType = TargetType.Channel, //TODO: read this from channel
|
TargetType = TargetType.Channel, //TODO: read this from channel
|
||||||
TargetId = target.Id,
|
TargetId = target.Id,
|
||||||
|
IsAction = isAction,
|
||||||
Content = postText
|
Content = postText
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
if (mod == null)
|
if (mod == null)
|
||||||
{
|
{
|
||||||
Mods = new Mod[0];
|
Mods = Array.Empty<Mod>();
|
||||||
Alpha = 0;
|
Alpha = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1,10 +1,25 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 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.Framework.Allocation;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Graphics
|
namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||||
{
|
{
|
||||||
public class DetailSettings : SettingsSubsection
|
public class DetailSettings : SettingsSubsection
|
||||||
{
|
{
|
||||||
protected override string Header => "Detail Settings";
|
protected override string Header => "Detail Settings";
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuConfigManager config)
|
||||||
|
{
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new SettingsCheckbox
|
||||||
|
{
|
||||||
|
LabelText = "Rotate cursor when dragging",
|
||||||
|
Bindable = config.GetBindable<bool>(OsuSetting.CursorRotation)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,13 +121,14 @@ namespace osu.Game.Screens.Menu
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool rightward;
|
||||||
|
|
||||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||||
{
|
{
|
||||||
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||||
|
|
||||||
if (!IsHovered) return;
|
if (!IsHovered) return;
|
||||||
|
|
||||||
bool rightward = beatIndex % 2 == 1;
|
|
||||||
double duration = timingPoint.BeatLength / 2;
|
double duration = timingPoint.BeatLength / 2;
|
||||||
|
|
||||||
icon.RotateTo(rightward ? 10 : -10, duration * 2, Easing.InOutSine);
|
icon.RotateTo(rightward ? 10 : -10, duration * 2, Easing.InOutSine);
|
||||||
@ -139,6 +140,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
i => i.MoveToY(0, duration, Easing.In),
|
i => i.MoveToY(0, duration, Easing.In),
|
||||||
i => i.ScaleTo(new Vector2(1, 0.9f), duration, Easing.In)
|
i => i.ScaleTo(new Vector2(1, 0.9f), duration, Easing.In)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
rightward = !rightward;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnHover(InputState state)
|
protected override bool OnHover(InputState state)
|
||||||
@ -152,7 +155,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
double duration = TimeUntilNextBeat;
|
double duration = TimeUntilNextBeat;
|
||||||
|
|
||||||
icon.ClearTransforms();
|
icon.ClearTransforms();
|
||||||
icon.RotateTo(10, duration, Easing.InOutSine);
|
icon.RotateTo(rightward ? -10 : 10, duration, Easing.InOutSine);
|
||||||
icon.ScaleTo(new Vector2(1, 0.9f), duration, Easing.Out);
|
icon.ScaleTo(new Vector2(1, 0.9f), duration, Easing.Out);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// 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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
@ -58,6 +59,31 @@ namespace osu.Game.Screens.Select
|
|||||||
Action = action,
|
Action = action,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private readonly List<OverlayContainer> overlays = new List<OverlayContainer>();
|
||||||
|
|
||||||
|
/// <param name="text">Text on the button.</param>
|
||||||
|
/// <param name="colour">Colour of the button.</param>
|
||||||
|
/// <param name="hotkey">Hotkey of the button.</param>
|
||||||
|
/// <param name="overlay">The <see cref="OverlayContainer"/> to be toggled by this button.</param>
|
||||||
|
/// <param name="depth">
|
||||||
|
/// <para>Higher depth to be put on the left, and lower to be put on the right.</para>
|
||||||
|
/// <para>Notice this is different to <see cref="Options.BeatmapOptionsOverlay"/>!</para>
|
||||||
|
/// </param>
|
||||||
|
public void AddButton(string text, Color4 colour, OverlayContainer overlay, Key? hotkey = null, float depth = 0)
|
||||||
|
{
|
||||||
|
overlays.Add(overlay);
|
||||||
|
AddButton(text, colour, () =>
|
||||||
|
{
|
||||||
|
foreach (var o in overlays)
|
||||||
|
{
|
||||||
|
if (o == overlay)
|
||||||
|
o.ToggleVisibility();
|
||||||
|
else
|
||||||
|
o.Hide();
|
||||||
|
}
|
||||||
|
}, hotkey, depth);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateModeLight() => modeLight.FadeColour(buttons.FirstOrDefault(b => b.IsHovered)?.SelectedColour ?? Color4.Transparent, TRANSITION_LENGTH, Easing.OutQuint);
|
private void updateModeLight() => modeLight.FadeColour(buttons.FirstOrDefault(b => b.IsHovered)?.SelectedColour ?? Color4.Transparent, TRANSITION_LENGTH, Easing.OutQuint);
|
||||||
|
|
||||||
public Footer()
|
public Footer()
|
||||||
|
@ -45,7 +45,7 @@ namespace osu.Game.Screens.Select
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
Footer.AddButton(@"mods", colours.Yellow, modSelect.ToggleVisibility, Key.F1, float.MaxValue);
|
Footer.AddButton(@"mods", colours.Yellow, modSelect, Key.F1, float.MaxValue);
|
||||||
|
|
||||||
BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, colours.Purple, null, Key.Number1);
|
BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, colours.Purple, null, Key.Number1);
|
||||||
BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.fa_eraser, colours.Purple, null, Key.Number2);
|
BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.fa_eraser, colours.Purple, null, Key.Number2);
|
||||||
|
@ -164,7 +164,7 @@ namespace osu.Game.Screens.Select
|
|||||||
if (Footer != null)
|
if (Footer != null)
|
||||||
{
|
{
|
||||||
Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2);
|
Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2);
|
||||||
Footer.AddButton(@"options", colours.Blue, BeatmapOptions.ToggleVisibility, Key.F3);
|
Footer.AddButton(@"options", colours.Blue, BeatmapOptions, Key.F3);
|
||||||
|
|
||||||
BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, () => promptDelete(Beatmap.Value.BeatmapSetInfo), Key.Number4, float.MaxValue);
|
BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, () => promptDelete(Beatmap.Value.BeatmapSetInfo), Key.Number4, float.MaxValue);
|
||||||
}
|
}
|
||||||
|
@ -372,6 +372,7 @@
|
|||||||
<Compile Include="Online\API\Requests\PostMessageRequest.cs" />
|
<Compile Include="Online\API\Requests\PostMessageRequest.cs" />
|
||||||
<Compile Include="Online\Chat\Channel.cs" />
|
<Compile Include="Online\Chat\Channel.cs" />
|
||||||
<Compile Include="Online\Chat\ErrorMessage.cs" />
|
<Compile Include="Online\Chat\ErrorMessage.cs" />
|
||||||
|
<Compile Include="Online\Chat\InfoMessage.cs" />
|
||||||
<Compile Include="Online\Chat\LocalEchoMessage.cs" />
|
<Compile Include="Online\Chat\LocalEchoMessage.cs" />
|
||||||
<Compile Include="Online\Chat\Message.cs" />
|
<Compile Include="Online\Chat\Message.cs" />
|
||||||
<Compile Include="Online\Multiplayer\GameType.cs" />
|
<Compile Include="Online\Multiplayer\GameType.cs" />
|
||||||
|
8
osu.sln
8
osu.sln
@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Mania", "
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Desktop.Deploy", "osu.Desktop.Deploy\osu.Desktop.Deploy.csproj", "{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Desktop.Deploy", "osu.Desktop.Deploy\osu.Desktop.Deploy.csproj", "{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}"
|
||||||
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
|
||||||
@ -71,6 +73,12 @@ Global
|
|||||||
{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.VisualTests|Any CPU.ActiveCfg = Debug|Any CPU
|
{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.VisualTests|Any CPU.ActiveCfg = Debug|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}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{54377672-20B1-40AF-8087-5CF73BF3953A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{54377672-20B1-40AF-8087-5CF73BF3953A}.VisualTests|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{54377672-20B1-40AF-8087-5CF73BF3953A}.VisualTests|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
Loading…
Reference in New Issue
Block a user