1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 17:02:55 +08:00

Merge remote-tracking branch 'refs/remotes/ppy/master' into comments_api

This commit is contained in:
Andrei Zavatski 2019-10-13 11:15:43 +03:00
commit 7f867562ca
53 changed files with 515 additions and 446 deletions

View File

@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="CatchRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset"> <configuration default="false" name="CatchRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Catch.Tests.dll" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
@ -12,7 +12,7 @@
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" /> <option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" /> <option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" /> <option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" /> <option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
<browser url="http://localhost:5000" /> <browser url="http://localhost:5000" />
<method v="2"> <method v="2">
<option name="Build" enabled="true" /> <option name="Build" enabled="true" />

View File

@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="ManiaRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset"> <configuration default="false" name="ManiaRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Mania.Tests.dll" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
@ -12,7 +12,7 @@
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" /> <option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" /> <option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" /> <option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" /> <option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
<browser url="http://localhost:5000" /> <browser url="http://localhost:5000" />
<method v="2"> <method v="2">
<option name="Build" enabled="true" /> <option name="Build" enabled="true" />

View File

@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="OsuRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset"> <configuration default="false" name="OsuRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Osu.Tests.dll" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
@ -12,7 +12,7 @@
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" /> <option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" /> <option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" /> <option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" /> <option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
<browser url="http://localhost:5000" /> <browser url="http://localhost:5000" />
<method v="2"> <method v="2">
<option name="Build" enabled="true" /> <option name="Build" enabled="true" />

View File

@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="TaikoRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset"> <configuration default="false" name="TaikoRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Taiko.Tests.dll" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
@ -12,7 +12,7 @@
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" /> <option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" /> <option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" /> <option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" /> <option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
<browser url="http://localhost:5000" /> <browser url="http://localhost:5000" />
<method v="2"> <method v="2">
<option name="Build" enabled="true" /> <option name="Build" enabled="true" />

View File

@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament"> <configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.0/osu!.dll" />
<option name="PROGRAM_PARAMETERS" value="--tournament" /> <option name="PROGRAM_PARAMETERS" value="--tournament" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
@ -12,7 +12,7 @@
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" /> <option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" /> <option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" /> <option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" /> <option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
<method v="2"> <method v="2">
<option name="Build" enabled="true" /> <option name="Build" enabled="true" />
</method> </method>

View File

@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!"> <configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.0/osu!.dll" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
@ -12,7 +12,7 @@
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" /> <option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" /> <option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" /> <option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" /> <option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
<method v="2"> <method v="2">
<option name="Build" enabled="true" /> <option name="Build" enabled="true" />
</method> </method>

View File

@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="osu! (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="osu!"> <configuration default="false" name="osu! (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp3.0/osu.Game.Tests.dll" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
@ -12,7 +12,7 @@
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" /> <option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" /> <option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" /> <option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" /> <option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
<method v="2"> <method v="2">
<option name="Build" enabled="true" /> <option name="Build" enabled="true" />
</method> </method>

32
.vscode/launch.json vendored
View File

@ -6,13 +6,13 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll" "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.0/osu!.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Debug)", "preLaunchTask": "Build osu! (Debug)",
"linux": { "linux": {
"env": { "env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}" "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
} }
}, },
"console": "internalConsole" "console": "internalConsole"
@ -23,13 +23,13 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2/osu!.dll" "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.0/osu!.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Release)", "preLaunchTask": "Build osu! (Release)",
"linux": { "linux": {
"env": { "env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}" "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
} }
}, },
"console": "internalConsole" "console": "internalConsole"
@ -40,13 +40,13 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll" "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.0/osu.Game.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build tests (Debug)", "preLaunchTask": "Build tests (Debug)",
"linux": { "linux": {
"env": { "env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}" "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
} }
}, },
"console": "internalConsole" "console": "internalConsole"
@ -56,13 +56,13 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2/osu.Game.Tests.dll" "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.0/osu.Game.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build tests (Release)", "preLaunchTask": "Build tests (Release)",
"linux": { "linux": {
"env": { "env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}" "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
} }
}, },
"console": "internalConsole" "console": "internalConsole"
@ -73,14 +73,14 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll", "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.0/osu!.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Debug)", "preLaunchTask": "Build osu! (Debug)",
"linux": { "linux": {
"env": { "env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}" "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
} }
}, },
"console": "internalConsole" "console": "internalConsole"
@ -91,14 +91,14 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2/osu!.dll", "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.0/osu!.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Release)", "preLaunchTask": "Build osu! (Release)",
"linux": { "linux": {
"env": { "env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}" "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
} }
}, },
"console": "internalConsole" "console": "internalConsole"
@ -109,14 +109,14 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tournament.Tests.dll", "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.0/osu.Game.Tournament.Tests.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build tournament tests (Debug)", "preLaunchTask": "Build tournament tests (Debug)",
"linux": { "linux": {
"env": { "env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}" "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
} }
}, },
"console": "internalConsole" "console": "internalConsole"
@ -127,14 +127,14 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tournament.Tests.dll", "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.0/osu.Game.Tournament.Tests.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build tournament tests (Release)", "preLaunchTask": "Build tournament tests (Release)",
"linux": { "linux": {
"env": { "env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}" "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
} }
}, },
"console": "internalConsole" "console": "internalConsole"

2
.vscode/tasks.json vendored
View File

@ -95,7 +95,7 @@
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
}, },
{ {
"label": "Restore (netcoreapp2.2)", "label": "Restore (netcoreapp3.0)",
"type": "shell", "type": "shell",
"command": "dotnet", "command": "dotnet",
"args": [ "args": [

View File

@ -18,7 +18,7 @@ GEM
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.5) dotenv (2.7.5)
emoji_regex (1.0.1) emoji_regex (1.0.1)
excon (0.66.0) excon (0.67.0)
faraday (0.15.4) faraday (0.15.4)
multipart-post (>= 1.2, < 3) multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6) faraday-cookie_jar (0.0.6)
@ -27,7 +27,7 @@ GEM
faraday_middleware (0.13.1) faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0) faraday (>= 0.7.4, < 1.0)
fastimage (2.1.7) fastimage (2.1.7)
fastlane (2.131.0) fastlane (2.133.0)
CFPropertyList (>= 2.3, < 4.0.0) CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0) addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0) babosa (>= 1.0.2, < 2.0.0)
@ -37,9 +37,9 @@ GEM
dotenv (>= 2.1.1, < 3.0.0) dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 2.0) emoji_regex (>= 0.1, < 2.0)
excon (>= 0.45.0, < 1.0.0) excon (>= 0.45.0, < 1.0.0)
faraday (~> 0.9) faraday (< 0.16.0)
faraday-cookie_jar (~> 0.0.6) faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 0.9) faraday_middleware (< 0.16.0)
fastimage (>= 2.1.0, < 3.0.0) fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0) gh_inspector (>= 1.1.2, < 2.0.0)
google-api-client (>= 0.21.2, < 0.24.0) google-api-client (>= 0.21.2, < 0.24.0)
@ -52,7 +52,7 @@ GEM
multipart-post (~> 2.0.0) multipart-post (~> 2.0.0)
plist (>= 3.1.0, < 4.0.0) plist (>= 3.1.0, < 4.0.0)
public_suffix (~> 2.0.0) public_suffix (~> 2.0.0)
rubyzip (>= 1.2.2, < 2.0.0) rubyzip (>= 1.3.0, < 2.0.0)
security (= 0.1.3) security (= 0.1.3)
simctl (~> 1.6.3) simctl (~> 1.6.3)
slack-notifier (>= 2.0.0, < 3.0.0) slack-notifier (>= 2.0.0, < 3.0.0)
@ -102,7 +102,7 @@ GEM
memoist (0.16.0) memoist (0.16.0)
mime-types (3.3) mime-types (3.3)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2019.0904) mime-types-data (3.2019.1009)
mini_magick (4.9.5) mini_magick (4.9.5)
mini_portile2 (2.4.0) mini_portile2 (2.4.0)
multi_json (1.13.1) multi_json (1.13.1)
@ -121,9 +121,9 @@ GEM
uber (< 0.2.0) uber (< 0.2.0)
retriable (3.1.2) retriable (3.1.2)
rouge (2.0.7) rouge (2.0.7)
rubyzip (1.2.4) rubyzip (1.3.0)
security (0.1.3) security (0.1.3)
signet (0.11.0) signet (0.12.0)
addressable (~> 2.3) addressable (~> 2.3)
faraday (~> 0.9) faraday (~> 0.9)
jwt (>= 1.5, < 3.0) jwt (>= 1.5, < 3.0)

