1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-07 23:23:12 +08:00

Merge branch 'master' into input-settings

This commit is contained in:
Bartłomiej Dach 2022-06-20 22:53:32 +02:00
commit ee96d84ffa
No known key found for this signature in database
GPG Key ID: BCECCD4FA41F6497
3615 changed files with 43608 additions and 15265 deletions

View File

@ -2,14 +2,8 @@
"version": 1, "version": 1,
"isRoot": true, "isRoot": true,
"tools": { "tools": {
"dotnet-format": {
"version": "3.1.37601",
"commands": [
"dotnet-format"
]
},
"jetbrains.resharper.globaltools": { "jetbrains.resharper.globaltools": {
"version": "2020.3.2", "version": "2022.1.1",
"commands": [ "commands": [
"jb" "jb"
] ]
@ -27,7 +21,7 @@
] ]
}, },
"ppy.localisationanalyser.tools": { "ppy.localisationanalyser.tools": {
"version": "2021.1210.0", "version": "2022.607.0",
"commands": [ "commands": [
"localisation" "localisation"
] ]

View File

@ -1,6 +1,14 @@
# EditorConfig is awesome: http://editorconfig.org # EditorConfig is awesome: http://editorconfig.org
root = true root = true
[*.{csproj,props,targets}]
charset = utf-8-bom
end_of_line = crlf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
[*.cs] [*.cs]
end_of_line = crlf end_of_line = crlf
insert_final_newline = true insert_final_newline = true
@ -8,8 +16,19 @@ indent_style = space
indent_size = 4 indent_size = 4
trim_trailing_whitespace = true trim_trailing_whitespace = true
#license header
file_header_template = Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\nSee the LICENCE file in the repository root for full licence text.
#Roslyn naming styles #Roslyn naming styles
#PascalCase for public and protected members
dotnet_naming_style.pascalcase.capitalization = pascal_case
dotnet_naming_symbols.public_members.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
dotnet_naming_symbols.public_members.applicable_kinds = property,method,field,event
dotnet_naming_rule.public_members_pascalcase.severity = error
dotnet_naming_rule.public_members_pascalcase.symbols = public_members
dotnet_naming_rule.public_members_pascalcase.style = pascalcase
#camelCase for private members #camelCase for private members
dotnet_naming_style.camelcase.capitalization = camel_case dotnet_naming_style.camelcase.capitalization = camel_case
@ -172,23 +191,11 @@ csharp_style_prefer_index_operator = false:silent
csharp_style_prefer_range_operator = false:silent csharp_style_prefer_range_operator = false:silent
csharp_style_prefer_switch_expression = false:none csharp_style_prefer_switch_expression = false:none
#Supressing roslyn built-in analyzers [*.{yaml,yml}]
# Suppress: EC112 insert_final_newline = true
indent_style = space
#Private method is unused indent_size = 2
dotnet_diagnostic.IDE0051.severity = silent trim_trailing_whitespace = true
#Private member is unused
dotnet_diagnostic.IDE0052.severity = silent
#Rules for disposable
dotnet_diagnostic.IDE0067.severity = none
dotnet_diagnostic.IDE0068.severity = none
dotnet_diagnostic.IDE0069.severity = none
#Disable operator overloads requiring alternate named methods
dotnet_diagnostic.CA2225.severity = none
# Banned APIs
dotnet_diagnostic.RS0030.severity = error
dotnet_diagnostic.OLOC001.words_in_name = 5
dotnet_diagnostic.OLOC001.license_header = // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\n// See the LICENCE file in the repository root for full licence text. dotnet_diagnostic.OLOC001.license_header = // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\n// See the LICENCE file in the repository root for full licence text.

2
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1,2 @@
# Normalize all the line endings
32a74f95a5c80a0ed18e693f13a47522099df5c3

80
.github/ISSUE_TEMPLATE/bug-issue.yml vendored Normal file
View File

@ -0,0 +1,80 @@
name: Bug report
description: Report a very clearly broken issue.
body:
- type: markdown
attributes:
value: |
# osu! bug report
Important to note that your issue may have already been reported before. Please check:
- Pinned issues, at the top of https://github.com/ppy/osu/issues.
- Current open `priority:0` issues, filterable [here](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Apriority%3A0).
- And most importantly, search for your issue both in the [issue listing](https://github.com/ppy/osu/issues) and the [Q&A discussion listing](https://github.com/ppy/osu/discussions/categories/q-a). If you find that it already exists, respond with a reaction or add any further information that may be helpful.
- type: dropdown
attributes:
label: Type
options:
- Crash to desktop
- Game behaviour
- Performance
- Cosmetic
- Other
validations:
required: true
- type: textarea
attributes:
label: Bug description
description: How did you find the bug? Any additional details that might help?
validations:
required: true
- type: textarea
attributes:
label: Screenshots or videos
description: Add screenshots or videos that show the bug here.
placeholder: Drag and drop the screenshots/videos into this box.
validations:
required: false
- type: input
attributes:
label: Version
description: The version you encountered this bug on. This is shown at the bottom of the main menu and also at the end of the settings screen.
validations:
required: true
- type: markdown
attributes:
value: |
## Logs
Attaching log files is required for every reported bug. See instructions below on how to find them.
**Logs are reset when you reopen the game.** If the game crashed or has been closed since you found the bug, retrieve the logs using the file explorer instead.
### Desktop platforms
If the game has not yet been closed since you found the bug:
1. Head on to game settings and click on "Open osu! folder"
2. Then open the `logs` folder located there
The default places to find the logs on desktop platforms are as follows:
- `%AppData%/osu/logs` *on Windows*
- `~/.local/share/osu/logs` *on Linux & macOS*
If you have selected a custom location for the game files, you can find the `logs` folder there.
### Mobile platforms
The places to find the logs on mobile platforms are as follows:
- *On Android*, navigate to `Android/data/sh.ppy.osulazer/files/logs` using a file browser app.
- *On iOS*, connect your device to a PC and copy the `logs` directory from the app's document storage using iTunes. (https://support.apple.com/en-us/HT201301#copy-to-computer)
---
After locating the `logs` folder, select all log files inside and drag them into the "Logs" box below.
- type: textarea
attributes:
label: Logs
placeholder: Drag and drop the log files into this box.
validations:
required: true

View File

@ -2,99 +2,6 @@ on: [push, pull_request]
name: Continuous Integration name: Continuous Integration
jobs: jobs:
test:
name: Test
runs-on: ${{matrix.os.fullname}}
env:
OSU_EXECUTION_MODE: ${{matrix.threadingMode}}
strategy:
fail-fast: false
matrix:
os:
- { prettyname: Windows, fullname: windows-latest }
- { prettyname: macOS, fullname: macos-latest }
- { prettyname: Linux, fullname: ubuntu-latest }
threadingMode: ['SingleThread', 'MultiThreaded']
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install .NET 6.0.x
uses: actions/setup-dotnet@v1
with:
dotnet-version: "6.0.x"
# FIXME: libavformat is not included in Ubuntu. Let's fix that.
# https://github.com/ppy/osu-framework/issues/4349
# Remove this once https://github.com/actions/virtual-environments/issues/3306 has been resolved.
- name: Install libavformat-dev
if: ${{matrix.os.fullname == 'ubuntu-latest'}}
run: |
sudo apt-get update && \
sudo apt-get -y install libavformat-dev
- name: Compile
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
- name: Test
run: dotnet test $pwd/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx"
shell: pwsh
# Attempt to upload results even if test fails.
# https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#always
- name: Upload Test Results
uses: actions/upload-artifact@v2
if: ${{ always() }}
with:
name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
path: ${{github.workspace}}/TestResults/TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx
build-only-android:
name: Build only (Android)
runs-on: macos-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v2
# Pin Xamarin.Android version to 11.2 for now to avoid build failures caused by a Xamarin-side regression.
# See: https://github.com/xamarin/xamarin-android/issues/6284
# This can be removed/reverted when the fix makes it to upstream and is deployed on github runners.
- name: Set default Xamarin SDK version
run: |
$VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=11.2
- name: Install .NET 6.0.x
uses: actions/setup-dotnet@v1
with:
dotnet-version: "6.0.x"
# Contrary to seemingly any other msbuild, msbuild running on macOS/Mono
# cannot accept .sln(f) files as arguments.
# Build just the main game for now.
- name: Build
run: msbuild osu.Android/osu.Android.csproj /restore /p:Configuration=Debug
build-only-ios:
name: Build only (iOS)
runs-on: macos-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install .NET 6.0.x
uses: actions/setup-dotnet@v1
with:
dotnet-version: "6.0.x"
# Contrary to seemingly any other msbuild, msbuild running on macOS/Mono
# cannot accept .sln(f) files as arguments.
# Build just the main game for now.
- name: Build
run: msbuild osu.iOS/osu.iOS.csproj /restore /p:Configuration=Debug
inspect-code: inspect-code:
name: Code Quality name: Code Quality
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -120,6 +27,15 @@ jobs:
- name: Restore Packages - name: Restore Packages
run: dotnet restore run: dotnet restore
- name: Restore inspectcode cache
uses: actions/cache@v3
with:
path: ${{ github.workspace }}/inspectcode
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
- name: Dotnet code style
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf -p:EnforceCodeStyleInBuild=true
- name: CodeFileSanity - name: CodeFileSanity
run: | run: |
# TODO: Add ignore filters and GitHub Workflow Command Reporting in CFS. That way we don't have to do this workaround. # TODO: Add ignore filters and GitHub Workflow Command Reporting in CFS. That way we don't have to do this workaround.
@ -133,12 +49,91 @@ jobs:
done <<< $(dotnet codefilesanity) done <<< $(dotnet codefilesanity)
exit $exit_code exit $exit_code
# Temporarily disabled due to test failures, but it won't work anyway until the tool is upgraded.
# - name: .NET Format (Dry Run)
# run: dotnet format --dry-run --check
- name: InspectCode - name: InspectCode
run: dotnet jb inspectcode $(pwd)/osu.Desktop.slnf --output=$(pwd)/inspectcodereport.xml --cachesDir=$(pwd)/inspectcode --verbosity=WARN run: dotnet jb inspectcode $(pwd)/osu.Desktop.slnf --no-build --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN
- name: NVika - name: NVika
run: dotnet nvika parsereport "${{github.workspace}}/inspectcodereport.xml" --treatwarningsaserrors run: dotnet nvika parsereport "${{github.workspace}}/inspectcodereport.xml" --treatwarningsaserrors
test:
name: Test
runs-on: ${{matrix.os.fullname}}
env:
OSU_EXECUTION_MODE: ${{matrix.threadingMode}}
strategy:
fail-fast: false
matrix:
os:
- { prettyname: Windows, fullname: windows-latest }
- { prettyname: macOS, fullname: macos-latest }
- { prettyname: Linux, fullname: ubuntu-latest }
threadingMode: ['SingleThread', 'MultiThreaded']
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install .NET 6.0.x
uses: actions/setup-dotnet@v1
with:
dotnet-version: "6.0.x"
- name: Compile
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
- name: Test
run: dotnet test $pwd/**/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx"
shell: pwsh
# Attempt to upload results even if test fails.
# https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#always
- name: Upload Test Results
uses: actions/upload-artifact@v2
if: ${{ always() }}
with:
name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
path: ${{github.workspace}}/TestResults/TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx
build-only-android:
name: Build only (Android)
runs-on: windows-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install .NET 6.0.x
uses: actions/setup-dotnet@v1
with:
dotnet-version: "6.0.x"
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1
- name: Build
run: msbuild osu.Android/osu.Android.csproj /restore /p:Configuration=Debug
build-only-ios:
name: Build only (iOS)
runs-on: macos-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install .NET 6.0.x
uses: actions/setup-dotnet@v1
with:
dotnet-version: "6.0.x"
# macOS agents recently have empty NuGet config files, resulting in restore failures,
# see https://github.com/actions/virtual-environments/issues/5768
# Add the global nuget package source manually for now.
- name: Setup NuGet.Config
run: echo '<configuration><packageSources><add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" /></packageSources></configuration>' > ~/.config/NuGet/NuGet.Config
# Contrary to seemingly any other msbuild, msbuild running on macOS/Mono
# cannot accept .sln(f) files as arguments.
# Build just the main game for now.
- name: Build
run: msbuild osu.iOS/osu.iOS.csproj /restore /p:Configuration=Debug

26
.github/workflows/sentry-release.yml vendored Normal file
View File

@ -0,0 +1,26 @@
name: Add Release to Sentry
on:
push:
tags:
- '*'
jobs:
sentry_release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Create Sentry release
uses: getsentry/action-release@v1
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ppy
SENTRY_PROJECT: osu
SENTRY_URL: https://sentry.ppy.sh/
with:
environment: production
version: osu@${{ github.ref_name }}

2
.gitignore vendored
View File

@ -340,3 +340,5 @@ inspectcode
# Fody (pulled in by Realm) - schema file # Fody (pulled in by Realm) - schema file
FodyWeavers.xsd FodyWeavers.xsd
**/FodyWeavers.xml **/FodyWeavers.xml
.idea/.idea.osu.Desktop/.idea/misc.xml

55
.globalconfig Normal file
View File

@ -0,0 +1,55 @@
is_global = true
# .NET Code Style
# IDE styles reference: https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/
# IDE0001: Simplify names
dotnet_diagnostic.IDE0001.severity = warning
# IDE0002: Simplify member access
dotnet_diagnostic.IDE0002.severity = warning
# IDE0003: Remove qualification
dotnet_diagnostic.IDE0003.severity = warning
# IDE0004: Remove unnecessary cast
dotnet_diagnostic.IDE0004.severity = warning
# IDE0005: Remove unnecessary imports
dotnet_diagnostic.IDE0005.severity = warning
# IDE0034: Simplify default literal
dotnet_diagnostic.IDE0034.severity = warning
# IDE0036: Sort modifiers
dotnet_diagnostic.IDE0036.severity = warning
# IDE0040: Add accessibility modifier
dotnet_diagnostic.IDE0040.severity = warning
# IDE0049: Use keyword for type name
dotnet_diagnostic.IDE0040.severity = warning
# IDE0055: Fix formatting
dotnet_diagnostic.IDE0055.severity = warning
# IDE0051: Private method is unused
dotnet_diagnostic.IDE0051.severity = silent
# IDE0052: Private member is unused
dotnet_diagnostic.IDE0052.severity = silent
# IDE0073: File header
dotnet_diagnostic.IDE0073.severity = warning
# IDE0130: Namespace mismatch with folder
dotnet_diagnostic.IDE0130.severity = warning
# IDE1006: Naming style
dotnet_diagnostic.IDE1006.severity = warning
#Disable operator overloads requiring alternate named methods
dotnet_diagnostic.CA2225.severity = none
# Banned APIs
dotnet_diagnostic.RS0030.severity = error

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="com.jetbrains.rider.android.RiderAndroidMiscFileCreationComponent">
<option name="ENSURE_MISC_FILE_EXISTS" value="true" />
</component>
</project>

View File

@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Benchmarks" type="DotNetProject" factoryName=".NET Project"> <configuration default="false" name="Benchmarks" type="DotNetProject" factoryName=".NET Project">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Benchmarks/bin/Debug/net5.0/osu.Game.Benchmarks.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Benchmarks/bin/Debug/net6.0/osu.Game.Benchmarks.dll" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Benchmarks/bin/Debug/net5.0" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Benchmarks/bin/Debug/net6.0" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" /> <option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" /> <option name="USE_MONO" value="0" />
@ -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="net5.0" /> <option name="PROJECT_TFM" value="net6.0" />
<method v="2"> <method v="2">
<option name="Build" /> <option name="Build" />
</method> </method>

View File

@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="CatchRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false"> <configuration default="false" name="CatchRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/net5.0/osu.Game.Rulesets.Catch.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/net6.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/bin/Debug/net5.0" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/net6.0" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" /> <option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" /> <option name="USE_MONO" value="0" />
@ -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="net5.0" /> <option name="PROJECT_TFM" value="net6.0" />
<browser url="http://localhost:5000" /> <browser url="http://localhost:5000" />
<method v="2"> <method v="2">
<option name="Build" /> <option name="Build" />

View File

@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="ManiaRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false"> <configuration default="false" name="ManiaRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/net5.0/osu.Game.Rulesets.Mania.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/net6.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/bin/Debug/net5.0" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/net6.0" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" /> <option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" /> <option name="USE_MONO" value="0" />
@ -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="net5.0" /> <option name="PROJECT_TFM" value="net6.0" />
<browser url="http://localhost:5000" /> <browser url="http://localhost:5000" />
<method v="2"> <method v="2">
<option name="Build" /> <option name="Build" />

View File

@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="OsuRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false"> <configuration default="false" name="OsuRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/net5.0/osu.Game.Rulesets.Osu.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/net6.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/bin/Debug/net5.0" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/net6.0" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" /> <option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" /> <option name="USE_MONO" value="0" />
@ -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="net5.0" /> <option name="PROJECT_TFM" value="net6.0" />
<browser url="http://localhost:5000" /> <browser url="http://localhost:5000" />
<method v="2"> <method v="2">
<option name="Build" /> <option name="Build" />

View File

@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="TaikoRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false"> <configuration default="false" name="TaikoRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/net5.0/osu.Game.Rulesets.Taiko.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/net6.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/bin/Debug/net5.0" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/net6.0" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" /> <option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" /> <option name="USE_MONO" value="0" />
@ -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="net5.0" /> <option name="PROJECT_TFM" value="net6.0" />
<browser url="http://localhost:5000" /> <browser url="http://localhost:5000" />
<method v="2"> <method v="2">
<option name="Build" /> <option name="Build" />

View File

@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament" activateToolWindowBeforeRun="false"> <configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament" activateToolWindowBeforeRun="false">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0/osu!.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net6.0/osu!.dll" />
<option name="PROGRAM_PARAMETERS" value="--tournament" /> <option name="PROGRAM_PARAMETERS" value="--tournament" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net6.0" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" /> <option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" /> <option name="USE_MONO" value="0" />
@ -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="net5.0" /> <option name="PROJECT_TFM" value="net6.0" />
<method v="2"> <method v="2">
<option name="Build" /> <option name="Build" />
</method> </method>

View File

@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Tournament (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Tournament" activateToolWindowBeforeRun="false"> <configuration default="false" name="Tournament (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Tournament" activateToolWindowBeforeRun="false">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/net5.0/osu.Game.Tournament.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/net6.0/osu.Game.Tournament.Tests.dll" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/net5.0" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/net6.0" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" /> <option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" /> <option name="USE_MONO" value="0" />
@ -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="net5.0" /> <option name="PROJECT_TFM" value="net6.0" />
<browser url="http://localhost:5000" /> <browser url="http://localhost:5000" />
<method v="2"> <method v="2">
<option name="Build" /> <option name="Build" />

View File

@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false"> <configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0/osu!.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net6.0/osu!.dll" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net6.0" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" /> <option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" /> <option name="USE_MONO" value="0" />
@ -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="net5.0" /> <option name="PROJECT_TFM" value="net6.0" />
<method v="2"> <method v="2">
<option name="Build" /> <option name="Build" />
</method> </method>

View File

@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="osu! (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false"> <configuration default="false" name="osu! (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/net5.0/osu.Game.Tests.dll" /> <option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/net6.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/bin/Debug/net5.0" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/net6.0" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" /> <option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" /> <option name="USE_MONO" value="0" />
@ -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="net5.0" /> <option name="PROJECT_TFM" value="net6.0" />
<method v="2"> <method v="2">
<option name="Build" /> <option name="Build" />
</method> </method>

5
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"recommendations": [
"ms-dotnettools.csharp"
]
}

18
.vscode/launch.json vendored
View File

@ -7,7 +7,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Debug/net5.0/osu!.dll" "${workspaceRoot}/osu.Desktop/bin/Debug/net6.0/osu!.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Debug)", "preLaunchTask": "Build osu! (Debug)",
@ -19,7 +19,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Release/net5.0/osu!.dll" "${workspaceRoot}/osu.Desktop/bin/Release/net6.0/osu!.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Release)", "preLaunchTask": "Build osu! (Release)",
@ -31,7 +31,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tests/bin/Debug/net5.0/osu.Game.Tests.dll" "${workspaceRoot}/osu.Game.Tests/bin/Debug/net6.0/osu.Game.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build tests (Debug)", "preLaunchTask": "Build tests (Debug)",
@ -43,7 +43,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tests/bin/Release/net5.0/osu.Game.Tests.dll" "${workspaceRoot}/osu.Game.Tests/bin/Release/net6.0/osu.Game.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build tests (Release)", "preLaunchTask": "Build tests (Release)",
@ -55,7 +55,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Debug/net5.0/osu!.dll", "${workspaceRoot}/osu.Desktop/bin/Debug/net6.0/osu!.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
@ -68,7 +68,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Release/net5.0/osu!.dll", "${workspaceRoot}/osu.Desktop/bin/Release/net6.0/osu!.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
@ -81,7 +81,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net5.0/osu.Game.Tournament.Tests.dll", "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net6.0/osu.Game.Tournament.Tests.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
@ -94,7 +94,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net5.0/osu.Game.Tournament.Tests.dll", "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net6.0/osu.Game.Tournament.Tests.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
@ -105,7 +105,7 @@
"name": "Benchmark", "name": "Benchmark",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"program": "${workspaceRoot}/osu.Game.Benchmarks/bin/Release/net5.0/osu.Game.Benchmarks.dll", "program": "${workspaceRoot}/osu.Game.Benchmarks/bin/Release/net6.0/osu.Game.Benchmarks.dll",
"args": [ "args": [
"--filter", "--filter",
"*" "*"

View File

@ -11,6 +11,7 @@ T:Microsoft.EntityFrameworkCore.Internal.TypeExtensions;Don't use internal exten
T:NuGet.Packaging.CollectionExtensions;Don't use internal extension methods. T:NuGet.Packaging.CollectionExtensions;Don't use internal extension methods.
M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.HasFlagFast<T>() instead. M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.HasFlagFast<T>() instead.
M:Realms.IRealmCollection`1.SubscribeForNotifications`1(Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IRealmCollection<T>,NotificationCallbackDelegate<T>) instead. M:Realms.IRealmCollection`1.SubscribeForNotifications`1(Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IRealmCollection<T>,NotificationCallbackDelegate<T>) instead.
M:System.Guid.#ctor;Probably meaning to use Guid.NewGuid() instead. If actually wanting empty, use Guid.Empty.
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Linq.IQueryable{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IQueryable<T>,NotificationCallbackDelegate<T>) instead. M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Linq.IQueryable{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IQueryable<T>,NotificationCallbackDelegate<T>) instead.
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IList<T>,NotificationCallbackDelegate<T>) instead. M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IList<T>,NotificationCallbackDelegate<T>) instead.
M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks. M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks.

View File

@ -1,8 +1,9 @@
<!-- Contains required properties for osu!framework projects. --> <!-- Contains required properties for osu!framework projects. -->
<Project> <Project>
<PropertyGroup Label="C#"> <PropertyGroup Label="C#">
<LangVersion>8.0</LangVersion> <LangVersion>8.0</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<ApplicationManifest>$(MSBuildThisFileDirectory)app.manifest</ApplicationManifest> <ApplicationManifest>$(MSBuildThisFileDirectory)app.manifest</ApplicationManifest>
@ -18,7 +19,6 @@
<ItemGroup Label="Code Analysis"> <ItemGroup Label="Code Analysis">
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.3" PrivateAssets="All" /> <PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.3" PrivateAssets="All" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt" /> <AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0" PrivateAssets="All" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Code Analysis"> <PropertyGroup Label="Code Analysis">
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodeAnalysis\osu.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodeAnalysis\osu.ruleset</CodeAnalysisRuleSet>
@ -27,14 +27,6 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn> <NoWarn>$(NoWarn);CS1591</NoWarn>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Label="Project">
<!--
NU1701:
DeepEqual is not netstandard-compatible. This is fine since we run tests with .NET Framework anyway.
This is required due to https://github.com/NuGet/Home/issues/5740
-->
<NoWarn>$(NoWarn);NU1701</NoWarn>
</PropertyGroup>
<PropertyGroup Label="Nuget"> <PropertyGroup Label="Nuget">
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<Authors>ppy Pty Ltd</Authors> <Authors>ppy Pty Ltd</Authors>
@ -43,7 +35,7 @@
<RepositoryUrl>https://github.com/ppy/osu</RepositoryUrl> <RepositoryUrl>https://github.com/ppy/osu</RepositoryUrl>
<PackageReleaseNotes>Automated release.</PackageReleaseNotes> <PackageReleaseNotes>Automated release.</PackageReleaseNotes>
<Company>ppy Pty Ltd</Company> <Company>ppy Pty Ltd</Company>
<Copyright>Copyright (c) 2021 ppy Pty Ltd</Copyright> <Copyright>Copyright (c) 2022 ppy Pty Ltd</Copyright>
<PackageTags>osu game</PackageTags> <PackageTags>osu game</PackageTags>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -8,17 +8,17 @@ GEM
artifactory (3.0.15) artifactory (3.0.15)
atomos (0.1.3) atomos (0.1.3)
aws-eventstream (1.2.0) aws-eventstream (1.2.0)
aws-partitions (1.553.0) aws-partitions (1.570.0)
aws-sdk-core (3.126.0) aws-sdk-core (3.130.0)
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0) aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
jmespath (~> 1.0) jmespath (~> 1.0)
aws-sdk-kms (1.54.0) aws-sdk-kms (1.55.0)
aws-sdk-core (~> 3, >= 3.126.0) aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.112.0) aws-sdk-s3 (1.113.0)
aws-sdk-core (~> 3, >= 3.126.0) aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4) aws-sigv4 (~> 1.4)
aws-sigv4 (1.4.0) aws-sigv4 (1.4.0)
@ -36,8 +36,8 @@ GEM
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6) dotenv (2.7.6)
emoji_regex (3.2.3) emoji_regex (3.2.3)
excon (0.91.0) excon (0.92.1)
faraday (1.9.3) faraday (1.10.0)
faraday-em_http (~> 1.0) faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0) faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1) faraday-excon (~> 1.1)
@ -66,7 +66,7 @@ GEM
faraday_middleware (1.2.0) faraday_middleware (1.2.0)
faraday (~> 1.0) faraday (~> 1.0)
fastimage (2.2.6) fastimage (2.2.6)
fastlane (2.204.2) fastlane (2.205.1)
CFPropertyList (>= 2.3, < 4.0.0) CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0) addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0) artifactory (~> 3.0)
@ -130,10 +130,10 @@ GEM
google-cloud-core (1.6.0) google-cloud-core (1.6.0)
google-cloud-env (~> 1.0) google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0) google-cloud-errors (~> 1.0)
google-cloud-env (1.5.0) google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 2.0) faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.2.0) google-cloud-errors (1.2.0)
google-cloud-storage (1.36.0) google-cloud-storage (1.36.1)
addressable (~> 2.8) addressable (~> 2.8)
digest-crc (~> 0.4) digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1) google-apis-iamcredentials_v1 (~> 0.1)
@ -141,8 +141,8 @@ GEM
google-cloud-core (~> 1.6) google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a) googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0) mini_mime (~> 1.0)
googleauth (1.1.0) googleauth (1.1.2)
faraday (>= 0.17.3, < 2.0) faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0) jwt (>= 1.4, < 3.0)
memoist (~> 0.16) memoist (~> 0.16)
multi_json (~> 1.11) multi_json (~> 1.11)
@ -152,7 +152,7 @@ GEM
http-cookie (1.0.4) http-cookie (1.0.4)
domain_name (~> 0.5) domain_name (~> 0.5)
httpclient (2.8.3) httpclient (2.8.3)
jmespath (1.5.0) jmespath (1.6.1)
json (2.6.1) json (2.6.1)
jwt (2.3.0) jwt (2.3.0)
memoist (0.16.2) memoist (0.16.2)
@ -182,9 +182,9 @@ GEM
ruby2_keywords (0.0.5) ruby2_keywords (0.0.5)
rubyzip (2.3.2) rubyzip (2.3.2)
security (0.1.3) security (0.1.3)
signet (0.16.0) signet (0.16.1)
addressable (~> 2.8) addressable (~> 2.8)
faraday (>= 0.17.3, < 2.0) faraday (>= 0.17.5, < 3.0)
jwt (>= 1.5, < 3.0) jwt (>= 1.5, < 3.0)
multi_json (~> 1.10) multi_json (~> 1.10)
simctl (1.6.8) simctl (1.6.8)
@ -205,7 +205,7 @@ GEM
uber (0.1.0) uber (0.1.0)
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.8) unf_ext (0.0.8.1)
unicode-display_width (1.8.0) unicode-display_width (1.8.0)
webrick (1.7.0) webrick (1.7.0)
word_wrap (1.0.0) word_wrap (1.0.0)

