Compare commits
165 Commits
fb7ccba4ba
...
old-testin
| Author | SHA1 | Date | |
|---|---|---|---|
| 17d56f8db0 | |||
| 9637ea1df7 | |||
| 0940d61f7e | |||
| e6a6352a9c | |||
|
|
734c6f933d | ||
|
|
ac213c90cb | ||
|
|
74ca87c252 | ||
|
|
032912e62b | ||
|
|
1e79c56240 | ||
| 86f0159e65 | |||
| ae5a64ba81 | |||
|
|
82256ae2de | ||
|
|
1142be45ec | ||
|
|
dcb6d71287 | ||
|
|
881a35b382 | ||
|
|
89d8b402af | ||
|
|
1d351002df | ||
| e3a7ae30cd | |||
| b6f845d99c | |||
|
|
2606f3a0b5 | ||
|
|
1c463aa060 | ||
|
|
7853abe8aa | ||
|
|
1aff418981 | ||
|
|
62e92bb242 | ||
|
|
79151ae5b4 | ||
| a1d6bda63e | |||
| 547d22a4b5 | |||
|
|
c17db2cdd0 | ||
|
|
bbdd70c843 | ||
|
|
4250a54245 | ||
|
|
40fdb8662e | ||
|
|
6ce8b0a4bc | ||
|
|
b30047def6 | ||
|
|
0ffb86262f | ||
|
|
f71eb4b980 | ||
|
|
1faf02e860 | ||
|
|
d700375e55 | ||
|
|
095a67c24e | ||
|
|
86054497d0 | ||
|
|
c4f7dee82b | ||
|
|
22825f6509 | ||
|
|
691e8bcd05 | ||
|
|
e68bab4f4b | ||
|
|
9430a62af4 | ||
| b4c530ac04 | |||
| 5af05d2479 | |||
| 43ab18ffea | |||
| 9f59259a40 | |||
| 82b3015fcc | |||
| 68f92ab57c | |||
| d76d4d9a35 | |||
|
|
bb7417c099 | ||
|
|
066e093987 | ||
|
|
56e0c3e65d | ||
|
|
89d7726903 | ||
|
|
36f1bfef07 | ||
|
|
118f07878a | ||
|
|
e144968893 | ||
|
|
d2ffea41c6 | ||
|
|
a8be9b1381 | ||
|
|
bdac75e542 | ||
|
|
5c2df50714 | ||
|
|
887d280bfa | ||
|
|
84db289779 | ||
|
|
4c0522b795 | ||
|
|
07ea9fe2a4 | ||
| 490a6fd724 | |||
|
|
f73307876e | ||
|
|
4e4aa44a02 | ||
| 237e1828f8 | |||
| 3413f722f7 | |||
| 9f779dac03 | |||
| 0727c53cdc | |||
| a57ff24191 | |||
|
|
a6c001244f | ||
|
|
107098314a | ||
|
|
d1d76a76ba | ||
|
|
2a7e71d7fd | ||
| bdb3418b67 | |||
|
|
0b4f96efc8 | ||
|
|
78c6973298 | ||
|
|
d8d7c80832 | ||
|
|
ae33690632 | ||
|
|
9e2ea63e70 | ||
|
|
79bfe7880a | ||
| 936640edeb | |||
| 1187d03333 | |||
| 3bd996ee43 | |||
| 37b9f91d42 | |||
| 1a5a5606dc | |||
| 87ff1051e9 | |||
|
|
80fbcd5fbd | ||
|
|
9c2319b989 | ||
|
|
a040143825 | ||
| 2e4b0ff197 | |||
| 499f410c94 | |||
| 616c0d8ecd | |||
| ed889138a0 | |||
| 18075bef29 | |||
| bc7780a870 | |||
| 8930b8fadb | |||
| 2d457f4305 | |||
| a784734f94 | |||
| ecfd4764e7 | |||
| f5ca5083d6 | |||
| 1d7c77d8d6 | |||
| 774e52fbd6 | |||
| a9d7a9d5d5 | |||
| f7069b1009 | |||
| c3ce5dc787 | |||
| 98076e2092 | |||
| b7d1092f90 | |||
| 08db90c278 | |||
| b7e36164c3 | |||
| 0f5f13858d | |||
| 89a0c75156 | |||
| ab7e5c94f1 | |||
| 8dc9ea4553 | |||
| dcf553c252 | |||
| 43f3a506ea | |||
| ab51579c27 | |||
| d8e977c05f | |||
| c023767df9 | |||
|
|
1867aad1a6 | ||
|
|
b1bc5cae87 | ||
| d47e26f1ae | |||
| b0e5ae1109 | |||
| 47b859ab17 | |||
| 5e523eb0b1 | |||
|
|
d912f8c3b9 | ||
| 65f275106e | |||
| 6e374762fd | |||
| 80646a166c | |||
| 8f0510d903 | |||
| 02e7000ee4 | |||
| 081355864e | |||
| 6435a835d1 | |||
|
|
038bf3fdda | ||
|
|
61c3aad537 | ||
|
|
3aad0868af | ||
|
|
973c4c8319 | ||
|
|
ac21f8b960 | ||
| 628181a883 | |||
| 835329efd3 | |||
| 5399943118 | |||
| d07f82f6f4 | |||
| 5b186bb740 | |||
| 6cb99c13c2 | |||
| 96008e06ab | |||
| 590b0a8028 | |||
| e78c8fa03d | |||
| 70f7f09a83 | |||
| 490137405f | |||
| f3c6f53f70 | |||
| 8cb5c682b4 | |||
| c3d79295d3 | |||
| f31d310135 | |||
| 26029de27d | |||
| c37f72f567 | |||
|
|
0b3b6468a5 | ||
|
|
7d1c54f045 | ||
|
|
fd504e5641 | ||
|
|
93ed0483b6 | ||
|
|
4dd0672aa5 | ||
|
|
66eff14d2b |
12
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,12 +1,6 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Help
|
- name: Help
|
||||||
url: https://github.com/ppy/osu/discussions/categories/q-a
|
url: https://t.me/jvnkosu_chat
|
||||||
about: osu! not working or performing as you'd expect? Not sure it's a bug? Check the Q&A section!
|
about: Your jvnkosu! is not working right? Please contact us using our Telegram chat
|
||||||
- name: Suggestions or feature request
|
|
||||||
url: https://github.com/ppy/osu/discussions/categories/ideas
|
|
||||||
about: Got something you think should change or be added? Search for or start a new discussion!
|
|
||||||
- name: osu!stable issues
|
|
||||||
url: https://github.com/ppy/osu-stable-issues
|
|
||||||
about: For osu!(stable) - ie. the current "live" game version, check out the dedicated repository. Note that this is for serious bug reports only, not tech support.
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
name: Update osu-web mod definitions
|
name: Update osu-web mod definitions (DO NOT USE YET!!!!!)
|
||||||
on:
|
on:
|
||||||
push:
|
workflow_dispatch:
|
||||||
tags:
|
# push:
|
||||||
- '*'
|
# tags:
|
||||||
|
# - '*'
|
||||||
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read # to fetch code (actions/checkout)
|
contents: read # to fetch code (actions/checkout)
|
||||||
10
.github/workflows/ci.yml
vendored
@@ -1,4 +1,10 @@
|
|||||||
on: [push, pull_request]
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
|
||||||
name: Continuous Integration
|
name: Continuous Integration
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
@@ -33,7 +39,7 @@ jobs:
|
|||||||
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
|
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
|
||||||
|
|
||||||
- name: Dotnet code style
|
- name: Dotnet code style
|
||||||
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf -p:EnforceCodeStyleInBuild=true
|
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
|
||||||
|
|
||||||
- name: CodeFileSanity
|
- name: CodeFileSanity
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
3
.github/workflows/deploy.yml
vendored
@@ -4,6 +4,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- '*'
|
- '*'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
notify_pending_production_deploy:
|
notify_pending_production_deploy:
|
||||||
@@ -12,7 +13,7 @@ jobs:
|
|||||||
- name: Submit pending deployment notification
|
- name: Submit pending deployment notification
|
||||||
run: |
|
run: |
|
||||||
export TITLE="Pending osu Production Deployment: $GITHUB_REF_NAME"
|
export TITLE="Pending osu Production Deployment: $GITHUB_REF_NAME"
|
||||||
export URL="https://github.com/ppy/osu/actions/runs/$GITHUB_RUN_ID"
|
export URL="https://github.com/jvnkosu-dev/client/actions/runs/$GITHUB_RUN_ID"
|
||||||
export DESCRIPTION="Awaiting approval for building NuGet packages for tag $GITHUB_REF_NAME:
|
export DESCRIPTION="Awaiting approval for building NuGet packages for tag $GITHUB_REF_NAME:
|
||||||
[View Workflow Run]($URL)"
|
[View Workflow Run]($URL)"
|
||||||
export ACTOR_ICON="https://avatars.githubusercontent.com/u/$GITHUB_ACTOR_ID"
|
export ACTOR_ICON="https://avatars.githubusercontent.com/u/$GITHUB_ACTOR_ID"
|
||||||
|
|||||||
8
.github/workflows/sentry-release.yml
vendored
@@ -21,9 +21,9 @@ jobs:
|
|||||||
uses: getsentry/action-release@v1
|
uses: getsentry/action-release@v1
|
||||||
env:
|
env:
|
||||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
SENTRY_ORG: ppy
|
SENTRY_ORG: jvnkosu
|
||||||
SENTRY_PROJECT: osu
|
SENTRY_PROJECT: client
|
||||||
SENTRY_URL: https://sentry.ppy.sh/
|
SENTRY_URL: https://satellite.jvnko.boats/
|
||||||
with:
|
with:
|
||||||
environment: production
|
environment: production
|
||||||
version: osu@${{ github.ref_name }}
|
version: jvnkosu@${{ github.ref_name }}
|
||||||
|
|||||||
1
.gitignore
vendored
@@ -19,6 +19,7 @@ bld/
|
|||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Ll]og/
|
[Ll]og/
|
||||||
|
[Pp]ub/
|
||||||
|
|
||||||
# Visual Studio 2015 cache/options directory
|
# Visual Studio 2015 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
|
|||||||
36
.vscode/launch.json
vendored
@@ -7,9 +7,9 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Debug/net8.0/osu!.dll"
|
"${workspaceFolder}/osu.Desktop/bin/Debug/net8.0/osu!.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build osu! (Debug)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Release/net8.0/osu!.dll"
|
"${workspaceFolder}/osu.Desktop/bin/Release/net8.0/osu!.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build osu! (Release)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -31,9 +31,9 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/net8.0/osu.Game.Tests.dll"
|
"${workspaceFolder}/osu.Game.Tests/bin/Debug/net8.0/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build tests (Debug)",
|
"preLaunchTask": "Build tests (Debug)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -43,9 +43,9 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/net8.0/osu.Game.Tests.dll"
|
"${workspaceFolder}/osu.Game.Tests/bin/Release/net8.0/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build tests (Release)",
|
"preLaunchTask": "Build tests (Release)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -55,10 +55,10 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Debug/net8.0/osu!.dll",
|
"${workspaceFolder}/osu.Desktop/bin/Debug/net8.0/osu!.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build osu! (Debug)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -68,10 +68,10 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Release/net8.0/osu!.dll",
|
"${workspaceFolder}/osu.Desktop/bin/Release/net8.0/osu!.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build osu! (Release)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -81,10 +81,10 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
"${workspaceFolder}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build tournament tests (Debug)",
|
"preLaunchTask": "Build tournament tests (Debug)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -94,10 +94,10 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
"${workspaceFolder}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build tournament tests (Release)",
|
"preLaunchTask": "Build tournament tests (Release)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -105,12 +105,12 @@
|
|||||||
"name": "Benchmark",
|
"name": "Benchmark",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceRoot}/osu.Game.Benchmarks/bin/Release/net8.0/osu.Game.Benchmarks.dll",
|
"program": "${workspaceFolder}/osu.Game.Benchmarks/bin/Release/net8.0/osu.Game.Benchmarks.dll",
|
||||||
"args": [
|
"args": [
|
||||||
"--filter",
|
"--filter",
|
||||||
"*"
|
"*"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build benchmarks",
|
"preLaunchTask": "Build benchmarks",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
}
|
}
|
||||||
|
|||||||
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"dotnet.defaultSolution": "osu.Desktop.slnf"
|
||||||
|
}
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
<PackageProjectUrl>https://github.com/ppy/osu</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/ppy/osu</PackageProjectUrl>
|
||||||
<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, jvnkosu! team</Company>
|
||||||
<Copyright>Copyright (c) 2025 ppy Pty Ltd</Copyright>
|
<Copyright>Copyright (c) 2025 ppy Pty Ltd</Copyright>
|
||||||
<PackageTags>osu game</PackageTags>
|
<PackageTags>osu game</PackageTags>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
19
MakeInstaller.ps1
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env powershell
|
||||||
|
param (
|
||||||
|
[string]$Version,
|
||||||
|
[string]$BuildConfig = "Release"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($Version -eq "") {
|
||||||
|
Write-Host "Usage: .\MakeInstaller.ps1 <VERSION_NUMBER> [-BuildConfig <BUILD_CONFIG>]"
|
||||||
|
Write-Host "Example: .\MakeInstaller.ps1 2025.823.0 -BuildConfig Debug"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmpPub = ".\pub"
|
||||||
|
if (-not (Test-Path -Path $tmpPub)) {
|
||||||
|
New-Item -ItemType Directory -path $tmpPub
|
||||||
|
}
|
||||||
|
|
||||||
|
dotnet publish -c $BuildConfig osu.Desktop --self-contained -r win-x64 -o $tmpPub -verbosity:m /p:Version=$Version
|
||||||
|
vpk pack --packId jvnkosu.Client --packTitle "jvnkosu!lazer" --packVersion $Version --packDir ./pub --mainExe="osu!.exe"
|
||||||
149
README.md
@@ -1,147 +1,40 @@
|
|||||||
<p align="center">
|
# jvnkosu! client
|
||||||
<img width="500" alt="osu! logo" src="assets/lazer.png">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
# osu!
|
A free-to-win rhythm game based on osu!(lazer). Click is just a *rhythm* away!
|
||||||
|
|
||||||
[](https://github.com/ppy/osu/actions/workflows/ci.yml)
|
## Disclaimer
|
||||||
[](https://github.com/ppy/osu/releases/latest)
|
|
||||||
[](https://www.codefactor.io/repository/github/ppy/osu)
|
|
||||||
[](https://discord.gg/ppy)
|
|
||||||
[](https://crowdin.com/project/osu-web)
|
|
||||||
|
|
||||||
A free-to-win rhythm game. Rhythm is just a *click* away!
|
*osu!* is a registered trademark of ppy Pty Ltd.
|
||||||
|
jvnkosu! is not affiliated with, or endorsed by ppy Pty Ltd., but makes use of its open-source components and resources.
|
||||||
|
|
||||||
This is the future – and final – iteration of the [osu!](https://osu.ppy.sh) game client which marks the beginning of an open era! Currently known by and released under the release codename "*lazer*". As in sharper than cutting-edge.
|
## License
|
||||||
|
Client source code is licensed under the MIT license, see the [LICENCE](LICENCE) file in repository root for more info.
|
||||||
|
|
||||||
## Status
|
Game assets are included as a NuGet package and licensed under the CC BY-NC 4.0, which prohibits commercial use. See [ppy/osu-resources](https://github.com/ppy/osu-resources) for more info.
|
||||||
|
|
||||||
This project is under constant development, but we do our best to keep things in a stable state. Players are encouraged to install from a release alongside their stable *osu!* client. This project will continue to evolve until we eventually reach the point where most users prefer it over the previous "osu!stable" release.
|
Registered trademarks "osu!" and "ppy" are property of ppy Pty Ltd., and protected by trademark law.
|
||||||
|
|
||||||
A few resources are available as starting points to getting involved and understanding the project:
|
## Compiling from source
|
||||||
|
Building jvnkosu! from source is pretty much possible (and welcome here).
|
||||||
|
|
||||||
- Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer).
|
First, you must have a desktop platform with [.NET Core SDK 8](https://dotnet.microsoft.com/download) installed. Windows, Linux, macOS should work well. You can check if you have the SDK installed by running `dotnet --version` in your command prompt/terminal.
|
||||||
- You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management).
|
|
||||||
- Track our current efforts [towards improving the game](https://github.com/orgs/ppy/projects/7/views/6).
|
|
||||||
|
|
||||||
## Running osu!
|
Then, download the source code. You may download it as an archive and unzip it, but using [Git](https://git-scm.com/) instead is recommended:
|
||||||
|
```
|
||||||
If you are just looking to give the game a whirl, you can grab the latest release for your platform:
|
git clone https://gitea.jvnko.boats/jvnkosu/client
|
||||||
|
|
||||||
### Latest release:
|
|
||||||
|
|
||||||
| [Windows 10+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 12+ ([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 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
|
|
||||||
|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------- | ------------- | ------------- |
|
|
||||||
|
|
||||||
You can also generally download a version for your current device from the [osu! site](https://osu.ppy.sh/home/download).
|
|
||||||
|
|
||||||
If your platform is unsupported or not listed above, there is still a chance you can run the release or manually build it by following the instructions below.
|
|
||||||
|
|
||||||
**For iOS/iPadOS users**: The iOS testflight link fills up very fast (Apple has a hard limit of 10,000 users). We reset it occasionally. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements. Our goal is to get the game on mobile app stores very soon so we don't have to live with this limitation.
|
|
||||||
|
|
||||||
## Developing a custom ruleset
|
|
||||||
|
|
||||||
osu! is designed to allow user-created gameplay variations, called "rulesets". Building one of these allows a developer to harness the power of the osu! beatmap library, game engine, and general UX for a new style of gameplay. To get started working on a ruleset, we have some templates available [here](https://github.com/ppy/osu/tree/master/Templates).
|
|
||||||
|
|
||||||
You can see some examples of custom rulesets by visiting the [custom ruleset directory](https://github.com/ppy/osu/discussions/13096).
|
|
||||||
|
|
||||||
## Developing osu!
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
Please make sure you have the following prerequisites:
|
|
||||||
|
|
||||||
- A desktop platform with the [.NET 8.0 SDK](https://dotnet.microsoft.com/download) installed.
|
|
||||||
|
|
||||||
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/) with the [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) and [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) plugin installed.
|
|
||||||
|
|
||||||
### Downloading the source code
|
|
||||||
|
|
||||||
Clone the repository:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git clone https://github.com/ppy/osu
|
|
||||||
cd osu
|
|
||||||
```
|
```
|
||||||
|
|
||||||
To update the source code to the latest commit, run the following command inside the `osu` directory:
|
|
||||||
|
|
||||||
```shell
|
To **run** the project, switch to project's directory and run the following:
|
||||||
git pull
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building
|
|
||||||
|
|
||||||
#### From an IDE
|
|
||||||
|
|
||||||
You should load the solution via one of the platform-specific `.slnf` files, rather than the main `.sln`. This will reduce dependencies and hide platforms that you don't care about. Valid `.slnf` files are:
|
|
||||||
|
|
||||||
- `osu.Desktop.slnf` (most common)
|
|
||||||
- `osu.Android.slnf`
|
|
||||||
- `osu.iOS.slnf`
|
|
||||||
|
|
||||||
Run 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 `osu! (Tests)` project/configuration. More information on this is provided [below](#contributing).
|
|
||||||
|
|
||||||
To build for mobile platforms, you will likely need to run `sudo dotnet workload restore` if you haven't done so previously. This will install Android/iOS tooling required to complete the build.
|
|
||||||
|
|
||||||
#### From CLI
|
|
||||||
|
|
||||||
You can also build and run *osu!* from the command-line with a single command:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
dotnet run --project osu.Desktop
|
dotnet run --project osu.Desktop
|
||||||
```
|
```
|
||||||
|
|
||||||
When running locally to do any kind of performance testing, make sure to add `-c Release` to the build command, as the overhead of running with the default `Debug` configuration can be large (especially when testing with local framework modifications as below).
|
To **compile**:
|
||||||
|
```
|
||||||
If the build fails, try to restore NuGet packages with `dotnet restore`.
|
dotnet build osu.Desktop
|
||||||
|
|
||||||
### Testing with resource/framework modifications
|
|
||||||
|
|
||||||
Sometimes it may be necessary to cross-test changes in [osu-resources](https://github.com/ppy/osu-resources) or [osu-framework](https://github.com/ppy/osu-framework). This can be quickly achieved using included commands:
|
|
||||||
|
|
||||||
Windows:
|
|
||||||
|
|
||||||
```ps
|
|
||||||
UseLocalFramework.ps1
|
|
||||||
UseLocalResources.ps1
|
|
||||||
```
|
```
|
||||||
|
|
||||||
macOS / Linux:
|
To reduce performance overhead in custom builds, it's recommended to build with the `-c Release` flag, that will use the release profile and remove possibly unneeded debugging code.
|
||||||
|
|
||||||
```ps
|
### See the [original readme](README.original.md) for more info.
|
||||||
UseLocalFramework.sh
|
|
||||||
UseLocalResources.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that these commands assume you have the relevant project(s) checked out in adjacent directories:
|
|
||||||
|
|
||||||
```
|
|
||||||
|- osu // this repository
|
|
||||||
|- osu-framework
|
|
||||||
|- osu-resources
|
|
||||||
```
|
|
||||||
|
|
||||||
### Code analysis
|
|
||||||
|
|
||||||
Before committing your code, please run a code formatter. This can be achieved by running `dotnet format` in the command line, or using the `Format code` command in your IDE.
|
|
||||||
|
|
||||||
We have adopted some cross-platform, compiler integrated analyzers. They can provide warnings when you are editing, building inside IDE or from command line, as-if they are provided by the compiler itself.
|
|
||||||
|
|
||||||
JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it from PowerShell with `.\InspectCode.ps1`. Alternatively, you can install ReSharper or use Rider to get inline support in your IDE of choice.
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
When it comes to contributing to the project, the two main things you can do to help out are reporting issues and submitting pull requests. Please refer to the [contributing guidelines](CONTRIBUTING.md) to understand how to help in the most effective way possible.
|
|
||||||
|
|
||||||
If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web).
|
|
||||||
|
|
||||||
We love to reward quality contributions. If you have made a large contribution, or are a regular contributor, you are welcome to [submit an expense via opencollective](https://opencollective.com/ppy/expenses/new). If you have any questions, feel free to [reach out to peppy](mailto:pe@ppy.sh) before doing so.
|
|
||||||
|
|
||||||
## Licence
|
|
||||||
|
|
||||||
*osu!*'s code and framework are licensed under the [MIT licence](https://opensource.org/licenses/MIT). Please see [the licence file](LICENCE) for more information. [tl;dr](https://tldrlegal.com/license/mit-license) you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.
|
|
||||||
|
|
||||||
Please note that this *does not cover* the usage of the "osu!" or "ppy" branding in any software, resources, advertising or promotion, as this is protected by trademark law.
|
|
||||||
|
|
||||||
Please also note that game resources are covered by a separate licence. Please see the [ppy/osu-resources](https://github.com/ppy/osu-resources) repository for clarifications.
|
|
||||||
147
README.original.md
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img width="500" alt="osu! logo" src="assets/lazer.png">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# osu!
|
||||||
|
|
||||||
|
[](https://github.com/ppy/osu/actions/workflows/ci.yml)
|
||||||
|
[](https://github.com/ppy/osu/releases/latest)
|
||||||
|
[](https://www.codefactor.io/repository/github/ppy/osu)
|
||||||
|
[](https://discord.gg/ppy)
|
||||||
|
[](https://crowdin.com/project/osu-web)
|
||||||
|
|
||||||
|
A free-to-win rhythm game. Rhythm is just a *click* away!
|
||||||
|
|
||||||
|
This is the future – and final – iteration of the [osu!](https://osu.ppy.sh) game client which marks the beginning of an open era! Currently known by and released under the release codename "*lazer*". As in sharper than cutting-edge.
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
This project is under constant development, but we do our best to keep things in a stable state. Players are encouraged to install from a release alongside their stable *osu!* client. This project will continue to evolve until we eventually reach the point where most users prefer it over the previous "osu!stable" release.
|
||||||
|
|
||||||
|
A few resources are available as starting points to getting involved and understanding the project:
|
||||||
|
|
||||||
|
- Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer).
|
||||||
|
- You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management).
|
||||||
|
- Track our current efforts [towards improving the game](https://github.com/orgs/ppy/projects/7/views/6).
|
||||||
|
|
||||||
|
## Running osu!
|
||||||
|
|
||||||
|
If you are just looking to give the game a whirl, you can grab the latest release for your platform:
|
||||||
|
|
||||||
|
### Latest release:
|
||||||
|
|
||||||
|
| [Windows 10+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 12+ ([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 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
|
||||||
|
|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------- | ------------- | ------------- |
|
||||||
|
|
||||||
|
You can also generally download a version for your current device from the [osu! site](https://osu.ppy.sh/home/download).
|
||||||
|
|
||||||
|
If your platform is unsupported or not listed above, there is still a chance you can run the release or manually build it by following the instructions below.
|
||||||
|
|
||||||
|
**For iOS/iPadOS users**: The iOS testflight link fills up very fast (Apple has a hard limit of 10,000 users). We reset it occasionally. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements. Our goal is to get the game on mobile app stores very soon so we don't have to live with this limitation.
|
||||||
|
|
||||||
|
## Developing a custom ruleset
|
||||||
|
|
||||||
|
osu! is designed to allow user-created gameplay variations, called "rulesets". Building one of these allows a developer to harness the power of the osu! beatmap library, game engine, and general UX for a new style of gameplay. To get started working on a ruleset, we have some templates available [here](https://github.com/ppy/osu/tree/master/Templates).
|
||||||
|
|
||||||
|
You can see some examples of custom rulesets by visiting the [custom ruleset directory](https://github.com/ppy/osu/discussions/13096).
|
||||||
|
|
||||||
|
## Developing osu!
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
Please make sure you have the following prerequisites:
|
||||||
|
|
||||||
|
- A desktop platform with the [.NET 8.0 SDK](https://dotnet.microsoft.com/download) installed.
|
||||||
|
|
||||||
|
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/) with the [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) and [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) plugin installed.
|
||||||
|
|
||||||
|
### Downloading the source code
|
||||||
|
|
||||||
|
Clone the repository:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/ppy/osu
|
||||||
|
cd osu
|
||||||
|
```
|
||||||
|
|
||||||
|
To update the source code to the latest commit, run the following command inside the `osu` directory:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git pull
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
#### From an IDE
|
||||||
|
|
||||||
|
You should load the solution via one of the platform-specific `.slnf` files, rather than the main `.sln`. This will reduce dependencies and hide platforms that you don't care about. Valid `.slnf` files are:
|
||||||
|
|
||||||
|
- `osu.Desktop.slnf` (most common)
|
||||||
|
- `osu.Android.slnf`
|
||||||
|
- `osu.iOS.slnf`
|
||||||
|
|
||||||
|
Run 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 `osu! (Tests)` project/configuration. More information on this is provided [below](#contributing).
|
||||||
|
|
||||||
|
To build for mobile platforms, you will likely need to run `sudo dotnet workload restore` if you haven't done so previously. This will install Android/iOS tooling required to complete the build.
|
||||||
|
|
||||||
|
#### From CLI
|
||||||
|
|
||||||
|
You can also build and run *osu!* from the command-line with a single command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dotnet run --project osu.Desktop
|
||||||
|
```
|
||||||
|
|
||||||
|
When running locally to do any kind of performance testing, make sure to add `-c Release` to the build command, as the overhead of running with the default `Debug` configuration can be large (especially when testing with local framework modifications as below).
|
||||||
|
|
||||||
|
If the build fails, try to restore NuGet packages with `dotnet restore`.
|
||||||
|
|
||||||
|
### Testing with resource/framework modifications
|
||||||
|
|
||||||
|
Sometimes it may be necessary to cross-test changes in [osu-resources](https://github.com/ppy/osu-resources) or [osu-framework](https://github.com/ppy/osu-framework). This can be quickly achieved using included commands:
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
|
||||||
|
```ps
|
||||||
|
UseLocalFramework.ps1
|
||||||
|
UseLocalResources.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
macOS / Linux:
|
||||||
|
|
||||||
|
```ps
|
||||||
|
UseLocalFramework.sh
|
||||||
|
UseLocalResources.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that these commands assume you have the relevant project(s) checked out in adjacent directories:
|
||||||
|
|
||||||
|
```
|
||||||
|
|- osu // this repository
|
||||||
|
|- osu-framework
|
||||||
|
|- osu-resources
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code analysis
|
||||||
|
|
||||||
|
Before committing your code, please run a code formatter. This can be achieved by running `dotnet format` in the command line, or using the `Format code` command in your IDE.
|
||||||
|
|
||||||
|
We have adopted some cross-platform, compiler integrated analyzers. They can provide warnings when you are editing, building inside IDE or from command line, as-if they are provided by the compiler itself.
|
||||||
|
|
||||||
|
JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it from PowerShell with `.\InspectCode.ps1`. Alternatively, you can install ReSharper or use Rider to get inline support in your IDE of choice.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
When it comes to contributing to the project, the two main things you can do to help out are reporting issues and submitting pull requests. Please refer to the [contributing guidelines](CONTRIBUTING.md) to understand how to help in the most effective way possible.
|
||||||
|
|
||||||
|
If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web).
|
||||||
|
|
||||||
|
We love to reward quality contributions. If you have made a large contribution, or are a regular contributor, you are welcome to [submit an expense via opencollective](https://opencollective.com/ppy/expenses/new). If you have any questions, feel free to [reach out to peppy](mailto:pe@ppy.sh) before doing so.
|
||||||
|
|
||||||
|
## Licence
|
||||||
|
|
||||||
|
*osu!*'s code and framework are licensed under the [MIT licence](https://opensource.org/licenses/MIT). Please see [the licence file](LICENCE) for more information. [tl;dr](https://tldrlegal.com/license/mit-license) you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.
|
||||||
|
|
||||||
|
Please note that this *does not cover* the usage of the "osu!" or "ppy" branding in any software, resources, advertising or promotion, as this is protected by trademark law.
|
||||||
|
|
||||||
|
Please also note that game resources are covered by a separate licence. Please see the [ppy/osu-resources](https://github.com/ppy/osu-resources) repository for clarifications.
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageType>Template</PackageType>
|
<PackageType>Template</PackageType>
|
||||||
<PackageId>ppy.osu.Game.Templates</PackageId>
|
<PackageId>jvnkosu.Client.Templates</PackageId>
|
||||||
<Title>osu! templates</Title>
|
<Title>osu! templates</Title>
|
||||||
<Authors>ppy Pty Ltd</Authors>
|
<Authors>ppy Pty Ltd</Authors>
|
||||||
<PackageLicenseUrl>https://github.com/ppy/osu/blob/master/LICENCE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/ppy/osu/blob/master/LICENCE</PackageLicenseUrl>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="sh.ppy.osulazer" android:installLocation="auto">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="boats.jvnko.osu.android" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
|
||||||
<application android:allowBackup="true"
|
<application android:allowBackup="true"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace osu.Desktop
|
|||||||
{
|
{
|
||||||
internal partial class DiscordRichPresence : Component
|
internal partial class DiscordRichPresence : Component
|
||||||
{
|
{
|
||||||
private const string client_id = "1216669957799018608";
|
private const string client_id = "1440647613358800918";
|
||||||
|
|
||||||
private DiscordRpcClient client = null!;
|
private DiscordRpcClient client = null!;
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ namespace osu.Desktop
|
|||||||
if (IsPackageManaged)
|
if (IsPackageManaged)
|
||||||
return new NoActionUpdateManager();
|
return new NoActionUpdateManager();
|
||||||
|
|
||||||
return new VelopackUpdateManager();
|
return new VelopackUpdateManager(); // yay
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool RestartAppWhenExited()
|
public override bool RestartAppWhenExited()
|
||||||
@@ -148,7 +148,13 @@ namespace osu.Desktop
|
|||||||
|
|
||||||
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
|
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
|
||||||
if (iconStream != null)
|
if (iconStream != null)
|
||||||
host.Window.SetIconFromStream(iconStream);
|
try
|
||||||
|
{
|
||||||
|
host.Window.SetIconFromStream(iconStream);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
host.Window.Title = Name;
|
host.Window.Title = Name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ namespace osu.Desktop
|
|||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
private const string base_game_name = @"osu-development";
|
private const string base_game_name = @"jvnkosu-development";
|
||||||
#else
|
#else
|
||||||
private const string base_game_name = @"osu";
|
private const string base_game_name = @"jvnkosu";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private static LegacyTcpIpcProvider? legacyIpc;
|
private static LegacyTcpIpcProvider? legacyIpc;
|
||||||
@@ -44,7 +44,7 @@ namespace osu.Desktop
|
|||||||
|
|
||||||
// While .NET 8 only supports Windows 10 and above, running on Windows 7/8.1 may still work. We are limited by realm currently, as they choose to only support 8.1 and higher.
|
// While .NET 8 only supports Windows 10 and above, running on Windows 7/8.1 may still work. We are limited by realm currently, as they choose to only support 8.1 and higher.
|
||||||
// See https://www.mongodb.com/docs/realm/sdk/dotnet/compatibility/
|
// See https://www.mongodb.com/docs/realm/sdk/dotnet/compatibility/
|
||||||
if (windowsVersion.Major < 6 || (windowsVersion.Major == 6 && windowsVersion.Minor <= 2))
|
if (windowsVersion.Major < 6)
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
@@ -53,13 +53,26 @@ namespace osu.Desktop
|
|||||||
// We could also better detect compatibility mode if required:
|
// We could also better detect compatibility mode if required:
|
||||||
// https://stackoverflow.com/questions/10744651/how-i-can-detect-if-my-application-is-running-under-compatibility-mode#comment58183249_10744730
|
// https://stackoverflow.com/questions/10744651/how-i-can-detect-if-my-application-is-running-under-compatibility-mode#comment58183249_10744730
|
||||||
SDL3.SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR,
|
SDL3.SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR,
|
||||||
"Your operating system is too old to run osu!"u8,
|
"Your operating system is too old to run this game!"u8,
|
||||||
"This version of osu! requires at least Windows 8.1 to run.\n"u8
|
"This version of the game requires at least Windows 8.1 to run reliably.\n"u8
|
||||||
+ "Please upgrade your operating system or consider using an older version of osu!.\n\n"u8
|
+ "You may try to run it on Windows 8 or older, but it's not guaranteed to actually work.\n\n"u8
|
||||||
+ "If you are running a newer version of windows, please check you don't have \"Compatibility mode\" turned on for osu!"u8, null);
|
+ "Please upgrade your operating system or consider using an older game version.\n\n"u8
|
||||||
|
+ "If you are running a newer version of Windows, please check you don't have \"Compatibility mode\" turned on for the game's executable."u8, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (windowsVersion.Major == 6 && windowsVersion.Minor <= 2)
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
SDL3.SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_WARNING,
|
||||||
|
"Your operating system is too old to run this game!"u8,
|
||||||
|
"While the version of Windows you're using may be able to launch it, it's likely to work unreliably and crash.\n"u8
|
||||||
|
+ "Please upgrade your operating system or consider using an older game version.\n\n"u8
|
||||||
|
+ "If you are running a newer version of Windows, please check you don't have \"Compatibility mode\" turned on for the game's executable."u8, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NVIDIA profiles are based on the executable name of a process.
|
// NVIDIA profiles are based on the executable name of a process.
|
||||||
@@ -208,9 +221,10 @@ namespace osu.Desktop
|
|||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
private static void configureWindows(VelopackApp app)
|
private static void configureWindows(VelopackApp app)
|
||||||
{
|
{
|
||||||
app.OnFirstRun(_ => WindowsAssociationManager.InstallAssociations());
|
// we do not want associations here, as that breaks official lazer's associations
|
||||||
app.OnAfterUpdateFastCallback(_ => WindowsAssociationManager.UpdateAssociations());
|
// app.OnFirstRun(_ => WindowsAssociationManager.InstallAssociations());
|
||||||
app.OnBeforeUninstallFastCallback(_ => WindowsAssociationManager.UninstallAssociations());
|
// app.OnAfterUpdateFastCallback(_ => WindowsAssociationManager.UpdateAssociations());
|
||||||
|
// app.OnBeforeUninstallFastCallback(_ => WindowsAssociationManager.UninstallAssociations());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace osu.Desktop.Updater
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IUpdateSource updateSource = new GithubSource(@"https://github.com/ppy/osu", null, ReleaseStream.Value == Game.Configuration.ReleaseStream.Tachyon);
|
IUpdateSource updateSource = new GiteaSource(@"https://gitea.jvnko.boats/jvnkosu/client", null, ReleaseStream.Value == Game.Configuration.ReleaseStream.Tachyon);
|
||||||
Velopack.UpdateManager updateManager = new Velopack.UpdateManager(updateSource, new UpdateOptions
|
Velopack.UpdateManager updateManager = new Velopack.UpdateManager(updateSource, new UpdateOptions
|
||||||
{
|
{
|
||||||
AllowVersionDowngrade = true
|
AllowVersionDowngrade = true
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ namespace osu.Desktop.Windows
|
|||||||
|
|
||||||
private static readonly UriAssociation[] uri_associations =
|
private static readonly UriAssociation[] uri_associations =
|
||||||
{
|
{
|
||||||
new UriAssociation(@"osu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
|
new UriAssociation(@"jvnkosu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
|
||||||
new UriAssociation(@"osump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
|
new UriAssociation(@"jvnkosump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 401 KiB |
@@ -3,11 +3,11 @@
|
|||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Description>A free-to-win rhythm game. Rhythm is just a *click* away!</Description>
|
<Description>A free-to-win rhythm game based on osu!(lazer). Click is just a *rhythm* away!</Description>
|
||||||
<AssemblyName>osu!</AssemblyName>
|
<AssemblyName>osu!</AssemblyName>
|
||||||
<AssemblyTitle>osu!(lazer)</AssemblyTitle>
|
<AssemblyTitle>jvnkosu!</AssemblyTitle>
|
||||||
<Title>osu!</Title>
|
<Title>jvnkosu!</Title>
|
||||||
<Product>osu!(lazer)</Product>
|
<Product>jvnkosu!</Product>
|
||||||
<ApplicationIcon>lazer.ico</ApplicationIcon>
|
<ApplicationIcon>lazer.ico</ApplicationIcon>
|
||||||
<Version>0.0.0</Version>
|
<Version>0.0.0</Version>
|
||||||
<FileVersion>0.0.0</FileVersion>
|
<FileVersion>0.0.0</FileVersion>
|
||||||
|
|||||||
@@ -3,16 +3,19 @@
|
|||||||
<metadata>
|
<metadata>
|
||||||
<id>osulazer</id>
|
<id>osulazer</id>
|
||||||
<version>0.0.0</version>
|
<version>0.0.0</version>
|
||||||
<title>osu!</title>
|
<title>jvnkosu!</title>
|
||||||
<authors>ppy Pty Ltd</authors>
|
<authors>ppy Pty Ltd., jvnkosu! team</authors>
|
||||||
<owners>Dean Herbert</owners>
|
<owners>Dean Herbert</owners>
|
||||||
<projectUrl>https://osu.ppy.sh/</projectUrl>
|
<projectUrl>https://osu.jvnko.boats/</projectUrl>
|
||||||
<iconUrl>https://github.com/ppy/osu/blob/master/assets/lazer-nuget.png?raw=true</iconUrl>
|
<iconUrl>https://github.com/ppy/osu/blob/master/assets/lazer-nuget.png?raw=true</iconUrl>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<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 based on osu!(lazer). Click is just a *rhythm* away!</description>
|
||||||
<releaseNotes>testing</releaseNotes>
|
<releaseNotes>testing</releaseNotes>
|
||||||
<copyright>Copyright (c) 2025 ppy Pty Ltd</copyright>
|
<copyright>
|
||||||
|
Copyright (c) 2025 ppy Pty Ltd
|
||||||
|
Copyright (c) 2025 jvnkosu! team
|
||||||
|
</copyright>
|
||||||
<language>en-AU</language>
|
<language>en-AU</language>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Label="Nuget">
|
<PropertyGroup Label="Nuget">
|
||||||
<Title>osu!catch (ruleset)</Title>
|
<Title>osu!catch (ruleset)</Title>
|
||||||
<PackageId>ppy.osu.Game.Rulesets.Catch</PackageId>
|
<PackageId>jvnkosu.Client.Rulesets.Catch</PackageId>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Acronym => Name;
|
public override string Acronym => Name;
|
||||||
public abstract int KeyCount { get; }
|
public abstract int KeyCount { get; }
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
public override double ScoreMultiplier => 0.9;
|
public override double ScoreMultiplier => 1;
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter)
|
public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
typeof(ManiaModFadeIn)
|
typeof(ManiaModFadeIn)
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
|
|
||||||
public override bool Ranked => false;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public override bool ValidForFreestyleAsRequiredMod => false;
|
public override bool ValidForFreestyleAsRequiredMod => false;
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,13 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
MinValue = 0,
|
MinValue = 0,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
// Use larger extended limits for mania to include OD values that occur with EZ or HR enabled
|
// Use larger extended limits for mania to include OD values that occur with EZ or HR enabled
|
||||||
|
#if !DEBUG
|
||||||
ExtendedMaxValue = 15,
|
ExtendedMaxValue = 15,
|
||||||
ExtendedMinValue = -15,
|
ExtendedMinValue = -15,
|
||||||
|
#else
|
||||||
|
ExtendedMinValue = -250,
|
||||||
|
ExtendedMaxValue = 50,
|
||||||
|
#endif
|
||||||
ReadCurrentFromDifficulty = diff => diff.OverallDifficulty,
|
ReadCurrentFromDifficulty = diff => diff.OverallDifficulty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public class ManiaModHardRock : ModHardRock, IApplicableToHitObject
|
public class ManiaModHardRock : ModHardRock, IApplicableToHitObject
|
||||||
{
|
{
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override bool Ranked => false;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public const double HIT_WINDOW_DIFFICULTY_MULTIPLIER = 1.4;
|
public const double HIT_WINDOW_DIFFICULTY_MULTIPLIER = 1.4;
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,5 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Acronym => "1K";
|
public override string Acronym => "1K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModOneKey;
|
public override IconUsage? Icon => OsuIcon.ModOneKey;
|
||||||
public override LocalisableString Description => @"Play with one key.";
|
public override LocalisableString Description => @"Play with one key.";
|
||||||
public override bool Ranked => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,5 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Acronym => "10K";
|
public override string Acronym => "10K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModTenKeys;
|
public override IconUsage? Icon => OsuIcon.ModTenKeys;
|
||||||
public override LocalisableString Description => @"Play with ten keys.";
|
public override LocalisableString Description => @"Play with ten keys.";
|
||||||
public override bool Ranked => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,5 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Acronym => "2K";
|
public override string Acronym => "2K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModTwoKeys;
|
public override IconUsage? Icon => OsuIcon.ModTwoKeys;
|
||||||
public override LocalisableString Description => @"Play with two keys.";
|
public override LocalisableString Description => @"Play with two keys.";
|
||||||
public override bool Ranked => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,5 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Acronym => "3K";
|
public override string Acronym => "3K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModThreeKeys;
|
public override IconUsage? Icon => OsuIcon.ModThreeKeys;
|
||||||
public override LocalisableString Description => @"Play with three keys.";
|
public override LocalisableString Description => @"Play with three keys.";
|
||||||
public override bool Ranked => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public class ManiaModMirror : ModMirror, IApplicableToBeatmap
|
public class ManiaModMirror : ModMirror, IApplicableToBeatmap
|
||||||
{
|
{
|
||||||
public override LocalisableString Description => "Notes are flipped horizontally.";
|
public override LocalisableString Description => "Notes are flipped horizontally.";
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public void ApplyToBeatmap(IBeatmap beatmap)
|
public void ApplyToBeatmap(IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Label="Nuget">
|
<PropertyGroup Label="Nuget">
|
||||||
<Title>osu!mania (ruleset)</Title>
|
<Title>osu!mania (ruleset)</Title>
|
||||||
<PackageId>ppy.osu.Game.Rulesets.Mania</PackageId>
|
<PackageId>jvnkosu.Client.Rulesets.Mania</PackageId>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
// 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 NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
|
{
|
||||||
|
public partial class TestSceneGameplayCursorSizeChange : PlayerTestScene
|
||||||
|
{
|
||||||
|
private const float initial_cursor_size = 1f;
|
||||||
|
protected override Ruleset CreatePlayerRuleset() => new OsuRuleset();
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private SkinManager? skins { get; set; }
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
if (skins != null) skins.CurrentSkinInfo.Value = skins.DefaultClassicSkin.SkinInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
|
||||||
|
AddStep("Set gameplay cursor size: 1", () => LocalConfig.SetValue(OsuSetting.GameplayCursorSize, initial_cursor_size));
|
||||||
|
AddStep("resume player", () => Player.GameplayClockContainer.Start());
|
||||||
|
AddUntilStep("clock running", () => Player.GameplayClockContainer.IsRunning);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPausedChangeCursorSize()
|
||||||
|
{
|
||||||
|
AddStep("move cursor to center", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.Centre));
|
||||||
|
AddStep("move cursor to top left", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopLeft));
|
||||||
|
AddStep("move cursor to center", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.Centre));
|
||||||
|
AddStep("move cursor to top right", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopRight));
|
||||||
|
AddStep("press escape", () => InputManager.Key(Key.Escape));
|
||||||
|
|
||||||
|
AddSliderStep("cursor size", 0.1f, 2f, 1f, v => LocalConfig.SetValue(OsuSetting.GameplayCursorSize, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,13 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModMagnetised), typeof(OsuModRepel), typeof(OsuModAutopilot), typeof(OsuModSpunOut), typeof(OsuModAlternate), typeof(OsuModSingleTap) }).ToArray();
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModMagnetised), typeof(OsuModRepel), typeof(OsuModAutopilot), typeof(OsuModSpunOut), typeof(OsuModAlternate), typeof(OsuModSingleTap) }).ToArray();
|
||||||
|
|
||||||
|
#if !DEBUG
|
||||||
|
private string username = "Autoplay";
|
||||||
|
#else
|
||||||
|
private string username = "Chicony";
|
||||||
|
#endif
|
||||||
|
|
||||||
public override ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList<Mod> mods)
|
public override ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||||
=> new ModReplayData(new OsuAutoGenerator(beatmap, mods).Generate(), new ModCreatedUser { Username = "Autoplay" });
|
=> new ModReplayData(new OsuAutoGenerator(beatmap, mods).Generate(), new ModCreatedUser { Username = username });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,19 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public partial class OsuModDifficultyAdjust : ModDifficultyAdjust
|
public partial class OsuModDifficultyAdjust : ModDifficultyAdjust
|
||||||
{
|
{
|
||||||
|
|
||||||
[SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1, SettingControlType = typeof(DifficultyAdjustSettingsControl))]
|
[SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1, SettingControlType = typeof(DifficultyAdjustSettingsControl))]
|
||||||
public DifficultyBindable CircleSize { get; } = new DifficultyBindable
|
public DifficultyBindable CircleSize { get; } = new DifficultyBindable
|
||||||
{
|
{
|
||||||
Precision = 0.1f,
|
Precision = 0.1f,
|
||||||
MinValue = 0,
|
MinValue = 0,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
|
#if !DEBUG
|
||||||
ExtendedMaxValue = 11,
|
ExtendedMaxValue = 11,
|
||||||
|
#else
|
||||||
|
ExtendedMinValue = -250,
|
||||||
|
ExtendedMaxValue = 13,
|
||||||
|
#endif
|
||||||
ReadCurrentFromDifficulty = diff => diff.CircleSize,
|
ReadCurrentFromDifficulty = diff => diff.CircleSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -32,8 +38,13 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
Precision = 0.1f,
|
Precision = 0.1f,
|
||||||
MinValue = 0,
|
MinValue = 0,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
|
#if !DEBUG
|
||||||
ExtendedMinValue = -10,
|
ExtendedMinValue = -10,
|
||||||
ExtendedMaxValue = 11,
|
ExtendedMaxValue = 11,
|
||||||
|
#else
|
||||||
|
ExtendedMinValue = -250,
|
||||||
|
ExtendedMaxValue = 13,
|
||||||
|
#endif
|
||||||
ReadCurrentFromDifficulty = diff => diff.ApproachRate,
|
ReadCurrentFromDifficulty = diff => diff.ApproachRate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override LocalisableString Description => @"Spinners will be automatically completed.";
|
public override LocalisableString Description => @"Spinners will be automatically completed.";
|
||||||
public override double ScoreMultiplier => 0.9;
|
public override double ScoreMultiplier => 0.9;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTargetPractice) };
|
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTargetPractice) };
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public void ApplyToDrawableHitObject(DrawableHitObject hitObject)
|
public void ApplyToDrawableHitObject(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public class OsuModTouchDevice : ModTouchDevice
|
public class OsuModTouchDevice : ModTouchDevice
|
||||||
{
|
{
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModBloom) }).ToArray();
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModBloom) }).ToArray();
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -230,6 +230,11 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
new ModScoreV2(),
|
new ModScoreV2(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case ModType.Special:
|
||||||
|
#if DEBUG
|
||||||
|
return Array.Empty<Mod>();
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Array.Empty<Mod>();
|
return Array.Empty<Mod>();
|
||||||
}
|
}
|
||||||
@@ -249,7 +254,11 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
|
|
||||||
public override string ShortName => SHORT_NAME;
|
public override string ShortName => SHORT_NAME;
|
||||||
|
|
||||||
|
#if !DEBUG
|
||||||
public override string PlayingVerb => "Clicking circles";
|
public override string PlayingVerb => "Clicking circles";
|
||||||
|
#else
|
||||||
|
public override string PlayingVerb => "Debugging circles";
|
||||||
|
#endif
|
||||||
|
|
||||||
public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this);
|
public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this);
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Label="Nuget">
|
<PropertyGroup Label="Nuget">
|
||||||
<Title>osu! (ruleset)</Title>
|
<Title>osu! (ruleset)</Title>
|
||||||
<PackageId>ppy.osu.Game.Rulesets.Osu</PackageId>
|
<PackageId>jvnkosu.Client.Rulesets.Osu</PackageId>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Label="Nuget">
|
<PropertyGroup Label="Nuget">
|
||||||
<Title>osu!taiko (ruleset)</Title>
|
<Title>osu!taiko (ruleset)</Title>
|
||||||
<PackageId>ppy.osu.Game.Rulesets.Taiko</PackageId>
|
<PackageId>jvnkosu.Client.Rulesets.Taiko</PackageId>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
public void OneTimeSetUp()
|
public void OneTimeSetUp()
|
||||||
{
|
{
|
||||||
originalWebsiteRootUrl = MessageFormatter.WebsiteRootUrl;
|
originalWebsiteRootUrl = MessageFormatter.WebsiteRootUrl;
|
||||||
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";
|
MessageFormatter.WebsiteRootUrl = "osu.jvnko.boats";
|
||||||
}
|
}
|
||||||
|
|
||||||
[OneTimeTearDown]
|
[OneTimeTearDown]
|
||||||
@@ -47,11 +47,11 @@ namespace osu.Game.Tests.Chat
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSupportedProtocolLinkParsing()
|
public void TestSupportedProtocolLinkParsing()
|
||||||
{
|
{
|
||||||
Message result = MessageFormatter.FormatMessage(new Message { Content = "forgotspacehttps://dev.ppy.sh joinmyosump://12345 jointheosu://chan/#english" });
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "forgotspacehttps://osu.jvnko.boats joinmyjvnkosump://12345 jointhejvnkosu://chan/#english" });
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh", result.Links[0].Url);
|
Assert.AreEqual("https://osu.jvnko.boats", result.Links[0].Url);
|
||||||
Assert.AreEqual("osump://12345", result.Links[1].Url);
|
Assert.AreEqual("jvnkosump://12345", result.Links[1].Url);
|
||||||
Assert.AreEqual("osu://chan/#english", result.Links[2].Url);
|
Assert.AreEqual("jvnkosu://chan/#english", result.Links[2].Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -66,15 +66,15 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual(36, result.Links[0].Length);
|
Assert.AreEqual(36, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456")]
|
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123#osu/456")]
|
||||||
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456?whatever")]
|
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123#osu/456?whatever")]
|
||||||
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123/456")]
|
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123/456")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc/def", "https://dev.ppy.sh/beatmapsets/abc/def")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/abc/def", "https://osu.jvnko.boats/beatmapsets/abc/def")]
|
||||||
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123")]
|
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://osu.jvnko.boats/beatmapsets/123")]
|
||||||
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123/whatever")]
|
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://osu.jvnko.boats/beatmapsets/123/whatever")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc", "https://dev.ppy.sh/beatmapsets/abc")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/abc", "https://osu.jvnko.boats/beatmapsets/abc")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions", "https://dev.ppy.sh/beatmapsets/discussions")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/discussions", "https://osu.jvnko.boats/beatmapsets/discussions")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions/123", "https://dev.ppy.sh/beatmapsets/discussions/123")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/discussions/123", "https://osu.jvnko.boats/beatmapsets/discussions/123")]
|
||||||
public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link)
|
public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link)
|
||||||
{
|
{
|
||||||
Message result = MessageFormatter.FormatMessage(new Message { Content = link });
|
Message result = MessageFormatter.FormatMessage(new Message { Content = link });
|
||||||
@@ -150,7 +150,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
|
|
||||||
Assert.AreEqual("This is a Wiki Link.", result.DisplayContent);
|
Assert.AreEqual("This is a Wiki Link.", result.DisplayContent);
|
||||||
Assert.AreEqual(1, result.Links.Count);
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki Link", result.Links[0].Url);
|
||||||
Assert.AreEqual(10, result.Links[0].Index);
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
Assert.AreEqual(9, result.Links[0].Length);
|
Assert.AreEqual(9, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
@@ -163,15 +163,15 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual("This is a Wiki Link Wiki:LinkWiki.Link.", result.DisplayContent);
|
Assert.AreEqual("This is a Wiki Link Wiki:LinkWiki.Link.", result.DisplayContent);
|
||||||
Assert.AreEqual(3, result.Links.Count);
|
Assert.AreEqual(3, result.Links.Count);
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki Link", result.Links[0].Url);
|
||||||
Assert.AreEqual(10, result.Links[0].Index);
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
Assert.AreEqual(9, result.Links[0].Length);
|
Assert.AreEqual(9, result.Links[0].Length);
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki:Link", result.Links[1].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki:Link", result.Links[1].Url);
|
||||||
Assert.AreEqual(20, result.Links[1].Index);
|
Assert.AreEqual(20, result.Links[1].Index);
|
||||||
Assert.AreEqual(9, result.Links[1].Length);
|
Assert.AreEqual(9, result.Links[1].Length);
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki.Link", result.Links[2].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki.Link", result.Links[2].Url);
|
||||||
Assert.AreEqual(29, result.Links[2].Index);
|
Assert.AreEqual(29, result.Links[2].Index);
|
||||||
Assert.AreEqual(9, result.Links[2].Length);
|
Assert.AreEqual(9, result.Links[2].Length);
|
||||||
}
|
}
|
||||||
@@ -452,7 +452,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual(1, result.Links.Count);
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
Assert.AreEqual($"{OsuGameBase.OSU_PROTOCOL}chan/#english", result.Links[0].Url);
|
Assert.AreEqual($"{OsuGameBase.OSU_PROTOCOL}chan/#english", result.Links[0].Url);
|
||||||
Assert.AreEqual(26, result.Links[0].Index);
|
Assert.AreEqual(26, result.Links[0].Index);
|
||||||
Assert.AreEqual(19, result.Links[0].Length);
|
Assert.AreEqual(23, result.Links[0].Length);
|
||||||
|
|
||||||
result = MessageFormatter.FormatMessage(new Message { Content = $"This is a [custom protocol]({OsuGameBase.OSU_PROTOCOL}chan/#english)." });
|
result = MessageFormatter.FormatMessage(new Message { Content = $"This is a [custom protocol]({OsuGameBase.OSU_PROTOCOL}chan/#english)." });
|
||||||
|
|
||||||
@@ -467,13 +467,13 @@ namespace osu.Game.Tests.Chat
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestOsuMpProtocol()
|
public void TestOsuMpProtocol()
|
||||||
{
|
{
|
||||||
Message result = MessageFormatter.FormatMessage(new Message { Content = "Join my multiplayer game osump://12346." });
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "Join my multiplayer game jvnkosump://12346." });
|
||||||
|
|
||||||
Assert.AreEqual(result.Content, result.DisplayContent);
|
Assert.AreEqual(result.Content, result.DisplayContent);
|
||||||
Assert.AreEqual(1, result.Links.Count);
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
Assert.AreEqual("osump://12346", result.Links[0].Url);
|
Assert.AreEqual("jvnkosump://12346", result.Links[0].Url);
|
||||||
Assert.AreEqual(25, result.Links[0].Index);
|
Assert.AreEqual(25, result.Links[0].Index);
|
||||||
Assert.AreEqual(13, result.Links[0].Length);
|
Assert.AreEqual(17, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -499,7 +499,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual("This is a simple test with some [traps] and wiki links. Don't forget to visit https://osu.ppy.sh now![emoji]", result.DisplayContent);
|
Assert.AreEqual("This is a simple test with some [traps] and wiki links. Don't forget to visit https://osu.ppy.sh now![emoji]", result.DisplayContent);
|
||||||
Assert.AreEqual(4, result.Links.Count);
|
Assert.AreEqual(4, result.Links.Count);
|
||||||
|
|
||||||
Link f = result.Links.Find(l => l.Url == "https://dev.ppy.sh/wiki/wiki links");
|
Link f = result.Links.Find(l => l.Url == "https://osu.jvnko.boats/wiki/wiki links");
|
||||||
Assert.That(f, Is.Not.Null);
|
Assert.That(f, Is.Not.Null);
|
||||||
Assert.AreEqual(44, f.Index);
|
Assert.AreEqual(44, f.Index);
|
||||||
Assert.AreEqual(10, f.Length);
|
Assert.AreEqual(10, f.Length);
|
||||||
@@ -554,8 +554,8 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual("/relative", result.Argument);
|
Assert.AreEqual("/relative", result.Argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("https://dev.ppy.sh/home/changelog", "")]
|
[TestCase("https://osu.jvnko.boats/home/changelog", "")]
|
||||||
[TestCase("https://dev.ppy.sh/home/changelog/lazer/2021.1012", "lazer/2021.1012")]
|
[TestCase("https://osu.jvnko.boats/home/changelog/lazer/2021.1012", "lazer/2021.1012")]
|
||||||
public void TestChangelogLinks(string link, string expectedArg)
|
public void TestChangelogLinks(string link, string expectedArg)
|
||||||
{
|
{
|
||||||
LinkDetails result = MessageFormatter.GetLinkDetails(link);
|
LinkDetails result = MessageFormatter.GetLinkDetails(link);
|
||||||
|
|||||||
@@ -134,10 +134,12 @@ namespace osu.Game.Tests.Mods
|
|||||||
|
|
||||||
var mod = (OsuModDifficultyAdjust)apiMod.ToMod(ruleset);
|
var mod = (OsuModDifficultyAdjust)apiMod.ToMod(ruleset);
|
||||||
|
|
||||||
|
// WARNING: this only makes sense for debug builds which have very extended limits
|
||||||
|
// release builds still use sane values
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(mod.CircleSize.Value, Is.GreaterThanOrEqualTo(0).And.LessThanOrEqualTo(11));
|
Assert.That(mod.CircleSize.Value, Is.GreaterThanOrEqualTo(-250).And.LessThanOrEqualTo(13));
|
||||||
Assert.That(mod.ApproachRate.Value, Is.GreaterThanOrEqualTo(-10).And.LessThanOrEqualTo(11));
|
Assert.That(mod.ApproachRate.Value, Is.GreaterThanOrEqualTo(-250).And.LessThanOrEqualTo(13));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace osu.Game.Tests.Online
|
|||||||
Assert.NotNull(converted);
|
Assert.NotNull(converted);
|
||||||
Assert.That(converted, Is.TypeOf(typeof(UnknownMod)));
|
Assert.That(converted, Is.TypeOf(typeof(UnknownMod)));
|
||||||
Assert.That(converted.Type, Is.EqualTo(ModType.System));
|
Assert.That(converted.Type, Is.EqualTo(ModType.System));
|
||||||
Assert.That(converted.Acronym, Is.EqualTo("WNG??"));
|
Assert.That(converted.Acronym, Is.EqualTo("WNG!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using osu.Framework.Platform;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
@@ -206,7 +207,7 @@ namespace osu.Game.Tests.Online
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm)
|
protected override BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm, OsuConfigManager? config = null)
|
||||||
{
|
{
|
||||||
return new TestBeatmapImporter(this, storage, realm);
|
return new TestBeatmapImporter(this, storage, realm);
|
||||||
}
|
}
|
||||||
@@ -216,7 +217,7 @@ namespace osu.Game.Tests.Online
|
|||||||
private readonly TestBeatmapManager testBeatmapManager;
|
private readonly TestBeatmapManager testBeatmapManager;
|
||||||
|
|
||||||
public TestBeatmapImporter(TestBeatmapManager testBeatmapManager, Storage storage, RealmAccess databaseAccess)
|
public TestBeatmapImporter(TestBeatmapManager testBeatmapManager, Storage storage, RealmAccess databaseAccess)
|
||||||
: base(storage, databaseAccess)
|
: base(storage, databaseAccess, null)
|
||||||
{
|
{
|
||||||
this.testBeatmapManager = testBeatmapManager;
|
this.testBeatmapManager = testBeatmapManager;
|
||||||
}
|
}
|
||||||
@@ -224,7 +225,7 @@ namespace osu.Game.Tests.Online
|
|||||||
public override Live<BeatmapSetInfo>? ImportModel(BeatmapSetInfo item, ArchiveReader? archive = null, ImportParameters parameters = default,
|
public override Live<BeatmapSetInfo>? ImportModel(BeatmapSetInfo item, ArchiveReader? archive = null, ImportParameters parameters = default,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (!testBeatmapManager.AllowImport.Wait(TimeSpan.FromSeconds(10), cancellationToken))
|
if (!testBeatmapManager.AllowImport.Wait(TimeSpan.FromSeconds(30), cancellationToken))
|
||||||
throw new TimeoutException("Timeout waiting for import to be allowed.");
|
throw new TimeoutException("Timeout waiting for import to be allowed.");
|
||||||
|
|
||||||
return testBeatmapManager.CurrentImport = base.ImportModel(item, archive, parameters, cancellationToken);
|
return testBeatmapManager.CurrentImport = base.ImportModel(item, archive, parameters, cancellationToken);
|
||||||
|
|||||||
BIN
osu.Game.Tests/Resources/Archives/modified-classic-20250827.osk
Normal file
BIN
osu.Game.Tests/Resources/special-skin/score-0@2x.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-1@2x.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-2@2x.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-3@2x.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-4@2x.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-5@2x.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-6@2x.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-7@2x.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-8@2x.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-9@2x.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-comma@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-dot@2x.png
Normal file
|
After Width: | Height: | Size: 930 B |
BIN
osu.Game.Tests/Resources/special-skin/score-percent@2x.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-pp@2x.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-x@2x.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
@@ -81,6 +81,8 @@ namespace osu.Game.Tests.Skins
|
|||||||
"Archives/modified-argon-20250809.osk",
|
"Archives/modified-argon-20250809.osk",
|
||||||
// Covers "Argon" judgement counter
|
// Covers "Argon" judgement counter
|
||||||
"Archives/modified-argon-20250308.osk",
|
"Archives/modified-argon-20250308.osk",
|
||||||
|
// Covers "Argon" clicks/s counter, longest combo counter, skinnable SR display and beatmap status pill
|
||||||
|
"Archives/modified-argon-20251215-jvnkosu.osk",
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,209 +1,209 @@
|
|||||||
// 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
|
// #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.Allocation;
|
// using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
// using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
// using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Rendering;
|
// using osu.Framework.Graphics.Rendering;
|
||||||
using osu.Framework.Graphics.Textures;
|
// using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Configuration;
|
// using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
// using osu.Game.Graphics.Backgrounds;
|
||||||
using osu.Game.Online.API;
|
// using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
// using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
// using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Background
|
// namespace osu.Game.Tests.Visual.Background
|
||||||
{
|
// {
|
||||||
public partial class TestSceneSeasonalBackgroundLoader : ScreenTestScene
|
// public partial class TestSceneSeasonalBackgroundLoader : ScreenTestScene
|
||||||
{
|
// {
|
||||||
[Resolved]
|
// [Resolved]
|
||||||
private OsuConfigManager config { get; set; }
|
// private OsuConfigManager config { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
// [Resolved]
|
||||||
private SessionStatics statics { get; set; }
|
// private SessionStatics statics { get; set; }
|
||||||
|
|
||||||
private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
|
// private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
|
||||||
|
|
||||||
private LookupLoggingTextureStore textureStore;
|
// private LookupLoggingTextureStore textureStore;
|
||||||
private SeasonalBackgroundLoader backgroundLoader;
|
// private SeasonalBackgroundLoader backgroundLoader;
|
||||||
private Container backgroundContainer;
|
// private Container backgroundContainer;
|
||||||
|
|
||||||
// in real usages these would be online URLs, but correct execution of this test
|
// // in real usages these would be online URLs, but correct execution of this test
|
||||||
// shouldn't be coupled to existence of online assets.
|
// // shouldn't be coupled to existence of online assets.
|
||||||
private static readonly List<string> seasonal_background_urls = new List<string>
|
// private static readonly List<string> seasonal_background_urls = new List<string>
|
||||||
{
|
// {
|
||||||
"Backgrounds/bg2",
|
// "Backgrounds/bg2",
|
||||||
"Backgrounds/bg4",
|
// "Backgrounds/bg4",
|
||||||
"Backgrounds/bg3"
|
// "Backgrounds/bg3"
|
||||||
};
|
// };
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
// protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
// {
|
||||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
// var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
textureStore = new LookupLoggingTextureStore(dependencies.Get<IRenderer>());
|
// textureStore = new LookupLoggingTextureStore(dependencies.Get<IRenderer>());
|
||||||
dependencies.CacheAs(typeof(LargeTextureStore), textureStore);
|
// dependencies.CacheAs(typeof(LargeTextureStore), textureStore);
|
||||||
|
|
||||||
return dependencies;
|
// return dependencies;
|
||||||
}
|
// }
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
// [BackgroundDependencyLoader]
|
||||||
private void load(LargeTextureStore wrappedStore)
|
// private void load(LargeTextureStore wrappedStore)
|
||||||
{
|
// {
|
||||||
textureStore.AddStore(wrappedStore);
|
// textureStore.AddStore(wrappedStore);
|
||||||
|
|
||||||
Child = new DependencyProvidingContainer
|
// Child = new DependencyProvidingContainer
|
||||||
{
|
// {
|
||||||
CachedDependencies = new (Type, object)[]
|
// CachedDependencies = new (Type, object)[]
|
||||||
{
|
// {
|
||||||
(typeof(LargeTextureStore), textureStore)
|
// (typeof(LargeTextureStore), textureStore)
|
||||||
},
|
// },
|
||||||
Child = backgroundContainer = new Container
|
// Child = backgroundContainer = new Container
|
||||||
{
|
// {
|
||||||
RelativeSizeAxes = Axes.Both
|
// RelativeSizeAxes = Axes.Both
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
[SetUp]
|
// [SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
// public void SetUp() => Schedule(() =>
|
||||||
{
|
// {
|
||||||
// reset API response in statics to avoid test crosstalk.
|
// // reset API response in statics to avoid test crosstalk.
|
||||||
statics.SetValue<APISeasonalBackgrounds>(Static.SeasonalBackgrounds, null);
|
// statics.SetValue<APISeasonalBackgrounds>(Static.SeasonalBackgrounds, null);
|
||||||
textureStore.PerformedLookups.Clear();
|
// textureStore.PerformedLookups.Clear();
|
||||||
dummyAPI.SetState(APIState.Online);
|
// dummyAPI.SetState(APIState.Online);
|
||||||
|
|
||||||
backgroundContainer.Clear();
|
// backgroundContainer.Clear();
|
||||||
});
|
// });
|
||||||
|
|
||||||
[TestCase(-5)]
|
// [TestCase(-5)]
|
||||||
[TestCase(5)]
|
// [TestCase(5)]
|
||||||
public void TestAlwaysSeasonal(int daysOffset)
|
// public void TestAlwaysSeasonal(int daysOffset)
|
||||||
{
|
// {
|
||||||
registerBackgroundsResponse(DateTimeOffset.Now.AddDays(daysOffset));
|
// registerBackgroundsResponse(DateTimeOffset.Now.AddDays(daysOffset));
|
||||||
setSeasonalBackgroundMode(SeasonalBackgroundMode.Always);
|
// setSeasonalBackgroundMode(SeasonalBackgroundMode.Always);
|
||||||
|
|
||||||
createLoader();
|
// createLoader();
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
// for (int i = 0; i < 4; ++i)
|
||||||
loadNextBackground();
|
// loadNextBackground();
|
||||||
|
|
||||||
AddAssert("all backgrounds cycled", () => new HashSet<string>(textureStore.PerformedLookups).SetEquals(seasonal_background_urls));
|
// AddAssert("all backgrounds cycled", () => new HashSet<string>(textureStore.PerformedLookups).SetEquals(seasonal_background_urls));
|
||||||
}
|
// }
|
||||||
|
|
||||||
[TestCase(-5)]
|
// [TestCase(-5)]
|
||||||
[TestCase(5)]
|
// [TestCase(5)]
|
||||||
public void TestNeverSeasonal(int daysOffset)
|
// public void TestNeverSeasonal(int daysOffset)
|
||||||
{
|
// {
|
||||||
registerBackgroundsResponse(DateTimeOffset.Now.AddDays(daysOffset));
|
// registerBackgroundsResponse(DateTimeOffset.Now.AddDays(daysOffset));
|
||||||
setSeasonalBackgroundMode(SeasonalBackgroundMode.Never);
|
// setSeasonalBackgroundMode(SeasonalBackgroundMode.Never);
|
||||||
|
|
||||||
createLoader();
|
// createLoader();
|
||||||
|
|
||||||
assertNoBackgrounds();
|
// assertNoBackgrounds();
|
||||||
}
|
// }
|
||||||
|
|
||||||
[Test]
|
// [Test]
|
||||||
public void TestSometimesInSeason()
|
// public void TestSometimesInSeason()
|
||||||
{
|
// {
|
||||||
registerBackgroundsResponse(DateTimeOffset.Now.AddDays(5));
|
// registerBackgroundsResponse(DateTimeOffset.Now.AddDays(5));
|
||||||
setSeasonalBackgroundMode(SeasonalBackgroundMode.Sometimes);
|
// setSeasonalBackgroundMode(SeasonalBackgroundMode.Sometimes);
|
||||||
|
|
||||||
createLoader();
|
// createLoader();
|
||||||
|
|
||||||
assertAnyBackground();
|
// assertAnyBackground();
|
||||||
}
|
// }
|
||||||
|
|
||||||
[Test]
|
// [Test]
|
||||||
public void TestSometimesOutOfSeason()
|
// public void TestSometimesOutOfSeason()
|
||||||
{
|
// {
|
||||||
registerBackgroundsResponse(DateTimeOffset.Now.AddDays(-10));
|
// registerBackgroundsResponse(DateTimeOffset.Now.AddDays(-10));
|
||||||
setSeasonalBackgroundMode(SeasonalBackgroundMode.Sometimes);
|
// setSeasonalBackgroundMode(SeasonalBackgroundMode.Sometimes);
|
||||||
|
|
||||||
createLoader();
|
// createLoader();
|
||||||
|
|
||||||
assertNoBackgrounds();
|
// assertNoBackgrounds();
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void registerBackgroundsResponse(DateTimeOffset endDate)
|
// private void registerBackgroundsResponse(DateTimeOffset endDate)
|
||||||
=> AddStep("setup request handler", () =>
|
// => AddStep("setup request handler", () =>
|
||||||
{
|
// {
|
||||||
dummyAPI.HandleRequest = request =>
|
// dummyAPI.HandleRequest = request =>
|
||||||
{
|
// {
|
||||||
if (dummyAPI.State.Value != APIState.Online || !(request is GetSeasonalBackgroundsRequest backgroundsRequest))
|
// if (dummyAPI.State.Value != APIState.Online || !(request is GetSeasonalBackgroundsRequest backgroundsRequest))
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
backgroundsRequest.TriggerSuccess(new APISeasonalBackgrounds
|
// backgroundsRequest.TriggerSuccess(new APISeasonalBackgrounds
|
||||||
{
|
// {
|
||||||
Backgrounds = seasonal_background_urls.Select(url => new APISeasonalBackground { Url = url }).ToList(),
|
// Backgrounds = seasonal_background_urls.Select(url => new APISeasonalBackground { Url = url }).ToList(),
|
||||||
EndDate = endDate
|
// EndDate = endDate
|
||||||
});
|
// });
|
||||||
|
|
||||||
return true;
|
// return true;
|
||||||
};
|
// };
|
||||||
});
|
// });
|
||||||
|
|
||||||
private void setSeasonalBackgroundMode(SeasonalBackgroundMode mode)
|
// private void setSeasonalBackgroundMode(SeasonalBackgroundMode mode)
|
||||||
=> AddStep($"set seasonal mode to {mode}", () => config.SetValue(OsuSetting.SeasonalBackgroundMode, mode));
|
// => AddStep($"set seasonal mode to {mode}", () => config.SetValue(OsuSetting.SeasonalBackgroundMode, mode));
|
||||||
|
|
||||||
private void createLoader()
|
// private void createLoader()
|
||||||
=> AddStep("create loader", () =>
|
// => AddStep("create loader", () =>
|
||||||
{
|
// {
|
||||||
if (backgroundLoader != null)
|
// if (backgroundLoader != null)
|
||||||
Remove(backgroundLoader, true);
|
// Remove(backgroundLoader, true);
|
||||||
|
|
||||||
Add(backgroundLoader = new SeasonalBackgroundLoader());
|
// Add(backgroundLoader = new SeasonalBackgroundLoader());
|
||||||
});
|
// });
|
||||||
|
|
||||||
private void loadNextBackground()
|
// private void loadNextBackground()
|
||||||
{
|
// {
|
||||||
SeasonalBackground previousBackground = null;
|
// SeasonalBackground previousBackground = null;
|
||||||
SeasonalBackground background = null;
|
// SeasonalBackground background = null;
|
||||||
|
|
||||||
AddStep("create next background", () =>
|
// AddStep("create next background", () =>
|
||||||
{
|
// {
|
||||||
previousBackground = (SeasonalBackground)backgroundContainer.SingleOrDefault();
|
// previousBackground = (SeasonalBackground)backgroundContainer.SingleOrDefault();
|
||||||
background = backgroundLoader.LoadNextBackground();
|
// background = backgroundLoader.LoadNextBackground();
|
||||||
if (background != null)
|
// if (background != null)
|
||||||
LoadComponentAsync(background, bg => backgroundContainer.Child = bg);
|
// LoadComponentAsync(background, bg => backgroundContainer.Child = bg);
|
||||||
});
|
// });
|
||||||
|
|
||||||
AddUntilStep("background loaded", () => background.IsLoaded);
|
// AddUntilStep("background loaded", () => background.IsLoaded);
|
||||||
AddAssert("background is different", () => !background.Equals(previousBackground));
|
// AddAssert("background is different", () => !background.Equals(previousBackground));
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void assertAnyBackground()
|
// private void assertAnyBackground()
|
||||||
{
|
// {
|
||||||
loadNextBackground();
|
// loadNextBackground();
|
||||||
AddAssert("background looked up", () => textureStore.PerformedLookups.Any());
|
// AddAssert("background looked up", () => textureStore.PerformedLookups.Any());
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void assertNoBackgrounds()
|
// private void assertNoBackgrounds()
|
||||||
{
|
// {
|
||||||
AddAssert("no background available", () => backgroundLoader.LoadNextBackground() == null);
|
// AddAssert("no background available", () => backgroundLoader.LoadNextBackground() == null);
|
||||||
AddAssert("no lookups performed", () => !textureStore.PerformedLookups.Any());
|
// AddAssert("no lookups performed", () => !textureStore.PerformedLookups.Any());
|
||||||
}
|
// }
|
||||||
|
|
||||||
private class LookupLoggingTextureStore : LargeTextureStore
|
// private class LookupLoggingTextureStore : LargeTextureStore
|
||||||
{
|
// {
|
||||||
public List<string> PerformedLookups { get; } = new List<string>();
|
// public List<string> PerformedLookups { get; } = new List<string>();
|
||||||
|
|
||||||
public LookupLoggingTextureStore(IRenderer renderer)
|
// public LookupLoggingTextureStore(IRenderer renderer)
|
||||||
: base(renderer)
|
// : base(renderer)
|
||||||
{
|
// {
|
||||||
}
|
// }
|
||||||
|
|
||||||
public override Texture Get(string name, WrapMode wrapModeS, WrapMode wrapModeT)
|
// public override Texture Get(string name, WrapMode wrapModeS, WrapMode wrapModeT)
|
||||||
{
|
// {
|
||||||
PerformedLookups.Add(name);
|
// PerformedLookups.Add(name);
|
||||||
return base.Get(name, wrapModeS, wrapModeT);
|
// return base.Get(name, wrapModeS, wrapModeT);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
|||||||
AddStep("create thumbnail", () =>
|
AddStep("create thumbnail", () =>
|
||||||
{
|
{
|
||||||
var beatmapSet = CreateAPIBeatmapSet(Ruleset.Value);
|
var beatmapSet = CreateAPIBeatmapSet(Ruleset.Value);
|
||||||
beatmapSet.OnlineID = 241526; // ID hardcoded to ensure that the preview track exists online.
|
beatmapSet.OnlineID = 1; // ID hardcoded to ensure that the preview track exists online.
|
||||||
|
|
||||||
Child = thumbnail = new BeatmapCardThumbnail(beatmapSet, beatmapSet)
|
Child = thumbnail = new BeatmapCardThumbnail(beatmapSet, beatmapSet)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
setUpEditor(new OsuRuleset().RulesetInfo);
|
setUpEditor(new OsuRuleset().RulesetInfo);
|
||||||
AddAssert("is osu! ruleset", () => editorBeatmap.BeatmapInfo.Ruleset.Equals(new OsuRuleset().RulesetInfo));
|
AddAssert("is osu! ruleset", () => editorBeatmap.BeatmapInfo.Ruleset.Equals(new OsuRuleset().RulesetInfo));
|
||||||
|
|
||||||
AddStep("jump to encoded link", () => Game.HandleLink("osu://edit/00:14:142%20(1)"));
|
AddStep("jump to encoded link", () => Game.HandleLink("jvnkosu://edit/00:14:142%20(1)"));
|
||||||
|
|
||||||
AddUntilStep("wait for seek", () => editorClock.SeekingOrStopped.Value);
|
AddUntilStep("wait for seek", () => editorClock.SeekingOrStopped.Value);
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new OsuRuleset());
|
loadPlayer(() => new OsuRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
||||||
checkKey(() => counter, 0, false);
|
checkKey(() => counter, 0, false);
|
||||||
|
|
||||||
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
||||||
@@ -117,7 +117,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new ManiaRuleset());
|
loadPlayer(() => new ManiaRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
||||||
checkKey(() => counter, 0, false);
|
checkKey(() => counter, 0, false);
|
||||||
|
|
||||||
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
||||||
@@ -150,8 +150,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counterX = null!;
|
KeyCounter counterX = null!;
|
||||||
|
|
||||||
loadPlayer(() => new OsuRuleset());
|
loadPlayer(() => new OsuRuleset());
|
||||||
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
||||||
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
|
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
|
||||||
|
|
||||||
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
||||||
AddStep("pause", () => Player.Pause());
|
AddStep("pause", () => Player.Pause());
|
||||||
@@ -184,7 +184,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new ManiaRuleset());
|
loadPlayer(() => new ManiaRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
||||||
|
|
||||||
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
||||||
AddStep("pause", () => Player.Pause());
|
AddStep("pause", () => Player.Pause());
|
||||||
@@ -204,8 +204,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counterX = null!;
|
KeyCounter counterX = null!;
|
||||||
|
|
||||||
loadPlayer(() => new OsuRuleset());
|
loadPlayer(() => new OsuRuleset());
|
||||||
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
||||||
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
|
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
|
||||||
|
|
||||||
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
||||||
AddStep("pause", () => Player.Pause());
|
AddStep("pause", () => Player.Pause());
|
||||||
@@ -247,7 +247,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new ManiaRuleset());
|
loadPlayer(() => new ManiaRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
||||||
|
|
||||||
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
||||||
checkKey(() => counter, 1, true);
|
checkKey(() => counter, 1, true);
|
||||||
@@ -271,7 +271,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new OsuRuleset());
|
loadPlayer(() => new OsuRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
||||||
|
|
||||||
AddStep("pause", () => Player.Pause());
|
AddStep("pause", () => Player.Pause());
|
||||||
AddStep("resume", () => Player.Resume());
|
AddStep("resume", () => Player.Resume());
|
||||||
@@ -297,7 +297,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new OsuRuleset());
|
loadPlayer(() => new OsuRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
||||||
|
|
||||||
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
||||||
AddAssert("circle hit", () => Player.ScoreProcessor.HighestCombo.Value, () => Is.EqualTo(1));
|
AddAssert("circle hit", () => Player.ScoreProcessor.HighestCombo.Value, () => Is.EqualTo(1));
|
||||||
|
|||||||
@@ -642,7 +642,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
if (!AllowLoad.Wait(TimeSpan.FromSeconds(10)))
|
if (!AllowLoad.Wait(TimeSpan.FromSeconds(30)))
|
||||||
throw new TimeoutException();
|
throw new TimeoutException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// 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.Framework.Allocation;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Screens.Menu;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Menus
|
||||||
|
{
|
||||||
|
public partial class TestSceneDisclaimer : ScreenTestScene
|
||||||
|
{
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
AddStep("load disclaimer", () => LoadScreen(new Disclaimer()));
|
||||||
|
|
||||||
|
AddStep("toggle support", () =>
|
||||||
|
{
|
||||||
|
((DummyAPIAccess)API).LocalUser.Value = new APIUser
|
||||||
|
{
|
||||||
|
Username = API.LocalUser.Value.Username,
|
||||||
|
Id = API.LocalUser.Value.Id + 1,
|
||||||
|
IsSupporter = !API.LocalUser.Value.IsSupporter,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -159,7 +159,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("check request received", () =>
|
AddStep("check request received", () =>
|
||||||
{
|
{
|
||||||
multiplayerClient.Verify(m => m.SendMatchRequest(It.Is<StartMatchCountdownRequest>(req =>
|
multiplayerClient.Verify(m => m.SendMatchRequest(It.Is<StartMatchCountdownRequest>(req =>
|
||||||
req.Duration == TimeSpan.FromSeconds(10)
|
req.Duration == TimeSpan.FromSeconds(30)
|
||||||
)), Times.Once);
|
)), Times.Once);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("check request received", () =>
|
AddStep("check request received", () =>
|
||||||
{
|
{
|
||||||
multiplayerClient.Verify(m => m.SendMatchRequest(It.Is<StartMatchCountdownRequest>(req =>
|
multiplayerClient.Verify(m => m.SendMatchRequest(It.Is<StartMatchCountdownRequest>(req =>
|
||||||
req.Duration == TimeSpan.FromSeconds(10)
|
req.Duration == TimeSpan.FromSeconds(30)
|
||||||
)), Times.Once);
|
)), Times.Once);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -305,6 +305,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
new APIMod(new OsuModDoubleTime { SpeedChange = { Value = 2.0 } }),
|
new APIMod(new OsuModDoubleTime { SpeedChange = { Value = 2.0 } }),
|
||||||
new APIMod(new OsuModStrictTracking()),
|
new APIMod(new OsuModStrictTracking()),
|
||||||
|
new APIMod(new OsuModAutoplay()), // THIS IS PURELY TO ENABLE UNRANKED BADGE AND LET TEST PASS
|
||||||
|
// I AM NOT PROUD OF THIS
|
||||||
},
|
},
|
||||||
AllowedMods = new[]
|
AllowedMods = new[]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
// Importantly, this occurs before base.load().
|
// Importantly, this occurs before base.load().
|
||||||
if (!loader.AllowLoad.Wait(TimeSpan.FromSeconds(10)))
|
if (!loader.AllowLoad.Wait(TimeSpan.FromSeconds(30)))
|
||||||
throw new TimeoutException();
|
throw new TimeoutException();
|
||||||
|
|
||||||
return base.CreateChildDependencies(parent);
|
return base.CreateChildDependencies(parent);
|
||||||
|
|||||||
@@ -920,8 +920,12 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
[Explicit("Featured Artist dialog is never displayed as the filter is disabled by default.")]
|
||||||
public void TestFeaturedArtistDisclaimerDialog()
|
public void TestFeaturedArtistDisclaimerDialog()
|
||||||
{
|
{
|
||||||
|
// NO-OP: FA dialog is not displayed ever
|
||||||
|
|
||||||
|
/*
|
||||||
BeatmapListingOverlay getBeatmapListingOverlay() => Game.ChildrenOfType<BeatmapListingOverlay>().FirstOrDefault();
|
BeatmapListingOverlay getBeatmapListingOverlay() => Game.ChildrenOfType<BeatmapListingOverlay>().FirstOrDefault();
|
||||||
|
|
||||||
AddStep("Wait for notifications to load", () => Game.SearchBeatmapSet(string.Empty));
|
AddStep("Wait for notifications to load", () => Game.SearchBeatmapSet(string.Empty));
|
||||||
@@ -939,6 +943,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
AddAssert("dialog dismissed", () => Game.ChildrenOfType<DialogOverlay>().Single().CurrentDialog == null);
|
AddAssert("dialog dismissed", () => Game.ChildrenOfType<DialogOverlay>().Single().CurrentDialog == null);
|
||||||
|
|
||||||
AddUntilStep("featured artist filter is off", () => !getBeatmapListingOverlay().ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
AddUntilStep("featured artist filter is off", () => !getBeatmapListingOverlay().ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
private const int requested_beatmap_id = 75;
|
private const int requested_beatmap_id = 75;
|
||||||
private const int requested_beatmap_set_id = 1;
|
private const int requested_beatmap_set_id = 1;
|
||||||
|
|
||||||
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"osu://b/{requested_beatmap_id}" });
|
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"jvnkosu://b/{requested_beatmap_id}" });
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup() => Schedule(() =>
|
public void Setup() => Schedule(() =>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
{
|
{
|
||||||
private const int requested_beatmap_set_id = 1;
|
private const int requested_beatmap_set_id = 1;
|
||||||
|
|
||||||
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"osu://s/{requested_beatmap_set_id}" });
|
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"jvnkosu://s/{requested_beatmap_set_id}" });
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup() => Schedule(() =>
|
public void Setup() => Schedule(() =>
|
||||||
|
|||||||
@@ -84,9 +84,9 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
public void TestFeaturedArtistFilter()
|
public void TestFeaturedArtistFilter()
|
||||||
{
|
{
|
||||||
AddAssert("is visible", () => overlay.State.Value == Visibility.Visible);
|
AddAssert("is visible", () => overlay.State.Value == Visibility.Visible);
|
||||||
AddAssert("featured artist filter is on", () => overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
|
||||||
AddStep("toggle featured artist filter", () => overlay.ChildrenOfType<FilterTabItem<SearchGeneral>>().First(i => i.Value == SearchGeneral.FeaturedArtists).TriggerClick());
|
|
||||||
AddAssert("featured artist filter is off", () => !overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
AddAssert("featured artist filter is off", () => !overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
||||||
|
AddStep("toggle featured artist filter", () => overlay.ChildrenOfType<FilterTabItem<SearchGeneral>>().First(i => i.Value == SearchGeneral.FeaturedArtists).TriggerClick());
|
||||||
|
AddAssert("featured artist filter is on", () => overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -55,31 +55,31 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
});
|
});
|
||||||
|
|
||||||
[TestCase("test!")]
|
[TestCase("test!")]
|
||||||
[TestCase("dev.ppy.sh!")]
|
[TestCase("osu.jvnko.boats!")]
|
||||||
[TestCase("https://dev.ppy.sh!", LinkAction.External)]
|
[TestCase("https://osu.jvnko.boats!", LinkAction.External)]
|
||||||
[TestCase("http://dev.ppy.sh!", LinkAction.External)]
|
[TestCase("http://osu.jvnko.boats!", LinkAction.External)]
|
||||||
[TestCase("forgothttps://dev.ppy.sh!", LinkAction.External)]
|
[TestCase("forgothttps://osu.jvnko.boats!", LinkAction.External)]
|
||||||
[TestCase("forgothttp://dev.ppy.sh!", LinkAction.External)]
|
[TestCase("forgothttp://osu.jvnko.boats!", LinkAction.External)]
|
||||||
[TestCase("00:12:345 - Test?", LinkAction.OpenEditorTimestamp)]
|
[TestCase("00:12:345 - Test?", LinkAction.OpenEditorTimestamp)]
|
||||||
[TestCase("00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)]
|
[TestCase("00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)]
|
||||||
[TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 - Test?", LinkAction.OpenEditorTimestamp)]
|
[TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 - Test?", LinkAction.OpenEditorTimestamp)]
|
||||||
[TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)]
|
[TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)]
|
||||||
[TestCase($"{OsuGameBase.OSU_PROTOCOL}00:12:345 - not an editor timestamp", LinkAction.External)]
|
[TestCase($"{OsuGameBase.OSU_PROTOCOL}00:12:345 - not an editor timestamp", LinkAction.External)]
|
||||||
[TestCase("Wiki link for tasty [[Performance Points]]", LinkAction.OpenWiki)]
|
[TestCase("Wiki link for tasty [[Performance Points]]", LinkAction.OpenWiki)]
|
||||||
[TestCase("(osu forums)[https://dev.ppy.sh/forum] (old link format)", LinkAction.External)]
|
[TestCase("(osu forums)[https://osu.jvnko.boats/forum] (old link format)", LinkAction.External)]
|
||||||
[TestCase("[https://dev.ppy.sh/home New site] (new link format)", LinkAction.External)]
|
[TestCase("[https://osu.jvnko.boats/home New site] (new link format)", LinkAction.External)]
|
||||||
[TestCase("[osu forums](https://dev.ppy.sh/forum) (new link format 2)", LinkAction.External)]
|
[TestCase("[osu forums](https://osu.jvnko.boats/forum) (new link format 2)", LinkAction.External)]
|
||||||
[TestCase("[https://dev.ppy.sh/home This is only a link to the new osu webpage but this is supposed to test word wrap.]", LinkAction.External)]
|
[TestCase("[https://osu.jvnko.boats/home This is only a link to the new osu webpage but this is supposed to test word wrap.]", LinkAction.External)]
|
||||||
[TestCase("Let's (try)[https://dev.ppy.sh/home] [https://dev.ppy.sh/b/252238 multiple links] https://dev.ppy.sh/home", LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External)]
|
[TestCase("Let's (try)[https://osu.jvnko.boats/home] [https://osu.jvnko.boats/b/252238 multiple links] https://osu.jvnko.boats/home", LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External)]
|
||||||
[TestCase("[https://dev.ppy.sh/home New link format with escaped [and \\[ paired] braces]", LinkAction.External)]
|
[TestCase("[https://osu.jvnko.boats/home New link format with escaped [and \\[ paired] braces]", LinkAction.External)]
|
||||||
[TestCase("[Markdown link format with escaped [and \\[ paired] braces](https://dev.ppy.sh/home)", LinkAction.External)]
|
[TestCase("[Markdown link format with escaped [and \\[ paired] braces](https://osu.jvnko.boats/home)", LinkAction.External)]
|
||||||
[TestCase("(Old link format with escaped (and \\( paired) parentheses)[https://dev.ppy.sh/home] and [[also a rogue wiki link]]", LinkAction.External, LinkAction.OpenWiki)]
|
[TestCase("(Old link format with escaped (and \\( paired) parentheses)[https://osu.jvnko.boats/home] and [[also a rogue wiki link]]", LinkAction.External, LinkAction.OpenWiki)]
|
||||||
[TestCase("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present).")] // note that there's 0 links here (they get removed if a channel is not found)
|
[TestCase("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present).")] // note that there's 0 links here (they get removed if a channel is not found)
|
||||||
[TestCase("Join my multiplayer game osu://room/12346.", LinkAction.JoinRoom)]
|
[TestCase("Join my multiplayer game jvnkosu://room/12346.", LinkAction.JoinRoom)]
|
||||||
[TestCase("Join my multiplayer gameosu://room/12346.", LinkAction.JoinRoom)]
|
[TestCase("Join my multiplayer gamejvnkosu://room/12346.", LinkAction.JoinRoom)]
|
||||||
[TestCase("Join my [multiplayer game](osu://room/12346).", LinkAction.JoinRoom)]
|
[TestCase("Join my [multiplayer game](jvnkosu://room/12346).", LinkAction.JoinRoom)]
|
||||||
[TestCase("Join my multiplayer game http://dev.ppy.sh/multiplayer/rooms/12346", LinkAction.JoinRoom)]
|
[TestCase("Join my multiplayer game http://osu.jvnko.boats/multiplayer/rooms/12346", LinkAction.JoinRoom)]
|
||||||
[TestCase("Join my [multiplayer game](http://dev.ppy.sh/multiplayer/rooms/12346).", LinkAction.JoinRoom)]
|
[TestCase("Join my [multiplayer game](http://osu.jvnko.boats/multiplayer/rooms/12346).", LinkAction.JoinRoom)]
|
||||||
[TestCase($"Join my [#english]({OsuGameBase.OSU_PROTOCOL}chan/#english).", LinkAction.OpenChannel)]
|
[TestCase($"Join my [#english]({OsuGameBase.OSU_PROTOCOL}chan/#english).", LinkAction.OpenChannel)]
|
||||||
[TestCase($"Join my {OsuGameBase.OSU_PROTOCOL}chan/#english.", LinkAction.OpenChannel)]
|
[TestCase($"Join my {OsuGameBase.OSU_PROTOCOL}chan/#english.", LinkAction.OpenChannel)]
|
||||||
[TestCase($"Join my{OsuGameBase.OSU_PROTOCOL}chan/#english.", LinkAction.OpenChannel)]
|
[TestCase($"Join my{OsuGameBase.OSU_PROTOCOL}chan/#english.", LinkAction.OpenChannel)]
|
||||||
@@ -91,11 +91,11 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
addMessageWithChecks(text, expectedActions: actions);
|
addMessageWithChecks(text, expectedActions: actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("is now listening to [https://dev.ppy.sh/s/93523 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmapSet)]
|
[TestCase("is now listening to [https://osu.jvnko.boats/s/93523 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmapSet)]
|
||||||
[TestCase("is now playing [https://dev.ppy.sh/b/252238 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmap)]
|
[TestCase("is now playing [https://osu.jvnko.boats/b/252238 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmap)]
|
||||||
[TestCase("I am important!", false, true)]
|
[TestCase("I am important!", false, true)]
|
||||||
[TestCase("feels important", true, true)]
|
[TestCase("feels important", true, true)]
|
||||||
[TestCase("likes to post this [https://dev.ppy.sh/home link].", true, true, LinkAction.External)]
|
[TestCase("likes to post this [https://osu.jvnko.boats/home link].", true, true, LinkAction.External)]
|
||||||
public void TestActionAndImportantLinks(string text, bool isAction, bool isImportant, params LinkAction[] expectedActions)
|
public void TestActionAndImportantLinks(string text, bool isAction, bool isImportant, params LinkAction[] expectedActions)
|
||||||
{
|
{
|
||||||
addMessageWithChecks(text, isAction, isImportant, expectedActions);
|
addMessageWithChecks(text, isAction, isImportant, expectedActions);
|
||||||
@@ -135,9 +135,9 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
int messageIndex = 0;
|
int messageIndex = 0;
|
||||||
|
|
||||||
addEchoWithWait("sent!", "received!");
|
addEchoWithWait("sent!", "received!");
|
||||||
addEchoWithWait("https://dev.ppy.sh/home", null, 500);
|
addEchoWithWait("https://osu.jvnko.boats/home", null, 500);
|
||||||
addEchoWithWait("[https://dev.ppy.sh/forum let's try multiple words too!]");
|
addEchoWithWait("[https://osu.jvnko.boats/forum let's try multiple words too!]");
|
||||||
addEchoWithWait("(long loading times! clickable while loading?)[https://dev.ppy.sh/home]", null, 5000);
|
addEchoWithWait("(long loading times! clickable while loading?)[https://osu.jvnko.boats/home]", null, 5000);
|
||||||
|
|
||||||
void addEchoWithWait(string text, string? completeText = null, double delay = 250)
|
void addEchoWithWait(string text, string? completeText = null, double delay = 250)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
AddStep("show example score", () =>
|
AddStep("show example score", () =>
|
||||||
{
|
{
|
||||||
var score = TestResources.CreateTestScoreInfo(createTestBeatmap(new RealmUser()));
|
var score = TestResources.CreateTestScoreInfo(createTestBeatmap(new RealmUser()));
|
||||||
score.Mods = score.Mods.Append(new OsuModDifficultyAdjust()).ToArray();
|
score.Mods = score.Mods.Append(new OsuModAutoplay()).ToArray();
|
||||||
showPanel(score);
|
showPanel(score);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
private void testInfoLabels(int expectedCount)
|
private void testInfoLabels(int expectedCount)
|
||||||
{
|
{
|
||||||
AddAssert("check info labels exists", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Any());
|
AddAssert("check info labels exists", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Any());
|
||||||
AddAssert("check info labels count", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Count() == expectedCount);
|
AddAssert("check info labels count", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Count() >= expectedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
assertGroup(results, 3, "Pending", pendingBeatmap.Beatmaps, ref total);
|
assertGroup(results, 3, "Pending", pendingBeatmap.Beatmaps, ref total);
|
||||||
assertGroup(results, 4, "Graveyard", graveyardBeatmap.Beatmaps, ref total);
|
assertGroup(results, 4, "Graveyard", graveyardBeatmap.Beatmaps, ref total);
|
||||||
assertGroup(results, 5, "Local", localBeatmap.Beatmaps, ref total);
|
assertGroup(results, 5, "Local", localBeatmap.Beatmaps, ref total);
|
||||||
assertGroup(results, 6, "Unknown", noneBeatmap.Beatmaps, ref total);
|
assertGroup(results, 6, "Offline", noneBeatmap.Beatmaps, ref total);
|
||||||
assertGroup(results, 7, "Loved", lovedBeatmap.Beatmaps, ref total);
|
assertGroup(results, 7, "Loved", lovedBeatmap.Beatmaps, ref total);
|
||||||
assertTotal(results, total);
|
assertTotal(results, total);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestUnrankedBadge()
|
public void TestUnrankedBadge()
|
||||||
{
|
{
|
||||||
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModDeflate() }));
|
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModAutoplay() }));
|
||||||
AddUntilStep("Unranked badge shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 1);
|
AddUntilStep("Unranked badge shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 1);
|
||||||
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
|
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
|
||||||
AddUntilStep("Unranked badge not shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 0);
|
AddUntilStep("Unranked badge not shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 0);
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestUnrankedBadge()
|
public void TestUnrankedBadge()
|
||||||
{
|
{
|
||||||
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModDeflate() }));
|
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModAutoplay() }));
|
||||||
AddAssert("Unranked badge shown", () => footerButtonMods.UnrankedBadge.Alpha == 1);
|
AddAssert("Unranked badge shown", () => footerButtonMods.UnrankedBadge.Alpha == 1);
|
||||||
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
|
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
|
||||||
AddAssert("Unranked badge not shown", () => footerButtonMods.UnrankedBadge.Alpha == 0);
|
AddAssert("Unranked badge not shown", () => footerButtonMods.UnrankedBadge.Alpha == 0);
|
||||||
|
|||||||
@@ -129,8 +129,9 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
setSliderValue("Circle Size", 99);
|
setSliderValue("Circle Size", 99);
|
||||||
|
|
||||||
checkSliderAtValue("Circle Size", 11);
|
// debug build maximum value
|
||||||
checkBindableAtValue("Circle Size", 11);
|
checkSliderAtValue("Circle Size", 13);
|
||||||
|
checkBindableAtValue("Circle Size", 13);
|
||||||
|
|
||||||
setSliderValue("Approach Rate", -5);
|
setSliderValue("Approach Rate", -5);
|
||||||
|
|
||||||
|
|||||||
@@ -207,23 +207,23 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
AddUntilStep("any column dimmed", () => this.ChildrenOfType<ModColumn>().Any(column => !column.Active.Value));
|
AddUntilStep("any column dimmed", () => this.ChildrenOfType<ModColumn>().Any(column => !column.Active.Value));
|
||||||
|
|
||||||
ModSelectColumn lastColumn = null!;
|
ModSelectColumn secondColumn = null!;
|
||||||
|
|
||||||
AddAssert("last column dimmed", () => !this.ChildrenOfType<ModColumn>().Last().Active.Value);
|
AddAssert("second column dimmed", () => !this.ChildrenOfType<ModColumn>().ElementAt(2).Active.Value);
|
||||||
AddStep("request scroll to last column", () =>
|
AddStep("request scroll to second column", () =>
|
||||||
{
|
{
|
||||||
var lastDimContainer = this.ChildrenOfType<ModSelectOverlay.ColumnDimContainer>().Last();
|
var secondDimContainer = this.ChildrenOfType<ModSelectOverlay.ColumnDimContainer>().ElementAt(2);
|
||||||
lastColumn = lastDimContainer.Column;
|
secondColumn = secondDimContainer.Column;
|
||||||
lastDimContainer.RequestScroll?.Invoke(lastDimContainer);
|
secondDimContainer.RequestScroll?.Invoke(secondDimContainer);
|
||||||
});
|
});
|
||||||
AddUntilStep("column undimmed", () => lastColumn.Active.Value);
|
AddUntilStep("column undimmed", () => secondColumn.Active.Value);
|
||||||
|
|
||||||
AddStep("click panel", () =>
|
AddStep("click panel", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(lastColumn.ChildrenOfType<ModPanel>().First());
|
InputManager.MoveMouseTo(secondColumn.ChildrenOfType<ModPanel>().First());
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
AddUntilStep("panel selected", () => lastColumn.ChildrenOfType<ModPanel>().First().Active.Value);
|
AddUntilStep("panel selected", () => secondColumn.ChildrenOfType<ModPanel>().First().Active.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -810,7 +810,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
|
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
|
||||||
|
|
||||||
AddStep("unset filter", () => modSelectOverlay.IsValidMod = _ => true);
|
AddStep("unset filter", () => modSelectOverlay.IsValidMod = _ => true);
|
||||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
|
||||||
|
|
||||||
AddStep("filter out everything", () => modSelectOverlay.IsValidMod = _ => false);
|
AddStep("filter out everything", () => modSelectOverlay.IsValidMod = _ => false);
|
||||||
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
|
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
|
||||||
@@ -839,7 +839,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
waitForColumnLoad();
|
waitForColumnLoad();
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
|
|
||||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
|
||||||
|
|
||||||
AddStep("set search", () => modSelectOverlay.SearchTerm = "HD");
|
AddStep("set search", () => modSelectOverlay.SearchTerm = "HD");
|
||||||
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
|
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
|
||||||
@@ -848,7 +848,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
|
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
|
||||||
|
|
||||||
AddStep("clear search bar", () => modSelectOverlay.SearchTerm = "");
|
AddStep("clear search bar", () => modSelectOverlay.SearchTerm = "");
|
||||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -863,7 +863,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
waitForColumnLoad();
|
waitForColumnLoad();
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
|
|
||||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
|
||||||
|
|
||||||
AddStep("set search", () => modSelectOverlay.SearchTerm = "fail");
|
AddStep("set search", () => modSelectOverlay.SearchTerm = "fail");
|
||||||
AddAssert("one column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);
|
AddAssert("one column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);
|
||||||
@@ -871,7 +871,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("hide", () => modSelectOverlay.Hide());
|
AddStep("hide", () => modSelectOverlay.Hide());
|
||||||
AddStep("show", () => modSelectOverlay.Show());
|
AddStep("show", () => modSelectOverlay.Show());
|
||||||
|
|
||||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -880,13 +880,13 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
createScreen();
|
createScreen();
|
||||||
|
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
AddAssert("5 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 5);
|
AddAssert("5 or more columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 5);
|
||||||
|
|
||||||
AddStep("change to ruleset without all mod types", () => Ruleset.Value = TestCustomisableModRuleset.CreateTestRulesetInfo());
|
AddStep("change to ruleset without all mod types", () => Ruleset.Value = TestCustomisableModRuleset.CreateTestRulesetInfo());
|
||||||
AddUntilStep("1 column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);
|
AddUntilStep("1 column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);
|
||||||
|
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
AddAssert("5 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 5);
|
AddAssert("5 or more columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ namespace osu.Game.Audio
|
|||||||
Logger.Log($"A {nameof(PreviewTrack)} was created without a containing {nameof(IPreviewTrackOwner)}. An owner should be added for correct behaviour.");
|
Logger.Log($"A {nameof(PreviewTrack)} was created without a containing {nameof(IPreviewTrackOwner)}. An owner should be added for correct behaviour.");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo.OnlineID}.mp3");
|
protected override Track GetTrack() => trackManager.Get($"https://osu.jvnko.boats/uploads/preview/{beatmapSetInfo.OnlineID}.mp3");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using osu.Framework.Extensions.IEnumerableExtensions;
|
|||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Collections;
|
using osu.Game.Collections;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
@@ -36,8 +37,8 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
public ProcessBeatmapDelegate? ProcessBeatmap { private get; set; }
|
public ProcessBeatmapDelegate? ProcessBeatmap { private get; set; }
|
||||||
|
|
||||||
public BeatmapImporter(Storage storage, RealmAccess realm)
|
public BeatmapImporter(Storage storage, RealmAccess realm, OsuConfigManager? config = null)
|
||||||
: base(storage, realm)
|
: base(storage, realm, config)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ using osu.Framework.IO.Stores;
|
|||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
@@ -59,7 +60,7 @@ namespace osu.Game.Beatmaps
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BeatmapManager(Storage storage, RealmAccess realm, IAPIProvider? api, AudioManager audioManager, IResourceStore<byte[]> gameResources, GameHost? host = null,
|
public BeatmapManager(Storage storage, RealmAccess realm, IAPIProvider? api, AudioManager audioManager, IResourceStore<byte[]> gameResources, GameHost? host = null,
|
||||||
WorkingBeatmap? defaultBeatmap = null, BeatmapDifficultyCache? difficultyCache = null, bool performOnlineLookups = false)
|
WorkingBeatmap? defaultBeatmap = null, BeatmapDifficultyCache? difficultyCache = null, bool performOnlineLookups = false, OsuConfigManager? config = null)
|
||||||
: base(storage, realm)
|
: base(storage, realm)
|
||||||
{
|
{
|
||||||
if (performOnlineLookups)
|
if (performOnlineLookups)
|
||||||
@@ -75,7 +76,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
BeatmapTrackStore = audioManager.GetTrackStore(userResources);
|
BeatmapTrackStore = audioManager.GetTrackStore(userResources);
|
||||||
|
|
||||||
beatmapImporter = CreateBeatmapImporter(storage, realm);
|
beatmapImporter = CreateBeatmapImporter(storage, realm, config);
|
||||||
beatmapImporter.ProcessBeatmap = (beatmapSet, scope) => ProcessBeatmap?.Invoke(beatmapSet, scope);
|
beatmapImporter.ProcessBeatmap = (beatmapSet, scope) => ProcessBeatmap?.Invoke(beatmapSet, scope);
|
||||||
beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj);
|
beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj);
|
||||||
|
|
||||||
@@ -98,7 +99,7 @@ namespace osu.Game.Beatmaps
|
|||||||
return new WorkingBeatmapCache(BeatmapTrackStore, audioManager, resources, storage, defaultBeatmap, host);
|
return new WorkingBeatmapCache(BeatmapTrackStore, audioManager, resources, storage, defaultBeatmap, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm) => new BeatmapImporter(storage, realm);
|
protected virtual BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm, OsuConfigManager? config = null) => new BeatmapImporter(storage, realm, config);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new beatmap set, backed by a <see cref="BeatmapSetInfo"/> model,
|
/// Create a new beatmap set, backed by a <see cref="BeatmapSetInfo"/> model,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace osu.Game.Beatmaps
|
|||||||
LocallyModified = -4,
|
LocallyModified = -4,
|
||||||
|
|
||||||
[LocalisableDescription(typeof(SongSelectStrings), nameof(SongSelectStrings.StatusUnknown))]
|
[LocalisableDescription(typeof(SongSelectStrings), nameof(SongSelectStrings.StatusUnknown))]
|
||||||
[Description("Unknown")]
|
[Description("Offline")]
|
||||||
None = -3,
|
None = -3,
|
||||||
|
|
||||||
[LocalisableDescription(typeof(BeatmapsetsStrings), nameof(BeatmapsetsStrings.ShowStatusGraveyard))]
|
[LocalisableDescription(typeof(BeatmapsetsStrings), nameof(BeatmapsetsStrings.ShowStatusGraveyard))]
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ namespace osu.Game.Beatmaps.Drawables.Cards
|
|||||||
Status = beatmapSet.Status,
|
Status = beatmapSet.Status,
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
TextSize = 13f
|
TextSize = 13f,
|
||||||
|
ShowUnknownStatus = true
|
||||||
},
|
},
|
||||||
new DifficultySpectrumDisplay
|
new DifficultySpectrumDisplay
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace osu.Game.Configuration
|
|||||||
Circles,
|
Circles,
|
||||||
Welcome,
|
Welcome,
|
||||||
Triangles,
|
Triangles,
|
||||||
|
None,
|
||||||
Random
|
Random
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using osu.Framework.Configuration;
|
|||||||
using osu.Framework.Configuration.Tracking;
|
using osu.Framework.Configuration.Tracking;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Extensions.LocalisationExtensions;
|
using osu.Framework.Extensions.LocalisationExtensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Beatmaps.Drawables.Cards;
|
using osu.Game.Beatmaps.Drawables.Cards;
|
||||||
@@ -41,6 +42,8 @@ namespace osu.Game.Configuration
|
|||||||
SetDefault(OsuSetting.Ruleset, string.Empty);
|
SetDefault(OsuSetting.Ruleset, string.Empty);
|
||||||
SetDefault(OsuSetting.Skin, SkinInfo.ARGON_SKIN.ToString());
|
SetDefault(OsuSetting.Skin, SkinInfo.ARGON_SKIN.ToString());
|
||||||
|
|
||||||
|
SetDefault(OsuSetting.MenuCookieColor, Colour4.FromHex(@"8400FF"));
|
||||||
|
|
||||||
SetDefault(OsuSetting.BeatmapDetailTab, BeatmapDetailTab.Local);
|
SetDefault(OsuSetting.BeatmapDetailTab, BeatmapDetailTab.Local);
|
||||||
SetDefault(OsuSetting.BeatmapLeaderboardSortMode, LeaderboardSortMode.Score);
|
SetDefault(OsuSetting.BeatmapLeaderboardSortMode, LeaderboardSortMode.Score);
|
||||||
SetDefault(OsuSetting.BeatmapDetailModsFilter, false);
|
SetDefault(OsuSetting.BeatmapDetailModsFilter, false);
|
||||||
@@ -59,12 +62,13 @@ namespace osu.Game.Configuration
|
|||||||
SetDefault(OsuSetting.ChatDisplayHeight, ChatOverlay.DEFAULT_HEIGHT, 0.2f, 1f, 0.01f);
|
SetDefault(OsuSetting.ChatDisplayHeight, ChatOverlay.DEFAULT_HEIGHT, 0.2f, 1f, 0.01f);
|
||||||
|
|
||||||
SetDefault(OsuSetting.BeatmapListingCardSize, BeatmapCardSize.Normal);
|
SetDefault(OsuSetting.BeatmapListingCardSize, BeatmapCardSize.Normal);
|
||||||
SetDefault(OsuSetting.BeatmapListingFeaturedArtistFilter, true);
|
SetDefault(OsuSetting.BeatmapListingFeaturedArtistFilter, false);
|
||||||
|
|
||||||
SetDefault(OsuSetting.ProfileCoverExpanded, true);
|
SetDefault(OsuSetting.ProfileCoverExpanded, true);
|
||||||
|
|
||||||
SetDefault(OsuSetting.ToolbarClockDisplayMode, ToolbarClockDisplayMode.Full);
|
SetDefault(OsuSetting.ToolbarClockDisplayMode, ToolbarClockDisplayMode.Full);
|
||||||
|
|
||||||
|
SetDefault(OsuSetting.ForceLegacySongSelect, false);
|
||||||
SetDefault(OsuSetting.SongSelectBackgroundBlur, false);
|
SetDefault(OsuSetting.SongSelectBackgroundBlur, false);
|
||||||
|
|
||||||
// Online settings
|
// Online settings
|
||||||
@@ -92,7 +96,7 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
SetDefault(OsuSetting.ExternalLinkWarning, true);
|
SetDefault(OsuSetting.ExternalLinkWarning, true);
|
||||||
SetDefault(OsuSetting.PreferNoVideo, false);
|
SetDefault(OsuSetting.PreferNoVideo, false);
|
||||||
|
SetDefault(OsuSetting.BackgroundCategory, "Default");
|
||||||
SetDefault(OsuSetting.ShowOnlineExplicitContent, false);
|
SetDefault(OsuSetting.ShowOnlineExplicitContent, false);
|
||||||
|
|
||||||
SetDefault(OsuSetting.NotifyOnUsernameMentioned, true);
|
SetDefault(OsuSetting.NotifyOnUsernameMentioned, true);
|
||||||
@@ -154,6 +158,7 @@ namespace osu.Game.Configuration
|
|||||||
SetDefault(OsuSetting.ReplayPlaybackControlsExpanded, true);
|
SetDefault(OsuSetting.ReplayPlaybackControlsExpanded, true);
|
||||||
SetDefault(OsuSetting.GameplayLeaderboard, true);
|
SetDefault(OsuSetting.GameplayLeaderboard, true);
|
||||||
SetDefault(OsuSetting.AlwaysPlayFirstComboBreak, true);
|
SetDefault(OsuSetting.AlwaysPlayFirstComboBreak, true);
|
||||||
|
SetDefault(OsuSetting.AlwaysPlayComboBreak, false);
|
||||||
|
|
||||||
SetDefault(OsuSetting.FloatingComments, false);
|
SetDefault(OsuSetting.FloatingComments, false);
|
||||||
|
|
||||||
@@ -193,10 +198,13 @@ namespace osu.Game.Configuration
|
|||||||
SetDefault(OsuSetting.IntroSequence, IntroSequence.Triangles);
|
SetDefault(OsuSetting.IntroSequence, IntroSequence.Triangles);
|
||||||
|
|
||||||
SetDefault(OsuSetting.MenuBackgroundSource, BackgroundSource.Skin);
|
SetDefault(OsuSetting.MenuBackgroundSource, BackgroundSource.Skin);
|
||||||
SetDefault(OsuSetting.SeasonalBackgroundMode, SeasonalBackgroundMode.Sometimes);
|
SetDefault(OsuSetting.SeasonalBackgroundMode, SeasonalBackgroundMode.Never);
|
||||||
|
SetDefault(OsuSetting.UseSeasonalBackgroundsV2, true);
|
||||||
|
|
||||||
SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full);
|
SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full);
|
||||||
|
|
||||||
|
SetDefault(OsuSetting.DeleteImportedArchives, true);
|
||||||
|
|
||||||
SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 0.75f, 0.25f);
|
SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 0.75f, 0.25f);
|
||||||
SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f);
|
SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f);
|
||||||
SetDefault(OsuSetting.EditorShowHitMarkers, true);
|
SetDefault(OsuSetting.EditorShowHitMarkers, true);
|
||||||
@@ -362,6 +370,7 @@ namespace osu.Game.Configuration
|
|||||||
GameplayLeaderboard,
|
GameplayLeaderboard,
|
||||||
PositionalHitsoundsLevel,
|
PositionalHitsoundsLevel,
|
||||||
AlwaysPlayFirstComboBreak,
|
AlwaysPlayFirstComboBreak,
|
||||||
|
AlwaysPlayComboBreak,
|
||||||
FloatingComments,
|
FloatingComments,
|
||||||
HUDVisibilityMode,
|
HUDVisibilityMode,
|
||||||
|
|
||||||
@@ -405,6 +414,7 @@ namespace osu.Game.Configuration
|
|||||||
ChatDisplayHeight,
|
ChatDisplayHeight,
|
||||||
BeatmapListingCardSize,
|
BeatmapListingCardSize,
|
||||||
ToolbarClockDisplayMode,
|
ToolbarClockDisplayMode,
|
||||||
|
ForceLegacySongSelect,
|
||||||
SongSelectBackgroundBlur,
|
SongSelectBackgroundBlur,
|
||||||
Version,
|
Version,
|
||||||
ShowFirstRunSetup,
|
ShowFirstRunSetup,
|
||||||
@@ -412,6 +422,7 @@ namespace osu.Game.Configuration
|
|||||||
Skin,
|
Skin,
|
||||||
ScreenshotFormat,
|
ScreenshotFormat,
|
||||||
ScreenshotCaptureMenuCursor,
|
ScreenshotCaptureMenuCursor,
|
||||||
|
MenuCookieColor,
|
||||||
BeatmapSkins,
|
BeatmapSkins,
|
||||||
BeatmapColours,
|
BeatmapColours,
|
||||||
BeatmapHitsounds,
|
BeatmapHitsounds,
|
||||||
@@ -436,10 +447,13 @@ namespace osu.Game.Configuration
|
|||||||
MenuBackgroundSource,
|
MenuBackgroundSource,
|
||||||
GameplayDisableWinKey,
|
GameplayDisableWinKey,
|
||||||
SeasonalBackgroundMode,
|
SeasonalBackgroundMode,
|
||||||
|
UseSeasonalBackgroundsV2, // TODO: add migrations
|
||||||
|
BackgroundCategory,
|
||||||
EditorWaveformOpacity,
|
EditorWaveformOpacity,
|
||||||
EditorShowHitMarkers,
|
EditorShowHitMarkers,
|
||||||
EditorAutoSeekOnPlacement,
|
EditorAutoSeekOnPlacement,
|
||||||
DiscordRichPresence,
|
DiscordRichPresence,
|
||||||
|
DeleteImportedArchives,
|
||||||
|
|
||||||
ShowOnlineExplicitContent,
|
ShowOnlineExplicitContent,
|
||||||
LastProcessedMetadataId,
|
LastProcessedMetadataId,
|
||||||
|
|||||||
@@ -14,12 +14,6 @@ namespace osu.Game.Configuration
|
|||||||
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.AlwaysSeasonalBackground))]
|
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.AlwaysSeasonalBackground))]
|
||||||
Always,
|
Always,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Seasonal backgrounds are shown only during their corresponding season.
|
|
||||||
/// </summary>
|
|
||||||
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.SometimesSeasonalBackground))]
|
|
||||||
Sometimes,
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Seasonal backgrounds are never shown.
|
/// Seasonal backgrounds are never shown.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
11
osu.Game/Configuration/WelcomeMusicMode.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Configuration
|
||||||
|
{
|
||||||
|
public enum WelcomeMusicMode
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
Custom
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -206,11 +206,26 @@ namespace osu.Game.Database
|
|||||||
if (!Filename.EndsWith(realm_extension, StringComparison.Ordinal))
|
if (!Filename.EndsWith(realm_extension, StringComparison.Ordinal))
|
||||||
Filename += realm_extension;
|
Filename += realm_extension;
|
||||||
|
|
||||||
|
// since I'm an idiot, I will have to suffer
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (!DebugUtils.IsNUnitRunning)
|
if (!DebugUtils.IsNUnitRunning)
|
||||||
applyFilenameSchemaSuffix(ref Filename);
|
applyFilenameSchemaSuffix(ref Filename);
|
||||||
#endif
|
#endif
|
||||||
|
#if !DEBUG
|
||||||
|
// in the lazer. straight up "migrating it". and by "it", haha, well. let's just say. My realm .
|
||||||
|
string altFilename = filename;
|
||||||
|
applyFilenameSchemaSuffix(ref altFilename);
|
||||||
|
if (storage.Exists(altFilename) && !storage.Exists(Filename))
|
||||||
|
{
|
||||||
|
using (var previous = storage.GetStream(altFilename))
|
||||||
|
using (var current = storage.CreateFileSafely(Filename))
|
||||||
|
{
|
||||||
|
Logger.Log($@"Migrating production build DB: {altFilename} -> {Filename}");
|
||||||
|
previous.CopyTo(current);
|
||||||
|
Logger.Log("Sucessfully migrated local database!", level: LogLevel.Important);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// `prepareFirstRealmAccess()` triggers the first `getRealmInstance` call, which will implicitly run realm migrations and bring the schema up-to-date.
|
// `prepareFirstRealmAccess()` triggers the first `getRealmInstance` call, which will implicitly run realm migrations and bring the schema up-to-date.
|
||||||
using (var realm = prepareFirstRealmAccess())
|
using (var realm = prepareFirstRealmAccess())
|
||||||
cleanupPendingDeletions(realm);
|
cleanupPendingDeletions(realm);
|
||||||
|
|||||||
@@ -8,11 +8,14 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
using osu.Game.Models;
|
using osu.Game.Models;
|
||||||
@@ -77,11 +80,19 @@ namespace osu.Game.Database
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Action<Notification>? PostNotification { get; set; }
|
public Action<Notification>? PostNotification { get; set; }
|
||||||
|
|
||||||
protected RealmArchiveModelImporter(Storage storage, RealmAccess realm)
|
private readonly OsuConfigManager? config;
|
||||||
|
|
||||||
|
private Bindable<bool>? deleteImportedArchives;
|
||||||
|
|
||||||
|
protected RealmArchiveModelImporter(Storage storage, RealmAccess realm, OsuConfigManager? config = null)
|
||||||
{
|
{
|
||||||
Realm = realm;
|
Realm = realm;
|
||||||
|
|
||||||
Files = new RealmFileStore(realm, storage);
|
Files = new RealmFileStore(realm, storage);
|
||||||
|
|
||||||
|
deleteImportedArchives = config?.GetBindable<bool>(OsuSetting.DeleteImportedArchives);
|
||||||
|
|
||||||
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Import(params string[] paths) => Import(paths.Select(p => new ImportTask(p)).ToArray());
|
public Task Import(params string[] paths) => Import(paths.Select(p => new ImportTask(p)).ToArray());
|
||||||
@@ -252,9 +263,10 @@ namespace osu.Game.Database
|
|||||||
// e.g. reconstructing/repairing database with items from default storage.
|
// e.g. reconstructing/repairing database with items from default storage.
|
||||||
// Also, not always a single file, i.e. for LegacyFilesystemReader
|
// Also, not always a single file, i.e. for LegacyFilesystemReader
|
||||||
// TODO: Add a check to prevent files from storage to be deleted.
|
// TODO: Add a check to prevent files from storage to be deleted.
|
||||||
|
bool allowDelete = deleteImportedArchives?.Value ?? true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (import != null && ShouldDeleteArchive(task.Path))
|
if (import != null && ShouldDeleteArchive(task.Path) && allowDelete)
|
||||||
task.DeleteFile();
|
task.DeleteFile();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@@ -19,79 +20,121 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
{
|
{
|
||||||
public partial class SeasonalBackgroundLoader : Component
|
public partial class SeasonalBackgroundLoader : Component
|
||||||
{
|
{
|
||||||
|
public event Action<Exception> OnLoadFailure;
|
||||||
|
public event Action BackgroundChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fired when background should be changed due to receiving backgrounds from API
|
/// Fired when categories have been successfully refreshed from the server.
|
||||||
/// or when the user setting is changed (as it might require unloading the seasonal background).
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action SeasonalBackgroundChanged;
|
public event Action OnCategoriesRefreshed;
|
||||||
|
|
||||||
|
public readonly Bindable<IEnumerable<string>> AvailableCategories = new Bindable<IEnumerable<string>>(new List<string>());
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
private Bindable<SeasonalBackgroundMode> seasonalBackgroundMode;
|
private readonly IBindable<APIState> apiState = new Bindable<APIState>();
|
||||||
private Bindable<APISeasonalBackgrounds> seasonalBackgrounds;
|
private Bindable<bool> useSeasonalBackgrounds;
|
||||||
|
private Bindable<string> selectedCategory;
|
||||||
|
private Bindable<APISeasonalBackgrounds> currentBackgrounds;
|
||||||
|
|
||||||
private int current;
|
private int currentBackgroundIndex;
|
||||||
|
|
||||||
|
private bool shouldShowCustomBackgrounds => useSeasonalBackgrounds.Value;
|
||||||
|
private bool shouldFetchCustomBackgrounds = false;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config, SessionStatics sessionStatics)
|
private void load(OsuConfigManager config, SessionStatics sessionStatics)
|
||||||
{
|
{
|
||||||
seasonalBackgroundMode = config.GetBindable<SeasonalBackgroundMode>(OsuSetting.SeasonalBackgroundMode);
|
useSeasonalBackgrounds = config.GetBindable<bool>(OsuSetting.UseSeasonalBackgroundsV2);
|
||||||
seasonalBackgroundMode.BindValueChanged(_ => SeasonalBackgroundChanged?.Invoke());
|
useSeasonalBackgrounds.BindValueChanged(_ => BackgroundChanged?.Invoke());
|
||||||
|
|
||||||
seasonalBackgrounds = sessionStatics.GetBindable<APISeasonalBackgrounds>(Static.SeasonalBackgrounds);
|
selectedCategory = config.GetBindable<string>(OsuSetting.BackgroundCategory);
|
||||||
seasonalBackgrounds.BindValueChanged(_ =>
|
selectedCategory.BindValueChanged(_ => fetchBackgroundsForSelectedCategory());
|
||||||
{
|
|
||||||
if (shouldShowSeasonal)
|
|
||||||
SeasonalBackgroundChanged?.Invoke();
|
|
||||||
});
|
|
||||||
|
|
||||||
fetchSeasonalBackgrounds();
|
currentBackgrounds = sessionStatics.GetBindable<APISeasonalBackgrounds>(Static.SeasonalBackgrounds);
|
||||||
|
|
||||||
|
if (shouldShowCustomBackgrounds)
|
||||||
|
fetchCategories(true);
|
||||||
|
|
||||||
|
apiState.BindTo(api.State);
|
||||||
|
apiState.BindValueChanged(d => shouldFetchCustomBackgrounds = d.NewValue == APIState.Online, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchSeasonalBackgrounds()
|
/// <summary>
|
||||||
|
/// Public method to trigger a refresh of categories from the UI.
|
||||||
|
/// </summary>
|
||||||
|
public void RefreshCategories(bool ignoreSuccess = false)
|
||||||
{
|
{
|
||||||
if (seasonalBackgrounds.Value != null)
|
fetchCategories(ignoreSuccess);
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
private void fetchCategories(bool ignoreSuccess = false)
|
||||||
|
{
|
||||||
|
if (!shouldShowCustomBackgrounds) return;
|
||||||
|
|
||||||
|
var request = new GetBackgroundCategoriesRequest();
|
||||||
|
|
||||||
var request = new GetSeasonalBackgroundsRequest();
|
|
||||||
request.Success += response =>
|
request.Success += response =>
|
||||||
{
|
{
|
||||||
seasonalBackgrounds.Value = response;
|
var serverCategories = response.Categories ?? Enumerable.Empty<string>();
|
||||||
current = RNG.Next(0, response.Backgrounds?.Count ?? 0);
|
|
||||||
|
AvailableCategories.Value = serverCategories.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
||||||
|
|
||||||
|
if (!AvailableCategories.Value.Any())
|
||||||
|
{
|
||||||
|
selectedCategory.Value = "";
|
||||||
|
return; // we don't have any categories!!!
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AvailableCategories.Value.Contains(selectedCategory.Value))
|
||||||
|
selectedCategory.Value = AvailableCategories.Value.Contains("Default")
|
||||||
|
? "Default"
|
||||||
|
: AvailableCategories.Value.ElementAt(0);
|
||||||
|
|
||||||
|
fetchBackgroundsForSelectedCategory();
|
||||||
|
|
||||||
|
if (!ignoreSuccess)
|
||||||
|
OnCategoriesRefreshed?.Invoke();
|
||||||
|
};
|
||||||
|
|
||||||
|
request.Failure += exception =>
|
||||||
|
{
|
||||||
|
AvailableCategories.Value = Array.Empty<string>();
|
||||||
|
OnLoadFailure?.Invoke(exception);
|
||||||
};
|
};
|
||||||
|
|
||||||
api.PerformAsync(request);
|
api.PerformAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SeasonalBackground LoadNextBackground()
|
private void fetchBackgroundsForSelectedCategory()
|
||||||
{
|
{
|
||||||
if (!shouldShowSeasonal)
|
if (!shouldShowCustomBackgrounds) return;
|
||||||
return null;
|
|
||||||
|
|
||||||
var backgrounds = seasonalBackgrounds.Value.Backgrounds;
|
string categoryToFetch = selectedCategory.Value == "Default" ? null : selectedCategory.Value;
|
||||||
|
var request = new GetSeasonalBackgroundsRequest(categoryToFetch);
|
||||||
|
|
||||||
current = (current + 1) % backgrounds.Count;
|
request.Success += response =>
|
||||||
string url = backgrounds[current].Url;
|
{
|
||||||
|
currentBackgrounds.Value = response;
|
||||||
|
currentBackgroundIndex = RNG.Next(0, response.Backgrounds?.Count ?? 0);
|
||||||
|
BackgroundChanged?.Invoke();
|
||||||
|
};
|
||||||
|
|
||||||
|
api.PerformAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Background LoadNextBackground()
|
||||||
|
{
|
||||||
|
if (!shouldShowCustomBackgrounds || !shouldFetchCustomBackgrounds || currentBackgrounds.Value?.Backgrounds?.Any() != true)
|
||||||
|
return new Background($@"Menu/menu-background-{RNG.Next(1, 9)}");
|
||||||
|
|
||||||
|
var backgrounds = currentBackgrounds.Value.Backgrounds;
|
||||||
|
currentBackgroundIndex = (currentBackgroundIndex + 1) % backgrounds.Count;
|
||||||
|
string url = backgrounds[currentBackgroundIndex].Url;
|
||||||
|
|
||||||
return new SeasonalBackground(url);
|
return new SeasonalBackground(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool shouldShowSeasonal
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (seasonalBackgroundMode.Value == SeasonalBackgroundMode.Never)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (seasonalBackgroundMode.Value == SeasonalBackgroundMode.Sometimes && !isInSeason)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return seasonalBackgrounds.Value?.Backgrounds?.Any() == true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool isInSeason => seasonalBackgrounds.Value != null && DateTimeOffset.Now < seasonalBackgrounds.Value.EndDate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[LongRunningLoad]
|
[LongRunningLoad]
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ namespace osu.Game.Graphics
|
|||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case BeatmapOnlineStatus.None:
|
case BeatmapOnlineStatus.None:
|
||||||
return Color4.RosyBrown;
|
return Color4.AliceBlue;
|
||||||
|
|
||||||
case BeatmapOnlineStatus.LocallyModified:
|
case BeatmapOnlineStatus.LocallyModified:
|
||||||
return Color4.OrangeRed;
|
return Color4.OrangeRed;
|
||||||
@@ -183,6 +183,9 @@ namespace osu.Game.Graphics
|
|||||||
case ModType.System:
|
case ModType.System:
|
||||||
return Yellow;
|
return Yellow;
|
||||||
|
|
||||||
|
case ModType.Special:
|
||||||
|
return Orange2;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException(nameof(modType), modType, "Unknown mod type");
|
throw new ArgumentOutOfRangeException(nameof(modType), modType, "Unknown mod type");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
protected OverlayColourProvider ColourProvider { get; private set; } = null!;
|
protected OverlayColourProvider? ColourProvider { get; private set; } = null!;
|
||||||
|
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
private readonly OsuSpriteText text;
|
private readonly OsuSpriteText text;
|
||||||
@@ -190,9 +190,9 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
private void updateState()
|
private void updateState()
|
||||||
{
|
{
|
||||||
var colourDark = darkerColour ?? ColourProvider.Background3;
|
var colourDark = darkerColour ?? ColourProvider?.Background3 ?? Colour4.DarkGray;
|
||||||
var colourLight = lighterColour ?? ColourProvider.Background1;
|
var colourLight = lighterColour ?? ColourProvider?.Background1 ?? Colour4.LightGray;
|
||||||
var colourContent = textColour ?? ColourProvider.Content1;
|
var colourContent = textColour ?? ColourProvider?.Content1 ?? Colour4.White;
|
||||||
|
|
||||||
if (!Enabled.Value)
|
if (!Enabled.Value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
@@ -63,9 +64,9 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
protected virtual void UpdateActiveState()
|
protected virtual void UpdateActiveState()
|
||||||
{
|
{
|
||||||
DarkerColour = Active.Value ? ColourProvider.Highlight1 : ColourProvider.Background3;
|
DarkerColour = Active.Value ? ColourProvider?.Highlight1 ?? Colour4.Gray : ColourProvider?.Background3 ?? Colour4.DimGray;
|
||||||
LighterColour = Active.Value ? ColourProvider.Colour0 : ColourProvider.Background1;
|
LighterColour = Active.Value ? ColourProvider?.Colour0 ?? Colour4.AliceBlue : ColourProvider?.Background1 ?? Colour4.LightGray;
|
||||||
TextColour = Active.Value ? ColourProvider.Background6 : ColourProvider.Content1;
|
TextColour = Active.Value ? ColourProvider?.Background6 ?? Colour4.Black : ColourProvider?.Content1 ?? Colour4.DarkGray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playSample()
|
private void playSample()
|
||||||
|
|||||||
@@ -140,9 +140,9 @@ namespace osu.Game.Localisation
|
|||||||
public static LocalisableString LoadInBrowserAfterSubmission => new TranslatableString(getKey(@"load_in_browser_after_submission"), @"Load in browser after submission");
|
public static LocalisableString LoadInBrowserAfterSubmission => new TranslatableString(getKey(@"load_in_browser_after_submission"), @"Load in browser after submission");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Note: In order to make it possible for users of all osu! versions to enjoy your beatmap, it will be exported in a backwards-compatible format. While we have made efforts to ensure that this process keeps the beatmap playable in its intended form, some data related to features that previous versions of osu! do not support may be lost."
|
/// "Note: In order to make it possible for users of all game versions to enjoy your beatmap, it will be exported in a backwards-compatible format. While we have made efforts to ensure that this process keeps the beatmap playable in its intended form, some data related to features that previous versions of osu! do not support may be lost."
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString LegacyExportDisclaimer => new TranslatableString(getKey(@"legacy_export_disclaimer"), @"Note: In order to make it possible for users of all osu! versions to enjoy your beatmap, it will be exported in a backwards-compatible format. While we have made efforts to ensure that this process keeps the beatmap playable in its intended form, some data related to features that previous versions of osu! do not support may be lost.");
|
public static LocalisableString LegacyExportDisclaimer => new TranslatableString(getKey(@"legacy_export_disclaimer"), @"Note: In order to make it possible for users of all game versions to enjoy your beatmap, it will be exported in a backwards-compatible format. While we have made efforts to ensure that this process keeps the beatmap playable in its intended form, some data related to features that previous versions of osu! do not support may be lost.");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Empty beatmaps cannot be submitted."
|
/// "Empty beatmaps cannot be submitted."
|
||||||
|
|||||||