mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 06:12:56 +08:00
Merge branch 'master' into diffcalc-modtypes
This commit is contained in:
commit
aaa65c428f
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -1,6 +1,3 @@
|
||||
[submodule "osu-framework"]
|
||||
path = osu-framework
|
||||
url = https://github.com/ppy/osu-framework
|
||||
[submodule "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">
|
||||
<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="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
|
||||
<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_MONO" value="0" />
|
||||
<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_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" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method />
|
||||
</configuration>
|
||||
|
@ -1,21 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<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="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
|
||||
<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_MONO" value="0" />
|
||||
<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_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" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method />
|
||||
</configuration>
|
||||
|
@ -1,21 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<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="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
|
||||
<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_MONO" value="0" />
|
||||
<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_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" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method />
|
||||
</configuration>
|
||||
|
@ -1,21 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<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="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
|
||||
<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_MONO" value="0" />
|
||||
<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_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" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method />
|
||||
</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">
|
||||
<configuration default="false" name="VisualTests (netcoreapp2.0)" type="DotNetProject" factoryName=".NET Project">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.0/osu.Game.Tests.dll" />
|
||||
<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.1/osu.Game.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
@ -12,7 +12,7 @@
|
||||
<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=".NETCoreApp,Version=v2.0" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<method />
|
||||
</configuration>
|
||||
</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">
|
||||
<configuration default="false" name="osu! (netcoreapp2.0)" type="DotNetProject" factoryName=".NET Project">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.0/osu!.dll" />
|
||||
<configuration default="false" name="osu! (netcoreapp2.1)" type="DotNetProject" factoryName=".NET Project">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
@ -12,7 +12,7 @@
|
||||
<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=".NETCoreApp,Version=v2.0" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
80
.vscode/launch.json
vendored
80
.vscode/launch.json
vendored
@ -2,110 +2,54 @@
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "VisualTests (Debug, net471)",
|
||||
"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/Release/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)",
|
||||
"name": "VisualTests (Debug)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"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}",
|
||||
"preLaunchTask": "Build tests (Debug, dotnet)",
|
||||
"preLaunchTask": "Build tests (Debug)",
|
||||
"env": {},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
||||
"name": "VisualTests (Release)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.0/osu.Game.Tests.dll"
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1/osu.Game.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tests (Release, dotnet)",
|
||||
"preLaunchTask": "Build tests (Release)",
|
||||
"env": {},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "osu! (Debug, netcoreapp2.0)",
|
||||
"name": "osu! (Debug)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.0/osu!.dll",
|
||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll",
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build osu! (Debug, dotnet)",
|
||||
"preLaunchTask": "Build osu! (Debug)",
|
||||
"env": {},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "osu! (Release, netcoreapp2.0)",
|
||||
"name": "osu! (Release)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.0/osu!.dll",
|
||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll",
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build osu! (Release, dotnet)",
|
||||
"preLaunchTask": "Build osu! (Release)",
|
||||
"env": {},
|
||||
"console": "internalConsole"
|
||||
}
|
||||
|
54
.vscode/tasks.json
vendored
54
.vscode/tasks.json
vendored
@ -4,41 +4,14 @@
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Build (Debug, msbuild)",
|
||||
"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 osu! (Debug, dotnet)",
|
||||
"label": "Build osu! (Debug)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Desktop",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -47,14 +20,14 @@
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Build osu! (Release, dotnet)",
|
||||
"label": "Build osu! (Release)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Desktop",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -64,14 +37,14 @@
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Build tests (Debug, dotnet)",
|
||||
"label": "Build tests (Debug)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Tests",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -80,14 +53,14 @@
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Build tests (Release, dotnet)",
|
||||
"label": "Build tests (Release)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Tests",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -97,16 +70,7 @@
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Restore (net471)",
|
||||
"type": "shell",
|
||||
"command": "nuget",
|
||||
"args": [
|
||||
"restore"
|
||||
],
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.0)",
|
||||
"label": "Restore (netcoreapp2.1)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
|
@ -2,11 +2,6 @@ clone_depth: 1
|
||||
version: '{branch}-{build}'
|
||||
image: Visual Studio 2017
|
||||
configuration: Debug
|
||||
cache:
|
||||
- C:\ProgramData\chocolatey\bin -> appveyor.yml
|
||||
- C:\ProgramData\chocolatey\lib -> appveyor.yml
|
||||
- inspectcode -> appveyor.yml
|
||||
- packages -> **\packages.config
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive --depth=5
|
||||
- cmd: choco install resharper-clt -y
|
||||
|
@ -1,29 +1,24 @@
|
||||
branches:
|
||||
only:
|
||||
- release
|
||||
skip_tags: true
|
||||
skip_branch_with_pr: true
|
||||
clone_depth: 1
|
||||
version: '{branch}-{build}'
|
||||
version: '{build}'
|
||||
skip_non_tags: true
|
||||
image: Visual Studio 2017
|
||||
configuration: Debug
|
||||
cache:
|
||||
- packages -> **\packages.config
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive --depth=5
|
||||
- git clone https://github.com/ppy/osu-deploy
|
||||
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
|
||||
build:
|
||||
project: osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
build_script:
|
||||
- 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
|
||||
- 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
|
||||
- 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.Desktop.Deploy\bin\Debug\net471\
|
||||
- osu.Desktop.Deploy.exe %code_signing_password%
|
||||
- cd osu-deploy
|
||||
- nuget restore -verbosity quiet
|
||||
- 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:
|
||||
TargetFramework: net471
|
||||
decode_secret:
|
||||
@ -31,4 +26,7 @@ environment:
|
||||
code_signing_password:
|
||||
secure: 34tLNqvjmmZEi97MLKfrnQ==
|
||||
artifacts:
|
||||
- path: 'Releases\*'
|
||||
- path: 'Releases\*'
|
||||
deploy:
|
||||
- provider: Environment
|
||||
name: github
|
@ -1 +0,0 @@
|
||||
Subproject commit 804a4b81b89cb4569af5221e6fa2296d559c28fb
|
@ -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>
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
@ -14,6 +13,7 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Utils;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
@ -118,7 +118,7 @@ namespace osu.Desktop.Overlays
|
||||
Icon = FontAwesome.fa_check_square;
|
||||
Activated = delegate
|
||||
{
|
||||
Process.Start($"https://github.com/ppy/osu/releases/tag/v{version}");
|
||||
Process.Start($"https://osu.ppy.sh/home/changelog/{version}");
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\osu.Game.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<TargetFrameworks>net471;netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net471;netcoreapp2.1</TargetFrameworks>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
@ -20,26 +20,19 @@
|
||||
<StartupObject>osu.Desktop.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<!-- This can be removed after .NET Core SDK version 2.1.300; see https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet -->
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.3" />
|
||||
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj" />
|
||||
<ProjectReference Include="..\osu.Game\osu.Game.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.Mania\osu.Game.Rulesets.Mania.csproj" />
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.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 Label="Package References">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0" />
|
||||
<PackageReference Include="squirrel.windows" Version="1.8.0" Condition="'$(TargetFramework)' == 'net471'" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Resources">
|
||||
<EmbeddedResource Include="lazer.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- This can be removed after .NET Core SDK version 2.1.300; see https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet -->
|
||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"type": "mono",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Release, msbuild)",
|
||||
"runtimeExecutable": null,
|
||||
@ -30,12 +30,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
||||
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Debug, dotnet)",
|
||||
@ -43,12 +43,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
||||
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Release, dotnet)",
|
||||
|
@ -40,7 +40,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Catch.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -56,7 +56,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Catch.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -75,7 +75,7 @@
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.0)",
|
||||
"label": "Restore (netcoreapp2.1)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
|
@ -53,10 +53,10 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
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() });
|
||||
return base.CreatePlayer(beatmap, ruleset);
|
||||
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
||||
return base.CreatePlayer(ruleset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"type": "mono",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Release, msbuild)",
|
||||
"runtimeExecutable": null,
|
||||
@ -30,12 +30,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
||||
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Debug, dotnet)",
|
||||
@ -43,12 +43,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
||||
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Release, dotnet)",
|
||||
|
@ -40,7 +40,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Mania.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -56,7 +56,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Mania.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -75,7 +75,7 @@
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.0)",
|
||||
"label": "Restore (netcoreapp2.1)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"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]
|
||||
private void load(RulesetStore rulesets, SettingsStore settings)
|
||||
{
|
||||
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)
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
||||
|
@ -5,6 +5,7 @@ using OpenTK;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
{
|
||||
@ -28,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
: base(barLine)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 1;
|
||||
Height = 2f;
|
||||
|
||||
AddInternal(new Box
|
||||
{
|
||||
@ -36,6 +37,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = new Color4(255, 204, 33, 255),
|
||||
});
|
||||
|
||||
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
|
||||
|
||||
using System.Linq;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using OpenTK.Graphics;
|
||||
@ -23,9 +23,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
private readonly DrawableNote head;
|
||||
private readonly DrawableNote tail;
|
||||
|
||||
private readonly GlowPiece glowPiece;
|
||||
private readonly BodyPiece bodyPiece;
|
||||
private readonly Container fullHeightContainer;
|
||||
|
||||
/// <summary>
|
||||
/// Time at which the user started holding this hold note. Null if the user is not holding this hold note.
|
||||
@ -37,25 +35,17 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
/// </summary>
|
||||
private bool hasBroken;
|
||||
|
||||
private readonly Container<DrawableHoldNoteTick> tickContainer;
|
||||
|
||||
public DrawableHoldNote(HoldNote hitObject, ManiaAction action)
|
||||
: base(hitObject, action)
|
||||
{
|
||||
Container<DrawableHoldNoteTick> tickContainer;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
||||
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
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
},
|
||||
tickContainer = new Container<DrawableHoldNoteTick>
|
||||
@ -92,21 +82,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
{
|
||||
base.AccentColour = value;
|
||||
|
||||
glowPiece.AccentColour = value;
|
||||
bodyPiece.AccentColour = value;
|
||||
head.AccentColour = value;
|
||||
tail.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;
|
||||
tickContainer.ForEach(t => t.AccentColour = value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,12 +100,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
base.Update();
|
||||
|
||||
// Make the body piece not lie under the head note
|
||||
bodyPiece.Y = head.Height;
|
||||
bodyPiece.Height = DrawHeight - head.Height;
|
||||
|
||||
// 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;
|
||||
bodyPiece.Y = head.Height / 2;
|
||||
bodyPiece.Height = DrawHeight - head.Height / 2 + tail.Height / 2;
|
||||
}
|
||||
|
||||
public bool OnPressed(ManiaAction action)
|
||||
@ -175,8 +150,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
: base(holdNote.HitObject.Head, action)
|
||||
{
|
||||
this.holdNote = holdNote;
|
||||
|
||||
GlowPiece.Alpha = 0;
|
||||
}
|
||||
|
||||
public override bool OnPressed(ManiaAction action)
|
||||
@ -194,11 +167,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
// The holdnote keeps scrolling through for now, so having the head disappear looks weird
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -219,8 +187,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
: base(holdNote.HitObject.Tail, action)
|
||||
{
|
||||
this.holdNote = holdNote;
|
||||
|
||||
GlowPiece.Alpha = 0;
|
||||
}
|
||||
|
||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||
@ -253,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 OnReleased(ManiaAction action)
|
||||
|
@ -8,7 +8,6 @@ using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
@ -87,16 +86,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
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()
|
||||
{
|
||||
if (AllJudged)
|
||||
|
@ -27,5 +27,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
if (action != null)
|
||||
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>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
@ -16,9 +17,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
/// </summary>
|
||||
public class DrawableNote : DrawableManiaHitObject<Note>, IKeyBindingHandler<ManiaAction>
|
||||
{
|
||||
protected readonly GlowPiece GlowPiece;
|
||||
|
||||
private readonly LaneGlowPiece laneGlowPiece;
|
||||
private readonly NotePiece headPiece;
|
||||
|
||||
public DrawableNote(Note hitObject, ManiaAction action)
|
||||
@ -27,14 +25,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
CornerRadius = 5;
|
||||
Masking = true;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
laneGlowPiece = new LaneGlowPiece
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
},
|
||||
GlowPiece = new GlowPiece(),
|
||||
headPiece = new NotePiece
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
@ -49,9 +44,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
set
|
||||
{
|
||||
base.AccentColour = value;
|
||||
laneGlowPiece.AccentColour = AccentColour;
|
||||
GlowPiece.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 });
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (action != Action)
|
||||
|
@ -123,8 +123,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
if (!IsLoaded)
|
||||
return;
|
||||
|
||||
foreground.Colour = AccentColour.Opacity(0.4f);
|
||||
background.Colour = AccentColour.Opacity(0.2f);
|
||||
foreground.Colour = AccentColour.Opacity(0.9f);
|
||||
background.Colour = AccentColour.Opacity(0.6f);
|
||||
|
||||
subtractionCache.Invalidate();
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
/// </summary>
|
||||
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 readonly Box colouredBox;
|
||||
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
public NotePiece()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = head_height;
|
||||
Height = NOTE_HEIGHT;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
|
@ -33,6 +33,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
public ManiaAction Action;
|
||||
|
||||
private readonly Box background;
|
||||
private readonly Box backgroundOverlay;
|
||||
private readonly Container hitTargetBar;
|
||||
private readonly Container keyIcon;
|
||||
|
||||
@ -42,22 +43,32 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
protected override Container<Drawable> Content => content;
|
||||
private readonly Container<Drawable> content;
|
||||
|
||||
private const float opacity_released = 0.1f;
|
||||
private const float opacity_pressed = 0.25f;
|
||||
|
||||
public Column()
|
||||
: base(ScrollingDirection.Up)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Width = column_width;
|
||||
|
||||
Masking = true;
|
||||
CornerRadius = 5;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
background = new Box
|
||||
{
|
||||
Name = "Background",
|
||||
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
|
||||
{
|
||||
@ -182,6 +193,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
accentColour = value;
|
||||
|
||||
background.Colour = accentColour;
|
||||
backgroundOverlay.Colour = ColourInfo.GradientVertical(accentColour.Opacity(0.6f), accentColour.Opacity(0));
|
||||
|
||||
hitTargetBar.EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
@ -223,8 +235,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
if (action == Action)
|
||||
{
|
||||
background.FadeTo(opacity_pressed, 50, Easing.OutQuint);
|
||||
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint);
|
||||
backgroundOverlay.FadeTo(1, 50, Easing.OutQuint).Then().FadeTo(0.5f, 250, Easing.OutQuint);
|
||||
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint).Then().ScaleTo(1.3f, 250, Easing.OutQuint);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -234,8 +246,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
if (action == Action)
|
||||
{
|
||||
background.FadeTo(opacity_released, 800, Easing.OutQuart);
|
||||
keyIcon.ScaleTo(1f, 400, Easing.OutQuart);
|
||||
backgroundOverlay.FadeTo(0, 250, Easing.OutQuint);
|
||||
keyIcon.ScaleTo(1f, 125, Easing.OutQuint);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1,19 +1,21 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
internal class HitExplosion : CompositeDrawable
|
||||
{
|
||||
private readonly Box inner;
|
||||
private readonly CircularContainer circle;
|
||||
|
||||
public HitExplosion(DrawableHitObject judgedObject)
|
||||
{
|
||||
@ -22,33 +24,32 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
Anchor = Anchor.TopCentre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Size = new Vector2(isTick ? 0.5f : 1);
|
||||
FillMode = FillMode.Fit;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Y = NotePiece.NOTE_HEIGHT / 2;
|
||||
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 = new CircularContainer
|
||||
InternalChild = circle = new CircularContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
BorderThickness = 1,
|
||||
BorderColour = accent,
|
||||
// we want our size to be very small so the glow dominates it.
|
||||
Size = new Vector2(0.1f),
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Colour = accent,
|
||||
Radius = 10,
|
||||
Hollow = true
|
||||
Colour = Interpolation.ValueAt(0.1f, judgedObject.AccentColour, Color4.White, 0, 1),
|
||||
Radius = 100,
|
||||
},
|
||||
Child = inner = new Box
|
||||
Child = new Box
|
||||
{
|
||||
Alpha = 0,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = accent,
|
||||
Alpha = 1,
|
||||
AlwaysPresent = true,
|
||||
AlwaysPresent = true
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -57,8 +58,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
this.ScaleTo(2f, 600, Easing.OutQuint).FadeOut(500);
|
||||
inner.FadeOut(250);
|
||||
circle.ResizeTo(circle.Size * new Vector2(4, 20), 1000, Easing.OutQuint);
|
||||
this.FadeIn(16).Then().FadeOut(500, Easing.OutQuint);
|
||||
|
||||
Expire(true);
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
@ -78,6 +77,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Masking = true,
|
||||
CornerRadius = 5,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
@ -183,15 +183,15 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
private void load()
|
||||
{
|
||||
normalColumnColours = new List<Color4>
|
||||
{
|
||||
colours.RedDark,
|
||||
colours.GreenDark
|
||||
new Color4(94, 0, 57, 255),
|
||||
new Color4(6, 84, 0, 255)
|
||||
};
|
||||
|
||||
specialColumnColour = colours.BlueDark;
|
||||
specialColumnColour = new Color4(0, 48, 63, 255);
|
||||
|
||||
// Set the special column + colour + key
|
||||
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",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Release, msbuild)",
|
||||
"runtimeExecutable": null,
|
||||
@ -30,12 +30,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
||||
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Debug, dotnet)",
|
||||
@ -43,12 +43,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
||||
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Release, dotnet)",
|
||||
|
@ -40,7 +40,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Osu.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -56,7 +56,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Osu.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -75,7 +75,7 @@
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.0)",
|
||||
"label": "Restore (netcoreapp2.1)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||
|
@ -7,33 +7,34 @@ using System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
|
||||
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 double ScoreMultiplier => 1.06;
|
||||
|
||||
private const double fade_in_duration_multiplier = 0.4;
|
||||
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>())
|
||||
{
|
||||
d.ApplyCustomUpdateState += ApplyHiddenState;
|
||||
|
||||
d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier;
|
||||
adjustFadeIn(d.HitObject);
|
||||
foreach (var h in d.HitObject.NestedHitObjects.OfType<OsuHitObject>())
|
||||
h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier;
|
||||
adjustFadeIn(h);
|
||||
}
|
||||
|
||||
base.ApplyToDrawableHitObjects(drawables);
|
||||
}
|
||||
|
||||
protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
|
||||
protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
|
||||
{
|
||||
if (!(drawable is DrawableOsuHitObject d))
|
||||
return;
|
||||
|
@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
|
||||
private Bindable<double> cursorScale;
|
||||
private Bindable<bool> autoCursorScale;
|
||||
private Bindable<WorkingBeatmap> beatmap;
|
||||
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
public OsuCursor()
|
||||
{
|
||||
@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager config, OsuGameBase game)
|
||||
private void load(OsuConfigManager config, IBindableBeatmap beatmap)
|
||||
{
|
||||
Child = cursorContainer = new SkinnableDrawable("cursor", _ => new CircularContainer
|
||||
{
|
||||
@ -160,7 +160,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
};
|
||||
|
||||
beatmap = game.Beatmap.GetBoundCopy();
|
||||
this.beatmap.BindTo(beatmap);
|
||||
beatmap.ValueChanged += v => calculateScale();
|
||||
|
||||
cursorScale = config.GetBindable<double>(OsuSetting.GameplayCursorSize);
|
||||
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"type": "mono",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Release, msbuild)",
|
||||
"runtimeExecutable": null,
|
||||
@ -30,12 +30,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
||||
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Debug, dotnet)",
|
||||
@ -43,12 +43,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
||||
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"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}",
|
||||
"preLaunchTask": "Build (Release, dotnet)",
|
||||
|
@ -40,7 +40,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Taiko.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -56,7 +56,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Taiko.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -75,7 +75,7 @@
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.0)",
|
||||
"label": "Restore (netcoreapp2.1)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
|
||||
|
@ -264,7 +264,8 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
|
||||
private string createTemporaryBeatmap()
|
||||
{
|
||||
var temp = new FileInfo(osz_path).CopyTo(Path.GetTempFileName(), true).FullName;
|
||||
var temp = Path.GetTempFileName() + ".osz";
|
||||
File.Copy(osz_path, temp, true);
|
||||
Assert.IsTrue(File.Exists(temp));
|
||||
return temp;
|
||||
}
|
||||
@ -344,12 +345,12 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
|
||||
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
|
||||
{
|
||||
Action waitAction = () =>
|
||||
Task task = Task.Run(() =>
|
||||
{
|
||||
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("Deif", meta.AuthorString);
|
||||
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("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags);
|
||||
Assert.AreEqual("Renatus", meta.Title);
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
@ -13,12 +12,11 @@ namespace osu.Game.Tests.Visual
|
||||
[Description("Player instantiated with an autoplay mod.")]
|
||||
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 new ScoreAccessiblePlayer
|
||||
{
|
||||
InitialBeatmap = beatmap,
|
||||
AllowPause = false,
|
||||
AllowLeadIn = false,
|
||||
AllowResults = false,
|
||||
|
@ -65,11 +65,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
carousel.SelectionChanged = s => currentSelection = s;
|
||||
|
||||
AddStep("Load Beatmaps", () => { carousel.BeatmapSets = beatmapSets; });
|
||||
|
||||
bool changed = false;
|
||||
carousel.BeatmapSetsChanged = () => changed = true;
|
||||
AddUntilStep(() => changed, "Wait for load");
|
||||
loadBeatmaps(beatmapSets);
|
||||
|
||||
testTraversal();
|
||||
testFiltering();
|
||||
@ -84,6 +80,17 @@ namespace osu.Game.Tests.Visual
|
||||
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() =>
|
||||
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++)
|
||||
beatmapSets.Add(createTestBeatmapSet(i));
|
||||
|
||||
AddStep("Load 50 Beatmaps", () => { carousel.BeatmapSets = beatmapSets; });
|
||||
loadBeatmaps(beatmapSets);
|
||||
advanceSelection(direction: 1, diff: false);
|
||||
checkNonmatchingFilter();
|
||||
checkNonmatchingFilter();
|
||||
|
@ -6,7 +6,6 @@ using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
@ -29,14 +28,11 @@ namespace osu.Game.Tests.Visual
|
||||
private RulesetStore rulesets;
|
||||
private TestBeatmapInfoWedge infoWedge;
|
||||
private readonly List<IBeatmap> beatmaps = new List<IBeatmap>();
|
||||
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game, RulesetStore rulesets)
|
||||
private void load(RulesetStore rulesets)
|
||||
{
|
||||
this.rulesets = rulesets;
|
||||
|
||||
beatmap.BindTo(game.Beatmap);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
@ -53,11 +49,11 @@ namespace osu.Game.Tests.Visual
|
||||
AddStep("show", () =>
|
||||
{
|
||||
infoWedge.State = Visibility.Visible;
|
||||
infoWedge.UpdateBeatmap(beatmap);
|
||||
infoWedge.Beatmap = Beatmap;
|
||||
});
|
||||
|
||||
// select part is redundant, but wait for load isn't
|
||||
selectBeatmap(beatmap.Value.Beatmap);
|
||||
selectBeatmap(Beatmap.Value.Beatmap);
|
||||
|
||||
AddWaitStep(3);
|
||||
|
||||
@ -120,8 +116,8 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
selectNullBeatmap();
|
||||
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 artist", () => infoWedge.Info.ArtistLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Artist);
|
||||
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 empty author", () => !infoWedge.Info.MapperContainer.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", () =>
|
||||
{
|
||||
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");
|
||||
@ -143,8 +139,8 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
AddStep("select null beatmap", () =>
|
||||
{
|
||||
beatmap.Value = beatmap.Default;
|
||||
infoWedge.UpdateBeatmap(beatmap);
|
||||
Beatmap.Value = Beatmap.Default;
|
||||
infoWedge.Beatmap = Beatmap;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,6 @@ namespace osu.Game.Tests.Visual
|
||||
typeof(MessageFormatter)
|
||||
};
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
|
||||
|
||||
public TestCaseChatLink()
|
||||
{
|
||||
Add(textContainer = new TestChatLineContainer
|
||||
@ -53,7 +50,7 @@ namespace osu.Game.Tests.Visual
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
linkColour = colours.Blue;
|
||||
dependencies.Cache(new ChatOverlay
|
||||
Dependencies.Cache(new ChatOverlay
|
||||
{
|
||||
AvailableChannels =
|
||||
{
|
||||
|
@ -17,14 +17,10 @@ namespace osu.Game.Tests.Visual
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(Compose) };
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase osuGame)
|
||||
private void load()
|
||||
{
|
||||
osuGame.Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||
|
||||
var compose = new Compose();
|
||||
compose.Beatmap.BindTo(osuGame.Beatmap);
|
||||
|
||||
Child = compose;
|
||||
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||
Child = new Compose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
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) };
|
||||
|
||||
private readonly ScrollableTimeline timeline;
|
||||
|
||||
public TestCaseEditorComposeTimeline()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
@ -30,7 +27,7 @@ namespace osu.Game.Tests.Visual
|
||||
Origin = Anchor.TopCentre,
|
||||
State = Visibility.Visible
|
||||
},
|
||||
timeline = new ScrollableTimeline
|
||||
new ScrollableTimeline
|
||||
{
|
||||
Anchor = 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]
|
||||
private void load(OsuGameBase osuGame)
|
||||
private void load()
|
||||
{
|
||||
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 };
|
||||
|
||||
|
@ -19,19 +19,16 @@ namespace osu.Game.Tests.Visual
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(SummaryTimeline) };
|
||||
|
||||
[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(summaryTimeline = new SummaryTimeline
|
||||
Add(new SummaryTimeline
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(500, 50)
|
||||
});
|
||||
|
||||
summaryTimeline.Beatmap.BindTo(osuGame.Beatmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,15 +32,10 @@ namespace osu.Game.Tests.Visual
|
||||
typeof(NotNullAttribute)
|
||||
};
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> dependencies = new DependencyContainer(parent);
|
||||
|
||||
[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>
|
||||
{
|
||||
@ -63,8 +58,8 @@ namespace osu.Game.Tests.Visual
|
||||
});
|
||||
|
||||
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
||||
dependencies.CacheAs<IAdjustableClock>(clock);
|
||||
dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||
Dependencies.CacheAs<IAdjustableClock>(clock);
|
||||
Dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,12 +2,9 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
@ -15,8 +12,6 @@ namespace osu.Game.Tests.Visual
|
||||
[TestFixture]
|
||||
public class TestCaseMusicController : OsuTestCase
|
||||
{
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
|
||||
public TestCaseMusicController()
|
||||
{
|
||||
Clock = new FramedClock();
|
||||
@ -30,13 +25,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
AddToggleStep(@"toggle visibility", state => mc.State = state ? Visibility.Visible : Visibility.Hidden);
|
||||
AddStep(@"show", () => mc.State = Visibility.Visible);
|
||||
AddToggleStep(@"toggle beatmap lock", state => beatmapBacking.Disabled = state);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game)
|
||||
{
|
||||
beatmapBacking.BindTo(game.Beatmap);
|
||||
AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
private RulesetStore rulesets;
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
private WorkingBeatmap defaultBeatmap;
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
@ -48,8 +47,6 @@ namespace osu.Game.Tests.Visual
|
||||
typeof(DrawableCarouselBeatmapSet),
|
||||
};
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
|
||||
|
||||
private class TestSongSelect : PlaySongSelect
|
||||
{
|
||||
public WorkingBeatmap CurrentBeatmap => Beatmap.Value;
|
||||
@ -58,7 +55,7 @@ namespace osu.Game.Tests.Visual
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game)
|
||||
private void load()
|
||||
{
|
||||
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.
|
||||
IDatabaseContextFactory factory = new SingletonContextFactory(new OsuDbContext());
|
||||
|
||||
dependencies.Cache(rulesets = new RulesetStore(factory));
|
||||
dependencies.Cache(manager = new BeatmapManager(storage, factory, rulesets, null, null)
|
||||
Dependencies.Cache(rulesets = new RulesetStore(factory));
|
||||
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", () =>
|
||||
@ -78,7 +75,7 @@ namespace osu.Game.Tests.Visual
|
||||
if (deleteMaps)
|
||||
{
|
||||
manager.Delete(manager.GetAllUsableBeatmapSets());
|
||||
game.Beatmap.SetDefault();
|
||||
Beatmap.SetDefault();
|
||||
}
|
||||
|
||||
if (songSelect != null)
|
||||
|
@ -15,17 +15,12 @@ namespace osu.Game.Tests.Visual
|
||||
[TestFixture]
|
||||
public class TestCasePlaybackControl : OsuTestCase
|
||||
{
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> dependencies = new DependencyContainer(parent);
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
||||
dependencies.CacheAs<IAdjustableClock>(clock);
|
||||
dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||
Dependencies.CacheAs<IAdjustableClock>(clock);
|
||||
Dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||
|
||||
var playback = new PlaybackControl
|
||||
{
|
||||
@ -34,7 +29,7 @@ namespace osu.Game.Tests.Visual
|
||||
Size = new Vector2(200,100)
|
||||
};
|
||||
|
||||
playback.Beatmap.Value = new TestWorkingBeatmap(new Beatmap());
|
||||
Beatmap.Value = new TestWorkingBeatmap(new Beatmap());
|
||||
|
||||
Child = playback;
|
||||
}
|
||||
|
@ -12,9 +12,10 @@ namespace osu.Game.Tests.Visual
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game)
|
||||
{
|
||||
Beatmap.Value = new DummyWorkingBeatmap(game);
|
||||
|
||||
AddStep("load dummy beatmap", () => Add(new PlayerLoader(new Player
|
||||
{
|
||||
InitialBeatmap = new DummyWorkingBeatmap(game),
|
||||
AllowPause = false,
|
||||
AllowLeadIn = false,
|
||||
AllowResults = false,
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Play;
|
||||
@ -13,23 +12,20 @@ namespace osu.Game.Tests.Visual
|
||||
[Description("Player instantiated with a replay.")]
|
||||
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
|
||||
// to simulate setting a replay rather than having the replay already set for us
|
||||
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
||||
var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(beatmap);
|
||||
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
||||
var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(Beatmap.Value);
|
||||
|
||||
// We have the replay
|
||||
var replay = dummyRulesetContainer.Replay;
|
||||
|
||||
// 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)
|
||||
{
|
||||
InitialBeatmap = beatmap
|
||||
};
|
||||
return new ReplayPlayer(replay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,18 +32,13 @@ namespace osu.Game.Tests.Visual
|
||||
this.beatmaps = beatmaps;
|
||||
}
|
||||
|
||||
private WorkingBeatmap beatmap;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
if (beatmap == null)
|
||||
{
|
||||
var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
|
||||
if (beatmapInfo != null)
|
||||
beatmap = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
||||
}
|
||||
var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
|
||||
if (beatmapInfo != null)
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
||||
|
||||
Add(new Results(new Score
|
||||
{
|
||||
@ -63,10 +58,7 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
Username = "peppy",
|
||||
}
|
||||
})
|
||||
{
|
||||
InitialBeatmap = beatmap
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,6 @@ namespace osu.Game.Tests.Visual
|
||||
private readonly SettingsOverlay settings;
|
||||
private readonly DialogOverlay dialogOverlay;
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
|
||||
|
||||
public TestCaseSettings()
|
||||
{
|
||||
settings = new MainSettings
|
||||
@ -33,7 +29,7 @@ namespace osu.Game.Tests.Visual
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
dependencies.Cache(dialogOverlay);
|
||||
Dependencies.Cache(dialogOverlay);
|
||||
|
||||
Add(settings);
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@ -18,8 +17,6 @@ namespace osu.Game.Tests.Visual
|
||||
[TestFixture]
|
||||
public class TestCaseStoryboard : OsuTestCase
|
||||
{
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private readonly Container<DrawableStoryboard> storyboardContainer;
|
||||
private DrawableStoryboard storyboard;
|
||||
|
||||
@ -43,6 +40,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Add(new MusicController
|
||||
{
|
||||
Origin = Anchor.TopRight,
|
||||
@ -55,10 +53,9 @@ namespace osu.Game.Tests.Visual
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game)
|
||||
private void load()
|
||||
{
|
||||
beatmapBacking.BindTo(game.Beatmap);
|
||||
beatmapBacking.ValueChanged += beatmapChanged;
|
||||
Beatmap.ValueChanged += beatmapChanged;
|
||||
}
|
||||
|
||||
private void beatmapChanged(WorkingBeatmap working)
|
||||
@ -66,10 +63,10 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
private void restart()
|
||||
{
|
||||
var track = beatmapBacking.Value.Track;
|
||||
var track = Beatmap.Value.Track;
|
||||
|
||||
track.Reset();
|
||||
loadStoryboard(beatmapBacking.Value);
|
||||
loadStoryboard(Beatmap);
|
||||
track.Start();
|
||||
}
|
||||
|
||||
@ -81,7 +78,7 @@ namespace osu.Game.Tests.Visual
|
||||
var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true };
|
||||
storyboardContainer.Clock = decoupledClock;
|
||||
|
||||
storyboard = working.Storyboard.CreateDrawable(beatmapBacking);
|
||||
storyboard = working.Storyboard.CreateDrawable(Beatmap);
|
||||
storyboard.Passing = false;
|
||||
|
||||
storyboardContainer.Add(storyboard);
|
||||
|
@ -5,11 +5,9 @@ using NUnit.Framework;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Screens.Edit.Screens.Compose.Timeline;
|
||||
@ -19,9 +17,8 @@ namespace osu.Game.Tests.Visual
|
||||
[TestFixture]
|
||||
public class TestCaseWaveform : OsuTestCase
|
||||
{
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
|
||||
public TestCaseWaveform()
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
FillFlowContainer flow;
|
||||
Child = flow = new FillFlowContainer
|
||||
@ -46,10 +43,11 @@ namespace osu.Game.Tests.Visual
|
||||
var newDisplay = new BeatmapWaveformGraph
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -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" />
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||
|
@ -170,7 +170,7 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
if (error is OperationCanceledException) return;
|
||||
|
||||
downloadNotification.State = ProgressNotificationState.Completed;
|
||||
downloadNotification.State = ProgressNotificationState.Cancelled;
|
||||
Logger.Error(error, "Beatmap download failed!");
|
||||
currentDownloads.Remove(request);
|
||||
};
|
||||
|
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
private readonly OsuGameBase game;
|
||||
|
||||
public DummyWorkingBeatmap(OsuGameBase game)
|
||||
public DummyWorkingBeatmap(OsuGameBase game = null)
|
||||
: base(new BeatmapInfo
|
||||
{
|
||||
Metadata = new BeatmapMetadata
|
||||
@ -43,7 +43,7 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
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();
|
||||
|
||||
|
@ -8,7 +8,6 @@ using System.Linq;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Rulesets.Objects.Legacy;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Framework;
|
||||
|
||||
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())));
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// Whether or not beatmap or runtime offsets should be applied. Defaults on; only disable for testing purposes.
|
||||
/// </summary>
|
||||
public bool ApplyOffsets = true;
|
||||
|
||||
private readonly int offset = UniversalOffset;
|
||||
private readonly int offset;
|
||||
|
||||
public LegacyBeatmapDecoder(int version = LATEST_VERSION) : base(version)
|
||||
{
|
||||
// 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)
|
||||
|
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.IncreaseFirstObjectVisibility, true);
|
||||
|
||||
// Update
|
||||
Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer);
|
||||
|
||||
@ -144,6 +146,7 @@ namespace osu.Game.Configuration
|
||||
ScreenshotCaptureMenuCursor,
|
||||
SongSelectRightMouseScroll,
|
||||
BeatmapSkins,
|
||||
BeatmapHitsounds
|
||||
BeatmapHitsounds,
|
||||
IncreaseFirstObjectVisibility
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using osu.Framework.IO.File;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.IO;
|
||||
@ -364,7 +365,7 @@ namespace osu.Game.Database
|
||||
using (Stream s = reader.GetStream(file))
|
||||
fileInfos.Add(new TFileModel
|
||||
{
|
||||
Filename = file,
|
||||
Filename = FileSafety.PathSanitise(file),
|
||||
FileInfo = files.Add(s)
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
@ -46,20 +47,36 @@ namespace osu.Game.Database
|
||||
public DatabaseWriteUsage GetForWrite(bool withTransaction = true)
|
||||
{
|
||||
Monitor.Enter(writeLock);
|
||||
OsuDbContext context;
|
||||
|
||||
if (currentWriteTransaction == null && withTransaction)
|
||||
try
|
||||
{
|
||||
// this mitigates the fact that changes on tracked entities will not be rolled back with the transaction by ensuring write operations are always executed in isolated contexts.
|
||||
// if this results in sub-optimal efficiency, we may need to look into removing Database-level transactions in favour of running SaveChanges where we currently commit the transaction.
|
||||
if (threadContexts.IsValueCreated)
|
||||
recycleThreadContexts();
|
||||
if (currentWriteTransaction == null && withTransaction)
|
||||
{
|
||||
// this mitigates the fact that changes on tracked entities will not be rolled back with the transaction by ensuring write operations are always executed in isolated contexts.
|
||||
// if this results in sub-optimal efficiency, we may need to look into removing Database-level transactions in favour of running SaveChanges where we currently commit the transaction.
|
||||
if (threadContexts.IsValueCreated)
|
||||
recycleThreadContexts();
|
||||
|
||||
currentWriteTransaction = threadContexts.Value.Database.BeginTransaction();
|
||||
context = threadContexts.Value;
|
||||
currentWriteTransaction = context.Database.BeginTransaction();
|
||||
}
|
||||
else
|
||||
{
|
||||
// we want to try-catch the retrieval of the context because it could throw an error (in CreateContext).
|
||||
context = threadContexts.Value;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// retrieval of a context could trigger a fatal error.
|
||||
Monitor.Exit(writeLock);
|
||||
throw;
|
||||
}
|
||||
|
||||
Interlocked.Increment(ref currentWriteUsages);
|
||||
|
||||
return new DatabaseWriteUsage(threadContexts.Value, usageCompleted) { IsTransactionLeader = currentWriteTransaction != null && currentWriteUsages == 1 };
|
||||
return new DatabaseWriteUsage(context, usageCompleted) { IsTransactionLeader = currentWriteTransaction != null && currentWriteUsages == 1 };
|
||||
}
|
||||
|
||||
private void usageCompleted(DatabaseWriteUsage usage)
|
||||
@ -100,19 +117,18 @@ namespace osu.Game.Database
|
||||
|
||||
private void recycleThreadContexts() => threadContexts = new ThreadLocal<OsuDbContext>(CreateContext);
|
||||
|
||||
protected virtual OsuDbContext CreateContext()
|
||||
protected virtual OsuDbContext CreateContext() => new OsuDbContext(host.Storage.GetDatabaseConnectionString(database_name))
|
||||
{
|
||||
var ctx = new OsuDbContext(host.Storage.GetDatabaseConnectionString(database_name));
|
||||
ctx.Database.AutoTransactionsEnabled = false;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
Database = { AutoTransactionsEnabled = false }
|
||||
};
|
||||
|
||||
public void ResetDatabase()
|
||||
{
|
||||
lock (writeLock)
|
||||
{
|
||||
recycleThreadContexts();
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
host.Storage.DeleteDatabase(database_name);
|
||||
}
|
||||
}
|
||||
|
@ -58,11 +58,20 @@ namespace osu.Game.Database
|
||||
this.connectionString = connectionString;
|
||||
|
||||
var connection = Database.GetDbConnection();
|
||||
connection.Open();
|
||||
using (var cmd = connection.CreateCommand())
|
||||
try
|
||||
{
|
||||
cmd.CommandText = "PRAGMA journal_mode=WAL;";
|
||||
cmd.ExecuteNonQuery();
|
||||
connection.Open();
|
||||
|
||||
using (var cmd = connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "PRAGMA journal_mode=WAL;";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
connection.Close();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ namespace osu.Game.Graphics.Containers
|
||||
{
|
||||
public class BeatSyncedContainer : Container
|
||||
{
|
||||
protected readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private int lastBeat;
|
||||
private TimingControlPoint lastTimingPoint;
|
||||
@ -74,9 +74,9 @@ namespace osu.Game.Graphics.Containers
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game)
|
||||
private void load(IBindableBeatmap beatmap)
|
||||
{
|
||||
Beatmap.BindTo(game.Beatmap);
|
||||
Beatmap.BindTo(beatmap);
|
||||
}
|
||||
|
||||
protected virtual void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
|
@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input;
|
||||
using OpenTK;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Graphics.Containers
|
||||
{
|
||||
@ -16,13 +17,13 @@ namespace osu.Game.Graphics.Containers
|
||||
private SampleChannel samplePopIn;
|
||||
private SampleChannel samplePopOut;
|
||||
|
||||
private readonly BindableBool allowOpeningOverlays = new BindableBool(true);
|
||||
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuGame osuGame, AudioManager audio)
|
||||
{
|
||||
if (osuGame != null)
|
||||
allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays);
|
||||
OverlayActivationMode.BindTo(osuGame.OverlayActivationMode);
|
||||
|
||||
samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in");
|
||||
samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out");
|
||||
@ -52,20 +53,18 @@ namespace osu.Game.Graphics.Containers
|
||||
|
||||
private void onStateChanged(Visibility visibility)
|
||||
{
|
||||
if (allowOpeningOverlays)
|
||||
switch (visibility)
|
||||
{
|
||||
switch (visibility)
|
||||
{
|
||||
case Visibility.Visible:
|
||||
case Visibility.Visible:
|
||||
if (OverlayActivationMode != OverlayActivation.Disabled)
|
||||
samplePopIn?.Play();
|
||||
break;
|
||||
case Visibility.Hidden:
|
||||
samplePopOut?.Play();
|
||||
break;
|
||||
}
|
||||
else
|
||||
State = Visibility.Hidden;
|
||||
break;
|
||||
case Visibility.Hidden:
|
||||
samplePopOut?.Play();
|
||||
break;
|
||||
}
|
||||
else
|
||||
State = Visibility.Hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using osu.Framework.IO.File;
|
||||
|
||||
namespace osu.Game.IO.Archives
|
||||
{
|
||||
@ -15,19 +14,20 @@ namespace osu.Game.IO.Archives
|
||||
{
|
||||
private readonly string path;
|
||||
|
||||
public LegacyFilesystemReader(string path) : base(Path.GetFileName(path))
|
||||
public LegacyFilesystemReader(string path)
|
||||
: base(Path.GetFileName(path))
|
||||
{
|
||||
this.path = path;
|
||||
// re-get full path to standardise with Directory.GetFiles return values below.
|
||||
this.path = Path.GetFullPath(path);
|
||||
}
|
||||
|
||||
public override Stream GetStream(string name) => File.OpenRead(Path.Combine(path, name));
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
public override IEnumerable<string> Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(f => FileSafety.GetRelativePath(f, path)).ToArray();
|
||||
public override IEnumerable<string> Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(f => f.Replace(path, string.Empty).Trim(Path.DirectorySeparatorChar)).ToArray();
|
||||
|
||||
public override Stream GetUnderlyingStream() => null;
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ namespace osu.Game.Online.API
|
||||
throw new TimeoutException(@"API request timeout hit");
|
||||
|
||||
WebRequest = CreateWebRequest();
|
||||
WebRequest.Failed += Fail;
|
||||
WebRequest.AllowRetryOnTimeout = false;
|
||||
WebRequest.AddHeader("Authorization", $"Bearer {api.AccessToken}");
|
||||
|
||||
|
@ -77,8 +77,7 @@ namespace osu.Game
|
||||
|
||||
public float ToolbarOffset => Toolbar.Position.Y + Toolbar.DrawHeight;
|
||||
|
||||
public readonly BindableBool HideOverlaysOnEnter = new BindableBool();
|
||||
public readonly BindableBool AllowOpeningOverlays = new BindableBool(true);
|
||||
public readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
|
||||
|
||||
private OsuScreen screenStack;
|
||||
|
||||
@ -94,6 +93,8 @@ namespace osu.Game
|
||||
|
||||
private SettingsOverlay settings;
|
||||
|
||||
private readonly List<OverlayContainer> overlays = new List<OverlayContainer>();
|
||||
|
||||
// todo: move this to SongSelect once Screen has the ability to unsuspend.
|
||||
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(new List<Mod>());
|
||||
|
||||
@ -106,6 +107,17 @@ namespace osu.Game
|
||||
|
||||
public void ToggleDirect() => direct.ToggleVisibility();
|
||||
|
||||
/// <summary>
|
||||
/// Close all game-wide overlays.
|
||||
/// </summary>
|
||||
/// <param name="toolbar">Whether the toolbar should also be hidden.</param>
|
||||
public void CloseAllOverlays(bool toolbar = true)
|
||||
{
|
||||
foreach (var o in overlays)
|
||||
o.State = Visibility.Hidden;
|
||||
if (toolbar) Toolbar.State = Visibility.Hidden;
|
||||
}
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
@ -251,7 +263,7 @@ namespace osu.Game
|
||||
Depth = -5,
|
||||
OnHome = delegate
|
||||
{
|
||||
hideAllOverlays();
|
||||
CloseAllOverlays(false);
|
||||
intro?.ChildScreen?.MakeCurrent();
|
||||
},
|
||||
}, overlayContent.Add);
|
||||
@ -308,6 +320,8 @@ namespace osu.Game
|
||||
|
||||
// ensure only one of these overlays are open at once.
|
||||
var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct };
|
||||
overlays.AddRange(singleDisplayOverlays);
|
||||
|
||||
foreach (var overlay in singleDisplayOverlays)
|
||||
{
|
||||
overlay.StateChanged += state =>
|
||||
@ -323,6 +337,8 @@ namespace osu.Game
|
||||
}
|
||||
|
||||
var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications };
|
||||
overlays.AddRange(singleDisplaySideOverlays);
|
||||
|
||||
foreach (var overlay in singleDisplaySideOverlays)
|
||||
{
|
||||
overlay.StateChanged += state =>
|
||||
@ -339,6 +355,8 @@ namespace osu.Game
|
||||
|
||||
// eventually informational overlays should be displayed in a stack, but for now let's only allow one to stay open at a time.
|
||||
var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile };
|
||||
overlays.AddRange(informationalOverlays);
|
||||
|
||||
foreach (var overlay in informationalOverlays)
|
||||
{
|
||||
overlay.StateChanged += state =>
|
||||
@ -353,6 +371,11 @@ namespace osu.Game
|
||||
};
|
||||
}
|
||||
|
||||
OverlayActivationMode.ValueChanged += v =>
|
||||
{
|
||||
if (v != OverlayActivation.All) CloseAllOverlays();
|
||||
};
|
||||
|
||||
void updateScreenOffset()
|
||||
{
|
||||
float offset = 0;
|
||||
@ -367,21 +390,6 @@ namespace osu.Game
|
||||
|
||||
settings.StateChanged += _ => updateScreenOffset();
|
||||
notifications.StateChanged += _ => updateScreenOffset();
|
||||
|
||||
notifications.Enabled.BindTo(AllowOpeningOverlays);
|
||||
|
||||
HideOverlaysOnEnter.ValueChanged += hide =>
|
||||
{
|
||||
//central game screen change logic.
|
||||
if (hide)
|
||||
{
|
||||
hideAllOverlays();
|
||||
musicController.State = Visibility.Hidden;
|
||||
Toolbar.State = Visibility.Hidden;
|
||||
}
|
||||
else
|
||||
Toolbar.State = Visibility.Visible;
|
||||
};
|
||||
}
|
||||
|
||||
private void forwardLoggedErrorsToNotifications()
|
||||
@ -498,16 +506,6 @@ namespace osu.Game
|
||||
private OsuScreen currentScreen;
|
||||
private FrameworkConfigManager frameworkConfig;
|
||||
|
||||
private void hideAllOverlays()
|
||||
{
|
||||
settings.State = Visibility.Hidden;
|
||||
chat.State = Visibility.Hidden;
|
||||
direct.State = Visibility.Hidden;
|
||||
social.State = Visibility.Hidden;
|
||||
userProfile.State = Visibility.Hidden;
|
||||
notifications.State = Visibility.Hidden;
|
||||
}
|
||||
|
||||
protected override bool OnExiting()
|
||||
{
|
||||
if (screenStack.ChildScreen == null) return false;
|
||||
|
@ -3,14 +3,12 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.IO.Stores;
|
||||
@ -31,6 +29,7 @@ using osu.Game.IO;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
using DebugUtils = osu.Game.Utils.DebugUtils;
|
||||
|
||||
namespace osu.Game
|
||||
{
|
||||
@ -59,13 +58,12 @@ namespace osu.Game
|
||||
|
||||
protected MenuCursorContainer MenuCursorContainer;
|
||||
|
||||
protected override string MainResourceFile => @"osu.Game.Resources.dll";
|
||||
|
||||
private Container content;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
public Bindable<WorkingBeatmap> Beatmap { get; private set; }
|
||||
private OsuBindableBeatmap beatmap;
|
||||
protected BindableBeatmap Beatmap => beatmap;
|
||||
|
||||
private Bindable<bool> fpsDisplayVisible;
|
||||
|
||||
@ -100,6 +98,8 @@ namespace osu.Game
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Resources.AddStore(new DllResourceStore(@"osu.Game.Resources.dll"));
|
||||
|
||||
dependencies.Cache(contextFactory = new DatabaseContextFactory(Host));
|
||||
|
||||
dependencies.Cache(new LargeTextureStore(new RawTextureLoaderStore(new NamespacedResourceStore<byte[]>(Resources, @"Textures"))));
|
||||
@ -157,33 +157,15 @@ namespace osu.Game
|
||||
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light"));
|
||||
|
||||
var defaultBeatmap = new DummyWorkingBeatmap(this);
|
||||
Beatmap = new NonNullableBindable<WorkingBeatmap>(defaultBeatmap);
|
||||
beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio);
|
||||
BeatmapManager.DefaultBeatmap = defaultBeatmap;
|
||||
|
||||
// tracks play so loud our samples can't keep up.
|
||||
// this adds a global reduction of track volume for the time being.
|
||||
Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
|
||||
|
||||
Beatmap.ValueChanged += b =>
|
||||
{
|
||||
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 != b.Track)
|
||||
{
|
||||
if (trackLoaded)
|
||||
{
|
||||
Debug.Assert(lastBeatmap != null);
|
||||
Debug.Assert(lastBeatmap.Track != null);
|
||||
|
||||
lastBeatmap.RecycleTrack();
|
||||
}
|
||||
|
||||
Audio.Track.AddItem(b.Track);
|
||||
}
|
||||
|
||||
lastBeatmap = b;
|
||||
};
|
||||
dependencies.CacheAs<BindableBeatmap>(beatmap);
|
||||
dependencies.CacheAs<IBindableBeatmap>(beatmap);
|
||||
|
||||
FileStore.Cleanup();
|
||||
|
||||
@ -204,29 +186,6 @@ namespace osu.Game
|
||||
dependencies.Cache(globalBinding);
|
||||
}
|
||||
|
||||
private void runMigrations()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var db = contextFactory.GetForWrite(false))
|
||||
db.Context.Migrate();
|
||||
}
|
||||
catch (MigrationFailedException e)
|
||||
{
|
||||
Logger.Error(e.InnerException ?? e, "Migration failed! We'll be starting with a fresh database.", LoggingTarget.Database);
|
||||
|
||||
// if we failed, let's delete the database and start fresh.
|
||||
// todo: we probably want a better (non-destructive) migrations/recovery process at a later point than this.
|
||||
contextFactory.ResetDatabase();
|
||||
Logger.Log("Database purged successfully.", LoggingTarget.Database, LogLevel.Important);
|
||||
|
||||
using (var db = contextFactory.GetForWrite(false))
|
||||
db.Context.Migrate();
|
||||
}
|
||||
}
|
||||
|
||||
private WorkingBeatmap lastBeatmap;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
@ -238,6 +197,29 @@ namespace osu.Game
|
||||
fpsDisplayVisible.TriggerChange();
|
||||
}
|
||||
|
||||
private void runMigrations()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var db = contextFactory.GetForWrite(false))
|
||||
db.Context.Migrate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e.InnerException ?? e, "Migration failed! We'll be starting with a fresh database.", LoggingTarget.Database);
|
||||
|
||||
// if we failed, let's delete the database and start fresh.
|
||||
// todo: we probably want a better (non-destructive) migrations/recovery process at a later point than this.
|
||||
contextFactory.ResetDatabase();
|
||||
|
||||
Logger.Log("Database purged successfully.", LoggingTarget.Database, LogLevel.Important);
|
||||
|
||||
// only run once more, then hard bail.
|
||||
using (var db = contextFactory.GetForWrite(false))
|
||||
db.Context.Migrate();
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetHost(GameHost host)
|
||||
{
|
||||
if (LocalConfig == null)
|
||||
@ -256,5 +238,26 @@ namespace osu.Game
|
||||
}
|
||||
|
||||
public string[] HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions).ToArray();
|
||||
|
||||
private class OsuBindableBeatmap : BindableBeatmap
|
||||
{
|
||||
public OsuBindableBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager)
|
||||
: this(defaultValue)
|
||||
{
|
||||
RegisterAudioManager(audioManager);
|
||||
}
|
||||
|
||||
private OsuBindableBeatmap(WorkingBeatmap defaultValue)
|
||||
: base(defaultValue)
|
||||
{
|
||||
}
|
||||
|
||||
public override BindableBeatmap GetBoundCopy()
|
||||
{
|
||||
var copy = new OsuBindableBeatmap(Default);
|
||||
copy.BindTo(this);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using OpenTK;
|
||||
@ -11,10 +13,11 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
|
||||
{
|
||||
public class DownloadButton : HeaderButton
|
||||
{
|
||||
public DownloadButton(string title, string subtitle)
|
||||
public DownloadButton(BeatmapSetInfo set, bool noVideo = false)
|
||||
{
|
||||
Width = 120;
|
||||
|
||||
BeatmapSetDownloader downloader;
|
||||
Add(new Container
|
||||
{
|
||||
Depth = -1,
|
||||
@ -22,6 +25,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
|
||||
Padding = new MarginPadding { Horizontal = 10 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
downloader = new BeatmapSetDownloader(set, noVideo),
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
@ -32,13 +36,13 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = title,
|
||||
Text = "Download",
|
||||
TextSize = 13,
|
||||
Font = @"Exo2.0-Bold",
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = subtitle,
|
||||
Text = set.OnlineInfo.HasVideo && noVideo ? "without Video" : string.Empty,
|
||||
TextSize = 11,
|
||||
Font = @"Exo2.0-Bold",
|
||||
},
|
||||
@ -54,6 +58,25 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Action = () =>
|
||||
{
|
||||
if (!downloader.Download())
|
||||
{
|
||||
Content.MoveToX(-5, 50, Easing.OutSine).Then()
|
||||
.MoveToX(5, 100, Easing.InOutSine).Then()
|
||||
.MoveToX(-5, 100, Easing.InOutSine).Then()
|
||||
.MoveToX(0, 50, Easing.InSine);
|
||||
}
|
||||
};
|
||||
|
||||
downloader.Downloaded.ValueChanged += d =>
|
||||
{
|
||||
if (d)
|
||||
this.FadeOut(200);
|
||||
else
|
||||
this.FadeIn(200);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,8 +35,6 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
private readonly BeatmapSetOnlineStatusPill onlineStatusPill;
|
||||
public Details Details;
|
||||
|
||||
private BeatmapManager beatmaps;
|
||||
|
||||
public readonly BeatmapPicker Picker;
|
||||
|
||||
private BeatmapSetInfo beatmapSet;
|
||||
@ -68,8 +66,24 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
downloadButtonsContainer.FadeIn(transition_duration);
|
||||
favouriteButton.FadeIn(transition_duration);
|
||||
|
||||
noVideoButtons.FadeTo(BeatmapSet.OnlineInfo.HasVideo ? 0 : 1, transition_duration);
|
||||
videoButtons.FadeTo(BeatmapSet.OnlineInfo.HasVideo ? 1 : 0, transition_duration);
|
||||
if (BeatmapSet.OnlineInfo.HasVideo)
|
||||
{
|
||||
videoButtons.Children = new[]
|
||||
{
|
||||
new DownloadButton(BeatmapSet),
|
||||
new DownloadButton(BeatmapSet, true),
|
||||
};
|
||||
|
||||
videoButtons.FadeIn(transition_duration);
|
||||
noVideoButtons.FadeOut(transition_duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
noVideoButtons.Child = new DownloadButton(BeatmapSet);
|
||||
|
||||
noVideoButtons.FadeIn(transition_duration);
|
||||
videoButtons.FadeOut(transition_duration);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -192,27 +206,12 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0f,
|
||||
Child = new DownloadButton("Download", @"")
|
||||
{
|
||||
Action = () => download(false),
|
||||
},
|
||||
},
|
||||
videoButtons = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Spacing = new Vector2(buttons_spacing),
|
||||
Alpha = 0f,
|
||||
Children = new[]
|
||||
{
|
||||
new DownloadButton("Download", "with Video")
|
||||
{
|
||||
Action = () => download(false),
|
||||
},
|
||||
new DownloadButton("Download", "without Video")
|
||||
{
|
||||
Action = () => download(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -248,41 +247,10 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, BeatmapManager beatmaps)
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
tabsBg.Colour = colours.Gray3;
|
||||
this.beatmaps = beatmaps;
|
||||
|
||||
beatmaps.ItemAdded += handleBeatmapAdd;
|
||||
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
if (beatmaps != null) beatmaps.ItemAdded -= handleBeatmapAdd;
|
||||
}
|
||||
|
||||
private void handleBeatmapAdd(BeatmapSetInfo beatmap) => Schedule(() =>
|
||||
{
|
||||
if (beatmap.OnlineBeatmapSetID == BeatmapSet?.OnlineBeatmapSetID)
|
||||
downloadButtonsContainer.FadeOut(transition_duration);
|
||||
});
|
||||
|
||||
private void download(bool noVideo)
|
||||
{
|
||||
if (beatmaps.GetExistingDownload(BeatmapSet) != null)
|
||||
{
|
||||
downloadButtonsContainer.MoveToX(-5, 50, Easing.OutSine).Then()
|
||||
.MoveToX(5, 100, Easing.InOutSine).Then()
|
||||
.MoveToX(-5, 100, Easing.InOutSine).Then()
|
||||
.MoveToX(0, 50, Easing.InSine).Then();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
beatmaps.Download(BeatmapSet, noVideo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
private const float metadata_width = 225;
|
||||
private const float spacing = 20;
|
||||
|
||||
private readonly MetadataSection description, source, tags;
|
||||
private readonly MetadataSection source, tags;
|
||||
private readonly Box successRateBackground;
|
||||
private readonly SuccessRate successRate;
|
||||
|
||||
@ -83,7 +83,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
Child = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = description = new MetadataSection("Description"),
|
||||
Child = new MetadataSection("Description"),
|
||||
},
|
||||
},
|
||||
new Container
|
||||
@ -135,8 +135,6 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
successRateBackground.Colour = colours.GrayE;
|
||||
source.TextColour = description.TextColour = colours.Gray5;
|
||||
tags.TextColour = colours.BlueDark;
|
||||
|
||||
updateDisplay();
|
||||
}
|
||||
@ -195,7 +193,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
header.Colour = colours.Gray5;
|
||||
header.Colour = textFlow.Colour = colours.Gray5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,14 +166,13 @@ namespace osu.Game.Overlays.Direct
|
||||
},
|
||||
},
|
||||
},
|
||||
new DownloadButton
|
||||
new DownloadButton(SetInfo)
|
||||
{
|
||||
Size = new Vector2(30),
|
||||
Margin = new MarginPadding(horizontal_padding),
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Colour = colours.Gray5,
|
||||
Action = StartDownload
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -12,28 +12,31 @@ using osu.Game.Graphics.Sprites;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Beatmaps;
|
||||
|
||||
namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
public class DirectListPanel : DirectPanel
|
||||
{
|
||||
private const float transition_duration = 120;
|
||||
private const float horizontal_padding = 10;
|
||||
private const float vertical_padding = 5;
|
||||
private const float height = 70;
|
||||
|
||||
private PlayButton playButton;
|
||||
private Box progressBar;
|
||||
private Container downloadContainer;
|
||||
|
||||
protected override PlayButton PlayButton => playButton;
|
||||
protected override Box PreviewBar => progressBar;
|
||||
|
||||
public DirectListPanel(BeatmapSetInfo beatmap) : base(beatmap)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
private PlayButton playButton;
|
||||
private Box progressBar;
|
||||
|
||||
protected override PlayButton PlayButton => playButton;
|
||||
protected override Box PreviewBar => progressBar;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LocalisationEngine localisation, OsuColour colours)
|
||||
{
|
||||
@ -59,7 +62,7 @@ namespace osu.Game.Overlays.Direct
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
LayoutEasing = Easing.OutQuint,
|
||||
LayoutDuration = 120,
|
||||
LayoutDuration = transition_duration,
|
||||
Spacing = new Vector2(10, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
@ -104,53 +107,69 @@ namespace osu.Game.Overlays.Direct
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Margin = new MarginPadding { Right = height - vertical_padding * 2 + vertical_padding },
|
||||
Direction = FillDirection.Horizontal,
|
||||
LayoutEasing = Easing.OutQuint,
|
||||
LayoutDuration = transition_duration,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0)
|
||||
downloadContainer = new Container
|
||||
{
|
||||
Margin = new MarginPadding { Right = 1 },
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
Child = new DownloadButton(SetInfo)
|
||||
{
|
||||
Size = new Vector2(height - vertical_padding * 2),
|
||||
Margin = new MarginPadding { Left = vertical_padding },
|
||||
},
|
||||
},
|
||||
new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0),
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0)
|
||||
{
|
||||
Text = "mapped by ",
|
||||
TextSize = 14,
|
||||
Margin = new MarginPadding { Right = 1 },
|
||||
},
|
||||
new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0),
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = "mapped by ",
|
||||
TextSize = 14,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = SetInfo.Metadata.Author.Username,
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-SemiBoldItalic",
|
||||
},
|
||||
},
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = SetInfo.Metadata.Author.Username,
|
||||
Text = $"from {SetInfo.Metadata.Source}",
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-SemiBoldItalic",
|
||||
Alpha = string.IsNullOrEmpty(SetInfo.Metadata.Source) ? 0f : 1f,
|
||||
},
|
||||
},
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = $"from {SetInfo.Metadata.Source}",
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
TextSize = 14,
|
||||
Alpha = string.IsNullOrEmpty(SetInfo.Metadata.Source) ? 0f : 1f,
|
||||
},
|
||||
},
|
||||
},
|
||||
new DownloadButton
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Size = new Vector2(height - vertical_padding * 2),
|
||||
Action = StartDownload
|
||||
},
|
||||
},
|
||||
},
|
||||
progressBar = new Box
|
||||
@ -165,5 +184,17 @@ namespace osu.Game.Overlays.Direct
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
downloadContainer.FadeIn(transition_duration, Easing.InOutQuint);
|
||||
return base.OnHover(state);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
downloadContainer.FadeOut(transition_duration, Easing.InOutQuint);
|
||||
base.OnHoverLost(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,22 +147,6 @@ namespace osu.Game.Overlays.Direct
|
||||
|
||||
protected void ShowInformation() => beatmapSetOverlay?.ShowBeatmapSet(SetInfo);
|
||||
|
||||
protected void StartDownload()
|
||||
{
|
||||
if (beatmaps.GetExistingDownload(SetInfo) != null)
|
||||
{
|
||||
// we already have an active download running.
|
||||
content.MoveToX(-5, 50, Easing.OutSine).Then()
|
||||
.MoveToX(5, 100, Easing.InOutSine).Then()
|
||||
.MoveToX(-5, 100, Easing.InOutSine).Then()
|
||||
.MoveToX(0, 50, Easing.InSine).Then();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
beatmaps.Download(SetInfo);
|
||||
}
|
||||
|
||||
private void attachDownload(DownloadBeatmapSetRequest request)
|
||||
{
|
||||
if (request.BeatmapSet.OnlineBeatmapSetID != SetInfo.OnlineBeatmapSetID)
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using OpenTK;
|
||||
@ -13,10 +15,12 @@ namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
private readonly SpriteIcon icon;
|
||||
|
||||
public DownloadButton()
|
||||
public DownloadButton(BeatmapSetInfo set, bool noVideo = false)
|
||||
{
|
||||
BeatmapSetDownloader downloader;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
downloader = new BeatmapSetDownloader(set, noVideo),
|
||||
icon = new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
@ -25,6 +29,25 @@ namespace osu.Game.Overlays.Direct
|
||||
Icon = FontAwesome.fa_osu_chevron_down_o,
|
||||
},
|
||||
};
|
||||
|
||||
Action = () =>
|
||||
{
|
||||
if (!downloader.Download())
|
||||
{
|
||||
Content.MoveToX(-5, 50, Easing.OutSine).Then()
|
||||
.MoveToX(5, 100, Easing.InOutSine).Then()
|
||||
.MoveToX(-5, 100, Easing.InOutSine).Then()
|
||||
.MoveToX(0, 50, Easing.InSine);
|
||||
}
|
||||
};
|
||||
|
||||
downloader.Downloaded.ValueChanged += d =>
|
||||
{
|
||||
if (d)
|
||||
this.FadeOut(200);
|
||||
else
|
||||
this.FadeIn(200);
|
||||
};
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||
|
@ -28,7 +28,6 @@ namespace osu.Game.Overlays
|
||||
|
||||
private APIAccess api;
|
||||
private RulesetStore rulesets;
|
||||
private BeatmapManager beatmaps;
|
||||
|
||||
private readonly FillFlowContainer resultCountsContainer;
|
||||
private readonly OsuSpriteText resultCountsText;
|
||||
@ -177,24 +176,14 @@ namespace osu.Game.Overlays
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, APIAccess api, RulesetStore rulesets, BeatmapManager beatmaps)
|
||||
private void load(OsuColour colours, APIAccess api, RulesetStore rulesets)
|
||||
{
|
||||
this.api = api;
|
||||
this.rulesets = rulesets;
|
||||
this.beatmaps = beatmaps;
|
||||
|
||||
resultCountsContainer.Colour = colours.Yellow;
|
||||
|
||||
beatmaps.ItemAdded += setAdded;
|
||||
}
|
||||
|
||||
private void setAdded(BeatmapSetInfo set) => Schedule(() =>
|
||||
{
|
||||
// if a new map was imported, we should remove it from search results (download completed etc.)
|
||||
panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire();
|
||||
BeatmapSets = BeatmapSets?.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID);
|
||||
});
|
||||
|
||||
private void updateResultCounts()
|
||||
{
|
||||
resultCountsContainer.FadeTo(ResultAmounts == null ? 0f : 1f, 200, Easing.OutQuint);
|
||||
@ -297,9 +286,7 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
var onlineIds = response.Select(r => r.OnlineBeatmapSetID).ToList();
|
||||
var presentOnlineIds = beatmaps.QueryBeatmapSets(s => onlineIds.Contains(s.OnlineBeatmapSetID) && !s.DeletePending).Select(r => r.OnlineBeatmapSetID).ToList();
|
||||
var sets = response.Select(r => r.ToBeatmapSet(rulesets)).Where(b => !presentOnlineIds.Contains(b.OnlineBeatmapSetID)).ToList();
|
||||
var sets = response.Select(r => r.ToBeatmapSet(rulesets)).ToList();
|
||||
|
||||
// may not need scheduling; loads async internally.
|
||||
Schedule(() =>
|
||||
@ -323,14 +310,6 @@ namespace osu.Game.Overlays
|
||||
|
||||
private int distinctCount(List<string> list) => list.Distinct().ToArray().Length;
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (beatmaps != null)
|
||||
beatmaps.ItemAdded -= setAdded;
|
||||
}
|
||||
|
||||
public class ResultCounts
|
||||
{
|
||||
public readonly int Artists;
|
||||
|
@ -180,7 +180,7 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool OnWheel(InputState state)
|
||||
protected override bool OnScroll(InputState state)
|
||||
{
|
||||
if (HasFocus)
|
||||
{
|
||||
@ -192,7 +192,7 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnWheel(state);
|
||||
return base.OnScroll(state);
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||
|
@ -73,13 +73,13 @@ namespace osu.Game.Overlays.Music
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(BeatmapManager beatmaps, OsuGameBase osuGame)
|
||||
private void load(BeatmapManager beatmaps, IBindableBeatmap beatmap)
|
||||
{
|
||||
beatmaps.GetAllUsableBeatmapSets().ForEach(addBeatmapSet);
|
||||
beatmaps.ItemAdded += addBeatmapSet;
|
||||
beatmaps.ItemRemoved += removeBeatmapSet;
|
||||
|
||||
beatmapBacking.BindTo(osuGame.Beatmap);
|
||||
beatmapBacking.BindTo(beatmap);
|
||||
beatmapBacking.ValueChanged += _ => updateSelectedSet();
|
||||
}
|
||||
|
||||
|
@ -21,17 +21,22 @@ namespace osu.Game.Overlays.Music
|
||||
private const float transition_duration = 600;
|
||||
private const float playlist_height = 510;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the order of an item in the list has changed.
|
||||
/// The second parameter indicates the new index of the item.
|
||||
/// </summary>
|
||||
public Action<BeatmapSetInfo, int> OrderChanged;
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
private BeatmapManager beatmaps;
|
||||
|
||||
private FilterControl filter;
|
||||
private PlaylistList list;
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours)
|
||||
private void load(OsuColour colours, BindableBeatmap beatmap, BeatmapManager beatmaps)
|
||||
{
|
||||
this.beatmap.BindTo(beatmap);
|
||||
this.beatmaps = beatmaps;
|
||||
|
||||
Children = new Drawable[]
|
||||
@ -73,15 +78,13 @@ namespace osu.Game.Overlays.Music
|
||||
},
|
||||
};
|
||||
|
||||
beatmapBacking.BindTo(game.Beatmap);
|
||||
|
||||
filter.Search.OnCommit = (sender, newText) =>
|
||||
{
|
||||
BeatmapInfo beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault();
|
||||
if (beatmap != null)
|
||||
BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault();
|
||||
if (toSelect != null)
|
||||
{
|
||||
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(beatmap);
|
||||
beatmapBacking.Value.Track.Restart();
|
||||
beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect);
|
||||
beatmap.Value.Track.Restart();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -105,14 +108,14 @@ namespace osu.Game.Overlays.Music
|
||||
|
||||
private void itemSelected(BeatmapSetInfo set)
|
||||
{
|
||||
if (set.ID == (beatmapBacking.Value?.BeatmapSetInfo?.ID ?? -1))
|
||||
if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1))
|
||||
{
|
||||
beatmapBacking.Value?.Track?.Seek(0);
|
||||
beatmap.Value?.Track?.Seek(0);
|
||||
return;
|
||||
}
|
||||
|
||||
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First());
|
||||
beatmapBacking.Value.Track.Restart();
|
||||
beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First());
|
||||
beatmap.Value.Track.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,8 @@ namespace osu.Game.Overlays
|
||||
public class MusicController : OsuFocusedOverlayContainer
|
||||
{
|
||||
private const float player_height = 130;
|
||||
|
||||
private const float transition_length = 800;
|
||||
|
||||
private const float progress_height = 10;
|
||||
|
||||
private const float bottom_black_area_height = 55;
|
||||
|
||||
private Drawable background;
|
||||
@ -49,16 +46,17 @@ namespace osu.Game.Overlays
|
||||
|
||||
private PlaylistOverlay playlist;
|
||||
|
||||
private BeatmapManager beatmaps;
|
||||
private LocalisationEngine localisation;
|
||||
|
||||
private BeatmapManager beatmaps;
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
private List<BeatmapSetInfo> beatmapSets;
|
||||
private BeatmapSetInfo currentSet;
|
||||
|
||||
private Container dragContainer;
|
||||
private Container playerContainer;
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
public MusicController()
|
||||
{
|
||||
Width = 400;
|
||||
@ -97,8 +95,9 @@ namespace osu.Game.Overlays
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation)
|
||||
private void load(BindableBeatmap beatmap, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation)
|
||||
{
|
||||
this.beatmap.BindTo(beatmap);
|
||||
this.beatmaps = beatmaps;
|
||||
this.localisation = localisation;
|
||||
|
||||
@ -224,8 +223,6 @@ namespace osu.Game.Overlays
|
||||
beatmaps.ItemAdded += handleBeatmapAdded;
|
||||
beatmaps.ItemRemoved += handleBeatmapRemoved;
|
||||
|
||||
beatmapBacking.BindTo(game.Beatmap);
|
||||
|
||||
playlist.StateChanged += s => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint);
|
||||
}
|
||||
|
||||
@ -240,10 +237,8 @@ namespace osu.Game.Overlays
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
beatmapBacking.ValueChanged += beatmapChanged;
|
||||
beatmapBacking.DisabledChanged += beatmapDisabledChanged;
|
||||
beatmapBacking.TriggerChange();
|
||||
|
||||
beatmap.BindValueChanged(beatmapChanged, true);
|
||||
beatmap.BindDisabledChanged(beatmapDisabledChanged, true);
|
||||
base.LoadComplete();
|
||||
}
|
||||
|
||||
@ -276,7 +271,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o;
|
||||
|
||||
if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled && beatmapSets.Any())
|
||||
if (track.HasCompleted && !track.Looping && !beatmap.Disabled && beatmapSets.Any())
|
||||
next();
|
||||
}
|
||||
else
|
||||
@ -289,7 +284,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
if (track == null)
|
||||
{
|
||||
if (!beatmapBacking.Disabled)
|
||||
if (!beatmap.Disabled)
|
||||
next(true);
|
||||
return;
|
||||
}
|
||||
@ -307,8 +302,8 @@ namespace osu.Game.Overlays
|
||||
var playable = beatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? beatmapSets.LastOrDefault();
|
||||
if (playable != null)
|
||||
{
|
||||
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking);
|
||||
beatmapBacking.Value.Track.Restart();
|
||||
beatmap.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value);
|
||||
beatmap.Value.Track.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,8 +315,8 @@ namespace osu.Game.Overlays
|
||||
var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault();
|
||||
if (playable != null)
|
||||
{
|
||||
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking);
|
||||
beatmapBacking.Value.Track.Restart();
|
||||
beatmap.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value);
|
||||
beatmap.Value.Track.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,11 +22,6 @@ namespace osu.Game.Overlays
|
||||
|
||||
public const float TRANSITION_LENGTH = 600;
|
||||
|
||||
/// <summary>
|
||||
/// Whether posted notifications should be processed.
|
||||
/// </summary>
|
||||
public readonly BindableBool Enabled = new BindableBool(true);
|
||||
|
||||
private FlowContainer<NotificationSection> sections;
|
||||
|
||||
/// <summary>
|
||||
@ -34,27 +29,6 @@ namespace osu.Game.Overlays
|
||||
/// </summary>
|
||||
public Func<float> GetToolbarHeight;
|
||||
|
||||
public NotificationOverlay()
|
||||
{
|
||||
ScheduledDelegate notificationsEnabler = null;
|
||||
Enabled.ValueChanged += v =>
|
||||
{
|
||||
if (!IsLoaded)
|
||||
{
|
||||
processingPosts = v;
|
||||
return;
|
||||
}
|
||||
|
||||
notificationsEnabler?.Cancel();
|
||||
|
||||
if (v)
|
||||
// we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed.
|
||||
notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, 1000);
|
||||
else
|
||||
processingPosts = false;
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
@ -103,6 +77,29 @@ namespace osu.Game.Overlays
|
||||
};
|
||||
}
|
||||
|
||||
private ScheduledDelegate notificationsEnabler;
|
||||
private void updateProcessingMode()
|
||||
{
|
||||
bool enabled = OverlayActivationMode == OverlayActivation.All || State == Visibility.Visible;
|
||||
|
||||
notificationsEnabler?.Cancel();
|
||||
|
||||
if (enabled)
|
||||
// we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed.
|
||||
notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, State == Visibility.Visible ? 0 : 1000);
|
||||
else
|
||||
processingPosts = false;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
StateChanged += _ => updateProcessingMode();
|
||||
OverlayActivationMode.ValueChanged += _ => updateProcessingMode();
|
||||
OverlayActivationMode.TriggerChange();
|
||||
}
|
||||
|
||||
private int totalCount => sections.Select(c => c.DisplayedCount).Sum();
|
||||
private int unreadCount => sections.Select(c => c.UnreadCount).Sum();
|
||||
|
||||
|
12
osu.Game/Overlays/OverlayActivation.cs
Normal file
12
osu.Game/Overlays/OverlayActivation.cs
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public enum OverlayActivation
|
||||
{
|
||||
Disabled,
|
||||
UserTriggered,
|
||||
All
|
||||
}
|
||||
}
|
@ -107,13 +107,20 @@ namespace osu.Game.Overlays.Profile.Header
|
||||
visibleBadge = 0;
|
||||
|
||||
badgeFlowContainer.Clear();
|
||||
foreach (var badge in badges)
|
||||
for (var index = 0; index < badges.Length; index++)
|
||||
{
|
||||
LoadComponentAsync(new DrawableBadge(badge)
|
||||
int displayIndex = index;
|
||||
LoadComponentAsync(new DrawableBadge(badges[index])
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
}, badgeFlowContainer.Add);
|
||||
}, asyncBadge =>
|
||||
{
|
||||
badgeFlowContainer.Add(asyncBadge);
|
||||
|
||||
// load in stable order regardless of async load order.
|
||||
badgeFlowContainer.SetLayoutPosition(asyncBadge, displayIndex);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user