View File

@ -5,7 +5,7 @@ dotnet tool restore
# - cmd: dotnet format --dry-run --check # - cmd: dotnet format --dry-run --check
dotnet CodeFileSanity dotnet CodeFileSanity
dotnet jb inspectcode "osu.Desktop.slnf" --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN dotnet jb inspectcode "osu.Desktop.slnf" --no-build --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN
dotnet nvika parsereport "inspectcodereport.xml" --treatwarningsaserrors dotnet nvika parsereport "inspectcodereport.xml" --treatwarningsaserrors
exit $LASTEXITCODE exit $LASTEXITCODE

View File

@ -2,5 +2,5 @@
dotnet tool restore dotnet tool restore
dotnet CodeFileSanity dotnet CodeFileSanity
dotnet jb inspectcode "osu.Desktop.slnf" --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN dotnet jb inspectcode "osu.Desktop.slnf" --no-build --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN
dotnet nvika parsereport "inspectcodereport.xml" --treatwarningsaserrors dotnet nvika parsereport "inspectcodereport.xml" --treatwarningsaserrors

View File

@ -1,4 +1,4 @@
Copyright (c) 2021 ppy Pty Ltd <contact@ppy.sh>. Copyright (c) 2022 ppy Pty Ltd <contact@ppy.sh>.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
<p align="center"> <p align="center">
<img width="500px" src="assets/lazer.png"> <img width="500" alt="osu! logo" src="assets/lazer.png">
</p> </p>
# osu! # osu!
@ -8,6 +8,7 @@
[![GitHub release](https://img.shields.io/github/release/ppy/osu.svg)](https://github.com/ppy/osu/releases/latest) [![GitHub release](https://img.shields.io/github/release/ppy/osu.svg)](https://github.com/ppy/osu/releases/latest)
[![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu) [![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu)
[![dev chat](https://discordapp.com/api/guilds/188630481301012481/widget.png?style=shield)](https://discord.gg/ppy) [![dev chat](https://discordapp.com/api/guilds/188630481301012481/widget.png?style=shield)](https://discord.gg/ppy)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/osu-web/localized.svg)](https://crowdin.com/project/osu-web)
A free-to-win rhythm game. Rhythm is just a *click* away! A free-to-win rhythm game. Rhythm is just a *click* away!
@ -31,7 +32,7 @@ If you are looking to install or test osu! without setting up a development envi
**Latest build:** **Latest build:**
| [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.15+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 10+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) | [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 10.15+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 10+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
| ------------- | ------------- | ------------- | ------------- | ------------- | | ------------- | ------------- | ------------- | ------------- | ------------- |
- The iOS testflight link may fill up (Apple has a hard limit of 10,000 users). We reset it occasionally when this happens. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements of link resets. - The iOS testflight link may fill up (Apple has a hard limit of 10,000 users). We reset it occasionally when this happens. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements of link resets.
@ -50,7 +51,7 @@ Please make sure you have the following prerequisites:
- A desktop platform with the [.NET 6.0 SDK](https://dotnet.microsoft.com/download) installed. - A desktop platform with the [.NET 6.0 SDK](https://dotnet.microsoft.com/download) installed.
- When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/). - When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/).
- When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as [Visual Studio 2019+](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 intelligent code completion and syntax highlighting, such as the latest version of [Visual Studio](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/).
- 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.
### Downloading the source code ### Downloading the source code
@ -72,7 +73,7 @@ git pull
Build configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `VisualTests` project/configuration. More information on this is provided [below](#contributing). Build configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `VisualTests` project/configuration. More information on this is provided [below](#contributing).
- Visual Studio / Rider users should load the project via one of the platform-specific `.slnf` files, rather than the main `.sln.` This will allow access to template run configurations. - Visual Studio / Rider users should load the project via one of the platform-specific `.slnf` files, rather than the main `.sln`. This will allow access to template run configurations.
You can also build and run *osu!* from the command-line with a single command: You can also build and run *osu!* from the command-line with a single command:
@ -104,6 +105,8 @@ When it comes to contributing to the project, the two main things you can do to
Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured, with any libraries we are using, or with any processes involved with contributing, *please* bring it up. We welcome all feedback so we can make contributing to this project as painless as possible. Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured, with any libraries we are using, or with any processes involved with contributing, *please* bring it up. We welcome all feedback so we can make contributing to this project as painless as possible.
If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web).
For those interested, we love to reward quality contributions via [bounties](https://docs.google.com/spreadsheets/d/1jNXfj_S3Pb5PErA-czDdC9DUu4IgUbe1Lt8E7CYUJuE/view?&rm=minimal#gid=523803337), paid out via PayPal or osu!supporter tags. Don't hesitate to [request a bounty](https://docs.google.com/forms/d/e/1FAIpQLSet_8iFAgPMG526pBZ2Kic6HSh7XPM3fE8xPcnWNkMzINDdYg/viewform) for your work on this project. For those interested, we love to reward quality contributions via [bounties](https://docs.google.com/spreadsheets/d/1jNXfj_S3Pb5PErA-czDdC9DUu4IgUbe1Lt8E7CYUJuE/view?&rm=minimal#gid=523803337), paid out via PayPal or osu!supporter tags. Don't hesitate to [request a bounty](https://docs.google.com/forms/d/e/1FAIpQLSet_8iFAgPMG526pBZ2Kic6HSh7XPM3fE8xPcnWNkMzINDdYg/viewform) for your work on this project.
## Licence ## Licence

View File

@ -7,7 +7,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Debug/net5.0/osu.Game.Rulesets.EmptyFreeformRuleset.Tests.dll" "${workspaceRoot}/bin/Debug/net6.0/osu.Game.Rulesets.EmptyFreeformRuleset.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/net5.0/osu.Game.Rulesets.EmptyFreeformRuleset.Tests.dll" "${workspaceRoot}/bin/Release/net6.0/osu.Game.Rulesets.EmptyFreeformRuleset.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)", "preLaunchTask": "Build (Release)",

View File

@ -11,7 +11,7 @@
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>

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.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -25,6 +26,6 @@ namespace osu.Game.Rulesets.EmptyFreeform
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[0]; protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => Array.Empty<Skill>();
} }
} }

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.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -41,7 +42,7 @@ namespace osu.Game.Rulesets.EmptyFreeform
return new[] { new EmptyFreeformModAutoplay() }; return new[] { new EmptyFreeformModAutoplay() };
default: default:
return new Mod[] { null }; return Array.Empty<Mod>();
} }
} }

