mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 14:12:56 +08:00
Resolve merge conflicts in DirectOverlay
This commit is contained in:
commit
8702a70524
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,6 +1,3 @@
|
|||||||
[submodule "osu-framework"]
|
|
||||||
path = osu-framework
|
|
||||||
url = https://github.com/ppy/osu-framework
|
|
||||||
[submodule "osu-resources"]
|
[submodule "osu-resources"]
|
||||||
path = osu-resources
|
path = osu-resources
|
||||||
url = https://github.com/ppy/osu-resources
|
url = https://github.com/ppy/osu-resources
|
@ -1,21 +1,17 @@
|
|||||||
<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/net471/osu.Game.Rulesets.Catch.Tests.exe" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp2.1/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" />
|
||||||
<envs>
|
|
||||||
<env name="ASPNETCORE_ENVIRONMENT" value="Development" />
|
|
||||||
<env name="ASPNETCORE_URLS" value="http://localhost:5000" />
|
|
||||||
</envs>
|
|
||||||
<option name="USE_MONO" value="0" />
|
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
|
<option name="USE_MONO" value="0" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.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=".NETFramework,Version=v4.7.1" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method />
|
<method />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -1,21 +1,17 @@
|
|||||||
<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/net471/osu.Game.Rulesets.Mania.Tests.exe" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp2.1/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" />
|
||||||
<envs>
|
|
||||||
<env name="ASPNETCORE_ENVIRONMENT" value="Development" />
|
|
||||||
<env name="ASPNETCORE_URLS" value="http://localhost:5000" />
|
|
||||||
</envs>
|
|
||||||
<option name="USE_MONO" value="0" />
|
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
|
<option name="USE_MONO" value="0" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.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=".NETFramework,Version=v4.7.1" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method />
|
<method />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -1,21 +1,17 @@
|
|||||||
<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/net471/osu.Game.Rulesets.Osu.Tests.exe" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp2.1/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" />
|
||||||
<envs>
|
|
||||||
<env name="ASPNETCORE_ENVIRONMENT" value="Development" />
|
|
||||||
<env name="ASPNETCORE_URLS" value="http://localhost:5000" />
|
|
||||||
</envs>
|
|
||||||
<option name="USE_MONO" value="0" />
|
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
|
<option name="USE_MONO" value="0" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.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=".NETFramework,Version=v4.7.1" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method />
|
<method />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -1,21 +1,17 @@
|
|||||||
<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/net471/osu.Game.Rulesets.Taiko.Tests.exe" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp2.1/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" />
|
||||||
<envs>
|
|
||||||
<env name="ASPNETCORE_ENVIRONMENT" value="Development" />
|
|
||||||
<env name="ASPNETCORE_URLS" value="http://localhost:5000" />
|
|
||||||
</envs>
|
|
||||||
<option name="USE_MONO" value="0" />
|
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
|
<option name="USE_MONO" value="0" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.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=".NETFramework,Version=v4.7.1" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method />
|
<method />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="VisualTests (net471)" type="DotNetProject" factoryName=".NET Project" singleton="true">
|
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/net471/osu.Game.Tests.exe" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
|
||||||
<envs />
|
|
||||||
<option name="USE_MONO" value="0" />
|
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Tests/osu.Game.Tests.csproj" />
|
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
|
||||||
<option name="PROJECT_TFM" value=".NETFramework,Version=v4.7.1" />
|
|
||||||
<method />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="VisualTests (netcoreapp2.0)" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="VisualTests (netcoreapp2.1)" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.0/osu.Game.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.1/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" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<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.0" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||||
<method />
|
<method />
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
@ -1,18 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="osu! (net471)" type="DotNetProject" factoryName=".NET Project" singleton="true">
|
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net471/osu!.exe" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
|
||||||
<envs />
|
|
||||||
<option name="USE_MONO" value="0" />
|
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Desktop/osu.Desktop.csproj" />
|
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
|
||||||
<option name="PROJECT_TFM" value=".NETFramework,Version=v4.7.1" />
|
|
||||||
<method />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="osu! (netcoreapp2.0)" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="osu! (netcoreapp2.1)" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.0/osu!.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.1/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" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<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.0" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||||
<method />
|
<method />
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
80
.vscode/launch.json
vendored
80
.vscode/launch.json
vendored
@ -2,110 +2,54 @@
|
|||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "VisualTests (Debug, net471)",
|
"name": "VisualTests (Debug)",
|
||||||
"windows": {
|
|
||||||
"type": "clr"
|
|
||||||
},
|
|
||||||
"type": "mono",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceRoot}/osu.Game.Tests/bin/Debug/net471/osu.Game.Tests.exe",
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
"preLaunchTask": "Build (Debug, msbuild)",
|
|
||||||
"runtimeExecutable": null,
|
|
||||||
"env": {},
|
|
||||||
"console": "internalConsole"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "VisualTests (Release, net471)",
|
|
||||||
"windows": {
|
|
||||||
"type": "clr"
|
|
||||||
},
|
|
||||||
"type": "mono",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceRoot}/osu.Game.Tests/bin/Debug/net471/osu.Game.Tests.exe",
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
"preLaunchTask": "Build (Release, msbuild)",
|
|
||||||
"runtimeExecutable": null,
|
|
||||||
"env": {},
|
|
||||||
"console": "internalConsole"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "osu! (Debug, net471)",
|
|
||||||
"windows": {
|
|
||||||
"type": "clr"
|
|
||||||
},
|
|
||||||
"type": "mono",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceRoot}/osu.Desktop/bin/Debug/net471/osu!.exe",
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
"preLaunchTask": "Build (Debug, msbuild)",
|
|
||||||
"runtimeExecutable": null,
|
|
||||||
"env": {},
|
|
||||||
"console": "internalConsole"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "osu! (Release, net471)",
|
|
||||||
"windows": {
|
|
||||||
"type": "clr"
|
|
||||||
},
|
|
||||||
"type": "mono",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceRoot}/osu.Desktop/bin/Release/net471/osu!.exe",
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
"preLaunchTask": "Build (Release, msbuild)",
|
|
||||||
"runtimeExecutable": null,
|
|
||||||
"env": {},
|
|
||||||
"console": "internalConsole"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.0/osu.Game.Tests.dll"
|
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug, dotnet)",
|
"preLaunchTask": "Build tests (Debug)",
|
||||||
"env": {},
|
"env": {},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
"name": "VisualTests (Release)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.0/osu.Game.Tests.dll"
|
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release, dotnet)",
|
"preLaunchTask": "Build tests (Release)",
|
||||||
"env": {},
|
"env": {},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "osu! (Debug, netcoreapp2.0)",
|
"name": "osu! (Debug)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.0/osu!.dll",
|
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll",
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug, dotnet)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"env": {},
|
"env": {},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "osu! (Release, netcoreapp2.0)",
|
"name": "osu! (Release)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.0/osu!.dll",
|
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll",
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release, dotnet)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"env": {},
|
"env": {},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
}
|
}
|
||||||
|
69
.vscode/tasks.json
vendored
69
.vscode/tasks.json
vendored
@ -4,41 +4,14 @@
|
|||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"label": "Build (Debug, msbuild)",
|
"label": "Build osu! (Debug)",
|
||||||
"type": "shell",
|
|
||||||
"command": "msbuild",
|
|
||||||
"args": [
|
|
||||||
"/p:TargetFramework=net471",
|
|
||||||
"/p:GenerateFullPaths=true",
|
|
||||||
"/m",
|
|
||||||
"/verbosity:m"
|
|
||||||
],
|
|
||||||
"group": "build",
|
|
||||||
"problemMatcher": "$msCompile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Build (Release, msbuild)",
|
|
||||||
"type": "shell",
|
|
||||||
"command": "msbuild",
|
|
||||||
"args": [
|
|
||||||
"/p:Configuration=Release",
|
|
||||||
"/p:TargetFramework=net471",
|
|
||||||
"/p:GenerateFullPaths=true",
|
|
||||||
"/m",
|
|
||||||
"/verbosity:m"
|
|
||||||
],
|
|
||||||
"group": "build",
|
|
||||||
"problemMatcher": "$msCompile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Build (Debug, dotnet)",
|
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Desktop",
|
"osu.Desktop",
|
||||||
"/p:TargetFramework=netcoreapp2.0",
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
"/verbosity:m"
|
"/verbosity:m"
|
||||||
@ -47,14 +20,14 @@
|
|||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Build (Release, dotnet)",
|
"label": "Build osu! (Release)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Desktop",
|
"osu.Desktop",
|
||||||
"/p:TargetFramework=netcoreapp2.0",
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
"/p:Configuration=Release",
|
"/p:Configuration=Release",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
@ -64,16 +37,40 @@
|
|||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Restore (net471)",
|
"label": "Build tests (Debug)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "nuget",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"restore"
|
"build",
|
||||||
|
"--no-restore",
|
||||||
|
"osu.Game.Tests",
|
||||||
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
|
"/p:GenerateFullPaths=true",
|
||||||
|
"/m",
|
||||||
|
"/verbosity:m"
|
||||||
],
|
],
|
||||||
"problemMatcher": []
|
"group": "build",
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Restore (netcoreapp2.0)",
|
"label": "Build tests (Release)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--no-restore",
|
||||||
|
"osu.Game.Tests",
|
||||||
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
|
"/p:Configuration=Release",
|
||||||
|
"/p:GenerateFullPaths=true",
|
||||||
|
"/m",
|
||||||
|
"/verbosity:m"
|
||||||
|
],
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Restore (netcoreapp2.1)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
|
@ -2,11 +2,6 @@ clone_depth: 1
|
|||||||
version: '{branch}-{build}'
|
version: '{branch}-{build}'
|
||||||
image: Visual Studio 2017
|
image: Visual Studio 2017
|
||||||
configuration: Debug
|
configuration: Debug
|
||||||
cache:
|
|
||||||
- C:\ProgramData\chocolatey\bin -> appveyor.yml
|
|
||||||
- C:\ProgramData\chocolatey\lib -> appveyor.yml
|
|
||||||
- inspectcode -> appveyor.yml
|
|
||||||
- packages -> **\packages.config
|
|
||||||
install:
|
install:
|
||||||
- cmd: git submodule update --init --recursive --depth=5
|
- cmd: git submodule update --init --recursive --depth=5
|
||||||
- cmd: choco install resharper-clt -y
|
- cmd: choco install resharper-clt -y
|
||||||
|
@ -1,29 +1,24 @@
|
|||||||
branches:
|
|
||||||
only:
|
|
||||||
- release
|
|
||||||
skip_tags: true
|
|
||||||
skip_branch_with_pr: true
|
|
||||||
clone_depth: 1
|
clone_depth: 1
|
||||||
version: '{branch}-{build}'
|
version: '{build}'
|
||||||
|
skip_non_tags: true
|
||||||
image: Visual Studio 2017
|
image: Visual Studio 2017
|
||||||
configuration: Debug
|
|
||||||
cache:
|
|
||||||
- packages -> **\packages.config
|
|
||||||
install:
|
install:
|
||||||
- cmd: git submodule update --init --recursive --depth=5
|
- git clone https://github.com/ppy/osu-deploy
|
||||||
before_build:
|
before_build:
|
||||||
|
- ps: if($env:appveyor_repo_tag -eq 'True') { Update-AppveyorBuild -Version $env:appveyor_repo_tag_name }
|
||||||
|
- cmd: git submodule update --init --recursive --depth=5
|
||||||
- cmd: nuget restore -verbosity quiet
|
- cmd: nuget restore -verbosity quiet
|
||||||
build:
|
build_script:
|
||||||
project: osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
|
|
||||||
verbosity: minimal
|
|
||||||
after_build:
|
|
||||||
- ps: iex ((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/appveyor/secure-file/master/install.ps1'))
|
- ps: iex ((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/appveyor/secure-file/master/install.ps1'))
|
||||||
- appveyor DownloadFile https://puu.sh/A6g5K/4d08705438.enc # signing certificate
|
- appveyor DownloadFile https://puu.sh/A6g5K/4d08705438.enc # signing certificate
|
||||||
- cmd: appveyor-tools\secure-file -decrypt 4d08705438.enc -secret %decode_secret% -out %HOMEPATH%\deanherbert.pfx
|
- cmd: appveyor-tools\secure-file -decrypt 4d08705438.enc -secret %decode_secret% -out %HOMEPATH%\deanherbert.pfx
|
||||||
- appveyor DownloadFile https://puu.sh/A6g75/fdc6f19b04.enc # deploy configuration
|
- appveyor DownloadFile https://puu.sh/A6g75/fdc6f19b04.enc # deploy configuration
|
||||||
- cmd: appveyor-tools\secure-file -decrypt fdc6f19b04.enc -secret %decode_secret% -out osu.Desktop.Deploy\bin\Debug\net471\osu.Desktop.Deploy.exe.config
|
- cd osu-deploy
|
||||||
- cd osu.Desktop.Deploy\bin\Debug\net471\
|
- nuget restore -verbosity quiet
|
||||||
- osu.Desktop.Deploy.exe %code_signing_password%
|
- msbuild osu.Desktop.Deploy.csproj
|
||||||
|
- cmd: ..\appveyor-tools\secure-file -decrypt ..\fdc6f19b04.enc -secret %decode_secret% -out bin\Debug\net471\osu.Desktop.Deploy.exe.config
|
||||||
|
- cd bin\Debug\net471\
|
||||||
|
- osu.Desktop.Deploy.exe %code_signing_password% %APPVEYOR_REPO_TAG_NAME%
|
||||||
environment:
|
environment:
|
||||||
TargetFramework: net471
|
TargetFramework: net471
|
||||||
decode_secret:
|
decode_secret:
|
||||||
@ -32,3 +27,6 @@ environment:
|
|||||||
secure: 34tLNqvjmmZEi97MLKfrnQ==
|
secure: 34tLNqvjmmZEi97MLKfrnQ==
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: 'Releases\*'
|
- path: 'Releases\*'
|
||||||
|
deploy:
|
||||||
|
- provider: Environment
|
||||||
|
name: github
|
@ -1 +0,0 @@
|
|||||||
Subproject commit eb076a3301231eb73917073499051e49a9b12978
|
|
@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
-->
|
|
||||||
<configuration>
|
|
||||||
<appSettings>
|
|
||||||
<add key="StagingFolder" value="Staging" />
|
|
||||||
<add key="ReleasesFolder" value="Releases" />
|
|
||||||
<add key="GitHubAccessToken" value="" />
|
|
||||||
<add key="GitHubUsername" value="ppy" />
|
|
||||||
<add key="GitHubRepoName" value="osu" />
|
|
||||||
<add key="ProjectName" value="osu.Desktop" />
|
|
||||||
<add key="NuSpecName" value="osu.Desktop\osu.nuspec" />
|
|
||||||
<add key="SolutionName" value="osu" />
|
|
||||||
<add key="TargetName" value="osu.Desktop" />
|
|
||||||
<add key="PackageName" value="osulazer" />
|
|
||||||
<add key="IconName" value="lazer.ico" />
|
|
||||||
<add key="CodeSigningCertificate" value="" />
|
|
||||||
</appSettings>
|
|
||||||
</configuration>
|
|
@ -1,16 +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 Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace osu.Desktop.Deploy
|
|
||||||
{
|
|
||||||
public class GitHubObject
|
|
||||||
{
|
|
||||||
[JsonProperty(@"id")]
|
|
||||||
public int Id;
|
|
||||||
|
|
||||||
[JsonProperty(@"name")]
|
|
||||||
public string Name;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +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 Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace osu.Desktop.Deploy
|
|
||||||
{
|
|
||||||
public class GitHubRelease
|
|
||||||
{
|
|
||||||
[JsonProperty(@"id")]
|
|
||||||
public int Id;
|
|
||||||
|
|
||||||
[JsonProperty(@"tag_name")]
|
|
||||||
public string TagName => $"v{Name}";
|
|
||||||
|
|
||||||
[JsonProperty(@"name")]
|
|
||||||
public string Name;
|
|
||||||
|
|
||||||
[JsonProperty(@"draft")]
|
|
||||||
public bool Draft;
|
|
||||||
|
|
||||||
[JsonProperty(@"prerelease")]
|
|
||||||
public bool PreRelease;
|
|
||||||
|
|
||||||
[JsonProperty(@"upload_url")]
|
|
||||||
public string UploadUrl;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,471 +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;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Configuration;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Management.Automation;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using osu.Framework.IO.Network;
|
|
||||||
using FileWebRequest = osu.Framework.IO.Network.FileWebRequest;
|
|
||||||
using WebRequest = osu.Framework.IO.Network.WebRequest;
|
|
||||||
|
|
||||||
namespace osu.Desktop.Deploy
|
|
||||||
{
|
|
||||||
internal static class Program
|
|
||||||
{
|
|
||||||
private static string packages => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
|
|
||||||
private static string nugetPath => Path.Combine(packages, @"nuget.commandline\4.5.1\tools\NuGet.exe");
|
|
||||||
private static string squirrelPath => Path.Combine(packages, @"squirrel.windows\1.8.0\tools\Squirrel.exe");
|
|
||||||
private const string msbuild_path = @"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe";
|
|
||||||
|
|
||||||
public static string StagingFolder = ConfigurationManager.AppSettings["StagingFolder"];
|
|
||||||
public static string ReleasesFolder = ConfigurationManager.AppSettings["ReleasesFolder"];
|
|
||||||
public static string GitHubAccessToken = ConfigurationManager.AppSettings["GitHubAccessToken"];
|
|
||||||
public static string GitHubUsername = ConfigurationManager.AppSettings["GitHubUsername"];
|
|
||||||
public static string GitHubRepoName = ConfigurationManager.AppSettings["GitHubRepoName"];
|
|
||||||
public static string SolutionName = ConfigurationManager.AppSettings["SolutionName"];
|
|
||||||
public static string ProjectName = ConfigurationManager.AppSettings["ProjectName"];
|
|
||||||
public static string NuSpecName = ConfigurationManager.AppSettings["NuSpecName"];
|
|
||||||
public static string TargetNames = ConfigurationManager.AppSettings["TargetName"];
|
|
||||||
public static string PackageName = ConfigurationManager.AppSettings["PackageName"];
|
|
||||||
public static string IconName = ConfigurationManager.AppSettings["IconName"];
|
|
||||||
public static string CodeSigningCertificate = ConfigurationManager.AppSettings["CodeSigningCertificate"];
|
|
||||||
|
|
||||||
public static string GitHubApiEndpoint => $"https://api.github.com/repos/{GitHubUsername}/{GitHubRepoName}/releases";
|
|
||||||
public static string GitHubReleasePage => $"https://github.com/{GitHubUsername}/{GitHubRepoName}/releases";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// How many previous build deltas we want to keep when publishing.
|
|
||||||
/// </summary>
|
|
||||||
private const int keep_delta_count = 4;
|
|
||||||
|
|
||||||
private static string codeSigningCmd => string.IsNullOrEmpty(codeSigningPassword) ? "" : $"-n \"/a /f {codeSigningCertPath} /p {codeSigningPassword} /t http://timestamp.comodoca.com/authenticode\"";
|
|
||||||
|
|
||||||
private static string homeDir => Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
|
||||||
private static string codeSigningCertPath => Path.Combine(homeDir, CodeSigningCertificate);
|
|
||||||
private static string solutionPath => Environment.CurrentDirectory;
|
|
||||||
private static string stagingPath => Path.Combine(solutionPath, StagingFolder);
|
|
||||||
private static string iconPath => Path.Combine(solutionPath, ProjectName, IconName);
|
|
||||||
|
|
||||||
private static string nupkgFilename(string ver) => $"{PackageName}.{ver}.nupkg";
|
|
||||||
private static string nupkgDistroFilename(string ver) => $"{PackageName}-{ver}-full.nupkg";
|
|
||||||
|
|
||||||
private static readonly Stopwatch sw = new Stopwatch();
|
|
||||||
|
|
||||||
private static string codeSigningPassword;
|
|
||||||
|
|
||||||
private static bool interactive;
|
|
||||||
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
interactive = args.Length == 0;
|
|
||||||
|
|
||||||
displayHeader();
|
|
||||||
|
|
||||||
findSolutionPath();
|
|
||||||
|
|
||||||
if (!Directory.Exists(ReleasesFolder))
|
|
||||||
{
|
|
||||||
write("WARNING: No release directory found. Make sure you want this!", ConsoleColor.Yellow);
|
|
||||||
Directory.CreateDirectory(ReleasesFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkGitHubReleases();
|
|
||||||
|
|
||||||
refreshDirectory(StagingFolder);
|
|
||||||
|
|
||||||
//increment build number until we have a unique one.
|
|
||||||
string verBase = DateTime.Now.ToString("yyyy.Mdd.");
|
|
||||||
int increment = 0;
|
|
||||||
while (Directory.GetFiles(ReleasesFolder, $"*{verBase}{increment}*").Any())
|
|
||||||
increment++;
|
|
||||||
|
|
||||||
string version = $"{verBase}{increment}";
|
|
||||||
|
|
||||||
Console.ForegroundColor = ConsoleColor.White;
|
|
||||||
Console.Write($"Ready to deploy {version}!");
|
|
||||||
pauseIfInteractive();
|
|
||||||
|
|
||||||
sw.Start();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(CodeSigningCertificate))
|
|
||||||
{
|
|
||||||
Console.Write("Enter code signing password: ");
|
|
||||||
codeSigningPassword = args.Length > 0 ? args[0] : readLineMasked();
|
|
||||||
}
|
|
||||||
|
|
||||||
write("Updating AssemblyInfo...");
|
|
||||||
updateCsprojVersion(version);
|
|
||||||
updateAppveyorVersion(version);
|
|
||||||
|
|
||||||
write("Running build process...");
|
|
||||||
foreach (string targetName in TargetNames.Split(','))
|
|
||||||
runCommand(msbuild_path, $"/v:quiet /m /t:{targetName.Replace('.', '_')} /p:OutputPath={stagingPath};Targets=\"Clean;Build\";Configuration=Release {SolutionName}.sln");
|
|
||||||
|
|
||||||
write("Creating NuGet deployment package...");
|
|
||||||
runCommand(nugetPath, $"pack {NuSpecName} -Version {version} -Properties Configuration=Deploy -OutputDirectory {stagingPath} -BasePath {stagingPath}");
|
|
||||||
|
|
||||||
//prune once before checking for files so we can avoid erroring on files which aren't even needed for this build.
|
|
||||||
pruneReleases();
|
|
||||||
|
|
||||||
checkReleaseFiles();
|
|
||||||
|
|
||||||
write("Running squirrel build...");
|
|
||||||
runCommand(squirrelPath, $"--releasify {stagingPath}\\{nupkgFilename(version)} --framework-version=net471 --setupIcon {iconPath} --icon {iconPath} {codeSigningCmd} --no-msi");
|
|
||||||
|
|
||||||
//prune again to clean up before upload.
|
|
||||||
pruneReleases();
|
|
||||||
|
|
||||||
//rename setup to install.
|
|
||||||
File.Copy(Path.Combine(ReleasesFolder, "Setup.exe"), Path.Combine(ReleasesFolder, "install.exe"), true);
|
|
||||||
File.Delete(Path.Combine(ReleasesFolder, "Setup.exe"));
|
|
||||||
|
|
||||||
uploadBuild(version);
|
|
||||||
|
|
||||||
//reset assemblyinfo.
|
|
||||||
updateCsprojVersion("0.0.0");
|
|
||||||
|
|
||||||
write("Done!", ConsoleColor.White);
|
|
||||||
pauseIfInteractive();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void displayHeader()
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
|
||||||
Console.WriteLine();
|
|
||||||
Console.WriteLine(" Please note that OSU! and PPY are registered trademarks and as such covered by trademark law.");
|
|
||||||
Console.WriteLine(" Do not distribute builds of this project publicly that make use of these.");
|
|
||||||
Console.ResetColor();
|
|
||||||
Console.WriteLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ensure we have all the files in the release directory which are expected to be there.
|
|
||||||
/// This should have been accounted for in earlier steps, and just serves as a verification step.
|
|
||||||
/// </summary>
|
|
||||||
private static void checkReleaseFiles()
|
|
||||||
{
|
|
||||||
if (!canGitHub) return;
|
|
||||||
|
|
||||||
var releaseLines = getReleaseLines();
|
|
||||||
|
|
||||||
//ensure we have all files necessary
|
|
||||||
foreach (var l in releaseLines)
|
|
||||||
if (!File.Exists(Path.Combine(ReleasesFolder, l.Filename)))
|
|
||||||
error($"Local file missing {l.Filename}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<ReleaseLine> getReleaseLines() => File.ReadAllLines(Path.Combine(ReleasesFolder, "RELEASES")).Select(l => new ReleaseLine(l));
|
|
||||||
|
|
||||||
private static void pruneReleases()
|
|
||||||
{
|
|
||||||
if (!canGitHub) return;
|
|
||||||
|
|
||||||
write("Pruning RELEASES...");
|
|
||||||
|
|
||||||
var releaseLines = getReleaseLines().ToList();
|
|
||||||
|
|
||||||
var fulls = releaseLines.Where(l => l.Filename.Contains("-full")).Reverse().Skip(1);
|
|
||||||
|
|
||||||
//remove any FULL releases (except most recent)
|
|
||||||
foreach (var l in fulls)
|
|
||||||
{
|
|
||||||
write($"- Removing old release {l.Filename}", ConsoleColor.Yellow);
|
|
||||||
File.Delete(Path.Combine(ReleasesFolder, l.Filename));
|
|
||||||
releaseLines.Remove(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove excess deltas
|
|
||||||
var deltas = releaseLines.Where(l => l.Filename.Contains("-delta")).ToArray();
|
|
||||||
if (deltas.Length > keep_delta_count)
|
|
||||||
{
|
|
||||||
foreach (var l in deltas.Take(deltas.Length - keep_delta_count))
|
|
||||||
{
|
|
||||||
write($"- Removing old delta {l.Filename}", ConsoleColor.Yellow);
|
|
||||||
File.Delete(Path.Combine(ReleasesFolder, l.Filename));
|
|
||||||
releaseLines.Remove(l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var lines = new List<string>();
|
|
||||||
releaseLines.ForEach(l => lines.Add(l.ToString()));
|
|
||||||
File.WriteAllLines(Path.Combine(ReleasesFolder, "RELEASES"), lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void uploadBuild(string version)
|
|
||||||
{
|
|
||||||
if (!canGitHub || string.IsNullOrEmpty(CodeSigningCertificate))
|
|
||||||
return;
|
|
||||||
|
|
||||||
write("Publishing to GitHub...");
|
|
||||||
|
|
||||||
write($"- Creating release {version}...", ConsoleColor.Yellow);
|
|
||||||
var req = new JsonWebRequest<GitHubRelease>($"{GitHubApiEndpoint}")
|
|
||||||
{
|
|
||||||
Method = HttpMethod.POST,
|
|
||||||
};
|
|
||||||
req.AddRaw(JsonConvert.SerializeObject(new GitHubRelease
|
|
||||||
{
|
|
||||||
Name = version,
|
|
||||||
Draft = true,
|
|
||||||
PreRelease = true
|
|
||||||
}));
|
|
||||||
req.AuthenticatedBlockingPerform();
|
|
||||||
|
|
||||||
var assetUploadUrl = req.ResponseObject.UploadUrl.Replace("{?name,label}", "?name={0}");
|
|
||||||
foreach (var a in Directory.GetFiles(ReleasesFolder).Reverse()) //reverse to upload RELEASES first.
|
|
||||||
{
|
|
||||||
write($"- Adding asset {a}...", ConsoleColor.Yellow);
|
|
||||||
var upload = new WebRequest(assetUploadUrl, Path.GetFileName(a))
|
|
||||||
{
|
|
||||||
Method = HttpMethod.POST,
|
|
||||||
Timeout = 240000,
|
|
||||||
ContentType = "application/octet-stream",
|
|
||||||
};
|
|
||||||
|
|
||||||
upload.AddRaw(File.ReadAllBytes(a));
|
|
||||||
upload.AuthenticatedBlockingPerform();
|
|
||||||
}
|
|
||||||
|
|
||||||
openGitHubReleasePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void openGitHubReleasePage() => Process.Start(GitHubReleasePage);
|
|
||||||
|
|
||||||
private static bool canGitHub => !string.IsNullOrEmpty(GitHubAccessToken);
|
|
||||||
|
|
||||||
private static void checkGitHubReleases()
|
|
||||||
{
|
|
||||||
if (!canGitHub) return;
|
|
||||||
|
|
||||||
write("Checking GitHub releases...");
|
|
||||||
var req = new JsonWebRequest<List<GitHubRelease>>($"{GitHubApiEndpoint}");
|
|
||||||
req.AuthenticatedBlockingPerform();
|
|
||||||
|
|
||||||
var lastRelease = req.ResponseObject.FirstOrDefault();
|
|
||||||
|
|
||||||
if (lastRelease == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (lastRelease.Draft)
|
|
||||||
{
|
|
||||||
openGitHubReleasePage();
|
|
||||||
error("There's a pending draft release! You probably don't want to push a build with this present.");
|
|
||||||
}
|
|
||||||
|
|
||||||
//there's a previous release for this project.
|
|
||||||
var assetReq = new JsonWebRequest<List<GitHubObject>>($"{GitHubApiEndpoint}/{lastRelease.Id}/assets");
|
|
||||||
assetReq.AuthenticatedBlockingPerform();
|
|
||||||
var assets = assetReq.ResponseObject;
|
|
||||||
|
|
||||||
//make sure our RELEASES file is the same as the last build on the server.
|
|
||||||
var releaseAsset = assets.FirstOrDefault(a => a.Name == "RELEASES");
|
|
||||||
|
|
||||||
//if we don't have a RELEASES asset then the previous release likely wasn't a Squirrel one.
|
|
||||||
if (releaseAsset == null) return;
|
|
||||||
|
|
||||||
write($"Last GitHub release was {lastRelease.Name}.");
|
|
||||||
|
|
||||||
bool requireDownload = false;
|
|
||||||
|
|
||||||
if (!File.Exists(Path.Combine(ReleasesFolder, nupkgDistroFilename(lastRelease.Name))))
|
|
||||||
{
|
|
||||||
write("Last version's package not found locally.", ConsoleColor.Red);
|
|
||||||
requireDownload = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var lastReleases = new RawFileWebRequest($"{GitHubApiEndpoint}/assets/{releaseAsset.Id}");
|
|
||||||
lastReleases.AuthenticatedBlockingPerform();
|
|
||||||
if (File.ReadAllText(Path.Combine(ReleasesFolder, "RELEASES")) != lastReleases.ResponseString)
|
|
||||||
{
|
|
||||||
write("Server's RELEASES differed from ours.", ConsoleColor.Red);
|
|
||||||
requireDownload = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!requireDownload) return;
|
|
||||||
|
|
||||||
write("Refreshing local releases directory...");
|
|
||||||
refreshDirectory(ReleasesFolder);
|
|
||||||
|
|
||||||
foreach (var a in assets)
|
|
||||||
{
|
|
||||||
if (a.Name.EndsWith(".exe")) continue;
|
|
||||||
|
|
||||||
write($"- Downloading {a.Name}...", ConsoleColor.Yellow);
|
|
||||||
new FileWebRequest(Path.Combine(ReleasesFolder, a.Name), $"{GitHubApiEndpoint}/assets/{a.Id}").AuthenticatedBlockingPerform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void refreshDirectory(string directory)
|
|
||||||
{
|
|
||||||
if (Directory.Exists(directory))
|
|
||||||
Directory.Delete(directory, true);
|
|
||||||
Directory.CreateDirectory(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void updateCsprojVersion(string version)
|
|
||||||
{
|
|
||||||
var toUpdate = new[] { "<Version>", "<FileVersion>" };
|
|
||||||
string file = Path.Combine(ProjectName, $"{ProjectName}.csproj");
|
|
||||||
|
|
||||||
var l1 = File.ReadAllLines(file);
|
|
||||||
List<string> l2 = new List<string>();
|
|
||||||
foreach (var l in l1)
|
|
||||||
{
|
|
||||||
string line = l;
|
|
||||||
|
|
||||||
foreach (var tag in toUpdate)
|
|
||||||
{
|
|
||||||
int startIndex = l.IndexOf(tag, StringComparison.InvariantCulture);
|
|
||||||
if (startIndex == -1)
|
|
||||||
continue;
|
|
||||||
startIndex += tag.Length;
|
|
||||||
|
|
||||||
int endIndex = l.IndexOf("<", startIndex, StringComparison.InvariantCulture);
|
|
||||||
line = $"{l.Substring(0, startIndex)}{version}{l.Substring(endIndex)}";
|
|
||||||
}
|
|
||||||
|
|
||||||
l2.Add(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
File.WriteAllLines(file, l2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Find the base path of the active solution (git checkout location)
|
|
||||||
/// </summary>
|
|
||||||
private static void findSolutionPath()
|
|
||||||
{
|
|
||||||
string path = Path.GetDirectoryName(Environment.CommandLine.Replace("\"", "").Trim());
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(path))
|
|
||||||
path = Environment.CurrentDirectory;
|
|
||||||
|
|
||||||
while (!File.Exists(Path.Combine(path, $"{SolutionName}.sln")))
|
|
||||||
path = path.Remove(path.LastIndexOf(Path.DirectorySeparatorChar));
|
|
||||||
path += Path.DirectorySeparatorChar;
|
|
||||||
|
|
||||||
Environment.CurrentDirectory = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool runCommand(string command, string args)
|
|
||||||
{
|
|
||||||
var psi = new ProcessStartInfo(command, args)
|
|
||||||
{
|
|
||||||
WorkingDirectory = solutionPath,
|
|
||||||
CreateNoWindow = true,
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
UseShellExecute = false,
|
|
||||||
WindowStyle = ProcessWindowStyle.Hidden
|
|
||||||
};
|
|
||||||
|
|
||||||
Process p = Process.Start(psi);
|
|
||||||
if (p == null) return false;
|
|
||||||
|
|
||||||
string output = p.StandardOutput.ReadToEnd();
|
|
||||||
output += p.StandardError.ReadToEnd();
|
|
||||||
|
|
||||||
if (p.ExitCode == 0) return true;
|
|
||||||
|
|
||||||
write(output);
|
|
||||||
error($"Command {command} {args} failed!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string readLineMasked()
|
|
||||||
{
|
|
||||||
var fg = Console.ForegroundColor;
|
|
||||||
Console.ForegroundColor = Console.BackgroundColor;
|
|
||||||
var ret = Console.ReadLine();
|
|
||||||
Console.ForegroundColor = fg;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void error(string message)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
|
||||||
Console.WriteLine($"FATAL ERROR: {message}");
|
|
||||||
|
|
||||||
pauseIfInteractive();
|
|
||||||
Environment.Exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void pauseIfInteractive()
|
|
||||||
{
|
|
||||||
if (interactive)
|
|
||||||
Console.ReadLine();
|
|
||||||
else
|
|
||||||
Console.WriteLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool updateAppveyorVersion(string version)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (PowerShell ps = PowerShell.Create())
|
|
||||||
{
|
|
||||||
ps.AddScript($"Update-AppveyorBuild -Version \"{version}\"");
|
|
||||||
ps.Invoke();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// we don't have appveyor and don't care
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void write(string message, ConsoleColor col = ConsoleColor.Gray)
|
|
||||||
{
|
|
||||||
if (sw.ElapsedMilliseconds > 0)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
|
||||||
Console.Write(sw.ElapsedMilliseconds.ToString().PadRight(8));
|
|
||||||
}
|
|
||||||
Console.ForegroundColor = col;
|
|
||||||
Console.WriteLine(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AuthenticatedBlockingPerform(this WebRequest r)
|
|
||||||
{
|
|
||||||
r.AddHeader("Authorization", $"token {GitHubAccessToken}");
|
|
||||||
r.Perform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class RawFileWebRequest : WebRequest
|
|
||||||
{
|
|
||||||
public RawFileWebRequest(string url) : base(url)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override string Accept => "application/octet-stream";
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class ReleaseLine
|
|
||||||
{
|
|
||||||
public string Hash;
|
|
||||||
public string Filename;
|
|
||||||
public int Filesize;
|
|
||||||
|
|
||||||
public ReleaseLine(string line)
|
|
||||||
{
|
|
||||||
var split = line.Split(' ');
|
|
||||||
Hash = split[0];
|
|
||||||
Filename = split[1];
|
|
||||||
Filesize = int.Parse(split[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() => $"{Hash} {Filename} {Filesize}";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\osu.Game.props" />
|
|
||||||
<PropertyGroup Label="Project">
|
|
||||||
<TargetFrameworks>net471</TargetFrameworks>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup Label="Project References">
|
|
||||||
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup Label="Package References">
|
|
||||||
<PackageReference Include="NuGet.CommandLine" Version="4.5.1" />
|
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
|
||||||
<PackageReference Include="squirrel.windows" Version="1.8.0" Condition="'$(TargetFramework)' == 'net471'" />
|
|
||||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.0" />
|
|
||||||
<PackageReference Include="System.Management.Automation.dll" Version="10.0.10586" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
@ -12,6 +12,7 @@ using osu.Framework.Platform;
|
|||||||
using osu.Game;
|
using osu.Game;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
using osu.Framework.Platform.Windows;
|
||||||
|
|
||||||
namespace osu.Desktop
|
namespace osu.Desktop
|
||||||
{
|
{
|
||||||
@ -40,7 +41,7 @@ namespace osu.Desktop
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A method of accessing an osu-stable install in a controlled fashion.
|
/// A method of accessing an osu-stable install in a controlled fashion.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private class StableStorage : DesktopStorage
|
private class StableStorage : WindowsStorage
|
||||||
{
|
{
|
||||||
protected override string LocateBasePath()
|
protected override string LocateBasePath()
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Development;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
@ -14,6 +13,7 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
|
using osu.Game.Utils;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ namespace osu.Desktop.Overlays
|
|||||||
Icon = FontAwesome.fa_check_square;
|
Icon = FontAwesome.fa_check_square;
|
||||||
Activated = delegate
|
Activated = delegate
|
||||||
{
|
{
|
||||||
Process.Start($"https://github.com/ppy/osu/releases/tag/v{version}");
|
Process.Start($"https://osu.ppy.sh/home/changelog/{version}");
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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">
|
||||||
<TargetFrameworks>net471;netcoreapp2.0</TargetFrameworks>
|
<TargetFrameworks>net471;netcoreapp2.1</TargetFrameworks>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
@ -20,17 +20,16 @@
|
|||||||
<StartupObject>osu.Desktop.Program</StartupObject>
|
<StartupObject>osu.Desktop.Program</StartupObject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
|
||||||
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
|
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
|
||||||
<PackageReference Include="Microsoft.Win32.Registry" Version="4.4.0" />
|
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0" />
|
||||||
<PackageReference Include="squirrel.windows" Version="1.8.0" Condition="'$(TargetFramework)' == 'net471'" />
|
<PackageReference Include="squirrel.windows" Version="1.8.0" Condition="'$(TargetFramework)' == 'net471'" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Resources">
|
<ItemGroup Label="Resources">
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"type": "mono",
|
"type": "mono",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Catch.Tests.exe",
|
"program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Catch.Tests.exe",
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release, msbuild)",
|
"preLaunchTask": "Build (Release, msbuild)",
|
||||||
"runtimeExecutable": null,
|
"runtimeExecutable": null,
|
||||||
@ -30,12 +30,12 @@
|
|||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Catch.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug, dotnet)",
|
"preLaunchTask": "Build (Debug, dotnet)",
|
||||||
@ -43,12 +43,12 @@
|
|||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Catch.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release, dotnet)",
|
"preLaunchTask": "Build (Release, dotnet)",
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Rulesets.Catch.Tests.csproj",
|
"osu.Game.Rulesets.Catch.Tests.csproj",
|
||||||
"/p:TargetFramework=netcoreapp2.0",
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
"/verbosity:m"
|
"/verbosity:m"
|
||||||
@ -56,7 +56,7 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Rulesets.Catch.Tests.csproj",
|
"osu.Game.Rulesets.Catch.Tests.csproj",
|
||||||
"/p:TargetFramework=netcoreapp2.0",
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
"/p:Configuration=Release",
|
"/p:Configuration=Release",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
@ -75,7 +75,7 @@
|
|||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Restore (netcoreapp2.0)",
|
"label": "Restore (netcoreapp2.1)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
|
@ -53,10 +53,10 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
return beatmap;
|
return beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
||||||
return base.CreatePlayer(beatmap, ruleset);
|
return base.CreatePlayer(ruleset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
Child = catcherArea = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size })
|
Child = catcherArea = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size })
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.BottomLeft
|
Origin = Anchor.TopLeft
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
typeof(DrawableCatchHitObject),
|
typeof(DrawableCatchHitObject),
|
||||||
typeof(DrawableFruit),
|
typeof(DrawableFruit),
|
||||||
typeof(DrawableDroplet),
|
typeof(DrawableDroplet),
|
||||||
|
typeof(BananaShower),
|
||||||
typeof(Pulp),
|
typeof(Pulp),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,7 +54,14 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
|
|
||||||
private DrawableFruit createDrawable(int index)
|
private DrawableFruit createDrawable(int index)
|
||||||
{
|
{
|
||||||
var fruit = new Fruit
|
Fruit fruit = index == 5
|
||||||
|
? new BananaShower.Banana
|
||||||
|
{
|
||||||
|
StartTime = 1000000000000,
|
||||||
|
IndexInBeatmap = index,
|
||||||
|
Scale = 1.5f,
|
||||||
|
}
|
||||||
|
: new Fruit
|
||||||
{
|
{
|
||||||
StartTime = 1000000000000,
|
StartTime = 1000000000000,
|
||||||
IndexInBeatmap = index,
|
IndexInBeatmap = index,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||||
</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" />
|
||||||
|
@ -28,7 +28,20 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
var endTime = obj as IHasEndTime;
|
var endTime = obj as IHasEndTime;
|
||||||
|
|
||||||
if (positionData == null)
|
if (positionData == null)
|
||||||
|
{
|
||||||
|
if (endTime != null)
|
||||||
|
{
|
||||||
|
yield return new BananaShower
|
||||||
|
{
|
||||||
|
StartTime = obj.StartTime,
|
||||||
|
Samples = obj.Samples,
|
||||||
|
Duration = endTime.Duration,
|
||||||
|
NewCombo = comboData?.NewCombo ?? false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
yield break;
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
if (curveData != null)
|
if (curveData != null)
|
||||||
{
|
{
|
||||||
@ -48,19 +61,6 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endTime != null)
|
|
||||||
{
|
|
||||||
yield return new BananaShower
|
|
||||||
{
|
|
||||||
StartTime = obj.StartTime,
|
|
||||||
Samples = obj.Samples,
|
|
||||||
Duration = endTime.Duration,
|
|
||||||
NewCombo = comboData?.NewCombo ?? false
|
|
||||||
};
|
|
||||||
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return new Fruit
|
yield return new Fruit
|
||||||
{
|
{
|
||||||
StartTime = obj.StartTime,
|
StartTime = obj.StartTime,
|
||||||
|
@ -18,12 +18,19 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
{
|
{
|
||||||
private Circle border;
|
private Circle border;
|
||||||
|
|
||||||
|
private const float drawable_radius = (float)CatchHitObject.OBJECT_RADIUS * radius_adjust;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Because we're adding a border around the fruit, we need to scale down some.
|
||||||
|
/// </summary>
|
||||||
|
private const float radius_adjust = 1.1f;
|
||||||
|
|
||||||
public DrawableFruit(Fruit h)
|
public DrawableFruit(Fruit h)
|
||||||
: base(h)
|
: base(h)
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS);
|
Size = new Vector2(drawable_radius);
|
||||||
Masking = false;
|
Masking = false;
|
||||||
|
|
||||||
Rotation = (float)(RNG.NextDouble() - 0.5f) * 40;
|
Rotation = (float)(RNG.NextDouble() - 0.5f) * 40;
|
||||||
@ -44,14 +51,14 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
{
|
{
|
||||||
Hollow = !HitObject.HyperDash,
|
Hollow = !HitObject.HyperDash,
|
||||||
Type = EdgeEffectType.Glow,
|
Type = EdgeEffectType.Glow,
|
||||||
Radius = 4,
|
Radius = 4 * radius_adjust,
|
||||||
Colour = HitObject.HyperDash ? Color4.Red : AccentColour.Darken(1).Opacity(0.6f)
|
Colour = HitObject.HyperDash ? Color4.Red : AccentColour.Darken(1).Opacity(0.6f)
|
||||||
},
|
},
|
||||||
Size = new Vector2(Height * 1.5f),
|
Size = new Vector2(Height),
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
BorderColour = Color4.White,
|
BorderColour = Color4.White,
|
||||||
BorderThickness = 4f,
|
BorderThickness = 3f * radius_adjust,
|
||||||
Children = new Framework.Graphics.Drawable[]
|
Children = new Framework.Graphics.Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
@ -82,8 +89,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
|
|
||||||
private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation)
|
private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation)
|
||||||
{
|
{
|
||||||
const float large_pulp_3 = 13f;
|
const float large_pulp_3 = 8f * radius_adjust;
|
||||||
const float distance_from_centre_3 = 0.23f;
|
const float distance_from_centre_3 = 0.15f;
|
||||||
|
|
||||||
const float large_pulp_4 = large_pulp_3 * 0.925f;
|
const float large_pulp_4 = large_pulp_3 * 0.925f;
|
||||||
const float distance_from_centre_4 = distance_from_centre_3 / 0.925f;
|
const float distance_from_centre_4 = distance_from_centre_3 / 0.925f;
|
||||||
@ -106,11 +113,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
{
|
{
|
||||||
new Pulp
|
new Pulp
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.BottomCentre,
|
|
||||||
AccentColour = AccentColour,
|
AccentColour = AccentColour,
|
||||||
Size = new Vector2(small_pulp),
|
Size = new Vector2(small_pulp),
|
||||||
Y = 0.05f,
|
Y = -0.34f,
|
||||||
},
|
},
|
||||||
new Pulp
|
new Pulp
|
||||||
{
|
{
|
||||||
@ -146,11 +151,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
{
|
{
|
||||||
new Pulp
|
new Pulp
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.BottomCentre,
|
|
||||||
AccentColour = AccentColour,
|
AccentColour = AccentColour,
|
||||||
Size = new Vector2(small_pulp),
|
Size = new Vector2(small_pulp),
|
||||||
Y = 0.1f,
|
Y = -0.3f,
|
||||||
},
|
},
|
||||||
new Pulp
|
new Pulp
|
||||||
{
|
{
|
||||||
@ -186,11 +189,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
{
|
{
|
||||||
new Pulp
|
new Pulp
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
AccentColour = AccentColour,
|
AccentColour = AccentColour,
|
||||||
Size = new Vector2(small_pulp),
|
Size = new Vector2(small_pulp),
|
||||||
Y = -0.1f,
|
Y = -0.33f,
|
||||||
},
|
},
|
||||||
new Pulp
|
new Pulp
|
||||||
{
|
{
|
||||||
@ -220,10 +221,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
{
|
{
|
||||||
new Pulp
|
new Pulp
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
AccentColour = AccentColour,
|
AccentColour = AccentColour,
|
||||||
Size = new Vector2(small_pulp),
|
Size = new Vector2(small_pulp),
|
||||||
|
Y = -0.25f,
|
||||||
},
|
},
|
||||||
new Pulp
|
new Pulp
|
||||||
{
|
{
|
||||||
@ -253,16 +253,15 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
{
|
{
|
||||||
new Pulp
|
new Pulp
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
AccentColour = AccentColour,
|
AccentColour = AccentColour,
|
||||||
Size = new Vector2(small_pulp),
|
Size = new Vector2(small_pulp),
|
||||||
Y = -0.15f
|
Y = -0.3f
|
||||||
},
|
},
|
||||||
new Pulp
|
new Pulp
|
||||||
{
|
{
|
||||||
AccentColour = AccentColour,
|
AccentColour = AccentColour,
|
||||||
Size = new Vector2(large_pulp_4 * 1.2f, large_pulp_4 * 3),
|
Size = new Vector2(large_pulp_4 * 0.8f, large_pulp_4 * 2.5f),
|
||||||
|
Y = 0.05f,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -29,14 +29,24 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
if (IsLoaded) updateAccentColour();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAccentColour()
|
||||||
|
{
|
||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Type = EdgeEffectType.Glow,
|
Type = EdgeEffectType.Glow,
|
||||||
Radius = 8,
|
Radius = Size.X / 2,
|
||||||
Colour = accentColour.Darken(0.2f).Opacity(0.75f)
|
Colour = accentColour.Darken(0.2f).Opacity(0.75f)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
updateAccentColour();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
|
public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
|
||||||
|
|
||||||
|
protected override Vector2 PlayfieldArea => new Vector2(0.86f); // matches stable's vertical offset for catcher plate
|
||||||
|
|
||||||
protected override DrawableHitObject<CatchHitObject> GetVisualRepresentation(CatchHitObject h)
|
protected override DrawableHitObject<CatchHitObject> GetVisualRepresentation(CatchHitObject h)
|
||||||
{
|
{
|
||||||
switch (h)
|
switch (h)
|
||||||
|
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
{
|
{
|
||||||
public class CatcherArea : Container
|
public class CatcherArea : Container
|
||||||
{
|
{
|
||||||
public const float CATCHER_SIZE = 172;
|
public const float CATCHER_SIZE = 84;
|
||||||
|
|
||||||
protected readonly Catcher MovableCatcher;
|
protected readonly Catcher MovableCatcher;
|
||||||
|
|
||||||
@ -99,8 +99,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
public class Catcher : Container, IKeyBindingHandler<CatchAction>
|
public class Catcher : Container, IKeyBindingHandler<CatchAction>
|
||||||
{
|
{
|
||||||
private Texture texture;
|
|
||||||
|
|
||||||
private Container<DrawableHitObject> caughtFruit;
|
private Container<DrawableHitObject> caughtFruit;
|
||||||
|
|
||||||
public Container ExplodingFruitTarget;
|
public Container ExplodingFruitTarget;
|
||||||
@ -121,10 +119,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(TextureStore textures)
|
private void load()
|
||||||
{
|
{
|
||||||
texture = textures.Get(@"Play/Catch/fruit-catcher-idle");
|
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
caughtFruit = new Container<DrawableHitObject>
|
caughtFruit = new Container<DrawableHitObject>
|
||||||
@ -196,13 +192,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50);
|
Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Sprite createCatcherSprite() => new Sprite
|
private Sprite createCatcherSprite() => new CatcherSprite();
|
||||||
{
|
|
||||||
Size = new Vector2(CATCHER_SIZE),
|
|
||||||
FillMode = FillMode.Fill,
|
|
||||||
Texture = texture,
|
|
||||||
OriginPosition = new Vector2(-3, 10) // temporary until the sprite is aligned correctly.
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a caught fruit to the catcher's stack.
|
/// Add a caught fruit to the catcher's stack.
|
||||||
@ -411,6 +401,23 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
f.Expire();
|
f.Expire();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class CatcherSprite : Sprite
|
||||||
|
{
|
||||||
|
public CatcherSprite()
|
||||||
|
{
|
||||||
|
Size = new Vector2(CATCHER_SIZE);
|
||||||
|
|
||||||
|
// Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling.
|
||||||
|
OriginPosition = new Vector2(-0.02f, 0.06f) * CATCHER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
Texture = textures.Get(@"Play/Catch/fruit-catcher-idle");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"type": "mono",
|
"type": "mono",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Mania.Tests.exe",
|
"program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Mania.Tests.exe",
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release, msbuild)",
|
"preLaunchTask": "Build (Release, msbuild)",
|
||||||
"runtimeExecutable": null,
|
"runtimeExecutable": null,
|
||||||
@ -30,12 +30,12 @@
|
|||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Mania.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug, dotnet)",
|
"preLaunchTask": "Build (Debug, dotnet)",
|
||||||
@ -43,12 +43,12 @@
|
|||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Mania.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release, dotnet)",
|
"preLaunchTask": "Build (Release, dotnet)",
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Rulesets.Mania.Tests.csproj",
|
"osu.Game.Rulesets.Mania.Tests.csproj",
|
||||||
"/p:TargetFramework=netcoreapp2.0",
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
"/verbosity:m"
|
"/verbosity:m"
|
||||||
@ -56,7 +56,7 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Rulesets.Mania.Tests.csproj",
|
"osu.Game.Rulesets.Mania.Tests.csproj",
|
||||||
"/p:TargetFramework=netcoreapp2.0",
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
"/p:Configuration=Release",
|
"/p:Configuration=Release",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
@ -75,7 +75,7 @@
|
|||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Restore (netcoreapp2.0)",
|
"label": "Restore (netcoreapp2.1)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
|
@ -98,17 +98,12 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
|
||||||
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(RulesetStore rulesets, SettingsStore settings)
|
private void load(RulesetStore rulesets, SettingsStore settings)
|
||||||
{
|
{
|
||||||
maniaRuleset = rulesets.GetRuleset(3);
|
maniaRuleset = rulesets.GetRuleset(3);
|
||||||
|
|
||||||
dependencies.Cache(new ManiaConfigManager(settings, maniaRuleset, 4));
|
Dependencies.Cache(new ManiaConfigManager(settings, maniaRuleset, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ManiaPlayfield createPlayfield(int cols, bool inverted = false)
|
private ManiaPlayfield createPlayfield(int cols, bool inverted = false)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||||
</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" />
|
||||||
|
@ -105,7 +105,8 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
|
|
||||||
private double computeAccuracyValue(double strainValue)
|
private double computeAccuracyValue(double strainValue)
|
||||||
{
|
{
|
||||||
double hitWindowGreat = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate;
|
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be remoevd in the future
|
||||||
|
double hitWindowGreat = (int)(Beatmap.HitObjects.First().HitWindows.Great / 2) / TimeRate;
|
||||||
if (hitWindowGreat <= 0)
|
if (hitWindowGreat <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Name => "Dual Stages";
|
public override string Name => "Dual Stages";
|
||||||
public override string ShortenedName => "DS";
|
public override string ShortenedName => "DS";
|
||||||
public override string Description => @"Double the stages, double the fun!";
|
public override string Description => @"Double the stages, double the fun!";
|
||||||
public override double ScoreMultiplier => 0;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
private bool isForCurrentRuleset;
|
private bool isForCurrentRuleset;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string ShortenedName => "RD";
|
public override string ShortenedName => "RD";
|
||||||
public override FontAwesome Icon => FontAwesome.fa_osu_dice;
|
public override FontAwesome Icon => FontAwesome.fa_osu_dice;
|
||||||
public override string Description => @"Shuffle around the keys!";
|
public override string Description => @"Shuffle around the keys!";
|
||||||
public override double ScoreMultiplier => 0;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
|
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,7 @@ using OpenTK;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||||
{
|
{
|
||||||
@ -28,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
: base(barLine)
|
: base(barLine)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Height = 1;
|
Height = 2f;
|
||||||
|
|
||||||
AddInternal(new Box
|
AddInternal(new Box
|
||||||
{
|
{
|
||||||
@ -36,6 +37,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
Anchor = Anchor.BottomCentre,
|
Anchor = Anchor.BottomCentre,
|
||||||
Origin = Anchor.BottomCentre,
|
Origin = Anchor.BottomCentre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = new Color4(255, 204, 33, 255),
|
||||||
});
|
});
|
||||||
|
|
||||||
bool isMajor = barLine.BeatIndex % (int)barLine.ControlPoint.TimeSignature == 0;
|
bool isMajor = barLine.BeatIndex % (int)barLine.ControlPoint.TimeSignature == 0;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
@ -18,12 +18,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DrawableHoldNote : DrawableManiaHitObject<HoldNote>, IKeyBindingHandler<ManiaAction>
|
public class DrawableHoldNote : DrawableManiaHitObject<HoldNote>, IKeyBindingHandler<ManiaAction>
|
||||||
{
|
{
|
||||||
|
public override bool DisplayJudgement => false;
|
||||||
|
|
||||||
private readonly DrawableNote head;
|
private readonly DrawableNote head;
|
||||||
private readonly DrawableNote tail;
|
private readonly DrawableNote tail;
|
||||||
|
|
||||||
private readonly GlowPiece glowPiece;
|
|
||||||
private readonly BodyPiece bodyPiece;
|
private readonly BodyPiece bodyPiece;
|
||||||
private readonly Container fullHeightContainer;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Time at which the user started holding this hold note. Null if the user is not holding this hold note.
|
/// Time at which the user started holding this hold note. Null if the user is not holding this hold note.
|
||||||
@ -35,25 +35,17 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private bool hasBroken;
|
private bool hasBroken;
|
||||||
|
|
||||||
|
private readonly Container<DrawableHoldNoteTick> tickContainer;
|
||||||
|
|
||||||
public DrawableHoldNote(HoldNote hitObject, ManiaAction action)
|
public DrawableHoldNote(HoldNote hitObject, ManiaAction action)
|
||||||
: base(hitObject, action)
|
: base(hitObject, action)
|
||||||
{
|
{
|
||||||
Container<DrawableHoldNoteTick> tickContainer;
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
// The hit object itself cannot be used for various elements because the tail overshoots it
|
|
||||||
// So a specialized container that is updated to contain the tail height is used
|
|
||||||
fullHeightContainer = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Child = glowPiece = new GlowPiece()
|
|
||||||
},
|
|
||||||
bodyPiece = new BodyPiece
|
bodyPiece = new BodyPiece
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
},
|
},
|
||||||
tickContainer = new Container<DrawableHoldNoteTick>
|
tickContainer = new Container<DrawableHoldNoteTick>
|
||||||
@ -90,21 +82,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
|
|
||||||
glowPiece.AccentColour = value;
|
|
||||||
bodyPiece.AccentColour = value;
|
bodyPiece.AccentColour = value;
|
||||||
head.AccentColour = value;
|
head.AccentColour = value;
|
||||||
tail.AccentColour = value;
|
tail.AccentColour = value;
|
||||||
}
|
tickContainer.ForEach(t => t.AccentColour = value);
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateState(ArmedState state)
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case ArmedState.Hit:
|
|
||||||
// Good enough for now, we just want them to have a lifetime end
|
|
||||||
this.Delay(2000).Expire();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,12 +100,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
// Make the body piece not lie under the head note
|
// Make the body piece not lie under the head note
|
||||||
bodyPiece.Y = head.Height;
|
bodyPiece.Y = head.Height / 2;
|
||||||
bodyPiece.Height = DrawHeight - head.Height;
|
bodyPiece.Height = DrawHeight - head.Height / 2 + tail.Height / 2;
|
||||||
|
|
||||||
// Make the fullHeightContainer "contain" the height of the tail note, keeping in mind
|
|
||||||
// that the tail note overshoots the height of this hit object
|
|
||||||
fullHeightContainer.Height = DrawHeight + tail.Height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnPressed(ManiaAction action)
|
public bool OnPressed(ManiaAction action)
|
||||||
@ -173,8 +150,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
: base(holdNote.HitObject.Head, action)
|
: base(holdNote.HitObject.Head, action)
|
||||||
{
|
{
|
||||||
this.holdNote = holdNote;
|
this.holdNote = holdNote;
|
||||||
|
|
||||||
GlowPiece.Alpha = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnPressed(ManiaAction action)
|
public override bool OnPressed(ManiaAction action)
|
||||||
@ -192,11 +167,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateState(ArmedState state)
|
|
||||||
{
|
|
||||||
// The holdnote keeps scrolling through for now, so having the head disappear looks weird
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -217,8 +187,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
: base(holdNote.HitObject.Tail, action)
|
: base(holdNote.HitObject.Tail, action)
|
||||||
{
|
{
|
||||||
this.holdNote = holdNote;
|
this.holdNote = holdNote;
|
||||||
|
|
||||||
GlowPiece.Alpha = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||||
@ -251,11 +219,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateState(ArmedState state)
|
|
||||||
{
|
|
||||||
// The holdnote keeps scrolling through, so having the tail disappear looks weird
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down
|
public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down
|
||||||
|
|
||||||
public override bool OnReleased(ManiaAction action)
|
public override bool OnReleased(ManiaAction action)
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Extensions.Color4Extensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Mania.Judgements;
|
using osu.Game.Rulesets.Mania.Judgements;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
@ -87,16 +86,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
AddJudgement(new HoldNoteTickJudgement { Result = HitResult.Perfect });
|
AddJudgement(new HoldNoteTickJudgement { Result = HitResult.Perfect });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateState(ArmedState state)
|
|
||||||
{
|
|
||||||
switch (State.Value)
|
|
||||||
{
|
|
||||||
case ArmedState.Hit:
|
|
||||||
AccentColour = Color4.Green;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
if (AllJudged)
|
if (AllJudged)
|
||||||
|
@ -27,5 +27,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
if (action != null)
|
if (action != null)
|
||||||
Action = action.Value;
|
Action = action.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void UpdateState(ArmedState state)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case ArmedState.Miss:
|
||||||
|
this.FadeOut(150, Easing.In).Expire();
|
||||||
|
break;
|
||||||
|
case ArmedState.Hit:
|
||||||
|
this.FadeOut(150, Easing.OutQuint).Expire();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +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.Framework.Extensions.Color4Extensions;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Game.Rulesets.Mania.Judgements;
|
using osu.Game.Rulesets.Mania.Judgements;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||||
@ -16,9 +17,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DrawableNote : DrawableManiaHitObject<Note>, IKeyBindingHandler<ManiaAction>
|
public class DrawableNote : DrawableManiaHitObject<Note>, IKeyBindingHandler<ManiaAction>
|
||||||
{
|
{
|
||||||
protected readonly GlowPiece GlowPiece;
|
|
||||||
|
|
||||||
private readonly LaneGlowPiece laneGlowPiece;
|
|
||||||
private readonly NotePiece headPiece;
|
private readonly NotePiece headPiece;
|
||||||
|
|
||||||
public DrawableNote(Note hitObject, ManiaAction action)
|
public DrawableNote(Note hitObject, ManiaAction action)
|
||||||
@ -27,14 +25,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
|
CornerRadius = 5;
|
||||||
|
Masking = true;
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
laneGlowPiece = new LaneGlowPiece
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre
|
|
||||||
},
|
|
||||||
GlowPiece = new GlowPiece(),
|
|
||||||
headPiece = new NotePiece
|
headPiece = new NotePiece
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
@ -49,9 +44,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
laneGlowPiece.AccentColour = AccentColour;
|
|
||||||
GlowPiece.AccentColour = AccentColour;
|
|
||||||
headPiece.AccentColour = AccentColour;
|
headPiece.AccentColour = AccentColour;
|
||||||
|
|
||||||
|
EdgeEffect = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Glow,
|
||||||
|
Colour = AccentColour.Lighten(1f).Opacity(0.6f),
|
||||||
|
Radius = 10,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,17 +71,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
AddJudgement(new ManiaJudgement { Result = result });
|
AddJudgement(new ManiaJudgement { Result = result });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateState(ArmedState state)
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case ArmedState.Hit:
|
|
||||||
case ArmedState.Miss:
|
|
||||||
this.FadeOut(100).Expire();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool OnPressed(ManiaAction action)
|
public virtual bool OnPressed(ManiaAction action)
|
||||||
{
|
{
|
||||||
if (action != Action)
|
if (action != Action)
|
||||||
|
@ -123,8 +123,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
|||||||
if (!IsLoaded)
|
if (!IsLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreground.Colour = AccentColour.Opacity(0.4f);
|
foreground.Colour = AccentColour.Opacity(0.9f);
|
||||||
background.Colour = AccentColour.Opacity(0.2f);
|
background.Colour = AccentColour.Opacity(0.6f);
|
||||||
|
|
||||||
subtractionCache.Invalidate();
|
subtractionCache.Invalidate();
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class NotePiece : Container, IHasAccentColour
|
internal class NotePiece : Container, IHasAccentColour
|
||||||
{
|
{
|
||||||
private const float head_height = 10;
|
public const float NOTE_HEIGHT = 10;
|
||||||
private const float head_colour_height = 6;
|
private const float head_colour_height = 6;
|
||||||
|
|
||||||
private readonly Box colouredBox;
|
private readonly Box colouredBox;
|
||||||
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
|||||||
public NotePiece()
|
public NotePiece()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Height = head_height;
|
Height = NOTE_HEIGHT;
|
||||||
|
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
public ManiaAction Action;
|
public ManiaAction Action;
|
||||||
|
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
|
private readonly Box backgroundOverlay;
|
||||||
private readonly Container hitTargetBar;
|
private readonly Container hitTargetBar;
|
||||||
private readonly Container keyIcon;
|
private readonly Container keyIcon;
|
||||||
|
|
||||||
@ -42,22 +43,32 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
protected override Container<Drawable> Content => content;
|
protected override Container<Drawable> Content => content;
|
||||||
private readonly Container<Drawable> content;
|
private readonly Container<Drawable> content;
|
||||||
|
|
||||||
private const float opacity_released = 0.1f;
|
|
||||||
private const float opacity_pressed = 0.25f;
|
|
||||||
|
|
||||||
public Column()
|
public Column()
|
||||||
: base(ScrollingDirection.Up)
|
: base(ScrollingDirection.Up)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
Width = column_width;
|
Width = column_width;
|
||||||
|
|
||||||
|
Masking = true;
|
||||||
|
CornerRadius = 5;
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
background = new Box
|
background = new Box
|
||||||
{
|
{
|
||||||
Name = "Background",
|
Name = "Background",
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Alpha = opacity_released
|
Alpha = 0.3f
|
||||||
|
},
|
||||||
|
backgroundOverlay = new Box
|
||||||
|
{
|
||||||
|
Name = "Background Gradient Overlay",
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Height = 0.5f,
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
Blending = BlendingMode.Additive,
|
||||||
|
Alpha = 0
|
||||||
},
|
},
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
@ -182,6 +193,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
background.Colour = accentColour;
|
background.Colour = accentColour;
|
||||||
|
backgroundOverlay.Colour = ColourInfo.GradientVertical(accentColour.Opacity(0.6f), accentColour.Opacity(0));
|
||||||
|
|
||||||
hitTargetBar.EdgeEffect = new EdgeEffectParameters
|
hitTargetBar.EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
@ -213,7 +225,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
||||||
{
|
{
|
||||||
if (!judgement.IsHit)
|
if (!judgement.IsHit || !judgedObject.DisplayJudgement)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
explosionContainer.Add(new HitExplosion(judgedObject));
|
explosionContainer.Add(new HitExplosion(judgedObject));
|
||||||
@ -223,8 +235,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
{
|
{
|
||||||
if (action == Action)
|
if (action == Action)
|
||||||
{
|
{
|
||||||
background.FadeTo(opacity_pressed, 50, Easing.OutQuint);
|
backgroundOverlay.FadeTo(1, 50, Easing.OutQuint).Then().FadeTo(0.5f, 250, Easing.OutQuint);
|
||||||
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint);
|
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint).Then().ScaleTo(1.3f, 250, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -234,8 +246,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
{
|
{
|
||||||
if (action == Action)
|
if (action == Action)
|
||||||
{
|
{
|
||||||
background.FadeTo(opacity_released, 800, Easing.OutQuart);
|
backgroundOverlay.FadeTo(0, 250, Easing.OutQuint);
|
||||||
keyIcon.ScaleTo(1f, 400, Easing.OutQuart);
|
keyIcon.ScaleTo(1f, 125, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
// 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 OpenTK;
|
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
internal class HitExplosion : CompositeDrawable
|
internal class HitExplosion : CompositeDrawable
|
||||||
{
|
{
|
||||||
private readonly Box inner;
|
private readonly CircularContainer circle;
|
||||||
|
|
||||||
public HitExplosion(DrawableHitObject judgedObject)
|
public HitExplosion(DrawableHitObject judgedObject)
|
||||||
{
|
{
|
||||||
@ -22,33 +24,32 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
Anchor = Anchor.TopCentre;
|
Anchor = Anchor.TopCentre;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.X;
|
||||||
Size = new Vector2(isTick ? 0.5f : 1);
|
Y = NotePiece.NOTE_HEIGHT / 2;
|
||||||
FillMode = FillMode.Fit;
|
Height = NotePiece.NOTE_HEIGHT;
|
||||||
|
|
||||||
Blending = BlendingMode.Additive;
|
// scale roughly in-line with visual appearance of notes
|
||||||
|
Scale = new Vector2(isTick ? 0.4f : 0.8f);
|
||||||
|
|
||||||
Color4 accent = isTick ? Color4.White : judgedObject.AccentColour;
|
InternalChild = circle = new CircularContainer
|
||||||
|
|
||||||
InternalChild = new CircularContainer
|
|
||||||
{
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
BorderThickness = 1,
|
// we want our size to be very small so the glow dominates it.
|
||||||
BorderColour = accent,
|
Size = new Vector2(0.1f),
|
||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Type = EdgeEffectType.Glow,
|
Type = EdgeEffectType.Glow,
|
||||||
Colour = accent,
|
Colour = Interpolation.ValueAt(0.1f, judgedObject.AccentColour, Color4.White, 0, 1),
|
||||||
Radius = 10,
|
Radius = 100,
|
||||||
Hollow = true
|
|
||||||
},
|
},
|
||||||
Child = inner = new Box
|
Child = new Box
|
||||||
{
|
{
|
||||||
|
Alpha = 0,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = accent,
|
AlwaysPresent = true
|
||||||
Alpha = 1,
|
|
||||||
AlwaysPresent = true,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -57,8 +58,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
this.ScaleTo(2f, 600, Easing.OutQuint).FadeOut(500);
|
circle.ResizeTo(circle.Size * new Vector2(4, 20), 1000, Easing.OutQuint);
|
||||||
inner.FadeOut(250);
|
this.FadeIn(16).Then().FadeOut(500, Easing.OutQuint);
|
||||||
|
|
||||||
Expire(true);
|
Expire(true);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Configuration;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
@ -78,6 +77,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
AutoSizeAxes = Axes.X,
|
AutoSizeAxes = Axes.X,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
|
CornerRadius = 5,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
@ -171,6 +171,9 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
||||||
{
|
{
|
||||||
|
if (!judgedObject.DisplayJudgement)
|
||||||
|
return;
|
||||||
|
|
||||||
judgements.Clear();
|
judgements.Clear();
|
||||||
judgements.Add(new DrawableManiaJudgement(judgement, judgedObject)
|
judgements.Add(new DrawableManiaJudgement(judgement, judgedObject)
|
||||||
{
|
{
|
||||||
@ -180,15 +183,15 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load()
|
||||||
{
|
{
|
||||||
normalColumnColours = new List<Color4>
|
normalColumnColours = new List<Color4>
|
||||||
{
|
{
|
||||||
colours.RedDark,
|
new Color4(94, 0, 57, 255),
|
||||||
colours.GreenDark
|
new Color4(6, 84, 0, 255)
|
||||||
};
|
};
|
||||||
|
|
||||||
specialColumnColour = colours.BlueDark;
|
specialColumnColour = new Color4(0, 48, 63, 255);
|
||||||
|
|
||||||
// Set the special column + colour + key
|
// Set the special column + colour + key
|
||||||
foreach (var column in Columns)
|
foreach (var column in Columns)
|
||||||
|
10
osu.Game.Rulesets.Osu.Tests/.vscode/launch.json
vendored
10
osu.Game.Rulesets.Osu.Tests/.vscode/launch.json
vendored
@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"type": "mono",
|
"type": "mono",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Osu.Tests.exe",
|
"program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Osu.Tests.exe",
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release, msbuild)",
|
"preLaunchTask": "Build (Release, msbuild)",
|
||||||
"runtimeExecutable": null,
|
"runtimeExecutable": null,
|
||||||
@ -30,12 +30,12 @@
|
|||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Osu.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug, dotnet)",
|
"preLaunchTask": "Build (Debug, dotnet)",
|
||||||
@ -43,12 +43,12 @@
|
|||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Osu.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release, dotnet)",
|
"preLaunchTask": "Build (Release, dotnet)",
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Rulesets.Osu.Tests.csproj",
|
"osu.Game.Rulesets.Osu.Tests.csproj",
|
||||||
"/p:TargetFramework=netcoreapp2.0",
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
"/verbosity:m"
|
"/verbosity:m"
|
||||||
@ -56,7 +56,7 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Rulesets.Osu.Tests.csproj",
|
"osu.Game.Rulesets.Osu.Tests.csproj",
|
||||||
"/p:TargetFramework=netcoreapp2.0",
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
"/p:Configuration=Release",
|
"/p:Configuration=Release",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
@ -75,7 +75,7 @@
|
|||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Restore (netcoreapp2.0)",
|
"label": "Restore (netcoreapp2.1)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||||
</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" />
|
||||||
|
@ -61,20 +61,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
if (mods.Any(m => !m.Ranked))
|
if (mods.Any(m => !m.Ranked))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Todo: In the future we should apply changes to PreEmpt/AR at an OsuHitObject/BaseDifficulty level, but this is done
|
// Todo: These int casts are temporary to achieve 1:1 results with osu!stable, and should be remoevd in the future
|
||||||
// locally for now as doing so would modify animations and other things unexpectedly
|
double hitWindowGreat = (int)(Beatmap.HitObjects.First().HitWindows.Great / 2) / TimeRate;
|
||||||
// DO NOT MODIFY THIS
|
double preEmpt = (int)BeatmapDifficulty.DifficultyRange(Beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / TimeRate;
|
||||||
double ar = Beatmap.BeatmapInfo.BaseDifficulty.ApproachRate;
|
|
||||||
if (mods.Any(m => m is OsuModHardRock))
|
|
||||||
ar = Math.Min(10, ar * 1.4);
|
|
||||||
if (mods.Any(m => m is OsuModEasy))
|
|
||||||
ar = Math.Max(0, ar / 2);
|
|
||||||
|
|
||||||
double preEmpt = BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450) / TimeRate;
|
|
||||||
double hitWindowGreat = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate;
|
|
||||||
|
|
||||||
realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5;
|
realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5;
|
||||||
realOverallDifficulty = (80 - 0.5 - hitWindowGreat) / 6;
|
realOverallDifficulty = (80 - hitWindowGreat) / 6;
|
||||||
|
|
||||||
// Custom multipliers for NoFail and SpunOut.
|
// Custom multipliers for NoFail and SpunOut.
|
||||||
double multiplier = 1.12f; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things
|
double multiplier = 1.12f; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things
|
||||||
|
@ -13,8 +13,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override string ShortenedName => "AP";
|
public override string ShortenedName => "AP";
|
||||||
public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot;
|
public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot;
|
||||||
public override string Description => @"Automatic cursor movement - just follow the rhythm.";
|
public override string Description => @"Automatic cursor movement - just follow the rhythm.";
|
||||||
public override double ScoreMultiplier => 0;
|
public override double ScoreMultiplier => 1;
|
||||||
public override bool Ranked => false;
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) };
|
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,33 +7,34 @@ using System.Linq;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects
|
public class OsuModHidden : ModHidden
|
||||||
{
|
{
|
||||||
public override string Description => @"Play with no approach circles and fading circles/sliders.";
|
public override string Description => @"Play with no approach circles and fading circles/sliders.";
|
||||||
public override double ScoreMultiplier => 1.06;
|
public override double ScoreMultiplier => 1.06;
|
||||||
|
|
||||||
private const double fade_in_duration_multiplier = 0.4;
|
private const double fade_in_duration_multiplier = 0.4;
|
||||||
private const double fade_out_duration_multiplier = 0.3;
|
private const double fade_out_duration_multiplier = 0.3;
|
||||||
|
|
||||||
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
public override void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||||
{
|
{
|
||||||
|
void adjustFadeIn(OsuHitObject h) => h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier;
|
||||||
|
|
||||||
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
|
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
|
||||||
{
|
{
|
||||||
d.ApplyCustomUpdateState += ApplyHiddenState;
|
adjustFadeIn(d.HitObject);
|
||||||
|
|
||||||
d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier;
|
|
||||||
foreach (var h in d.HitObject.NestedHitObjects.OfType<OsuHitObject>())
|
foreach (var h in d.HitObject.NestedHitObjects.OfType<OsuHitObject>())
|
||||||
h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier;
|
adjustFadeIn(h);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
|
base.ApplyToDrawableHitObjects(drawables);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
|
||||||
{
|
{
|
||||||
if (!(drawable is DrawableOsuHitObject d))
|
if (!(drawable is DrawableOsuHitObject d))
|
||||||
return;
|
return;
|
||||||
|
@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
|
|
||||||
private Bindable<double> cursorScale;
|
private Bindable<double> cursorScale;
|
||||||
private Bindable<bool> autoCursorScale;
|
private Bindable<bool> autoCursorScale;
|
||||||
private Bindable<WorkingBeatmap> beatmap;
|
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||||
|
|
||||||
public OsuCursor()
|
public OsuCursor()
|
||||||
{
|
{
|
||||||
@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config, OsuGameBase game)
|
private void load(OsuConfigManager config, IBindableBeatmap beatmap)
|
||||||
{
|
{
|
||||||
Child = cursorContainer = new SkinnableDrawable("cursor", _ => new CircularContainer
|
Child = cursorContainer = new SkinnableDrawable("cursor", _ => new CircularContainer
|
||||||
{
|
{
|
||||||
@ -160,7 +160,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
};
|
};
|
||||||
|
|
||||||
beatmap = game.Beatmap.GetBoundCopy();
|
this.beatmap.BindTo(beatmap);
|
||||||
beatmap.ValueChanged += v => calculateScale();
|
beatmap.ValueChanged += v => calculateScale();
|
||||||
|
|
||||||
cursorScale = config.GetBindable<double>(OsuSetting.GameplayCursorSize);
|
cursorScale = config.GetBindable<double>(OsuSetting.GameplayCursorSize);
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"type": "mono",
|
"type": "mono",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Taiko.Tests.exe",
|
"program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Taiko.Tests.exe",
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release, msbuild)",
|
"preLaunchTask": "Build (Release, msbuild)",
|
||||||
"runtimeExecutable": null,
|
"runtimeExecutable": null,
|
||||||
@ -30,12 +30,12 @@
|
|||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Taiko.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug, dotnet)",
|
"preLaunchTask": "Build (Debug, dotnet)",
|
||||||
@ -43,12 +43,12 @@
|
|||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Taiko.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release, dotnet)",
|
"preLaunchTask": "Build (Release, dotnet)",
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Rulesets.Taiko.Tests.csproj",
|
"osu.Game.Rulesets.Taiko.Tests.csproj",
|
||||||
"/p:TargetFramework=netcoreapp2.0",
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
"/verbosity:m"
|
"/verbosity:m"
|
||||||
@ -56,7 +56,7 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Rulesets.Taiko.Tests.csproj",
|
"osu.Game.Rulesets.Taiko.Tests.csproj",
|
||||||
"/p:TargetFramework=netcoreapp2.0",
|
"/p:TargetFramework=netcoreapp2.1",
|
||||||
"/p:Configuration=Release",
|
"/p:Configuration=Release",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
@ -75,7 +75,7 @@
|
|||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Restore (netcoreapp2.0)",
|
"label": "Restore (netcoreapp2.1)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||||
</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" />
|
||||||
|
@ -94,7 +94,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
|||||||
|
|
||||||
private double computeAccuracyValue()
|
private double computeAccuracyValue()
|
||||||
{
|
{
|
||||||
double hitWindowGreat = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate;
|
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be remoevd in the future
|
||||||
|
double hitWindowGreat = (int)(Beatmap.HitObjects.First().HitWindows.Great / 2) / TimeRate;
|
||||||
if (hitWindowGreat <= 0)
|
if (hitWindowGreat <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ using osu.Framework.Platform;
|
|||||||
using osu.Game.IPC;
|
using osu.Game.IPC;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using SharpCompress.Archives.Zip;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Beatmaps.IO
|
namespace osu.Game.Tests.Beatmaps.IO
|
||||||
{
|
{
|
||||||
@ -77,8 +78,69 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
|
|
||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
Assert.IsTrue(manager.GetAllUsableBeatmapSets().Count == 1);
|
Assert.AreEqual(1, manager.GetAllUsableBeatmapSets().Count);
|
||||||
Assert.IsTrue(manager.QueryBeatmapSets(_ => true).ToList().Count == 1);
|
Assert.AreEqual(1, manager.QueryBeatmapSets(_ => true).ToList().Count);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
host.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestRollbackOnFailure()
|
||||||
|
{
|
||||||
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestRollbackOnFailure"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var osu = loadOsu(host);
|
||||||
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
|
int fireCount = 0;
|
||||||
|
|
||||||
|
// ReSharper disable once AccessToModifiedClosure
|
||||||
|
manager.ItemAdded += _ => fireCount++;
|
||||||
|
manager.ItemRemoved += _ => fireCount++;
|
||||||
|
|
||||||
|
var imported = loadOszIntoOsu(osu);
|
||||||
|
|
||||||
|
Assert.AreEqual(0, fireCount -= 1);
|
||||||
|
|
||||||
|
imported.Hash += "-changed";
|
||||||
|
manager.Update(imported);
|
||||||
|
|
||||||
|
Assert.AreEqual(0, fireCount -= 2);
|
||||||
|
|
||||||
|
var breakTemp = createTemporaryBeatmap();
|
||||||
|
|
||||||
|
MemoryStream brokenOsu = new MemoryStream(new byte[] { 1, 3, 3, 7 });
|
||||||
|
MemoryStream brokenOsz = new MemoryStream(File.ReadAllBytes(breakTemp));
|
||||||
|
|
||||||
|
File.Delete(breakTemp);
|
||||||
|
|
||||||
|
using (var outStream = File.Open(breakTemp, FileMode.CreateNew))
|
||||||
|
using (var zip = ZipArchive.Open(brokenOsz))
|
||||||
|
{
|
||||||
|
zip.AddEntry("broken.osu", brokenOsu, false);
|
||||||
|
zip.SaveTo(outStream, SharpCompress.Common.CompressionType.Deflate);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(1, manager.GetAllUsableBeatmapSets().Count);
|
||||||
|
Assert.AreEqual(1, manager.QueryBeatmapSets(_ => true).ToList().Count);
|
||||||
|
Assert.AreEqual(12, manager.QueryBeatmaps(_ => true).ToList().Count);
|
||||||
|
|
||||||
|
// this will trigger purging of the existing beatmap (online set id match) but should rollback due to broken osu.
|
||||||
|
manager.Import(breakTemp);
|
||||||
|
|
||||||
|
// no events should be fired in the case of a rollback.
|
||||||
|
Assert.AreEqual(0, fireCount);
|
||||||
|
|
||||||
|
Assert.AreEqual(1, manager.GetAllUsableBeatmapSets().Count);
|
||||||
|
Assert.AreEqual(1, manager.QueryBeatmapSets(_ => true).ToList().Count);
|
||||||
|
Assert.AreEqual(12, manager.QueryBeatmaps(_ => true).ToList().Count);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -100,18 +162,17 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
|
|
||||||
var imported = loadOszIntoOsu(osu);
|
var imported = loadOszIntoOsu(osu);
|
||||||
|
|
||||||
//var change = manager.QueryBeatmapSets(_ => true).First();
|
|
||||||
imported.Hash += "-changed";
|
imported.Hash += "-changed";
|
||||||
manager.Update(imported);
|
manager.Update(imported);
|
||||||
|
|
||||||
var importedSecondTime = loadOszIntoOsu(osu);
|
var importedSecondTime = loadOszIntoOsu(osu);
|
||||||
|
|
||||||
// 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);
|
||||||
Assert.IsTrue(imported.Beatmaps.First().ID < importedSecondTime.Beatmaps.First().ID);
|
Assert.IsTrue(imported.Beatmaps.First().ID < importedSecondTime.Beatmaps.First().ID);
|
||||||
|
|
||||||
Assert.IsTrue(manager.GetAllUsableBeatmapSets().Count == 1);
|
// only one beatmap will exist as the online set ID matched, causing purging of the first import.
|
||||||
Assert.IsTrue(manager.QueryBeatmapSets(_ => true).ToList().Count == 1);
|
Assert.AreEqual(1, manager.GetAllUsableBeatmapSets().Count);
|
||||||
|
Assert.AreEqual(1, manager.QueryBeatmapSets(_ => true).ToList().Count);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -162,8 +223,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
|
|
||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
var temp = prepareTempCopy(osz_path);
|
var temp = createTemporaryBeatmap();
|
||||||
Assert.IsTrue(File.Exists(temp));
|
|
||||||
|
|
||||||
var importer = new ArchiveImportIPCChannel(client);
|
var importer = new ArchiveImportIPCChannel(client);
|
||||||
if (!importer.ImportAsync(temp).Wait(10000))
|
if (!importer.ImportAsync(temp).Wait(10000))
|
||||||
@ -188,8 +248,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
var temp = prepareTempCopy(osz_path);
|
var temp = createTemporaryBeatmap();
|
||||||
Assert.IsTrue(File.Exists(temp), "Temporary file copy never substantiated");
|
|
||||||
using (File.OpenRead(temp))
|
using (File.OpenRead(temp))
|
||||||
osu.Dependencies.Get<BeatmapManager>().Import(temp);
|
osu.Dependencies.Get<BeatmapManager>().Import(temp);
|
||||||
ensureLoaded(osu);
|
ensureLoaded(osu);
|
||||||
@ -203,11 +262,17 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BeatmapSetInfo loadOszIntoOsu(OsuGameBase osu)
|
private string createTemporaryBeatmap()
|
||||||
{
|
{
|
||||||
var temp = prepareTempCopy(osz_path);
|
var temp = Path.GetTempFileName() + ".osz";
|
||||||
|
File.Copy(osz_path, temp, true);
|
||||||
Assert.IsTrue(File.Exists(temp));
|
Assert.IsTrue(File.Exists(temp));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BeatmapSetInfo loadOszIntoOsu(OsuGameBase osu, string path = null)
|
||||||
|
{
|
||||||
|
var temp = path ?? createTemporaryBeatmap();
|
||||||
|
|
||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
@ -219,7 +284,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
|
|
||||||
waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000);
|
waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000);
|
||||||
|
|
||||||
return imported.FirstOrDefault();
|
return imported.LastOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteBeatmapSet(BeatmapSetInfo imported, OsuGameBase osu)
|
private void deleteBeatmapSet(BeatmapSetInfo imported, OsuGameBase osu)
|
||||||
@ -228,16 +293,10 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
manager.Delete(imported);
|
manager.Delete(imported);
|
||||||
|
|
||||||
Assert.IsTrue(manager.GetAllUsableBeatmapSets().Count == 0);
|
Assert.IsTrue(manager.GetAllUsableBeatmapSets().Count == 0);
|
||||||
Assert.IsTrue(manager.QueryBeatmapSets(_ => true).ToList().Count == 1);
|
Assert.AreEqual(1, manager.QueryBeatmapSets(_ => true).ToList().Count);
|
||||||
Assert.IsTrue(manager.QueryBeatmapSets(_ => true).First().DeletePending);
|
Assert.IsTrue(manager.QueryBeatmapSets(_ => true).First().DeletePending);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string prepareTempCopy(string path)
|
|
||||||
{
|
|
||||||
var temp = Path.GetTempFileName();
|
|
||||||
return new FileInfo(path).CopyTo(temp, true).FullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private OsuGameBase loadOsu(GameHost host)
|
private OsuGameBase loadOsu(GameHost host)
|
||||||
{
|
{
|
||||||
var osu = new OsuGameBase();
|
var osu = new OsuGameBase();
|
||||||
@ -286,12 +345,12 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
|
|
||||||
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
|
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
|
||||||
{
|
{
|
||||||
Action waitAction = () =>
|
Task task = Task.Run(() =>
|
||||||
{
|
{
|
||||||
while (!result()) Thread.Sleep(200);
|
while (!result()) Thread.Sleep(200);
|
||||||
};
|
});
|
||||||
|
|
||||||
Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), failureMessage);
|
Assert.IsTrue(task.Wait(timeout), failureMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile);
|
Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile);
|
||||||
Assert.AreEqual("Deif", meta.AuthorString);
|
Assert.AreEqual("Deif", meta.AuthorString);
|
||||||
Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile);
|
Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile);
|
||||||
Assert.AreEqual(164471 + LegacyBeatmapDecoder.UniversalOffset, meta.PreviewTime);
|
Assert.AreEqual(164471, meta.PreviewTime);
|
||||||
Assert.AreEqual(string.Empty, meta.Source);
|
Assert.AreEqual(string.Empty, meta.Source);
|
||||||
Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags);
|
Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags);
|
||||||
Assert.AreEqual("Renatus", meta.Title);
|
Assert.AreEqual("Renatus", meta.Title);
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
@ -12,10 +12,22 @@ namespace osu.Game.Tests.Visual
|
|||||||
[Description("Player instantiated with an autoplay mod.")]
|
[Description("Player instantiated with an autoplay mod.")]
|
||||||
public class TestCaseAutoplay : TestCasePlayer
|
public class TestCaseAutoplay : TestCasePlayer
|
||||||
{
|
{
|
||||||
protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
||||||
return base.CreatePlayer(beatmap, ruleset);
|
return new ScoreAccessiblePlayer
|
||||||
|
{
|
||||||
|
AllowPause = false,
|
||||||
|
AllowLeadIn = false,
|
||||||
|
AllowResults = false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ContinueCondition(Player player) => base.ContinueCondition(player) && ((ScoreAccessiblePlayer)player).ScoreProcessor.TotalScore > 0;
|
||||||
|
|
||||||
|
private class ScoreAccessiblePlayer : Player
|
||||||
|
{
|
||||||
|
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,11 +65,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
carousel.SelectionChanged = s => currentSelection = s;
|
carousel.SelectionChanged = s => currentSelection = s;
|
||||||
|
|
||||||
AddStep("Load Beatmaps", () => { carousel.BeatmapSets = beatmapSets; });
|
loadBeatmaps(beatmapSets);
|
||||||
|
|
||||||
bool changed = false;
|
|
||||||
carousel.BeatmapSetsChanged = () => changed = true;
|
|
||||||
AddUntilStep(() => changed, "Wait for load");
|
|
||||||
|
|
||||||
testTraversal();
|
testTraversal();
|
||||||
testFiltering();
|
testFiltering();
|
||||||
@ -84,6 +80,17 @@ namespace osu.Game.Tests.Visual
|
|||||||
testCarouselRootIsRandom();
|
testCarouselRootIsRandom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadBeatmaps(List<BeatmapSetInfo> beatmapSets)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
AddStep($"Load {beatmapSets.Count} Beatmaps", () =>
|
||||||
|
{
|
||||||
|
carousel.BeatmapSetsChanged = () => changed = true;
|
||||||
|
carousel.BeatmapSets = beatmapSets;
|
||||||
|
});
|
||||||
|
AddUntilStep(() => changed, "Wait for load");
|
||||||
|
}
|
||||||
|
|
||||||
private void ensureRandomFetchSuccess() =>
|
private void ensureRandomFetchSuccess() =>
|
||||||
AddAssert("ensure prev random fetch worked", () => selectedSets.Peek() == carousel.SelectedBeatmapSet);
|
AddAssert("ensure prev random fetch worked", () => selectedSets.Peek() == carousel.SelectedBeatmapSet);
|
||||||
|
|
||||||
@ -423,7 +430,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
for (int i = 1; i <= 50; i++)
|
for (int i = 1; i <= 50; i++)
|
||||||
beatmapSets.Add(createTestBeatmapSet(i));
|
beatmapSets.Add(createTestBeatmapSet(i));
|
||||||
|
|
||||||
AddStep("Load 50 Beatmaps", () => { carousel.BeatmapSets = beatmapSets; });
|
loadBeatmaps(beatmapSets);
|
||||||
advanceSelection(direction: 1, diff: false);
|
advanceSelection(direction: 1, diff: false);
|
||||||
checkNonmatchingFilter();
|
checkNonmatchingFilter();
|
||||||
checkNonmatchingFilter();
|
checkNonmatchingFilter();
|
||||||
|
@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -29,14 +28,11 @@ namespace osu.Game.Tests.Visual
|
|||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
private TestBeatmapInfoWedge infoWedge;
|
private TestBeatmapInfoWedge infoWedge;
|
||||||
private readonly List<IBeatmap> beatmaps = new List<IBeatmap>();
|
private readonly List<IBeatmap> beatmaps = new List<IBeatmap>();
|
||||||
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase game, RulesetStore rulesets)
|
private void load(RulesetStore rulesets)
|
||||||
{
|
{
|
||||||
this.rulesets = rulesets;
|
this.rulesets = rulesets;
|
||||||
|
|
||||||
beatmap.BindTo(game.Beatmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -53,11 +49,11 @@ namespace osu.Game.Tests.Visual
|
|||||||
AddStep("show", () =>
|
AddStep("show", () =>
|
||||||
{
|
{
|
||||||
infoWedge.State = Visibility.Visible;
|
infoWedge.State = Visibility.Visible;
|
||||||
infoWedge.UpdateBeatmap(beatmap);
|
infoWedge.Beatmap = Beatmap;
|
||||||
});
|
});
|
||||||
|
|
||||||
// select part is redundant, but wait for load isn't
|
// select part is redundant, but wait for load isn't
|
||||||
selectBeatmap(beatmap.Value.Beatmap);
|
selectBeatmap(Beatmap.Value.Beatmap);
|
||||||
|
|
||||||
AddWaitStep(3);
|
AddWaitStep(3);
|
||||||
|
|
||||||
@ -120,8 +116,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
selectNullBeatmap();
|
selectNullBeatmap();
|
||||||
AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Text));
|
AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Text));
|
||||||
AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Title);
|
AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Title);
|
||||||
AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Artist);
|
AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Artist);
|
||||||
AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any());
|
AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any());
|
||||||
AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any());
|
AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any());
|
||||||
}
|
}
|
||||||
@ -133,7 +129,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
AddStep($"select {b.Metadata.Title} beatmap", () =>
|
AddStep($"select {b.Metadata.Title} beatmap", () =>
|
||||||
{
|
{
|
||||||
infoBefore = infoWedge.Info;
|
infoBefore = infoWedge.Info;
|
||||||
infoWedge.UpdateBeatmap(beatmap.Value = new TestWorkingBeatmap(b));
|
infoWedge.Beatmap = Beatmap.Value = new TestWorkingBeatmap(b);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load");
|
AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load");
|
||||||
@ -143,8 +139,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
AddStep("select null beatmap", () =>
|
AddStep("select null beatmap", () =>
|
||||||
{
|
{
|
||||||
beatmap.Value = beatmap.Default;
|
Beatmap.Value = Beatmap.Default;
|
||||||
infoWedge.UpdateBeatmap(beatmap);
|
infoWedge.Beatmap = Beatmap;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,9 +35,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
typeof(MessageFormatter)
|
typeof(MessageFormatter)
|
||||||
};
|
};
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
|
|
||||||
|
|
||||||
public TestCaseChatLink()
|
public TestCaseChatLink()
|
||||||
{
|
{
|
||||||
Add(textContainer = new TestChatLineContainer
|
Add(textContainer = new TestChatLineContainer
|
||||||
@ -53,7 +50,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
linkColour = colours.Blue;
|
linkColour = colours.Blue;
|
||||||
dependencies.Cache(new ChatOverlay
|
Dependencies.Cache(new ChatOverlay
|
||||||
{
|
{
|
||||||
AvailableChannels =
|
AvailableChannels =
|
||||||
{
|
{
|
||||||
|
@ -19,12 +19,12 @@ namespace osu.Game.Tests.Visual
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseCursors : ManualInputManagerTestCase
|
public class TestCaseCursors : ManualInputManagerTestCase
|
||||||
{
|
{
|
||||||
private readonly CursorOverrideContainer cursorOverrideContainer;
|
private readonly MenuCursorContainer menuCursorContainer;
|
||||||
private readonly CustomCursorBox[] cursorBoxes = new CustomCursorBox[6];
|
private readonly CustomCursorBox[] cursorBoxes = new CustomCursorBox[6];
|
||||||
|
|
||||||
public TestCaseCursors()
|
public TestCaseCursors()
|
||||||
{
|
{
|
||||||
Child = cursorOverrideContainer = new CursorOverrideContainer
|
Child = menuCursorContainer = new MenuCursorContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
@ -99,7 +99,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
AddAssert("Check green cursor at mouse", () => checkAtMouse(cursorBoxes[0].Cursor));
|
AddAssert("Check green cursor at mouse", () => checkAtMouse(cursorBoxes[0].Cursor));
|
||||||
AddStep("Move out", moveOut);
|
AddStep("Move out", moveOut);
|
||||||
AddAssert("Check green cursor invisible", () => !checkVisible(cursorBoxes[0].Cursor));
|
AddAssert("Check green cursor invisible", () => !checkVisible(cursorBoxes[0].Cursor));
|
||||||
AddAssert("Check global cursor visible", () => checkVisible(cursorOverrideContainer.Cursor));
|
AddAssert("Check global cursor visible", () => checkVisible(menuCursorContainer.Cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -112,11 +112,11 @@ namespace osu.Game.Tests.Visual
|
|||||||
AddStep("Move to purple area", () => InputManager.MoveMouseTo(cursorBoxes[3]));
|
AddStep("Move to purple area", () => InputManager.MoveMouseTo(cursorBoxes[3]));
|
||||||
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
|
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
|
||||||
AddAssert("Check purple cursor at mouse", () => checkAtMouse(cursorBoxes[3].Cursor));
|
AddAssert("Check purple cursor at mouse", () => checkAtMouse(cursorBoxes[3].Cursor));
|
||||||
AddAssert("Check global cursor visible", () => checkVisible(cursorOverrideContainer.Cursor));
|
AddAssert("Check global cursor visible", () => checkVisible(menuCursorContainer.Cursor));
|
||||||
AddAssert("Check global cursor at mouse", () => checkAtMouse(cursorOverrideContainer.Cursor));
|
AddAssert("Check global cursor at mouse", () => checkAtMouse(menuCursorContainer.Cursor));
|
||||||
AddStep("Move out", moveOut);
|
AddStep("Move out", moveOut);
|
||||||
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
|
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
|
||||||
AddAssert("Check global cursor visible", () => checkVisible(cursorOverrideContainer.Cursor));
|
AddAssert("Check global cursor visible", () => checkVisible(menuCursorContainer.Cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -17,14 +17,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(Compose) };
|
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(Compose) };
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase osuGame)
|
private void load()
|
||||||
{
|
{
|
||||||
osuGame.Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||||
|
Child = new Compose();
|
||||||
var compose = new Compose();
|
|
||||||
compose.Beatmap.BindTo(osuGame.Beatmap);
|
|
||||||
|
|
||||||
Child = compose;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
@ -18,8 +17,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) };
|
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) };
|
||||||
|
|
||||||
private readonly ScrollableTimeline timeline;
|
|
||||||
|
|
||||||
public TestCaseEditorComposeTimeline()
|
public TestCaseEditorComposeTimeline()
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -30,7 +27,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
State = Visibility.Visible
|
State = Visibility.Visible
|
||||||
},
|
},
|
||||||
timeline = new ScrollableTimeline
|
new ScrollableTimeline
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -38,11 +35,5 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuGameBase osuGame)
|
|
||||||
{
|
|
||||||
timeline.Beatmap.BindTo(osuGame.Beatmap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase osuGame)
|
private void load()
|
||||||
{
|
{
|
||||||
var testBeatmap = new Beatmap
|
var testBeatmap = new Beatmap
|
||||||
{
|
{
|
||||||
@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
osuGame.Beatmap.Value = new TestWorkingBeatmap(testBeatmap);
|
Beatmap.Value = new TestWorkingBeatmap(testBeatmap);
|
||||||
|
|
||||||
Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock };
|
Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock };
|
||||||
|
|
||||||
|
@ -19,19 +19,16 @@ namespace osu.Game.Tests.Visual
|
|||||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(SummaryTimeline) };
|
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(SummaryTimeline) };
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase osuGame)
|
private void load()
|
||||||
{
|
{
|
||||||
osuGame.Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||||
|
|
||||||
SummaryTimeline summaryTimeline;
|
Add(new SummaryTimeline
|
||||||
Add(summaryTimeline = new SummaryTimeline
|
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Size = new Vector2(500, 50)
|
Size = new Vector2(500, 50)
|
||||||
});
|
});
|
||||||
|
|
||||||
summaryTimeline.Beatmap.BindTo(osuGame.Beatmap);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
osu.Game.Tests/Visual/TestCaseExternalLinkButton.cs
Normal file
23
osu.Game.Tests/Visual/TestCaseExternalLinkButton.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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseExternalLinkButton : OsuTestCase
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(ExternalLinkButton) };
|
||||||
|
|
||||||
|
public TestCaseExternalLinkButton()
|
||||||
|
{
|
||||||
|
Child = new ExternalLinkButton("https://osu.ppy.sh/home")
|
||||||
|
{
|
||||||
|
Size = new Vector2(50)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -32,15 +32,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
typeof(NotNullAttribute)
|
typeof(NotNullAttribute)
|
||||||
};
|
};
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
|
||||||
=> dependencies = new DependencyContainer(parent);
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase osuGame)
|
private void load()
|
||||||
{
|
{
|
||||||
osuGame.Beatmap.Value = new TestWorkingBeatmap(new Beatmap
|
Beatmap.Value = new TestWorkingBeatmap(new Beatmap
|
||||||
{
|
{
|
||||||
HitObjects = new List<HitObject>
|
HitObjects = new List<HitObject>
|
||||||
{
|
{
|
||||||
@ -63,8 +58,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
});
|
});
|
||||||
|
|
||||||
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
||||||
dependencies.CacheAs<IAdjustableClock>(clock);
|
Dependencies.CacheAs<IAdjustableClock>(clock);
|
||||||
dependencies.CacheAs<IFrameBasedClock>(clock);
|
Dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||||
|
|
||||||
Child = new OsuHitObjectComposer(new OsuRuleset());
|
Child = new OsuHitObjectComposer(new OsuRuleset());
|
||||||
}
|
}
|
||||||
|
115
osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs
Normal file
115
osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// 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.Graphics.Shapes;
|
||||||
|
using osu.Game.Screens;
|
||||||
|
using osu.Game.Screens.Menu;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestCaseLoaderAnimation : OsuTestCase
|
||||||
|
{
|
||||||
|
private TestLoader loader;
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
// required to preload the logo in a headless run (so it doesn't delay the loading itself).
|
||||||
|
Add(new OsuLogo());
|
||||||
|
|
||||||
|
bool logoVisible = false;
|
||||||
|
AddStep("almost instant display", () => Child = loader = new TestLoader(250));
|
||||||
|
AddUntilStep(() =>
|
||||||
|
{
|
||||||
|
logoVisible = loader.Logo?.Alpha > 0;
|
||||||
|
return loader.Logo != null && loader.ScreenLoaded;
|
||||||
|
}, "loaded");
|
||||||
|
AddAssert("logo not visible", () => !logoVisible);
|
||||||
|
|
||||||
|
AddStep("short load", () => Child = loader = new TestLoader(800));
|
||||||
|
AddUntilStep(() =>
|
||||||
|
{
|
||||||
|
logoVisible = loader.Logo?.Alpha > 0;
|
||||||
|
return loader.Logo != null && loader.ScreenLoaded;
|
||||||
|
}, "loaded");
|
||||||
|
AddAssert("logo visible", () => logoVisible);
|
||||||
|
AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone");
|
||||||
|
|
||||||
|
AddStep("longer load", () => Child = loader = new TestLoader(1400));
|
||||||
|
AddUntilStep(() =>
|
||||||
|
{
|
||||||
|
logoVisible = loader.Logo?.Alpha > 0;
|
||||||
|
return loader.Logo != null && loader.ScreenLoaded;
|
||||||
|
}, "loaded");
|
||||||
|
AddAssert("logo visible", () => logoVisible);
|
||||||
|
AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone");
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestLoader : Loader
|
||||||
|
{
|
||||||
|
private readonly double delay;
|
||||||
|
|
||||||
|
public OsuLogo Logo;
|
||||||
|
private TestScreen screen;
|
||||||
|
|
||||||
|
public bool ScreenLoaded => screen.IsCurrentScreen;
|
||||||
|
|
||||||
|
public TestLoader(double delay)
|
||||||
|
{
|
||||||
|
this.delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
||||||
|
{
|
||||||
|
Logo = logo;
|
||||||
|
base.LogoArriving(logo, resuming);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override OsuScreen CreateLoadableScreen() => screen = new TestScreen();
|
||||||
|
protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(delay);
|
||||||
|
|
||||||
|
private class TestShaderPrecompiler : ShaderPrecompiler
|
||||||
|
{
|
||||||
|
private readonly double delay;
|
||||||
|
private double startTime;
|
||||||
|
|
||||||
|
public TestShaderPrecompiler(double delay)
|
||||||
|
{
|
||||||
|
this.delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
startTime = Time.Current;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool AllLoaded => Time.Current > startTime + delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestScreen : OsuScreen
|
||||||
|
{
|
||||||
|
public TestScreen()
|
||||||
|
{
|
||||||
|
Child = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.DarkSlateGray,
|
||||||
|
Alpha = 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
||||||
|
{
|
||||||
|
base.LogoArriving(logo, resuming);
|
||||||
|
Child.FadeInFromZero(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
211
osu.Game.Tests/Visual/TestCaseLounge.cs
Normal file
211
osu.Game.Tests/Visual/TestCaseLounge.cs
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
// 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.Multi.Components;
|
||||||
|
using osu.Game.Screens.Multi.Screens.Lounge;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using OpenTK.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));
|
||||||
|
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
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -39,8 +39,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
typeof(SpecialSection),
|
typeof(SpecialSection),
|
||||||
};
|
};
|
||||||
|
|
||||||
private const string unranked_suffix = " (Unranked)";
|
|
||||||
|
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
private ModDisplay modDisplay;
|
private ModDisplay modDisplay;
|
||||||
private TestModSelectOverlay modSelect;
|
private TestModSelectOverlay modSelect;
|
||||||
@ -121,7 +119,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private void testManiaMods(ManiaRuleset ruleset)
|
private void testManiaMods(ManiaRuleset ruleset)
|
||||||
{
|
{
|
||||||
testMultiplierTextUnranked(ruleset.GetModsFor(ModType.Special).First(m => m is ManiaModRandom));
|
testRankedText(ruleset.GetModsFor(ModType.Special).First(m => m is ManiaModRandom));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testSingleMod(Mod mod)
|
private void testSingleMod(Mod mod)
|
||||||
@ -198,13 +196,16 @@ namespace osu.Game.Tests.Visual
|
|||||||
checkLabelColor(Color4.White);
|
checkLabelColor(Color4.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testMultiplierTextUnranked(Mod mod)
|
private void testRankedText(Mod mod)
|
||||||
{
|
{
|
||||||
AddAssert("check for ranked", () => !modSelect.MultiplierLabel.Text.EndsWith(unranked_suffix));
|
AddWaitStep(1, "wait for fade");
|
||||||
|
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
|
||||||
selectNext(mod);
|
selectNext(mod);
|
||||||
AddAssert("check for unranked", () => modSelect.MultiplierLabel.Text.EndsWith(unranked_suffix));
|
AddWaitStep(1, "wait for fade");
|
||||||
|
AddAssert("check for unranked", () => modSelect.UnrankedLabel.Alpha != 0);
|
||||||
selectPrevious(mod);
|
selectPrevious(mod);
|
||||||
AddAssert("check for ranked", () => !modSelect.MultiplierLabel.Text.EndsWith(unranked_suffix));
|
AddWaitStep(1, "wait for fade");
|
||||||
|
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectNext(Mod mod) => AddStep($"left click {mod.Name}", () => modSelect.GetModButton(mod)?.SelectNext(1));
|
private void selectNext(Mod mod) => AddStep($"left click {mod.Name}", () => modSelect.GetModButton(mod)?.SelectNext(1));
|
||||||
@ -240,6 +241,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
|
|
||||||
public new OsuSpriteText MultiplierLabel => base.MultiplierLabel;
|
public new OsuSpriteText MultiplierLabel => base.MultiplierLabel;
|
||||||
|
public new OsuSpriteText UnrankedLabel => base.UnrankedLabel;
|
||||||
public new TriangleButton DeselectAllButton => base.DeselectAllButton;
|
public new TriangleButton DeselectAllButton => base.DeselectAllButton;
|
||||||
|
|
||||||
public new Color4 LowMultiplierColour => base.LowMultiplierColour;
|
public new Color4 LowMultiplierColour => base.LowMultiplierColour;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Screens.Multi;
|
using osu.Game.Screens.Multi;
|
||||||
using osu.Game.Screens.Multi.Screens;
|
using osu.Game.Screens.Multi.Screens.Lounge;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
@ -13,14 +13,14 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
public TestCaseMultiHeader()
|
public TestCaseMultiHeader()
|
||||||
{
|
{
|
||||||
Lobby lobby;
|
Lounge lounge;
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
lobby = new Lobby
|
lounge = new Lounge
|
||||||
{
|
{
|
||||||
Padding = new MarginPadding { Top = Header.HEIGHT },
|
Padding = new MarginPadding { Top = Header.HEIGHT },
|
||||||
},
|
},
|
||||||
new Header(lobby),
|
new Header(lounge),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,9 @@
|
|||||||
// 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 NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
@ -15,8 +12,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseMusicController : OsuTestCase
|
public class TestCaseMusicController : OsuTestCase
|
||||||
{
|
{
|
||||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
|
||||||
|
|
||||||
public TestCaseMusicController()
|
public TestCaseMusicController()
|
||||||
{
|
{
|
||||||
Clock = new FramedClock();
|
Clock = new FramedClock();
|
||||||
@ -30,13 +25,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
AddToggleStep(@"toggle visibility", state => mc.State = state ? Visibility.Visible : Visibility.Hidden);
|
AddToggleStep(@"toggle visibility", state => mc.State = state ? Visibility.Visible : Visibility.Hidden);
|
||||||
AddStep(@"show", () => mc.State = Visibility.Visible);
|
AddStep(@"show", () => mc.State = Visibility.Visible);
|
||||||
AddToggleStep(@"toggle beatmap lock", state => beatmapBacking.Disabled = state);
|
AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state);
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuGameBase game)
|
|
||||||
{
|
|
||||||
beatmapBacking.BindTo(game.Beatmap);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
|
||||||
private WorkingBeatmap defaultBeatmap;
|
private WorkingBeatmap defaultBeatmap;
|
||||||
|
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
@ -48,8 +47,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
typeof(DrawableCarouselBeatmapSet),
|
typeof(DrawableCarouselBeatmapSet),
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
|
|
||||||
|
|
||||||
private class TestSongSelect : PlaySongSelect
|
private class TestSongSelect : PlaySongSelect
|
||||||
{
|
{
|
||||||
public WorkingBeatmap CurrentBeatmap => Beatmap.Value;
|
public WorkingBeatmap CurrentBeatmap => Beatmap.Value;
|
||||||
@ -58,7 +55,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase game)
|
private void load()
|
||||||
{
|
{
|
||||||
TestSongSelect songSelect = null;
|
TestSongSelect songSelect = null;
|
||||||
|
|
||||||
@ -67,10 +64,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
// this is by no means clean. should be replacing inside of OsuGameBase somehow.
|
// this is by no means clean. should be replacing inside of OsuGameBase somehow.
|
||||||
IDatabaseContextFactory factory = new SingletonContextFactory(new OsuDbContext());
|
IDatabaseContextFactory factory = new SingletonContextFactory(new OsuDbContext());
|
||||||
|
|
||||||
dependencies.Cache(rulesets = new RulesetStore(factory));
|
Dependencies.Cache(rulesets = new RulesetStore(factory));
|
||||||
dependencies.Cache(manager = new BeatmapManager(storage, factory, rulesets, null, null)
|
Dependencies.Cache(manager = new BeatmapManager(storage, factory, rulesets, null, null)
|
||||||
{
|
{
|
||||||
DefaultBeatmap = defaultBeatmap = game.Beatmap.Default
|
DefaultBeatmap = defaultBeatmap = Beatmap.Default
|
||||||
});
|
});
|
||||||
|
|
||||||
void loadNewSongSelect(bool deleteMaps = false) => AddStep("reload song select", () =>
|
void loadNewSongSelect(bool deleteMaps = false) => AddStep("reload song select", () =>
|
||||||
@ -78,7 +75,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
if (deleteMaps)
|
if (deleteMaps)
|
||||||
{
|
{
|
||||||
manager.Delete(manager.GetAllUsableBeatmapSets());
|
manager.Delete(manager.GetAllUsableBeatmapSets());
|
||||||
game.Beatmap.SetDefault();
|
Beatmap.SetDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (songSelect != null)
|
if (songSelect != null)
|
||||||
|
@ -15,17 +15,12 @@ namespace osu.Game.Tests.Visual
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCasePlaybackControl : OsuTestCase
|
public class TestCasePlaybackControl : OsuTestCase
|
||||||
{
|
{
|
||||||
private DependencyContainer dependencies;
|
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
|
||||||
=> dependencies = new DependencyContainer(parent);
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
||||||
dependencies.CacheAs<IAdjustableClock>(clock);
|
Dependencies.CacheAs<IAdjustableClock>(clock);
|
||||||
dependencies.CacheAs<IFrameBasedClock>(clock);
|
Dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||||
|
|
||||||
var playback = new PlaybackControl
|
var playback = new PlaybackControl
|
||||||
{
|
{
|
||||||
@ -34,7 +29,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
Size = new Vector2(200,100)
|
Size = new Vector2(200,100)
|
||||||
};
|
};
|
||||||
|
|
||||||
playback.Beatmap.Value = new TestWorkingBeatmap(new Beatmap());
|
Beatmap.Value = new TestWorkingBeatmap(new Beatmap());
|
||||||
|
|
||||||
Child = playback;
|
Child = playback;
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase game)
|
private void load(OsuGameBase game)
|
||||||
{
|
{
|
||||||
|
Beatmap.Value = new DummyWorkingBeatmap(game);
|
||||||
|
|
||||||
AddStep("load dummy beatmap", () => Add(new PlayerLoader(new Player
|
AddStep("load dummy beatmap", () => Add(new PlayerLoader(new Player
|
||||||
{
|
{
|
||||||
InitialBeatmap = new DummyWorkingBeatmap(game),
|
|
||||||
AllowPause = false,
|
AllowPause = false,
|
||||||
AllowLeadIn = false,
|
AllowLeadIn = false,
|
||||||
AllowResults = false,
|
AllowResults = false,
|
||||||
|
@ -31,10 +31,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
var text = quitButton.Children.OfType<SpriteText>().First();
|
var text = quitButton.Children.OfType<SpriteText>().First();
|
||||||
|
|
||||||
// initial display
|
|
||||||
AddUntilStep(() => text.IsPresent && !exitAction, "Text visible");
|
|
||||||
AddUntilStep(() => !text.IsPresent && !exitAction, "Text is not visible");
|
|
||||||
|
|
||||||
AddStep("Trigger text fade in", () => InputManager.MoveMouseTo(quitButton));
|
AddStep("Trigger text fade in", () => InputManager.MoveMouseTo(quitButton));
|
||||||
AddUntilStep(() => text.IsPresent && !exitAction, "Text visible");
|
AddUntilStep(() => text.IsPresent && !exitAction, "Text visible");
|
||||||
AddStep("Trigger text fade out", () => InputManager.MoveMouseTo(Vector2.One));
|
AddStep("Trigger text fade out", () => InputManager.MoveMouseTo(Vector2.One));
|
||||||
@ -44,13 +40,13 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
exitAction = false;
|
exitAction = false;
|
||||||
InputManager.MoveMouseTo(quitButton);
|
InputManager.MoveMouseTo(quitButton);
|
||||||
InputManager.ButtonDown(MouseButton.Left);
|
InputManager.PressButton(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("Early release", () => InputManager.ButtonUp(MouseButton.Left));
|
AddStep("Early release", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
AddAssert("action not triggered", () => !exitAction);
|
AddAssert("action not triggered", () => !exitAction);
|
||||||
|
|
||||||
AddStep("Trigger exit action", () => InputManager.ButtonDown(MouseButton.Left));
|
AddStep("Trigger exit action", () => InputManager.PressButton(MouseButton.Left));
|
||||||
AddUntilStep(() => exitAction, $"{nameof(quitButton.Action)} was triggered");
|
AddUntilStep(() => exitAction, $"{nameof(quitButton.Action)} was triggered");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
@ -13,23 +12,20 @@ namespace osu.Game.Tests.Visual
|
|||||||
[Description("Player instantiated with a replay.")]
|
[Description("Player instantiated with a replay.")]
|
||||||
public class TestCaseReplay : TestCasePlayer
|
public class TestCaseReplay : TestCasePlayer
|
||||||
{
|
{
|
||||||
protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
// We create a dummy RulesetContainer just to get the replay - we don't want to use mods here
|
// We create a dummy RulesetContainer just to get the replay - we don't want to use mods here
|
||||||
// to simulate setting a replay rather than having the replay already set for us
|
// to simulate setting a replay rather than having the replay already set for us
|
||||||
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
||||||
var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(beatmap);
|
var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(Beatmap.Value);
|
||||||
|
|
||||||
// We have the replay
|
// We have the replay
|
||||||
var replay = dummyRulesetContainer.Replay;
|
var replay = dummyRulesetContainer.Replay;
|
||||||
|
|
||||||
// Reset the mods
|
// Reset the mods
|
||||||
beatmap.Mods.Value = beatmap.Mods.Value.Where(m => !(m is ModAutoplay));
|
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay));
|
||||||
|
|
||||||
return new ReplayPlayer(replay)
|
return new ReplayPlayer(replay);
|
||||||
{
|
|
||||||
InitialBeatmap = beatmap
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,18 +32,13 @@ namespace osu.Game.Tests.Visual
|
|||||||
this.beatmaps = beatmaps;
|
this.beatmaps = beatmaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
private WorkingBeatmap beatmap;
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
if (beatmap == null)
|
|
||||||
{
|
|
||||||
var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
|
var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
|
||||||
if (beatmapInfo != null)
|
if (beatmapInfo != null)
|
||||||
beatmap = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
||||||
}
|
|
||||||
|
|
||||||
Add(new Results(new Score
|
Add(new Results(new Score
|
||||||
{
|
{
|
||||||
@ -63,10 +58,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
Username = "peppy",
|
Username = "peppy",
|
||||||
}
|
}
|
||||||
})
|
}));
|
||||||
{
|
|
||||||
InitialBeatmap = beatmap
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,12 +84,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private abstract class TestScreen : OsuScreen
|
private abstract class TestScreen : OsuScreen
|
||||||
{
|
{
|
||||||
protected abstract string Title { get; }
|
|
||||||
protected abstract string NextTitle { get; }
|
protected abstract string NextTitle { get; }
|
||||||
protected abstract TestScreen CreateNextScreen();
|
protected abstract TestScreen CreateNextScreen();
|
||||||
|
|
||||||
public override string ToString() => Title;
|
|
||||||
|
|
||||||
public TestScreen PushNext()
|
public TestScreen PushNext()
|
||||||
{
|
{
|
||||||
TestScreen screen = CreateNextScreen();
|
TestScreen screen = CreateNextScreen();
|
||||||
@ -130,14 +127,14 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private class TestScreenOne : TestScreen
|
private class TestScreenOne : TestScreen
|
||||||
{
|
{
|
||||||
protected override string Title => @"Screen One";
|
public override string Title => @"Screen One";
|
||||||
protected override string NextTitle => @"Two";
|
protected override string NextTitle => @"Two";
|
||||||
protected override TestScreen CreateNextScreen() => new TestScreenTwo();
|
protected override TestScreen CreateNextScreen() => new TestScreenTwo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestScreenTwo : TestScreen
|
private class TestScreenTwo : TestScreen
|
||||||
{
|
{
|
||||||
protected override string Title => @"Screen Two";
|
public override string Title => @"Screen Two";
|
||||||
protected override string NextTitle => @"One";
|
protected override string NextTitle => @"One";
|
||||||
protected override TestScreen CreateNextScreen() => new TestScreenOne();
|
protected override TestScreen CreateNextScreen() => new TestScreenOne();
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
private readonly SettingsOverlay settings;
|
private readonly SettingsOverlay settings;
|
||||||
private readonly DialogOverlay dialogOverlay;
|
private readonly DialogOverlay dialogOverlay;
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
|
|
||||||
|
|
||||||
public TestCaseSettings()
|
public TestCaseSettings()
|
||||||
{
|
{
|
||||||
settings = new MainSettings
|
settings = new MainSettings
|
||||||
@ -33,7 +29,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
dependencies.Cache(dialogOverlay);
|
Dependencies.Cache(dialogOverlay);
|
||||||
|
|
||||||
Add(settings);
|
Add(settings);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -18,8 +17,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseStoryboard : OsuTestCase
|
public class TestCaseStoryboard : OsuTestCase
|
||||||
{
|
{
|
||||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
|
||||||
|
|
||||||
private readonly Container<DrawableStoryboard> storyboardContainer;
|
private readonly Container<DrawableStoryboard> storyboardContainer;
|
||||||
private DrawableStoryboard storyboard;
|
private DrawableStoryboard storyboard;
|
||||||
|
|
||||||
@ -43,6 +40,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Add(new MusicController
|
Add(new MusicController
|
||||||
{
|
{
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
@ -55,10 +53,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase game)
|
private void load()
|
||||||
{
|
{
|
||||||
beatmapBacking.BindTo(game.Beatmap);
|
Beatmap.ValueChanged += beatmapChanged;
|
||||||
beatmapBacking.ValueChanged += beatmapChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void beatmapChanged(WorkingBeatmap working)
|
private void beatmapChanged(WorkingBeatmap working)
|
||||||
@ -66,10 +63,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private void restart()
|
private void restart()
|
||||||
{
|
{
|
||||||
var track = beatmapBacking.Value.Track;
|
var track = Beatmap.Value.Track;
|
||||||
|
|
||||||
track.Reset();
|
track.Reset();
|
||||||
loadStoryboard(beatmapBacking.Value);
|
loadStoryboard(Beatmap);
|
||||||
track.Start();
|
track.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +78,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true };
|
var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true };
|
||||||
storyboardContainer.Clock = decoupledClock;
|
storyboardContainer.Clock = decoupledClock;
|
||||||
|
|
||||||
storyboard = working.Storyboard.CreateDrawable(beatmapBacking);
|
storyboard = working.Storyboard.CreateDrawable(Beatmap);
|
||||||
storyboard.Passing = false;
|
storyboard.Passing = false;
|
||||||
|
|
||||||
storyboardContainer.Add(storyboard);
|
storyboardContainer.Add(storyboard);
|
||||||
|
@ -5,11 +5,9 @@ using NUnit.Framework;
|
|||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Screens.Edit.Screens.Compose.Timeline;
|
using osu.Game.Screens.Edit.Screens.Compose.Timeline;
|
||||||
@ -19,9 +17,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseWaveform : OsuTestCase
|
public class TestCaseWaveform : OsuTestCase
|
||||||
{
|
{
|
||||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
public TestCaseWaveform()
|
|
||||||
{
|
{
|
||||||
FillFlowContainer flow;
|
FillFlowContainer flow;
|
||||||
Child = flow = new FillFlowContainer
|
Child = flow = new FillFlowContainer
|
||||||
@ -46,10 +43,11 @@ namespace osu.Game.Tests.Visual
|
|||||||
var newDisplay = new BeatmapWaveformGraph
|
var newDisplay = new BeatmapWaveformGraph
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Resolution = 1f / i
|
Resolution = 1f / i,
|
||||||
|
Beatmap = Beatmap
|
||||||
};
|
};
|
||||||
|
|
||||||
newDisplay.Beatmap.BindTo(beatmapBacking);
|
Beatmap.ValueChanged += b => newDisplay.Beatmap = b;
|
||||||
|
|
||||||
flow.Add(new Container
|
flow.Add(new Container
|
||||||
{
|
{
|
||||||
@ -83,8 +81,5 @@ namespace osu.Game.Tests.Visual
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuGameBase osuGame) => beatmapBacking.BindTo(osuGame.Beatmap);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||||
</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" />
|
||||||
|
@ -81,7 +81,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
protected override void Populate(BeatmapSetInfo model, ArchiveReader archive)
|
protected override void Populate(BeatmapSetInfo model, ArchiveReader archive)
|
||||||
{
|
{
|
||||||
model.Beatmaps = createBeatmapDifficulties(archive);
|
model.Beatmaps = createBeatmapDifficulties(model, archive);
|
||||||
|
|
||||||
// remove metadata from difficulties where it matches the set
|
// remove metadata from difficulties where it matches the set
|
||||||
foreach (BeatmapInfo b in model.Beatmaps)
|
foreach (BeatmapInfo b in model.Beatmaps)
|
||||||
@ -107,6 +107,7 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
Delete(existingOnlineId);
|
Delete(existingOnlineId);
|
||||||
beatmaps.PurgeDeletable(s => s.ID == existingOnlineId.ID);
|
beatmaps.PurgeDeletable(s => s.ID == existingOnlineId.ID);
|
||||||
|
Logger.Log($"Found existing beatmap set with same OnlineBeatmapSetID ({model.OnlineBeatmapSetID}). It has been purged.", LoggingTarget.Database);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +170,7 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
if (error is OperationCanceledException) return;
|
if (error is OperationCanceledException) return;
|
||||||
|
|
||||||
downloadNotification.State = ProgressNotificationState.Completed;
|
downloadNotification.State = ProgressNotificationState.Cancelled;
|
||||||
Logger.Error(error, "Beatmap download failed!");
|
Logger.Error(error, "Beatmap download failed!");
|
||||||
currentDownloads.Remove(request);
|
currentDownloads.Remove(request);
|
||||||
};
|
};
|
||||||
@ -241,7 +242,13 @@ namespace osu.Game.Beatmaps
|
|||||||
/// Returns a list of all usable <see cref="BeatmapSetInfo"/>s.
|
/// Returns a list of all usable <see cref="BeatmapSetInfo"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A list of available <see cref="BeatmapSetInfo"/>.</returns>
|
/// <returns>A list of available <see cref="BeatmapSetInfo"/>.</returns>
|
||||||
public List<BeatmapSetInfo> GetAllUsableBeatmapSets() => beatmaps.ConsumableItems.Where(s => !s.DeletePending && !s.Protected).ToList();
|
public List<BeatmapSetInfo> GetAllUsableBeatmapSets() => GetAllUsableBeatmapSetsEnumerable().ToList();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a list of all usable <see cref="BeatmapSetInfo"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A list of available <see cref="BeatmapSetInfo"/>.</returns>
|
||||||
|
public IQueryable<BeatmapSetInfo> GetAllUsableBeatmapSetsEnumerable() => beatmaps.ConsumableItems.Where(s => !s.DeletePending && !s.Protected);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform a lookup query on available <see cref="BeatmapSetInfo"/>s.
|
/// Perform a lookup query on available <see cref="BeatmapSetInfo"/>s.
|
||||||
@ -303,7 +310,7 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
// let's make sure there are actually .osu files to import.
|
// let's make sure there are actually .osu files to import.
|
||||||
string mapName = reader.Filenames.FirstOrDefault(f => f.EndsWith(".osu"));
|
string mapName = reader.Filenames.FirstOrDefault(f => f.EndsWith(".osu"));
|
||||||
if (string.IsNullOrEmpty(mapName)) throw new InvalidOperationException("No beatmap files found in the map folder.");
|
if (string.IsNullOrEmpty(mapName)) throw new InvalidOperationException("No beatmap files found in this beatmap archive.");
|
||||||
|
|
||||||
BeatmapMetadata metadata;
|
BeatmapMetadata metadata;
|
||||||
using (var stream = new StreamReader(reader.GetStream(mapName)))
|
using (var stream = new StreamReader(reader.GetStream(mapName)))
|
||||||
@ -321,7 +328,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create all required <see cref="BeatmapInfo"/>s for the provided archive.
|
/// Create all required <see cref="BeatmapInfo"/>s for the provided archive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<BeatmapInfo> createBeatmapDifficulties(ArchiveReader reader)
|
private List<BeatmapInfo> createBeatmapDifficulties(BeatmapSetInfo model, ArchiveReader reader)
|
||||||
{
|
{
|
||||||
var beatmapInfos = new List<BeatmapInfo>();
|
var beatmapInfos = new List<BeatmapInfo>();
|
||||||
|
|
||||||
@ -341,6 +348,14 @@ namespace osu.Game.Beatmaps
|
|||||||
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
|
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
|
||||||
beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();
|
beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();
|
||||||
|
|
||||||
|
// ensure we have the same online set ID as the set itself.
|
||||||
|
beatmap.BeatmapInfo.OnlineBeatmapSetID = model.OnlineBeatmapSetID;
|
||||||
|
beatmap.BeatmapInfo.Metadata.OnlineBeatmapSetID = model.OnlineBeatmapSetID;
|
||||||
|
|
||||||
|
// check that no existing beatmap exists that is imported with the same online beatmap ID. if so, give it precedence.
|
||||||
|
if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue && QueryBeatmap(b => b.OnlineBeatmapID.Value == beatmap.BeatmapInfo.OnlineBeatmapID.Value) != null)
|
||||||
|
beatmap.BeatmapInfo.OnlineBeatmapID = null;
|
||||||
|
|
||||||
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
||||||
|
|
||||||
beatmap.BeatmapInfo.Ruleset = ruleset;
|
beatmap.BeatmapInfo.Ruleset = ruleset;
|
||||||
|
@ -36,6 +36,11 @@ namespace osu.Game.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HasVideo { get; set; }
|
public bool HasVideo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not this beatmap set has a storyboard.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasStoryboard { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The different sizes of cover art for this beatmap set.
|
/// The different sizes of cover art for this beatmap set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
75
osu.Game/Beatmaps/BindableBeatmap.cs
Normal file
75
osu.Game/Beatmaps/BindableBeatmap.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// 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.Diagnostics;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="Bindable{WorkingBeatmap}"/> for the <see cref="OsuGame"/> beatmap.
|
||||||
|
/// This should be used sparingly in-favour of <see cref="IBindableBeatmap"/>.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class BindableBeatmap : NonNullableBindable<WorkingBeatmap>, IBindableBeatmap
|
||||||
|
{
|
||||||
|
private AudioManager audioManager;
|
||||||
|
private WorkingBeatmap lastBeatmap;
|
||||||
|
|
||||||
|
protected BindableBeatmap(WorkingBeatmap defaultValue)
|
||||||
|
: base(defaultValue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers an <see cref="AudioManager"/> for <see cref="Track"/>s to be added to.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="audioManager">The <see cref="AudioManager"/> to register.</param>
|
||||||
|
protected void RegisterAudioManager([NotNull] AudioManager audioManager)
|
||||||
|
{
|
||||||
|
if (this.audioManager != null) throw new InvalidOperationException($"Cannot register multiple {nameof(AudioManager)}s.");
|
||||||
|
|
||||||
|
this.audioManager = audioManager;
|
||||||
|
|
||||||
|
ValueChanged += registerAudioTrack;
|
||||||
|
|
||||||
|
// If the track has changed prior to this being called, let's register it
|
||||||
|
if (Value != Default)
|
||||||
|
registerAudioTrack(Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerAudioTrack(WorkingBeatmap beatmap)
|
||||||
|
{
|
||||||
|
var trackLoaded = lastBeatmap?.TrackLoaded ?? false;
|
||||||
|
|
||||||
|
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
|
||||||
|
if (!trackLoaded || lastBeatmap?.Track != beatmap.Track)
|
||||||
|
{
|
||||||
|
if (trackLoaded)
|
||||||
|
{
|
||||||
|
Debug.Assert(lastBeatmap != null);
|
||||||
|
Debug.Assert(lastBeatmap.Track != null);
|
||||||
|
|
||||||
|
lastBeatmap.RecycleTrack();
|
||||||
|
}
|
||||||
|
|
||||||
|
audioManager.Track.AddItem(beatmap.Track);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastBeatmap = beatmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
[NotNull]
|
||||||
|
IBindableBeatmap IBindableBeatmap.GetBoundCopy() => GetBoundCopy();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve a new <see cref="BindableBeatmap"/> instance weakly bound to this <see cref="BindableBeatmap"/>.
|
||||||
|
/// If you are further binding to events of the retrieved <see cref="BindableBeatmap"/>, ensure a local reference is held.
|
||||||
|
/// </summary>
|
||||||
|
[NotNull]
|
||||||
|
public abstract BindableBeatmap GetBoundCopy();
|
||||||
|
}
|
||||||
|
}
|
84
osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs
Normal file
84
osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// 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;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps.Drawables
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A component to allow downloading of a beatmap set. Automatically handles state syncing between other instances.
|
||||||
|
/// </summary>
|
||||||
|
public class BeatmapSetDownloader : Component
|
||||||
|
{
|
||||||
|
private readonly BeatmapSetInfo set;
|
||||||
|
private readonly bool noVideo;
|
||||||
|
|
||||||
|
private BeatmapManager beatmaps;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the associated beatmap set has been downloading (by this instance or any other instance).
|
||||||
|
/// </summary>
|
||||||
|
public readonly BindableBool Downloaded = new BindableBool();
|
||||||
|
|
||||||
|
public BeatmapSetDownloader(BeatmapSetInfo set, bool noVideo = false)
|
||||||
|
{
|
||||||
|
this.set = set;
|
||||||
|
this.noVideo = noVideo;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(BeatmapManager beatmaps)
|
||||||
|
{
|
||||||
|
this.beatmaps = beatmaps;
|
||||||
|
|
||||||
|
beatmaps.ItemAdded += setAdded;
|
||||||
|
beatmaps.ItemRemoved += setRemoved;
|
||||||
|
|
||||||
|
// initial value
|
||||||
|
if (set.OnlineBeatmapSetID != null)
|
||||||
|
Downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Any();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
if (beatmaps != null)
|
||||||
|
{
|
||||||
|
beatmaps.ItemAdded -= setAdded;
|
||||||
|
beatmaps.ItemRemoved -= setRemoved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Begin downloading the associated beatmap set.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if downloading began. False if an existing download is active or completed.</returns>
|
||||||
|
public bool Download()
|
||||||
|
{
|
||||||
|
if (Downloaded.Value)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (beatmaps.GetExistingDownload(set) != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
beatmaps.Download(set, noVideo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setAdded(BeatmapSetInfo s)
|
||||||
|
{
|
||||||
|
if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID)
|
||||||
|
Downloaded.Value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRemoved(BeatmapSetInfo s)
|
||||||
|
{
|
||||||
|
if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID)
|
||||||
|
Downloaded.Value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
79
osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs
Normal file
79
osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps.Drawables
|
||||||
|
{
|
||||||
|
public class UpdateableBeatmapSetCover : Container
|
||||||
|
{
|
||||||
|
private Drawable displayedCover;
|
||||||
|
|
||||||
|
private BeatmapSetInfo beatmapSet;
|
||||||
|
public BeatmapSetInfo BeatmapSet
|
||||||
|
{
|
||||||
|
get { return beatmapSet; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == beatmapSet) return;
|
||||||
|
beatmapSet = value;
|
||||||
|
|
||||||
|
if (IsLoaded)
|
||||||
|
updateCover();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BeatmapSetCoverType coverType = BeatmapSetCoverType.Cover;
|
||||||
|
public BeatmapSetCoverType CoverType
|
||||||
|
{
|
||||||
|
get { return coverType; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == coverType) return;
|
||||||
|
coverType = value;
|
||||||
|
|
||||||
|
if (IsLoaded)
|
||||||
|
updateCover();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UpdateableBeatmapSetCover()
|
||||||
|
{
|
||||||
|
Child = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
updateCover();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCover()
|
||||||
|
{
|
||||||
|
displayedCover?.FadeOut(400);
|
||||||
|
displayedCover?.Expire();
|
||||||
|
displayedCover = null;
|
||||||
|
|
||||||
|
if (beatmapSet != null)
|
||||||
|
{
|
||||||
|
Add(displayedCover = new DelayedLoadWrapper(
|
||||||
|
new BeatmapSetCover(beatmapSet, coverType)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
FillMode = FillMode.Fill,
|
||||||
|
OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
private readonly OsuGameBase game;
|
private readonly OsuGameBase game;
|
||||||
|
|
||||||
public DummyWorkingBeatmap(OsuGameBase game)
|
public DummyWorkingBeatmap(OsuGameBase game = null)
|
||||||
: base(new BeatmapInfo
|
: base(new BeatmapInfo
|
||||||
{
|
{
|
||||||
Metadata = new BeatmapMetadata
|
Metadata = new BeatmapMetadata
|
||||||
@ -43,7 +43,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
protected override IBeatmap GetBeatmap() => new Beatmap();
|
protected override IBeatmap GetBeatmap() => new Beatmap();
|
||||||
|
|
||||||
protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4");
|
protected override Texture GetBackground() => game?.Textures.Get(@"Backgrounds/bg4");
|
||||||
|
|
||||||
protected override Track GetTrack() => new TrackVirtual();
|
protected override Track GetTrack() => new TrackVirtual();
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ using System.Linq;
|
|||||||
using osu.Game.Beatmaps.Timing;
|
using osu.Game.Beatmaps.Timing;
|
||||||
using osu.Game.Rulesets.Objects.Legacy;
|
using osu.Game.Rulesets.Objects.Legacy;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Framework;
|
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps.Formats
|
namespace osu.Game.Beatmaps.Formats
|
||||||
{
|
{
|
||||||
@ -28,23 +27,17 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
AddDecoder<Beatmap>(@"osu file format v", m => new LegacyBeatmapDecoder(int.Parse(m.Split('v').Last())));
|
AddDecoder<Beatmap>(@"osu file format v", m => new LegacyBeatmapDecoder(int.Parse(m.Split('v').Last())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// lazer's audio timings in general doesn't match stable. this is the result of user testing, albeit limited.
|
|
||||||
/// This only seems to be required on windows. We need to eventually figure out why, with a bit of luck.
|
|
||||||
/// </summary>
|
|
||||||
public static int UniversalOffset => RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? -22 : 0;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not beatmap or runtime offsets should be applied. Defaults on; only disable for testing purposes.
|
/// Whether or not beatmap or runtime offsets should be applied. Defaults on; only disable for testing purposes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ApplyOffsets = true;
|
public bool ApplyOffsets = true;
|
||||||
|
|
||||||
private readonly int offset = UniversalOffset;
|
private readonly int offset;
|
||||||
|
|
||||||
public LegacyBeatmapDecoder(int version = LATEST_VERSION) : base(version)
|
public LegacyBeatmapDecoder(int version = LATEST_VERSION) : base(version)
|
||||||
{
|
{
|
||||||
// BeatmapVersion 4 and lower had an incorrect offset (stable has this set as 24ms off)
|
// BeatmapVersion 4 and lower had an incorrect offset (stable has this set as 24ms off)
|
||||||
offset += FormatVersion < 5 ? 24 : 0;
|
offset = FormatVersion < 5 ? 24 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ParseStreamInto(StreamReader stream, Beatmap beatmap)
|
protected override void ParseStreamInto(StreamReader stream, Beatmap beatmap)
|
||||||
|
19
osu.Game/Beatmaps/IBindableBeatmap.cs
Normal file
19
osu.Game/Beatmaps/IBindableBeatmap.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// 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.Configuration;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Read-only interface for the <see cref="OsuGame"/> beatmap.
|
||||||
|
/// </summary>
|
||||||
|
public interface IBindableBeatmap : IBindable<WorkingBeatmap>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve a new <see cref="IBindableBeatmap"/> instance weakly bound to this <see cref="IBindableBeatmap"/>.
|
||||||
|
/// If you are further binding to events of the retrieved <see cref="IBindableBeatmap"/>, ensure a local reference is held.
|
||||||
|
/// </summary>
|
||||||
|
IBindableBeatmap GetBoundCopy();
|
||||||
|
}
|
||||||
|
}
|
@ -82,6 +82,8 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential);
|
Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential);
|
||||||
|
|
||||||
|
Set(OsuSetting.IncreaseFirstObjectVisibility, true);
|
||||||
|
|
||||||
// Update
|
// Update
|
||||||
Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer);
|
Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer);
|
||||||
|
|
||||||
@ -144,6 +146,7 @@ namespace osu.Game.Configuration
|
|||||||
ScreenshotCaptureMenuCursor,
|
ScreenshotCaptureMenuCursor,
|
||||||
SongSelectRightMouseScroll,
|
SongSelectRightMouseScroll,
|
||||||
BeatmapSkins,
|
BeatmapSkins,
|
||||||
BeatmapHitsounds
|
BeatmapHitsounds,
|
||||||
|
IncreaseFirstObjectVisibility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using osu.Framework.IO.File;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
@ -56,13 +57,49 @@ namespace osu.Game.Database
|
|||||||
// ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised)
|
// ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised)
|
||||||
private ArchiveImportIPCChannel ipc;
|
private ArchiveImportIPCChannel ipc;
|
||||||
|
|
||||||
|
private readonly List<Action> cachedEvents = new List<Action>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allows delaying of outwards events until an operation is confirmed (at a database level).
|
||||||
|
/// </summary>
|
||||||
|
private bool delayingEvents;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Begin delaying outwards events.
|
||||||
|
/// </summary>
|
||||||
|
private void delayEvents() => delayingEvents = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flush delayed events and disable delaying.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="perform">Whether the flushed events should be performed.</param>
|
||||||
|
private void flushEvents(bool perform)
|
||||||
|
{
|
||||||
|
if (perform)
|
||||||
|
{
|
||||||
|
foreach (var a in cachedEvents)
|
||||||
|
a.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedEvents.Clear();
|
||||||
|
delayingEvents = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleEvent(Action a)
|
||||||
|
{
|
||||||
|
if (delayingEvents)
|
||||||
|
cachedEvents.Add(a);
|
||||||
|
else
|
||||||
|
a.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
protected ArchiveModelManager(Storage storage, IDatabaseContextFactory contextFactory, MutableDatabaseBackedStore<TModel> modelStore, IIpcHost importHost = null)
|
protected ArchiveModelManager(Storage storage, IDatabaseContextFactory contextFactory, MutableDatabaseBackedStore<TModel> modelStore, IIpcHost importHost = null)
|
||||||
{
|
{
|
||||||
ContextFactory = contextFactory;
|
ContextFactory = contextFactory;
|
||||||
|
|
||||||
ModelStore = modelStore;
|
ModelStore = modelStore;
|
||||||
ModelStore.ItemAdded += s => ItemAdded?.Invoke(s);
|
ModelStore.ItemAdded += s => handleEvent(() => ItemAdded?.Invoke(s));
|
||||||
ModelStore.ItemRemoved += s => ItemRemoved?.Invoke(s);
|
ModelStore.ItemRemoved += s => handleEvent(() => ItemRemoved?.Invoke(s));
|
||||||
|
|
||||||
Files = new FileStore(contextFactory, storage);
|
Files = new FileStore(contextFactory, storage);
|
||||||
|
|
||||||
@ -138,14 +175,27 @@ namespace osu.Game.Database
|
|||||||
/// <param name="archive">The archive to be imported.</param>
|
/// <param name="archive">The archive to be imported.</param>
|
||||||
public TModel Import(ArchiveReader archive)
|
public TModel Import(ArchiveReader archive)
|
||||||
{
|
{
|
||||||
using (ContextFactory.GetForWrite()) // used to share a context for full import. keep in mind this will block all writes.
|
TModel item = null;
|
||||||
|
delayEvents();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
|
using (var write = ContextFactory.GetForWrite()) // used to share a context for full import. keep in mind this will block all writes.
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!write.IsTransactionLeader) throw new InvalidOperationException($"Ensure there is no parent transaction so errors can correctly be handled by {this}");
|
||||||
|
|
||||||
// create a new model (don't yet add to database)
|
// create a new model (don't yet add to database)
|
||||||
var item = CreateModel(archive);
|
item = CreateModel(archive);
|
||||||
|
|
||||||
var existing = CheckForExisting(item);
|
var existing = CheckForExisting(item);
|
||||||
|
|
||||||
if (existing != null) return existing;
|
if (existing != null)
|
||||||
|
{
|
||||||
|
Logger.Log($"Found existing {typeof(TModel)} for {archive.Name} (ID {existing.ID}). Skipping import.", LoggingTarget.Database);
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
item.Files = createFileInfos(archive, Files);
|
item.Files = createFileInfos(archive, Files);
|
||||||
|
|
||||||
@ -153,10 +203,29 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
// import to store
|
// import to store
|
||||||
ModelStore.Add(item);
|
ModelStore.Add(item);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
write.Errors.Add(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Log($"Import of {archive.Name} successfully completed!", LoggingTarget.Database);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.Error(e, $"Import of {archive.Name} failed and has been rolled back.", LoggingTarget.Database);
|
||||||
|
item = null;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// we only want to flush events after we've confirmed the write context didn't have any errors.
|
||||||
|
flushEvents(item != null);
|
||||||
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Import an item from a <see cref="TModel"/>.
|
/// Import an item from a <see cref="TModel"/>.
|
||||||
@ -178,12 +247,8 @@ namespace osu.Game.Database
|
|||||||
/// <param name="item">The item to delete.</param>
|
/// <param name="item">The item to delete.</param>
|
||||||
public void Delete(TModel item)
|
public void Delete(TModel item)
|
||||||
{
|
{
|
||||||
using (var usage = ContextFactory.GetForWrite())
|
using (ContextFactory.GetForWrite())
|
||||||
{
|
{
|
||||||
var context = usage.Context;
|
|
||||||
|
|
||||||
context.ChangeTracker.AutoDetectChangesEnabled = false;
|
|
||||||
|
|
||||||
// re-fetch the model on the import context.
|
// re-fetch the model on the import context.
|
||||||
var foundModel = queryModel().Include(s => s.Files).ThenInclude(f => f.FileInfo).First(s => s.ID == item.ID);
|
var foundModel = queryModel().Include(s => s.Files).ThenInclude(f => f.FileInfo).First(s => s.ID == item.ID);
|
||||||
|
|
||||||
@ -191,8 +256,6 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
if (ModelStore.Delete(foundModel))
|
if (ModelStore.Delete(foundModel))
|
||||||
Files.Dereference(foundModel.Files.Select(f => f.FileInfo).ToArray());
|
Files.Dereference(foundModel.Files.Select(f => f.FileInfo).ToArray());
|
||||||
|
|
||||||
context.ChangeTracker.AutoDetectChangesEnabled = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +365,7 @@ namespace osu.Game.Database
|
|||||||
using (Stream s = reader.GetStream(file))
|
using (Stream s = reader.GetStream(file))
|
||||||
fileInfos.Add(new TFileModel
|
fileInfos.Add(new TFileModel
|
||||||
{
|
{
|
||||||
Filename = file,
|
Filename = FileSafety.PathSanitise(file),
|
||||||
FileInfo = files.Add(s)
|
FileInfo = files.Add(s)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user