View File

@ -18,7 +18,7 @@ Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh
## Requirements ## Requirements
- A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed. - A desktop platform with the [.NET Core SDK 3.0](https://www.microsoft.com/net/learn/get-started) or higher installed.
- When running on linux, please have a system-wide ffmpeg installation available to support video decoding. - When running on linux, please have a system-wide ffmpeg installation available to support video decoding.
- When running on Windows 7 or 8.1, **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs. - When running on Windows 7 or 8.1, **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs.
- When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio 2017+](https://visualstudio.microsoft.com/vs/), [Jetbrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/). - When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio 2017+](https://visualstudio.microsoft.com/vs/), [Jetbrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/).
@ -78,7 +78,7 @@ On Linux, the environment variable `LD_LIBRARY_PATH` must point to the build dir
For example, you can run osu! with the following command: For example, you can run osu! with the following command:
```shell ```shell
LD_LIBRARY_PATH="$(pwd)/osu.Desktop/bin/Debug/netcoreapp2.2" dotnet run --project osu.Desktop LD_LIBRARY_PATH="$(pwd)/osu.Desktop/bin/Debug/netcoreapp3.0" dotnet run --project osu.Desktop
``` ```
### Testing with resource/framework modifications ### Testing with resource/framework modifications

View File

@ -1,6 +1,6 @@
clone_depth: 1 clone_depth: 1
version: '{branch}-{build}' version: '{branch}-{build}'
image: Previous Visual Studio 2017 image: Visual Studio 2019 Preview
test: off test: off
build_script: build_script:
- cmd: PowerShell -Version 2.0 .\build.ps1 - cmd: PowerShell -Version 2.0 .\build.ps1

View File

@ -1,6 +1,6 @@
clone_depth: 1 clone_depth: 1
version: '{build}' version: '{build}'
image: Previous Visual Studio 2017 image: Visual Studio 2019 Preview
test: off test: off
skip_non_tags: true skip_non_tags: true
build_script: build_script:

63
build.ps1 Normal file → Executable file
View File

@ -1,39 +1,5 @@
##########################################################################
# This is a customized Cake bootstrapper script for PowerShell.
##########################################################################
<#
.SYNOPSIS
This is a Powershell script to bootstrap a Cake build.
.DESCRIPTION
This Powershell script restores NuGet tools (including Cake)
and execute your Cake build script with the parameters you provide.
.PARAMETER Script
The build script to execute.
.PARAMETER Target
The build script target to run.
.PARAMETER Configuration
The build configuration to use.
.PARAMETER Verbosity
Specifies the amount of information to be displayed.
.PARAMETER ShowDescription
Shows description about tasks.
.PARAMETER DryRun
Performs a dry run.
.PARAMETER ScriptArgs
Remaining arguments are added here.
.LINK
https://cakebuild.net
#>
[CmdletBinding()] [CmdletBinding()]
Param( Param(
[string]$Script = "build.cake",
[string]$Target, [string]$Target,
[string]$Configuration, [string]$Configuration,
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
@ -45,27 +11,8 @@ Param(
[string[]]$ScriptArgs [string[]]$ScriptArgs
) )
Write-Host "Preparing to run build script..."
# Determine the script root for resolving other paths.
if(!$PSScriptRoot) {
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
}
# Resolve the paths for resources used for debugging.
$BUILD_DIR = Join-Path $PSScriptRoot "build"
$TOOLS_DIR = Join-Path $BUILD_DIR "tools"
$CAKE_CSPROJ = Join-Path $BUILD_DIR "cakebuild.csproj"
# Install the required tools locally.
Write-Host "Restoring cake tools..."
Invoke-Expression "dotnet restore `"$CAKE_CSPROJ`" --packages `"$TOOLS_DIR`"" | Out-Null
# Find the Cake executable
$CAKE_EXECUTABLE = (Get-ChildItem -Path "$TOOLS_DIR/cake.coreclr/" -Filter Cake.dll -Recurse).FullName
# Build Cake arguments # Build Cake arguments
$cakeArguments = @("$Script"); $cakeArguments = "";
if ($Target) { $cakeArguments += "-target=$Target" } if ($Target) { $cakeArguments += "-target=$Target" }
if ($Configuration) { $cakeArguments += "-configuration=$Configuration" } if ($Configuration) { $cakeArguments += "-configuration=$Configuration" }
if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" } if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" }
@ -74,9 +21,7 @@ if ($DryRun) { $cakeArguments += "-dryrun" }
if ($Experimental) { $cakeArguments += "-experimental" } if ($Experimental) { $cakeArguments += "-experimental" }
$cakeArguments += $ScriptArgs $cakeArguments += $ScriptArgs
# Start Cake dotnet tool install Cake.Tool --global --version 0.35.0
Write-Host "Running build script..." dotnet cake ./build/build.cake --bootstrap
Push-Location -Path $BUILD_DIR dotnet cake ./build/build.cake $cakeArguments
Invoke-Expression "dotnet `"$CAKE_EXECUTABLE`" $cakeArguments"
Pop-Location
exit $LASTEXITCODE exit $LASTEXITCODE

View File

@ -1,18 +1,5 @@
#!/usr/bin/env bash echo "Installing Cake.Tool..."
dotnet tool install Cake.Tool --global --version 0.35.0
##########################################################################
# This is a customized Cake bootstrapper script for Shell.
##########################################################################
echo "Preparing to run build script..."
cd build
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
TOOLS_DIR=$SCRIPT_DIR/tools
CAKE_BINARY_PATH=$TOOLS_DIR/"cake.coreclr"
SCRIPT="build.cake"
CAKE_CSPROJ=$SCRIPT_DIR/"cakebuild.csproj"
# Parse arguments. # Parse arguments.
CAKE_ARGUMENTS=() CAKE_ARGUMENTS=()
@ -25,14 +12,6 @@ for i in "$@"; do
shift shift
done done
# Install the required tools locally.
echo "Restoring cake tools..."
dotnet restore $CAKE_CSPROJ --packages $TOOLS_DIR > /dev/null 2>&1
# Search for the CakeBuild binary.
CAKE_BINARY=$(find $CAKE_BINARY_PATH -name "Cake.dll")
# Start Cake
echo "Running build script..." echo "Running build script..."
dotnet cake ./build/build.cake --bootstrap
dotnet "$CAKE_BINARY" $SCRIPT "${CAKE_ARGUMENTS[@]}" dotnet cake ./build/build.cake "${CAKE_ARGUMENTS[@]}"

View File

@ -1,5 +1,5 @@
#addin "nuget:?package=CodeFileSanity&version=0.0.21" #addin "nuget:?package=CodeFileSanity&version=0.0.33"
#addin "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2019.1.1" #addin "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2019.2.1"
#tool "nuget:?package=NVika.MSBuild&version=1.0.1" #tool "nuget:?package=NVika.MSBuild&version=1.0.1"
var nVikaToolPath = GetFiles("./tools/NVika.MSBuild.*/tools/NVika.exe").First(); var nVikaToolPath = GetFiles("./tools/NVika.MSBuild.*/tools/NVika.exe").First();

View File

@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<PackAsTool>true</PackAsTool>
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Cake" Version="0.34.1" />
<PackageReference Include="Cake.CoreCLR" Version="0.34.1" />
</ItemGroup>
</Project>

View File

@ -61,7 +61,7 @@
<Reference Include="Java.Interop" /> <Reference Include="Java.Interop" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.913.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.930.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2019.1011.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\osu.Game.props" /> <Import Project="..\osu.Game.props" />
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>

View File

@ -7,7 +7,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll" "${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Catch.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug)", "preLaunchTask": "Build (Debug)",
@ -20,7 +20,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll" "${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Catch.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)", "preLaunchTask": "Build (Release)",

View File

@ -9,7 +9,7 @@
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Project References"> <ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />

View File

@ -7,7 +7,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll" "${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Mania.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug)", "preLaunchTask": "Build (Debug)",
@ -20,7 +20,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll" "${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Mania.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)", "preLaunchTask": "Build (Release)",

View File

@ -9,7 +9,7 @@
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Project References"> <ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />

View File

@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
public Vector2 ScreenSpaceDragPosition { get; private set; } public Vector2 ScreenSpaceDragPosition { get; private set; }
public Vector2 DragPosition { get; private set; } public Vector2 DragPosition { get; private set; }
protected new DrawableManiaHitObject HitObject => (DrawableManiaHitObject)base.HitObject; public new DrawableManiaHitObject HitObject => (DrawableManiaHitObject)base.HitObject;
protected IClock EditorClock { get; private set; } protected IClock EditorClock { get; private set; }

View File

@ -3,9 +3,7 @@
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Input.Events;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Edit.Blueprints; using osu.Game.Rulesets.Mania.Edit.Blueprints;
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
@ -31,13 +29,16 @@ namespace osu.Game.Rulesets.Mania.Edit
editorClock = clock; editorClock = clock;
} }
public override void HandleDrag(SelectionBlueprint blueprint, DragEvent dragEvent) public override void HandleMovement(MoveSelectionEvent moveEvent)
{ {
adjustOrigins((ManiaSelectionBlueprint)blueprint); var maniaBlueprint = (ManiaSelectionBlueprint)moveEvent.Blueprint;
performDragMovement(dragEvent); int lastColumn = maniaBlueprint.HitObject.HitObject.Column;
performColumnMovement(dragEvent);
base.HandleDrag(blueprint, dragEvent); adjustOrigins(maniaBlueprint);
performDragMovement(moveEvent);
performColumnMovement(lastColumn, moveEvent);
base.HandleMovement(moveEvent);
} }
/// <summary> /// <summary>
@ -62,7 +63,7 @@ namespace osu.Game.Rulesets.Mania.Edit
b.HitObject.Y += movementDelta; b.HitObject.Y += movementDelta;
} }
private void performDragMovement(DragEvent dragEvent) private void performDragMovement(MoveSelectionEvent moveEvent)
{ {
foreach (var b in SelectedBlueprints) foreach (var b in SelectedBlueprints)
{ {
@ -72,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.Edit
// Using the hitobject position is required since AdjustPosition can be invoked multiple times per frame // Using the hitobject position is required since AdjustPosition can be invoked multiple times per frame
// without the position having been updated by the parenting ScrollingHitObjectContainer // without the position having been updated by the parenting ScrollingHitObjectContainer
hitObject.Y += dragEvent.Delta.Y; hitObject.Y += moveEvent.InstantDelta.Y;
float targetPosition; float targetPosition;
@ -94,14 +95,13 @@ namespace osu.Game.Rulesets.Mania.Edit
} }
} }
private void performColumnMovement(DragEvent dragEvent) private void performColumnMovement(int lastColumn, MoveSelectionEvent moveEvent)
{ {
var lastColumn = composer.ColumnAt(dragEvent.ScreenSpaceLastMousePosition); var currentColumn = composer.ColumnAt(moveEvent.ScreenSpacePosition);
var currentColumn = composer.ColumnAt(dragEvent.ScreenSpaceMousePosition); if (currentColumn == null)
if (lastColumn == null || currentColumn == null)
return; return;
int columnDelta = currentColumn.Index - lastColumn.Index; int columnDelta = currentColumn.Index - lastColumn;
if (columnDelta == 0) if (columnDelta == 0)
return; return;

View File

@ -7,7 +7,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll" "${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Osu.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug)", "preLaunchTask": "Build (Debug)",
@ -20,7 +20,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll" "${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Osu.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)", "preLaunchTask": "Build (Release)",

View File

@ -9,7 +9,7 @@
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Project References"> <ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />

View File

@ -2,8 +2,6 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Linq; using System.Linq;
using osu.Framework.Input.Events;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components;
@ -11,7 +9,7 @@ namespace osu.Game.Rulesets.Osu.Edit
{ {
public class OsuSelectionHandler : SelectionHandler public class OsuSelectionHandler : SelectionHandler
{ {
public override void HandleDrag(SelectionBlueprint blueprint, DragEvent dragEvent) public override void HandleMovement(MoveSelectionEvent moveEvent)
{ {
foreach (var h in SelectedHitObjects.OfType<OsuHitObject>()) foreach (var h in SelectedHitObjects.OfType<OsuHitObject>())
{ {
@ -21,10 +19,10 @@ namespace osu.Game.Rulesets.Osu.Edit
continue; continue;
} }
h.Position += dragEvent.Delta; h.Position += moveEvent.InstantDelta;
} }
base.HandleDrag(blueprint, dragEvent); base.HandleMovement(moveEvent);
} }
} }
} }

View File

@ -7,7 +7,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll" "${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Taiko.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug)", "preLaunchTask": "Build (Debug)",
@ -20,7 +20,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll" "${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Taiko.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)", "preLaunchTask": "Build (Release)",

View File

@ -9,7 +9,7 @@
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Project References"> <ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />

View File

@ -29,7 +29,7 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportWhenClosed() public async Task TestImportWhenClosed()
{ {
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWhenClosed")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWhenClosed)))
{ {
try try
{ {
@ -46,7 +46,7 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportThenDelete() public async Task TestImportThenDelete()
{ {
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenDelete")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenDelete)))
{ {
try try
{ {
@ -67,7 +67,7 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportThenImport() public async Task TestImportThenImport()
{ {
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenImport")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImport)))
{ {
try try
{ {
@ -94,7 +94,7 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportCorruptThenImport() public async Task TestImportCorruptThenImport()
{ {
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenImport")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportCorruptThenImport)))
{ {
try try
{ {
@ -136,7 +136,7 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestRollbackOnFailure() public async Task TestRollbackOnFailure()
{ {
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestRollbackOnFailure")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestRollbackOnFailure)))
{ {
try try
{ {
@ -213,7 +213,7 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportThenImportDifferentHash() public async Task TestImportThenImportDifferentHash()
{ {
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenImportDifferentHash")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImportDifferentHash)))
{ {
try try
{ {
@ -244,7 +244,7 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportThenDeleteThenImport() public async Task TestImportThenDeleteThenImport()
{ {
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenDeleteThenImport")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenDeleteThenImport)))
{ {
try try
{ {
@ -272,7 +272,7 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportThenDeleteThenImportWithOnlineIDMismatch(bool set) public async Task TestImportThenDeleteThenImportWithOnlineIDMismatch(bool set)
{ {
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost($"TestImportThenDeleteThenImport-{set}")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost($"{nameof(TestImportThenDeleteThenImportWithOnlineIDMismatch)}-{set}"))
{ {
try try
{ {
@ -306,7 +306,7 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportWithDuplicateBeatmapIDs() public async Task TestImportWithDuplicateBeatmapIDs()
{ {
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWithDuplicateBeatmapID")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWithDuplicateBeatmapIDs)))
{ {
try try
{ {
@ -392,7 +392,7 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test] [Test]
public async Task TestImportWhenFileOpen() public async Task TestImportWhenFileOpen()
{ {
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWhenFileOpen")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWhenFileOpen)))
{ {
try try
{ {
@ -414,7 +414,7 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test] [Test]
public async Task TestImportNestedStructure() public async Task TestImportNestedStructure()
{ {
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportNestedStructure")) using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportNestedStructure)))
{ {
try try
{ {
@ -456,9 +456,63 @@ namespace osu.Game.Tests.Beatmaps.IO
} }
} }
public static async Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null) [Test]
public async Task TestImportWithIgnoredDirectoryInArchive()
{ {
var temp = path ?? TestResources.GetTestBeatmapForImport(); using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWithIgnoredDirectoryInArchive)))
{
try
{
var osu = loadOsu(host);
var temp = TestResources.GetTestBeatmapForImport();
string extractedFolder = $"{temp}_extracted";
string dataFolder = Path.Combine(extractedFolder, "actual_data");
string resourceForkFolder = Path.Combine(extractedFolder, "__MACOSX");
string resourceForkFilePath = Path.Combine(resourceForkFolder, ".extracted");
Directory.CreateDirectory(dataFolder);
Directory.CreateDirectory(resourceForkFolder);
using (var resourceForkFile = File.CreateText(resourceForkFilePath))
{
resourceForkFile.WriteLine("adding content so that it's not empty");
}
try
{
using (var zip = ZipArchive.Open(temp))
zip.WriteToDirectory(dataFolder);
using (var zip = ZipArchive.Create())
{
zip.AddAllFromDirectory(extractedFolder);
zip.SaveTo(temp, new ZipWriterOptions(CompressionType.Deflate));
}
var imported = await osu.Dependencies.Get<BeatmapManager>().Import(temp);
ensureLoaded(osu);
Assert.IsFalse(imported.Files.Any(f => f.Filename.Contains("__MACOSX")), "Files contain resource fork folder, which should be ignored");
Assert.IsFalse(imported.Files.Any(f => f.Filename.Contains("actual_data")), "Files contain common subfolder");
}
finally
{
Directory.Delete(extractedFolder, true);
}
}
finally
{
host.Exit();
}
}
}
public static async Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false)
{
var temp = path ?? TestResources.GetTestBeatmapForImport(virtualTrack);
var manager = osu.Dependencies.Get<BeatmapManager>(); var manager = osu.Dependencies.Get<BeatmapManager>();

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System;
using System.IO; using System.IO;
using System.Text; using System.Text;
using NUnit.Framework; using NUnit.Framework;
@ -14,9 +15,7 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test] [Test]
public void TestReadLineByLine() public void TestReadLineByLine()
{ {
const string contents = @"line 1 const string contents = "line 1\rline 2\nline 3";
line 2
line 3";
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents))) using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents)))
using (var bufferedReader = new LineBufferedReader(stream)) using (var bufferedReader = new LineBufferedReader(stream))
@ -31,9 +30,7 @@ line 3";
[Test] [Test]
public void TestPeekLineOnce() public void TestPeekLineOnce()
{ {
const string contents = @"line 1 const string contents = "line 1\r\npeek this\nline 3";
peek this
line 3";
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents))) using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents)))
using (var bufferedReader = new LineBufferedReader(stream)) using (var bufferedReader = new LineBufferedReader(stream))
@ -49,9 +46,7 @@ line 3";
[Test] [Test]
public void TestPeekLineMultipleTimes() public void TestPeekLineMultipleTimes()
{ {
const string contents = @"peek this once const string contents = "peek this once\nline 2\rpeek this a lot";
line 2
peek this a lot";
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents))) using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents)))
using (var bufferedReader = new LineBufferedReader(stream)) using (var bufferedReader = new LineBufferedReader(stream))
@ -70,8 +65,7 @@ peek this a lot";
[Test] [Test]
public void TestPeekLineAtEndOfStream() public void TestPeekLineAtEndOfStream()
{ {
const string contents = @"first line const string contents = "first line\r\nsecond line";
second line";
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents))) using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents)))
using (var bufferedReader = new LineBufferedReader(stream)) using (var bufferedReader = new LineBufferedReader(stream))
@ -100,8 +94,7 @@ second line";
[Test] [Test]
public void TestReadToEndNoPeeks() public void TestReadToEndNoPeeks()
{ {
const string contents = @"first line const string contents = "first line\r\nsecond line";
second line";
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents))) using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents)))
using (var bufferedReader = new LineBufferedReader(stream)) using (var bufferedReader = new LineBufferedReader(stream))
@ -113,20 +106,19 @@ second line";
[Test] [Test]
public void TestReadToEndAfterReadsAndPeeks() public void TestReadToEndAfterReadsAndPeeks()
{ {
const string contents = @"this line is gone const string contents = "this line is gone\rthis one shouldn't be\r\nthese ones\ndefinitely not";
this one shouldn't be
these ones
definitely not";
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents))) using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents)))
using (var bufferedReader = new LineBufferedReader(stream)) using (var bufferedReader = new LineBufferedReader(stream))
{ {
Assert.AreEqual("this line is gone", bufferedReader.ReadLine()); Assert.AreEqual("this line is gone", bufferedReader.ReadLine());
Assert.AreEqual("this one shouldn't be", bufferedReader.PeekLine()); Assert.AreEqual("this one shouldn't be", bufferedReader.PeekLine());
const string ending = @"this one shouldn't be
these ones var endingLines = bufferedReader.ReadToEnd().Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
definitely not"; Assert.AreEqual(3, endingLines.Length);
Assert.AreEqual(ending, bufferedReader.ReadToEnd()); Assert.AreEqual("this one shouldn't be", endingLines[0]);
Assert.AreEqual("these ones", endingLines[1]);
Assert.AreEqual("definitely not", endingLines[2]);
} }
} }
} }

View File

@ -11,13 +11,13 @@ namespace osu.Game.Tests.Resources
{ {
public static Stream OpenResource(string name) => new DllResourceStore("osu.Game.Tests.dll").GetStream($"Resources/{name}"); public static Stream OpenResource(string name) => new DllResourceStore("osu.Game.Tests.dll").GetStream($"Resources/{name}");
public static Stream GetTestBeatmapStream() => new DllResourceStore("osu.Game.Resources.dll").GetStream("Beatmaps/241526 Soleily - Renatus.osz"); public static Stream GetTestBeatmapStream(bool virtualTrack = false) => new DllResourceStore("osu.Game.Resources.dll").GetStream($"Beatmaps/241526 Soleily - Renatus{(virtualTrack ? "_virtual" : "")}.osz");
public static string GetTestBeatmapForImport() public static string GetTestBeatmapForImport(bool virtualTrack = false)
{ {
var temp = Path.GetTempFileName() + ".osz"; var temp = Path.GetTempFileName() + ".osz";
using (var stream = GetTestBeatmapStream()) using (var stream = GetTestBeatmapStream(virtualTrack))
using (var newFile = File.Create(temp)) using (var newFile = File.Create(temp))
stream.CopyTo(newFile); stream.CopyTo(newFile);

View File

@ -5,12 +5,15 @@ using System;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API; using osu.Game.Online.API;
@ -18,7 +21,9 @@ using osu.Game.Overlays;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Screens; using osu.Game.Screens;
using osu.Game.Screens.Menu; using osu.Game.Screens.Menu;
using osu.Game.Screens.Play;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
using osu.Game.Tests.Beatmaps.IO;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
using osuTK.Input; using osuTK.Input;
@ -31,11 +36,11 @@ namespace osu.Game.Tests.Visual.Menus
private const float click_padding = 25; private const float click_padding = 25;
private GameHost host; private GameHost host;
private TestOsuGame osuGame; private TestOsuGame game;
private Vector2 backButtonPosition => osuGame.ToScreenSpace(new Vector2(click_padding, osuGame.LayoutRectangle.Bottom - click_padding)); private Vector2 backButtonPosition => game.ToScreenSpace(new Vector2(click_padding, game.LayoutRectangle.Bottom - click_padding));
private Vector2 optionsButtonPosition => osuGame.ToScreenSpace(new Vector2(click_padding, click_padding)); private Vector2 optionsButtonPosition => game.ToScreenSpace(new Vector2(click_padding, click_padding));
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host) private void load(GameHost host)
@ -54,23 +59,23 @@ namespace osu.Game.Tests.Visual.Menus
{ {
AddStep("Create new game instance", () => AddStep("Create new game instance", () =>
{ {
if (osuGame != null) if (game != null)
{ {
Remove(osuGame); Remove(game);
osuGame.Dispose(); game.Dispose();
} }
osuGame = new TestOsuGame(LocalStorage, API); game = new TestOsuGame(LocalStorage, API);
osuGame.SetHost(host); game.SetHost(host);
// todo: this can be removed once we can run audio trakcs without a device present // todo: this can be removed once we can run audio trakcs without a device present
// see https://github.com/ppy/osu/issues/1302 // see https://github.com/ppy/osu/issues/1302
osuGame.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles); game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles);
Add(osuGame); Add(game);
}); });
AddUntilStep("Wait for load", () => osuGame.IsLoaded); AddUntilStep("Wait for load", () => game.IsLoaded);
AddUntilStep("Wait for intro", () => osuGame.ScreenStack.CurrentScreen is IntroScreen); AddUntilStep("Wait for intro", () => game.ScreenStack.CurrentScreen is IntroScreen);
confirmAtMainMenu(); confirmAtMainMenu();
} }
@ -82,11 +87,43 @@ namespace osu.Game.Tests.Visual.Menus
pushAndConfirm(() => songSelect = new TestSongSelect()); pushAndConfirm(() => songSelect = new TestSongSelect());
AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show()); AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show());
AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible); AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
AddStep("Press escape", () => pressAndRelease(Key.Escape)); pushEscape();
AddAssert("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden); AddAssert("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden);
exitViaEscapeAndConfirm(); exitViaEscapeAndConfirm();
} }
[TestCase(true)]
[TestCase(false)]
public void TestSongContinuesAfterExitPlayer(bool withUserPause)
{
Player player = null;
WorkingBeatmap beatmap() => game.Beatmap.Value;
Track track() => beatmap().Track;
pushAndConfirm(() => new TestSongSelect());
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Wait());
AddUntilStep("wait for selected", () => !game.Beatmap.IsDefault);
if (withUserPause)
AddStep("pause", () => game.Dependencies.Get<MusicController>().Stop());
AddStep("press enter", () => pressAndRelease(Key.Enter));
AddUntilStep("wait for player", () => (player = game.ScreenStack.CurrentScreen as Player) != null);
AddUntilStep("wait for fail", () => player.HasFailed);
AddUntilStep("wait for track stop", () => !track().IsRunning);
AddAssert("Ensure time before preview point", () => track().CurrentTime < beatmap().Metadata.PreviewTime);
pushEscape();
AddUntilStep("wait for track playing", () => track().IsRunning);
AddAssert("Ensure time wasn't reset to preview point", () => track().CurrentTime < beatmap().Metadata.PreviewTime);
}
[Test] [Test]
public void TestExitSongSelectWithClick() public void TestExitSongSelectWithClick()
{ {
@ -98,7 +135,7 @@ namespace osu.Game.Tests.Visual.Menus
AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition)); AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition));
// BackButton handles hover using its child button, so this checks whether or not any of BackButton's children are hovered. // BackButton handles hover using its child button, so this checks whether or not any of BackButton's children are hovered.
AddUntilStep("Back button is hovered", () => InputManager.HoveredDrawables.Any(d => d.Parent == osuGame.BackButton)); AddUntilStep("Back button is hovered", () => InputManager.HoveredDrawables.Any(d => d.Parent == game.BackButton));
AddStep("Click back button", () => InputManager.Click(MouseButton.Left)); AddStep("Click back button", () => InputManager.Click(MouseButton.Left));
AddUntilStep("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden); AddUntilStep("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden);
@ -122,25 +159,28 @@ namespace osu.Game.Tests.Visual.Menus
[Test] [Test]
public void TestOpenOptionsAndExitWithEscape() public void TestOpenOptionsAndExitWithEscape()
{ {
AddUntilStep("Wait for options to load", () => osuGame.Settings.IsLoaded); AddUntilStep("Wait for options to load", () => game.Settings.IsLoaded);
AddStep("Enter menu", () => pressAndRelease(Key.Enter)); AddStep("Enter menu", () => pressAndRelease(Key.Enter));
AddStep("Move mouse to options overlay", () => InputManager.MoveMouseTo(optionsButtonPosition)); AddStep("Move mouse to options overlay", () => InputManager.MoveMouseTo(optionsButtonPosition));
AddStep("Click options overlay", () => InputManager.Click(MouseButton.Left)); AddStep("Click options overlay", () => InputManager.Click(MouseButton.Left));
AddAssert("Options overlay was opened", () => osuGame.Settings.State.Value == Visibility.Visible); AddAssert("Options overlay was opened", () => game.Settings.State.Value == Visibility.Visible);
AddStep("Hide options overlay using escape", () => pressAndRelease(Key.Escape)); AddStep("Hide options overlay using escape", () => pressAndRelease(Key.Escape));
AddAssert("Options overlay was closed", () => osuGame.Settings.State.Value == Visibility.Hidden); AddAssert("Options overlay was closed", () => game.Settings.State.Value == Visibility.Hidden);
} }
private void pushAndConfirm(Func<Screen> newScreen) private void pushAndConfirm(Func<Screen> newScreen)
{ {
Screen screen = null; Screen screen = null;
AddStep("Push new screen", () => osuGame.ScreenStack.Push(screen = newScreen())); AddStep("Push new screen", () => game.ScreenStack.Push(screen = newScreen()));
AddUntilStep("Wait for new screen", () => osuGame.ScreenStack.CurrentScreen == screen && screen.IsLoaded); AddUntilStep("Wait for new screen", () => game.ScreenStack.CurrentScreen == screen && screen.IsLoaded);
} }
private void pushEscape() =>
AddStep("Press escape", () => pressAndRelease(Key.Escape));
private void exitViaEscapeAndConfirm() private void exitViaEscapeAndConfirm()
{ {
AddStep("Press escape", () => pressAndRelease(Key.Escape)); pushEscape();
confirmAtMainMenu(); confirmAtMainMenu();
} }
@ -151,7 +191,7 @@ namespace osu.Game.Tests.Visual.Menus
confirmAtMainMenu(); confirmAtMainMenu();
} }
private void confirmAtMainMenu() => AddUntilStep("Wait for main menu", () => osuGame.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded); private void confirmAtMainMenu() => AddUntilStep("Wait for main menu", () => game.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded);
private void pressAndRelease(Key key) private void pressAndRelease(Key key)
{ {
@ -169,6 +209,8 @@ namespace osu.Game.Tests.Visual.Menus
public new OsuConfigManager LocalConfig => base.LocalConfig; public new OsuConfigManager LocalConfig => base.LocalConfig;
public new Bindable<WorkingBeatmap> Beatmap => base.Beatmap;
protected override Loader CreateLoader() => new TestLoader(); protected override Loader CreateLoader() => new TestLoader();
public TestOsuGame(Storage storage, IAPIProvider api) public TestOsuGame(Storage storage, IAPIProvider api)

View File

@ -10,7 +10,7 @@
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Project References"> <ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />

View File

@ -11,7 +11,7 @@
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Project References"> <ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />

View File

@ -1,15 +1,30 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using SharpCompress.Archives.Zip; using SharpCompress.Archives.Zip;
using SharpCompress.Common;
namespace osu.Game.IO.Archives namespace osu.Game.IO.Archives
{ {
public sealed class ZipArchiveReader : ArchiveReader public sealed class ZipArchiveReader : ArchiveReader
{ {
/// <summary>
/// List of substrings that indicate a file should be ignored during the import process
/// (usually due to representing no useful data and being autogenerated by the OS).
/// </summary>
private static readonly string[] filename_ignore_list =
{
// Mac-specific
"__MACOSX",
".DS_Store",
// Windows-specific
"Thumbs.db"
};
private readonly Stream archiveStream; private readonly Stream archiveStream;
private readonly ZipArchive archive; private readonly ZipArchive archive;
@ -43,7 +58,9 @@ namespace osu.Game.IO.Archives
archiveStream.Dispose(); archiveStream.Dispose();
} }
public override IEnumerable<string> Filenames => archive.Entries.Select(e => e.Key).ToArray(); private static bool canBeIgnored(IEntry entry) => filename_ignore_list.Any(ignoredName => entry.Key.IndexOf(ignoredName, StringComparison.OrdinalIgnoreCase) >= 0);
public override IEnumerable<string> Filenames => archive.Entries.Where(e => !canBeIgnored(e)).Select(e => e.Key).ToArray();
public override Stream GetUnderlyingStream() => archiveStream; public override Stream GetUnderlyingStream() => archiveStream;
} }

View File

@ -1,12 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API.Requests namespace osu.Game.Online.API.Requests
{ {
public class GetUsersRequest : APIRequest<List<APIUser>> public class GetUsersRequest : APIRequest<GetUsersResponse>
{ {
protected override string Target => @"rankings/osu/performance"; protected override string Target => @"rankings/osu/performance";
} }

View File

@ -0,0 +1,15 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API.Requests
{
public class GetUsersResponse : ResponseWithCursor
{
[JsonProperty("ranking")]
public List<APIUser> Users;
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using Newtonsoft.Json;
namespace osu.Game.Online.API.Requests
{
public abstract class ResponseWithCursor
{
/// <summary>
/// A collection of parameters which should be passed to the search endpoint to fetch the next page.
/// </summary>
[JsonProperty("cursor")]
public dynamic CursorJson;
}
}

View File

@ -2,19 +2,12 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API.Requests namespace osu.Game.Online.API.Requests
{ {
public class SearchBeatmapSetsResponse public class SearchBeatmapSetsResponse : ResponseWithCursor
{ {
public IEnumerable<APIBeatmapSet> BeatmapSets; public IEnumerable<APIBeatmapSet> BeatmapSets;
/// <summary>
/// A collection of parameters which should be passed to the search endpoint to fetch the next page.
/// </summary>
[JsonProperty("cursor")]
public dynamic CursorJson;
} }
} }

View File

@ -98,20 +98,13 @@ namespace osu.Game.Overlays
/// <summary> /// <summary>
/// Start playing the current track (if not already playing). /// Start playing the current track (if not already playing).
/// </summary> /// </summary>
public void Play()
{
if (!IsPlaying)
TogglePause();
}
/// <summary>
/// Toggle pause / play.
/// </summary>
/// <returns>Whether the operation was successful.</returns> /// <returns>Whether the operation was successful.</returns>
public bool TogglePause() public bool Play(bool restart = false)
{ {
var track = current?.Track; var track = current?.Track;
IsUserPaused = false;
if (track == null) if (track == null)
{ {
if (beatmap.Disabled) if (beatmap.Disabled)
@ -121,16 +114,38 @@ namespace osu.Game.Overlays
return true; return true;
} }
if (track.IsRunning) if (restart)
track.Restart();
else if (!IsPlaying)
track.Start();
return true;
}
/// <summary>
/// Stop playing the current track and pause at the current position.
/// </summary>
public void Stop()
{ {
var track = current?.Track;
IsUserPaused = true; IsUserPaused = true;
if (track?.IsRunning == true)
track.Stop(); track.Stop();
} }
else
/// <summary>
/// Toggle pause / play.
/// </summary>
/// <returns>Whether the operation was successful.</returns>
public bool TogglePause()
{ {
track.Start(); var track = current?.Track;
IsUserPaused = false;
} if (track?.IsRunning == true)
Stop();
else
Play();
return true; return true;
} }

View File

@ -118,7 +118,7 @@ namespace osu.Game.Overlays
default: default:
var userRequest = new GetUsersRequest(); // TODO filter arguments! var userRequest = new GetUsersRequest(); // TODO filter arguments!
userRequest.Success += response => updateUsers(response.Select(r => r.User)); userRequest.Success += res => updateUsers(res.Users.Select(r => r.User));
API.Queue(getUsersRequest = userRequest); API.Queue(getUsersRequest = userRequest);
break; break;
} }

View File

@ -45,6 +45,11 @@ namespace osu.Game.Rulesets.Edit
/// </summary> /// </summary>
public readonly DrawableHitObject HitObject; public readonly DrawableHitObject HitObject;
/// <summary>
/// The screen-space position of <see cref="HitObject"/> prior to handling a movement event.
/// </summary>
internal Vector2 ScreenSpaceMovementStartPosition { get; private set; }
protected override bool ShouldBeAlive => (HitObject.IsAlive && HitObject.IsPresent) || State == SelectionState.Selected; protected override bool ShouldBeAlive => (HitObject.IsAlive && HitObject.IsPresent) || State == SelectionState.Selected;
public override bool HandlePositionalInput => ShouldBeAlive; public override bool HandlePositionalInput => ShouldBeAlive;
public override bool RemoveWhenNotAlive => false; public override bool RemoveWhenNotAlive => false;
@ -131,7 +136,11 @@ namespace osu.Game.Rulesets.Edit
return base.OnClick(e); return base.OnClick(e);
} }
protected override bool OnDragStart(DragStartEvent e) => true; protected override bool OnDragStart(DragStartEvent e)
{
ScreenSpaceMovementStartPosition = HitObject.ToScreenSpace(HitObject.OriginPosition);
return true;
}
protected override bool OnDrag(DragEvent e) protected override bool OnDrag(DragEvent e)
{ {

View File

@ -216,7 +216,12 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void onSelectionRequested(SelectionBlueprint blueprint, InputState state) => selectionHandler.HandleSelectionRequested(blueprint, state); private void onSelectionRequested(SelectionBlueprint blueprint, InputState state) => selectionHandler.HandleSelectionRequested(blueprint, state);
private void onDragRequested(SelectionBlueprint blueprint, DragEvent dragEvent) => selectionHandler.HandleDrag(blueprint, dragEvent); private void onDragRequested(SelectionBlueprint blueprint, DragEvent dragEvent)
{
var movePosition = blueprint.ScreenSpaceMovementStartPosition + dragEvent.ScreenSpaceMousePosition - dragEvent.ScreenSpaceMouseDownPosition;
selectionHandler.HandleMovement(new MoveSelectionEvent(blueprint, blueprint.ScreenSpaceMovementStartPosition, movePosition));
}
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {

View File

@ -0,0 +1,46 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Edit;
using osuTK;
namespace osu.Game.Screens.Edit.Compose.Components
{
/// <summary>
/// An event which occurs when a <see cref="SelectionBlueprint"/> is moved.
/// </summary>
public class MoveSelectionEvent
{
/// <summary>
/// The <see cref="SelectionBlueprint"/> that triggered this <see cref="MoveSelectionEvent"/>.
/// </summary>
public readonly SelectionBlueprint Blueprint;
/// <summary>
/// The starting screen-space position of the hitobject.
/// </summary>
public readonly Vector2 ScreenSpaceStartPosition;
/// <summary>
/// The expected screen-space position of the hitobject at the current cursor position.
/// </summary>
public readonly Vector2 ScreenSpacePosition;
/// <summary>
/// The distance between <see cref="ScreenSpacePosition"/> and the hitobject's current position, in the coordinate-space of the hitobject's parent.
/// </summary>
/// <remarks>
/// This does not use <see cref="ScreenSpaceStartPosition"/> and does not represent the cumulative movement distance.
/// </remarks>
public readonly Vector2 InstantDelta;
public MoveSelectionEvent(SelectionBlueprint blueprint, Vector2 screenSpaceStartPosition, Vector2 screenSpacePosition)
{
Blueprint = blueprint;
ScreenSpaceStartPosition = screenSpaceStartPosition;
ScreenSpacePosition = screenSpacePosition;
InstantDelta = Blueprint.HitObject.Parent.ToLocalSpace(ScreenSpacePosition) - Blueprint.HitObject.Position;
}
}
}

View File

@ -65,11 +65,10 @@ namespace osu.Game.Screens.Edit.Compose.Components
#region User Input Handling #region User Input Handling
/// <summary> /// <summary>
/// Handles the selected <see cref="DrawableHitObject"/>s being dragged. /// Handles the selected <see cref="DrawableHitObject"/>s being moved.
/// </summary> /// </summary>
/// <param name="blueprint">The <see cref="SelectionBlueprint"/> that received the drag event.</param> /// <param name="moveEvent">The move event.</param>
/// <param name="dragEvent">The drag event.</param> public virtual void HandleMovement(MoveSelectionEvent moveEvent)
public virtual void HandleDrag(SelectionBlueprint blueprint, DragEvent dragEvent)
{ {
} }

View File

@ -2,87 +2,42 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample; using osu.Framework.Audio.Sample;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.IO.Archives;
namespace osu.Game.Screens.Menu namespace osu.Game.Screens.Menu
{ {
public class IntroCircles : IntroScreen public class IntroCircles : IntroScreen
{ {
private const string menu_music_beatmap_hash = "3c8b1fcc9434dbb29e2fb613d3b9eada9d7bb6c125ceb32396c3b53437280c83"; protected override string BeatmapHash => "3c8b1fcc9434dbb29e2fb613d3b9eada9d7bb6c125ceb32396c3b53437280c83";
private SampleChannel welcome; protected override string BeatmapFile => "circles.osz";
private Bindable<bool> menuMusic;
private Track track;
private WorkingBeatmap introBeatmap;
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game, ISampleStore samples)
{
menuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic);
BeatmapSetInfo setInfo = null;
if (!menuMusic.Value)
{
var sets = beatmaps.GetAllUsableBeatmapSets();
if (sets.Count > 0)
setInfo = beatmaps.QueryBeatmapSet(s => s.ID == sets[RNG.Next(0, sets.Count - 1)].ID);
}
if (setInfo == null)
{
setInfo = beatmaps.QueryBeatmapSet(b => b.Hash == menu_music_beatmap_hash);
if (setInfo == null)
{
// we need to import the default menu background beatmap
setInfo = beatmaps.Import(new ZipArchiveReader(game.Resources.GetStream(@"Tracks/circles.osz"), "circles.osz")).Result;
setInfo.Protected = true;
beatmaps.Update(setInfo);
}
}
introBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
track = introBeatmap.Track;
if (config.Get<bool>(OsuSetting.MenuVoice))
welcome = samples.Get(@"welcome");
}
private const double delay_step_one = 2300; private const double delay_step_one = 2300;
private const double delay_step_two = 600; private const double delay_step_two = 600;
private SampleChannel welcome;
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
if (MenuVoice.Value)
welcome = audio.Samples.Get(@"welcome");
}
protected override void LogoArriving(OsuLogo logo, bool resuming) protected override void LogoArriving(OsuLogo logo, bool resuming)
{ {
base.LogoArriving(logo, resuming); base.LogoArriving(logo, resuming);
if (!resuming) if (!resuming)
{ {
Beatmap.Value = introBeatmap;
introBeatmap = null;
welcome?.Play(); welcome?.Play();
Scheduler.AddDelayed(delegate Scheduler.AddDelayed(delegate
{ {
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu. StartTrack();
if (menuMusic.Value)
{
track.Restart();
track = null;
}
PrepareMenuLoad(); PrepareMenuLoad();
@ -97,8 +52,6 @@ namespace osu.Game.Screens.Menu
public override void OnSuspending(IScreen next) public override void OnSuspending(IScreen next)
{ {
track = null;
this.FadeOut(300); this.FadeOut(300);
base.OnSuspending(next); base.OnSuspending(next);
} }

View File

@ -4,12 +4,16 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Audio.Sample; using osu.Framework.Audio.Sample;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.MathUtils;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.IO.Archives;
using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Backgrounds;
using osu.Game.Skinning;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -17,51 +21,90 @@ namespace osu.Game.Screens.Menu
{ {
public abstract class IntroScreen : StartupScreen public abstract class IntroScreen : StartupScreen
{ {
private readonly BindableDouble exitingVolumeFade = new BindableDouble(1);
public const int EXIT_DELAY = 3000;
[Resolved]
private AudioManager audio { get; set; }
private SampleChannel seeya;
private Bindable<bool> menuVoice;
private LeasedBindable<WorkingBeatmap> beatmap;
public new Bindable<WorkingBeatmap> Beatmap => beatmap;
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBlack();
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game)
{
// prevent user from changing beatmap while the intro is still runnning.
beatmap = base.Beatmap.BeginLease(false);
menuVoice = config.GetBindable<bool>(OsuSetting.MenuVoice);
seeya = audio.Samples.Get(@"seeya");
}
/// <summary> /// <summary>
/// Whether we have loaded the menu previously. /// Whether we have loaded the menu previously.
/// </summary> /// </summary>
public bool DidLoadMenu { get; private set; } public bool DidLoadMenu { get; private set; }
public override bool OnExiting(IScreen next) /// <summary>
/// A hash used to find the associated beatmap if already imported.
/// </summary>
protected abstract string BeatmapHash { get; }
/// <summary>
/// A source file to use as an import source if the intro beatmap is not yet present.
/// Should be within the "Tracks" namespace of game resources.
/// </summary>
protected abstract string BeatmapFile { get; }
protected IBindable<bool> MenuVoice { get; private set; }
protected IBindable<bool> MenuMusic { get; private set; }
private WorkingBeatmap introBeatmap;
protected Track Track { get; private set; }
private readonly BindableDouble exitingVolumeFade = new BindableDouble(1);
private const int exit_delay = 3000;
private SampleChannel seeya;
private LeasedBindable<WorkingBeatmap> beatmap;
private MainMenu mainMenu;
[Resolved]
private AudioManager audio { get; set; }
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, SkinManager skinManager, BeatmapManager beatmaps, Framework.Game game)
{ {
//cancel exiting if we haven't loaded the menu yet. // prevent user from changing beatmap while the intro is still runnning.
return !DidLoadMenu; beatmap = Beatmap.BeginLease(false);
MenuVoice = config.GetBindable<bool>(OsuSetting.MenuVoice);
MenuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic);
seeya = audio.Samples.Get(@"seeya");
BeatmapSetInfo setInfo = null;
if (!MenuMusic.Value)
{
var sets = beatmaps.GetAllUsableBeatmapSets();
if (sets.Count > 0)
setInfo = beatmaps.QueryBeatmapSet(s => s.ID == sets[RNG.Next(0, sets.Count - 1)].ID);
} }
if (setInfo == null)
{
setInfo = beatmaps.QueryBeatmapSet(b => b.Hash == BeatmapHash);
if (setInfo == null)
{
// we need to import the default menu background beatmap
setInfo = beatmaps.Import(new ZipArchiveReader(game.Resources.GetStream($"Tracks/{BeatmapFile}"), BeatmapFile)).Result;
setInfo.Protected = true;
beatmaps.Update(setInfo);
}
}
introBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
Track = introBeatmap.Track;
}
public override bool OnExiting(IScreen next) => !DidLoadMenu;
public override void OnResuming(IScreen last) public override void OnResuming(IScreen last)
{ {
this.FadeIn(300); this.FadeIn(300);
double fadeOutTime = EXIT_DELAY; double fadeOutTime = exit_delay;
//we also handle the exit transition. //we also handle the exit transition.
if (menuVoice.Value) if (MenuVoice.Value)
seeya.Play(); seeya.Play();
else else
fadeOutTime = 500; fadeOutTime = 500;
@ -75,6 +118,21 @@ namespace osu.Game.Screens.Menu
base.OnResuming(last); base.OnResuming(last);
} }
public override void OnSuspending(IScreen next)
{
base.OnSuspending(next);
Track = null;
}
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBlack();
protected void StartTrack()
{
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu.
if (MenuMusic.Value)
Track.Restart();
}
protected override void LogoArriving(OsuLogo logo, bool resuming) protected override void LogoArriving(OsuLogo logo, bool resuming)
{ {
base.LogoArriving(logo, resuming); base.LogoArriving(logo, resuming);
@ -85,6 +143,9 @@ namespace osu.Game.Screens.Menu
if (!resuming) if (!resuming)
{ {
beatmap.Value = introBeatmap;
introBeatmap = null;
logo.MoveTo(new Vector2(0.5f)); logo.MoveTo(new Vector2(0.5f));
logo.ScaleTo(Vector2.One); logo.ScaleTo(Vector2.One);
logo.Hide(); logo.Hide();
@ -92,7 +153,7 @@ namespace osu.Game.Screens.Menu
else else
{ {
const int quick_appear = 350; const int quick_appear = 350;
int initialMovementTime = logo.Alpha > 0.2f ? quick_appear : 0; var initialMovementTime = logo.Alpha > 0.2f ? quick_appear : 0;
logo.MoveTo(new Vector2(0.5f), initialMovementTime, Easing.OutQuint); logo.MoveTo(new Vector2(0.5f), initialMovementTime, Easing.OutQuint);
@ -100,17 +161,12 @@ namespace osu.Game.Screens.Menu
.ScaleTo(1, initialMovementTime, Easing.OutQuint) .ScaleTo(1, initialMovementTime, Easing.OutQuint)
.FadeIn(quick_appear, Easing.OutQuint) .FadeIn(quick_appear, Easing.OutQuint)
.Then() .Then()
.RotateTo(20, EXIT_DELAY * 1.5f) .RotateTo(20, exit_delay * 1.5f)
.FadeOut(EXIT_DELAY); .FadeOut(exit_delay);
} }
} }
private MainMenu mainMenu; protected void PrepareMenuLoad() => LoadComponentAsync(mainMenu = new MainMenu());
protected void PrepareMenuLoad()
{
LoadComponentAsync(mainMenu = new MainMenu());
}
protected void LoadMenu() protected void LoadMenu()
{ {

View File

@ -7,8 +7,6 @@ using System.IO;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Audio.Sample; using osu.Framework.Audio.Sample;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -17,12 +15,9 @@ using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Video; using osu.Framework.Graphics.Video;
using osu.Framework.MathUtils; using osu.Framework.MathUtils;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.IO.Archives;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Backgrounds;
using osuTK; using osuTK;
@ -32,9 +27,9 @@ namespace osu.Game.Screens.Menu
{ {
public class IntroTriangles : IntroScreen public class IntroTriangles : IntroScreen
{ {
private const string menu_music_beatmap_hash = "a1556d0801b3a6b175dda32ef546f0ec812b400499f575c44fccbe9c67f9b1e5"; protected override string BeatmapHash => "a1556d0801b3a6b175dda32ef546f0ec812b400499f575c44fccbe9c67f9b1e5";
private SampleChannel welcome; protected override string BeatmapFile => "triangles.osz";
protected override BackgroundScreen CreateBackground() => background = new BackgroundScreenDefault(false) protected override BackgroundScreen CreateBackground() => background = new BackgroundScreenDefault(false)
{ {
@ -44,47 +39,14 @@ namespace osu.Game.Screens.Menu
[Resolved] [Resolved]
private AudioManager audio { get; set; } private AudioManager audio { get; set; }
private Bindable<bool> menuMusic;
private Track track;
private WorkingBeatmap introBeatmap;
private BackgroundScreenDefault background; private BackgroundScreenDefault background;
private SampleChannel welcome;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game) private void load(AudioManager audio)
{ {
menuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic); if (MenuVoice.Value && !MenuMusic.Value)
BeatmapSetInfo setInfo = null;
if (!menuMusic.Value)
{
var sets = beatmaps.GetAllUsableBeatmapSets();
if (sets.Count > 0)
setInfo = beatmaps.QueryBeatmapSet(s => s.ID == sets[RNG.Next(0, sets.Count - 1)].ID);
}
if (setInfo == null)
{
setInfo = beatmaps.QueryBeatmapSet(b => b.Hash == menu_music_beatmap_hash);
if (setInfo == null)
{
// we need to import the default menu background beatmap
setInfo = beatmaps.Import(new ZipArchiveReader(game.Resources.GetStream(@"Tracks/triangles.osz"), "triangles.osz")).Result;
setInfo.Protected = true;
beatmaps.Update(setInfo);
}
}
introBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
track = introBeatmap.Track;
track.Reset();
if (config.Get<bool>(OsuSetting.MenuVoice) && !menuMusic.Value)
// triangles has welcome sound included in the track. only play this if the user doesn't want menu music.
welcome = audio.Samples.Get(@"welcome"); welcome = audio.Samples.Get(@"welcome");
} }
@ -96,24 +58,19 @@ namespace osu.Game.Screens.Menu
if (!resuming) if (!resuming)
{ {
Beatmap.Value = introBeatmap;
introBeatmap = null;
PrepareMenuLoad(); PrepareMenuLoad();
LoadComponentAsync(new TrianglesIntroSequence(logo, background) LoadComponentAsync(new TrianglesIntroSequence(logo, background)
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Clock = new FramedClock(menuMusic.Value ? track : null), Clock = new FramedClock(MenuMusic.Value ? Track : null),
LoadMenu = LoadMenu LoadMenu = LoadMenu
}, t => }, t =>
{ {
AddInternal(t); AddInternal(t);
welcome?.Play(); welcome?.Play();
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu. StartTrack();
if (menuMusic.Value)
track.Start();
}); });
} }
} }
@ -124,12 +81,6 @@ namespace osu.Game.Screens.Menu
background.FadeOut(100); background.FadeOut(100);
} }
public override void OnSuspending(IScreen next)
{
track = null;
base.OnSuspending(next);
}
private class TrianglesIntroSequence : CompositeDrawable private class TrianglesIntroSequence : CompositeDrawable
{ {
private readonly OsuLogo logo; private readonly OsuLogo logo;

View File

@ -66,11 +66,7 @@ namespace osu.Game.Screens.Select
/// </summary> /// </summary>
protected readonly Container FooterPanels; protected readonly Container FooterPanels;
protected override BackgroundScreen CreateBackground() protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap();
{
var background = new BackgroundScreenBeatmap();
return background;
}
protected readonly BeatmapCarousel Carousel; protected readonly BeatmapCarousel Carousel;
private readonly BeatmapInfoWedge beatmapInfoWedge; private readonly BeatmapInfoWedge beatmapInfoWedge;
@ -490,7 +486,9 @@ namespace osu.Game.Screens.Select
if (Beatmap != null && !Beatmap.Value.BeatmapSetInfo.DeletePending) if (Beatmap != null && !Beatmap.Value.BeatmapSetInfo.DeletePending)
{ {
UpdateBeatmap(Beatmap.Value); UpdateBeatmap(Beatmap.Value);
ensurePlayingSelected();
// restart playback on returning to song select, regardless.
music?.Play();
} }
base.OnResuming(last); base.OnResuming(last);
@ -596,7 +594,7 @@ namespace osu.Game.Screens.Select
track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; track.RestartPoint = Beatmap.Value.Metadata.PreviewTime;
if (!track.IsRunning && (music?.IsUserPaused != true || isNewTrack)) if (!track.IsRunning && (music?.IsUserPaused != true || isNewTrack))
track.Restart(); music?.Play(true);
lastTrack.SetTarget(track); lastTrack.SetTarget(track);
} }

View File

@ -25,8 +25,8 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.913.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.930.0" /> <PackageReference Include="ppy.osu.Framework" Version="2019.1011.0" />
<PackageReference Include="SharpCompress" Version="0.24.0" /> <PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />

View File

@ -117,13 +117,13 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.913.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.930.0" /> <PackageReference Include="ppy.osu.Framework" Version="2019.1011.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.930.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2019.1011.0" />
<PackageReference Include="SharpCompress" Version="0.24.0" /> <PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.11.0" /> <PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.6.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="4.6.0" />
<PackageReference Include="ppy.osu.Framework.NativeLibs" Version="2019.813.0" ExcludeAssets="all" /> <PackageReference Include="ppy.osu.Framework.NativeLibs" Version="2019.1010.0" ExcludeAssets="all" />
</ItemGroup> </ItemGroup>
</Project> </Project>