View File

@ -3,22 +3,14 @@
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.EmptyFreeform.Replays; using osu.Game.Rulesets.EmptyFreeform.Replays;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.EmptyFreeform.Mods namespace osu.Game.Rulesets.EmptyFreeform.Mods
{ {
public class EmptyFreeformModAutoplay : ModAutoplay public class EmptyFreeformModAutoplay : ModAutoplay
{ {
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList<Mod> mods) => new Score public override ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList<Mod> mods)
{ => new ModReplayData(new EmptyFreeformAutoGenerator(beatmap).Generate(), new ModCreatedUser { Username = "sample" });
ScoreInfo = new ScoreInfo
{
User = new APIUser { Username = "sample" },
},
Replay = new EmptyFreeformAutoGenerator(beatmap).Generate(),
};
} }
} }

View File

@ -7,7 +7,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Debug/net5.0/osu.Game.Rulesets.Pippidon.Tests.dll" "${workspaceRoot}/bin/Debug/net6.0/osu.Game.Rulesets.Pippidon.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/net5.0/osu.Game.Rulesets.Pippidon.Tests.dll" "${workspaceRoot}/bin/Release/net6.0/osu.Game.Rulesets.Pippidon.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)", "preLaunchTask": "Build (Release)",

View File

@ -11,7 +11,7 @@
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>

