mirror of
https://github.com/ppy/osu.git
synced 2025-02-27 02:42:58 +08:00
Merge remote-tracking branch 'upstream/master' into android
This commit is contained in:
commit
2088bd1f1f
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (catch)" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="RulesetTests (catch)" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (mania)" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="RulesetTests (mania)" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (osu!)" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="RulesetTests (osu!)" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (taiko)" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="RulesetTests (taiko)" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="VisualTests" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="VisualTests" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
<option name="USE_MONO" value="0" />
|
<option name="USE_MONO" value="0" />
|
||||||
|
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Desktop/osu.Desktop.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Desktop/osu.Desktop.csproj" />
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" />
|
||||||
<method />
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
@ -7,13 +7,13 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll"
|
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tests (Debug)",
|
"preLaunchTask": "Build tests (Debug)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -24,13 +24,13 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1/osu.Game.Tests.dll"
|
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tests (Release)",
|
"preLaunchTask": "Build tests (Release)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -41,13 +41,13 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll"
|
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Debug)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -58,13 +58,13 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll"
|
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2/osu!.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Release)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
|
6
.vscode/tasks.json
vendored
6
.vscode/tasks.json
vendored
@ -11,7 +11,6 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Desktop",
|
"osu.Desktop",
|
||||||
"/p:TargetFramework=netcoreapp2.1",
|
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
"/verbosity:m"
|
"/verbosity:m"
|
||||||
@ -27,7 +26,6 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Desktop",
|
"osu.Desktop",
|
||||||
"/p:TargetFramework=netcoreapp2.1",
|
|
||||||
"/p:Configuration=Release",
|
"/p:Configuration=Release",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
@ -44,7 +42,6 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Tests",
|
"osu.Game.Tests",
|
||||||
"/p:TargetFramework=netcoreapp2.1",
|
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
"/verbosity:m"
|
"/verbosity:m"
|
||||||
@ -60,7 +57,6 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Tests",
|
"osu.Game.Tests",
|
||||||
"/p:TargetFramework=netcoreapp2.1",
|
|
||||||
"/p:Configuration=Release",
|
"/p:Configuration=Release",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
@ -70,7 +66,7 @@
|
|||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Restore (netcoreapp2.1)",
|
"label": "Restore (netcoreapp2.2)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
|
@ -10,7 +10,7 @@ We are accepting bug reports (please report with as much detail as possible). Fe
|
|||||||
|
|
||||||
# Requirements
|
# Requirements
|
||||||
|
|
||||||
- A desktop platform with the [.NET Core SDK 2.1](https://www.microsoft.com/net/learn/get-started) or higher installed.
|
- A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed.
|
||||||
- When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio Community Edition](https://www.visualstudio.com/) (Windows), [Visual Studio Code](https://code.visualstudio.com/) (with the C# plugin installed) or [Jetbrains Rider](https://www.jetbrains.com/rider/) (commercial).
|
- When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio Community Edition](https://www.visualstudio.com/) (Windows), [Visual Studio Code](https://code.visualstudio.com/) (with the C# plugin installed) or [Jetbrains Rider](https://www.jetbrains.com/rider/) (commercial).
|
||||||
|
|
||||||
# Building and running
|
# Building and running
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 694cb03f19c93106ed0f2593f3e506e835fb652a
|
Subproject commit 9880089b4e8fcd78d68f30c8a40d43bf8dccca86
|
@ -15,12 +15,16 @@ using Microsoft.Win32;
|
|||||||
using osu.Desktop.Updater;
|
using osu.Desktop.Updater;
|
||||||
using osu.Framework;
|
using osu.Framework;
|
||||||
using osu.Framework.Platform.Windows;
|
using osu.Framework.Platform.Windows;
|
||||||
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Screens;
|
||||||
|
using osu.Game.Screens.Menu;
|
||||||
|
|
||||||
namespace osu.Desktop
|
namespace osu.Desktop
|
||||||
{
|
{
|
||||||
internal class OsuGameDesktop : OsuGame
|
internal class OsuGameDesktop : OsuGame
|
||||||
{
|
{
|
||||||
private readonly bool noVersionOverlay;
|
private readonly bool noVersionOverlay;
|
||||||
|
private VersionManager versionManager;
|
||||||
|
|
||||||
public OsuGameDesktop(string[] args = null)
|
public OsuGameDesktop(string[] args = null)
|
||||||
: base(args)
|
: base(args)
|
||||||
@ -46,7 +50,7 @@ namespace osu.Desktop
|
|||||||
|
|
||||||
if (!noVersionOverlay)
|
if (!noVersionOverlay)
|
||||||
{
|
{
|
||||||
LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
|
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, v =>
|
||||||
{
|
{
|
||||||
Add(v);
|
Add(v);
|
||||||
v.State = Visibility.Visible;
|
v.State = Visibility.Visible;
|
||||||
@ -59,6 +63,23 @@ namespace osu.Desktop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void ScreenChanged(OsuScreen current, Screen newScreen)
|
||||||
|
{
|
||||||
|
base.ScreenChanged(current, newScreen);
|
||||||
|
switch (newScreen)
|
||||||
|
{
|
||||||
|
case Intro _:
|
||||||
|
case MainMenu _:
|
||||||
|
if (versionManager != null)
|
||||||
|
versionManager.State = Visibility.Visible;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (versionManager != null)
|
||||||
|
versionManager.State = Visibility.Hidden;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetHost(GameHost host)
|
public override void SetHost(GameHost host)
|
||||||
{
|
{
|
||||||
base.SetHost(host);
|
base.SetHost(host);
|
||||||
|
@ -128,11 +128,12 @@ namespace osu.Desktop.Overlays
|
|||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
this.FadeIn(1000);
|
this.FadeIn(1400, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
|
this.FadeOut(500, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<Import Project="..\osu.Game.props" />
|
<Import Project="..\osu.Game.props" />
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override float HealthIncreaseFor(HitResult result)
|
protected override double HealthIncreaseFor(HitResult result)
|
||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override float HealthIncreaseFor(HitResult result)
|
protected override double HealthIncreaseFor(HitResult result)
|
||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
|
@ -22,29 +22,17 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
protected override double HealthIncreaseFor(HitResult result)
|
||||||
/// Retrieves the numeric health increase of a <see cref="HitResult"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="result">The <see cref="HitResult"/> to find the numeric health increase for.</param>
|
|
||||||
/// <returns>The numeric health increase of <paramref name="result"/>.</returns>
|
|
||||||
protected virtual float HealthIncreaseFor(HitResult result)
|
|
||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
case HitResult.Perfect:
|
case HitResult.Perfect:
|
||||||
return 10.2f;
|
return 10.2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves the numeric health increase of a <see cref="JudgementResult"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="result">The <see cref="JudgementResult"/> to find the numeric health increase for.</param>
|
|
||||||
/// <returns>The numeric health increase of <paramref name="result"/>.</returns>
|
|
||||||
public float HealthIncreaseFor(JudgementResult result) => HealthIncreaseFor(result.Type);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether fruit on the platter should explode or drop.
|
/// Whether fruit on the platter should explode or drop.
|
||||||
/// Note that this is only checked if the owning object is also <see cref="IHasComboInformation.LastInCombo" />
|
/// Note that this is only checked if the owning object is also <see cref="IHasComboInformation.LastInCombo" />
|
||||||
|
@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override float HealthIncreaseFor(HitResult result)
|
protected override double HealthIncreaseFor(HitResult result)
|
||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
|
23
osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs
Normal file
23
osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Objects
|
||||||
|
{
|
||||||
|
public class CatchHitWindows : HitWindows
|
||||||
|
{
|
||||||
|
public override bool IsHitResultAllowed(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.Perfect:
|
||||||
|
case HitResult.Miss:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Judgements;
|
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
@ -40,8 +40,9 @@ namespace osu.Game.Rulesets.Catch.Scoring
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.Judgement is CatchJudgement catchJudgement)
|
Health.Value += Math.Max(result.Judgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness;
|
||||||
Health.Value += Math.Max(catchJudgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness;
|
}
|
||||||
}
|
|
||||||
|
protected override HitWindows CreateHitWindows() => new CatchHitWindows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
||||||
|
@ -20,11 +20,10 @@ namespace osu.Game.Rulesets.Mania.Objects
|
|||||||
{ HitResult.Miss, (376, 346, 316) },
|
{ HitResult.Miss, (376, 346, 316) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public override bool IsHitResultAllowed(HitResult result) => true;
|
||||||
|
|
||||||
public override void SetDifficulty(double difficulty)
|
public override void SetDifficulty(double difficulty)
|
||||||
{
|
{
|
||||||
AllowsPerfect = true;
|
|
||||||
AllowsOk = true;
|
|
||||||
|
|
||||||
Perfect = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Perfect]);
|
Perfect = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Perfect]);
|
||||||
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);
|
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);
|
||||||
Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]);
|
Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]);
|
||||||
|
@ -5,6 +5,7 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Mania.Judgements;
|
using osu.Game.Rulesets.Mania.Judgements;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
@ -157,5 +158,7 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override HitWindows CreateHitWindows() => new ManiaHitWindows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||||
|
@ -123,8 +123,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
if (mods.Any(h => h is OsuModFlashlight))
|
if (mods.Any(h => h is OsuModFlashlight))
|
||||||
{
|
{
|
||||||
// Apply length bonus again if flashlight is on simply because it becomes a lot harder on longer maps.
|
// Apply object-based bonus for flashlight.
|
||||||
aimValue *= 1.45f * lengthBonus;
|
aimValue *= 1.0f + 0.35f * Math.Min(1.0f, totalHits / 200.0f) +
|
||||||
|
(totalHits > 200 ? 0.3f * Math.Min(1.0f, (totalHits - 200) / 300.0f) +
|
||||||
|
(totalHits > 500 ? (totalHits - 500) / 1200.0f : 0.0f) : 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scale the aim value with accuracy _slightly_
|
// Scale the aim value with accuracy _slightly_
|
||||||
|
194
osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs
Normal file
194
osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
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.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModBlinds : Mod, IApplicableToRulesetContainer<OsuHitObject>, IApplicableToScoreProcessor
|
||||||
|
{
|
||||||
|
public override string Name => "Blinds";
|
||||||
|
public override string Description => "Play with blinds on your screen.";
|
||||||
|
public override string Acronym => "BL";
|
||||||
|
|
||||||
|
public override FontAwesome Icon => FontAwesome.fa_adjust;
|
||||||
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
|
|
||||||
|
public override bool Ranked => false;
|
||||||
|
|
||||||
|
public override double ScoreMultiplier => 1.12;
|
||||||
|
private DrawableOsuBlinds blinds;
|
||||||
|
|
||||||
|
public void ApplyToRulesetContainer(RulesetContainer<OsuHitObject> rulesetContainer)
|
||||||
|
{
|
||||||
|
rulesetContainer.Overlays.Add(blinds = new DrawableOsuBlinds(rulesetContainer.Playfield.HitObjectContainer, rulesetContainer.Beatmap));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
|
||||||
|
{
|
||||||
|
scoreProcessor.Health.ValueChanged += val => { blinds.AnimateClosedness((float)val); };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Element for the Blinds mod drawing 2 black boxes covering the whole screen which resize inside a restricted area with some leniency.
|
||||||
|
/// </summary>
|
||||||
|
public class DrawableOsuBlinds : Container
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Black background boxes behind blind panel textures.
|
||||||
|
/// </summary>
|
||||||
|
private Box blackBoxLeft, blackBoxRight;
|
||||||
|
|
||||||
|
private Drawable panelLeft, panelRight, bgPanelLeft, bgPanelRight;
|
||||||
|
|
||||||
|
private readonly Beatmap<OsuHitObject> beatmap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Value between 0 and 1 setting a maximum "closedness" for the blinds.
|
||||||
|
/// Useful for animating how far the blinds can be opened while keeping them at the original position if they are wider open than this.
|
||||||
|
/// </summary>
|
||||||
|
private const float target_clamp = 1;
|
||||||
|
|
||||||
|
private readonly float targetBreakMultiplier = 0;
|
||||||
|
private readonly float easing = 1;
|
||||||
|
|
||||||
|
private readonly CompositeDrawable restrictTo;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// Percentage of playfield to extend blinds over. Basically moves the origin points where the blinds start.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// -1 would mean the blinds always cover the whole screen no matter health.
|
||||||
|
/// 0 would mean the blinds will only ever be on the edge of the playfield on 0% health.
|
||||||
|
/// 1 would mean the blinds are fully outside the playfield on 50% health.
|
||||||
|
/// Infinity would mean the blinds are always outside the playfield except on 100% health.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
private const float leniency = 0.1f;
|
||||||
|
|
||||||
|
public DrawableOsuBlinds(CompositeDrawable restrictTo, Beatmap<OsuHitObject> beatmap)
|
||||||
|
{
|
||||||
|
this.restrictTo = restrictTo;
|
||||||
|
this.beatmap = beatmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
blackBoxLeft = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
},
|
||||||
|
blackBoxRight = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
},
|
||||||
|
bgPanelLeft = new ModBlindsPanel
|
||||||
|
{
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Colour = Color4.Gray,
|
||||||
|
},
|
||||||
|
panelLeft = new ModBlindsPanel { Origin = Anchor.TopRight, },
|
||||||
|
bgPanelRight = new ModBlindsPanel { Colour = Color4.Gray },
|
||||||
|
panelRight = new ModBlindsPanel()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private float calculateGap(float value) => MathHelper.Clamp(value, 0, target_clamp) * targetBreakMultiplier;
|
||||||
|
|
||||||
|
// lagrange polinominal for (0,0) (0.6,0.4) (1,1) should make a good curve
|
||||||
|
private static float applyAdjustmentCurve(float value) => 0.6f * value * value + 0.4f * value;
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
float start = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopLeft).X;
|
||||||
|
float end = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopRight).X;
|
||||||
|
|
||||||
|
float rawWidth = end - start;
|
||||||
|
|
||||||
|
start -= rawWidth * leniency * 0.5f;
|
||||||
|
end += rawWidth * leniency * 0.5f;
|
||||||
|
|
||||||
|
float width = (end - start) * 0.5f * applyAdjustmentCurve(calculateGap(easing));
|
||||||
|
|
||||||
|
// different values in case the playfield ever moves from center to somewhere else.
|
||||||
|
blackBoxLeft.Width = start + width;
|
||||||
|
blackBoxRight.Width = DrawWidth - end + width;
|
||||||
|
|
||||||
|
panelLeft.X = start + width;
|
||||||
|
panelRight.X = end - width;
|
||||||
|
bgPanelLeft.X = start;
|
||||||
|
bgPanelRight.X = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
const float break_open_early = 500;
|
||||||
|
const float break_close_late = 250;
|
||||||
|
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
var firstObj = beatmap.HitObjects[0];
|
||||||
|
var startDelay = firstObj.StartTime - firstObj.TimePreempt;
|
||||||
|
|
||||||
|
using (BeginAbsoluteSequence(startDelay + break_close_late, true))
|
||||||
|
leaveBreak();
|
||||||
|
|
||||||
|
foreach (var breakInfo in beatmap.Breaks)
|
||||||
|
{
|
||||||
|
if (breakInfo.HasEffect)
|
||||||
|
{
|
||||||
|
using (BeginAbsoluteSequence(breakInfo.StartTime - break_open_early, true))
|
||||||
|
{
|
||||||
|
enterBreak();
|
||||||
|
using (BeginDelayedSequence(breakInfo.Duration + break_open_early + break_close_late, true))
|
||||||
|
leaveBreak();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enterBreak() => this.TransformTo(nameof(targetBreakMultiplier), 0f, 1000, Easing.OutSine);
|
||||||
|
|
||||||
|
private void leaveBreak() => this.TransformTo(nameof(targetBreakMultiplier), 1f, 2500, Easing.OutBounce);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 0 is open, 1 is closed.
|
||||||
|
/// </summary>
|
||||||
|
public void AnimateClosedness(float value) => this.TransformTo(nameof(easing), value, 200, Easing.OutQuint);
|
||||||
|
|
||||||
|
public class ModBlindsPanel : Sprite
|
||||||
|
{
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
Texture = textures.Get("Play/osu/blinds-panel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,9 +26,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
if (slider == null)
|
if (slider == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
slider.HeadCircle.Position = new Vector2(slider.HeadCircle.Position.X, OsuPlayfield.BASE_SIZE.Y - slider.HeadCircle.Position.Y);
|
|
||||||
slider.TailCircle.Position = new Vector2(slider.TailCircle.Position.X, OsuPlayfield.BASE_SIZE.Y - slider.TailCircle.Position.Y);
|
|
||||||
|
|
||||||
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
||||||
slider.NestedHitObjects.OfType<RepeatPoint>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
slider.NestedHitObjects.OfType<RepeatPoint>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
||||||
|
|
||||||
|
@ -21,7 +21,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
protected DrawableOsuHitObject(OsuHitObject hitObject)
|
protected DrawableOsuHitObject(OsuHitObject hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
base.AddInternal(shakeContainer = new ShakeContainer { RelativeSizeAxes = Axes.Both });
|
base.AddInternal(shakeContainer = new ShakeContainer
|
||||||
|
{
|
||||||
|
ShakeDuration = 30,
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
});
|
||||||
Alpha = 0;
|
Alpha = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
|
|
||||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||||
{
|
{
|
||||||
new KeyBinding(InputKey.A, OsuAction.LeftButton),
|
new KeyBinding(InputKey.Z, OsuAction.LeftButton),
|
||||||
new KeyBinding(InputKey.S, OsuAction.RightButton),
|
new KeyBinding(InputKey.X, OsuAction.RightButton),
|
||||||
new KeyBinding(InputKey.MouseLeft, OsuAction.LeftButton),
|
new KeyBinding(InputKey.MouseLeft, OsuAction.LeftButton),
|
||||||
new KeyBinding(InputKey.MouseRight, OsuAction.RightButton),
|
new KeyBinding(InputKey.MouseRight, OsuAction.RightButton),
|
||||||
};
|
};
|
||||||
@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
new MultiMod(new OsuModSuddenDeath(), new OsuModPerfect()),
|
new MultiMod(new OsuModSuddenDeath(), new OsuModPerfect()),
|
||||||
new MultiMod(new OsuModDoubleTime(), new OsuModNightcore()),
|
new MultiMod(new OsuModDoubleTime(), new OsuModNightcore()),
|
||||||
new OsuModHidden(),
|
new OsuModHidden(),
|
||||||
new OsuModFlashlight(),
|
new MultiMod(new OsuModFlashlight(), new OsuModBlinds()),
|
||||||
};
|
};
|
||||||
case ModType.Conversion:
|
case ModType.Conversion:
|
||||||
return new Mod[]
|
return new Mod[]
|
||||||
|
@ -9,7 +9,6 @@ using osu.Game.Rulesets.Osu.Judgements;
|
|||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Scoring
|
namespace osu.Game.Rulesets.Osu.Scoring
|
||||||
{
|
{
|
||||||
@ -22,7 +21,6 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
|||||||
|
|
||||||
private float hpDrainRate;
|
private float hpDrainRate;
|
||||||
|
|
||||||
private readonly Dictionary<HitResult, int> scoreResultCounts = new Dictionary<HitResult, int>();
|
|
||||||
private readonly Dictionary<ComboResult, int> comboResultCounts = new Dictionary<ComboResult, int>();
|
private readonly Dictionary<ComboResult, int> comboResultCounts = new Dictionary<ComboResult, int>();
|
||||||
|
|
||||||
protected override void ApplyBeatmap(Beatmap<OsuHitObject> beatmap)
|
protected override void ApplyBeatmap(Beatmap<OsuHitObject> beatmap)
|
||||||
@ -35,21 +33,9 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
|||||||
protected override void Reset(bool storeResults)
|
protected override void Reset(bool storeResults)
|
||||||
{
|
{
|
||||||
base.Reset(storeResults);
|
base.Reset(storeResults);
|
||||||
|
|
||||||
scoreResultCounts.Clear();
|
|
||||||
comboResultCounts.Clear();
|
comboResultCounts.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void PopulateScore(ScoreInfo score)
|
|
||||||
{
|
|
||||||
base.PopulateScore(score);
|
|
||||||
|
|
||||||
score.Statistics[HitResult.Great] = scoreResultCounts.GetOrDefault(HitResult.Great);
|
|
||||||
score.Statistics[HitResult.Good] = scoreResultCounts.GetOrDefault(HitResult.Good);
|
|
||||||
score.Statistics[HitResult.Meh] = scoreResultCounts.GetOrDefault(HitResult.Meh);
|
|
||||||
score.Statistics[HitResult.Miss] = scoreResultCounts.GetOrDefault(HitResult.Miss);
|
|
||||||
}
|
|
||||||
|
|
||||||
private const double harshness = 0.01;
|
private const double harshness = 0.01;
|
||||||
|
|
||||||
protected override void ApplyResult(JudgementResult result)
|
protected override void ApplyResult(JudgementResult result)
|
||||||
@ -59,10 +45,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
|||||||
var osuResult = (OsuJudgementResult)result;
|
var osuResult = (OsuJudgementResult)result;
|
||||||
|
|
||||||
if (result.Type != HitResult.None)
|
if (result.Type != HitResult.None)
|
||||||
{
|
|
||||||
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1;
|
|
||||||
comboResultCounts[osuResult.ComboType] = comboResultCounts.GetOrDefault(osuResult.ComboType) + 1;
|
comboResultCounts[osuResult.ComboType] = comboResultCounts.GetOrDefault(osuResult.ComboType) + 1;
|
||||||
}
|
|
||||||
|
|
||||||
switch (result.Type)
|
switch (result.Type)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
|
||||||
|
24
osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollJudgement.cs
Normal file
24
osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollJudgement.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Judgements
|
||||||
|
{
|
||||||
|
public class TaikoDrumRollJudgement : TaikoJudgement
|
||||||
|
{
|
||||||
|
public override bool AffectsCombo => false;
|
||||||
|
|
||||||
|
protected override double HealthIncreaseFor(HitResult result)
|
||||||
|
{
|
||||||
|
// Drum rolls can be ignored with no health penalty
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.Miss:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return base.HealthIncreaseFor(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,10 +13,21 @@ namespace osu.Game.Rulesets.Taiko.Judgements
|
|||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
case HitResult.Great:
|
case HitResult.Great:
|
||||||
return 200;
|
return 200;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override double HealthIncreaseFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.Great:
|
||||||
|
return 0.15;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Judgements
|
|
||||||
{
|
|
||||||
public class TaikoIntermediateSwellJudgement : TaikoJudgement
|
|
||||||
{
|
|
||||||
public override HitResult MaxResult => HitResult.Great;
|
|
||||||
|
|
||||||
public override bool AffectsCombo => false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Computes the numeric result value for the combo portion of the score.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="result">The result to compute the value for.</param>
|
|
||||||
/// <returns>The numeric result value.</returns>
|
|
||||||
protected override int NumericResultFor(HitResult result) => 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,21 +10,31 @@ namespace osu.Game.Rulesets.Taiko.Judgements
|
|||||||
{
|
{
|
||||||
public override HitResult MaxResult => HitResult.Great;
|
public override HitResult MaxResult => HitResult.Great;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Computes the numeric result value for the combo portion of the score.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="result">The result to compute the value for.</param>
|
|
||||||
/// <returns>The numeric result value.</returns>
|
|
||||||
protected override int NumericResultFor(HitResult result)
|
protected override int NumericResultFor(HitResult result)
|
||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
case HitResult.Good:
|
case HitResult.Good:
|
||||||
return 100;
|
return 100;
|
||||||
case HitResult.Great:
|
case HitResult.Great:
|
||||||
return 300;
|
return 300;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override double HealthIncreaseFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.Miss:
|
||||||
|
return -1.0;
|
||||||
|
case HitResult.Good:
|
||||||
|
return 1.1;
|
||||||
|
case HitResult.Great:
|
||||||
|
return 3.0;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Judgements
|
namespace osu.Game.Rulesets.Taiko.Judgements
|
||||||
{
|
{
|
||||||
public class TaikoStrongJudgement : TaikoJudgement
|
public class TaikoStrongJudgement : TaikoJudgement
|
||||||
{
|
{
|
||||||
|
// MainObject already changes the HP
|
||||||
|
protected override double HealthIncreaseFor(HitResult result) => 0;
|
||||||
|
|
||||||
public override bool AffectsCombo => false;
|
public override bool AffectsCombo => false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
osu.Game.Rulesets.Taiko/Judgements/TaikoSwellJudgement.cs
Normal file
23
osu.Game.Rulesets.Taiko/Judgements/TaikoSwellJudgement.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Judgements
|
||||||
|
{
|
||||||
|
public class TaikoSwellJudgement : TaikoJudgement
|
||||||
|
{
|
||||||
|
public override bool AffectsCombo => false;
|
||||||
|
|
||||||
|
protected override double HealthIncreaseFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.Miss:
|
||||||
|
return -0.65;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Judgements
|
||||||
|
{
|
||||||
|
public class TaikoSwellTickJudgement : TaikoJudgement
|
||||||
|
{
|
||||||
|
public override bool AffectsCombo => false;
|
||||||
|
|
||||||
|
protected override int NumericResultFor(HitResult result) => 0;
|
||||||
|
|
||||||
|
protected override double HealthIncreaseFor(HitResult result) => 0;
|
||||||
|
}
|
||||||
|
}
|
@ -173,13 +173,13 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
|
|
||||||
if (!userTriggered)
|
if (!userTriggered)
|
||||||
{
|
{
|
||||||
if (timeOffset > second_hit_window)
|
if (timeOffset - MainObject.Result.TimeOffset > second_hit_window)
|
||||||
ApplyResult(r => r.Type = HitResult.Miss);
|
ApplyResult(r => r.Type = HitResult.Miss);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Math.Abs(MainObject.Result.TimeOffset - timeOffset) < second_hit_window)
|
if (Math.Abs(timeOffset - MainObject.Result.TimeOffset) <= second_hit_window)
|
||||||
ApplyResult(r => r.Type = HitResult.Great);
|
ApplyResult(r => r.Type = MainObject.Result.Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnPressed(TaikoAction action)
|
public override bool OnPressed(TaikoAction action)
|
||||||
|
@ -6,11 +6,11 @@ using osu.Game.Rulesets.Scoring;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
{
|
{
|
||||||
public class DrawableSwellTick : DrawableTaikoHitObject
|
public class DrawableSwellTick : DrawableTaikoHitObject<SwellTick>
|
||||||
{
|
{
|
||||||
public override bool DisplayResult => false;
|
public override bool DisplayResult => false;
|
||||||
|
|
||||||
public DrawableSwellTick(TaikoHitObject hitObject)
|
public DrawableSwellTick(SwellTick hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ using osu.Game.Rulesets.Objects.Types;
|
|||||||
using System;
|
using System;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects
|
namespace osu.Game.Rulesets.Taiko.Objects
|
||||||
{
|
{
|
||||||
@ -81,5 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Judgement CreateJudgement() => new TaikoDrumRollJudgement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects
|
namespace osu.Game.Rulesets.Taiko.Objects
|
||||||
{
|
{
|
||||||
@ -26,5 +28,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
for (int i = 0; i < RequiredHits; i++)
|
for (int i = 0; i < RequiredHits; i++)
|
||||||
AddNested(new SwellTick());
|
AddNested(new SwellTick());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Judgement CreateJudgement() => new TaikoSwellJudgement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects
|
namespace osu.Game.Rulesets.Taiko.Objects
|
||||||
{
|
{
|
||||||
public class SwellTick : TaikoHitObject
|
public class SwellTick : TaikoHitObject
|
||||||
{
|
{
|
||||||
|
public override Judgement CreateJudgement() => new TaikoSwellTickJudgement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,15 +14,26 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
{
|
{
|
||||||
{ HitResult.Great, (100, 70, 40) },
|
{ HitResult.Great, (100, 70, 40) },
|
||||||
{ HitResult.Good, (240, 160, 100) },
|
{ HitResult.Good, (240, 160, 100) },
|
||||||
{ HitResult.Meh, (270, 190, 140) },
|
{ HitResult.Miss, (270, 190, 140) },
|
||||||
{ HitResult.Miss, (400, 400, 400) },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public override bool IsHitResultAllowed(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.Great:
|
||||||
|
case HitResult.Good:
|
||||||
|
case HitResult.Miss:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetDifficulty(double difficulty)
|
public override void SetDifficulty(double difficulty)
|
||||||
{
|
{
|
||||||
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);
|
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);
|
||||||
Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]);
|
Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]);
|
||||||
Meh = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Meh]);
|
|
||||||
Miss = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Miss]);
|
Miss = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Miss]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Taiko.Judgements;
|
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
@ -13,51 +13,24 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
|||||||
internal class TaikoScoreProcessor : ScoreProcessor<TaikoHitObject>
|
internal class TaikoScoreProcessor : ScoreProcessor<TaikoHitObject>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The HP awarded by a <see cref="HitResult.Great"/> hit.
|
/// A value used for calculating <see cref="hpMultiplier"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const double hp_hit_great = 0.03;
|
private const double object_count_factor = 3;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The HP awarded for a <see cref="HitResult.Good"/> hit.
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_hit_good = 0.011;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The minimum HP deducted for a <see cref="HitResult.Miss"/>.
|
|
||||||
/// This occurs when HP Drain = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_miss_min = -0.0018;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The median HP deducted for a <see cref="HitResult.Miss"/>.
|
|
||||||
/// This occurs when HP Drain = 5.
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_miss_mid = -0.0075;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The maximum HP deducted for a <see cref="HitResult.Miss"/>.
|
|
||||||
/// This occurs when HP Drain = 10.
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_miss_max = -0.12;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The HP awarded for a <see cref="DrumRollTick"/> hit.
|
|
||||||
/// <para>
|
|
||||||
/// <see cref="DrumRollTick"/> hits award less HP as they're more spammable, although in hindsight
|
|
||||||
/// this probably awards too little HP and is kept at this value for now for compatibility.
|
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_hit_tick = 0.00000003;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Taiko fails at the end of the map if the player has not half-filled their HP bar.
|
/// Taiko fails at the end of the map if the player has not half-filled their HP bar.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override bool DefaultFailCondition => JudgedHits == MaxHits && Health.Value <= 0.5;
|
protected override bool DefaultFailCondition => JudgedHits == MaxHits && Health.Value <= 0.5;
|
||||||
|
|
||||||
private double hpIncreaseTick;
|
/// <summary>
|
||||||
private double hpIncreaseGreat;
|
/// HP multiplier for a successful <see cref="HitResult"/>.
|
||||||
private double hpIncreaseGood;
|
/// </summary>
|
||||||
private double hpIncreaseMiss;
|
private double hpMultiplier;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HP multiplier for a <see cref="HitResult.Miss"/>.
|
||||||
|
/// </summary>
|
||||||
|
private double hpMissMultiplier;
|
||||||
|
|
||||||
public TaikoScoreProcessor(RulesetContainer<TaikoHitObject> rulesetContainer)
|
public TaikoScoreProcessor(RulesetContainer<TaikoHitObject> rulesetContainer)
|
||||||
: base(rulesetContainer)
|
: base(rulesetContainer)
|
||||||
@ -68,38 +41,23 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
|||||||
{
|
{
|
||||||
base.ApplyBeatmap(beatmap);
|
base.ApplyBeatmap(beatmap);
|
||||||
|
|
||||||
double hpMultiplierNormal = 1 / (hp_hit_great * beatmap.HitObjects.FindAll(o => o is Hit).Count * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98));
|
hpMultiplier = 1 / (object_count_factor * beatmap.HitObjects.FindAll(o => o is Hit).Count * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98));
|
||||||
|
|
||||||
hpIncreaseTick = hp_hit_tick;
|
hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120);
|
||||||
hpIncreaseGreat = hpMultiplierNormal * hp_hit_great;
|
|
||||||
hpIncreaseGood = hpMultiplierNormal * hp_hit_good;
|
|
||||||
hpIncreaseMiss = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, hp_miss_min, hp_miss_mid, hp_miss_max);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ApplyResult(JudgementResult result)
|
protected override void ApplyResult(JudgementResult result)
|
||||||
{
|
{
|
||||||
base.ApplyResult(result);
|
base.ApplyResult(result);
|
||||||
|
|
||||||
bool isTick = result.Judgement is TaikoDrumRollTickJudgement;
|
double hpIncrease = result.Judgement.HealthIncreaseFor(result);
|
||||||
|
|
||||||
// Apply HP changes
|
if (result.Type == HitResult.Miss)
|
||||||
switch (result.Type)
|
hpIncrease *= hpMissMultiplier;
|
||||||
{
|
|
||||||
case HitResult.Miss:
|
|
||||||
// Missing ticks shouldn't drop HP
|
|
||||||
if (!isTick)
|
|
||||||
Health.Value += hpIncreaseMiss;
|
|
||||||
break;
|
|
||||||
case HitResult.Good:
|
|
||||||
Health.Value += hpIncreaseGood;
|
|
||||||
break;
|
|
||||||
case HitResult.Great:
|
|
||||||
if (isTick)
|
|
||||||
Health.Value += hpIncreaseTick;
|
|
||||||
else
|
else
|
||||||
Health.Value += hpIncreaseGreat;
|
hpIncrease *= hpMultiplier;
|
||||||
break;
|
|
||||||
}
|
Health.Value += hpIncrease;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Reset(bool storeResults)
|
protected override void Reset(bool storeResults)
|
||||||
@ -108,5 +66,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
|||||||
|
|
||||||
Health.Value = 0;
|
Health.Value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override HitWindows CreateHitWindows() => new TaikoHitWindows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
loadOszIntoOsu(loadOsu(host));
|
LoadOszIntoOsu(loadOsu(host));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -48,7 +48,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
var imported = loadOszIntoOsu(osu);
|
var imported = LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
deleteBeatmapSet(imported, osu);
|
deleteBeatmapSet(imported, osu);
|
||||||
}
|
}
|
||||||
@ -69,8 +69,8 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
var imported = loadOszIntoOsu(osu);
|
var imported = LoadOszIntoOsu(osu);
|
||||||
var importedSecondTime = loadOszIntoOsu(osu);
|
var importedSecondTime = LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||||
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
||||||
@ -105,7 +105,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
manager.ItemAdded += (_, __, ___) => fireCount++;
|
manager.ItemAdded += (_, __, ___) => fireCount++;
|
||||||
manager.ItemRemoved += _ => fireCount++;
|
manager.ItemRemoved += _ => fireCount++;
|
||||||
|
|
||||||
var imported = loadOszIntoOsu(osu);
|
var imported = LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
Assert.AreEqual(0, fireCount -= 1);
|
Assert.AreEqual(0, fireCount -= 1);
|
||||||
|
|
||||||
@ -160,12 +160,12 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
var imported = loadOszIntoOsu(osu);
|
var imported = LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
imported.Hash += "-changed";
|
imported.Hash += "-changed";
|
||||||
manager.Update(imported);
|
manager.Update(imported);
|
||||||
|
|
||||||
var importedSecondTime = loadOszIntoOsu(osu);
|
var importedSecondTime = LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
||||||
Assert.IsTrue(imported.Beatmaps.First().ID < importedSecondTime.Beatmaps.First().ID);
|
Assert.IsTrue(imported.Beatmaps.First().ID < importedSecondTime.Beatmaps.First().ID);
|
||||||
@ -191,11 +191,11 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
var imported = loadOszIntoOsu(osu);
|
var imported = LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
deleteBeatmapSet(imported, osu);
|
deleteBeatmapSet(imported, osu);
|
||||||
|
|
||||||
var importedSecondTime = loadOszIntoOsu(osu);
|
var importedSecondTime = LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||||
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
||||||
@ -262,7 +262,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string createTemporaryBeatmap()
|
private static string createTemporaryBeatmap()
|
||||||
{
|
{
|
||||||
var temp = Path.GetTempFileName() + ".osz";
|
var temp = Path.GetTempFileName() + ".osz";
|
||||||
File.Copy(TEST_OSZ_PATH, temp, true);
|
File.Copy(TEST_OSZ_PATH, temp, true);
|
||||||
@ -270,7 +270,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BeatmapSetInfo loadOszIntoOsu(OsuGameBase osu, string path = null)
|
public static BeatmapSetInfo LoadOszIntoOsu(OsuGameBase osu, string path = null)
|
||||||
{
|
{
|
||||||
var temp = path ?? createTemporaryBeatmap();
|
var temp = path ?? createTemporaryBeatmap();
|
||||||
|
|
||||||
@ -305,7 +305,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
return osu;
|
return osu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureLoaded(OsuGameBase osu, int timeout = 60000)
|
private static void ensureLoaded(OsuGameBase osu, int timeout = 60000)
|
||||||
{
|
{
|
||||||
IEnumerable<BeatmapSetInfo> resultSets = null;
|
IEnumerable<BeatmapSetInfo> resultSets = null;
|
||||||
var store = osu.Dependencies.Get<BeatmapManager>();
|
var store = osu.Dependencies.Get<BeatmapManager>();
|
||||||
@ -343,7 +343,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
Assert.IsTrue(beatmap?.HitObjects.Any() == true);
|
Assert.IsTrue(beatmap?.HitObjects.Any() == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
|
private static void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
|
||||||
{
|
{
|
||||||
Task task = Task.Run(() =>
|
Task task = Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
32
osu.Game.Tests/Visual/TestCaseAccountCreationOverlay.cs
Normal file
32
osu.Game.Tests/Visual/TestCaseAccountCreationOverlay.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.AccountCreation;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseAccountCreationOverlay : OsuTestCase
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(ErrorTextFlowContainer),
|
||||||
|
typeof(AccountCreationBackground),
|
||||||
|
typeof(ScreenEntry),
|
||||||
|
typeof(ScreenWarning),
|
||||||
|
typeof(ScreenWelcome),
|
||||||
|
typeof(AccountCreationScreen),
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestCaseAccountCreationOverlay()
|
||||||
|
{
|
||||||
|
var accountCreation = new AccountCreationOverlay();
|
||||||
|
Child = accountCreation;
|
||||||
|
|
||||||
|
accountCreation.State = Visibility.Visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
osu.Game.Tests/Visual/TestCaseDrawableDate.cs
Normal file
67
osu.Game.Tests/Visual/TestCaseDrawableDate.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseDrawableDate : OsuTestCase
|
||||||
|
{
|
||||||
|
public TestCaseDrawableDate()
|
||||||
|
{
|
||||||
|
Child = new FillFlowContainer
|
||||||
|
{
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(60))),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(55))),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(50))),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Add(TimeSpan.FromSeconds(60))),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Add(TimeSpan.FromSeconds(65))),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Add(TimeSpan.FromSeconds(70))),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PokeyDrawableDate : CompositeDrawable
|
||||||
|
{
|
||||||
|
public PokeyDrawableDate(DateTimeOffset date)
|
||||||
|
{
|
||||||
|
const float box_size = 10;
|
||||||
|
|
||||||
|
DrawableDate drawableDate;
|
||||||
|
Box flash;
|
||||||
|
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
flash = new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Yellow,
|
||||||
|
Size = new Vector2(box_size),
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Alpha = 0
|
||||||
|
},
|
||||||
|
drawableDate = new DrawableDate(date)
|
||||||
|
{
|
||||||
|
X = box_size + 2,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
drawableDate.Current.ValueChanged += v => flash.FadeOutFromOne(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,135 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
using osu.Game.Online.Multiplayer;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Screens.Multi.Components;
|
|
||||||
using osu.Game.Users;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class TestCaseDrawableRoom : OsuTestCase
|
|
||||||
{
|
|
||||||
private RulesetStore rulesets;
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
DrawableRoom first;
|
|
||||||
Add(new FillFlowContainer
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Width = 580f,
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
first = new DrawableRoom(new Room
|
|
||||||
{
|
|
||||||
Name = { Value = @"Great Room Right Here" },
|
|
||||||
Host = { Value = new User { Username = @"Naeferith", Id = 9492835, Country = new Country { FlagName = @"FR" } } },
|
|
||||||
Status = { Value = new RoomStatusOpen() },
|
|
||||||
Type = { Value = new GameTypeTeamVersus() },
|
|
||||||
Beatmap =
|
|
||||||
{
|
|
||||||
Value = new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 4.65,
|
|
||||||
Ruleset = rulesets.GetRuleset(3),
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Title = @"Critical Crystal",
|
|
||||||
Artist = @"Seiryu",
|
|
||||||
},
|
|
||||||
BeatmapSet = new BeatmapSetInfo
|
|
||||||
{
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
|
||||||
Cover = @"https://assets.ppy.sh//beatmaps/376340/covers/cover.jpg?1456478455",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Participants =
|
|
||||||
{
|
|
||||||
Value = new[]
|
|
||||||
{
|
|
||||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 1355 } } },
|
|
||||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 8756 } } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
new DrawableRoom(new Room
|
|
||||||
{
|
|
||||||
Name = { Value = @"Relax It's The Weekend" },
|
|
||||||
Host = { Value = new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" } } },
|
|
||||||
Status = { Value = new RoomStatusPlaying() },
|
|
||||||
Type = { Value = new GameTypeTagTeam() },
|
|
||||||
Beatmap =
|
|
||||||
{
|
|
||||||
Value = new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 1.96,
|
|
||||||
Ruleset = rulesets.GetRuleset(0),
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Title = @"Serendipity",
|
|
||||||
Artist = @"ZAQ",
|
|
||||||
},
|
|
||||||
BeatmapSet = new BeatmapSetInfo
|
|
||||||
{
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
|
||||||
Cover = @"https://assets.ppy.sh//beatmaps/526839/covers/cover.jpg?1493815706",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Participants =
|
|
||||||
{
|
|
||||||
Value = new[]
|
|
||||||
{
|
|
||||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 578975 } } },
|
|
||||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24554 } } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep(@"select", () => first.State = SelectionState.Selected);
|
|
||||||
AddStep(@"change title", () => first.Room.Name.Value = @"I Changed Name");
|
|
||||||
AddStep(@"change host", () => first.Room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } });
|
|
||||||
AddStep(@"change status", () => first.Room.Status.Value = new RoomStatusPlaying());
|
|
||||||
AddStep(@"change type", () => first.Room.Type.Value = new GameTypeVersus());
|
|
||||||
AddStep(@"change beatmap", () => first.Room.Beatmap.Value = null);
|
|
||||||
AddStep(@"change participants", () => first.Room.Participants.Value = new[]
|
|
||||||
{
|
|
||||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 1254 } } },
|
|
||||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 123189 } } },
|
|
||||||
});
|
|
||||||
AddStep(@"deselect", () => first.State = SelectionState.NotSelected);
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(RulesetStore rulesets)
|
|
||||||
{
|
|
||||||
this.rulesets = rulesets;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,6 +11,7 @@ using osu.Framework.Allocation;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.Leaderboards;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Size = new Vector2(550f, 450f),
|
Size = new Vector2(550f, 450f),
|
||||||
Scope = LeaderboardScope.Global,
|
Scope = BeatmapLeaderboardScope.Global,
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep(@"New Scores", newScores);
|
AddStep(@"New Scores", newScores);
|
||||||
@ -275,7 +276,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FailableLeaderboard : Leaderboard
|
private class FailableLeaderboard : BeatmapLeaderboard
|
||||||
{
|
{
|
||||||
public void SetRetrievalState(PlaceholderState state)
|
public void SetRetrievalState(PlaceholderState state)
|
||||||
{
|
{
|
||||||
|
@ -1,216 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Online.Multiplayer;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Screens;
|
|
||||||
using osu.Game.Screens.Backgrounds;
|
|
||||||
using osu.Game.Screens.Multi.Components;
|
|
||||||
using osu.Game.Screens.Multi.Screens.Lounge;
|
|
||||||
using osu.Game.Users;
|
|
||||||
using osuTK.Input;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class TestCaseLounge : ManualInputManagerTestCase
|
|
||||||
{
|
|
||||||
private TestLounge lounge;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(RulesetStore rulesets)
|
|
||||||
{
|
|
||||||
lounge = new TestLounge();
|
|
||||||
|
|
||||||
Room[] rooms =
|
|
||||||
{
|
|
||||||
new Room
|
|
||||||
{
|
|
||||||
Name = { Value = @"Just Another Room" },
|
|
||||||
Host = { Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } } },
|
|
||||||
Status = { Value = new RoomStatusPlaying() },
|
|
||||||
Availability = { Value = RoomAvailability.Public },
|
|
||||||
Type = { Value = new GameTypeTagTeam() },
|
|
||||||
Beatmap =
|
|
||||||
{
|
|
||||||
Value = new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 5.65,
|
|
||||||
Ruleset = rulesets.GetRuleset(0),
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Title = @"Sidetracked Day (Short Ver.)",
|
|
||||||
Artist = @"VINXIS",
|
|
||||||
AuthorString = @"Hobbes2",
|
|
||||||
},
|
|
||||||
BeatmapSet = new BeatmapSetInfo
|
|
||||||
{
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/767600/covers/cover.jpg?1526243446",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MaxParticipants = { Value = 10 },
|
|
||||||
Participants =
|
|
||||||
{
|
|
||||||
Value = new[]
|
|
||||||
{
|
|
||||||
new User { Username = @"flyte", Id = 3103765, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 142 } } },
|
|
||||||
new User { Username = @"Cookiezi", Id = 124493, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 546 } } },
|
|
||||||
new User { Username = @"Angelsim", Id = 1777162, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 287 } } },
|
|
||||||
new User { Username = @"Rafis", Id = 2558286, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 468 } } },
|
|
||||||
new User { Username = @"hvick225", Id = 50265, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 325 } } },
|
|
||||||
new User { Username = @"peppy", Id = 2, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 625 } } },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Room
|
|
||||||
{
|
|
||||||
Name = { Value = @"Not Just Any Room" },
|
|
||||||
Host = { Value = new User { Username = @"Monstrata", Id = 2706438, Country = new Country { FlagName = @"CA" } } },
|
|
||||||
Status = { Value = new RoomStatusOpen() },
|
|
||||||
Availability = { Value = RoomAvailability.FriendsOnly },
|
|
||||||
Type = { Value = new GameTypeTeamVersus() },
|
|
||||||
Beatmap =
|
|
||||||
{
|
|
||||||
Value = new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 2.73,
|
|
||||||
Ruleset = rulesets.GetRuleset(0),
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Title = @"lit(var)",
|
|
||||||
Artist = @"kensuke ushio",
|
|
||||||
AuthorString = @"Monstrata",
|
|
||||||
},
|
|
||||||
BeatmapSet = new BeatmapSetInfo
|
|
||||||
{
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/623972/covers/cover.jpg?1521167183",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Participants =
|
|
||||||
{
|
|
||||||
Value = new[]
|
|
||||||
{
|
|
||||||
new User { Username = @"Jeby", Id = 3136279, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 3497 } } },
|
|
||||||
new User { Username = @"DualAkira", Id = 5220933, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 643 } } },
|
|
||||||
new User { Username = @"Datenshi Yohane", Id = 7171857, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 10555 } } },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Room
|
|
||||||
{
|
|
||||||
Name = { Value = @"room THE FINAL" },
|
|
||||||
Host = { Value = new User { Username = @"Delis", Id = 1603923, Country = new Country { FlagName = @"JP" } } },
|
|
||||||
Status = { Value = new RoomStatusPlaying() },
|
|
||||||
Availability = { Value = RoomAvailability.Public },
|
|
||||||
Type = { Value = new GameTypeTagTeam() },
|
|
||||||
Beatmap =
|
|
||||||
{
|
|
||||||
Value = new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 4.48,
|
|
||||||
Ruleset = rulesets.GetRuleset(3),
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Title = @"ONIGIRI FREEWAY",
|
|
||||||
Artist = @"OISHII",
|
|
||||||
AuthorString = @"Mentholzzz",
|
|
||||||
},
|
|
||||||
BeatmapSet = new BeatmapSetInfo
|
|
||||||
{
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/663098/covers/cover.jpg?1521898837",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MaxParticipants = { Value = 30 },
|
|
||||||
Participants =
|
|
||||||
{
|
|
||||||
Value = new[]
|
|
||||||
{
|
|
||||||
new User { Username = @"KizuA", Id = 6510442, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 5372 } } },
|
|
||||||
new User { Username = @"Colored", Id = 827563, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 810 } } },
|
|
||||||
new User { Username = @"Beryl", Id = 3817591, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 10096 } } },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
AddStep(@"show", () => Add(lounge));
|
|
||||||
AddStep(@"set rooms", () => lounge.Rooms = rooms);
|
|
||||||
selectAssert(0);
|
|
||||||
AddStep(@"clear rooms", () => lounge.Rooms = new Room[] {});
|
|
||||||
AddAssert(@"no room selected", () => lounge.SelectedRoom == null);
|
|
||||||
AddStep(@"set rooms", () => lounge.Rooms = rooms);
|
|
||||||
selectAssert(1);
|
|
||||||
AddStep(@"open room 1", () => clickRoom(1));
|
|
||||||
AddUntilStep(() => lounge.ChildScreen?.IsCurrentScreen == true, "wait until room current");
|
|
||||||
AddStep(@"make lounge current", lounge.MakeCurrent);
|
|
||||||
filterAssert(@"THE FINAL", LoungeTab.Public, 1);
|
|
||||||
filterAssert(string.Empty, LoungeTab.Public, 2);
|
|
||||||
filterAssert(string.Empty, LoungeTab.Private, 1);
|
|
||||||
filterAssert(string.Empty, LoungeTab.Public, 2);
|
|
||||||
filterAssert(@"no matches", LoungeTab.Public, 0);
|
|
||||||
AddStep(@"clear rooms", () => lounge.Rooms = new Room[] {});
|
|
||||||
AddStep(@"set rooms", () => lounge.Rooms = rooms);
|
|
||||||
AddAssert(@"no matches after clear", () => !lounge.ChildRooms.Any());
|
|
||||||
filterAssert(string.Empty, LoungeTab.Public, 2);
|
|
||||||
AddStep(@"exit", lounge.Exit);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clickRoom(int n)
|
|
||||||
{
|
|
||||||
InputManager.MoveMouseTo(lounge.ChildRooms.ElementAt(n));
|
|
||||||
InputManager.Click(MouseButton.Left);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectAssert(int n)
|
|
||||||
{
|
|
||||||
AddStep($@"select room {n}", () => clickRoom(n));
|
|
||||||
AddAssert($@"room {n} selected", () => lounge.SelectedRoom == lounge.ChildRooms.ElementAt(n).Room);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void filterAssert(string filter, LoungeTab tab, int endCount)
|
|
||||||
{
|
|
||||||
AddStep($@"filter '{filter}', {tab}", () => lounge.SetFilter(filter, tab));
|
|
||||||
AddAssert(@"filtered correctly", () => lounge.ChildRooms.Count() == endCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestLounge : Lounge
|
|
||||||
{
|
|
||||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenDefault();
|
|
||||||
|
|
||||||
public IEnumerable<DrawableRoom> ChildRooms => RoomsContainer.Children.Where(r => r.MatchingFilter);
|
|
||||||
public Room SelectedRoom => Inspector.Room;
|
|
||||||
|
|
||||||
public void SetFilter(string filter, LoungeTab tab)
|
|
||||||
{
|
|
||||||
Filter.Search.Current.Value = filter;
|
|
||||||
Filter.Tabs.Current.Value = tab;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
99
osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs
Normal file
99
osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Screens.Multi;
|
||||||
|
using osu.Game.Screens.Multi.Lounge.Components;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseLoungeRoomsContainer : OsuTestCase
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(RoomsContainer),
|
||||||
|
typeof(DrawableRoom)
|
||||||
|
};
|
||||||
|
|
||||||
|
[Cached(Type = typeof(IRoomManager))]
|
||||||
|
private TestRoomManager roomManager = new TestRoomManager();
|
||||||
|
|
||||||
|
public TestCaseLoungeRoomsContainer()
|
||||||
|
{
|
||||||
|
RoomsContainer container;
|
||||||
|
|
||||||
|
Child = container = new RoomsContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Width = 0.5f,
|
||||||
|
JoinRequested = joinRequested
|
||||||
|
};
|
||||||
|
|
||||||
|
AddStep("clear rooms", () => roomManager.Rooms.Clear());
|
||||||
|
|
||||||
|
AddStep("add rooms", () =>
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
roomManager.Rooms.Add(new Room
|
||||||
|
{
|
||||||
|
RoomID = { Value = i },
|
||||||
|
Name = { Value = $"Room {i}" },
|
||||||
|
Host = { Value = new User { Username = "Host" } },
|
||||||
|
EndDate = { Value = DateTimeOffset.Now + TimeSpan.FromSeconds(10) }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("has 2 rooms", () => container.Rooms.Count == 3);
|
||||||
|
AddStep("remove first room", () => roomManager.Rooms.Remove(roomManager.Rooms.FirstOrDefault()));
|
||||||
|
AddAssert("has 2 rooms", () => container.Rooms.Count == 2);
|
||||||
|
AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID.Value != 0));
|
||||||
|
|
||||||
|
AddStep("select first room", () => container.Rooms.First().Action?.Invoke());
|
||||||
|
AddAssert("first room selected", () => container.SelectedRoom.Value == roomManager.Rooms.First());
|
||||||
|
|
||||||
|
AddStep("join first room", () => container.Rooms.First().Action?.Invoke());
|
||||||
|
AddAssert("first room joined", () => roomManager.Rooms.First().Status.Value is JoinedRoomStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void joinRequested(Room room) => room.Status.Value = new JoinedRoomStatus();
|
||||||
|
|
||||||
|
private class TestRoomManager : IRoomManager
|
||||||
|
{
|
||||||
|
public readonly BindableCollection<Room> Rooms = new BindableCollection<Room>();
|
||||||
|
IBindableCollection<Room> IRoomManager.Rooms => Rooms;
|
||||||
|
|
||||||
|
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null) => Rooms.Add(room);
|
||||||
|
|
||||||
|
public void JoinRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PartRoom()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Filter(FilterCriteria criteria)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class JoinedRoomStatus : RoomStatus
|
||||||
|
{
|
||||||
|
public override string Message => "Joined";
|
||||||
|
|
||||||
|
public override Color4 GetAppropriateColour(OsuColour colours) => colours.Yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,142 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Online.Multiplayer;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Screens.Multi.Screens.Match;
|
|
||||||
using osu.Game.Users;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class TestCaseMatch : OsuTestCase
|
|
||||||
{
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(RulesetStore rulesets)
|
|
||||||
{
|
|
||||||
Room room = new Room
|
|
||||||
{
|
|
||||||
Name = { Value = @"One Awesome Room" },
|
|
||||||
Status = { Value = new RoomStatusOpen() },
|
|
||||||
Availability = { Value = RoomAvailability.Public },
|
|
||||||
Type = { Value = new GameTypeTeamVersus() },
|
|
||||||
Beatmap =
|
|
||||||
{
|
|
||||||
Value = new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 5.02,
|
|
||||||
Ruleset = rulesets.GetRuleset(1),
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Title = @"Paradigm Shift",
|
|
||||||
Artist = @"Morimori Atsushi",
|
|
||||||
AuthorString = @"eiri-",
|
|
||||||
},
|
|
||||||
BeatmapSet = new BeatmapSetInfo
|
|
||||||
{
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/765055/covers/cover.jpg?1526955337",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MaxParticipants = { Value = 5 },
|
|
||||||
Participants =
|
|
||||||
{
|
|
||||||
Value = new[]
|
|
||||||
{
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"eiri-",
|
|
||||||
Id = 3388410,
|
|
||||||
Country = new Country { FlagName = @"US" },
|
|
||||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/3388410/00a8486a247831e1cc4375db519f611ac970bda8bc0057d78b0f540ea38c3e58.jpeg",
|
|
||||||
IsSupporter = true,
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"Nepuri",
|
|
||||||
Id = 6637817,
|
|
||||||
Country = new Country { FlagName = @"DE" },
|
|
||||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/6637817/9085fc60248b6b5327a72c1dcdecf2dbedba810ae0ab6bcf7224e46b1339632a.jpeg",
|
|
||||||
IsSupporter = true,
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"goheegy",
|
|
||||||
Id = 8057655,
|
|
||||||
Country = new Country { FlagName = @"GB" },
|
|
||||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/8057655/21cec27c25a11dc197a4ec6a74253dbabb495949b0e0697113352f12007018c5.jpeg",
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"Alumetri",
|
|
||||||
Id = 5371497,
|
|
||||||
Country = new Country { FlagName = @"RU" },
|
|
||||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/5371497/e023b8c7fbe3613e64bd4856703517ea50fbed8a5805dc9acda9efe9897c67e2.jpeg",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
Match match = new Match(room);
|
|
||||||
|
|
||||||
AddStep(@"show", () => Add(match));
|
|
||||||
AddStep(@"null beatmap", () => room.Beatmap.Value = null);
|
|
||||||
AddStep(@"change name", () => room.Name.Value = @"Two Awesome Rooms");
|
|
||||||
AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying());
|
|
||||||
AddStep(@"change availability", () => room.Availability.Value = RoomAvailability.FriendsOnly);
|
|
||||||
AddStep(@"change type", () => room.Type.Value = new GameTypeTag());
|
|
||||||
AddStep(@"change beatmap", () => room.Beatmap.Value = new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 4.33,
|
|
||||||
Ruleset = rulesets.GetRuleset(2),
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Title = @"Yasashisa no Riyuu",
|
|
||||||
Artist = @"ChouCho",
|
|
||||||
AuthorString = @"celerih",
|
|
||||||
},
|
|
||||||
BeatmapSet = new BeatmapSetInfo
|
|
||||||
{
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/685391/covers/cover.jpg?1524597970",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep(@"null max participants", () => room.MaxParticipants.Value = null);
|
|
||||||
AddStep(@"change participants", () => room.Participants.Value = new[]
|
|
||||||
{
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"Spectator",
|
|
||||||
Id = 702598,
|
|
||||||
Country = new Country { FlagName = @"KR" },
|
|
||||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/702598/3bbf4cb8b8d2cf8b03145000a975ff27e191ab99b0920832e7dd67386280e288.jpeg",
|
|
||||||
IsSupporter = true,
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"celerih",
|
|
||||||
Id = 4696296,
|
|
||||||
Country = new Country { FlagName = @"CA" },
|
|
||||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/4696296/7f8500731d0ac66d5472569d146a7be07d9460273361913f22c038867baddaef.jpeg",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep(@"exit", match.Exit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +1,54 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using NUnit.Framework;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Screens.Multi.Screens.Match;
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Multiplayer.GameTypes;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
|
using osu.Game.Screens.Multi.Match.Components;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
[TestFixture]
|
|
||||||
public class TestCaseMatchHeader : OsuTestCase
|
public class TestCaseMatchHeader : OsuTestCase
|
||||||
{
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(Header)
|
||||||
|
};
|
||||||
|
|
||||||
public TestCaseMatchHeader()
|
public TestCaseMatchHeader()
|
||||||
{
|
{
|
||||||
Header header = new Header();
|
var room = new Room();
|
||||||
Add(header);
|
|
||||||
|
|
||||||
AddStep(@"set beatmap set", () => header.BeatmapSet = new BeatmapSetInfo
|
var header = new Header(room);
|
||||||
|
|
||||||
|
room.Playlist.Add(new PlaylistItem
|
||||||
{
|
{
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
Beatmap = new BeatmapInfo
|
||||||
{
|
{
|
||||||
Covers = new BeatmapSetOnlineCovers
|
Metadata = new BeatmapMetadata
|
||||||
{
|
{
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/760757/covers/cover.jpg?1526944540",
|
Title = "Title",
|
||||||
|
Artist = "Artist",
|
||||||
|
AuthorString = "Author",
|
||||||
},
|
},
|
||||||
|
Version = "Version",
|
||||||
|
Ruleset = new OsuRuleset().RulesetInfo
|
||||||
},
|
},
|
||||||
|
RequiredMods =
|
||||||
|
{
|
||||||
|
new OsuModDoubleTime(),
|
||||||
|
new OsuModNoFail(),
|
||||||
|
new OsuModRelax(),
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep(@"change beatmap set", () => header.BeatmapSet = new BeatmapSetInfo
|
room.Type.Value = new GameTypeTimeshift();
|
||||||
{
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/761883/covers/cover.jpg?1525557400",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep(@"null beatmap set", () => header.BeatmapSet = null);
|
Child = header;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs
Normal file
35
osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Screens.Multi.Match.Components;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseMatchHostInfo : OsuTestCase
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(HostInfo)
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly Bindable<User> host = new Bindable<User>(new User { Username = "SomeHost" });
|
||||||
|
|
||||||
|
public TestCaseMatchHostInfo()
|
||||||
|
{
|
||||||
|
HostInfo hostInfo;
|
||||||
|
|
||||||
|
Child = hostInfo = new HostInfo
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre
|
||||||
|
};
|
||||||
|
|
||||||
|
hostInfo.Host.BindTo(host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,28 +1,46 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Multiplayer.RoomStatuses;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Screens.Multi.Screens.Match;
|
using osu.Game.Screens.Multi.Match.Components;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseMatchInfo : OsuTestCase
|
public class TestCaseMatchInfo : OsuTestCase
|
||||||
{
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(Info),
|
||||||
|
typeof(HeaderButton),
|
||||||
|
typeof(ReadyButton),
|
||||||
|
typeof(ViewBeatmapButton)
|
||||||
|
};
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(RulesetStore rulesets)
|
private void load(RulesetStore rulesets)
|
||||||
{
|
{
|
||||||
Info info = new Info();
|
var room = new Room();
|
||||||
|
|
||||||
|
Info info = new Info(room);
|
||||||
Add(info);
|
Add(info);
|
||||||
|
|
||||||
AddStep(@"set name", () => info.Name = @"Room Name?");
|
AddStep(@"set name", () => room.Name.Value = @"Room Name?");
|
||||||
AddStep(@"set availability", () => info.Availability = RoomAvailability.FriendsOnly);
|
AddStep(@"set availability", () => room.Availability.Value = RoomAvailability.FriendsOnly);
|
||||||
AddStep(@"set status", () => info.Status = new RoomStatusPlaying());
|
AddStep(@"set status", () => room.Status.Value = new RoomStatusPlaying());
|
||||||
AddStep(@"set beatmap", () => info.Beatmap = new BeatmapInfo
|
AddStep(@"set beatmap", () =>
|
||||||
|
{
|
||||||
|
room.Playlist.Clear();
|
||||||
|
room.Playlist.Add(new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = new BeatmapInfo
|
||||||
{
|
{
|
||||||
StarDifficulty = 2.4,
|
StarDifficulty = 2.4,
|
||||||
Ruleset = rulesets.GetRuleset(0),
|
Ruleset = rulesets.GetRuleset(0),
|
||||||
@ -32,16 +50,20 @@ namespace osu.Game.Tests.Visual
|
|||||||
Artist = @"VisualTests",
|
Artist = @"VisualTests",
|
||||||
AuthorString = @"osu!lazer",
|
AuthorString = @"osu!lazer",
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep(@"set type", () => info.Type = new GameTypeTagTeam());
|
AddStep(@"change name", () => room.Name.Value = @"Room Name!");
|
||||||
|
AddStep(@"change availability", () => room.Availability.Value = RoomAvailability.InviteOnly);
|
||||||
AddStep(@"change name", () => info.Name = @"Room Name!");
|
AddStep(@"change status", () => room.Status.Value = new RoomStatusOpen());
|
||||||
AddStep(@"change availability", () => info.Availability = RoomAvailability.InviteOnly);
|
AddStep(@"null beatmap", () => room.Playlist.Clear());
|
||||||
AddStep(@"change status", () => info.Status = new RoomStatusOpen());
|
AddStep(@"change beatmap", () =>
|
||||||
AddStep(@"null beatmap", () => info.Beatmap = null);
|
{
|
||||||
AddStep(@"change type", () => info.Type = new GameTypeTeamVersus());
|
room.Playlist.Clear();
|
||||||
AddStep(@"change beatmap", () => info.Beatmap = new BeatmapInfo
|
room.Playlist.Add(new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = new BeatmapInfo
|
||||||
{
|
{
|
||||||
StarDifficulty = 4.2,
|
StarDifficulty = 4.2,
|
||||||
Ruleset = rulesets.GetRuleset(3),
|
Ruleset = rulesets.GetRuleset(3),
|
||||||
@ -51,6 +73,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
Artist = @"Tester",
|
Artist = @"Tester",
|
||||||
AuthorString = @"Someone",
|
AuthorString = @"Someone",
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
68
osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs
Normal file
68
osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Screens.Multi.Match.Components;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseMatchLeaderboard : OsuTestCase
|
||||||
|
{
|
||||||
|
public TestCaseMatchLeaderboard()
|
||||||
|
{
|
||||||
|
Add(new MatchLeaderboard(new Room { RoomID = { Value = 3 } })
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Size = new Vector2(550f, 450f),
|
||||||
|
Scope = MatchLeaderboardScope.Overall,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private APIAccess api { get; set; }
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
var req = new GetRoomScoresRequest();
|
||||||
|
req.Success += v => { };
|
||||||
|
req.Failure += _ => { };
|
||||||
|
|
||||||
|
api.Queue(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class GetRoomScoresRequest : APIRequest<List<RoomScore>>
|
||||||
|
{
|
||||||
|
protected override string Target => "rooms/3/leaderboard";
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RoomScore
|
||||||
|
{
|
||||||
|
[JsonProperty("user")]
|
||||||
|
public User User { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("accuracy")]
|
||||||
|
public double Accuracy { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("total_score")]
|
||||||
|
public int TotalScore { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("pp")]
|
||||||
|
public double PP { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("attempts")]
|
||||||
|
public int TotalAttempts { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("completed")]
|
||||||
|
public int CompletedAttempts { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Screens.Multi.Screens.Match;
|
using osu.Game.Screens.Multi.Match.Components;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
@ -11,16 +13,20 @@ namespace osu.Game.Tests.Visual
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseMatchParticipants : OsuTestCase
|
public class TestCaseMatchParticipants : OsuTestCase
|
||||||
{
|
{
|
||||||
|
private readonly Bindable<int?> maxParticipants = new Bindable<int?>();
|
||||||
|
private readonly Bindable<IEnumerable<User>> users = new Bindable<IEnumerable<User>>();
|
||||||
|
|
||||||
public TestCaseMatchParticipants()
|
public TestCaseMatchParticipants()
|
||||||
{
|
{
|
||||||
Participants participants;
|
Participants participants;
|
||||||
Add(participants = new Participants
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep(@"set max to null", () => participants.Max = null);
|
Add(participants = new Participants { RelativeSizeAxes = Axes.Both });
|
||||||
AddStep(@"set users", () => participants.Users = new[]
|
|
||||||
|
participants.MaxParticipants.BindTo(maxParticipants);
|
||||||
|
participants.Users.BindTo(users);
|
||||||
|
|
||||||
|
AddStep(@"set max to null", () => maxParticipants.Value = null);
|
||||||
|
AddStep(@"set users", () => users.Value = new[]
|
||||||
{
|
{
|
||||||
new User
|
new User
|
||||||
{
|
{
|
||||||
@ -48,9 +54,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep(@"set max", () => participants.Max = 10);
|
AddStep(@"set max", () => maxParticipants.Value = 10);
|
||||||
AddStep(@"clear users", () => participants.Users = new User[] { });
|
AddStep(@"clear users", () => users.Value = new User[] { });
|
||||||
AddStep(@"set max to null", () => participants.Max = null);
|
AddStep(@"set max to null", () => maxParticipants.Value = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
123
osu.Game.Tests/Visual/TestCaseMatchResults.cs
Normal file
123
osu.Game.Tests/Visual/TestCaseMatchResults.cs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Multi.Match.Components;
|
||||||
|
using osu.Game.Screens.Multi.Ranking;
|
||||||
|
using osu.Game.Screens.Multi.Ranking.Pages;
|
||||||
|
using osu.Game.Screens.Multi.Ranking.Types;
|
||||||
|
using osu.Game.Screens.Ranking;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseMatchResults : OsuTestCase
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(MatchResults),
|
||||||
|
typeof(RoomLeaderboardPageInfo),
|
||||||
|
typeof(RoomLeaderboardPage)
|
||||||
|
};
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapManager beatmaps { get; set; }
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
|
||||||
|
if (beatmapInfo != null)
|
||||||
|
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
||||||
|
|
||||||
|
Child = new TestMatchResults(new ScoreInfo
|
||||||
|
{
|
||||||
|
User = new User { Id = 10 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestMatchResults : MatchResults
|
||||||
|
{
|
||||||
|
private readonly Room room;
|
||||||
|
|
||||||
|
public TestMatchResults(ScoreInfo score)
|
||||||
|
: this(score, new Room
|
||||||
|
{
|
||||||
|
RoomID = { Value = 1 },
|
||||||
|
Name = { Value = "an awesome room" }
|
||||||
|
})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestMatchResults(ScoreInfo score, Room room)
|
||||||
|
: base(score, room)
|
||||||
|
{
|
||||||
|
this.room = room;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<IResultPageInfo> CreateResultPages() => new[] { new TestRoomLeaderboardPageInfo(Score, Beatmap, room) };
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestRoomLeaderboardPageInfo : RoomLeaderboardPageInfo
|
||||||
|
{
|
||||||
|
private readonly ScoreInfo score;
|
||||||
|
private readonly WorkingBeatmap beatmap;
|
||||||
|
private readonly Room room;
|
||||||
|
|
||||||
|
public TestRoomLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap, Room room)
|
||||||
|
: base(score, beatmap, room)
|
||||||
|
{
|
||||||
|
this.score = score;
|
||||||
|
this.beatmap = beatmap;
|
||||||
|
this.room = room;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ResultsPage CreatePage() => new TestRoomLeaderboardPage(score, beatmap, room);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestRoomLeaderboardPage : RoomLeaderboardPage
|
||||||
|
{
|
||||||
|
public TestRoomLeaderboardPage(ScoreInfo score, WorkingBeatmap beatmap, Room room)
|
||||||
|
: base(score, beatmap, room)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override MatchLeaderboard CreateLeaderboard(Room room) => new TestMatchLeaderboard(room);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestMatchLeaderboard : RoomLeaderboardPage.ResultsMatchLeaderboard
|
||||||
|
{
|
||||||
|
public TestMatchLeaderboard(Room room)
|
||||||
|
: base(room)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override APIRequest FetchScores(Action<IEnumerable<APIRoomScoreInfo>> scoresCallback)
|
||||||
|
{
|
||||||
|
var scores = Enumerable.Range(0, 50).Select(createRoomScore).ToArray();
|
||||||
|
|
||||||
|
scoresCallback?.Invoke(scores);
|
||||||
|
ScoresLoaded?.Invoke(scores);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private APIRoomScoreInfo createRoomScore(int id) => new APIRoomScoreInfo
|
||||||
|
{
|
||||||
|
User = new User { Id = id, Username = $"User {id}" },
|
||||||
|
Accuracy = 0.98,
|
||||||
|
TotalScore = 987654,
|
||||||
|
TotalAttempts = 13,
|
||||||
|
CompletedBeatmaps = 5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
159
osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs
Normal file
159
osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Screens.Multi;
|
||||||
|
using osu.Game.Screens.Multi.Lounge.Components;
|
||||||
|
using osu.Game.Screens.Multi.Match.Components;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseMatchSettingsOverlay : OsuTestCase
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(MatchSettingsOverlay)
|
||||||
|
};
|
||||||
|
|
||||||
|
[Cached(Type = typeof(IRoomManager))]
|
||||||
|
private TestRoomManager roomManager = new TestRoomManager();
|
||||||
|
|
||||||
|
private Room room;
|
||||||
|
private TestRoomSettings settings;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup() => Schedule(() =>
|
||||||
|
{
|
||||||
|
room = new Room();
|
||||||
|
settings = new TestRoomSettings(room)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
State = Visibility.Visible
|
||||||
|
};
|
||||||
|
|
||||||
|
Child = settings;
|
||||||
|
});
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestButtonEnabledOnlyWithNameAndBeatmap()
|
||||||
|
{
|
||||||
|
AddStep("clear name and beatmap", () =>
|
||||||
|
{
|
||||||
|
room.Name.Value = "";
|
||||||
|
room.Playlist.Clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("button disabled", () => !settings.ApplyButton.Enabled);
|
||||||
|
|
||||||
|
AddStep("set name", () => room.Name.Value = "Room name");
|
||||||
|
AddAssert("button disabled", () => !settings.ApplyButton.Enabled);
|
||||||
|
|
||||||
|
AddStep("set beatmap", () => room.Playlist.Add(new PlaylistItem { Beatmap = new DummyWorkingBeatmap().BeatmapInfo }));
|
||||||
|
AddAssert("button enabled", () => settings.ApplyButton.Enabled);
|
||||||
|
|
||||||
|
AddStep("clear name", () => room.Name.Value = "");
|
||||||
|
AddAssert("button disabled", () => !settings.ApplyButton.Enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCorrectSettingsApplied()
|
||||||
|
{
|
||||||
|
const string expected_name = "expected name";
|
||||||
|
TimeSpan expectedDuration = TimeSpan.FromMinutes(15);
|
||||||
|
|
||||||
|
Room createdRoom = null;
|
||||||
|
|
||||||
|
AddStep("setup", () =>
|
||||||
|
{
|
||||||
|
settings.NameField.Current.Value = expected_name;
|
||||||
|
settings.DurationField.Current.Value = expectedDuration;
|
||||||
|
|
||||||
|
roomManager.CreateRequested = r =>
|
||||||
|
{
|
||||||
|
createdRoom = r;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("create room", () => settings.ApplyButton.Action.Invoke());
|
||||||
|
AddAssert("has correct name", () => createdRoom.Name.Value == expected_name);
|
||||||
|
AddAssert("has correct duration", () => createdRoom.Duration.Value == expectedDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCreationFailureDisplaysError()
|
||||||
|
{
|
||||||
|
bool fail;
|
||||||
|
|
||||||
|
AddStep("setup", () =>
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
roomManager.CreateRequested = _ => !fail;
|
||||||
|
});
|
||||||
|
AddAssert("error not displayed", () => !settings.ErrorText.IsPresent);
|
||||||
|
|
||||||
|
AddStep("create room", () => settings.ApplyButton.Action.Invoke());
|
||||||
|
AddAssert("error displayed", () => settings.ErrorText.IsPresent);
|
||||||
|
AddAssert("error has correct text", () => settings.ErrorText.Text == TestRoomManager.FAILED_TEXT);
|
||||||
|
|
||||||
|
AddStep("create room no fail", () =>
|
||||||
|
{
|
||||||
|
fail = false;
|
||||||
|
settings.ApplyButton.Action.Invoke();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep(() => !settings.ErrorText.IsPresent, "error not displayed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestRoomSettings : MatchSettingsOverlay
|
||||||
|
{
|
||||||
|
public new TriangleButton ApplyButton => base.ApplyButton;
|
||||||
|
|
||||||
|
public new OsuTextBox NameField => base.NameField;
|
||||||
|
public new OsuDropdown<TimeSpan> DurationField => base.DurationField;
|
||||||
|
|
||||||
|
public new OsuSpriteText ErrorText => base.ErrorText;
|
||||||
|
|
||||||
|
public TestRoomSettings(Room room)
|
||||||
|
: base(room)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestRoomManager : IRoomManager
|
||||||
|
{
|
||||||
|
public const string FAILED_TEXT = "failed";
|
||||||
|
|
||||||
|
public Func<Room, bool> CreateRequested;
|
||||||
|
|
||||||
|
public IBindableCollection<Room> Rooms { get; } = null;
|
||||||
|
|
||||||
|
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
|
||||||
|
{
|
||||||
|
if (CreateRequested == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!CreateRequested.Invoke(room))
|
||||||
|
onError?.Invoke(FAILED_TEXT);
|
||||||
|
else
|
||||||
|
onSuccess?.Invoke(room);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void JoinRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public void PartRoom() => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public void Filter(FilterCriteria criteria) => throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Screens;
|
||||||
using osu.Game.Screens.Multi;
|
using osu.Game.Screens.Multi;
|
||||||
using osu.Game.Screens.Multi.Screens.Lounge;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
@ -13,15 +13,31 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
public TestCaseMultiHeader()
|
public TestCaseMultiHeader()
|
||||||
{
|
{
|
||||||
Lounge lounge;
|
int index = 0;
|
||||||
|
|
||||||
|
OsuScreen currentScreen = new TestMultiplayerSubScreen(index);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
lounge = new Lounge
|
currentScreen,
|
||||||
{
|
new Header(currentScreen)
|
||||||
Padding = new MarginPadding { Top = Header.HEIGHT },
|
|
||||||
},
|
|
||||||
new Header(lounge),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AddStep("push multi screen", () => currentScreen.Push(currentScreen = new TestMultiplayerSubScreen(++index)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestMultiplayerSubScreen : OsuScreen, IMultiplayerSubScreen
|
||||||
|
{
|
||||||
|
private readonly int index;
|
||||||
|
|
||||||
|
public string ShortTitle => $"Screen {index}";
|
||||||
|
|
||||||
|
public TestMultiplayerSubScreen(int index)
|
||||||
|
{
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() => ShortTitle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,25 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Screens.Multi;
|
using osu.Game.Screens.Multi;
|
||||||
|
using osu.Game.Screens.Multi.Lounge;
|
||||||
|
using osu.Game.Screens.Multi.Lounge.Components;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseMultiScreen : OsuTestCase
|
public class TestCaseMultiScreen : OsuTestCase
|
||||||
{
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(Multiplayer),
|
||||||
|
typeof(LoungeSubScreen),
|
||||||
|
typeof(FilterControl)
|
||||||
|
};
|
||||||
|
|
||||||
public TestCaseMultiScreen()
|
public TestCaseMultiScreen()
|
||||||
{
|
{
|
||||||
Multiplayer multi = new Multiplayer();
|
Multiplayer multi = new Multiplayer();
|
||||||
|
@ -87,10 +87,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
usage.Migrate();
|
usage.Migrate();
|
||||||
|
|
||||||
Dependencies.Cache(rulesets = new RulesetStore(factory));
|
Dependencies.Cache(rulesets = new RulesetStore(factory));
|
||||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null)
|
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null, null, defaultBeatmap = Beatmap.Default));
|
||||||
{
|
|
||||||
DefaultBeatmap = defaultBeatmap = Beatmap.Default
|
|
||||||
});
|
|
||||||
|
|
||||||
Beatmap.SetDefault();
|
Beatmap.SetDefault();
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
Beatmap.Value = new DummyWorkingBeatmap(game);
|
Beatmap.Value = new DummyWorkingBeatmap(game);
|
||||||
|
|
||||||
AddStep("load dummy beatmap", () => Add(loader = new PlayerLoader(new Player
|
AddStep("load dummy beatmap", () => Add(loader = new PlayerLoader(() => new Player
|
||||||
{
|
{
|
||||||
AllowPause = false,
|
AllowPause = false,
|
||||||
AllowLeadIn = false,
|
AllowLeadIn = false,
|
||||||
@ -30,9 +30,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
AddStep("load slow dummy beatmap", () =>
|
AddStep("load slow dummy beatmap", () =>
|
||||||
{
|
{
|
||||||
SlowLoadPlayer slow;
|
SlowLoadPlayer slow = null;
|
||||||
|
|
||||||
Add(loader = new PlayerLoader(slow = new SlowLoadPlayer
|
Add(loader = new PlayerLoader(() => slow = new SlowLoadPlayer
|
||||||
{
|
{
|
||||||
AllowPause = false,
|
AllowPause = false,
|
||||||
AllowLeadIn = false,
|
AllowLeadIn = false,
|
||||||
|
143
osu.Game.Tests/Visual/TestCasePollingComponent.cs
Normal file
143
osu.Game.Tests/Visual/TestCasePollingComponent.cs
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Logging;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Online;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCasePollingComponent : OsuTestCase
|
||||||
|
{
|
||||||
|
private Container pollBox;
|
||||||
|
private TestPoller poller;
|
||||||
|
|
||||||
|
private const float safety_adjust = 1f;
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp() => Schedule(() =>
|
||||||
|
{
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
pollBox = new Container
|
||||||
|
{
|
||||||
|
Alpha = 0,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Scale = new Vector2(0.4f),
|
||||||
|
Colour = Color4.LimeGreen,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Text = "Poll!",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestInstantPolling()
|
||||||
|
{
|
||||||
|
createPoller(true);
|
||||||
|
|
||||||
|
AddStep("set poll interval to 1", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust);
|
||||||
|
checkCount(1);
|
||||||
|
checkCount(2);
|
||||||
|
checkCount(3);
|
||||||
|
|
||||||
|
AddStep("set poll interval to 5", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust * 5);
|
||||||
|
checkCount(4);
|
||||||
|
checkCount(4);
|
||||||
|
checkCount(4);
|
||||||
|
|
||||||
|
skip();
|
||||||
|
|
||||||
|
checkCount(5);
|
||||||
|
checkCount(5);
|
||||||
|
|
||||||
|
AddStep("set poll interval to 1", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust);
|
||||||
|
checkCount(6);
|
||||||
|
checkCount(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Ignore("i have no idea how to fix the timing of this one")]
|
||||||
|
public void TestSlowPolling()
|
||||||
|
{
|
||||||
|
createPoller(false);
|
||||||
|
|
||||||
|
AddStep("set poll interval to 1", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust * 5);
|
||||||
|
checkCount(0);
|
||||||
|
skip();
|
||||||
|
checkCount(0);
|
||||||
|
skip();
|
||||||
|
skip();
|
||||||
|
checkCount(0);
|
||||||
|
skip();
|
||||||
|
skip();
|
||||||
|
checkCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skip() => AddStep("skip", () =>
|
||||||
|
{
|
||||||
|
// could be 4 or 5 at this point due to timing discrepancies (safety_adjust @ 0.2 * 5 ~= 1)
|
||||||
|
// easiest to just ignore the value at this point and move on.
|
||||||
|
});
|
||||||
|
|
||||||
|
private void checkCount(int checkValue)
|
||||||
|
{
|
||||||
|
Logger.Log($"value is {count}");
|
||||||
|
AddAssert($"count is {checkValue}", () => count == checkValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPoller(bool instant) => AddStep("create poller", () =>
|
||||||
|
{
|
||||||
|
poller?.Expire();
|
||||||
|
|
||||||
|
Add(poller = instant ? new TestPoller() : new TestSlowPoller());
|
||||||
|
poller.OnPoll += () =>
|
||||||
|
{
|
||||||
|
pollBox.FadeOutFromOne(500);
|
||||||
|
count++;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
protected override double TimePerAction => 500;
|
||||||
|
|
||||||
|
public class TestPoller : PollingComponent
|
||||||
|
{
|
||||||
|
public event Action OnPoll;
|
||||||
|
|
||||||
|
protected override Task Poll()
|
||||||
|
{
|
||||||
|
Schedule(() => OnPoll?.Invoke());
|
||||||
|
return base.Poll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestSlowPoller : TestPoller
|
||||||
|
{
|
||||||
|
protected override Task Poll() => Task.Delay((int)(TimeBetweenPolls / 2f / Clock.Rate)).ContinueWith(_ => base.Poll());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,9 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
|
using osu.Game.Screens.Ranking.Pages;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
@ -23,8 +25,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
typeof(ScoreInfo),
|
typeof(ScoreInfo),
|
||||||
typeof(Results),
|
typeof(Results),
|
||||||
typeof(ResultsPage),
|
typeof(ResultsPage),
|
||||||
typeof(ResultsPageScore),
|
typeof(ScoreResultsPage),
|
||||||
typeof(ResultsPageRanking)
|
typeof(LocalLeaderboardPage)
|
||||||
};
|
};
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -41,7 +43,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
if (beatmapInfo != null)
|
if (beatmapInfo != null)
|
||||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
||||||
|
|
||||||
Add(new Results(new ScoreInfo
|
Add(new SoloResults(new ScoreInfo
|
||||||
{
|
{
|
||||||
TotalScore = 2845370,
|
TotalScore = 2845370,
|
||||||
Accuracy = 0.98,
|
Accuracy = 0.98,
|
||||||
|
@ -1,147 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Online.Multiplayer;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Screens.Multi.Components;
|
|
||||||
using osu.Game.Users;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class TestCaseRoomInspector : OsuTestCase
|
|
||||||
{
|
|
||||||
private RulesetStore rulesets;
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
Room room = new Room
|
|
||||||
{
|
|
||||||
Name = { Value = @"My Awesome Room" },
|
|
||||||
Host = { Value = new User { Username = @"flyte", Id = 3103765, Country = new Country { FlagName = @"JP" } } },
|
|
||||||
Status = { Value = new RoomStatusOpen() },
|
|
||||||
Type = { Value = new GameTypeTeamVersus() },
|
|
||||||
Beatmap =
|
|
||||||
{
|
|
||||||
Value = new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 3.7,
|
|
||||||
Ruleset = rulesets.GetRuleset(3),
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Title = @"Platina",
|
|
||||||
Artist = @"Maaya Sakamoto",
|
|
||||||
AuthorString = @"uwutm8",
|
|
||||||
},
|
|
||||||
BeatmapSet = new BeatmapSetInfo
|
|
||||||
{
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/560573/covers/cover.jpg?1492722343",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MaxParticipants = { Value = 200 },
|
|
||||||
Participants =
|
|
||||||
{
|
|
||||||
Value = new[]
|
|
||||||
{
|
|
||||||
new User { Username = @"flyte", Id = 3103765, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 142 } } },
|
|
||||||
new User { Username = @"Cookiezi", Id = 124493, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 546 } } },
|
|
||||||
new User { Username = @"Angelsim", Id = 1777162, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 287 } } },
|
|
||||||
new User { Username = @"Rafis", Id = 2558286, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 468 } } },
|
|
||||||
new User { Username = @"hvick225", Id = 50265, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 325 } } },
|
|
||||||
new User { Username = @"peppy", Id = 2, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 625 } } },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RoomInspector inspector;
|
|
||||||
Add(inspector = new RoomInspector
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Width = 0.5f,
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep(@"set room", () => inspector.Room = room);
|
|
||||||
AddStep(@"null room", () => inspector.Room = null);
|
|
||||||
AddStep(@"set room", () => inspector.Room = room);
|
|
||||||
AddStep(@"change title", () => room.Name.Value = @"A Better Room Than The Above");
|
|
||||||
AddStep(@"change host", () => room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } });
|
|
||||||
AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying());
|
|
||||||
AddStep(@"change type", () => room.Type.Value = new GameTypeTag());
|
|
||||||
AddStep(@"change beatmap", () => room.Beatmap.Value = null);
|
|
||||||
AddStep(@"change max participants", () => room.MaxParticipants.Value = null);
|
|
||||||
AddStep(@"change participants", () => room.Participants.Value = new[]
|
|
||||||
{
|
|
||||||
new User { Username = @"filsdelama", Id = 2831793, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 854 } } },
|
|
||||||
new User { Username = @"_index", Id = 652457, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 150 } } }
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep(@"change room", () =>
|
|
||||||
{
|
|
||||||
Room newRoom = new Room
|
|
||||||
{
|
|
||||||
Name = { Value = @"My New, Better Than Ever Room" },
|
|
||||||
Host = { Value = new User { Username = @"Angelsim", Id = 1777162, Country = new Country { FlagName = @"KR" } } },
|
|
||||||
Status = { Value = new RoomStatusOpen() },
|
|
||||||
Type = { Value = new GameTypeTagTeam() },
|
|
||||||
Beatmap =
|
|
||||||
{
|
|
||||||
Value = new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 7.07,
|
|
||||||
Ruleset = rulesets.GetRuleset(0),
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Title = @"FREEDOM DIVE",
|
|
||||||
Artist = @"xi",
|
|
||||||
AuthorString = @"Nakagawa-Kanon",
|
|
||||||
},
|
|
||||||
BeatmapSet = new BeatmapSetInfo
|
|
||||||
{
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/39804/covers/cover.jpg?1456506845",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MaxParticipants = { Value = 10 },
|
|
||||||
Participants =
|
|
||||||
{
|
|
||||||
Value = new[]
|
|
||||||
{
|
|
||||||
new User { Username = @"Angelsim", Id = 1777162, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 4 } } },
|
|
||||||
new User { Username = @"HappyStick", Id = 256802, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 752 } } },
|
|
||||||
new User { Username = @"-Konpaku-", Id = 2258797, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 571 } } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inspector.Room = newRoom;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(RulesetStore rulesets)
|
|
||||||
{
|
|
||||||
this.rulesets = rulesets;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Testing.Input;
|
|
||||||
using osu.Game.Online.Multiplayer;
|
|
||||||
using osu.Game.Screens.Multi.Screens.Match.Settings;
|
|
||||||
using osuTK.Input;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class TestCaseRoomSettings : ManualInputManagerTestCase
|
|
||||||
{
|
|
||||||
private readonly Room room;
|
|
||||||
private readonly TestRoomSettingsOverlay overlay;
|
|
||||||
|
|
||||||
public TestCaseRoomSettings()
|
|
||||||
{
|
|
||||||
room = new Room
|
|
||||||
{
|
|
||||||
Name = { Value = "One Testing Room" },
|
|
||||||
Availability = { Value = RoomAvailability.Public },
|
|
||||||
Type = { Value = new GameTypeTeamVersus() },
|
|
||||||
MaxParticipants = { Value = 10 },
|
|
||||||
};
|
|
||||||
|
|
||||||
Add(overlay = new TestRoomSettingsOverlay(room)
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Height = 0.75f,
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep(@"show", overlay.Show);
|
|
||||||
assertAll();
|
|
||||||
AddStep(@"set name", () => overlay.CurrentName = @"Two Testing Room");
|
|
||||||
AddStep(@"set max", () => overlay.CurrentMaxParticipants = null);
|
|
||||||
AddStep(@"set availability", () => overlay.CurrentAvailability = RoomAvailability.InviteOnly);
|
|
||||||
AddStep(@"set type", () => overlay.CurrentType = new GameTypeTagTeam());
|
|
||||||
apply();
|
|
||||||
assertAll();
|
|
||||||
AddStep(@"show", overlay.Show);
|
|
||||||
AddStep(@"set room name", () => room.Name.Value = @"Room Changed Name!");
|
|
||||||
AddStep(@"set room availability", () => room.Availability.Value = RoomAvailability.Public);
|
|
||||||
AddStep(@"set room type", () => room.Type.Value = new GameTypeTag());
|
|
||||||
AddStep(@"set room max", () => room.MaxParticipants.Value = 100);
|
|
||||||
assertAll();
|
|
||||||
AddStep(@"set name", () => overlay.CurrentName = @"Unsaved Testing Room");
|
|
||||||
AddStep(@"set max", () => overlay.CurrentMaxParticipants = 20);
|
|
||||||
AddStep(@"set availability", () => overlay.CurrentAvailability = RoomAvailability.FriendsOnly);
|
|
||||||
AddStep(@"set type", () => overlay.CurrentType = new GameTypeVersus());
|
|
||||||
AddStep(@"hide", overlay.Hide);
|
|
||||||
AddWaitStep(5);
|
|
||||||
AddStep(@"show", overlay.Show);
|
|
||||||
assertAll();
|
|
||||||
AddStep(@"hide", overlay.Hide);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void apply()
|
|
||||||
{
|
|
||||||
AddStep(@"apply", () =>
|
|
||||||
{
|
|
||||||
overlay.ClickApplyButton(InputManager);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertAll()
|
|
||||||
{
|
|
||||||
AddAssert(@"name == room name", () => overlay.CurrentName == room.Name.Value);
|
|
||||||
AddAssert(@"max == room max", () => overlay.CurrentMaxParticipants == room.MaxParticipants.Value);
|
|
||||||
AddAssert(@"availability == room availability", () => overlay.CurrentAvailability == room.Availability.Value);
|
|
||||||
AddAssert(@"type == room type", () => Equals(overlay.CurrentType, room.Type.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestRoomSettingsOverlay : RoomSettingsOverlay
|
|
||||||
{
|
|
||||||
public string CurrentName
|
|
||||||
{
|
|
||||||
get => NameField.Text;
|
|
||||||
set => NameField.Text = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int? CurrentMaxParticipants
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (int.TryParse(MaxParticipantsField.Text, out int max))
|
|
||||||
return max;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
set => MaxParticipantsField.Text = value?.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public RoomAvailability CurrentAvailability
|
|
||||||
{
|
|
||||||
get => AvailabilityPicker.Current.Value;
|
|
||||||
set => AvailabilityPicker.Current.Value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameType CurrentType
|
|
||||||
{
|
|
||||||
get => TypePicker.Current.Value;
|
|
||||||
set => TypePicker.Current.Value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestRoomSettingsOverlay(Room room) : base(room)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClickApplyButton(ManualInputManager inputManager)
|
|
||||||
{
|
|
||||||
inputManager.MoveMouseTo(ApplyButton);
|
|
||||||
inputManager.Click(MouseButton.Left);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
50
osu.Game.Tests/Visual/TestCaseRoomStatus.cs
Normal file
50
osu.Game.Tests/Visual/TestCaseRoomStatus.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Multiplayer.RoomStatuses;
|
||||||
|
using osu.Game.Screens.Multi.Lounge.Components;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseRoomStatus : OsuTestCase
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(RoomStatusEnded),
|
||||||
|
typeof(RoomStatusOpen),
|
||||||
|
typeof(RoomStatusPlaying)
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestCaseRoomStatus()
|
||||||
|
{
|
||||||
|
Child = new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Width = 0.5f,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new DrawableRoom(new Room
|
||||||
|
{
|
||||||
|
Name = { Value = "Room 1" },
|
||||||
|
Status = { Value = new RoomStatusOpen() }
|
||||||
|
}),
|
||||||
|
new DrawableRoom(new Room
|
||||||
|
{
|
||||||
|
Name = { Value = "Room 2" },
|
||||||
|
Status = { Value = new RoomStatusPlaying() }
|
||||||
|
}),
|
||||||
|
new DrawableRoom(new Room
|
||||||
|
{
|
||||||
|
Name = { Value = "Room 3" },
|
||||||
|
Status = { Value = new RoomStatusEnded() }
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
osu.Game.Tests/Visual/TestCaseStandAloneChatDisplay.cs
Normal file
104
osu.Game.Tests/Visual/TestCaseStandAloneChatDisplay.cs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Online.Chat;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseStandAloneChatDisplay : OsuTestCase
|
||||||
|
{
|
||||||
|
private readonly Channel testChannel = new Channel();
|
||||||
|
|
||||||
|
private readonly User admin = new User
|
||||||
|
{
|
||||||
|
Username = "HappyStick",
|
||||||
|
Id = 2,
|
||||||
|
Colour = "f2ca34"
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly User redUser = new User
|
||||||
|
{
|
||||||
|
Username = "BanchoBot",
|
||||||
|
Id = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly User blueUser = new User
|
||||||
|
{
|
||||||
|
Username = "Zallius",
|
||||||
|
Id = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
private ChannelManager channelManager = new ChannelManager();
|
||||||
|
|
||||||
|
private readonly StandAloneChatDisplay chatDisplay;
|
||||||
|
private readonly StandAloneChatDisplay chatDisplay2;
|
||||||
|
|
||||||
|
public TestCaseStandAloneChatDisplay()
|
||||||
|
{
|
||||||
|
Add(channelManager);
|
||||||
|
|
||||||
|
Add(chatDisplay = new StandAloneChatDisplay
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Margin = new MarginPadding(20),
|
||||||
|
Size = new Vector2(400, 80)
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(chatDisplay2 = new StandAloneChatDisplay(true)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreRight,
|
||||||
|
Origin = Anchor.CentreRight,
|
||||||
|
Margin = new MarginPadding(20),
|
||||||
|
Size = new Vector2(400, 150)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
channelManager.CurrentChannel.Value = testChannel;
|
||||||
|
|
||||||
|
chatDisplay.Channel.Value = testChannel;
|
||||||
|
chatDisplay2.Channel.Value = testChannel;
|
||||||
|
|
||||||
|
int sequence = 0;
|
||||||
|
|
||||||
|
AddStep("message from admin", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||||
|
{
|
||||||
|
Sender = admin,
|
||||||
|
Content = "I am a wang!"
|
||||||
|
}));
|
||||||
|
|
||||||
|
AddStep("message from team red", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||||
|
{
|
||||||
|
Sender = redUser,
|
||||||
|
Content = "I am team red."
|
||||||
|
}));
|
||||||
|
|
||||||
|
AddStep("message from team red", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||||
|
{
|
||||||
|
Sender = redUser,
|
||||||
|
Content = "I plan to win!"
|
||||||
|
}));
|
||||||
|
|
||||||
|
AddStep("message from team blue", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||||
|
{
|
||||||
|
Sender = blueUser,
|
||||||
|
Content = "Not on my watch. Prepare to eat saaaaaaaaaand. Lots and lots of saaaaaaand."
|
||||||
|
}));
|
||||||
|
|
||||||
|
AddStep("message from admin", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||||
|
{
|
||||||
|
Sender = admin,
|
||||||
|
Content = "Okay okay, calm down guys. Let's do this!"
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.Drawables;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseUpdateableBeatmapBackgroundSprite : OsuTestCase
|
||||||
|
{
|
||||||
|
private UpdateableBeatmapBackgroundSprite backgroundSprite;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapManager beatmaps { get; set; }
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuGameBase osu, APIAccess api, RulesetStore rulesets)
|
||||||
|
{
|
||||||
|
Bindable<BeatmapInfo> beatmapBindable = new Bindable<BeatmapInfo>();
|
||||||
|
|
||||||
|
var imported = ImportBeatmapTest.LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
|
Child = backgroundSprite = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
|
backgroundSprite.Beatmap.BindTo(beatmapBindable);
|
||||||
|
|
||||||
|
var req = new GetBeatmapSetRequest(1);
|
||||||
|
api.Queue(req);
|
||||||
|
|
||||||
|
AddStep("null", () => beatmapBindable.Value = null);
|
||||||
|
|
||||||
|
AddStep("imported", () => beatmapBindable.Value = imported.Beatmaps.First());
|
||||||
|
|
||||||
|
if (api.IsLoggedIn)
|
||||||
|
{
|
||||||
|
AddUntilStep(() => req.Result != null, "wait for api response");
|
||||||
|
|
||||||
|
AddStep("online", () => beatmapBindable.Value = new BeatmapInfo
|
||||||
|
{
|
||||||
|
BeatmapSet = req.Result?.ToBeatmapSet(rulesets)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddStep("online (login first)", () => { });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||||
|
@ -59,7 +59,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A default representation of a WorkingBeatmap to use when no beatmap is available.
|
/// A default representation of a WorkingBeatmap to use when no beatmap is available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public WorkingBeatmap DefaultBeatmap { private get; set; }
|
public readonly WorkingBeatmap DefaultBeatmap;
|
||||||
|
|
||||||
public override string[] HandledExtensions => new[] { ".osz" };
|
public override string[] HandledExtensions => new[] { ".osz" };
|
||||||
|
|
||||||
@ -77,16 +77,19 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
private readonly List<DownloadBeatmapSetRequest> currentDownloads = new List<DownloadBeatmapSetRequest>();
|
private readonly List<DownloadBeatmapSetRequest> currentDownloads = new List<DownloadBeatmapSetRequest>();
|
||||||
|
|
||||||
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, IIpcHost importHost = null)
|
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, IIpcHost importHost = null,
|
||||||
|
WorkingBeatmap defaultBeatmap = null)
|
||||||
: base(storage, contextFactory, new BeatmapStore(contextFactory), importHost)
|
: base(storage, contextFactory, new BeatmapStore(contextFactory), importHost)
|
||||||
{
|
{
|
||||||
beatmaps = (BeatmapStore)ModelStore;
|
|
||||||
beatmaps.BeatmapHidden += b => BeatmapHidden?.Invoke(b);
|
|
||||||
beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b);
|
|
||||||
|
|
||||||
this.rulesets = rulesets;
|
this.rulesets = rulesets;
|
||||||
this.api = api;
|
this.api = api;
|
||||||
this.audioManager = audioManager;
|
this.audioManager = audioManager;
|
||||||
|
|
||||||
|
DefaultBeatmap = defaultBeatmap;
|
||||||
|
|
||||||
|
beatmaps = (BeatmapStore)ModelStore;
|
||||||
|
beatmaps.BeatmapHidden += b => BeatmapHidden?.Invoke(b);
|
||||||
|
beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive)
|
protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive)
|
||||||
|
@ -23,7 +23,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(TextureStore textures)
|
private void load(LargeTextureStore textures)
|
||||||
{
|
{
|
||||||
string resource = null;
|
string resource = null;
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -16,15 +17,16 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
{
|
{
|
||||||
public class DifficultyIcon : DifficultyColouredContainer
|
public class DifficultyIcon : DifficultyColouredContainer
|
||||||
{
|
{
|
||||||
private readonly BeatmapInfo beatmap;
|
private readonly RulesetInfo ruleset;
|
||||||
|
|
||||||
public DifficultyIcon(BeatmapInfo beatmap)
|
public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null)
|
||||||
: base(beatmap)
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
if (beatmap == null)
|
if (beatmap == null)
|
||||||
throw new ArgumentNullException(nameof(beatmap));
|
throw new ArgumentNullException(nameof(beatmap));
|
||||||
|
|
||||||
this.beatmap = beatmap;
|
this.ruleset = ruleset ?? beatmap.Ruleset;
|
||||||
|
|
||||||
Size = new Vector2(20);
|
Size = new Vector2(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +60,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
|
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
|
||||||
Icon = beatmap.Ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.fa_question_circle_o }
|
Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.fa_question_circle_o }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps.Drawables
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Display a baetmap background from a local source, but fallback to online source if not available.
|
||||||
|
/// </summary>
|
||||||
|
public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable<BeatmapInfo>
|
||||||
|
{
|
||||||
|
public readonly IBindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapManager beatmaps { get; set; }
|
||||||
|
|
||||||
|
public UpdateableBeatmapBackgroundSprite()
|
||||||
|
{
|
||||||
|
Beatmap.BindValueChanged(b => Model = b);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Drawable CreateDrawable(BeatmapInfo model)
|
||||||
|
{
|
||||||
|
Drawable drawable;
|
||||||
|
|
||||||
|
var localBeatmap = beatmaps.GetWorkingBeatmap(model);
|
||||||
|
|
||||||
|
if (localBeatmap.BeatmapInfo.ID == 0 && model?.BeatmapSet?.OnlineInfo != null)
|
||||||
|
drawable = new BeatmapSetCover(model.BeatmapSet);
|
||||||
|
else
|
||||||
|
drawable = new BeatmapBackgroundSprite(localBeatmap);
|
||||||
|
|
||||||
|
drawable.RelativeSizeAxes = Axes.Both;
|
||||||
|
drawable.Anchor = Anchor.Centre;
|
||||||
|
drawable.Origin = Anchor.Centre;
|
||||||
|
drawable.FillMode = FillMode.Fill;
|
||||||
|
|
||||||
|
return drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override double FadeDuration => 400;
|
||||||
|
}
|
||||||
|
}
|
@ -149,8 +149,10 @@ namespace osu.Game.Database
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
notification.Text = $"Importing ({++current} of {paths.Length})\n{Path.GetFileName(path)}";
|
notification.Text = $"Importing ({++current} of {paths.Length})\n{Path.GetFileName(path)}";
|
||||||
|
|
||||||
|
TModel import;
|
||||||
using (ArchiveReader reader = getReaderFrom(path))
|
using (ArchiveReader reader = getReaderFrom(path))
|
||||||
imported.Add(Import(reader));
|
imported.Add(import = Import(reader));
|
||||||
|
|
||||||
notification.Progress = (float)current / paths.Length;
|
notification.Progress = (float)current / paths.Length;
|
||||||
|
|
||||||
@ -160,7 +162,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 (File.Exists(path))
|
if (import != null && File.Exists(path))
|
||||||
File.Delete(path);
|
File.Delete(path);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
@ -61,11 +62,25 @@ namespace osu.Game.Graphics.Containers
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||||
|
=> createLink(AddText(text, creationParameters), text, url, linkType, linkArgument, tooltipText);
|
||||||
|
|
||||||
|
public void AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||||
|
=> createLink(AddText(text, creationParameters), text, tooltipText: tooltipText, action: action);
|
||||||
|
|
||||||
|
public void AddLink(IEnumerable<SpriteText> text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null)
|
||||||
{
|
{
|
||||||
AddInternal(new DrawableLinkCompiler(AddText(text, creationParameters).ToList())
|
foreach (var t in text)
|
||||||
|
AddArbitraryDrawable(t);
|
||||||
|
|
||||||
|
createLink(text, null, url, linkType, linkArgument, tooltipText);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createLink(IEnumerable<Drawable> drawables, string text, string url = null, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action action = null)
|
||||||
|
{
|
||||||
|
AddInternal(new DrawableLinkCompiler(drawables.OfType<SpriteText>().ToList())
|
||||||
{
|
{
|
||||||
TooltipText = tooltipText ?? (url != text ? url : string.Empty),
|
TooltipText = tooltipText ?? (url != text ? url : string.Empty),
|
||||||
Action = () =>
|
Action = action ?? (() =>
|
||||||
{
|
{
|
||||||
switch (linkType)
|
switch (linkType)
|
||||||
{
|
{
|
||||||
@ -104,7 +119,7 @@ namespace osu.Game.Graphics.Containers
|
|||||||
default:
|
default:
|
||||||
throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action.");
|
throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action.");
|
||||||
}
|
}
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ namespace osu.Game.Graphics.Containers
|
|||||||
|
|
||||||
private PreviewTrackManager previewTrackManager;
|
private PreviewTrackManager previewTrackManager;
|
||||||
|
|
||||||
|
|
||||||
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
|
@ -11,29 +11,43 @@ namespace osu.Game.Graphics.Containers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ShakeContainer : Container
|
public class ShakeContainer : Container
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The length of a single shake.
|
||||||
|
/// </summary>
|
||||||
|
public float ShakeDuration = 80;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total number of shakes. May be shortened if possible.
|
||||||
|
/// </summary>
|
||||||
|
public float TotalShakes = 4;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pixels of displacement per shake.
|
||||||
|
/// </summary>
|
||||||
|
public float ShakeMagnitude = 8;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shake the contents of this container.
|
/// Shake the contents of this container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="maximumLength">The maximum length the shake should last.</param>
|
/// <param name="maximumLength">The maximum length the shake should last.</param>
|
||||||
public void Shake(double maximumLength)
|
public void Shake(double? maximumLength = null)
|
||||||
{
|
{
|
||||||
const float shake_amount = 8;
|
const float shake_amount = 8;
|
||||||
const float shake_duration = 30;
|
|
||||||
|
|
||||||
// if we don't have enough time, don't bother shaking.
|
// if we don't have enough time, don't bother shaking.
|
||||||
if (maximumLength < shake_duration * 2)
|
if (maximumLength < ShakeDuration * 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var sequence = this.MoveToX(shake_amount, shake_duration / 2, Easing.OutSine).Then()
|
var sequence = this.MoveToX(shake_amount, ShakeDuration / 2, Easing.OutSine).Then()
|
||||||
.MoveToX(-shake_amount, shake_duration, Easing.InOutSine).Then();
|
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
|
||||||
|
|
||||||
// if we don't have enough time for the second shake, skip it.
|
// if we don't have enough time for the second shake, skip it.
|
||||||
if (maximumLength > shake_duration * 4)
|
if (!maximumLength.HasValue || maximumLength >= ShakeDuration * 4)
|
||||||
sequence = sequence
|
sequence = sequence
|
||||||
.MoveToX(shake_amount, shake_duration, Easing.InOutSine).Then()
|
.MoveToX(shake_amount, ShakeDuration, Easing.InOutSine).Then()
|
||||||
.MoveToX(-shake_amount, shake_duration, Easing.InOutSine).Then();
|
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
|
||||||
|
|
||||||
sequence.MoveToX(0, shake_duration / 2, Easing.InSine);
|
sequence.MoveToX(0, ShakeDuration / 2, Easing.InSine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
@ -11,13 +12,27 @@ namespace osu.Game.Graphics
|
|||||||
{
|
{
|
||||||
public class DrawableDate : OsuSpriteText, IHasTooltip
|
public class DrawableDate : OsuSpriteText, IHasTooltip
|
||||||
{
|
{
|
||||||
protected readonly DateTimeOffset Date;
|
private DateTimeOffset date;
|
||||||
|
|
||||||
|
public DateTimeOffset Date
|
||||||
|
{
|
||||||
|
get => date;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (date == value)
|
||||||
|
return;
|
||||||
|
date = value.ToLocalTime();
|
||||||
|
|
||||||
|
if (LoadState >= LoadState.Ready)
|
||||||
|
updateTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public DrawableDate(DateTimeOffset date)
|
public DrawableDate(DateTimeOffset date)
|
||||||
{
|
{
|
||||||
Font = "Exo2.0-RegularItalic";
|
Font = "Exo2.0-RegularItalic";
|
||||||
|
|
||||||
Date = date.ToLocalTime();
|
Date = date;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -39,14 +54,14 @@ namespace osu.Game.Graphics
|
|||||||
var diffToNow = DateTimeOffset.Now.Subtract(Date);
|
var diffToNow = DateTimeOffset.Now.Subtract(Date);
|
||||||
|
|
||||||
double timeUntilNextUpdate = 1000;
|
double timeUntilNextUpdate = 1000;
|
||||||
if (diffToNow.TotalSeconds > 60)
|
if (Math.Abs(diffToNow.TotalSeconds) > 120)
|
||||||
{
|
{
|
||||||
timeUntilNextUpdate *= 60;
|
timeUntilNextUpdate *= 60;
|
||||||
if (diffToNow.TotalMinutes > 60)
|
if (Math.Abs(diffToNow.TotalMinutes) > 120)
|
||||||
{
|
{
|
||||||
timeUntilNextUpdate *= 60;
|
timeUntilNextUpdate *= 60;
|
||||||
|
|
||||||
if (diffToNow.TotalHours > 24)
|
if (Math.Abs(diffToNow.TotalHours) > 48)
|
||||||
timeUntilNextUpdate *= 24;
|
timeUntilNextUpdate *= 24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,9 @@ using osuTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A loading spinner.
|
||||||
|
/// </summary>
|
||||||
public class LoadingAnimation : VisibilityContainer
|
public class LoadingAnimation : VisibilityContainer
|
||||||
{
|
{
|
||||||
private readonly SpriteIcon spinner;
|
private readonly SpriteIcon spinner;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -99,7 +100,20 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bindable<bool> Current { get; } = new Bindable<bool>();
|
private readonly Bindable<bool> current = new Bindable<bool>();
|
||||||
|
|
||||||
|
public Bindable<bool> Current
|
||||||
|
{
|
||||||
|
get => current;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
|
||||||
|
current.UnbindBindings();
|
||||||
|
current.BindTo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Color4 accentColour;
|
private Color4 accentColour;
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
|
56
osu.Game/Graphics/UserInterface/ProcessingOverlay.cs
Normal file
56
osu.Game/Graphics/UserInterface/ProcessingOverlay.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Graphics.UserInterface
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An overlay that will consume all available space and block input when required.
|
||||||
|
/// Useful for disabling all elements in a form and showing we are waiting on a response, for instance.
|
||||||
|
/// </summary>
|
||||||
|
public class ProcessingOverlay : VisibilityContainer
|
||||||
|
{
|
||||||
|
private const float transition_duration = 200;
|
||||||
|
|
||||||
|
public ProcessingOverlay()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Black,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0.9f,
|
||||||
|
},
|
||||||
|
new LoadingAnimation { State = Visibility.Visible }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool Handle(UIEvent e)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PopIn()
|
||||||
|
{
|
||||||
|
this.FadeIn(transition_duration * 2, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PopOut()
|
||||||
|
{
|
||||||
|
this.FadeOut(transition_duration, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,9 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
@ -102,7 +104,7 @@ namespace osu.Game.Online.API
|
|||||||
if (queue.Count == 0)
|
if (queue.Count == 0)
|
||||||
{
|
{
|
||||||
log.Add(@"Queueing a ping request");
|
log.Add(@"Queueing a ping request");
|
||||||
Queue(new ListChannelsRequest { Timeout = 5000 });
|
Queue(new GetUserRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -143,7 +145,8 @@ namespace osu.Game.Online.API
|
|||||||
|
|
||||||
if (!handleRequest(userReq))
|
if (!handleRequest(userReq))
|
||||||
{
|
{
|
||||||
Thread.Sleep(500);
|
if (State == APIState.Connecting)
|
||||||
|
State = APIState.Failing;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +162,7 @@ namespace osu.Game.Online.API
|
|||||||
//hard bail if we can't get a valid access token.
|
//hard bail if we can't get a valid access token.
|
||||||
if (authentication.RequestAccessToken() == null)
|
if (authentication.RequestAccessToken() == null)
|
||||||
{
|
{
|
||||||
Logout(false);
|
Logout();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +176,6 @@ namespace osu.Game.Online.API
|
|||||||
req = queue.Dequeue();
|
req = queue.Dequeue();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle failures better
|
|
||||||
handleRequest(req);
|
handleRequest(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,66 +191,65 @@ namespace osu.Game.Online.API
|
|||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password)
|
||||||
|
{
|
||||||
|
Debug.Assert(State == APIState.Offline);
|
||||||
|
|
||||||
|
var req = new RegistrationRequest
|
||||||
|
{
|
||||||
|
Url = $@"{Endpoint}/users",
|
||||||
|
Method = HttpMethod.Post,
|
||||||
|
Username = username,
|
||||||
|
Email = email,
|
||||||
|
Password = password
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
req.Perform();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return JObject.Parse(req.ResponseString).SelectToken("form_error", true).ToObject<RegistrationRequest.RegistrationRequestErrors>();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// if we couldn't deserialize the error message let's throw the original exception outwards.
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handle a single API request.
|
/// Handle a single API request.
|
||||||
|
/// Ensures all exceptions are caught and dealt with correctly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="req">The request.</param>
|
/// <param name="req">The request.</param>
|
||||||
/// <returns>true if we should remove this request from the queue.</returns>
|
/// <returns>true if the request succeeded.</returns>
|
||||||
private bool handleRequest(APIRequest req)
|
private bool handleRequest(APIRequest req)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.Log($@"Performing request {req}", LoggingTarget.Network);
|
|
||||||
req.Perform(this);
|
req.Perform(this);
|
||||||
|
|
||||||
//we could still be in initialisation, at which point we don't want to say we're Online yet.
|
//we could still be in initialisation, at which point we don't want to say we're Online yet.
|
||||||
if (IsLoggedIn)
|
if (IsLoggedIn) State = APIState.Online;
|
||||||
State = APIState.Online;
|
|
||||||
|
|
||||||
failureCount = 0;
|
failureCount = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (WebException we)
|
catch (WebException we)
|
||||||
{
|
{
|
||||||
HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode
|
handleWebException(we);
|
||||||
?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout);
|
|
||||||
|
|
||||||
// special cases for un-typed but useful message responses.
|
|
||||||
switch (we.Message)
|
|
||||||
{
|
|
||||||
case "Unauthorized":
|
|
||||||
statusCode = HttpStatusCode.Unauthorized;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (statusCode)
|
|
||||||
{
|
|
||||||
case HttpStatusCode.Unauthorized:
|
|
||||||
Logout(false);
|
|
||||||
return true;
|
|
||||||
case HttpStatusCode.RequestTimeout:
|
|
||||||
failureCount++;
|
|
||||||
log.Add($@"API failure count is now {failureCount}");
|
|
||||||
|
|
||||||
if (failureCount < 3)
|
|
||||||
//we might try again at an api level.
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
State = APIState.Failing;
|
|
||||||
flushQueue();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Fail(we);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (e is TimeoutException)
|
return false;
|
||||||
log.Add(@"API level timeout exception was hit");
|
|
||||||
|
|
||||||
req.Fail(e);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,6 +277,45 @@ namespace osu.Game.Online.API
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool handleWebException(WebException we)
|
||||||
|
{
|
||||||
|
HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode
|
||||||
|
?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout);
|
||||||
|
|
||||||
|
// special cases for un-typed but useful message responses.
|
||||||
|
switch (we.Message)
|
||||||
|
{
|
||||||
|
case "Unauthorized":
|
||||||
|
case "Forbidden":
|
||||||
|
statusCode = HttpStatusCode.Unauthorized;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (statusCode)
|
||||||
|
{
|
||||||
|
case HttpStatusCode.Unauthorized:
|
||||||
|
Logout();
|
||||||
|
return true;
|
||||||
|
case HttpStatusCode.RequestTimeout:
|
||||||
|
failureCount++;
|
||||||
|
log.Add($@"API failure count is now {failureCount}");
|
||||||
|
|
||||||
|
if (failureCount < 3)
|
||||||
|
//we might try again at an api level.
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (State == APIState.Online)
|
||||||
|
{
|
||||||
|
State = APIState.Failing;
|
||||||
|
flushQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsLoggedIn => LocalUser.Value.Id > 1;
|
public bool IsLoggedIn => LocalUser.Value.Id > 1;
|
||||||
|
|
||||||
public void Queue(APIRequest request)
|
public void Queue(APIRequest request)
|
||||||
@ -303,10 +343,9 @@ namespace osu.Game.Online.API
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Logout(bool clearUsername = true)
|
public void Logout()
|
||||||
{
|
{
|
||||||
flushQueue();
|
flushQueue();
|
||||||
if (clearUsername) ProvidedUsername = null;
|
|
||||||
password = null;
|
password = null;
|
||||||
authentication.Clear();
|
authentication.Clear();
|
||||||
LocalUser.Value = createGuestUser();
|
LocalUser.Value = createGuestUser();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.IO.Network;
|
using osu.Framework.IO.Network;
|
||||||
|
using osu.Framework.Logging;
|
||||||
|
|
||||||
namespace osu.Game.Online.API
|
namespace osu.Game.Online.API
|
||||||
{
|
{
|
||||||
@ -35,23 +36,12 @@ namespace osu.Game.Online.API
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class APIRequest
|
public abstract class APIRequest
|
||||||
{
|
{
|
||||||
/// <summary>
|
protected abstract string Target { get; }
|
||||||
/// The maximum amount of time before this request will fail.
|
|
||||||
/// </summary>
|
|
||||||
public int Timeout = WebRequest.DEFAULT_TIMEOUT;
|
|
||||||
|
|
||||||
protected virtual string Target => string.Empty;
|
|
||||||
|
|
||||||
protected virtual WebRequest CreateWebRequest() => new WebRequest(Uri);
|
protected virtual WebRequest CreateWebRequest() => new WebRequest(Uri);
|
||||||
|
|
||||||
protected virtual string Uri => $@"{API.Endpoint}/api/v2/{Target}";
|
protected virtual string Uri => $@"{API.Endpoint}/api/v2/{Target}";
|
||||||
|
|
||||||
private double remainingTime => Math.Max(0, Timeout - (DateTimeOffset.UtcNow - (startTime ?? DateTimeOffset.MinValue)).TotalMilliseconds);
|
|
||||||
|
|
||||||
public bool ExceededTimeout => remainingTime == 0;
|
|
||||||
|
|
||||||
private DateTimeOffset? startTime;
|
|
||||||
|
|
||||||
protected APIAccess API;
|
protected APIAccess API;
|
||||||
protected WebRequest WebRequest;
|
protected WebRequest WebRequest;
|
||||||
|
|
||||||
@ -75,27 +65,24 @@ namespace osu.Game.Online.API
|
|||||||
{
|
{
|
||||||
API = api;
|
API = api;
|
||||||
|
|
||||||
if (checkAndProcessFailure())
|
if (checkAndScheduleFailure())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (startTime == null)
|
|
||||||
startTime = DateTimeOffset.UtcNow;
|
|
||||||
|
|
||||||
if (remainingTime <= 0)
|
|
||||||
throw new TimeoutException(@"API request timeout hit");
|
|
||||||
|
|
||||||
WebRequest = CreateWebRequest();
|
WebRequest = CreateWebRequest();
|
||||||
WebRequest.Failed += Fail;
|
WebRequest.Failed += Fail;
|
||||||
WebRequest.AllowRetryOnTimeout = false;
|
WebRequest.AllowRetryOnTimeout = false;
|
||||||
WebRequest.AddHeader("Authorization", $"Bearer {api.AccessToken}");
|
WebRequest.AddHeader("Authorization", $"Bearer {api.AccessToken}");
|
||||||
|
|
||||||
if (checkAndProcessFailure())
|
if (checkAndScheduleFailure())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!WebRequest.Aborted) //could have been aborted by a Cancel() call
|
if (!WebRequest.Aborted) //could have been aborted by a Cancel() call
|
||||||
|
{
|
||||||
|
Logger.Log($@"Performing request {this}", LoggingTarget.Network);
|
||||||
WebRequest.Perform();
|
WebRequest.Perform();
|
||||||
|
}
|
||||||
|
|
||||||
if (checkAndProcessFailure())
|
if (checkAndScheduleFailure())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
api.Schedule(delegate { Success?.Invoke(); });
|
api.Schedule(delegate { Success?.Invoke(); });
|
||||||
@ -105,19 +92,25 @@ namespace osu.Game.Online.API
|
|||||||
|
|
||||||
public void Fail(Exception e)
|
public void Fail(Exception e)
|
||||||
{
|
{
|
||||||
cancelled = true;
|
if (WebRequest?.Completed == true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cancelled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cancelled = true;
|
||||||
WebRequest?.Abort();
|
WebRequest?.Abort();
|
||||||
|
|
||||||
|
Logger.Log($@"Failing request {this} ({e})", LoggingTarget.Network);
|
||||||
pendingFailure = () => Failure?.Invoke(e);
|
pendingFailure = () => Failure?.Invoke(e);
|
||||||
checkAndProcessFailure();
|
checkAndScheduleFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checked for cancellation or error. Also queues up the Failed event if we can.
|
/// Checked for cancellation or error. Also queues up the Failed event if we can.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Whether we are in a failed or cancelled state.</returns>
|
/// <returns>Whether we are in a failed or cancelled state.</returns>
|
||||||
private bool checkAndProcessFailure()
|
private bool checkAndScheduleFailure()
|
||||||
{
|
{
|
||||||
if (API == null || pendingFailure == null) return cancelled;
|
if (API == null || pendingFailure == null) return cancelled;
|
||||||
|
|
||||||
|
41
osu.Game/Online/API/RegistrationRequest.cs
Normal file
41
osu.Game/Online/API/RegistrationRequest.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Framework.IO.Network;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API
|
||||||
|
{
|
||||||
|
public class RegistrationRequest : WebRequest
|
||||||
|
{
|
||||||
|
internal string Username;
|
||||||
|
internal string Email;
|
||||||
|
internal string Password;
|
||||||
|
|
||||||
|
protected override void PrePerform()
|
||||||
|
{
|
||||||
|
AddParameter("user[username]", Username);
|
||||||
|
AddParameter("user[user_email]", Email);
|
||||||
|
AddParameter("user[password]", Password);
|
||||||
|
|
||||||
|
base.PrePerform();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RegistrationRequestErrors
|
||||||
|
{
|
||||||
|
public UserErrors User;
|
||||||
|
|
||||||
|
public class UserErrors
|
||||||
|
{
|
||||||
|
[JsonProperty("username")]
|
||||||
|
public string[] Username;
|
||||||
|
|
||||||
|
[JsonProperty("user_email")]
|
||||||
|
public string[] Email;
|
||||||
|
|
||||||
|
[JsonProperty("password")]
|
||||||
|
public string[] Password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
osu.Game/Online/API/Requests/CreateRoomRequest.cs
Normal file
35
osu.Game/Online/API/Requests/CreateRoomRequest.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Net.Http;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Framework.IO.Network;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class CreateRoomRequest : APIRequest<APICreatedRoom>
|
||||||
|
{
|
||||||
|
private readonly Room room;
|
||||||
|
|
||||||
|
public CreateRoomRequest(Room room)
|
||||||
|
{
|
||||||
|
this.room = room;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override WebRequest CreateWebRequest()
|
||||||
|
{
|
||||||
|
var req = base.CreateWebRequest();
|
||||||
|
|
||||||
|
req.ContentType = "application/json";
|
||||||
|
req.Method = HttpMethod.Post;
|
||||||
|
|
||||||
|
req.AddRaw(JsonConvert.SerializeObject(room));
|
||||||
|
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Target => "rooms";
|
||||||
|
}
|
||||||
|
}
|
30
osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs
Normal file
30
osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Net.Http;
|
||||||
|
using osu.Framework.IO.Network;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class CreateRoomScoreRequest : APIRequest<APIScoreToken>
|
||||||
|
{
|
||||||
|
private readonly int roomId;
|
||||||
|
private readonly int playlistItemId;
|
||||||
|
|
||||||
|
public CreateRoomScoreRequest(int roomId, int playlistItemId)
|
||||||
|
{
|
||||||
|
this.roomId = roomId;
|
||||||
|
this.playlistItemId = playlistItemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override WebRequest CreateWebRequest()
|
||||||
|
{
|
||||||
|
var req = base.CreateWebRequest();
|
||||||
|
req.Method = HttpMethod.Post;
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Target => $@"rooms/{roomId}/playlist/{playlistItemId}/scores";
|
||||||
|
}
|
||||||
|
}
|
20
osu.Game/Online/API/Requests/GetRoomScoresRequest.cs
Normal file
20
osu.Game/Online/API/Requests/GetRoomScoresRequest.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class GetRoomScoresRequest : APIRequest<List<APIRoomScoreInfo>>
|
||||||
|
{
|
||||||
|
private readonly int roomId;
|
||||||
|
|
||||||
|
public GetRoomScoresRequest(int roomId)
|
||||||
|
{
|
||||||
|
this.roomId = roomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Target => $@"rooms/{roomId}/leaderboard";
|
||||||
|
}
|
||||||
|
}
|
44
osu.Game/Online/API/Requests/GetRoomsRequest.cs
Normal file
44
osu.Game/Online/API/Requests/GetRoomsRequest.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Screens.Multi.Lounge.Components;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class GetRoomsRequest : APIRequest<List<Room>>
|
||||||
|
{
|
||||||
|
private readonly PrimaryFilter primaryFilter;
|
||||||
|
|
||||||
|
public GetRoomsRequest(PrimaryFilter primaryFilter)
|
||||||
|
{
|
||||||
|
this.primaryFilter = primaryFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Target
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string target = "rooms";
|
||||||
|
|
||||||
|
switch (primaryFilter)
|
||||||
|
{
|
||||||
|
case PrimaryFilter.Open:
|
||||||
|
break;
|
||||||
|
case PrimaryFilter.Owned:
|
||||||
|
target += "/owned";
|
||||||
|
break;
|
||||||
|
case PrimaryFilter.Participated:
|
||||||
|
target += "/participated";
|
||||||
|
break;
|
||||||
|
case PrimaryFilter.RecentlyEnded:
|
||||||
|
target += "/ended";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,15 +13,15 @@ namespace osu.Game.Online.API.Requests
|
|||||||
public class GetScoresRequest : APIRequest<APIScores>
|
public class GetScoresRequest : APIRequest<APIScores>
|
||||||
{
|
{
|
||||||
private readonly BeatmapInfo beatmap;
|
private readonly BeatmapInfo beatmap;
|
||||||
private readonly LeaderboardScope scope;
|
private readonly BeatmapLeaderboardScope scope;
|
||||||
private readonly RulesetInfo ruleset;
|
private readonly RulesetInfo ruleset;
|
||||||
|
|
||||||
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, LeaderboardScope scope = LeaderboardScope.Global)
|
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global)
|
||||||
{
|
{
|
||||||
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)}.");
|
||||||
|
|
||||||
if (scope == LeaderboardScope.Local)
|
if (scope == BeatmapLeaderboardScope.Local)
|
||||||
throw new InvalidOperationException("Should not attempt to request online scores for a local scoped leaderboard");
|
throw new InvalidOperationException("Should not attempt to request online scores for a local scoped leaderboard");
|
||||||
|
|
||||||
this.beatmap = beatmap;
|
this.beatmap = beatmap;
|
||||||
|
31
osu.Game/Online/API/Requests/JoinRoomRequest.cs
Normal file
31
osu.Game/Online/API/Requests/JoinRoomRequest.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Net.Http;
|
||||||
|
using osu.Framework.IO.Network;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class JoinRoomRequest : APIRequest
|
||||||
|
{
|
||||||
|
private readonly Room room;
|
||||||
|
private readonly User user;
|
||||||
|
|
||||||
|
public JoinRoomRequest(Room room, User user)
|
||||||
|
{
|
||||||
|
this.room = room;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override WebRequest CreateWebRequest()
|
||||||
|
{
|
||||||
|
var req = base.CreateWebRequest();
|
||||||
|
req.Method = HttpMethod.Put;
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Target => $"rooms/{room.RoomID.Value}/users/{user.Id}";
|
||||||
|
}
|
||||||
|
}
|
31
osu.Game/Online/API/Requests/PartRoomRequest.cs
Normal file
31
osu.Game/Online/API/Requests/PartRoomRequest.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Net.Http;
|
||||||
|
using osu.Framework.IO.Network;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class PartRoomRequest : APIRequest
|
||||||
|
{
|
||||||
|
private readonly Room room;
|
||||||
|
private readonly User user;
|
||||||
|
|
||||||
|
public PartRoomRequest(Room room, User user)
|
||||||
|
{
|
||||||
|
this.room = room;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override WebRequest CreateWebRequest()
|
||||||
|
{
|
||||||
|
var req = base.CreateWebRequest();
|
||||||
|
req.Method = HttpMethod.Delete;
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Target => $"rooms/{room.RoomID.Value}/users/{user.Id}";
|
||||||
|
}
|
||||||
|
}
|
@ -59,19 +59,17 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
|
|
||||||
public BeatmapInfo ToBeatmap(RulesetStore rulesets)
|
public BeatmapInfo ToBeatmap(RulesetStore rulesets)
|
||||||
{
|
{
|
||||||
|
var set = BeatmapSet?.ToBeatmapSet(rulesets);
|
||||||
|
|
||||||
return new BeatmapInfo
|
return new BeatmapInfo
|
||||||
{
|
{
|
||||||
Metadata = this,
|
Metadata = set?.Metadata ?? this,
|
||||||
Ruleset = rulesets.GetRuleset(ruleset),
|
Ruleset = rulesets.GetRuleset(ruleset),
|
||||||
StarDifficulty = starDifficulty,
|
StarDifficulty = starDifficulty,
|
||||||
OnlineBeatmapID = OnlineBeatmapID,
|
OnlineBeatmapID = OnlineBeatmapID,
|
||||||
Version = version,
|
Version = version,
|
||||||
Status = Status,
|
Status = Status,
|
||||||
BeatmapSet = new BeatmapSetInfo
|
BeatmapSet = set,
|
||||||
{
|
|
||||||
OnlineBeatmapSetID = OnlineBeatmapSetID,
|
|
||||||
Status = BeatmapSet?.Status ?? BeatmapSetOnlineStatus.None
|
|
||||||
},
|
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
{
|
{
|
||||||
DrainRate = drainRate,
|
DrainRate = drainRate,
|
||||||
|
14
osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs
Normal file
14
osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
|
{
|
||||||
|
public class APICreatedRoom : Room
|
||||||
|
{
|
||||||
|
[JsonProperty("error")]
|
||||||
|
public string Error { get; set; }
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user