mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 23:52:57 +08:00
Merge branch 'master' into fix-skip-button-clickability
This commit is contained in:
commit
ecbd0f7eff
@ -11,7 +11,7 @@
|
|||||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||||
<AndroidApplication>True</AndroidApplication>
|
<AndroidApplication>True</AndroidApplication>
|
||||||
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
||||||
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
|
||||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
@ -63,6 +63,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.702.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.702.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.704.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.711.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" package="ppy.osu.lazer" android:installLocation="auto" android:versionName="0.1.0">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" package="sh.ppy.osulazer" android:installLocation="auto" android:versionName="0.1.0">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
@ -14,6 +14,11 @@
|
|||||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||||
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
|
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<MandroidI18n>cjk;mideast;other;rare;west</MandroidI18n>
|
||||||
|
<AndroidDexTool>d8</AndroidDexTool>
|
||||||
|
<AndroidLinkTool>r8</AndroidLinkTool>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="OsuGameActivity.cs" />
|
<Compile Include="OsuGameActivity.cs" />
|
||||||
<Compile Include="OsuGameAndroid.cs" />
|
<Compile Include="OsuGameAndroid.cs" />
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Catch.Tests.Android" android:installLocation="auto">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Catch.Tests.Android" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
|
||||||
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!catch Test" />
|
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!catch Test" />
|
||||||
</manifest>
|
</manifest>
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Catch.Tests.iOS
|
|||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
UIApplication.Main(args, null, "AppDelegate");
|
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Mania.Tests.Android" android:installLocation="auto">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Mania.Tests.Android" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
|
||||||
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!mania Test" />
|
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!mania Test" />
|
||||||
</manifest>
|
</manifest>
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Mania.Tests.iOS
|
|||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
UIApplication.Main(args, null, "AppDelegate");
|
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Osu.Tests.Android" android:installLocation="auto">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Osu.Tests.Android" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
|
||||||
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!standard Test" />
|
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!standard Test" />
|
||||||
</manifest>
|
</manifest>
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Osu.Tests.iOS
|
|||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
UIApplication.Main(args, null, "AppDelegate");
|
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -13,13 +13,11 @@ using static osu.Game.Input.Handlers.ReplayInputHandler;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
public class OsuModRelax : ModRelax, IApplicableFailOverride, IUpdatableByPlayfield, IApplicableToDrawableRuleset<OsuHitObject>
|
public class OsuModRelax : ModRelax, IUpdatableByPlayfield, IApplicableToDrawableRuleset<OsuHitObject>
|
||||||
{
|
{
|
||||||
public override string Description => @"You don't need to click. Give your clicking/tapping fingers a break from the heat of things.";
|
public override string Description => @"You don't need to click. Give your clicking/tapping fingers a break from the heat of things.";
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
|
||||||
|
|
||||||
public bool AllowFail => false;
|
|
||||||
|
|
||||||
public void Update(Playfield playfield)
|
public void Update(Playfield playfield)
|
||||||
{
|
{
|
||||||
bool requiresHold = false;
|
bool requiresHold = false;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Taiko.Tests.Android" android:installLocation="auto">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Taiko.Tests.Android" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
|
||||||
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!taiko Test" />
|
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!taiko Test" />
|
||||||
</manifest>
|
</manifest>
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.iOS
|
|||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
UIApplication.Main(args, null, "AppDelegate");
|
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Tests.Android" android:installLocation="auto">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Tests.Android" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
|
||||||
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!visual Test" />
|
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!visual Test" />
|
||||||
</manifest>
|
</manifest>
|
@ -9,7 +9,7 @@ namespace osu.Game.Tests.iOS
|
|||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
UIApplication.Main(args, null, "AppDelegate");
|
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
@ -9,7 +10,7 @@ using osu.Game.Rulesets.Replays;
|
|||||||
namespace osu.Game.Tests.NonVisual
|
namespace osu.Game.Tests.NonVisual
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class FramedReplayinputHandlerTest
|
public class FramedReplayInputHandlerTest
|
||||||
{
|
{
|
||||||
private Replay replay;
|
private Replay replay;
|
||||||
private TestInputHandler handler;
|
private TestInputHandler handler;
|
||||||
@ -160,10 +161,7 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestRewindInsideImportantSection()
|
public void TestRewindInsideImportantSection()
|
||||||
{
|
{
|
||||||
// fast forward to important section
|
fastForwardToPoint(3000);
|
||||||
while (handler.SetFrameFromTime(3000) != null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
setTime(4000, 4000);
|
setTime(4000, 4000);
|
||||||
confirmCurrentFrame(4);
|
confirmCurrentFrame(4);
|
||||||
@ -205,10 +203,7 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestRewindOutOfImportantSection()
|
public void TestRewindOutOfImportantSection()
|
||||||
{
|
{
|
||||||
// fast forward to important section
|
fastForwardToPoint(3500);
|
||||||
while (handler.SetFrameFromTime(3500) != null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
confirmCurrentFrame(3);
|
confirmCurrentFrame(3);
|
||||||
confirmNextFrame(4);
|
confirmNextFrame(4);
|
||||||
@ -227,6 +222,15 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
confirmNextFrame(2);
|
confirmNextFrame(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fastForwardToPoint(double destination)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 1000; i++)
|
||||||
|
if (handler.SetFrameFromTime(destination) == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
throw new TimeoutException("Seek was never fulfilled");
|
||||||
|
}
|
||||||
|
|
||||||
private void setTime(double set, double? expect)
|
private void setTime(double set, double? expect)
|
||||||
{
|
{
|
||||||
Assert.AreEqual(expect, handler.SetFrameFromTime(set));
|
Assert.AreEqual(expect, handler.SetFrameFromTime(set));
|
||||||
@ -274,6 +278,7 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
public TestInputHandler(Replay replay)
|
public TestInputHandler(Replay replay)
|
||||||
: base(replay)
|
: base(replay)
|
||||||
{
|
{
|
||||||
|
FrameAccuratePlayback = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override double AllowedImportantTimeSpan => 1000;
|
protected override double AllowedImportantTimeSpan => 1000;
|
@ -9,6 +9,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
@ -16,12 +17,13 @@ using osu.Game.Rulesets.Scoring;
|
|||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens;
|
using osu.Game.Screens;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Screens.Play.PlayerSettings;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
public class TestScenePlayerLoader : ManualInputManagerTestScene
|
public class TestScenePlayerLoader : ManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
private PlayerLoader loader;
|
private TestPlayerLoader loader;
|
||||||
private OsuScreenStack stack;
|
private OsuScreenStack stack;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
@ -31,19 +33,29 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestBlockLoadViaMouseMovement()
|
||||||
|
{
|
||||||
|
AddStep("load dummy beatmap", () => stack.Push(loader = new TestPlayerLoader(() => new TestPlayer(false, false))));
|
||||||
|
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
|
||||||
|
AddRepeatStep("move mouse", () => InputManager.MoveMouseTo(loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft + (loader.VisualSettings.ScreenSpaceDrawQuad.BottomRight - loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft) * RNG.NextSingle()), 20);
|
||||||
|
AddAssert("loader still active", () => loader.IsCurrentScreen());
|
||||||
|
AddUntilStep("loads after idle", () => !loader.IsCurrentScreen());
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLoadContinuation()
|
public void TestLoadContinuation()
|
||||||
{
|
{
|
||||||
Player player = null;
|
Player player = null;
|
||||||
SlowLoadPlayer slowPlayer = null;
|
SlowLoadPlayer slowPlayer = null;
|
||||||
|
|
||||||
AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => player = new TestPlayer(false, false))));
|
AddStep("load dummy beatmap", () => stack.Push(loader = new TestPlayerLoader(() => player = new TestPlayer(false, false))));
|
||||||
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
|
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
|
||||||
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
|
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
|
||||||
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen());
|
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen());
|
||||||
AddStep("load slow dummy beatmap", () =>
|
AddStep("load slow dummy beatmap", () =>
|
||||||
{
|
{
|
||||||
stack.Push(loader = new PlayerLoader(() => slowPlayer = new SlowLoadPlayer(false, false)));
|
stack.Push(loader = new TestPlayerLoader(() => slowPlayer = new SlowLoadPlayer(false, false)));
|
||||||
Scheduler.AddDelayed(() => slowPlayer.AllowLoad.Set(), 5000);
|
Scheduler.AddDelayed(() => slowPlayer.AllowLoad.Set(), 5000);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -61,7 +73,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddStep("load player", () =>
|
AddStep("load player", () =>
|
||||||
{
|
{
|
||||||
Mods.Value = new[] { gameMod = new TestMod() };
|
Mods.Value = new[] { gameMod = new TestMod() };
|
||||||
stack.Push(loader = new PlayerLoader(() => player = new TestPlayer()));
|
stack.Push(loader = new TestPlayerLoader(() => player = new TestPlayer()));
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for loader to become current", () => loader.IsCurrentScreen());
|
AddUntilStep("wait for loader to become current", () => loader.IsCurrentScreen());
|
||||||
@ -85,6 +97,16 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddAssert("player mods applied", () => playerMod2.Applied);
|
AddAssert("player mods applied", () => playerMod2.Applied);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestPlayerLoader : PlayerLoader
|
||||||
|
{
|
||||||
|
public new VisualSettings VisualSettings => base.VisualSettings;
|
||||||
|
|
||||||
|
public TestPlayerLoader(Func<Player> createPlayer)
|
||||||
|
: base(createPlayer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class TestMod : Mod, IApplicableToScoreProcessor
|
private class TestMod : Mod, IApplicableToScoreProcessor
|
||||||
{
|
{
|
||||||
public override string Name => string.Empty;
|
public override string Name => string.Empty;
|
||||||
|
@ -108,6 +108,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
StarDifficulty = 9.99,
|
StarDifficulty = 9.99,
|
||||||
Version = @"TEST",
|
Version = @"TEST",
|
||||||
|
Length = 456000,
|
||||||
Ruleset = maniaRuleset,
|
Ruleset = maniaRuleset,
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
{
|
{
|
||||||
@ -118,7 +119,6 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
},
|
},
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
OnlineInfo = new BeatmapOnlineInfo
|
||||||
{
|
{
|
||||||
Length = 456000,
|
|
||||||
CircleCount = 111,
|
CircleCount = 111,
|
||||||
SliderCount = 12,
|
SliderCount = 12,
|
||||||
PlayCount = 222,
|
PlayCount = 222,
|
||||||
@ -181,6 +181,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
StarDifficulty = 5.67,
|
StarDifficulty = 5.67,
|
||||||
Version = @"ANOTHER TEST",
|
Version = @"ANOTHER TEST",
|
||||||
|
Length = 123000,
|
||||||
Ruleset = taikoRuleset,
|
Ruleset = taikoRuleset,
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
{
|
{
|
||||||
@ -191,7 +192,6 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
},
|
},
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
OnlineInfo = new BeatmapOnlineInfo
|
||||||
{
|
{
|
||||||
Length = 123000,
|
|
||||||
CircleCount = 123,
|
CircleCount = 123,
|
||||||
SliderCount = 45,
|
SliderCount = 45,
|
||||||
PlayCount = 567,
|
PlayCount = 567,
|
||||||
|
@ -24,6 +24,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
typeof(ChangelogListing),
|
typeof(ChangelogListing),
|
||||||
typeof(ChangelogSingleBuild),
|
typeof(ChangelogSingleBuild),
|
||||||
typeof(ChangelogBuild),
|
typeof(ChangelogBuild),
|
||||||
|
typeof(Comments),
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
});
|
});
|
||||||
|
|
||||||
channelTabControl.OnRequestLeave += channel => channelTabControl.RemoveChannel(channel);
|
channelTabControl.OnRequestLeave += channel => channelTabControl.RemoveChannel(channel);
|
||||||
channelTabControl.Current.ValueChanged += channel => currentText.Text = "Currently selected channel: " + channel.NewValue.ToString();
|
channelTabControl.Current.ValueChanged += channel => currentText.Text = "Currently selected channel: " + channel.NewValue;
|
||||||
|
|
||||||
AddStep("Add random private channel", addRandomPrivateChannel);
|
AddStep("Add random private channel", addRandomPrivateChannel);
|
||||||
AddAssert("There is only one channels", () => channelTabControl.Items.Count() == 2);
|
AddAssert("There is only one channels", () => channelTabControl.Items.Count() == 2);
|
||||||
|
@ -3,19 +3,18 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Overlays.BeatmapSet.Scores;
|
using osu.Game.Overlays.BeatmapSet.Scores;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Online
|
namespace osu.Game.Tests.Visual.Online
|
||||||
{
|
{
|
||||||
@ -30,11 +29,9 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
typeof(ScoreTableRowBackground),
|
typeof(ScoreTableRowBackground),
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly Box background;
|
|
||||||
|
|
||||||
public TestSceneScoresContainer()
|
public TestSceneScoresContainer()
|
||||||
{
|
{
|
||||||
ScoresContainer scoresContainer;
|
TestScoresContainer scoresContainer;
|
||||||
|
|
||||||
Child = new Container
|
Child = new Container
|
||||||
{
|
{
|
||||||
@ -44,108 +41,137 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Width = 0.8f,
|
Width = 0.8f,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
background = new Box { RelativeSizeAxes = Axes.Both },
|
new Box
|
||||||
scoresContainer = new ScoresContainer(),
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
},
|
||||||
|
scoresContainer = new TestScoresContainer(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var scores = new List<ScoreInfo>
|
var allScores = new APILegacyScores
|
||||||
{
|
{
|
||||||
new ScoreInfo
|
Scores = new List<APILegacyScoreInfo>
|
||||||
{
|
{
|
||||||
User = new User
|
new APILegacyScoreInfo
|
||||||
{
|
{
|
||||||
Id = 6602580,
|
User = new User
|
||||||
Username = @"waaiiru",
|
|
||||||
Country = new Country
|
|
||||||
{
|
{
|
||||||
FullName = @"Spain",
|
Id = 6602580,
|
||||||
FlagName = @"ES",
|
Username = @"waaiiru",
|
||||||
|
Country = new Country
|
||||||
|
{
|
||||||
|
FullName = @"Spain",
|
||||||
|
FlagName = @"ES",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
Mods = new Mod[]
|
||||||
Mods = new Mod[]
|
|
||||||
{
|
|
||||||
new OsuModDoubleTime(),
|
|
||||||
new OsuModHidden(),
|
|
||||||
new OsuModFlashlight(),
|
|
||||||
new OsuModHardRock(),
|
|
||||||
},
|
|
||||||
Rank = ScoreRank.XH,
|
|
||||||
PP = 200,
|
|
||||||
MaxCombo = 1234,
|
|
||||||
TotalScore = 1234567890,
|
|
||||||
Accuracy = 1,
|
|
||||||
},
|
|
||||||
new ScoreInfo
|
|
||||||
{
|
|
||||||
User = new User
|
|
||||||
{
|
|
||||||
Id = 4608074,
|
|
||||||
Username = @"Skycries",
|
|
||||||
Country = new Country
|
|
||||||
{
|
{
|
||||||
FullName = @"Brazil",
|
new OsuModDoubleTime(),
|
||||||
FlagName = @"BR",
|
new OsuModHidden(),
|
||||||
|
new OsuModFlashlight(),
|
||||||
|
new OsuModHardRock(),
|
||||||
},
|
},
|
||||||
|
Rank = ScoreRank.XH,
|
||||||
|
PP = 200,
|
||||||
|
MaxCombo = 1234,
|
||||||
|
TotalScore = 1234567890,
|
||||||
|
Accuracy = 1,
|
||||||
},
|
},
|
||||||
Mods = new Mod[]
|
new APILegacyScoreInfo
|
||||||
{
|
{
|
||||||
new OsuModDoubleTime(),
|
User = new User
|
||||||
new OsuModHidden(),
|
|
||||||
new OsuModFlashlight(),
|
|
||||||
},
|
|
||||||
Rank = ScoreRank.S,
|
|
||||||
PP = 190,
|
|
||||||
MaxCombo = 1234,
|
|
||||||
TotalScore = 1234789,
|
|
||||||
Accuracy = 0.9997,
|
|
||||||
},
|
|
||||||
new ScoreInfo
|
|
||||||
{
|
|
||||||
User = new User
|
|
||||||
{
|
|
||||||
Id = 1014222,
|
|
||||||
Username = @"eLy",
|
|
||||||
Country = new Country
|
|
||||||
{
|
{
|
||||||
FullName = @"Japan",
|
Id = 4608074,
|
||||||
FlagName = @"JP",
|
Username = @"Skycries",
|
||||||
|
Country = new Country
|
||||||
|
{
|
||||||
|
FullName = @"Brazil",
|
||||||
|
FlagName = @"BR",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
Mods = new Mod[]
|
||||||
Mods = new Mod[]
|
|
||||||
{
|
|
||||||
new OsuModDoubleTime(),
|
|
||||||
new OsuModHidden(),
|
|
||||||
},
|
|
||||||
Rank = ScoreRank.B,
|
|
||||||
PP = 180,
|
|
||||||
MaxCombo = 1234,
|
|
||||||
TotalScore = 12345678,
|
|
||||||
Accuracy = 0.9854,
|
|
||||||
},
|
|
||||||
new ScoreInfo
|
|
||||||
{
|
|
||||||
User = new User
|
|
||||||
{
|
|
||||||
Id = 1541390,
|
|
||||||
Username = @"Toukai",
|
|
||||||
Country = new Country
|
|
||||||
{
|
{
|
||||||
FullName = @"Canada",
|
new OsuModDoubleTime(),
|
||||||
FlagName = @"CA",
|
new OsuModHidden(),
|
||||||
|
new OsuModFlashlight(),
|
||||||
},
|
},
|
||||||
|
Rank = ScoreRank.S,
|
||||||
|
PP = 190,
|
||||||
|
MaxCombo = 1234,
|
||||||
|
TotalScore = 1234789,
|
||||||
|
Accuracy = 0.9997,
|
||||||
},
|
},
|
||||||
Mods = new Mod[]
|
new APILegacyScoreInfo
|
||||||
{
|
{
|
||||||
new OsuModDoubleTime(),
|
User = new User
|
||||||
|
{
|
||||||
|
Id = 1014222,
|
||||||
|
Username = @"eLy",
|
||||||
|
Country = new Country
|
||||||
|
{
|
||||||
|
FullName = @"Japan",
|
||||||
|
FlagName = @"JP",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Mods = new Mod[]
|
||||||
|
{
|
||||||
|
new OsuModDoubleTime(),
|
||||||
|
new OsuModHidden(),
|
||||||
|
},
|
||||||
|
Rank = ScoreRank.B,
|
||||||
|
PP = 180,
|
||||||
|
MaxCombo = 1234,
|
||||||
|
TotalScore = 12345678,
|
||||||
|
Accuracy = 0.9854,
|
||||||
},
|
},
|
||||||
Rank = ScoreRank.C,
|
new APILegacyScoreInfo
|
||||||
PP = 170,
|
{
|
||||||
MaxCombo = 1234,
|
User = new User
|
||||||
TotalScore = 1234567,
|
{
|
||||||
Accuracy = 0.8765,
|
Id = 1541390,
|
||||||
},
|
Username = @"Toukai",
|
||||||
new ScoreInfo
|
Country = new Country
|
||||||
|
{
|
||||||
|
FullName = @"Canada",
|
||||||
|
FlagName = @"CA",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Mods = new Mod[]
|
||||||
|
{
|
||||||
|
new OsuModDoubleTime(),
|
||||||
|
},
|
||||||
|
Rank = ScoreRank.C,
|
||||||
|
PP = 170,
|
||||||
|
MaxCombo = 1234,
|
||||||
|
TotalScore = 1234567,
|
||||||
|
Accuracy = 0.8765,
|
||||||
|
},
|
||||||
|
new APILegacyScoreInfo
|
||||||
|
{
|
||||||
|
User = new User
|
||||||
|
{
|
||||||
|
Id = 7151382,
|
||||||
|
Username = @"Mayuri Hana",
|
||||||
|
Country = new Country
|
||||||
|
{
|
||||||
|
FullName = @"Thailand",
|
||||||
|
FlagName = @"TH",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Rank = ScoreRank.D,
|
||||||
|
PP = 160,
|
||||||
|
MaxCombo = 1234,
|
||||||
|
TotalScore = 123456,
|
||||||
|
Accuracy = 0.6543,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var myBestScore = new APILegacyUserTopScoreInfo
|
||||||
|
{
|
||||||
|
Score = new APILegacyScoreInfo
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -163,9 +189,42 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
TotalScore = 123456,
|
TotalScore = 123456,
|
||||||
Accuracy = 0.6543,
|
Accuracy = 0.6543,
|
||||||
},
|
},
|
||||||
|
Position = 1337,
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var s in scores)
|
var oneScore = new APILegacyScores
|
||||||
|
{
|
||||||
|
Scores = new List<APILegacyScoreInfo>
|
||||||
|
{
|
||||||
|
new APILegacyScoreInfo
|
||||||
|
{
|
||||||
|
User = new User
|
||||||
|
{
|
||||||
|
Id = 6602580,
|
||||||
|
Username = @"waaiiru",
|
||||||
|
Country = new Country
|
||||||
|
{
|
||||||
|
FullName = @"Spain",
|
||||||
|
FlagName = @"ES",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Mods = new Mod[]
|
||||||
|
{
|
||||||
|
new OsuModDoubleTime(),
|
||||||
|
new OsuModHidden(),
|
||||||
|
new OsuModFlashlight(),
|
||||||
|
new OsuModHardRock(),
|
||||||
|
},
|
||||||
|
Rank = ScoreRank.XH,
|
||||||
|
PP = 200,
|
||||||
|
MaxCombo = 1234,
|
||||||
|
TotalScore = 1234567890,
|
||||||
|
Accuracy = 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var s in allScores.Scores)
|
||||||
{
|
{
|
||||||
s.Statistics.Add(HitResult.Great, RNG.Next(2000));
|
s.Statistics.Add(HitResult.Great, RNG.Next(2000));
|
||||||
s.Statistics.Add(HitResult.Good, RNG.Next(2000));
|
s.Statistics.Add(HitResult.Good, RNG.Next(2000));
|
||||||
@ -173,15 +232,26 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
s.Statistics.Add(HitResult.Miss, RNG.Next(2000));
|
s.Statistics.Add(HitResult.Miss, RNG.Next(2000));
|
||||||
}
|
}
|
||||||
|
|
||||||
AddStep("Load all scores", () => scoresContainer.Scores = scores);
|
AddStep("Load all scores", () =>
|
||||||
|
{
|
||||||
|
allScores.UserScore = null;
|
||||||
|
scoresContainer.Scores = allScores;
|
||||||
|
});
|
||||||
AddStep("Load null scores", () => scoresContainer.Scores = null);
|
AddStep("Load null scores", () => scoresContainer.Scores = null);
|
||||||
AddStep("Load only one score", () => scoresContainer.Scores = new[] { scores.First() });
|
AddStep("Load only one score", () => scoresContainer.Scores = oneScore);
|
||||||
|
AddStep("Load scores with my best", () =>
|
||||||
|
{
|
||||||
|
allScores.UserScore = myBestScore;
|
||||||
|
scoresContainer.Scores = allScores;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
private class TestScoresContainer : ScoresContainer
|
||||||
private void load(OsuColour colours)
|
|
||||||
{
|
{
|
||||||
background.Colour = colours.Gray2;
|
public new APILegacyScores Scores
|
||||||
|
{
|
||||||
|
set => base.Scores = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Online.Leaderboards;
|
using osu.Game.Online.Leaderboards;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
using osu.Game.Screens.Select.Leaderboards;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
@ -27,8 +24,6 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
typeof(RetrievalFailurePlaceholder),
|
typeof(RetrievalFailurePlaceholder),
|
||||||
};
|
};
|
||||||
|
|
||||||
private RulesetStore rulesets;
|
|
||||||
|
|
||||||
private readonly FailableLeaderboard leaderboard;
|
private readonly FailableLeaderboard leaderboard;
|
||||||
|
|
||||||
public TestSceneLeaderboard()
|
public TestSceneLeaderboard()
|
||||||
@ -47,13 +42,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
AddStep(@"No supporter", () => leaderboard.SetRetrievalState(PlaceholderState.NotSupporter));
|
AddStep(@"No supporter", () => leaderboard.SetRetrievalState(PlaceholderState.NotSupporter));
|
||||||
AddStep(@"Not logged in", () => leaderboard.SetRetrievalState(PlaceholderState.NotLoggedIn));
|
AddStep(@"Not logged in", () => leaderboard.SetRetrievalState(PlaceholderState.NotLoggedIn));
|
||||||
AddStep(@"Unavailable", () => leaderboard.SetRetrievalState(PlaceholderState.Unavailable));
|
AddStep(@"Unavailable", () => leaderboard.SetRetrievalState(PlaceholderState.Unavailable));
|
||||||
AddStep(@"Real beatmap", realBeatmap);
|
foreach (BeatmapSetOnlineStatus status in Enum.GetValues(typeof(BeatmapSetOnlineStatus)))
|
||||||
}
|
AddStep($"{status} beatmap", () => showBeatmapWithStatus(status));
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(RulesetStore rulesets)
|
|
||||||
{
|
|
||||||
this.rulesets = rulesets;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void newScores()
|
private void newScores()
|
||||||
@ -245,34 +235,12 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
leaderboard.Scores = scores;
|
leaderboard.Scores = scores;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void realBeatmap()
|
private void showBeatmapWithStatus(BeatmapSetOnlineStatus status)
|
||||||
{
|
{
|
||||||
leaderboard.Beatmap = new BeatmapInfo
|
leaderboard.Beatmap = new BeatmapInfo
|
||||||
{
|
{
|
||||||
StarDifficulty = 1.36,
|
|
||||||
Version = @"BASIC",
|
|
||||||
OnlineBeatmapID = 1113057,
|
OnlineBeatmapID = 1113057,
|
||||||
Ruleset = rulesets.GetRuleset(0),
|
Status = status,
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
|
||||||
{
|
|
||||||
CircleSize = 4,
|
|
||||||
DrainRate = 6.5f,
|
|
||||||
OverallDifficulty = 6.5f,
|
|
||||||
ApproachRate = 5,
|
|
||||||
},
|
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
|
||||||
{
|
|
||||||
Length = 115000,
|
|
||||||
CircleCount = 265,
|
|
||||||
SliderCount = 71,
|
|
||||||
PlayCount = 47906,
|
|
||||||
PassCount = 19899,
|
|
||||||
},
|
|
||||||
Metrics = new BeatmapMetrics
|
|
||||||
{
|
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(),
|
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,9 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; });
|
AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; });
|
||||||
AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; });
|
AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; });
|
||||||
AddStep(@"Sort by Author", delegate { songSelect.FilterControl.Sort = SortMode.Author; });
|
AddStep(@"Sort by Author", delegate { songSelect.FilterControl.Sort = SortMode.Author; });
|
||||||
|
AddStep(@"Sort by DateAdded", delegate { songSelect.FilterControl.Sort = SortMode.DateAdded; });
|
||||||
|
AddStep(@"Sort by BPM", delegate { songSelect.FilterControl.Sort = SortMode.BPM; });
|
||||||
|
AddStep(@"Sort by Length", delegate { songSelect.FilterControl.Sort = SortMode.Length; });
|
||||||
AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; });
|
AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,16 +268,21 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
int beatmapId = setId * 10 + i;
|
int beatmapId = setId * 10 + i;
|
||||||
|
|
||||||
|
int length = RNG.Next(30000, 200000);
|
||||||
|
double bpm = RNG.NextSingle(80, 200);
|
||||||
|
|
||||||
beatmaps.Add(new BeatmapInfo
|
beatmaps.Add(new BeatmapInfo
|
||||||
{
|
{
|
||||||
Ruleset = getRuleset(),
|
Ruleset = getRuleset(),
|
||||||
OnlineBeatmapID = beatmapId,
|
OnlineBeatmapID = beatmapId,
|
||||||
Path = "normal.osu",
|
Path = "normal.osu",
|
||||||
Version = $"{beatmapId}",
|
Version = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})",
|
||||||
|
Length = length,
|
||||||
|
BPM = bpm,
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
{
|
{
|
||||||
OverallDifficulty = 3.5f,
|
OverallDifficulty = 3.5f,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,10 +294,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
// Create random metadata, then we can check if sorting works based on these
|
// Create random metadata, then we can check if sorting works based on these
|
||||||
Artist = "Some Artist " + RNG.Next(0, 9),
|
Artist = "Some Artist " + RNG.Next(0, 9),
|
||||||
Title = $"Some Song (set id {setId})",
|
Title = $"Some Song (set id {setId}, max bpm {beatmaps.Max(b => b.BPM):0.#})",
|
||||||
AuthorString = "Some Guy " + RNG.Next(0, 9),
|
AuthorString = "Some Guy " + RNG.Next(0, 9),
|
||||||
},
|
},
|
||||||
Beatmaps = beatmaps
|
Beatmaps = beatmaps,
|
||||||
|
DateAdded = DateTimeOffset.UtcNow,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,6 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
public class TestSceneBackButton : OsuTestScene
|
public class TestSceneBackButton : OsuTestScene
|
||||||
{
|
{
|
||||||
private readonly BackButton button;
|
|
||||||
|
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
{
|
{
|
||||||
typeof(TwoLayerButton)
|
typeof(TwoLayerButton)
|
||||||
@ -23,6 +21,8 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
public TestSceneBackButton()
|
public TestSceneBackButton()
|
||||||
{
|
{
|
||||||
|
BackButton button;
|
||||||
|
|
||||||
Child = new Container
|
Child = new Container
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -40,11 +40,12 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Action = () => button.Hide(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
button.Action = () => button.Hide();
|
||||||
|
|
||||||
AddStep("show button", () => button.Show());
|
AddStep("show button", () => button.Show());
|
||||||
AddStep("hide button", () => button.Hide());
|
AddStep("hide button", () => button.Hide());
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.UserInterface
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
@ -23,11 +24,12 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
typeof(Button)
|
typeof(Button)
|
||||||
};
|
};
|
||||||
|
|
||||||
public TestSceneButtonSystem()
|
private OsuLogo logo;
|
||||||
{
|
private ButtonSystem buttons;
|
||||||
OsuLogo logo;
|
|
||||||
ButtonSystem buttons;
|
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp() => Schedule(() =>
|
||||||
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
@ -36,13 +38,47 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
buttons = new ButtonSystem(),
|
buttons = new ButtonSystem(),
|
||||||
logo = new OsuLogo { RelativePositionAxes = Axes.Both }
|
logo = new OsuLogo
|
||||||
|
{
|
||||||
|
RelativePositionAxes = Axes.Both,
|
||||||
|
Position = new Vector2(0.5f)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
buttons.SetOsuLogo(logo);
|
buttons.SetOsuLogo(logo);
|
||||||
|
});
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAllStates()
|
||||||
|
{
|
||||||
foreach (var s in Enum.GetValues(typeof(ButtonSystemState)).OfType<ButtonSystemState>().Skip(1))
|
foreach (var s in Enum.GetValues(typeof(ButtonSystemState)).OfType<ButtonSystemState>().Skip(1))
|
||||||
AddStep($"State to {s}", () => buttons.State = s);
|
AddStep($"State to {s}", () => buttons.State = s);
|
||||||
|
|
||||||
|
AddStep("Enter mode", performEnterMode);
|
||||||
|
|
||||||
|
AddStep("Return to menu", () =>
|
||||||
|
{
|
||||||
|
buttons.State = ButtonSystemState.Play;
|
||||||
|
buttons.FadeIn(MainMenu.FADE_IN_DURATION, Easing.OutQuint);
|
||||||
|
buttons.MoveTo(new Vector2(0), MainMenu.FADE_IN_DURATION, Easing.OutQuint);
|
||||||
|
logo.FadeColour(Color4.White, 100, Easing.OutQuint);
|
||||||
|
logo.FadeIn(100, Easing.OutQuint);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSmoothExit()
|
||||||
|
{
|
||||||
|
AddStep("Enter mode", performEnterMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performEnterMode()
|
||||||
|
{
|
||||||
|
buttons.State = ButtonSystemState.EnteringMode;
|
||||||
|
buttons.FadeOut(MainMenu.FADE_OUT_DURATION, Easing.InSine);
|
||||||
|
buttons.MoveTo(new Vector2(-800, 0), MainMenu.FADE_OUT_DURATION, Easing.InSine);
|
||||||
|
logo.FadeOut(300, Easing.InSine)
|
||||||
|
.ScaleTo(0.2f, 300, Easing.InSine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
breadcrumbs.Current.ValueChanged += screen => titleText.Text = $"Changed to {screen.NewValue.ToString()}";
|
breadcrumbs.Current.ValueChanged += screen => titleText.Text = $"Changed to {screen.NewValue}";
|
||||||
breadcrumbs.Current.TriggerChange();
|
breadcrumbs.Current.TriggerChange();
|
||||||
|
|
||||||
waitForCurrent();
|
waitForCurrent();
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
|
@ -159,7 +159,7 @@ namespace osu.Game.Tournament.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
var bpm = beatmap.BeatmapSet.OnlineInfo.BPM;
|
var bpm = beatmap.BeatmapSet.OnlineInfo.BPM;
|
||||||
var length = beatmap.OnlineInfo.Length;
|
var length = beatmap.Length;
|
||||||
string hardRockExtra = "";
|
string hardRockExtra = "";
|
||||||
string srExtra = "";
|
string srExtra = "";
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ namespace osu.Game.Tournament.Components
|
|||||||
|
|
||||||
panelContents.Children = new Drawable[]
|
panelContents.Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new DiffPiece(("Length", TimeSpan.FromSeconds(length).ToString(@"mm\:ss")))
|
new DiffPiece(("Length", TimeSpan.FromMilliseconds(length).ToString(@"mm\:ss")))
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
|
@ -51,6 +51,16 @@ namespace osu.Game.Beatmaps
|
|||||||
[NotMapped]
|
[NotMapped]
|
||||||
public BeatmapOnlineInfo OnlineInfo { get; set; }
|
public BeatmapOnlineInfo OnlineInfo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The playable length in milliseconds of this beatmap.
|
||||||
|
/// </summary>
|
||||||
|
public double Length { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The most common BPM of this beatmap.
|
||||||
|
/// </summary>
|
||||||
|
public double BPM { get; set; }
|
||||||
|
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
|
||||||
[JsonProperty("file_sha2")]
|
[JsonProperty("file_sha2")]
|
||||||
|
@ -23,6 +23,7 @@ using osu.Game.IO.Archives;
|
|||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
namespace osu.Game.Beatmaps
|
||||||
{
|
{
|
||||||
@ -82,6 +83,8 @@ namespace osu.Game.Beatmaps
|
|||||||
protected override ArchiveDownloadRequest<BeatmapSetInfo> CreateDownloadRequest(BeatmapSetInfo set, bool minimiseDownloadSize) =>
|
protected override ArchiveDownloadRequest<BeatmapSetInfo> CreateDownloadRequest(BeatmapSetInfo set, bool minimiseDownloadSize) =>
|
||||||
new DownloadBeatmapSetRequest(set, minimiseDownloadSize);
|
new DownloadBeatmapSetRequest(set, minimiseDownloadSize);
|
||||||
|
|
||||||
|
protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path)?.ToLowerInvariant() == ".osz";
|
||||||
|
|
||||||
protected override Task Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive, CancellationToken cancellationToken = default)
|
protected override Task Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (archive != null)
|
if (archive != null)
|
||||||
@ -176,20 +179,22 @@ namespace osu.Game.Beatmaps
|
|||||||
if (beatmapInfo?.BeatmapSet == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo)
|
if (beatmapInfo?.BeatmapSet == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo)
|
||||||
return DefaultBeatmap;
|
return DefaultBeatmap;
|
||||||
|
|
||||||
var cached = workingCache.FirstOrDefault(w => w.BeatmapInfo?.ID == beatmapInfo.ID);
|
lock (workingCache)
|
||||||
|
{
|
||||||
|
var working = workingCache.FirstOrDefault(w => w.BeatmapInfo?.ID == beatmapInfo.ID);
|
||||||
|
|
||||||
if (cached != null)
|
if (working == null)
|
||||||
return cached;
|
{
|
||||||
|
if (beatmapInfo.Metadata == null)
|
||||||
|
beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata;
|
||||||
|
|
||||||
if (beatmapInfo.Metadata == null)
|
workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store,
|
||||||
beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata;
|
new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager));
|
||||||
|
}
|
||||||
|
|
||||||
WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(Files.Store, new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager);
|
previous?.TransferTo(working);
|
||||||
|
return working;
|
||||||
previous?.TransferTo(working);
|
}
|
||||||
workingCache.Add(working);
|
|
||||||
|
|
||||||
return working;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -297,6 +302,8 @@ namespace osu.Game.Beatmaps
|
|||||||
beatmap.BeatmapInfo.Ruleset = ruleset;
|
beatmap.BeatmapInfo.Ruleset = ruleset;
|
||||||
// TODO: this should be done in a better place once we actually need to dynamically update it.
|
// TODO: this should be done in a better place once we actually need to dynamically update it.
|
||||||
beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating ?? 0;
|
beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating ?? 0;
|
||||||
|
beatmap.BeatmapInfo.Length = calculateLength(beatmap);
|
||||||
|
beatmap.BeatmapInfo.BPM = beatmap.ControlPointInfo.BPMMode;
|
||||||
|
|
||||||
beatmapInfos.Add(beatmap.BeatmapInfo);
|
beatmapInfos.Add(beatmap.BeatmapInfo);
|
||||||
}
|
}
|
||||||
@ -305,6 +312,19 @@ namespace osu.Game.Beatmaps
|
|||||||
return beatmapInfos;
|
return beatmapInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double calculateLength(IBeatmap b)
|
||||||
|
{
|
||||||
|
if (!b.HitObjects.Any())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var lastObject = b.HitObjects.Last();
|
||||||
|
|
||||||
|
double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime;
|
||||||
|
double startTime = b.HitObjects.First().StartTime;
|
||||||
|
|
||||||
|
return endTime - startTime;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A dummy WorkingBeatmap for the purpose of retrieving a beatmap for star difficulty calculation.
|
/// A dummy WorkingBeatmap for the purpose of retrieving a beatmap for star difficulty calculation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -8,11 +8,6 @@ namespace osu.Game.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class BeatmapOnlineInfo
|
public class BeatmapOnlineInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The length in milliseconds of this beatmap's song.
|
|
||||||
/// </summary>
|
|
||||||
public double Length { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of circles in this beatmap.
|
/// The amount of circles in this beatmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -35,8 +35,21 @@ namespace osu.Game.Beatmaps
|
|||||||
[NotMapped]
|
[NotMapped]
|
||||||
public BeatmapSetMetrics Metrics { get; set; }
|
public BeatmapSetMetrics Metrics { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum star difficulty of all beatmaps in this set.
|
||||||
|
/// </summary>
|
||||||
public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarDifficulty) ?? 0;
|
public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarDifficulty) ?? 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum playable length in milliseconds of all beatmaps in this set.
|
||||||
|
/// </summary>
|
||||||
|
public double MaxLength => Beatmaps?.Max(b => b.Length) ?? 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum BPM of all beatmaps in this set.
|
||||||
|
/// </summary>
|
||||||
|
public double MaxBPM => Beatmaps?.Max(b => b.BPM) ?? 0;
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public bool DeletePending { get; set; }
|
public bool DeletePending { get; set; }
|
||||||
|
|
||||||
|
@ -35,15 +35,15 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
protected override DelayedLoadWrapper CreateDelayedLoadWrapper(Func<Drawable> createContentFunc, double timeBeforeLoad)
|
protected override DelayedLoadWrapper CreateDelayedLoadWrapper(Func<Drawable> createContentFunc, double timeBeforeLoad)
|
||||||
=> new DelayedLoadUnloadWrapper(createContentFunc, timeBeforeLoad, UnloadDelay);
|
=> new DelayedLoadUnloadWrapper(createContentFunc, timeBeforeLoad, UnloadDelay);
|
||||||
|
|
||||||
|
protected override double TransformDuration => 400;
|
||||||
|
|
||||||
protected override Drawable CreateDrawable(BeatmapInfo model)
|
protected override Drawable CreateDrawable(BeatmapInfo model)
|
||||||
{
|
{
|
||||||
Drawable drawable = getDrawableForModel(model);
|
var drawable = getDrawableForModel(model);
|
||||||
|
|
||||||
drawable.RelativeSizeAxes = Axes.Both;
|
drawable.RelativeSizeAxes = Axes.Both;
|
||||||
drawable.Anchor = Anchor.Centre;
|
drawable.Anchor = Anchor.Centre;
|
||||||
drawable.Origin = Anchor.Centre;
|
drawable.Origin = Anchor.Centre;
|
||||||
drawable.FillMode = FillMode.Fill;
|
drawable.FillMode = FillMode.Fill;
|
||||||
drawable.OnLoadComplete += d => d.FadeInFromZero(400);
|
|
||||||
|
|
||||||
return drawable;
|
return drawable;
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,7 @@ namespace osu.Game.Configuration
|
|||||||
Set(OsuSetting.BlurLevel, 0, 0, 1, 0.01);
|
Set(OsuSetting.BlurLevel, 0, 0, 1, 0.01);
|
||||||
|
|
||||||
Set(OsuSetting.ShowInterface, true);
|
Set(OsuSetting.ShowInterface, true);
|
||||||
|
Set(OsuSetting.ShowHealthDisplayWhenCantFail, true);
|
||||||
Set(OsuSetting.KeyOverlay, false);
|
Set(OsuSetting.KeyOverlay, false);
|
||||||
|
|
||||||
Set(OsuSetting.FloatingComments, false);
|
Set(OsuSetting.FloatingComments, false);
|
||||||
@ -131,6 +132,7 @@ namespace osu.Game.Configuration
|
|||||||
KeyOverlay,
|
KeyOverlay,
|
||||||
FloatingComments,
|
FloatingComments,
|
||||||
ShowInterface,
|
ShowInterface,
|
||||||
|
ShowHealthDisplayWhenCantFail,
|
||||||
MouseDisableButtons,
|
MouseDisableButtons,
|
||||||
MouseDisableWheel,
|
MouseDisableWheel,
|
||||||
AudioOffset,
|
AudioOffset,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -114,7 +114,8 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
lock (imported)
|
lock (imported)
|
||||||
{
|
{
|
||||||
imported.Add(model);
|
if (model != null)
|
||||||
|
imported.Add(model);
|
||||||
current++;
|
current++;
|
||||||
|
|
||||||
notification.Text = $"Imported {current} of {paths.Length} {HumanisedModelName}s";
|
notification.Text = $"Imported {current} of {paths.Length} {HumanisedModelName}s";
|
||||||
@ -140,7 +141,7 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
notification.CompletionText = imported.Count == 1
|
notification.CompletionText = imported.Count == 1
|
||||||
? $"Imported {imported.First()}!"
|
? $"Imported {imported.First()}!"
|
||||||
: $"Imported {current} {HumanisedModelName}s!";
|
: $"Imported {imported.Count} {HumanisedModelName}s!";
|
||||||
|
|
||||||
if (imported.Count > 0 && PresentImport != null)
|
if (imported.Count > 0 && PresentImport != null)
|
||||||
{
|
{
|
||||||
@ -176,7 +177,7 @@ namespace osu.Game.Database
|
|||||||
// TODO: Add a check to prevent files from storage to be deleted.
|
// TODO: Add a check to prevent files from storage to be deleted.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (import != null && File.Exists(path))
|
if (import != null && File.Exists(path) && ShouldDeleteArchive(path))
|
||||||
File.Delete(path);
|
File.Delete(path);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -207,7 +208,7 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
model = CreateModel(archive);
|
model = CreateModel(archive);
|
||||||
|
|
||||||
if (model == null) return null;
|
if (model == null) return Task.FromResult<TModel>(null);
|
||||||
|
|
||||||
model.Hash = computeHash(archive);
|
model.Hash = computeHash(archive);
|
||||||
}
|
}
|
||||||
@ -498,6 +499,18 @@ namespace osu.Game.Database
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual string ImportFromStablePath => null;
|
protected virtual string ImportFromStablePath => null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Select paths to import from stable. Default implementation iterates all directories in <see cref="ImportFromStablePath"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual IEnumerable<string> GetStableImportPaths(Storage stableStoage) => stableStoage.GetDirectories(ImportFromStablePath);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this specified path should be removed after successful import.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path for consideration. May be a file or a directory.</param>
|
||||||
|
/// <returns>Whether to perform deletion.</returns>
|
||||||
|
protected virtual bool ShouldDeleteArchive(string path) => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future.
|
/// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -518,7 +531,7 @@ namespace osu.Game.Database
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.Run(async () => await Import(stable.GetDirectories(ImportFromStablePath).Select(f => stable.GetFullPath(f)).ToArray()));
|
return Task.Run(async () => await Import(GetStableImportPaths(GetStableStorage()).Select(f => stable.GetFullPath(f)).ToArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -41,6 +41,9 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
// required to initialise native SQLite libraries on some platforms.
|
// required to initialise native SQLite libraries on some platforms.
|
||||||
SQLitePCL.Batteries_V2.Init();
|
SQLitePCL.Batteries_V2.Init();
|
||||||
|
|
||||||
|
// https://github.com/aspnet/EntityFrameworkCore/issues/9994#issuecomment-508588678
|
||||||
|
SQLitePCL.raw.sqlite3_config(2 /*SQLITE_CONFIG_MULTITHREAD*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -37,6 +37,8 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
text.Colour = AccentColour;
|
text.Colour = AccentColour;
|
||||||
icon.Colour = AccentColour;
|
icon.Colour = AccentColour;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateFade();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,39 +50,6 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
private const float transition_length = 500;
|
private const float transition_length = 500;
|
||||||
|
|
||||||
private void fadeIn()
|
|
||||||
{
|
|
||||||
box.FadeIn(transition_length, Easing.OutQuint);
|
|
||||||
text.FadeColour(Color4.White, transition_length, Easing.OutQuint);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fadeOut()
|
|
||||||
{
|
|
||||||
box.FadeOut(transition_length, Easing.OutQuint);
|
|
||||||
text.FadeColour(AccentColour, transition_length, Easing.OutQuint);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
|
||||||
{
|
|
||||||
fadeIn();
|
|
||||||
return base.OnHover(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnHoverLost(HoverLostEvent e)
|
|
||||||
{
|
|
||||||
if (!Current.Value)
|
|
||||||
fadeOut();
|
|
||||||
|
|
||||||
base.OnHoverLost(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuColour colours)
|
|
||||||
{
|
|
||||||
if (accentColour == null)
|
|
||||||
AccentColour = colours.Blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OsuTabControlCheckbox()
|
public OsuTabControlCheckbox()
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both;
|
AutoSizeAxes = Axes.Both;
|
||||||
@ -115,19 +84,34 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Current.ValueChanged += selected =>
|
Current.ValueChanged += selected => { icon.Icon = selected.NewValue ? FontAwesome.Regular.CheckCircle : FontAwesome.Regular.Circle; };
|
||||||
{
|
}
|
||||||
if (selected.NewValue)
|
|
||||||
{
|
[BackgroundDependencyLoader]
|
||||||
fadeIn();
|
private void load(OsuColour colours)
|
||||||
icon.Icon = FontAwesome.Regular.CheckCircle;
|
{
|
||||||
}
|
if (accentColour == null)
|
||||||
else
|
AccentColour = colours.Blue;
|
||||||
{
|
}
|
||||||
fadeOut();
|
|
||||||
icon.Icon = FontAwesome.Regular.Circle;
|
protected override bool OnHover(HoverEvent e)
|
||||||
}
|
{
|
||||||
};
|
updateFade();
|
||||||
|
return base.OnHover(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
|
{
|
||||||
|
if (!Current.Value)
|
||||||
|
updateFade();
|
||||||
|
|
||||||
|
base.OnHoverLost(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFade()
|
||||||
|
{
|
||||||
|
box.FadeTo(IsHovered ? 1 : 0, transition_length, Easing.OutQuint);
|
||||||
|
text.FadeColour(IsHovered ? Color4.White : AccentColour, transition_length, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ namespace osu.Game.Input.Bindings
|
|||||||
new KeyBinding(InputKey.F4, GlobalAction.ToggleMute),
|
new KeyBinding(InputKey.F4, GlobalAction.ToggleMute),
|
||||||
|
|
||||||
new KeyBinding(InputKey.Escape, GlobalAction.Back),
|
new KeyBinding(InputKey.Escape, GlobalAction.Back),
|
||||||
new KeyBinding(InputKey.MouseButton1, GlobalAction.Back),
|
new KeyBinding(InputKey.ExtraMouseButton1, GlobalAction.Back),
|
||||||
|
|
||||||
new KeyBinding(InputKey.Space, GlobalAction.Select),
|
new KeyBinding(InputKey.Space, GlobalAction.Select),
|
||||||
new KeyBinding(InputKey.Enter, GlobalAction.Select),
|
new KeyBinding(InputKey.Enter, GlobalAction.Select),
|
||||||
|
504
osu.Game/Migrations/20190708070844_AddBPMAndLengthColumns.Designer.cs
generated
Normal file
504
osu.Game/Migrations/20190708070844_AddBPMAndLengthColumns.Designer.cs
generated
Normal file
@ -0,0 +1,504 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using osu.Game.Database;
|
||||||
|
|
||||||
|
namespace osu.Game.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(OsuDbContext))]
|
||||||
|
[Migration("20190708070844_AddBPMAndLengthColumns")]
|
||||||
|
partial class AddBPMAndLengthColumns
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<float>("ApproachRate");
|
||||||
|
|
||||||
|
b.Property<float>("CircleSize");
|
||||||
|
|
||||||
|
b.Property<float>("DrainRate");
|
||||||
|
|
||||||
|
b.Property<float>("OverallDifficulty");
|
||||||
|
|
||||||
|
b.Property<double>("SliderMultiplier");
|
||||||
|
|
||||||
|
b.Property<double>("SliderTickRate");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapDifficulty");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AudioLeadIn");
|
||||||
|
|
||||||
|
b.Property<double>("BPM");
|
||||||
|
|
||||||
|
b.Property<int>("BaseDifficultyID");
|
||||||
|
|
||||||
|
b.Property<int>("BeatDivisor");
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.Property<bool>("Countdown");
|
||||||
|
|
||||||
|
b.Property<double>("DistanceSpacing");
|
||||||
|
|
||||||
|
b.Property<int>("GridSize");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<bool>("Hidden");
|
||||||
|
|
||||||
|
b.Property<double>("Length");
|
||||||
|
|
||||||
|
b.Property<bool>("LetterboxInBreaks");
|
||||||
|
|
||||||
|
b.Property<string>("MD5Hash");
|
||||||
|
|
||||||
|
b.Property<int?>("MetadataID");
|
||||||
|
|
||||||
|
b.Property<int?>("OnlineBeatmapID");
|
||||||
|
|
||||||
|
b.Property<string>("Path");
|
||||||
|
|
||||||
|
b.Property<int>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<bool>("SpecialStyle");
|
||||||
|
|
||||||
|
b.Property<float>("StackLeniency");
|
||||||
|
|
||||||
|
b.Property<double>("StarDifficulty");
|
||||||
|
|
||||||
|
b.Property<int>("Status");
|
||||||
|
|
||||||
|
b.Property<string>("StoredBookmarks");
|
||||||
|
|
||||||
|
b.Property<double>("TimelineZoom");
|
||||||
|
|
||||||
|
b.Property<string>("Version");
|
||||||
|
|
||||||
|
b.Property<bool>("WidescreenStoryboard");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BaseDifficultyID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("Hash");
|
||||||
|
|
||||||
|
b.HasIndex("MD5Hash");
|
||||||
|
|
||||||
|
b.HasIndex("MetadataID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineBeatmapID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Artist");
|
||||||
|
|
||||||
|
b.Property<string>("ArtistUnicode");
|
||||||
|
|
||||||
|
b.Property<string>("AudioFile");
|
||||||
|
|
||||||
|
b.Property<string>("AuthorString")
|
||||||
|
.HasColumnName("Author");
|
||||||
|
|
||||||
|
b.Property<string>("BackgroundFile");
|
||||||
|
|
||||||
|
b.Property<int>("PreviewTime");
|
||||||
|
|
||||||
|
b.Property<string>("Source");
|
||||||
|
|
||||||
|
b.Property<string>("Tags");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("TitleUnicode");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapMetadata");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapSetFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("DateAdded");
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int?>("MetadataID");
|
||||||
|
|
||||||
|
b.Property<int?>("OnlineBeatmapSetID");
|
||||||
|
|
||||||
|
b.Property<bool>("Protected");
|
||||||
|
|
||||||
|
b.Property<int>("Status");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("DeletePending");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("MetadataID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineBeatmapSetID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("BeatmapSetInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.HasColumnName("Key");
|
||||||
|
|
||||||
|
b.Property<int?>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<int?>("SkinInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("StringValue")
|
||||||
|
.HasColumnName("Value");
|
||||||
|
|
||||||
|
b.Property<int?>("Variant");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("SkinInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID", "Variant");
|
||||||
|
|
||||||
|
b.ToTable("Settings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int>("ReferenceCount");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("ReferenceCount");
|
||||||
|
|
||||||
|
b.ToTable("FileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("IntAction")
|
||||||
|
.HasColumnName("Action");
|
||||||
|
|
||||||
|
b.Property<string>("KeysString")
|
||||||
|
.HasColumnName("Keys");
|
||||||
|
|
||||||
|
b.Property<int?>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<int?>("Variant");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("IntAction");
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID", "Variant");
|
||||||
|
|
||||||
|
b.ToTable("KeyBinding");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int?>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Available");
|
||||||
|
|
||||||
|
b.Property<string>("InstantiationInfo");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("ShortName");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("Available");
|
||||||
|
|
||||||
|
b.HasIndex("ShortName")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("RulesetInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<int?>("ScoreInfoID");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("ScoreInfoID");
|
||||||
|
|
||||||
|
b.ToTable("ScoreFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<double>("Accuracy")
|
||||||
|
.HasColumnType("DECIMAL(1,4)");
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapInfoID");
|
||||||
|
|
||||||
|
b.Property<int>("Combo");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Date");
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int>("MaxCombo");
|
||||||
|
|
||||||
|
b.Property<string>("ModsJson")
|
||||||
|
.HasColumnName("Mods");
|
||||||
|
|
||||||
|
b.Property<long?>("OnlineScoreID");
|
||||||
|
|
||||||
|
b.Property<double?>("PP");
|
||||||
|
|
||||||
|
b.Property<int>("Rank");
|
||||||
|
|
||||||
|
b.Property<int>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<string>("StatisticsJson")
|
||||||
|
.HasColumnName("Statistics");
|
||||||
|
|
||||||
|
b.Property<long>("TotalScore");
|
||||||
|
|
||||||
|
b.Property<long?>("UserID")
|
||||||
|
.HasColumnName("UserID");
|
||||||
|
|
||||||
|
b.Property<string>("UserString")
|
||||||
|
.HasColumnName("User");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineScoreID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID");
|
||||||
|
|
||||||
|
b.ToTable("ScoreInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<int>("SkinInfoID");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("SkinInfoID");
|
||||||
|
|
||||||
|
b.ToTable("SkinFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Creator");
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("DeletePending");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("SkinInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BaseDifficultyID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet")
|
||||||
|
.WithMany("Beatmaps")
|
||||||
|
.HasForeignKey("BeatmapSetInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
|
||||||
|
.WithMany("Beatmaps")
|
||||||
|
.HasForeignKey("MetadataID");
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RulesetID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("BeatmapSetInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
|
||||||
|
.WithMany("BeatmapSets")
|
||||||
|
.HasForeignKey("MetadataID");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Skinning.SkinInfo")
|
||||||
|
.WithMany("Settings")
|
||||||
|
.HasForeignKey("SkinInfoID");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Scoring.ScoreInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("ScoreInfoID");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapInfo", "Beatmap")
|
||||||
|
.WithMany("Scores")
|
||||||
|
.HasForeignKey("BeatmapInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RulesetID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Skinning.SkinInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("SkinInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
osu.Game/Migrations/20190708070844_AddBPMAndLengthColumns.cs
Normal file
33
osu.Game/Migrations/20190708070844_AddBPMAndLengthColumns.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace osu.Game.Migrations
|
||||||
|
{
|
||||||
|
public partial class AddBPMAndLengthColumns : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<double>(
|
||||||
|
name: "BPM",
|
||||||
|
table: "BeatmapInfo",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0.0);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<double>(
|
||||||
|
name: "Length",
|
||||||
|
table: "BeatmapInfo",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "BPM",
|
||||||
|
table: "BeatmapInfo");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Length",
|
||||||
|
table: "BeatmapInfo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -45,6 +45,8 @@ namespace osu.Game.Migrations
|
|||||||
|
|
||||||
b.Property<int>("AudioLeadIn");
|
b.Property<int>("AudioLeadIn");
|
||||||
|
|
||||||
|
b.Property<double>("BPM");
|
||||||
|
|
||||||
b.Property<int>("BaseDifficultyID");
|
b.Property<int>("BaseDifficultyID");
|
||||||
|
|
||||||
b.Property<int>("BeatDivisor");
|
b.Property<int>("BeatDivisor");
|
||||||
@ -61,6 +63,8 @@ namespace osu.Game.Migrations
|
|||||||
|
|
||||||
b.Property<bool>("Hidden");
|
b.Property<bool>("Hidden");
|
||||||
|
|
||||||
|
b.Property<double>("Length");
|
||||||
|
|
||||||
b.Property<bool>("LetterboxInBreaks");
|
b.Property<bool>("LetterboxInBreaks");
|
||||||
|
|
||||||
b.Property<string>("MD5Hash");
|
b.Property<string>("MD5Hash");
|
||||||
|
@ -5,8 +5,10 @@ using System;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
using osu.Game.Screens.Select.Leaderboards;
|
||||||
using osu.Framework.IO.Network;
|
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using System.Text;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
@ -15,8 +17,9 @@ namespace osu.Game.Online.API.Requests
|
|||||||
private readonly BeatmapInfo beatmap;
|
private readonly BeatmapInfo beatmap;
|
||||||
private readonly BeatmapLeaderboardScope scope;
|
private readonly BeatmapLeaderboardScope scope;
|
||||||
private readonly RulesetInfo ruleset;
|
private readonly RulesetInfo ruleset;
|
||||||
|
private readonly IEnumerable<Mod> mods;
|
||||||
|
|
||||||
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global)
|
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global, IEnumerable<Mod> mods = null)
|
||||||
{
|
{
|
||||||
if (!beatmap.OnlineBeatmapID.HasValue)
|
if (!beatmap.OnlineBeatmapID.HasValue)
|
||||||
throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}.");
|
throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}.");
|
||||||
@ -27,6 +30,7 @@ namespace osu.Game.Online.API.Requests
|
|||||||
this.beatmap = beatmap;
|
this.beatmap = beatmap;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.ruleset = ruleset ?? throw new ArgumentNullException(nameof(ruleset));
|
this.ruleset = ruleset ?? throw new ArgumentNullException(nameof(ruleset));
|
||||||
|
this.mods = mods ?? Array.Empty<Mod>();
|
||||||
|
|
||||||
Success += onSuccess;
|
Success += onSuccess;
|
||||||
}
|
}
|
||||||
@ -38,19 +42,29 @@ namespace osu.Game.Online.API.Requests
|
|||||||
score.Beatmap = beatmap;
|
score.Beatmap = beatmap;
|
||||||
score.Ruleset = ruleset;
|
score.Ruleset = ruleset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var userScore = r.UserScore;
|
||||||
|
|
||||||
|
if (userScore != null)
|
||||||
|
{
|
||||||
|
userScore.Score.Beatmap = beatmap;
|
||||||
|
userScore.Score.Ruleset = ruleset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override WebRequest CreateWebRequest()
|
protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores{createQueryParameters()}";
|
||||||
|
|
||||||
|
private string createQueryParameters()
|
||||||
{
|
{
|
||||||
var req = base.CreateWebRequest();
|
StringBuilder query = new StringBuilder(@"?");
|
||||||
|
|
||||||
req.Timeout = 30000;
|
query.Append($@"type={scope.ToString().ToLowerInvariant()}");
|
||||||
req.AddParameter(@"type", scope.ToString().ToLowerInvariant());
|
query.Append($@"&mode={ruleset.ShortName}");
|
||||||
req.AddParameter(@"mode", ruleset.ShortName);
|
|
||||||
|
|
||||||
return req;
|
foreach (var mod in mods)
|
||||||
|
query.Append($@"&mods[]={mod.Acronym}");
|
||||||
|
|
||||||
|
return query.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -71,6 +72,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
StarDifficulty = starDifficulty,
|
StarDifficulty = starDifficulty,
|
||||||
OnlineBeatmapID = OnlineBeatmapID,
|
OnlineBeatmapID = OnlineBeatmapID,
|
||||||
Version = version,
|
Version = version,
|
||||||
|
Length = TimeSpan.FromSeconds(length).TotalMilliseconds,
|
||||||
Status = Status,
|
Status = Status,
|
||||||
BeatmapSet = set,
|
BeatmapSet = set,
|
||||||
Metrics = metrics,
|
Metrics = metrics,
|
||||||
@ -85,7 +87,6 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
{
|
{
|
||||||
PlayCount = playCount,
|
PlayCount = playCount,
|
||||||
PassCount = passCount,
|
PassCount = passCount,
|
||||||
Length = length,
|
|
||||||
CircleCount = circleCount,
|
CircleCount = circleCount,
|
||||||
SliderCount = sliderCount,
|
SliderCount = sliderCount,
|
||||||
},
|
},
|
||||||
|
@ -33,6 +33,8 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty("versions")]
|
[JsonProperty("versions")]
|
||||||
public VersionNavigation Versions { get; set; }
|
public VersionNavigation Versions { get; set; }
|
||||||
|
|
||||||
|
public string Url => $"https://osu.ppy.sh/home/changelog/{UpdateStream.Name}/{Version}";
|
||||||
|
|
||||||
public class VersionNavigation
|
public class VersionNavigation
|
||||||
{
|
{
|
||||||
[JsonProperty("next")]
|
[JsonProperty("next")]
|
||||||
|
@ -10,5 +10,17 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
{
|
{
|
||||||
[JsonProperty(@"scores")]
|
[JsonProperty(@"scores")]
|
||||||
public List<APILegacyScoreInfo> Scores;
|
public List<APILegacyScoreInfo> Scores;
|
||||||
|
|
||||||
|
[JsonProperty(@"userScore")]
|
||||||
|
public APILegacyUserTopScoreInfo UserScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class APILegacyUserTopScoreInfo
|
||||||
|
{
|
||||||
|
[JsonProperty(@"position")]
|
||||||
|
public int Position;
|
||||||
|
|
||||||
|
[JsonProperty(@"score")]
|
||||||
|
public APILegacyScoreInfo Score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ using osu.Game.Online.API;
|
|||||||
namespace osu.Game.Online
|
namespace osu.Game.Online
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A component which tracks a beatmap through potential download/import/deletion.
|
/// A component which tracks a <see cref="TModel"/> through potential download/import/deletion.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class DownloadTrackingComposite<TModel, TModelManager> : CompositeDrawable
|
public abstract class DownloadTrackingComposite<TModel, TModelManager> : CompositeDrawable
|
||||||
where TModel : class, IEquatable<TModel>
|
where TModel : class, IEquatable<TModel>
|
||||||
@ -22,7 +22,7 @@ namespace osu.Game.Online
|
|||||||
private TModelManager manager;
|
private TModelManager manager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Holds the current download state of the beatmap, whether is has already been downloaded, is in progress, or is not downloaded.
|
/// Holds the current download state of the <see cref="TModel"/>, whether is has already been downloaded, is in progress, or is not downloaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly Bindable<DownloadState> State = new Bindable<DownloadState>();
|
protected readonly Bindable<DownloadState> State = new Bindable<DownloadState>();
|
||||||
|
|
||||||
|
@ -203,8 +203,13 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
|
|
||||||
public void APIStateChanged(IAPIProvider api, APIState state)
|
public void APIStateChanged(IAPIProvider api, APIState state)
|
||||||
{
|
{
|
||||||
if (state == APIState.Online)
|
switch (state)
|
||||||
UpdateScores();
|
{
|
||||||
|
case APIState.Online:
|
||||||
|
case APIState.Offline:
|
||||||
|
UpdateScores();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void UpdateScores()
|
protected void UpdateScores()
|
||||||
@ -231,12 +236,6 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
if (getScoresRequest == null)
|
if (getScoresRequest == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (api?.IsLoggedIn != true)
|
|
||||||
{
|
|
||||||
PlaceholderState = PlaceholderState.NotLoggedIn;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
getScoresRequest.Failure += e => Schedule(() =>
|
getScoresRequest.Failure += e => Schedule(() =>
|
||||||
{
|
{
|
||||||
if (e is OperationCanceledException)
|
if (e is OperationCanceledException)
|
||||||
|
@ -282,11 +282,9 @@ namespace osu.Game
|
|||||||
|
|
||||||
performFromMainMenu(() =>
|
performFromMainMenu(() =>
|
||||||
{
|
{
|
||||||
Ruleset.Value = databasedScoreInfo.Ruleset;
|
|
||||||
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap);
|
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap);
|
||||||
Mods.Value = databasedScoreInfo.Mods;
|
|
||||||
|
|
||||||
menuScreen.Push(new PlayerLoader(() => new ReplayPlayer(databasedScore)));
|
menuScreen.Push(new ReplayPlayerLoader(databasedScore));
|
||||||
}, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true);
|
}, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,6 +385,7 @@ namespace osu.Game
|
|||||||
BeatmapManager.PresentImport = items => PresentBeatmap(items.First());
|
BeatmapManager.PresentImport = items => PresentBeatmap(items.First());
|
||||||
|
|
||||||
ScoreManager.PostNotification = n => notifications?.Post(n);
|
ScoreManager.PostNotification = n => notifications?.Post(n);
|
||||||
|
ScoreManager.GetStableStorage = GetStorageForStableInstall;
|
||||||
ScoreManager.PresentImport = items => PresentScore(items.First());
|
ScoreManager.PresentImport = items => PresentScore(items.First());
|
||||||
|
|
||||||
Container logoContainer;
|
Container logoContainer;
|
||||||
|
@ -60,7 +60,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
length.Value = TimeSpan.FromSeconds(beatmap.OnlineInfo.Length).ToString(@"m\:ss");
|
length.Value = TimeSpan.FromMilliseconds(beatmap.Length).ToString(@"m\:ss");
|
||||||
circleCount.Value = beatmap.OnlineInfo.CircleCount.ToString();
|
circleCount.Value = beatmap.OnlineInfo.CircleCount.ToString();
|
||||||
sliderCount.Value = beatmap.OnlineInfo.SliderCount.ToString();
|
sliderCount.Value = beatmap.OnlineInfo.SliderCount.ToString();
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
private Color4 backgroundHoveredColour;
|
private Color4 backgroundHoveredColour;
|
||||||
|
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
private readonly TopScoreUserSection userSection;
|
|
||||||
private readonly TopScoreStatisticsSection statisticsSection;
|
|
||||||
|
|
||||||
public DrawableTopScore()
|
public DrawableTopScore(ScoreInfo score, int position = 1)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
@ -61,16 +59,19 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
{
|
{
|
||||||
new Drawable[]
|
new Drawable[]
|
||||||
{
|
{
|
||||||
userSection = new TopScoreUserSection
|
new TopScoreUserSection
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
|
Score = score,
|
||||||
|
ScorePosition = position,
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
statisticsSection = new TopScoreStatisticsSection
|
new TopScoreStatisticsSection
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreRight,
|
Anchor = Anchor.CentreRight,
|
||||||
Origin = Anchor.CentreRight,
|
Origin = Anchor.CentreRight,
|
||||||
|
Score = score,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -91,18 +92,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
background.Colour = backgroundIdleColour;
|
background.Colour = backgroundIdleColour;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the score to be displayed.
|
|
||||||
/// </summary>
|
|
||||||
public ScoreInfo Score
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
userSection.Score = value;
|
|
||||||
statisticsSection.Score = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
protected override bool OnHover(HoverEvent e)
|
||||||
{
|
{
|
||||||
background.FadeColour(backgroundHoveredColour, fade_duration, Easing.OutQuint);
|
background.FadeColour(backgroundHoveredColour, fade_duration, Easing.OutQuint);
|
||||||
|
@ -59,7 +59,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
Content = null;
|
Content = null;
|
||||||
backgroundFlow.Clear();
|
backgroundFlow.Clear();
|
||||||
|
|
||||||
if (value == null || !value.Any())
|
if (value?.Any() != true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < value.Count; i++)
|
for (int i = 0; i < value.Count; i++)
|
||||||
|
@ -5,15 +5,14 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osuTK;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osuTK;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Game.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||||
{
|
{
|
||||||
@ -24,18 +23,65 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
|
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
private readonly ScoreTable scoreTable;
|
private readonly ScoreTable scoreTable;
|
||||||
|
private readonly FillFlowContainer topScoresContainer;
|
||||||
private readonly DrawableTopScore topScore;
|
|
||||||
private readonly LoadingAnimation loadingAnimation;
|
private readonly LoadingAnimation loadingAnimation;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
|
private GetScoresRequest getScoresRequest;
|
||||||
|
|
||||||
|
private BeatmapInfo beatmap;
|
||||||
|
|
||||||
|
public BeatmapInfo Beatmap
|
||||||
|
{
|
||||||
|
get => beatmap;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (beatmap == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
beatmap = value;
|
||||||
|
|
||||||
|
getScores(beatmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected APILegacyScores Scores
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
loading = false;
|
||||||
|
|
||||||
|
topScoresContainer.Clear();
|
||||||
|
|
||||||
|
if (value?.Scores.Any() != true)
|
||||||
|
{
|
||||||
|
scoreTable.Scores = null;
|
||||||
|
scoreTable.Hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scoreTable.Scores = value.Scores;
|
||||||
|
scoreTable.Show();
|
||||||
|
|
||||||
|
var topScore = value.Scores.First();
|
||||||
|
var userScore = value.UserScore;
|
||||||
|
|
||||||
|
topScoresContainer.Add(new DrawableTopScore(topScore));
|
||||||
|
|
||||||
|
if (userScore != null && userScore.Score.OnlineScoreID != topScore.OnlineScoreID)
|
||||||
|
topScoresContainer.Add(new DrawableTopScore(userScore.Score, userScore.Position));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ScoresContainer()
|
public ScoresContainer()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
background = new Box
|
background = new Box
|
||||||
@ -54,7 +100,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
Margin = new MarginPadding { Vertical = spacing },
|
Margin = new MarginPadding { Vertical = spacing },
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
topScore = new DrawableTopScore(),
|
topScoresContainer = new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, 5),
|
||||||
|
},
|
||||||
scoreTable = new ScoreTable
|
scoreTable = new ScoreTable
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
@ -65,7 +117,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
loadingAnimation = new LoadingAnimation
|
loadingAnimation = new LoadingAnimation
|
||||||
{
|
{
|
||||||
Alpha = 0,
|
Alpha = 0,
|
||||||
Margin = new MarginPadding(20)
|
Margin = new MarginPadding(20),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -74,7 +126,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
background.Colour = colours.Gray2;
|
background.Colour = colours.Gray2;
|
||||||
updateDisplay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool loading
|
private bool loading
|
||||||
@ -82,62 +133,23 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
set => loadingAnimation.FadeTo(value ? 1 : 0, fade_duration);
|
set => loadingAnimation.FadeTo(value ? 1 : 0, fade_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GetScoresRequest getScoresRequest;
|
private void getScores(BeatmapInfo beatmap)
|
||||||
private IReadOnlyList<ScoreInfo> scores;
|
|
||||||
|
|
||||||
public IReadOnlyList<ScoreInfo> Scores
|
|
||||||
{
|
|
||||||
get => scores;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
getScoresRequest?.Cancel();
|
|
||||||
scores = value;
|
|
||||||
|
|
||||||
updateDisplay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private BeatmapInfo beatmap;
|
|
||||||
|
|
||||||
public BeatmapInfo Beatmap
|
|
||||||
{
|
|
||||||
get => beatmap;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
beatmap = value;
|
|
||||||
|
|
||||||
Scores = null;
|
|
||||||
|
|
||||||
if (beatmap?.OnlineBeatmapID.HasValue != true)
|
|
||||||
return;
|
|
||||||
|
|
||||||
loading = true;
|
|
||||||
|
|
||||||
getScoresRequest = new GetScoresRequest(beatmap, beatmap.Ruleset);
|
|
||||||
getScoresRequest.Success += r => Schedule(() => Scores = r.Scores);
|
|
||||||
api.Queue(getScoresRequest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateDisplay()
|
|
||||||
{
|
|
||||||
loading = false;
|
|
||||||
|
|
||||||
scoreTable.Scores = scores?.Count > 1 ? scores : new List<ScoreInfo>();
|
|
||||||
scoreTable.FadeTo(scores?.Count > 1 ? 1 : 0);
|
|
||||||
|
|
||||||
if (scores?.Any() == true)
|
|
||||||
{
|
|
||||||
topScore.Score = scores.FirstOrDefault();
|
|
||||||
topScore.Show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
topScore.Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
|
||||||
{
|
{
|
||||||
getScoresRequest?.Cancel();
|
getScoresRequest?.Cancel();
|
||||||
|
getScoresRequest = null;
|
||||||
|
|
||||||
|
Scores = null;
|
||||||
|
|
||||||
|
if (beatmap?.OnlineBeatmapID.HasValue != true)
|
||||||
|
{
|
||||||
|
loading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getScoresRequest = new GetScoresRequest(beatmap, beatmap.Ruleset);
|
||||||
|
getScoresRequest.Success += scores => Scores = scores;
|
||||||
|
api.Queue(getScoresRequest);
|
||||||
|
loading = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,19 +39,28 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
Spacing = new Vector2(10, 0),
|
Spacing = new Vector2(10, 0),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
rankText = new OsuSpriteText
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Text = "#1",
|
AutoSizeAxes = Axes.Both,
|
||||||
Font = OsuFont.GetFont(size: 30, weight: FontWeight.Bold, italics: true)
|
Direction = FillDirection.Vertical,
|
||||||
},
|
Children = new Drawable[]
|
||||||
rank = new UpdateableRank(ScoreRank.D)
|
{
|
||||||
{
|
rankText = new OsuSpriteText
|
||||||
Anchor = Anchor.Centre,
|
{
|
||||||
Origin = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Size = new Vector2(40),
|
Origin = Anchor.Centre,
|
||||||
FillMode = FillMode.Fit,
|
Font = OsuFont.GetFont(size: 24, weight: FontWeight.Bold, italics: true)
|
||||||
|
},
|
||||||
|
rank = new UpdateableRank(ScoreRank.D)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(40),
|
||||||
|
FillMode = FillMode.Fit,
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
avatar = new UpdateableAvatar(hideImmediately: true)
|
avatar = new UpdateableAvatar(hideImmediately: true)
|
||||||
{
|
{
|
||||||
@ -109,6 +118,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
rankText.Colour = colours.Yellow;
|
rankText.Colour = colours.Yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int ScorePosition
|
||||||
|
{
|
||||||
|
set => rankText.Text = $"#{value}";
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the score to be displayed.
|
/// Sets the score to be displayed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -21,12 +21,9 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
public class BeatmapSetOverlay : FullscreenOverlay
|
public class BeatmapSetOverlay : FullscreenOverlay
|
||||||
{
|
{
|
||||||
private const int fade_duration = 300;
|
|
||||||
|
|
||||||
public const float X_PADDING = 40;
|
public const float X_PADDING = 40;
|
||||||
public const float TOP_PADDING = 25;
|
public const float TOP_PADDING = 25;
|
||||||
public const float RIGHT_WIDTH = 275;
|
public const float RIGHT_WIDTH = 275;
|
||||||
|
|
||||||
protected readonly Header Header;
|
protected readonly Header Header;
|
||||||
|
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
@ -40,7 +37,7 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
OsuScrollContainer scroll;
|
OsuScrollContainer scroll;
|
||||||
Info info;
|
Info info;
|
||||||
ScoresContainer scores;
|
ScoresContainer scoreContainer;
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
@ -62,7 +59,7 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
Header = new Header(),
|
Header = new Header(),
|
||||||
info = new Info(),
|
info = new Info(),
|
||||||
scores = new ScoresContainer(),
|
scoreContainer = new ScoresContainer(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -74,7 +71,7 @@ namespace osu.Game.Overlays
|
|||||||
Header.Picker.Beatmap.ValueChanged += b =>
|
Header.Picker.Beatmap.ValueChanged += b =>
|
||||||
{
|
{
|
||||||
info.Beatmap = b.NewValue;
|
info.Beatmap = b.NewValue;
|
||||||
scores.Beatmap = b.NewValue;
|
scoreContainer.Beatmap = b.NewValue;
|
||||||
|
|
||||||
scroll.ScrollToStart();
|
scroll.ScrollToStart();
|
||||||
};
|
};
|
||||||
@ -101,6 +98,7 @@ namespace osu.Game.Overlays
|
|||||||
public void FetchAndShowBeatmap(int beatmapId)
|
public void FetchAndShowBeatmap(int beatmapId)
|
||||||
{
|
{
|
||||||
beatmapSet.Value = null;
|
beatmapSet.Value = null;
|
||||||
|
|
||||||
var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId);
|
var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId);
|
||||||
req.Success += res =>
|
req.Success += res =>
|
||||||
{
|
{
|
||||||
@ -108,15 +106,18 @@ namespace osu.Game.Overlays
|
|||||||
Header.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId);
|
Header.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId);
|
||||||
};
|
};
|
||||||
API.Queue(req);
|
API.Queue(req);
|
||||||
|
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FetchAndShowBeatmapSet(int beatmapSetId)
|
public void FetchAndShowBeatmapSet(int beatmapSetId)
|
||||||
{
|
{
|
||||||
beatmapSet.Value = null;
|
beatmapSet.Value = null;
|
||||||
|
|
||||||
var req = new GetBeatmapSetRequest(beatmapSetId);
|
var req = new GetBeatmapSetRequest(beatmapSetId);
|
||||||
req.Success += res => beatmapSet.Value = res.ToBeatmapSet(rulesets);
|
req.Success += res => beatmapSet.Value = res.ToBeatmapSet(rulesets);
|
||||||
API.Queue(req);
|
API.Queue(req);
|
||||||
|
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,11 @@ namespace osu.Game.Overlays.Changelog
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (build != null)
|
if (build != null)
|
||||||
Child = new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild };
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild },
|
||||||
|
new Comments(build)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChangelogBuildWithNavigation : ChangelogBuild
|
public class ChangelogBuildWithNavigation : ChangelogBuild
|
||||||
|
79
osu.Game/Overlays/Changelog/Comments.cs
Normal file
79
osu.Game/Overlays/Changelog/Comments.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Changelog
|
||||||
|
{
|
||||||
|
public class Comments : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly APIChangelogBuild build;
|
||||||
|
|
||||||
|
public Comments(APIChangelogBuild build)
|
||||||
|
{
|
||||||
|
this.build = build;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
|
Padding = new MarginPadding
|
||||||
|
{
|
||||||
|
Horizontal = 50,
|
||||||
|
Vertical = 20,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
LinkFlowContainer text;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Masking = true,
|
||||||
|
CornerRadius = 10,
|
||||||
|
Child = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = colours.GreyVioletDarker
|
||||||
|
},
|
||||||
|
},
|
||||||
|
text = new LinkFlowContainer(t =>
|
||||||
|
{
|
||||||
|
t.Colour = colours.PinkLighter;
|
||||||
|
t.Font = OsuFont.Default.With(size: 14);
|
||||||
|
})
|
||||||
|
{
|
||||||
|
Padding = new MarginPadding(20),
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
text.AddParagraph("Got feedback?", t =>
|
||||||
|
{
|
||||||
|
t.Colour = Color4.White;
|
||||||
|
t.Font = OsuFont.Default.With(italics: true, size: 20);
|
||||||
|
t.Padding = new MarginPadding { Bottom = 20 };
|
||||||
|
});
|
||||||
|
|
||||||
|
text.AddParagraph("We would love to hear what you think of this update! ");
|
||||||
|
text.AddIcon(FontAwesome.Regular.GrinHearts);
|
||||||
|
|
||||||
|
text.AddParagraph("Please visit the ");
|
||||||
|
text.AddLink("web version", $"{build.Url}#comments");
|
||||||
|
text.AddText(" of this changelog to leave any comments.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -55,6 +55,8 @@ namespace osu.Game.Overlays
|
|||||||
private Container dragContainer;
|
private Container dragContainer;
|
||||||
private Container playerContainer;
|
private Container playerContainer;
|
||||||
|
|
||||||
|
public bool IsUserPaused { get; private set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private Bindable<WorkingBeatmap> beatmap { get; set; }
|
private Bindable<WorkingBeatmap> beatmap { get; set; }
|
||||||
|
|
||||||
@ -157,7 +159,7 @@ namespace osu.Game.Overlays
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Scale = new Vector2(1.4f),
|
Scale = new Vector2(1.4f),
|
||||||
IconScale = new Vector2(1.4f),
|
IconScale = new Vector2(1.4f),
|
||||||
Action = play,
|
Action = togglePause,
|
||||||
Icon = FontAwesome.Regular.PlayCircle,
|
Icon = FontAwesome.Regular.PlayCircle,
|
||||||
},
|
},
|
||||||
nextButton = new MusicIconButton
|
nextButton = new MusicIconButton
|
||||||
@ -276,7 +278,7 @@ namespace osu.Game.Overlays
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void play()
|
private void togglePause()
|
||||||
{
|
{
|
||||||
var track = current?.Track;
|
var track = current?.Track;
|
||||||
|
|
||||||
@ -288,9 +290,15 @@ namespace osu.Game.Overlays
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (track.IsRunning)
|
if (track.IsRunning)
|
||||||
|
{
|
||||||
|
IsUserPaused = true;
|
||||||
track.Stop();
|
track.Stop();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
track.Start();
|
track.Start();
|
||||||
|
IsUserPaused = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prev()
|
private void prev()
|
||||||
|
@ -35,6 +35,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
Bindable = config.GetBindable<bool>(OsuSetting.ShowInterface)
|
Bindable = config.GetBindable<bool>(OsuSetting.ShowInterface)
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
|
{
|
||||||
|
LabelText = "Show health display even when you can't fail",
|
||||||
|
Bindable = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail),
|
||||||
|
},
|
||||||
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Always show key overlay",
|
LabelText = "Always show key overlay",
|
||||||
Bindable = config.GetBindable<bool>(OsuSetting.KeyOverlay)
|
Bindable = config.GetBindable<bool>(OsuSetting.KeyOverlay)
|
||||||
|
@ -7,6 +7,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Maintenance
|
namespace osu.Game.Overlays.Settings.Sections.Maintenance
|
||||||
@ -16,14 +17,16 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
|
|||||||
protected override string Header => "General";
|
protected override string Header => "General";
|
||||||
|
|
||||||
private TriangleButton importBeatmapsButton;
|
private TriangleButton importBeatmapsButton;
|
||||||
|
private TriangleButton importScoresButton;
|
||||||
private TriangleButton importSkinsButton;
|
private TriangleButton importSkinsButton;
|
||||||
private TriangleButton deleteSkinsButton;
|
|
||||||
private TriangleButton deleteBeatmapsButton;
|
private TriangleButton deleteBeatmapsButton;
|
||||||
|
private TriangleButton deleteScoresButton;
|
||||||
|
private TriangleButton deleteSkinsButton;
|
||||||
private TriangleButton restoreButton;
|
private TriangleButton restoreButton;
|
||||||
private TriangleButton undeleteButton;
|
private TriangleButton undeleteButton;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(BeatmapManager beatmaps, SkinManager skins, DialogOverlay dialogOverlay)
|
private void load(BeatmapManager beatmaps, ScoreManager scores, SkinManager skins, DialogOverlay dialogOverlay)
|
||||||
{
|
{
|
||||||
if (beatmaps.SupportsImportFromStable)
|
if (beatmaps.SupportsImportFromStable)
|
||||||
{
|
{
|
||||||
@ -51,6 +54,32 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (scores.SupportsImportFromStable)
|
||||||
|
{
|
||||||
|
Add(importScoresButton = new SettingsButton
|
||||||
|
{
|
||||||
|
Text = "Import scores from stable",
|
||||||
|
Action = () =>
|
||||||
|
{
|
||||||
|
importScoresButton.Enabled.Value = false;
|
||||||
|
scores.ImportFromStableAsync().ContinueWith(t => Schedule(() => importScoresButton.Enabled.Value = true));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Add(deleteScoresButton = new DangerousSettingsButton
|
||||||
|
{
|
||||||
|
Text = "Delete ALL scores",
|
||||||
|
Action = () =>
|
||||||
|
{
|
||||||
|
dialogOverlay?.Push(new DeleteAllBeatmapsDialog(() =>
|
||||||
|
{
|
||||||
|
deleteScoresButton.Enabled.Value = false;
|
||||||
|
Task.Run(() => scores.Delete(scores.GetAllUsableScores())).ContinueWith(t => Schedule(() => deleteScoresButton.Enabled.Value = true));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (skins.SupportsImportFromStable)
|
if (skins.SupportsImportFromStable)
|
||||||
{
|
{
|
||||||
Add(importSkinsButton = new SettingsButton
|
Add(importSkinsButton = new SettingsButton
|
||||||
|
18
osu.Game/Rulesets/Mods/IApplicableToHUD.cs
Normal file
18
osu.Game/Rulesets/Mods/IApplicableToHUD.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mods
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An interface for mods that apply changes to the <see cref="HUDOverlay"/>.
|
||||||
|
/// </summary>
|
||||||
|
public interface IApplicableToHUD : IApplicableMod
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provide a <see cref="HUDOverlay"/>. Called once on initialisation of a play instance.
|
||||||
|
/// </summary>
|
||||||
|
void ApplyToHUD(HUDOverlay overlay);
|
||||||
|
}
|
||||||
|
}
|
29
osu.Game/Rulesets/Mods/ModBlockFail.cs
Normal file
29
osu.Game/Rulesets/Mods/ModBlockFail.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mods
|
||||||
|
{
|
||||||
|
public abstract class ModBlockFail : Mod, IApplicableFailOverride, IApplicableToHUD, IReadFromConfig
|
||||||
|
{
|
||||||
|
private Bindable<bool> showHealthBar;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// We never fail, 'yo.
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowFail => false;
|
||||||
|
|
||||||
|
public void ReadFromConfig(OsuConfigManager config)
|
||||||
|
{
|
||||||
|
showHealthBar = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyToHUD(HUDOverlay overlay)
|
||||||
|
{
|
||||||
|
overlay.ShowHealthbar.BindTo(showHealthBar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ using osu.Game.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
public abstract class ModNoFail : Mod, IApplicableFailOverride
|
public abstract class ModNoFail : ModBlockFail
|
||||||
{
|
{
|
||||||
public override string Name => "No Fail";
|
public override string Name => "No Fail";
|
||||||
public override string Acronym => "NF";
|
public override string Acronym => "NF";
|
||||||
@ -17,10 +17,5 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override double ScoreMultiplier => 0.5;
|
public override double ScoreMultiplier => 0.5;
|
||||||
public override bool Ranked => true;
|
public override bool Ranked => true;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModAutoplay) };
|
public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModAutoplay) };
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// We never fail, 'yo.
|
|
||||||
/// </summary>
|
|
||||||
public bool AllowFail => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ using osu.Game.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
public abstract class ModRelax : Mod
|
public abstract class ModRelax : ModBlockFail
|
||||||
{
|
{
|
||||||
public override string Name => "Relax";
|
public override string Name => "Relax";
|
||||||
public override string Acronym => "RX";
|
public override string Acronym => "RX";
|
||||||
|
@ -84,7 +84,7 @@ namespace osu.Game.Rulesets.Replays
|
|||||||
/// When set, we will ensure frames executed by nested drawables are frame-accurate to replay data.
|
/// When set, we will ensure frames executed by nested drawables are frame-accurate to replay data.
|
||||||
/// Disabling this can make replay playback smoother (useful for autoplay, currently).
|
/// Disabling this can make replay playback smoother (useful for autoplay, currently).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool FrameAccuratePlayback = true;
|
public bool FrameAccuratePlayback = false;
|
||||||
|
|
||||||
protected bool HasFrames => Frames.Count > 0;
|
protected bool HasFrames => Frames.Count > 0;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -24,7 +25,7 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
protected override string[] HashableFileTypes => new[] { ".osr" };
|
protected override string[] HashableFileTypes => new[] { ".osr" };
|
||||||
|
|
||||||
protected override string ImportFromStablePath => "Replays";
|
protected override string ImportFromStablePath => Path.Combine("Data", "r");
|
||||||
|
|
||||||
private readonly RulesetStore rulesets;
|
private readonly RulesetStore rulesets;
|
||||||
private readonly Func<BeatmapManager> beatmaps;
|
private readonly Func<BeatmapManager> beatmaps;
|
||||||
@ -55,6 +56,9 @@ namespace osu.Game.Scoring
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<string> GetStableImportPaths(Storage stableStorage)
|
||||||
|
=> stableStorage.GetFiles(ImportFromStablePath).Where(p => HandledExtensions.Any(ext => Path.GetExtension(p)?.Equals(ext, StringComparison.InvariantCultureIgnoreCase) ?? false));
|
||||||
|
|
||||||
public Score GetScore(ScoreInfo score) => new LegacyDatabasedScore(score, rulesets, beatmaps(), Files.Store);
|
public Score GetScore(ScoreInfo score) => new LegacyDatabasedScore(score, rulesets, beatmaps(), Files.Store);
|
||||||
|
|
||||||
public List<ScoreInfo> GetAllUsableScores() => ModelStore.ConsumableItems.Where(s => !s.DeletePending).ToList();
|
public List<ScoreInfo> GetAllUsableScores() => ModelStore.ConsumableItems.Where(s => !s.DeletePending).ToList();
|
||||||
@ -65,6 +69,6 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
protected override ArchiveDownloadRequest<ScoreInfo> CreateDownloadRequest(ScoreInfo score, bool minimiseDownload) => new DownloadReplayRequest(score);
|
protected override ArchiveDownloadRequest<ScoreInfo> CreateDownloadRequest(ScoreInfo score, bool minimiseDownload) => new DownloadReplayRequest(score);
|
||||||
|
|
||||||
protected override bool CheckLocalAvailability(ScoreInfo model, IQueryable<ScoreInfo> items) => items.Any(s => s.OnlineScoreID == model.OnlineScoreID);
|
protected override bool CheckLocalAvailability(ScoreInfo model, IQueryable<ScoreInfo> items) => items.Any(s => s.OnlineScoreID == model.OnlineScoreID && s.Files.Any());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,30 +224,32 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
public override void OnResuming(IScreen last)
|
public override void OnResuming(IScreen last)
|
||||||
{
|
{
|
||||||
Beatmap.Value.Track?.Stop();
|
|
||||||
base.OnResuming(last);
|
base.OnResuming(last);
|
||||||
|
Beatmap.Value.Track?.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnEntering(IScreen last)
|
public override void OnEntering(IScreen last)
|
||||||
{
|
{
|
||||||
base.OnEntering(last);
|
base.OnEntering(last);
|
||||||
|
|
||||||
Background.FadeColour(Color4.DarkGray, 500);
|
Background.FadeColour(Color4.DarkGray, 500);
|
||||||
Beatmap.Value.Track?.Stop();
|
resetTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnExiting(IScreen next)
|
public override bool OnExiting(IScreen next)
|
||||||
{
|
{
|
||||||
Background.FadeColour(Color4.White, 500);
|
Background.FadeColour(Color4.White, 500);
|
||||||
|
resetTrack();
|
||||||
if (Beatmap.Value.Track != null)
|
|
||||||
{
|
|
||||||
Beatmap.Value.Track.Tempo.Value = 1;
|
|
||||||
Beatmap.Value.Track.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnExiting(next);
|
return base.OnExiting(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resetTrack()
|
||||||
|
{
|
||||||
|
Beatmap.Value.Track?.ResetSpeedAdjustments();
|
||||||
|
Beatmap.Value.Track?.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
private void exportBeatmap() => host.OpenFileExternally(Beatmap.Value.Save());
|
private void exportBeatmap() => host.OpenFileExternally(Beatmap.Value.Save());
|
||||||
|
|
||||||
private void onModeChanged(ValueChangedEvent<EditorScreenMode> e)
|
private void onModeChanged(ValueChangedEvent<EditorScreenMode> e)
|
||||||
|
@ -332,7 +332,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonSystemState.EnteringMode:
|
case ButtonSystemState.EnteringMode:
|
||||||
logoTrackingContainer.StartTracking(logo, 0, Easing.In);
|
logoTrackingContainer.StartTracking(logo, lastState == ButtonSystemState.Initial ? MainMenu.FADE_OUT_DURATION : 0, Easing.InSine);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,18 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBlack();
|
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBlack();
|
||||||
|
|
||||||
|
private readonly BindableDouble exitingVolumeFade = new BindableDouble(1);
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private AudioManager audio { get; set; }
|
||||||
|
|
||||||
private Bindable<bool> menuVoice;
|
private Bindable<bool> menuVoice;
|
||||||
private Bindable<bool> menuMusic;
|
private Bindable<bool> menuMusic;
|
||||||
private Track track;
|
private Track track;
|
||||||
private WorkingBeatmap introBeatmap;
|
private WorkingBeatmap introBeatmap;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game)
|
private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game)
|
||||||
{
|
{
|
||||||
menuVoice = config.GetBindable<bool>(OsuSetting.MenuVoice);
|
menuVoice = config.GetBindable<bool>(OsuSetting.MenuVoice);
|
||||||
menuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic);
|
menuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic);
|
||||||
@ -161,7 +166,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
else
|
else
|
||||||
fadeOutTime = 500;
|
fadeOutTime = 500;
|
||||||
|
|
||||||
Scheduler.AddDelayed(this.Exit, fadeOutTime);
|
audio.AddAdjustment(AdjustableProperty.Volume, exitingVolumeFade);
|
||||||
|
this.TransformBindableTo(exitingVolumeFade, 0, fadeOutTime).OnComplete(_ => this.Exit());
|
||||||
|
|
||||||
//don't want to fade out completely else we will stop running updates.
|
//don't want to fade out completely else we will stop running updates.
|
||||||
Game.FadeTo(0.01f, fadeOutTime);
|
Game.FadeTo(0.01f, fadeOutTime);
|
||||||
|
@ -23,7 +23,9 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
public class MainMenu : OsuScreen
|
public class MainMenu : OsuScreen
|
||||||
{
|
{
|
||||||
private ButtonSystem buttons;
|
public const float FADE_IN_DURATION = 300;
|
||||||
|
|
||||||
|
public const float FADE_OUT_DURATION = 400;
|
||||||
|
|
||||||
public override bool HideOverlaysOnEnter => buttons == null || buttons.State == ButtonSystemState.Initial;
|
public override bool HideOverlaysOnEnter => buttons == null || buttons.State == ButtonSystemState.Initial;
|
||||||
|
|
||||||
@ -35,9 +37,14 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
private MenuSideFlashes sideFlashes;
|
private MenuSideFlashes sideFlashes;
|
||||||
|
|
||||||
|
private ButtonSystem buttons;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private GameHost host { get; set; }
|
private GameHost host { get; set; }
|
||||||
|
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private MusicController music { get; set; }
|
||||||
|
|
||||||
private BackgroundScreenDefault background;
|
private BackgroundScreenDefault background;
|
||||||
|
|
||||||
protected override BackgroundScreen CreateBackground() => background;
|
protected override BackgroundScreen CreateBackground() => background;
|
||||||
@ -141,12 +148,10 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
buttons.State = ButtonSystemState.TopLevel;
|
buttons.State = ButtonSystemState.TopLevel;
|
||||||
|
|
||||||
const float length = 300;
|
this.FadeIn(FADE_IN_DURATION, Easing.OutQuint);
|
||||||
|
this.MoveTo(new Vector2(0, 0), FADE_IN_DURATION, Easing.OutQuint);
|
||||||
|
|
||||||
this.FadeIn(length, Easing.OutQuint);
|
sideFlashes.Delay(FADE_IN_DURATION).FadeIn(64, Easing.InQuint);
|
||||||
this.MoveTo(new Vector2(0, 0), length, Easing.OutQuint);
|
|
||||||
|
|
||||||
sideFlashes.Delay(length).FadeIn(64, Easing.InQuint);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,12 +176,10 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
base.OnSuspending(next);
|
base.OnSuspending(next);
|
||||||
|
|
||||||
const float length = 400;
|
|
||||||
|
|
||||||
buttons.State = ButtonSystemState.EnteringMode;
|
buttons.State = ButtonSystemState.EnteringMode;
|
||||||
|
|
||||||
this.FadeOut(length, Easing.InSine);
|
this.FadeOut(FADE_OUT_DURATION, Easing.InSine);
|
||||||
this.MoveTo(new Vector2(-800, 0), length, Easing.InSine);
|
this.MoveTo(new Vector2(-800, 0), FADE_OUT_DURATION, Easing.InSine);
|
||||||
|
|
||||||
sideFlashes.FadeOut(64, Easing.OutQuint);
|
sideFlashes.FadeOut(64, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
@ -189,6 +192,9 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
//we may have consumed our preloaded instance, so let's make another.
|
//we may have consumed our preloaded instance, so let's make another.
|
||||||
preloadSongSelect();
|
preloadSongSelect();
|
||||||
|
|
||||||
|
if (Beatmap.Value.Track != null && music?.IsUserPaused != true)
|
||||||
|
Beatmap.Value.Track.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnExiting(IScreen next)
|
public override bool OnExiting(IScreen next)
|
||||||
|
@ -23,7 +23,8 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
public class HUDOverlay : Container
|
public class HUDOverlay : Container
|
||||||
{
|
{
|
||||||
private const int duration = 100;
|
private const int duration = 250;
|
||||||
|
private const Easing easing = Easing.OutQuint;
|
||||||
|
|
||||||
public readonly KeyCounterDisplay KeyCounter;
|
public readonly KeyCounterDisplay KeyCounter;
|
||||||
public readonly RollingCounter<int> ComboCounter;
|
public readonly RollingCounter<int> ComboCounter;
|
||||||
@ -35,6 +36,8 @@ namespace osu.Game.Screens.Play
|
|||||||
public readonly HoldForMenuButton HoldToQuit;
|
public readonly HoldForMenuButton HoldToQuit;
|
||||||
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
|
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
|
||||||
|
|
||||||
|
public Bindable<bool> ShowHealthbar = new Bindable<bool>(true);
|
||||||
|
|
||||||
private readonly ScoreProcessor scoreProcessor;
|
private readonly ScoreProcessor scoreProcessor;
|
||||||
private readonly DrawableRuleset drawableRuleset;
|
private readonly DrawableRuleset drawableRuleset;
|
||||||
private readonly IReadOnlyList<Mod> mods;
|
private readonly IReadOnlyList<Mod> mods;
|
||||||
@ -47,6 +50,8 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
public Action<double> RequestSeek;
|
public Action<double> RequestSeek;
|
||||||
|
|
||||||
|
private readonly Container topScoreContainer;
|
||||||
|
|
||||||
public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, IReadOnlyList<Mod> mods)
|
public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, IReadOnlyList<Mod> mods)
|
||||||
{
|
{
|
||||||
this.scoreProcessor = scoreProcessor;
|
this.scoreProcessor = scoreProcessor;
|
||||||
@ -62,11 +67,10 @@ namespace osu.Game.Screens.Play
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Container
|
topScoreContainer = new Container
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
Y = 30,
|
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
AutoSizeDuration = 200,
|
AutoSizeDuration = 200,
|
||||||
AutoSizeEasing = Easing.Out,
|
AutoSizeEasing = Easing.Out,
|
||||||
@ -113,8 +117,21 @@ namespace osu.Game.Screens.Play
|
|||||||
ModDisplay.Current.Value = mods;
|
ModDisplay.Current.Value = mods;
|
||||||
|
|
||||||
showHud = config.GetBindable<bool>(OsuSetting.ShowInterface);
|
showHud = config.GetBindable<bool>(OsuSetting.ShowInterface);
|
||||||
showHud.ValueChanged += visible => visibilityContainer.FadeTo(visible.NewValue ? 1 : 0, duration);
|
showHud.BindValueChanged(visible => visibilityContainer.FadeTo(visible.NewValue ? 1 : 0, duration, easing), true);
|
||||||
showHud.TriggerChange();
|
|
||||||
|
ShowHealthbar.BindValueChanged(healthBar =>
|
||||||
|
{
|
||||||
|
if (healthBar.NewValue)
|
||||||
|
{
|
||||||
|
HealthDisplay.FadeIn(duration, easing);
|
||||||
|
topScoreContainer.MoveToY(30, duration, easing);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HealthDisplay.FadeOut(duration, easing);
|
||||||
|
topScoreContainer.MoveToY(0, duration, easing);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
if (!showHud.Value && !hasShownNotificationOnce)
|
if (!showHud.Value && !hasShownNotificationOnce)
|
||||||
{
|
{
|
||||||
|
@ -498,6 +498,9 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
GameplayClockContainer.Restart();
|
GameplayClockContainer.Restart();
|
||||||
GameplayClockContainer.FadeInFromZero(750, Easing.OutQuint);
|
GameplayClockContainer.FadeInFromZero(750, Easing.OutQuint);
|
||||||
|
|
||||||
|
foreach (var mod in Mods.Value.OfType<IApplicableToHUD>())
|
||||||
|
mod.ApplyToHUD(HUDOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnSuspending(IScreen next)
|
public override void OnSuspending(IScreen next)
|
||||||
|
@ -18,6 +18,7 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Input;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using osu.Game.Screens.Play.HUD;
|
using osu.Game.Screens.Play.HUD;
|
||||||
@ -53,6 +54,8 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
private InputManager inputManager;
|
private InputManager inputManager;
|
||||||
|
|
||||||
|
private IdleTracker idleTracker;
|
||||||
|
|
||||||
public PlayerLoader(Func<Player> createPlayer)
|
public PlayerLoader(Func<Player> createPlayer)
|
||||||
{
|
{
|
||||||
this.createPlayer = createPlayer;
|
this.createPlayer = createPlayer;
|
||||||
@ -93,7 +96,8 @@ namespace osu.Game.Screens.Play
|
|||||||
VisualSettings = new VisualSettings(),
|
VisualSettings = new VisualSettings(),
|
||||||
new InputSettings()
|
new InputSettings()
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
idleTracker = new IdleTracker(750)
|
||||||
});
|
});
|
||||||
|
|
||||||
loadNewPlayer();
|
loadNewPlayer();
|
||||||
@ -193,7 +197,7 @@ namespace osu.Game.Screens.Play
|
|||||||
// Here because IsHovered will not update unless we do so.
|
// Here because IsHovered will not update unless we do so.
|
||||||
public override bool HandlePositionalInput => true;
|
public override bool HandlePositionalInput => true;
|
||||||
|
|
||||||
private bool readyForPush => player.LoadState == LoadState.Ready && IsHovered && GetContainingInputManager()?.DraggedDrawable == null;
|
private bool readyForPush => player.LoadState == LoadState.Ready && (IsHovered || idleTracker.IsIdle.Value) && inputManager?.DraggedDrawable == null;
|
||||||
|
|
||||||
private void pushWhenLoaded()
|
private void pushWhenLoaded()
|
||||||
{
|
{
|
||||||
|
@ -86,11 +86,7 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
if (replayAvailability == ReplayAvailability.NotAvailable)
|
button.Enabled.Value = replayAvailability != ReplayAvailability.NotAvailable;
|
||||||
{
|
|
||||||
button.Enabled.Value = false;
|
|
||||||
button.Alpha = 0.6f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum ReplayAvailability
|
private enum ReplayAvailability
|
||||||
|
34
osu.Game/Screens/Play/ReplayPlayerLoader.cs
Normal file
34
osu.Game/Screens/Play/ReplayPlayerLoader.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Play
|
||||||
|
{
|
||||||
|
public class ReplayPlayerLoader : PlayerLoader
|
||||||
|
{
|
||||||
|
private readonly ScoreInfo scoreInfo;
|
||||||
|
|
||||||
|
public ReplayPlayerLoader(Score score)
|
||||||
|
: base(() => new ReplayPlayer(score))
|
||||||
|
{
|
||||||
|
if (score.Replay == null)
|
||||||
|
throw new ArgumentNullException(nameof(score.Replay), $"{nameof(score)} must have a non-null {nameof(score.Replay)}.");
|
||||||
|
|
||||||
|
scoreInfo = score.ScoreInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
|
{
|
||||||
|
var dependencies = base.CreateChildDependencies(parent);
|
||||||
|
|
||||||
|
// these will be reverted thanks to PlayerLoader's lease.
|
||||||
|
Mods.Value = scoreInfo.Mods;
|
||||||
|
Ruleset.Value = scoreInfo.Ruleset;
|
||||||
|
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -41,6 +41,8 @@ namespace osu.Game.Screens.Select
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
OnFilter = (tab, mods) =>
|
OnFilter = (tab, mods) =>
|
||||||
{
|
{
|
||||||
|
Leaderboard.FilterMods = mods;
|
||||||
|
|
||||||
switch (tab)
|
switch (tab)
|
||||||
{
|
{
|
||||||
case BeatmapDetailTab.Details:
|
case BeatmapDetailTab.Details:
|
||||||
|
@ -18,8 +18,6 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Beatmaps.Drawables;
|
using osu.Game.Beatmaps.Drawables;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Objects;
|
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
@ -289,14 +287,11 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
if (b?.HitObjects?.Any() == true)
|
if (b?.HitObjects?.Any() == true)
|
||||||
{
|
{
|
||||||
HitObject lastObject = b.HitObjects.LastOrDefault();
|
|
||||||
double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0;
|
|
||||||
|
|
||||||
labels.Add(new InfoLabel(new BeatmapStatistic
|
labels.Add(new InfoLabel(new BeatmapStatistic
|
||||||
{
|
{
|
||||||
Name = "Length",
|
Name = "Length",
|
||||||
Icon = FontAwesome.Regular.Clock,
|
Icon = FontAwesome.Regular.Clock,
|
||||||
Content = TimeSpan.FromMilliseconds(endTime - b.HitObjects.First().StartTime).ToString(@"m\:ss"),
|
Content = TimeSpan.FromMilliseconds(b.BeatmapInfo.Length).ToString(@"m\:ss"),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
labels.Add(new InfoLabel(new BeatmapStatistic
|
labels.Add(new InfoLabel(new BeatmapStatistic
|
||||||
|
@ -48,6 +48,12 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
case SortMode.DateAdded:
|
case SortMode.DateAdded:
|
||||||
return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded);
|
return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded);
|
||||||
|
|
||||||
|
case SortMode.BPM:
|
||||||
|
return BeatmapSet.MaxBPM.CompareTo(otherSet.BeatmapSet.MaxBPM);
|
||||||
|
|
||||||
|
case SortMode.Length:
|
||||||
|
return BeatmapSet.MaxLength.CompareTo(otherSet.BeatmapSet.MaxLength);
|
||||||
|
|
||||||
case SortMode.Difficulty:
|
case SortMode.Difficulty:
|
||||||
return BeatmapSet.MaxStarDifficulty.CompareTo(otherSet.BeatmapSet.MaxStarDifficulty);
|
return BeatmapSet.MaxStarDifficulty.CompareTo(otherSet.BeatmapSet.MaxStarDifficulty);
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using osu.Framework.Screens;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
|
||||||
{
|
|
||||||
public class EditSongSelect : SongSelect
|
|
||||||
{
|
|
||||||
protected override bool ShowFooter => false;
|
|
||||||
|
|
||||||
protected override bool OnStart()
|
|
||||||
{
|
|
||||||
this.Exit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,7 +12,7 @@ namespace osu.Game.Screens.Select
|
|||||||
public ImportFromStablePopup(Action importFromStable)
|
public ImportFromStablePopup(Action importFromStable)
|
||||||
{
|
{
|
||||||
HeaderText = @"You have no beatmaps!";
|
HeaderText = @"You have no beatmaps!";
|
||||||
BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps (and skins)?";
|
BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps, skins and scores?";
|
||||||
|
|
||||||
Icon = FontAwesome.Solid.Plane;
|
Icon = FontAwesome.Solid.Plane;
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ using osu.Game.Online.API;
|
|||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.Leaderboards;
|
using osu.Game.Online.Leaderboards;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
@ -36,12 +37,34 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool filterMods;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to apply the game's currently selected mods as a filter when retrieving scores.
|
||||||
|
/// </summary>
|
||||||
|
public bool FilterMods
|
||||||
|
{
|
||||||
|
get => filterMods;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == filterMods)
|
||||||
|
return;
|
||||||
|
|
||||||
|
filterMods = value;
|
||||||
|
|
||||||
|
UpdateScores();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private ScoreManager scoreManager { get; set; }
|
private ScoreManager scoreManager { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IBindable<RulesetInfo> ruleset { get; set; }
|
private IBindable<RulesetInfo> ruleset { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
@ -49,32 +72,66 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
ruleset.ValueChanged += _ => UpdateScores();
|
ruleset.ValueChanged += _ => UpdateScores();
|
||||||
|
mods.ValueChanged += _ =>
|
||||||
|
{
|
||||||
|
if (filterMods)
|
||||||
|
UpdateScores();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback)
|
protected override APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback)
|
||||||
{
|
{
|
||||||
if (Scope == BeatmapLeaderboardScope.Local)
|
if (Scope == BeatmapLeaderboardScope.Local)
|
||||||
{
|
{
|
||||||
Scores = scoreManager
|
var scores = scoreManager
|
||||||
.QueryScores(s => !s.DeletePending && s.Beatmap.ID == Beatmap.ID && s.Ruleset.ID == ruleset.Value.ID)
|
.QueryScores(s => !s.DeletePending && s.Beatmap.ID == Beatmap.ID && s.Ruleset.ID == ruleset.Value.ID);
|
||||||
.OrderByDescending(s => s.TotalScore).ToArray();
|
|
||||||
|
if (filterMods && !mods.Value.Any())
|
||||||
|
{
|
||||||
|
// we need to filter out all scores that have any mods to get all local nomod scores
|
||||||
|
scores = scores.Where(s => !s.Mods.Any());
|
||||||
|
}
|
||||||
|
else if (filterMods)
|
||||||
|
{
|
||||||
|
// otherwise find all the scores that have *any* of the currently selected mods (similar to how web applies mod filters)
|
||||||
|
// we're creating and using a string list representation of selected mods so that it can be translated into the DB query itself
|
||||||
|
var selectedMods = mods.Value.Select(m => m.Acronym);
|
||||||
|
scores = scores.Where(s => s.Mods.Any(m => selectedMods.Contains(m.Acronym)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Scores = scores.OrderByDescending(s => s.TotalScore).ToArray();
|
||||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Beatmap?.OnlineBeatmapID == null)
|
if (api?.IsLoggedIn != true)
|
||||||
|
{
|
||||||
|
PlaceholderState = PlaceholderState.NotLoggedIn;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Beatmap?.OnlineBeatmapID == null || Beatmap?.Status <= BeatmapSetOnlineStatus.Pending)
|
||||||
{
|
{
|
||||||
PlaceholderState = PlaceholderState.Unavailable;
|
PlaceholderState = PlaceholderState.Unavailable;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Scope != BeatmapLeaderboardScope.Global && !api.LocalUser.Value.IsSupporter)
|
if (!api.LocalUser.Value.IsSupporter && (Scope != BeatmapLeaderboardScope.Global || filterMods))
|
||||||
{
|
{
|
||||||
PlaceholderState = PlaceholderState.NotSupporter;
|
PlaceholderState = PlaceholderState.NotSupporter;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var req = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope);
|
IReadOnlyList<Mod> requestMods = null;
|
||||||
|
|
||||||
|
if (filterMods && !mods.Value.Any())
|
||||||
|
// add nomod for the request
|
||||||
|
requestMods = new Mod[] { new ModNoMod() };
|
||||||
|
else if (filterMods)
|
||||||
|
requestMods = mods.Value;
|
||||||
|
|
||||||
|
var req = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope, requestMods);
|
||||||
|
|
||||||
req.Success += r => scoresCallback?.Invoke(r.Scores);
|
req.Success += r => scoresCallback?.Invoke(r.Scores);
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
namespace osu.Game.Screens.Select
|
||||||
{
|
{
|
||||||
@ -86,6 +87,9 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
private readonly Bindable<RulesetInfo> decoupledRuleset = new Bindable<RulesetInfo>();
|
private readonly Bindable<RulesetInfo> decoupledRuleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private MusicController music { get; set; }
|
||||||
|
|
||||||
[Cached]
|
[Cached]
|
||||||
[Cached(Type = typeof(IBindable<IReadOnlyList<Mod>>))]
|
[Cached(Type = typeof(IBindable<IReadOnlyList<Mod>>))]
|
||||||
private readonly Bindable<IReadOnlyList<Mod>> mods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>()); // Bound to the game's mods, but is not reset on exiting
|
private readonly Bindable<IReadOnlyList<Mod>> mods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>()); // Bound to the game's mods, but is not reset on exiting
|
||||||
@ -215,7 +219,7 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins)
|
private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins, ScoreManager scores)
|
||||||
{
|
{
|
||||||
mods.BindTo(Mods);
|
mods.BindTo(Mods);
|
||||||
|
|
||||||
@ -252,7 +256,7 @@ namespace osu.Game.Screens.Select
|
|||||||
if (!beatmaps.GetAllUsableBeatmapSets().Any() && beatmaps.StableInstallationAvailable)
|
if (!beatmaps.GetAllUsableBeatmapSets().Any() && beatmaps.StableInstallationAvailable)
|
||||||
dialogOverlay.Push(new ImportFromStablePopup(() =>
|
dialogOverlay.Push(new ImportFromStablePopup(() =>
|
||||||
{
|
{
|
||||||
Task.Run(beatmaps.ImportFromStableAsync);
|
Task.Run(beatmaps.ImportFromStableAsync).ContinueWith(_ => scores.ImportFromStableAsync(), TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||||
Task.Run(skins.ImportFromStableAsync);
|
Task.Run(skins.ImportFromStableAsync);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
@ -569,7 +573,7 @@ namespace osu.Game.Screens.Select
|
|||||||
{
|
{
|
||||||
Track track = Beatmap.Value.Track;
|
Track track = Beatmap.Value.Track;
|
||||||
|
|
||||||
if (!track.IsRunning || restart)
|
if ((!track.IsRunning || restart) && music?.IsUserPaused != true)
|
||||||
{
|
{
|
||||||
track.RestartPoint = Beatmap.Value.Metadata.PreviewTime;
|
track.RestartPoint = Beatmap.Value.Metadata.PreviewTime;
|
||||||
track.Restart();
|
track.Restart();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -54,6 +55,8 @@ namespace osu.Game.Skinning
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path)?.ToLowerInvariant() == ".osk";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a list of all usable <see cref="SkinInfo"/>s. Includes the special default skin plus all skins from <see cref="GetAllUserSkins"/>.
|
/// Returns a list of all usable <see cref="SkinInfo"/>s. Includes the special default skin plus all skins from <see cref="GetAllUserSkins"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.702.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.702.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2019.704.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2019.711.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.23.0" />
|
<PackageReference Include="SharpCompress" Version="0.23.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
@ -105,8 +105,8 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.702.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.702.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2019.704.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2019.711.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.704.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.711.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user