View File

@ -3,22 +3,14 @@
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Pippidon.Replays; using osu.Game.Rulesets.Pippidon.Replays;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.Pippidon.Mods namespace osu.Game.Rulesets.Pippidon.Mods
{ {
public class PippidonModAutoplay : ModAutoplay public class PippidonModAutoplay : ModAutoplay
{ {
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList<Mod> mods) => new Score public override ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList<Mod> mods)
{ => new ModReplayData(new PippidonAutoGenerator(beatmap).Generate(), new ModCreatedUser { Username = "sample" });
ScoreInfo = new ScoreInfo
{
User = new APIUser { Username = "sample" },
},
Replay = new PippidonAutoGenerator(beatmap).Generate(),
};
} }
} }

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.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -25,6 +26,6 @@ namespace osu.Game.Rulesets.Pippidon
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[0]; protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => Array.Empty<Skill>();
} }
} }

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.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
@ -37,7 +38,7 @@ namespace osu.Game.Rulesets.Pippidon
return new[] { new PippidonModAutoplay() }; return new[] { new PippidonModAutoplay() };
default: default:
return new Mod[] { null }; return Array.Empty<Mod>();
} }
} }

View File

@ -1,11 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Pippidon.Scoring
{
public class PippidonScoreProcessor : ScoreProcessor
{
}
}

View File

@ -7,7 +7,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Debug/net5.0/osu.Game.Rulesets.EmptyScrolling.Tests.dll" "${workspaceRoot}/bin/Debug/net6.0/osu.Game.Rulesets.EmptyScrolling.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/net5.0/osu.Game.Rulesets.EmptyScrolling.Tests.dll" "${workspaceRoot}/bin/Release/net6.0/osu.Game.Rulesets.EmptyScrolling.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)", "preLaunchTask": "Build (Release)",

View File

@ -11,7 +11,7 @@
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>

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.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -25,6 +26,6 @@ namespace osu.Game.Rulesets.EmptyScrolling
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[0]; protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => Array.Empty<Skill>();
} }
} }

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.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
@ -34,7 +35,7 @@ namespace osu.Game.Rulesets.EmptyScrolling
return new[] { new EmptyScrollingModAutoplay() }; return new[] { new EmptyScrollingModAutoplay() };
default: default:
return new Mod[] { null }; return Array.Empty<Mod>();
} }
} }

View File

@ -1,24 +1,16 @@
// 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 osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.EmptyScrolling.Replays;
using osu.Game.Scoring;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Beatmaps;
using osu.Game.Rulesets.EmptyScrolling.Replays;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.EmptyScrolling.Mods namespace osu.Game.Rulesets.EmptyScrolling.Mods
{ {
public class EmptyScrollingModAutoplay : ModAutoplay public class EmptyScrollingModAutoplay : ModAutoplay
{ {
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList<Mod> mods) => new Score public override ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList<Mod> mods)
{ => new ModReplayData(new EmptyScrollingAutoGenerator(beatmap).Generate(), new ModCreatedUser { Username = "sample" });
ScoreInfo = new ScoreInfo
{
User = new APIUser { Username = "sample" },
},
Replay = new EmptyScrollingAutoGenerator(beatmap).Generate(),
};
} }
} }

View File

@ -7,7 +7,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Debug/net5.0/osu.Game.Rulesets.Pippidon.Tests.dll" "${workspaceRoot}/bin/Debug/net6.0/osu.Game.Rulesets.Pippidon.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/net5.0/osu.Game.Rulesets.Pippidon.Tests.dll" "${workspaceRoot}/bin/Release/net6.0/osu.Game.Rulesets.Pippidon.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)", "preLaunchTask": "Build (Release)",

View File

@ -11,7 +11,7 @@
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>

View File

@ -3,22 +3,14 @@
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Pippidon.Replays; using osu.Game.Rulesets.Pippidon.Replays;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.Pippidon.Mods namespace osu.Game.Rulesets.Pippidon.Mods
{ {
public class PippidonModAutoplay : ModAutoplay public class PippidonModAutoplay : ModAutoplay
{ {
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList<Mod> mods) => new Score public override ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList<Mod> mods)
{ => new ModReplayData(new PippidonAutoGenerator(beatmap).Generate(), new ModCreatedUser { Username = "sample" });
ScoreInfo = new ScoreInfo
{
User = new APIUser { Username = "sample" },
},
Replay = new PippidonAutoGenerator(beatmap).Generate(),
};
} }
} }

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.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -25,6 +26,6 @@ namespace osu.Game.Rulesets.Pippidon
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[0]; protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => Array.Empty<Skill>();
} }
} }

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.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
@ -34,7 +35,7 @@ namespace osu.Game.Rulesets.Pippidon
return new[] { new PippidonModAutoplay() }; return new[] { new PippidonModAutoplay() };
default: default:
return new Mod[] { null }; return Array.Empty<Mod>();
} }
} }

View File

@ -8,7 +8,7 @@
<PackageProjectUrl>https://github.com/ppy/osu/blob/master/Templates</PackageProjectUrl> <PackageProjectUrl>https://github.com/ppy/osu/blob/master/Templates</PackageProjectUrl>
<RepositoryUrl>https://github.com/ppy/osu</RepositoryUrl> <RepositoryUrl>https://github.com/ppy/osu</RepositoryUrl>
<PackageReleaseNotes>Automated release.</PackageReleaseNotes> <PackageReleaseNotes>Automated release.</PackageReleaseNotes>
<copyright>Copyright (c) 2021 ppy Pty Ltd</copyright> <copyright>Copyright (c) 2022 ppy Pty Ltd</copyright>
<Description>Templates to use when creating a ruleset for consumption in osu!.</Description> <Description>Templates to use when creating a ruleset for consumption in osu!.</Description>
<PackageTags>dotnet-new;templates;osu</PackageTags> <PackageTags>dotnet-new;templates;osu</PackageTags>
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>netstandard2.1</TargetFramework>

View File

@ -1,4 +1,4 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<LangVersion>8.0</LangVersion> <LangVersion>8.0</LangVersion>
<OutputPath>bin\$(Configuration)</OutputPath> <OutputPath>bin\$(Configuration)</OutputPath>
@ -51,11 +51,11 @@
<Reference Include="Java.Interop" /> <Reference Include="Java.Interop" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.211.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2022.616.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.217.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2022.615.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Transitive Dependencies"> <ItemGroup Label="Transitive Dependencies">
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. --> <!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
<PackageReference Include="Realm" Version="10.9.0" /> <PackageReference Include="Realm" Version="10.14.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using Android.Content.PM; using Android.Content.PM;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System; using System;
using Android.App; using Android.App;
using Android.OS; using Android.OS;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using Android; using Android;
using Android.App; using Android.App;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System; using System;
using System.Text; using System.Text;
using DiscordRPC; using DiscordRPC;
@ -9,7 +11,9 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Extensions;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets; using osu.Game.Rulesets;
@ -29,6 +33,9 @@ namespace osu.Desktop
private IBindable<APIUser> user; private IBindable<APIUser> user;
[Resolved]
private IAPIProvider api { get; set; }
private readonly IBindable<UserStatus> status = new Bindable<UserStatus>(); private readonly IBindable<UserStatus> status = new Bindable<UserStatus>();
private readonly IBindable<UserActivity> activity = new Bindable<UserActivity>(); private readonly IBindable<UserActivity> activity = new Bindable<UserActivity>();
@ -40,7 +47,7 @@ namespace osu.Desktop
}; };
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(IAPIProvider provider, OsuConfigManager config) private void load(OsuConfigManager config)
{ {
client = new DiscordRpcClient(client_id) client = new DiscordRpcClient(client_id)
{ {
@ -56,7 +63,8 @@ namespace osu.Desktop
config.BindWith(OsuSetting.DiscordRichPresence, privacyMode); config.BindWith(OsuSetting.DiscordRichPresence, privacyMode);
(user = provider.LocalUser.GetBoundCopy()).BindValueChanged(u => user = api.LocalUser.GetBoundCopy();
user.BindValueChanged(u =>
{ {
status.UnbindBindings(); status.UnbindBindings();
status.BindTo(u.NewValue.Status); status.BindTo(u.NewValue.Status);
@ -94,6 +102,22 @@ namespace osu.Desktop
{ {
presence.State = truncate(activity.Value.Status); presence.State = truncate(activity.Value.Status);
presence.Details = truncate(getDetails(activity.Value)); presence.Details = truncate(getDetails(activity.Value));
if (getBeatmap(activity.Value) is IBeatmapInfo beatmap && beatmap.OnlineID > 0)
{
presence.Buttons = new[]
{
new Button
{
Label = "View beatmap",
Url = $@"{api.WebsiteRootUrl}/beatmapsets/{beatmap.BeatmapSet?.OnlineID}#{ruleset.Value.ShortName}/{beatmap.OnlineID}"
}
};
}
else
{
presence.Buttons = null;
}
} }
else else
{ {
@ -105,13 +129,15 @@ namespace osu.Desktop
if (privacyMode.Value == DiscordRichPresenceMode.Limited) if (privacyMode.Value == DiscordRichPresenceMode.Limited)
presence.Assets.LargeImageText = string.Empty; presence.Assets.LargeImageText = string.Empty;
else else
presence.Assets.LargeImageText = $"{user.Value.Username}" + (user.Value.Statistics?.GlobalRank > 0 ? $" (rank #{user.Value.Statistics.GlobalRank:N0})" : string.Empty); {
if (user.Value.RulesetsStatistics != null && user.Value.RulesetsStatistics.TryGetValue(ruleset.Value.ShortName, out UserStatistics statistics))
presence.Assets.LargeImageText = $"{user.Value.Username}" + (statistics.GlobalRank > 0 ? $" (rank #{statistics.GlobalRank:N0})" : string.Empty);
else
presence.Assets.LargeImageText = $"{user.Value.Username}" + (user.Value.Statistics?.GlobalRank > 0 ? $" (rank #{user.Value.Statistics.GlobalRank:N0})" : string.Empty);
}
// update ruleset // update ruleset
int onlineID = ruleset.Value.OnlineID; presence.Assets.SmallImageKey = ruleset.Value.IsLegacyRuleset() ? $"mode_{ruleset.Value.OnlineID}" : "mode_custom";
bool isLegacyRuleset = onlineID >= 0 && onlineID <= ILegacyRuleset.MAX_LEGACY_RULESET_ID;
presence.Assets.SmallImageKey = isLegacyRuleset ? $"mode_{onlineID}" : "mode_custom";
presence.Assets.SmallImageText = ruleset.Value.Name; presence.Assets.SmallImageText = ruleset.Value.Name;
client.SetPresence(presence); client.SetPresence(presence);
@ -138,6 +164,20 @@ namespace osu.Desktop
}); });
} }
private IBeatmapInfo getBeatmap(UserActivity activity)
{
switch (activity)
{
case UserActivity.InGame game:
return game.BeatmapInfo;
case UserActivity.Editing edit:
return edit.BeatmapInfo;
}
return null;
}
private string getDetails(UserActivity activity) private string getDetails(UserActivity activity)
{ {
switch (activity) switch (activity)

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
namespace osu.Desktop.LegacyIpc namespace osu.Desktop.LegacyIpc
{ {
/// <summary> /// <summary>

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
namespace osu.Desktop.LegacyIpc namespace osu.Desktop.LegacyIpc
{ {
/// <summary> /// <summary>

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using osu.Framework.Platform; using osu.Framework.Platform;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;

View File

@ -15,8 +15,6 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Taiko; using osu.Game.Rulesets.Taiko;
#nullable enable
namespace osu.Desktop.LegacyIpc namespace osu.Desktop.LegacyIpc
{ {
/// <summary> /// <summary>
@ -77,10 +75,9 @@ namespace osu.Desktop.LegacyIpc
case LegacyIpcDifficultyCalculationRequest req: case LegacyIpcDifficultyCalculationRequest req:
try try
{ {
var ruleset = getLegacyRulesetFromID(req.RulesetId); WorkingBeatmap beatmap = new FlatFileWorkingBeatmap(req.BeatmapFile);
var ruleset = beatmap.BeatmapInfo.Ruleset.CreateInstance();
Mod[] mods = ruleset.ConvertFromLegacyMods((LegacyMods)req.Mods).ToArray(); Mod[] mods = ruleset.ConvertFromLegacyMods((LegacyMods)req.Mods).ToArray();
WorkingBeatmap beatmap = new FlatFileWorkingBeatmap(req.BeatmapFile, _ => ruleset);
return new LegacyIpcDifficultyCalculationResponse return new LegacyIpcDifficultyCalculationResponse
{ {

View File

@ -1,8 +1,11 @@
// 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.
#nullable disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -24,7 +27,6 @@ using osu.Framework.Input.Handlers.Tablet;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.IO; using osu.Game.IO;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
using osu.Game.Overlays.Settings.Sections;
using osu.Game.Overlays.Settings.Sections.Input; using osu.Game.Overlays.Settings.Sections.Input;
namespace osu.Desktop namespace osu.Desktop
@ -103,6 +105,8 @@ namespace osu.Desktop
switch (RuntimeInfo.OS) switch (RuntimeInfo.OS)
{ {
case RuntimeInfo.Platform.Windows: case RuntimeInfo.Platform.Windows:
Debug.Assert(OperatingSystem.IsWindows());
return new SquirrelUpdateManager(); return new SquirrelUpdateManager();
default: default:
@ -146,8 +150,8 @@ namespace osu.Desktop
case MouseHandler mh: case MouseHandler mh:
return new MouseSettings(mh); return new MouseSettings(mh);
case JoystickHandler _: case JoystickHandler jh:
return new InputSection.HandlerSection(handler); return new JoystickSettings(jh);
default: default:
return base.CreateSettingsSubsectionFor(handler); return base.CreateSettingsSubsectionFor(handler);

View File

@ -1,10 +1,11 @@
// 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.
#nullable disable
using System; using System;
using System.IO; using System.IO;
using System.Threading; using System.Runtime.Versioning;
using System.Threading.Tasks;
using osu.Desktop.LegacyIpc; using osu.Desktop.LegacyIpc;
using osu.Framework; using osu.Framework;
using osu.Framework.Development; using osu.Framework.Development;
@ -12,6 +13,7 @@ using osu.Framework.Logging;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.IPC; using osu.Game.IPC;
using osu.Game.Tournament; using osu.Game.Tournament;
using Squirrel;
namespace osu.Desktop namespace osu.Desktop
{ {
@ -24,6 +26,10 @@ namespace osu.Desktop
[STAThread] [STAThread]
public static void Main(string[] args) public static void Main(string[] args)
{ {
// run Squirrel first, as the app may exit after these run
if (OperatingSystem.IsWindows())
setupSquirrel();
// Back up the cwd before DesktopGameHost changes it // Back up the cwd before DesktopGameHost changes it
string cwd = Environment.CurrentDirectory; string cwd = Environment.CurrentDirectory;
@ -57,8 +63,6 @@ namespace osu.Desktop
using (DesktopGameHost host = Host.GetSuitableDesktopHost(gameName, new HostOptions { BindIPC = true })) using (DesktopGameHost host = Host.GetSuitableDesktopHost(gameName, new HostOptions { BindIPC = true }))
{ {
host.ExceptionThrown += handleException;
if (!host.IsPrimaryInstance) if (!host.IsPrimaryInstance)
{ {
if (args.Length > 0 && args[0].Contains('.')) // easy way to check for a file import in args if (args.Length > 0 && args[0].Contains('.')) // easy way to check for a file import in args
@ -104,22 +108,29 @@ namespace osu.Desktop
} }
} }
private static int allowableExceptions = DebugUtils.IsDebugBuild ? 0 : 1; [SupportedOSPlatform("windows")]
private static void setupSquirrel()
/// <summary>
/// Allow a maximum of one unhandled exception, per second of execution.
/// </summary>
/// <param name="arg"></param>
private static bool handleException(Exception arg)
{ {
bool continueExecution = Interlocked.Decrement(ref allowableExceptions) >= 0; SquirrelAwareApp.HandleEvents(onInitialInstall: (version, tools) =>
{
Logger.Log($"Unhandled exception has been {(continueExecution ? $"allowed with {allowableExceptions} more allowable exceptions" : "denied")} ."); tools.CreateShortcutForThisExe();
tools.CreateUninstallerRegistryEntry();
// restore the stock of allowable exceptions after a short delay. }, onAppUpdate: (version, tools) =>
Task.Delay(1000).ContinueWith(_ => Interlocked.Increment(ref allowableExceptions)); {
tools.CreateUninstallerRegistryEntry();
return continueExecution; }, onAppUninstall: (version, tools) =>
{
tools.RemoveShortcutForThisExe();
tools.RemoveUninstallerRegistryEntry();
}, onEveryRun: (version, tools, firstRun) =>
{
// While setting the `ProcessAppUserModelId` fixes duplicate icons/shortcuts on the taskbar, it currently
// causes the right-click context menu to function incorrectly.
//
// This may turn out to be non-required after an alternative solution is implemented.
// see https://github.com/clowd/Clowd.Squirrel/issues/24
// tools.SetProcessAppUserModelId();
});
} }
} }
} }

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System; using System;
using System.Security.Principal; using System.Security.Principal;
using osu.Framework; using osu.Framework;
@ -19,7 +21,7 @@ namespace osu.Desktop.Security
public class ElevatedPrivilegesChecker : Component public class ElevatedPrivilegesChecker : Component
{ {
[Resolved] [Resolved]
private NotificationOverlay notifications { get; set; } private INotificationOverlay notifications { get; set; }
private bool elevated; private bool elevated;

View File

@ -1,7 +1,10 @@
// 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.
#nullable disable
using System; using System;
using System.Runtime.Versioning;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -16,14 +19,15 @@ using osu.Game.Overlays.Notifications;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
using Squirrel; using Squirrel;
using LogLevel = Splat.LogLevel; using Squirrel.SimpleSplat;
namespace osu.Desktop.Updater namespace osu.Desktop.Updater
{ {
[SupportedOSPlatform("windows")]
public class SquirrelUpdateManager : osu.Game.Updater.UpdateManager public class SquirrelUpdateManager : osu.Game.Updater.UpdateManager
{ {
private UpdateManager updateManager; private UpdateManager updateManager;
private NotificationOverlay notificationOverlay; private INotificationOverlay notificationOverlay;
public Task PrepareUpdateAsync() => UpdateManager.RestartAppWhenExited(); public Task PrepareUpdateAsync() => UpdateManager.RestartAppWhenExited();
@ -34,12 +38,14 @@ namespace osu.Desktop.Updater
/// </summary> /// </summary>
private bool updatePending; private bool updatePending;
[BackgroundDependencyLoader] private readonly SquirrelLogger squirrelLogger = new SquirrelLogger();
private void load(NotificationOverlay notification)
{
notificationOverlay = notification;
Splat.Locator.CurrentMutable.Register(() => new SquirrelLogger(), typeof(Splat.ILogger)); [BackgroundDependencyLoader]
private void load(INotificationOverlay notifications)
{
notificationOverlay = notifications;
SquirrelLocator.CurrentMutable.Register(() => squirrelLogger, typeof(ILogger));
} }
protected override async Task<bool> PerformUpdateCheck() => await checkForUpdateAsync().ConfigureAwait(false); protected override async Task<bool> PerformUpdateCheck() => await checkForUpdateAsync().ConfigureAwait(false);
@ -49,9 +55,11 @@ namespace osu.Desktop.Updater
// should we schedule a retry on completion of this check? // should we schedule a retry on completion of this check?
bool scheduleRecheck = true; bool scheduleRecheck = true;
const string github_token = null; // TODO: populate.
try try
{ {
updateManager ??= await UpdateManager.GitHubUpdateManager(@"https://github.com/ppy/osu", @"osulazer", null, null, true).ConfigureAwait(false); updateManager ??= new GithubUpdateManager(@"https://github.com/ppy/osu", false, github_token, @"osulazer");
var info = await updateManager.CheckForUpdate(!useDeltaPatching).ConfigureAwait(false); var info = await updateManager.CheckForUpdate(!useDeltaPatching).ConfigureAwait(false);
@ -146,7 +154,7 @@ namespace osu.Desktop.Updater
Activated = () => Activated = () =>
{ {
updateManager.PrepareUpdateAsync() updateManager.PrepareUpdateAsync()
.ContinueWith(_ => updateManager.Schedule(() => game?.GracefullyExit())); .ContinueWith(_ => updateManager.Schedule(() => game?.AttemptExit()));
return true; return true;
}; };
} }
@ -201,11 +209,11 @@ namespace osu.Desktop.Updater
} }
} }
private class SquirrelLogger : Splat.ILogger, IDisposable private class SquirrelLogger : ILogger, IDisposable
{ {
public LogLevel Level { get; set; } = LogLevel.Info; public Squirrel.SimpleSplat.LogLevel Level { get; set; } = Squirrel.SimpleSplat.LogLevel.Info;
public void Write(string message, LogLevel logLevel) public void Write(string message, Squirrel.SimpleSplat.LogLevel logLevel)
{ {
if (logLevel < Level) if (logLevel < Level)
return; return;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> <asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity version="1.0.0.0" name="osu!" /> <assemblyIdentity version="1.0.0.0" name="osu!" />
<SquirrelAwareVersion xmlns="urn:schema-squirrel-com:asm.v1">1</SquirrelAwareVersion>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security> <security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">

View File

@ -24,16 +24,14 @@
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NETCore.Targets" Version="5.0.0" /> <PackageReference Include="Clowd.Squirrel" Version="2.9.40" />
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" /> <PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="System.IO.Packaging" Version="6.0.0" /> <PackageReference Include="System.IO.Packaging" Version="6.0.0" />
<PackageReference Include="ppy.squirrel.windows" Version="1.9.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.14" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.14" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.14"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.14">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="DiscordRichPresence" Version="1.0.175" /> <PackageReference Include="DiscordRichPresence" Version="1.0.175" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Resources"> <ItemGroup Label="Resources">

View File

@ -11,12 +11,13 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>A free-to-win rhythm game. Rhythm is just a *click* away!</description> <description>A free-to-win rhythm game. Rhythm is just a *click* away!</description>
<releaseNotes>testing</releaseNotes> <releaseNotes>testing</releaseNotes>
<copyright>Copyright (c) 2021 ppy Pty Ltd</copyright> <copyright>Copyright (c) 2022 ppy Pty Ltd</copyright>
<language>en-AU</language> <language>en-AU</language>
</metadata> </metadata>
<files> <files>
<file src="**.exe" target="lib\net45\" exclude="**vshost**"/> <file src="**.exe" target="lib\net45\" exclude="**vshost**"/>
<file src="**.dll" target="lib\net45\"/> <file src="**.dll" target="lib\net45\"/>
<file src="**.config" target="lib\net45\"/> <file src="**.config" target="lib\net45\"/>
<file src="**.json" target="lib\net45\"/>
</files> </files>
</package> </package>

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System.IO; using System.IO;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System; using System;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Mods;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
@ -27,7 +29,7 @@ namespace osu.Game.Benchmarks
storage = new TemporaryNativeStorage("realm-benchmark"); storage = new TemporaryNativeStorage("realm-benchmark");
storage.DeleteDirectory(string.Empty); storage.DeleteDirectory(string.Empty);
realm = new RealmAccess(storage, "client"); realm = new RealmAccess(storage, OsuGameBase.CLIENT_DATABASE_FILENAME);
realm.Run(r => realm.Run(r =>
{ {

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines; using BenchmarkDotNet.Engines;
using osu.Game.Online.API; using osu.Game.Online.API;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running; using BenchmarkDotNet.Running;
using NUnit.Framework; using NUnit.Framework;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using BenchmarkDotNet.Configs; using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Running; using BenchmarkDotNet.Running;

View File

@ -8,7 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" /> <PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="nunit" Version="3.13.2" /> <PackageReference Include="nunit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
</ItemGroup> </ItemGroup>

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using Android.App; using Android.App;
using osu.Framework.Android; using osu.Framework.Android;
using osu.Game.Tests; using osu.Game.Tests;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using Foundation; using Foundation;
using osu.Framework.iOS; using osu.Framework.iOS;
using osu.Game.Tests; using osu.Game.Tests;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using osu.Framework.iOS; using osu.Framework.iOS;
using UIKit; using UIKit;

View File

@ -37,6 +37,8 @@
</array> </array>
<key>XSAppIconAssets</key> <key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string> <string>Assets.xcassets/AppIcon.appiconset</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>
<true/> <true/>
</dict> </dict>

View File

@ -7,7 +7,7 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/bin/Debug/net5.0/osu.Game.Rulesets.Catch.Tests.dll" "${workspaceRoot}/bin/Debug/net6.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/net5.0/osu.Game.Rulesets.Catch.Tests.dll" "${workspaceRoot}/bin/Release/net6.0/osu.Game.Rulesets.Catch.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)", "preLaunchTask": "Build (Release)",

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Difficulty; using osu.Game.Rulesets.Catch.Difficulty;
@ -14,13 +16,13 @@ namespace osu.Game.Rulesets.Catch.Tests
{ {
protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; protected override string ResourceAssembly => "osu.Game.Rulesets.Catch";
[TestCase(4.0505463516206195d, "diffcalc-test")] [TestCase(4.0505463516206195d, 127, "diffcalc-test")]
public void Test(double expected, string name) public void Test(double expectedStarRating, int expectedMaxCombo, string name)
=> base.Test(expected, name); => base.Test(expectedStarRating, expectedMaxCombo, name);
[TestCase(5.1696411260785498d, "diffcalc-test")] [TestCase(5.1696411260785498d, 127, "diffcalc-test")]
public void TestClockRateAdjusted(double expected, string name) public void TestClockRateAdjusted(double expectedStarRating, int expectedMaxCombo, string name)
=> Test(expected, name, new CatchModDoubleTime()); => Test(expectedStarRating, expectedMaxCombo, name, new CatchModDoubleTime());
protected override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new CatchDifficultyCalculator(new CatchRuleset().RulesetInfo, beatmap); protected override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new CatchDifficultyCalculator(new CatchRuleset().RulesetInfo, beatmap);

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps.Legacy; using osu.Game.Beatmaps.Legacy;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
using osu.Game.Rulesets.Catch.Skinning; using osu.Game.Rulesets.Catch.Skinning;
@ -30,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.Tests
{ {
public TestLegacySkin(SkinInfo skin, IResourceStore<byte[]> storage) public TestLegacySkin(SkinInfo skin, IResourceStore<byte[]> storage)
// Bypass LegacySkinResourceStore to avoid returning null for retrieving files due to bad skin info (SkinInfo.Files = null). // Bypass LegacySkinResourceStore to avoid returning null for retrieving files due to bad skin info (SkinInfo.Files = null).
: base(skin, storage, null, "skin.ini") : base(skin, null, storage)
{ {
} }
} }

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests namespace osu.Game.Rulesets.Catch.Tests

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -29,13 +31,14 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
protected CatchSelectionBlueprintTestScene() protected CatchSelectionBlueprintTestScene()
{ {
EditorBeatmap = new EditorBeatmap(new CatchBeatmap var catchBeatmap = new CatchBeatmap
{ {
BeatmapInfo = BeatmapInfo =
{ {
Ruleset = new CatchRuleset().RulesetInfo, Ruleset = new CatchRuleset().RulesetInfo,
} }
}) { Difficulty = { CircleSize = 0 } }; };
EditorBeatmap = new EditorBeatmap(catchBeatmap) { Difficulty = { CircleSize = 0 } };
EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint
{ {
BeatLength = 100 BeatLength = 100

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -55,7 +57,10 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
AddMoveStep(end_time, 0); AddMoveStep(end_time, 0);
AddClickStep(MouseButton.Left); AddClickStep(MouseButton.Left);
AddMoveStep(start_time, 0); AddMoveStep(start_time, 0);
AddAssert("duration is positive", () => ((BananaShower)CurrentBlueprint.HitObject).Duration > 0);
AddClickStep(MouseButton.Right); AddClickStep(MouseButton.Right);
AddAssert("start time is correct", () => Precision.AlmostEquals(LastObject.HitObject.StartTime, start_time)); AddAssert("start time is correct", () => Precision.AlmostEquals(LastObject.HitObject.StartTime, start_time));
AddAssert("end time is correct", () => Precision.AlmostEquals(LastObject.HitObject.GetEndTime(), end_time)); AddAssert("end time is correct", () => Precision.AlmostEquals(LastObject.HitObject.GetEndTime(), end_time));

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Utils; using osu.Framework.Utils;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
@ -19,7 +21,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
public class TestSceneJuiceStreamPlacementBlueprint : CatchPlacementBlueprintTestScene public class TestSceneJuiceStreamPlacementBlueprint : CatchPlacementBlueprintTestScene
{ {
private const double velocity = 0.5; private const double velocity_factor = 0.5;
private JuiceStream lastObject => LastObject?.HitObject as JuiceStream; private JuiceStream lastObject => LastObject?.HitObject as JuiceStream;
@ -27,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
var playable = base.GetPlayableBeatmap(); var playable = base.GetPlayableBeatmap();
playable.Difficulty.SliderTickRate = 5; playable.Difficulty.SliderTickRate = 5;
playable.Difficulty.SliderMultiplier = velocity * 10; playable.Difficulty.SliderMultiplier = velocity_factor * 10;
return playable; return playable;
} }
@ -43,6 +45,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
AddAssert("end time is correct", () => Precision.AlmostEquals(lastObject.EndTime, times[1])); AddAssert("end time is correct", () => Precision.AlmostEquals(lastObject.EndTime, times[1]));
AddAssert("start position is correct", () => Precision.AlmostEquals(lastObject.OriginalX, positions[0])); AddAssert("start position is correct", () => Precision.AlmostEquals(lastObject.OriginalX, positions[0]));
AddAssert("end position is correct", () => Precision.AlmostEquals(lastObject.EndX, positions[1])); AddAssert("end position is correct", () => Precision.AlmostEquals(lastObject.EndX, positions[1]));
AddAssert("default slider velocity", () => lastObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
} }
[Test] [Test]
@ -66,28 +69,21 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
} }
[Test] [Test]
public void TestVelocityLimit() public void TestSliderVelocityChange()
{ {
double[] times = { 100, 300 }; double[] times = { 100, 300 };
float[] positions = { 200, 500 }; float[] positions = { 200, 500 };
addPlacementSteps(times, positions); addPlacementSteps(times, positions);
addPathCheckStep(times, new float[] { 200, 300 }); addPathCheckStep(times, positions);
}
[Test] AddAssert("slider velocity changed", () => !lastObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
public void TestPreviousVerticesAreFixed()
{
double[] times = { 100, 300, 500, 700 };
float[] positions = { 200, 400, 100, 500 };
addPlacementSteps(times, positions);
addPathCheckStep(times, new float[] { 200, 300, 200, 300 });
} }
[Test] [Test]
public void TestClampedPositionIsRestored() public void TestClampedPositionIsRestored()
{ {
double[] times = { 100, 300, 500 }; double[] times = { 100, 300, 500 };
float[] positions = { 200, 200, 0, 250 }; float[] positions = { 200, 200, -3000, 250 };
addMoveAndClickSteps(times[0], positions[0]); addMoveAndClickSteps(times[0], positions[0]);
addMoveAndClickSteps(times[1], positions[1]); addMoveAndClickSteps(times[1], positions[1]);
@ -97,15 +93,6 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
addPathCheckStep(times, new float[] { 200, 200, 250 }); addPathCheckStep(times, new float[] { 200, 200, 250 });
} }
[Test]
public void TestFirstVertexIsFixed()
{
double[] times = { 100, 200 };
float[] positions = { 100, 300 };
addPlacementSteps(times, positions);
addPathCheckStep(times, new float[] { 100, 150 });
}
[Test] [Test]
public void TestOutOfOrder() public void TestOutOfOrder()
{ {

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
@ -101,31 +103,16 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
} }
[Test] [Test]
public void TestClampedPositionIsRestored() public void TestSliderVelocityChange()
{ {
const double velocity = 0.25; double[] times = { 100, 300 };
double[] times = { 100, 500, 700 }; float[] positions = { 200, 300 };
float[] positions = { 100, 100, 100 }; addBlueprintStep(times, positions);
addBlueprintStep(times, positions, velocity); AddAssert("default slider velocity", () => hitObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
addDragStartStep(times[1], positions[1]); addDragStartStep(times[1], positions[1]);
AddMouseMoveStep(times[1], 400);
AddMouseMoveStep(times[1], 200); AddAssert("slider velocity changed", () => !hitObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
addVertexCheckStep(3, 1, times[1], 200);
addVertexCheckStep(3, 2, times[2], 150);
AddMouseMoveStep(times[1], 100);
addVertexCheckStep(3, 1, times[1], 100);
// Stored position is restored.
addVertexCheckStep(3, 2, times[2], positions[2]);
AddMouseMoveStep(times[1], 300);
addDragEndStep();
addDragStartStep(times[1], 300);
AddMouseMoveStep(times[1], 100);
// Position is different because a changed position is committed when the previous drag is ended.
addVertexCheckStep(3, 2, times[2], 250);
} }
[Test] [Test]
@ -174,7 +161,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
addAddVertexSteps(500, 150); addAddVertexSteps(500, 150);
addVertexCheckStep(3, 1, 500, 150); addVertexCheckStep(3, 1, 500, 150);
addAddVertexSteps(90, 220); addAddVertexSteps(90, 200);
addVertexCheckStep(4, 1, times[0], positions[0]); addVertexCheckStep(4, 1, times[0], positions[0]);
addAddVertexSteps(750, 180); addAddVertexSteps(750, 180);
@ -234,10 +221,10 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
var path = new JuiceStreamPath(); var path = new JuiceStreamPath();
for (int i = 1; i < times.Length; i++) for (int i = 1; i < times.Length; i++)
path.Add((times[i] - times[0]) * velocity, positions[i] - positions[0]); path.Add(times[i] - times[0], positions[i] - positions[0]);
var sliderPath = new SliderPath(); var sliderPath = new SliderPath();
path.ConvertToSliderPath(sliderPath, 0); path.ConvertToSliderPath(sliderPath, 0, velocity);
addBlueprintStep(times[0], positions[0], sliderPath, velocity); addBlueprintStep(times[0], positions[0], sliderPath, velocity);
} }
@ -245,11 +232,11 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
private void addVertexCheckStep(int count, int index, double time, float x) => AddAssert($"vertex {index} of {count} at {time}, {x}", () => private void addVertexCheckStep(int count, int index, double time, float x) => AddAssert($"vertex {index} of {count} at {time}, {x}", () =>
{ {
double expectedDistance = (time - hitObject.StartTime) * hitObject.Velocity; double expectedTime = time - hitObject.StartTime;
float expectedX = x - hitObject.OriginalX; float expectedX = x - hitObject.OriginalX;
var vertices = getVertices(); var vertices = getVertices();
return vertices.Count == count && return vertices.Count == count &&
Precision.AlmostEquals(vertices[index].Distance, expectedDistance, 1e-3) && Precision.AlmostEquals(vertices[index].Time, expectedTime, 1e-3) &&
Precision.AlmostEquals(vertices[index].X, expectedX); Precision.AlmostEquals(vertices[index].X, expectedX);
}); });

View File

@ -1,11 +1,12 @@
// 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.
#nullable disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Utils;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
@ -37,14 +38,14 @@ namespace osu.Game.Rulesets.Catch.Tests
{ {
case 0: case 0:
{ {
double distance = rng.NextDouble() * scale * 2 - scale; double time = rng.NextDouble() * scale * 2 - scale;
if (integralValues) if (integralValues)
distance = Math.Round(distance); time = Math.Round(time);
float oldX = path.PositionAtDistance(distance); float oldX = path.PositionAtTime(time);
int index = path.InsertVertex(distance); int index = path.InsertVertex(time);
Assert.That(path.Vertices.Count, Is.EqualTo(vertexCount + 1)); Assert.That(path.Vertices.Count, Is.EqualTo(vertexCount + 1));
Assert.That(path.Vertices[index].Distance, Is.EqualTo(distance)); Assert.That(path.Vertices[index].Time, Is.EqualTo(time));
Assert.That(path.Vertices[index].X, Is.EqualTo(oldX)); Assert.That(path.Vertices[index].X, Is.EqualTo(oldX));
break; break;
} }
@ -52,20 +53,20 @@ namespace osu.Game.Rulesets.Catch.Tests
case 1: case 1:
{ {
int index = rng.Next(path.Vertices.Count); int index = rng.Next(path.Vertices.Count);
double distance = path.Vertices[index].Distance; double time = path.Vertices[index].Time;
float newX = (float)(rng.NextDouble() * scale * 2 - scale); float newX = (float)(rng.NextDouble() * scale * 2 - scale);
if (integralValues) if (integralValues)
newX = MathF.Round(newX); newX = MathF.Round(newX);
path.SetVertexPosition(index, newX); path.SetVertexPosition(index, newX);
Assert.That(path.Vertices.Count, Is.EqualTo(vertexCount)); Assert.That(path.Vertices.Count, Is.EqualTo(vertexCount));
Assert.That(path.Vertices[index].Distance, Is.EqualTo(distance)); Assert.That(path.Vertices[index].Time, Is.EqualTo(time));
Assert.That(path.Vertices[index].X, Is.EqualTo(newX)); Assert.That(path.Vertices[index].X, Is.EqualTo(newX));
break; break;
} }
} }
assertInvariants(path.Vertices, checkSlope); assertInvariants(path.Vertices);
} }
} }
@ -76,7 +77,7 @@ namespace osu.Game.Rulesets.Catch.Tests
path.Add(10, 5); path.Add(10, 5);
path.Add(20, -5); path.Add(20, -5);
int removeCount = path.RemoveVertices((v, i) => v.Distance == 10 && i == 1); int removeCount = path.RemoveVertices((v, i) => v.Time == 10 && i == 1);
Assert.That(removeCount, Is.EqualTo(1)); Assert.That(removeCount, Is.EqualTo(1));
Assert.That(path.Vertices, Is.EqualTo(new[] Assert.That(path.Vertices, Is.EqualTo(new[]
{ {
@ -131,8 +132,9 @@ namespace osu.Game.Rulesets.Catch.Tests
})); }));
} }
[Test] [TestCase(10)]
public void TestRandomConvertFromSliderPath() [TestCase(0.1)]
public void TestRandomConvertFromSliderPath(double velocity)
{ {
var rng = new Random(1); var rng = new Random(1);
var path = new JuiceStreamPath(); var path = new JuiceStreamPath();
@ -162,28 +164,28 @@ namespace osu.Game.Rulesets.Catch.Tests
else else
sliderPath.ExpectedDistance.Value = null; sliderPath.ExpectedDistance.Value = null;
path.ConvertFromSliderPath(sliderPath); path.ConvertFromSliderPath(sliderPath, velocity);
Assert.That(path.Vertices[0].Distance, Is.EqualTo(0)); Assert.That(path.Vertices[0].Time, Is.EqualTo(0));
Assert.That(path.Distance, Is.EqualTo(sliderPath.Distance).Within(1e-3)); Assert.That(path.Duration * velocity, Is.EqualTo(sliderPath.Distance).Within(1e-3));
assertInvariants(path.Vertices, true); assertInvariants(path.Vertices);
double[] sampleDistances = Enumerable.Range(0, 10) double[] sampleTimes = Enumerable.Range(0, 10)
.Select(_ => rng.NextDouble() * sliderPath.Distance) .Select(_ => rng.NextDouble() * sliderPath.Distance / velocity)
.ToArray(); .ToArray();
foreach (double distance in sampleDistances) foreach (double time in sampleTimes)
{ {
float expected = sliderPath.PositionAt(distance / sliderPath.Distance).X; float expected = sliderPath.PositionAt(time * velocity / sliderPath.Distance).X;
Assert.That(path.PositionAtDistance(distance), Is.EqualTo(expected).Within(1e-3)); Assert.That(path.PositionAtTime(time), Is.EqualTo(expected).Within(1e-3));
} }
path.ResampleVertices(sampleDistances); path.ResampleVertices(sampleTimes);
assertInvariants(path.Vertices, true); assertInvariants(path.Vertices);
foreach (double distance in sampleDistances) foreach (double time in sampleTimes)
{ {
float expected = sliderPath.PositionAt(distance / sliderPath.Distance).X; float expected = sliderPath.PositionAt(time * velocity / sliderPath.Distance).X;
Assert.That(path.PositionAtDistance(distance), Is.EqualTo(expected).Within(1e-3)); Assert.That(path.PositionAtTime(time), Is.EqualTo(expected).Within(1e-3));
} }
} }
} }
@ -201,17 +203,17 @@ namespace osu.Game.Rulesets.Catch.Tests
do do
{ {
double distance = rng.NextDouble() * 1e3; double time = rng.NextDouble() * 1e3;
float x = (float)(rng.NextDouble() * 1e3); float x = (float)(rng.NextDouble() * 1e3);
path.Add(distance, x); path.Add(time, x);
} while (rng.Next(5) != 0); } while (rng.Next(5) != 0);
float sliderStartY = (float)(rng.NextDouble() * JuiceStreamPath.OSU_PLAYFIELD_HEIGHT); float sliderStartY = (float)(rng.NextDouble() * JuiceStreamPath.OSU_PLAYFIELD_HEIGHT);
path.ConvertToSliderPath(sliderPath, sliderStartY); double requiredVelocity = path.ComputeRequiredVelocity();
Assert.That(sliderPath.Distance, Is.EqualTo(path.Distance).Within(1e-3)); double velocity = Math.Clamp(requiredVelocity, 1, 100);
Assert.That(sliderPath.ControlPoints[0].Position.X, Is.EqualTo(path.Vertices[0].X));
assertInvariants(path.Vertices, true); path.ConvertToSliderPath(sliderPath, sliderStartY, velocity);
foreach (var point in sliderPath.ControlPoints) foreach (var point in sliderPath.ControlPoints)
{ {
@ -219,11 +221,18 @@ namespace osu.Game.Rulesets.Catch.Tests
Assert.That(sliderStartY + point.Position.Y, Is.InRange(0, JuiceStreamPath.OSU_PLAYFIELD_HEIGHT)); Assert.That(sliderStartY + point.Position.Y, Is.InRange(0, JuiceStreamPath.OSU_PLAYFIELD_HEIGHT));
} }
Assert.That(sliderPath.ControlPoints[0].Position.X, Is.EqualTo(path.Vertices[0].X));
// The path is preserved only if required velocity is used.
if (velocity < requiredVelocity) continue;
Assert.That(sliderPath.Distance / velocity, Is.EqualTo(path.Duration).Within(1e-3));
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
double distance = rng.NextDouble() * path.Distance; double time = rng.NextDouble() * path.Duration;
float expected = path.PositionAtDistance(distance); float expected = path.PositionAtTime(time);
Assert.That(sliderPath.PositionAt(distance / sliderPath.Distance).X, Is.EqualTo(expected).Within(1e-3)); Assert.That(sliderPath.PositionAt(time * velocity / sliderPath.Distance).X, Is.EqualTo(expected).Within(3e-3));
} }
} }
} }
@ -244,7 +253,7 @@ namespace osu.Game.Rulesets.Catch.Tests
path.Add(20, 0); path.Add(20, 0);
checkNewId(); checkNewId();
path.RemoveVertices((v, _) => v.Distance == 20); path.RemoveVertices((v, _) => v.Time == 20);
checkNewId(); checkNewId();
path.ResampleVertices(new double[] { 5, 10, 15 }); path.ResampleVertices(new double[] { 5, 10, 15 });
@ -253,7 +262,7 @@ namespace osu.Game.Rulesets.Catch.Tests
path.Clear(); path.Clear();
checkNewId(); checkNewId();
path.ConvertFromSliderPath(new SliderPath()); path.ConvertFromSliderPath(new SliderPath(), 1);
checkNewId(); checkNewId();
void checkNewId() void checkNewId()
@ -263,25 +272,19 @@ namespace osu.Game.Rulesets.Catch.Tests
} }
} }
private void assertInvariants(IReadOnlyList<JuiceStreamPathVertex> vertices, bool checkSlope) private void assertInvariants(IReadOnlyList<JuiceStreamPathVertex> vertices)
{ {
Assert.That(vertices, Is.Not.Empty); Assert.That(vertices, Is.Not.Empty);
for (int i = 0; i < vertices.Count; i++) for (int i = 0; i < vertices.Count; i++)
{ {
Assert.That(double.IsFinite(vertices[i].Distance)); Assert.That(double.IsFinite(vertices[i].Time));
Assert.That(float.IsFinite(vertices[i].X)); Assert.That(float.IsFinite(vertices[i].X));
} }
for (int i = 1; i < vertices.Count; i++) for (int i = 1; i < vertices.Count; i++)
{ {
Assert.That(vertices[i].Distance, Is.GreaterThanOrEqualTo(vertices[i - 1].Distance)); Assert.That(vertices[i].Time, Is.GreaterThanOrEqualTo(vertices[i - 1].Time));
if (!checkSlope) continue;
float xDiff = Math.Abs(vertices[i].X - vertices[i - 1].X);
double distanceDiff = vertices[i].Distance - vertices[i - 1].Distance;
Assert.That(xDiff, Is.LessThanOrEqualTo(distanceDiff).Within(Precision.FLOAT_EPSILON));
} }
} }
} }

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Utils; using osu.Framework.Utils;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Utils; using osu.Framework.Utils;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Catch.Mods;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;

View File

@ -1,6 +1,8 @@
// 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.
#nullable disable
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;

Some files were not shown because too many files have changed in this diff Show More