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

Merge remote-tracking branch 'upstream/master' into fix-op-non-current-onexiting

This commit is contained in:
Joseph Madamba 2022-12-24 14:01:11 -08:00
commit 00ed5d6f92
3098 changed files with 41866 additions and 31216 deletions

View File

@ -3,7 +3,7 @@
"isRoot": true, "isRoot": true,
"tools": { "tools": {
"jetbrains.resharper.globaltools": { "jetbrains.resharper.globaltools": {
"version": "2022.1.1", "version": "2022.2.3",
"commands": [ "commands": [
"jb" "jb"
] ]
@ -21,7 +21,7 @@
] ]
}, },
"ppy.localisationanalyser.tools": { "ppy.localisationanalyser.tools": {
"version": "2022.607.0", "version": "2022.809.0",
"commands": [ "commands": [
"localisation" "localisation"
] ]

View File

@ -1,2 +1,8 @@
# Normalize all the line endings # Normalize all the line endings
32a74f95a5c80a0ed18e693f13a47522099df5c3 32a74f95a5c80a0ed18e693f13a47522099df5c3
# Partial everything
7bc8908ca9c026fed1d831eb6e58df7624a8d614
# Add a few more missing partial specs
212d78865a6b5f091173a347bad5686834d1d5fe
# Add partial specs in mobile projects too
00c11b2b4e389e48f3995d63484a6bc66a7afbdb

View File

@ -58,7 +58,8 @@ body:
The default places to find the logs on desktop platforms are as follows: The default places to find the logs on desktop platforms are as follows:
- `%AppData%/osu/logs` *on Windows* - `%AppData%/osu/logs` *on Windows*
- `~/.local/share/osu/logs` *on Linux & macOS* - `~/.local/share/osu/logs` *on Linux*
- `~/Library/Application Support/osu/logs` *on macOS*
If you have selected a custom location for the game files, you can find the `logs` folder there. If you have selected a custom location for the game files, you can find the `logs` folder there.

View File

@ -1,5 +1,11 @@
on: [push, pull_request] on: [push, pull_request]
name: Continuous Integration name: Continuous Integration
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read # to fetch code (actions/checkout)
jobs: jobs:
inspect-code: inspect-code:
@ -25,7 +31,7 @@ jobs:
run: dotnet tool restore run: dotnet tool restore
- name: Restore Packages - name: Restore Packages
run: dotnet restore run: dotnet restore osu.Desktop.slnf
- name: Restore inspectcode cache - name: Restore inspectcode cache
uses: actions/cache@v3 uses: actions/cache@v3
@ -82,7 +88,7 @@ jobs:
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
- name: Test - name: Test
run: dotnet test $pwd/**/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx" run: dotnet test $pwd/**/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx" -- NUnit.ConsoleOut=0
shell: pwsh shell: pwsh
# Attempt to upload results even if test fails. # Attempt to upload results even if test fails.
@ -107,27 +113,36 @@ jobs:
with: with:
dotnet-version: "6.0.x" dotnet-version: "6.0.x"
- name: Setup MSBuild - name: Install .NET workloads
uses: microsoft/setup-msbuild@v1 run: dotnet workload install maui-android
- name: Build - name: Compile
run: msbuild osu.Android/osu.Android.csproj /restore /p:Configuration=Debug run: dotnet build -c Debug osu.Android.slnf
build-only-ios: build-only-ios:
name: Build only (iOS) name: Build only (iOS)
runs-on: macos-latest # change to macos-latest once GitHub finishes migrating all repositories to macOS 12.
runs-on: macos-12
timeout-minutes: 60 timeout-minutes: 60
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
# see https://github.com/actions/runner-images/issues/6771#issuecomment-1354713617
# remove once all workflow VMs use Xcode 14.1
- name: Set Xcode Version
shell: bash
run: |
sudo xcode-select -s "/Applications/Xcode_14.1.app"
echo "MD_APPLE_SDK_ROOT=/Applications/Xcode_14.1.app" >> $GITHUB_ENV
- name: Install .NET 6.0.x - name: Install .NET 6.0.x
uses: actions/setup-dotnet@v1 uses: actions/setup-dotnet@v1
with: with:
dotnet-version: "6.0.x" dotnet-version: "6.0.x"
# Contrary to seemingly any other msbuild, msbuild running on macOS/Mono - name: Install .NET Workloads
# cannot accept .sln(f) files as arguments. run: dotnet workload install maui-ios
# Build just the main game for now.
- name: Build - name: Build
run: msbuild osu.iOS/osu.iOS.csproj /restore /p:Configuration=Debug run: dotnet build -c Debug osu.iOS

View File

@ -8,8 +8,12 @@ on:
workflows: ["Continuous Integration"] workflows: ["Continuous Integration"]
types: types:
- completed - completed
permissions: {}
jobs: jobs:
annotate: annotate:
permissions:
checks: write # to create checks (dorny/test-reporter)
name: Annotate CI run with test results name: Annotate CI run with test results
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion != 'cancelled' }} if: ${{ github.event.workflow_run.conclusion != 'cancelled' }}
@ -24,7 +28,7 @@ jobs:
timeout-minutes: 5 timeout-minutes: 5
steps: steps:
- name: Annotate CI run with test results - name: Annotate CI run with test results
uses: dorny/test-reporter@v1.4.2 uses: dorny/test-reporter@v1.6.0
with: with:
artifact: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}} artifact: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
name: Test Results (${{matrix.os.prettyname}}, ${{matrix.threadingMode}}) name: Test Results (${{matrix.os.prettyname}}, ${{matrix.threadingMode}})

View File

@ -5,6 +5,9 @@ on:
tags: tags:
- '*' - '*'
permissions:
contents: read # to fetch code (actions/checkout)
jobs: jobs:
sentry_release: sentry_release:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -53,3 +53,7 @@ dotnet_diagnostic.CA2225.severity = none
# Banned APIs # Banned APIs
dotnet_diagnostic.RS0030.severity = error dotnet_diagnostic.RS0030.severity = error
# Temporarily disable analysing CanBeNull = true in NRT contexts due to mobile issues.
# See: https://github.com/ppy/osu/pull/19677
dotnet_diagnostic.OSUF001.severity = none

View File

@ -23,7 +23,8 @@ Issues, bug reports and feature suggestions are welcomed, though please keep in
* the in-game logs, which are located at: * the in-game logs, which are located at:
* `%AppData%/osu/logs` (on Windows), * `%AppData%/osu/logs` (on Windows),
* `~/.local/share/osu/logs` (on Linux and macOS), * `~/.local/share/osu/logs` (on Linux),
* `~/Library/Application Support/osu/logs` (on macOS),
* `Android/data/sh.ppy.osulazer/files/logs` (on Android), * `Android/data/sh.ppy.osulazer/files/logs` (on Android),
* on iOS they can be obtained by connecting your device to your desktop and [copying the `logs` directory from the app's own document storage using iTunes](https://support.apple.com/en-us/HT201301#copy-to-computer), * on iOS they can be obtained by connecting your device to your desktop and [copying the `logs` directory from the app's own document storage using iTunes](https://support.apple.com/en-us/HT201301#copy-to-computer),
* your system specifications (including the operating system and platform you are playing on), * your system specifications (including the operating system and platform you are playing on),

View File

@ -6,8 +6,6 @@ T:System.IComparable;Don't use non-generic IComparable. Use generic version inst
T:SixLabors.ImageSharp.IDeepCloneable`1;Use osu.Game.Utils.IDeepCloneable<T> instead. T:SixLabors.ImageSharp.IDeepCloneable`1;Use osu.Game.Utils.IDeepCloneable<T> instead.
M:osu.Framework.Graphics.Sprites.SpriteText.#ctor;Use OsuSpriteText. M:osu.Framework.Graphics.Sprites.SpriteText.#ctor;Use OsuSpriteText.
M:osu.Framework.Bindables.IBindableList`1.GetBoundCopy();Fails on iOS. Use manual ctor + BindTo instead. (see https://github.com/mono/mono/issues/19900) M:osu.Framework.Bindables.IBindableList`1.GetBoundCopy();Fails on iOS. Use manual ctor + BindTo instead. (see https://github.com/mono/mono/issues/19900)
T:Microsoft.EntityFrameworkCore.Internal.EnumerableExtensions;Don't use internal extension methods.
T:Microsoft.EntityFrameworkCore.Internal.TypeExtensions;Don't use internal extension methods.
T:NuGet.Packaging.CollectionExtensions;Don't use internal extension methods. T:NuGet.Packaging.CollectionExtensions;Don't use internal extension methods.
M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.HasFlagFast<T>() instead. M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.HasFlagFast<T>() instead.
M:Realms.IRealmCollection`1.SubscribeForNotifications`1(Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IRealmCollection<T>,NotificationCallbackDelegate<T>) instead. M:Realms.IRealmCollection`1.SubscribeForNotifications`1(Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IRealmCollection<T>,NotificationCallbackDelegate<T>) instead.
@ -17,6 +15,8 @@ M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Gen
M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks. M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks.
P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result. Use Task.GetResultSafely() to ensure we avoid deadlocks. P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result. Use Task.GetResultSafely() to ensure we avoid deadlocks.
M:System.Threading.ManualResetEventSlim.Wait();Specify a timeout to avoid waiting forever. M:System.Threading.ManualResetEventSlim.Wait();Specify a timeout to avoid waiting forever.
M:System.Char.ToLower(System.Char);char.ToLower() changes behaviour depending on CultureInfo.CurrentCulture. Use char.ToLowerInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture.
M:System.Char.ToUpper(System.Char);char.ToUpper() changes behaviour depending on CultureInfo.CurrentCulture. Use char.ToUpperInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture.
M:System.String.ToLower();string.ToLower() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToLowerInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString. M:System.String.ToLower();string.ToLower() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToLowerInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString.
M:System.String.ToUpper();string.ToUpper() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToUpperInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString. M:System.String.ToUpper();string.ToUpper() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToUpperInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString.
M:Humanizer.InflectorExtensions.Pascalize(System.String);Humanizer's .Pascalize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToPascalCase() instead. M:Humanizer.InflectorExtensions.Pascalize(System.String);Humanizer's .Pascalize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToPascalCase() instead.

View File

@ -3,25 +3,25 @@ GEM
specs: specs:
CFPropertyList (3.0.5) CFPropertyList (3.0.5)
rexml rexml
addressable (2.8.0) addressable (2.8.1)
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 6.0)
artifactory (3.0.15) artifactory (3.0.15)
atomos (0.1.3) atomos (0.1.3)
aws-eventstream (1.2.0) aws-eventstream (1.2.0)
aws-partitions (1.601.0) aws-partitions (1.653.0)
aws-sdk-core (3.131.2) aws-sdk-core (3.166.0)
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0) aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1) jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.57.0) aws-sdk-kms (1.59.0)
aws-sdk-core (~> 3, >= 3.127.0) aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.114.0) aws-sdk-s3 (1.117.1)
aws-sdk-core (~> 3, >= 3.127.0) aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4) aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.0) aws-sigv4 (1.5.2)
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4) babosa (1.0.4)
claide (1.1.0) claide (1.1.0)
@ -34,10 +34,10 @@ GEM
rake (>= 12.0.0, < 14.0.0) rake (>= 12.0.0, < 14.0.0)
domain_name (0.5.20190701) domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6) dotenv (2.8.1)
emoji_regex (3.2.3) emoji_regex (3.2.3)
excon (0.92.3) excon (0.93.1)
faraday (1.10.0) faraday (1.10.2)
faraday-em_http (~> 1.0) faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0) faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1) faraday-excon (~> 1.1)
@ -66,7 +66,7 @@ GEM
faraday_middleware (1.2.0) faraday_middleware (1.2.0)
faraday (~> 1.0) faraday (~> 1.0)
fastimage (2.2.6) fastimage (2.2.6)
fastlane (2.206.2) fastlane (2.210.1)
CFPropertyList (>= 2.3, < 4.0.0) CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0) addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0) artifactory (~> 3.0)
@ -110,9 +110,9 @@ GEM
souyuz (= 0.11.1) souyuz (= 0.11.1)
fastlane-plugin-xamarin (0.6.3) fastlane-plugin-xamarin (0.6.3)
gh_inspector (1.1.3) gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.23.0) google-apis-androidpublisher_v3 (0.29.0)
google-apis-core (>= 0.6, < 2.a) google-apis-core (>= 0.9.0, < 2.a)
google-apis-core (0.6.0) google-apis-core (0.9.1)
addressable (~> 2.5, >= 2.5.1) addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a) googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a) httpclient (>= 2.8.1, < 3.a)
@ -121,27 +121,27 @@ GEM
retriable (>= 2.0, < 4.a) retriable (>= 2.0, < 4.a)
rexml rexml
webrick webrick
google-apis-iamcredentials_v1 (0.12.0) google-apis-iamcredentials_v1 (0.15.0)
google-apis-core (>= 0.6, < 2.a) google-apis-core (>= 0.9.0, < 2.a)
google-apis-playcustomapp_v1 (0.9.0) google-apis-playcustomapp_v1 (0.12.0)
google-apis-core (>= 0.6, < 2.a) google-apis-core (>= 0.9.1, < 2.a)
google-apis-storage_v1 (0.16.0) google-apis-storage_v1 (0.19.0)
google-apis-core (>= 0.6, < 2.a) google-apis-core (>= 0.9.0, < 2.a)
google-cloud-core (1.6.0) google-cloud-core (1.6.0)
google-cloud-env (~> 1.0) google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0) google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0) google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0) faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.2.0) google-cloud-errors (1.3.0)
google-cloud-storage (1.36.2) google-cloud-storage (1.43.0)
addressable (~> 2.8) addressable (~> 2.8)
digest-crc (~> 0.4) digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1) google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.1) google-apis-storage_v1 (~> 0.19.0)
google-cloud-core (~> 1.6) google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a) googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0) mini_mime (~> 1.0)
googleauth (1.2.0) googleauth (1.3.0)
faraday (>= 0.17.3, < 3.a) faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0) jwt (>= 1.4, < 3.0)
memoist (~> 0.16) memoist (~> 0.16)
@ -154,22 +154,22 @@ GEM
httpclient (2.8.3) httpclient (2.8.3)
jmespath (1.6.1) jmespath (1.6.1)
json (2.6.2) json (2.6.2)
jwt (2.4.1) jwt (2.5.0)
memoist (0.16.2) memoist (0.16.2)
mini_magick (4.11.0) mini_magick (4.11.0)
mini_mime (1.1.2) mini_mime (1.1.2)
mini_portile2 (2.7.1) mini_portile2 (2.8.0)
multi_json (1.15.0) multi_json (1.15.0)
multipart-post (2.0.0) multipart-post (2.0.0)
nanaimo (0.3.0) nanaimo (0.3.0)
naturally (2.2.1) naturally (2.2.1)
nokogiri (1.13.1) nokogiri (1.13.9)
mini_portile2 (~> 2.7.0) mini_portile2 (~> 2.8.0)
racc (~> 1.4) racc (~> 1.4)
optparse (0.1.1) optparse (0.1.1)
os (1.1.4) os (1.1.4)
plist (3.6.0) plist (3.6.0)
public_suffix (4.0.7) public_suffix (5.0.0)
racc (1.6.0) racc (1.6.0)
rake (13.0.6) rake (13.0.6)
representable (3.2.0) representable (3.2.0)

View File

@ -32,7 +32,7 @@ If you are looking to install or test osu! without setting up a development envi
**Latest build:** **Latest build:**
| [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 10.15+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 10+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) | | [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 10.15+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
| ------------- | ------------- | ------------- | ------------- | ------------- | | ------------- | ------------- | ------------- | ------------- | ------------- |
- The iOS testflight link may fill up (Apple has a hard limit of 10,000 users). We reset it occasionally when this happens. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements of link resets. - The iOS testflight link may fill up (Apple has a hard limit of 10,000 users). We reset it occasionally when this happens. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements of link resets.

View File

@ -9,7 +9,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.EmptyFreeform.Tests namespace osu.Game.Rulesets.EmptyFreeform.Tests
{ {
public class TestSceneOsuGame : OsuTestScene public partial class TestSceneOsuGame : OsuTestScene
{ {
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()

View File

@ -7,7 +7,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.EmptyFreeform.Tests namespace osu.Game.Rulesets.EmptyFreeform.Tests
{ {
[TestFixture] [TestFixture]
public class TestSceneOsuPlayer : PlayerTestScene public partial class TestSceneOsuPlayer : PlayerTestScene
{ {
protected override Ruleset CreatePlayerRuleset() => new EmptyFreeformRuleset(); protected override Ruleset CreatePlayerRuleset() => new EmptyFreeformRuleset();
} }

View File

@ -9,10 +9,9 @@
<GenerateProgramFile>false</GenerateProgramFile> <GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="NUnit" Version="3.13.3" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.EmptyFreeform\osu.Game.Rulesets.EmptyFreeform.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.EmptyFreeform\osu.Game.Rulesets.EmptyFreeform.csproj" />

View File

@ -7,7 +7,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.EmptyFreeform namespace osu.Game.Rulesets.EmptyFreeform
{ {
public class EmptyFreeformInputManager : RulesetInputManager<EmptyFreeformAction> public partial class EmptyFreeformInputManager : RulesetInputManager<EmptyFreeformAction>
{ {
public EmptyFreeformInputManager(RulesetInfo ruleset) public EmptyFreeformInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique) : base(ruleset, 0, SimultaneousBindingMode.Unique)

View File

@ -21,7 +21,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.EmptyFreeform namespace osu.Game.Rulesets.EmptyFreeform
{ {
public class EmptyFreeformRuleset : Ruleset public partial class EmptyFreeformRuleset : Ruleset
{ {
public override string Description => "a very emptyfreeformruleset ruleset"; public override string Description => "a very emptyfreeformruleset ruleset";
@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.EmptyFreeform
public override Drawable CreateIcon() => new Icon(ShortName[0]); public override Drawable CreateIcon() => new Icon(ShortName[0]);
public class Icon : CompositeDrawable public partial class Icon : CompositeDrawable
{ {
public Icon(char c) public Icon(char c)
{ {
@ -77,5 +77,8 @@ namespace osu.Game.Rulesets.EmptyFreeform
}; };
} }
} }
// Leave this line intact. It will bake the correct version into the ruleset on each build/release.
public override string RulesetAPIVersionSupported => CURRENT_RULESET_API_VERSION;
} }
} }

View File

@ -9,7 +9,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.EmptyFreeform.Objects.Drawables namespace osu.Game.Rulesets.EmptyFreeform.Objects.Drawables
{ {
public class DrawableEmptyFreeformHitObject : DrawableHitObject<EmptyFreeformHitObject> public partial class DrawableEmptyFreeformHitObject : DrawableHitObject<EmptyFreeformHitObject>
{ {
public DrawableEmptyFreeformHitObject(EmptyFreeformHitObject hitObject) public DrawableEmptyFreeformHitObject(EmptyFreeformHitObject hitObject)
: base(hitObject) : base(hitObject)

View File

@ -17,7 +17,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.EmptyFreeform.UI namespace osu.Game.Rulesets.EmptyFreeform.UI
{ {
[Cached] [Cached]
public class DrawableEmptyFreeformRuleset : DrawableRuleset<EmptyFreeformHitObject> public partial class DrawableEmptyFreeformRuleset : DrawableRuleset<EmptyFreeformHitObject>
{ {
public DrawableEmptyFreeformRuleset(EmptyFreeformRuleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null) public DrawableEmptyFreeformRuleset(EmptyFreeformRuleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
: base(ruleset, beatmap, mods) : base(ruleset, beatmap, mods)

View File

@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.EmptyFreeform.UI namespace osu.Game.Rulesets.EmptyFreeform.UI
{ {
[Cached] [Cached]
public class EmptyFreeformPlayfield : Playfield public partial class EmptyFreeformPlayfield : Playfield
{ {
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<AssemblyTitle>osu.Game.Rulesets.EmptyFreeform</AssemblyTitle> <AssemblyTitle>osu.Game.Rulesets.EmptyFreeform</AssemblyTitle>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>

View File

@ -9,7 +9,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Pippidon.Tests namespace osu.Game.Rulesets.Pippidon.Tests
{ {
public class TestSceneOsuGame : OsuTestScene public partial class TestSceneOsuGame : OsuTestScene
{ {
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()

View File

@ -7,7 +7,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Pippidon.Tests namespace osu.Game.Rulesets.Pippidon.Tests
{ {
[TestFixture] [TestFixture]
public class TestSceneOsuPlayer : PlayerTestScene public partial class TestSceneOsuPlayer : PlayerTestScene
{ {
protected override Ruleset CreatePlayerRuleset() => new PippidonRuleset(); protected override Ruleset CreatePlayerRuleset() => new PippidonRuleset();
} }

View File

@ -9,10 +9,9 @@
<GenerateProgramFile>false</GenerateProgramFile> <GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="NUnit" Version="3.13.3" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.Pippidon\osu.Game.Rulesets.Pippidon.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.Pippidon\osu.Game.Rulesets.Pippidon.csproj" />

View File

@ -16,7 +16,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Pippidon.Objects.Drawables namespace osu.Game.Rulesets.Pippidon.Objects.Drawables
{ {
public class DrawablePippidonHitObject : DrawableHitObject<PippidonHitObject> public partial class DrawablePippidonHitObject : DrawableHitObject<PippidonHitObject>
{ {
private const double time_preempt = 600; private const double time_preempt = 600;
private const double time_fadein = 400; private const double time_fadein = 400;

View File

@ -7,7 +7,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Pippidon namespace osu.Game.Rulesets.Pippidon
{ {
public class PippidonInputManager : RulesetInputManager<PippidonAction> public partial class PippidonInputManager : RulesetInputManager<PippidonAction>
{ {
public PippidonInputManager(RulesetInfo ruleset) public PippidonInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique) : base(ruleset, 0, SimultaneousBindingMode.Unique)

View File

@ -4,8 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty;
@ -50,9 +48,9 @@ namespace osu.Game.Rulesets.Pippidon
new KeyBinding(InputKey.X, PippidonAction.Button2), new KeyBinding(InputKey.X, PippidonAction.Button2),
}; };
public override Drawable CreateIcon() => new Sprite public override Drawable CreateIcon() => new PippidonRulesetIcon(this);
{
Texture = new TextureStore(new TextureLoaderStore(CreateResourceStore()), false).Get("Textures/coin"), // Leave this line intact. It will bake the correct version into the ruleset on each build/release.
}; public override string RulesetAPIVersionSupported => CURRENT_RULESET_API_VERSION;
} }
} }

View File

@ -0,0 +1,26 @@
// 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.Framework.Graphics.Rendering;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
namespace osu.Game.Rulesets.Pippidon
{
public partial class PippidonRulesetIcon : Sprite
{
private readonly Ruleset ruleset;
public PippidonRulesetIcon(Ruleset ruleset)
{
this.ruleset = ruleset;
}
[BackgroundDependencyLoader]
private void load(IRenderer renderer)
{
Texture = new TextureStore(renderer, new TextureLoaderStore(ruleset.CreateResourceStore()), false).Get("Textures/coin");
}
}
}

View File

@ -17,7 +17,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Pippidon.UI namespace osu.Game.Rulesets.Pippidon.UI
{ {
[Cached] [Cached]
public class DrawablePippidonRuleset : DrawableRuleset<PippidonHitObject> public partial class DrawablePippidonRuleset : DrawableRuleset<PippidonHitObject>
{ {
public DrawablePippidonRuleset(PippidonRuleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null) public DrawablePippidonRuleset(PippidonRuleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
: base(ruleset, beatmap, mods) : base(ruleset, beatmap, mods)

View File

@ -10,7 +10,7 @@ using osuTK;
namespace osu.Game.Rulesets.Pippidon.UI namespace osu.Game.Rulesets.Pippidon.UI
{ {
public class PippidonCursorContainer : GameplayCursorContainer public partial class PippidonCursorContainer : GameplayCursorContainer
{ {
private Sprite cursorSprite; private Sprite cursorSprite;
private Texture cursorTexture; private Texture cursorTexture;

View File

@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Pippidon.UI namespace osu.Game.Rulesets.Pippidon.UI
{ {
[Cached] [Cached]
public class PippidonPlayfield : Playfield public partial class PippidonPlayfield : Playfield
{ {
protected override GameplayCursorContainer CreateCursor() => new PippidonCursorContainer(); protected override GameplayCursorContainer CreateCursor() => new PippidonCursorContainer();

View File

@ -7,7 +7,7 @@ using osuTK;
namespace osu.Game.Rulesets.Pippidon.UI namespace osu.Game.Rulesets.Pippidon.UI
{ {
public class PippidonPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer public partial class PippidonPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer
{ {
public PippidonPlayfieldAdjustmentContainer() public PippidonPlayfieldAdjustmentContainer()
{ {

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<AssemblyTitle>osu.Game.Rulesets.Pippidon</AssemblyTitle> <AssemblyTitle>osu.Game.Rulesets.Pippidon</AssemblyTitle>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>

View File

@ -9,7 +9,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.EmptyScrolling.Tests namespace osu.Game.Rulesets.EmptyScrolling.Tests
{ {
public class TestSceneOsuGame : OsuTestScene public partial class TestSceneOsuGame : OsuTestScene
{ {
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()

View File

@ -7,7 +7,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.EmptyScrolling.Tests namespace osu.Game.Rulesets.EmptyScrolling.Tests
{ {
[TestFixture] [TestFixture]
public class TestSceneOsuPlayer : PlayerTestScene public partial class TestSceneOsuPlayer : PlayerTestScene
{ {
protected override Ruleset CreatePlayerRuleset() => new EmptyScrollingRuleset(); protected override Ruleset CreatePlayerRuleset() => new EmptyScrollingRuleset();
} }

View File

@ -9,10 +9,9 @@
<GenerateProgramFile>false</GenerateProgramFile> <GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="NUnit" Version="3.13.3" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.EmptyScrolling\osu.Game.Rulesets.EmptyScrolling.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.EmptyScrolling\osu.Game.Rulesets.EmptyScrolling.csproj" />

View File

@ -7,7 +7,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.EmptyScrolling namespace osu.Game.Rulesets.EmptyScrolling
{ {
public class EmptyScrollingInputManager : RulesetInputManager<EmptyScrollingAction> public partial class EmptyScrollingInputManager : RulesetInputManager<EmptyScrollingAction>
{ {
public EmptyScrollingInputManager(RulesetInfo ruleset) public EmptyScrollingInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique) : base(ruleset, 0, SimultaneousBindingMode.Unique)

View File

@ -54,5 +54,8 @@ namespace osu.Game.Rulesets.EmptyScrolling
Text = ShortName[0].ToString(), Text = ShortName[0].ToString(),
Font = OsuFont.Default.With(size: 18), Font = OsuFont.Default.With(size: 18),
}; };
// Leave this line intact. It will bake the correct version into the ruleset on each build/release.
public override string RulesetAPIVersionSupported => CURRENT_RULESET_API_VERSION;
} }
} }

View File

@ -9,7 +9,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.EmptyScrolling.Objects.Drawables namespace osu.Game.Rulesets.EmptyScrolling.Objects.Drawables
{ {
public class DrawableEmptyScrollingHitObject : DrawableHitObject<EmptyScrollingHitObject> public partial class DrawableEmptyScrollingHitObject : DrawableHitObject<EmptyScrollingHitObject>
{ {
public DrawableEmptyScrollingHitObject(EmptyScrollingHitObject hitObject) public DrawableEmptyScrollingHitObject(EmptyScrollingHitObject hitObject)
: base(hitObject) : base(hitObject)

View File

@ -18,7 +18,7 @@ using osu.Game.Rulesets.UI.Scrolling;
namespace osu.Game.Rulesets.EmptyScrolling.UI namespace osu.Game.Rulesets.EmptyScrolling.UI
{ {
[Cached] [Cached]
public class DrawableEmptyScrollingRuleset : DrawableScrollingRuleset<EmptyScrollingHitObject> public partial class DrawableEmptyScrollingRuleset : DrawableScrollingRuleset<EmptyScrollingHitObject>
{ {
public DrawableEmptyScrollingRuleset(EmptyScrollingRuleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null) public DrawableEmptyScrollingRuleset(EmptyScrollingRuleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
: base(ruleset, beatmap, mods) : base(ruleset, beatmap, mods)

View File

@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI.Scrolling;
namespace osu.Game.Rulesets.EmptyScrolling.UI namespace osu.Game.Rulesets.EmptyScrolling.UI
{ {
[Cached] [Cached]
public class EmptyScrollingPlayfield : ScrollingPlayfield public partial class EmptyScrollingPlayfield : ScrollingPlayfield
{ {
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<AssemblyTitle>osu.Game.Rulesets.EmptyScrolling</AssemblyTitle> <AssemblyTitle>osu.Game.Rulesets.EmptyScrolling</AssemblyTitle>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>

View File

@ -9,7 +9,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Pippidon.Tests namespace osu.Game.Rulesets.Pippidon.Tests
{ {
public class TestSceneOsuGame : OsuTestScene public partial class TestSceneOsuGame : OsuTestScene
{ {
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()

View File

@ -7,7 +7,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Pippidon.Tests namespace osu.Game.Rulesets.Pippidon.Tests
{ {
[TestFixture] [TestFixture]
public class TestSceneOsuPlayer : PlayerTestScene public partial class TestSceneOsuPlayer : PlayerTestScene
{ {
protected override Ruleset CreatePlayerRuleset() => new PippidonRuleset(); protected override Ruleset CreatePlayerRuleset() => new PippidonRuleset();
} }

View File

@ -9,10 +9,9 @@
<GenerateProgramFile>false</GenerateProgramFile> <GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="NUnit" Version="3.13.3" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.Pippidon\osu.Game.Rulesets.Pippidon.csproj" /> <ProjectReference Include="..\osu.Game.Rulesets.Pippidon\osu.Game.Rulesets.Pippidon.csproj" />

View File

@ -20,10 +20,13 @@ namespace osu.Game.Rulesets.Pippidon.Beatmaps
public PippidonBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) public PippidonBeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
: base(beatmap, ruleset) : base(beatmap, ruleset)
{
if (beatmap.HitObjects.Any())
{ {
minPosition = beatmap.HitObjects.Min(getUsablePosition); minPosition = beatmap.HitObjects.Min(getUsablePosition);
maxPosition = beatmap.HitObjects.Max(getUsablePosition); maxPosition = beatmap.HitObjects.Max(getUsablePosition);
} }
}
public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasXPosition && h is IHasYPosition); public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasXPosition && h is IHasYPosition);

View File

@ -17,7 +17,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Pippidon.Objects.Drawables namespace osu.Game.Rulesets.Pippidon.Objects.Drawables
{ {
public class DrawablePippidonHitObject : DrawableHitObject<PippidonHitObject> public partial class DrawablePippidonHitObject : DrawableHitObject<PippidonHitObject>
{ {
private BindableNumber<int> currentLane; private BindableNumber<int> currentLane;

View File

@ -7,7 +7,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Pippidon namespace osu.Game.Rulesets.Pippidon
{ {
public class PippidonInputManager : RulesetInputManager<PippidonAction> public partial class PippidonInputManager : RulesetInputManager<PippidonAction>
{ {
public PippidonInputManager(RulesetInfo ruleset) public PippidonInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique) : base(ruleset, 0, SimultaneousBindingMode.Unique)

View File

@ -4,8 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty;
@ -47,10 +45,9 @@ namespace osu.Game.Rulesets.Pippidon
new KeyBinding(InputKey.S, PippidonAction.MoveDown), new KeyBinding(InputKey.S, PippidonAction.MoveDown),
}; };
public override Drawable CreateIcon() => new Sprite public override Drawable CreateIcon() => new PippidonRulesetIcon(this);
{
Margin = new MarginPadding { Top = 3 }, // Leave this line intact. It will bake the correct version into the ruleset on each build/release.
Texture = new TextureStore(new TextureLoaderStore(CreateResourceStore()), false).Get("Textures/coin"), public override string RulesetAPIVersionSupported => CURRENT_RULESET_API_VERSION;
};
} }
} }

View 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.Framework.Graphics;
using osu.Framework.Graphics.Rendering;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
namespace osu.Game.Rulesets.Pippidon
{
public partial class PippidonRulesetIcon : Sprite
{
private readonly Ruleset ruleset;
public PippidonRulesetIcon(Ruleset ruleset)
{
this.ruleset = ruleset;
Margin = new MarginPadding { Top = 3 };
}
[BackgroundDependencyLoader]
private void load(IRenderer renderer)
{
Texture = new TextureStore(renderer, new TextureLoaderStore(ruleset.CreateResourceStore()), false).Get("Textures/coin");
}
}
}

View File

@ -18,7 +18,7 @@ using osu.Game.Rulesets.UI.Scrolling;
namespace osu.Game.Rulesets.Pippidon.UI namespace osu.Game.Rulesets.Pippidon.UI
{ {
[Cached] [Cached]
public class DrawablePippidonRuleset : DrawableScrollingRuleset<PippidonHitObject> public partial class DrawablePippidonRuleset : DrawableScrollingRuleset<PippidonHitObject>
{ {
public DrawablePippidonRuleset(PippidonRuleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null) public DrawablePippidonRuleset(PippidonRuleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
: base(ruleset, beatmap, mods) : base(ruleset, beatmap, mods)

View File

@ -15,7 +15,7 @@ using osuTK;
namespace osu.Game.Rulesets.Pippidon.UI namespace osu.Game.Rulesets.Pippidon.UI
{ {
public class PippidonCharacter : BeatSyncedContainer, IKeyBindingHandler<PippidonAction> public partial class PippidonCharacter : BeatSyncedContainer, IKeyBindingHandler<PippidonAction>
{ {
public readonly BindableInt LanePosition = new BindableInt public readonly BindableInt LanePosition = new BindableInt
{ {

View File

@ -16,7 +16,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Pippidon.UI namespace osu.Game.Rulesets.Pippidon.UI
{ {
[Cached] [Cached]
public class PippidonPlayfield : ScrollingPlayfield public partial class PippidonPlayfield : ScrollingPlayfield
{ {
public const float LANE_HEIGHT = 70; public const float LANE_HEIGHT = 70;
@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Pippidon.UI
}); });
} }
private class LaneContainer : BeatSyncedContainer private partial class LaneContainer : BeatSyncedContainer
{ {
private OsuColour colours; private OsuColour colours;
private FillFlowContainer fill; private FillFlowContainer fill;
@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Pippidon.UI
} }
} }
private class Lane : CompositeDrawable private partial class Lane : CompositeDrawable
{ {
public Lane() public Lane()
{ {

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<AssemblyTitle>osu.Game.Rulesets.Pippidon</AssemblyTitle> <AssemblyTitle>osu.Game.Rulesets.Pippidon</AssemblyTitle>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>

17
UseLocalFramework.ps1 Normal file
View File

@ -0,0 +1,17 @@
# Run this script to use a local copy of osu-framework rather than fetching it from nuget.
# It expects the osu-framework directory to be at the same level as the osu directory
#
# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects
$CSPROJ="osu.Game/osu.Game.csproj"
$SLN="osu.sln"
dotnet remove $CSPROJ package ppy.osu.Framework;
dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj;
dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj
$SLNF=Get-Content "osu.Desktop.slnf" | ConvertFrom-Json
$TMP=New-TemporaryFile
$SLNF.solution.projects += ("../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj")
ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8
Move-Item -Path $TMP -Destination "osu.Desktop.slnf" -Force

18
UseLocalFramework.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/sh
# Run this script to use a local copy of osu-framework rather than fetching it from nuget.
# It expects the osu-framework directory to be at the same level as the osu directory
#
# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects
CSPROJ="osu.Game/osu.Game.csproj"
SLN="osu.sln"
dotnet remove $CSPROJ package ppy.osu.Framework
dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj
dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj
SLNF="osu.Desktop.slnf"
tmp=$(mktemp)
jq '.solution.projects += ["../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj"]' osu.Desktop.slnf > $tmp
mv -f $tmp $SLNF

12
UseLocalResources.ps1 Normal file
View File

@ -0,0 +1,12 @@
$CSPROJ="osu.Game/osu.Game.csproj"
$SLN="osu.sln"
dotnet remove $CSPROJ package ppy.osu.Game.Resources;
dotnet sln $SLN add ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj
dotnet add $CSPROJ reference ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj
$SLNF=Get-Content "osu.Desktop.slnf" | ConvertFrom-Json
$TMP=New-TemporaryFile
$SLNF.solution.projects += ("../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj")
ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8
Move-Item -Path $TMP -Destination "osu.Desktop.slnf" -Force

11
UseLocalResources.sh Executable file
View File

@ -0,0 +1,11 @@
CSPROJ="osu.Game/osu.Game.csproj"
SLN="osu.sln"
dotnet remove $CSPROJ package ppy.osu.Game.Resources;
dotnet sln $SLN add ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj
dotnet add $CSPROJ reference ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj
SLNF="osu.Desktop.slnf"
TMP=$(mktemp)
jq '.solution.projects += ["../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj"]' $SLNF > $TMP
mv -f $TMP $SLNF

View File

@ -1,6 +1,6 @@
clone_depth: 1 clone_depth: 1
version: '{branch}-{build}' version: '{branch}-{build}'
image: Visual Studio 2019 image: Visual Studio 2022
cache: cache:
- '%LOCALAPPDATA%\NuGet\v3-cache -> appveyor.yml' - '%LOCALAPPDATA%\NuGet\v3-cache -> appveyor.yml'
@ -11,6 +11,8 @@ dotnet_csproj:
before_build: before_build:
- cmd: dotnet --info # Useful when version mismatch between CI and local - cmd: dotnet --info # Useful when version mismatch between CI and local
- cmd: dotnet workload install maui-android # Change to `dotnet workload restore` once there's no old projects
- cmd: dotnet workload install maui-ios # Change to `dotnet workload restore` once there's no old projects
- cmd: nuget restore -verbosity quiet # Only nuget.exe knows both new (.NET Core) and old (Xamarin) projects - cmd: nuget restore -verbosity quiet # Only nuget.exe knows both new (.NET Core) and old (Xamarin) projects
build: build:

View File

@ -138,10 +138,10 @@ platform :ios do
end end
lane :testflight_prune_dry do lane :testflight_prune_dry do
clean_testflight_testers(days_of_inactivity:45, dry_run: true) clean_testflight_testers(days_of_inactivity:30, dry_run: true)
end end
lane :testflight_prune do lane :testflight_prune do
clean_testflight_testers(days_of_inactivity: 45) clean_testflight_testers(days_of_inactivity: 30)
end end
end end

View File

@ -1,61 +1,20 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<LangVersion>8.0</LangVersion> <SupportedOSPlatformVersion>21.0</SupportedOSPlatformVersion>
<OutputPath>bin\$(Configuration)</OutputPath> <RuntimeIdentifiers>android-x86;android-arm;android-arm64</RuntimeIdentifiers>
<WarningLevel>4</WarningLevel> <AndroidPackageFormat>apk</AndroidPackageFormat>
<SchemaVersion>2.0</SchemaVersion> <MandroidI18n>CJK;Mideast;Rare;West;Other;</MandroidI18n>
<BundleAssemblies>false</BundleAssemblies> <AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidMessageHandler</AndroidHttpClientHandlerType>
<AotAssemblies>false</AotAssemblies> <!-- NullabilityInfoContextSupport is disabled by default for Android -->
<OutputType>Library</OutputType> <NullabilityInfoContextSupport>true</NullabilityInfoContextSupport>
<FileAlignment>512</FileAlignment>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AndroidApplication>True</AndroidApplication>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
<MandroidI18n>cjk,mideast,other,rare,west</MandroidI18n>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<DebugSymbols>True</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>False</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AndroidManagedSymbols>false</AndroidManagedSymbols>
<AndroidUseSharedRuntime>true</AndroidUseSharedRuntime>
<EmbedAssembliesIntoApk>false</EmbedAssembliesIntoApk>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<DebugSymbols>false</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<AndroidManagedSymbols>false</AndroidManagedSymbols>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk> <EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\osu.licenseheader"> <PackageReference Include="ppy.osu.Framework.Android" Version="2022.1219.0" />
<Link>osu.licenseheader</Link>
</None>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Mono.Android" />
<Reference Include="Java.Interop" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.722.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.730.0" />
</ItemGroup>
<ItemGroup Label="Transitive Dependencies">
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
<PackageReference Include="Realm" Version="10.14.0" />
</ItemGroup> </ItemGroup>
<PropertyGroup>
<!-- Fody does not handle Android build well, and warns when unchanged.
Since Realm objects are not declared directly in Android projects, simply disable Fody. -->
<DisableFody>true</DisableFody>
</PropertyGroup>
</Project> </Project>

View File

@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings;
namespace osu.Android namespace osu.Android
{ {
public class AndroidJoystickSettings : SettingsSubsection public partial class AndroidJoystickSettings : SettingsSubsection
{ {
protected override LocalisableString Header => JoystickSettingsStrings.JoystickGamepad; protected override LocalisableString Header => JoystickSettingsStrings.JoystickGamepad;

View File

@ -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" android:versionCode="1" package="sh.ppy.osulazer" android:installLocation="auto" android:versionName="0.1.0"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" package="sh.ppy.osulazer" android:installLocation="auto" android:versionName="0.1.0">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29" /> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!" android:icon="@drawable/lazer" /> <application android:allowBackup="true" android:supportsRtl="true" android:label="osu!" android:icon="@drawable/lazer" />
</manifest> </manifest>

View File

@ -14,7 +14,7 @@ using osu.Game.Overlays.Settings.Sections.Input;
namespace osu.Android namespace osu.Android
{ {
public class AndroidMouseSettings : SettingsSubsection public partial class AndroidMouseSettings : SettingsSubsection
{ {
private readonly AndroidMouseHandler mouseHandler; private readonly AndroidMouseHandler mouseHandler;

View File

@ -11,7 +11,7 @@ using osu.Game;
namespace osu.Android namespace osu.Android
{ {
public class GameplayScreenRotationLocker : Component public partial class GameplayScreenRotationLocker : Component
{ {
private Bindable<bool> localUserPlaying; private Bindable<bool> localUserPlaying;

View File

@ -7,6 +7,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Android.App; using Android.App;
using Android.Content; using Android.Content;
@ -74,11 +75,23 @@ namespace osu.Android
Debug.Assert(Resources?.DisplayMetrics != null); Debug.Assert(Resources?.DisplayMetrics != null);
Point displaySize = new Point(); Point displaySize = new Point();
#pragma warning disable 618 // GetSize is deprecated
WindowManager.DefaultDisplay.GetSize(displaySize); WindowManager.DefaultDisplay.GetSize(displaySize);
#pragma warning restore 618
float smallestWidthDp = Math.Min(displaySize.X, displaySize.Y) / Resources.DisplayMetrics.Density; float smallestWidthDp = Math.Min(displaySize.X, displaySize.Y) / Resources.DisplayMetrics.Density;
bool isTablet = smallestWidthDp >= 600f; bool isTablet = smallestWidthDp >= 600f;
RequestedOrientation = DefaultOrientation = isTablet ? ScreenOrientation.FullUser : ScreenOrientation.SensorLandscape; RequestedOrientation = DefaultOrientation = isTablet ? ScreenOrientation.FullUser : ScreenOrientation.SensorLandscape;
// Currently (SDK 6.0.200), BundleAssemblies is not runnable for net6-android.
// The assembly files are not available as files either after native AOT.
// Manually load them so that they can be loaded by RulesetStore.loadFromAppDomain.
// REMEMBER to fully uninstall previous version every time when investigating this!
// Don't forget osu.Game.Tests.Android too.
Assembly.Load("osu.Game.Rulesets.Osu");
Assembly.Load("osu.Game.Rulesets.Taiko");
Assembly.Load("osu.Game.Rulesets.Catch");
Assembly.Load("osu.Game.Rulesets.Mania");
} }
protected override void OnNewIntent(Intent intent) => handleIntent(intent); protected override void OnNewIntent(Intent intent) => handleIntent(intent);
@ -127,7 +140,7 @@ namespace osu.Android
cursor.MoveToFirst(); cursor.MoveToFirst();
int filenameColumn = cursor.GetColumnIndex(OpenableColumns.DisplayName); int filenameColumn = cursor.GetColumnIndex(IOpenableColumns.DisplayName);
string filename = cursor.GetString(filenameColumn); string filename = cursor.GetString(filenameColumn);
// SharpCompress requires archive streams to be seekable, which the stream opened by // SharpCompress requires archive streams to be seekable, which the stream opened by

View File

@ -5,7 +5,7 @@
using System; using System;
using Android.App; using Android.App;
using Android.OS; using Microsoft.Maui.Devices;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Android.Input; using osu.Framework.Android.Input;
using osu.Framework.Input.Handlers; using osu.Framework.Input.Handlers;
@ -14,11 +14,10 @@ using osu.Game;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
using osu.Game.Updater; using osu.Game.Updater;
using osu.Game.Utils; using osu.Game.Utils;
using Xamarin.Essentials;
namespace osu.Android namespace osu.Android
{ {
public class OsuGameAndroid : OsuGame public partial class OsuGameAndroid : OsuGame
{ {
[Cached] [Cached]
private readonly OsuGameActivity gameActivity; private readonly OsuGameActivity gameActivity;
@ -48,7 +47,7 @@ namespace osu.Android
// https://stackoverflow.com/questions/52977079/android-sdk-28-versioncode-in-packageinfo-has-been-deprecated // https://stackoverflow.com/questions/52977079/android-sdk-28-versioncode-in-packageinfo-has-been-deprecated
string versionName = string.Empty; string versionName = string.Empty;
if (Build.VERSION.SdkInt >= BuildVersionCodes.P) if (OperatingSystem.IsAndroidVersionAtLeast(28))
{ {
versionName = packageInfo.LongVersionCode.ToString(); versionName = packageInfo.LongVersionCode.ToString();
// ensure we only read the trailing portion of long (the part we are interested in). // ensure we only read the trailing portion of long (the part we are interested in).

View File

@ -1,73 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\osu.Android.props" /> <Import Project="..\osu.Android.props" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFramework>net6.0-android</TargetFramework>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <OutputType>Exe</OutputType>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{D1D5F9A8-B40B-40E6-B02F-482D03346D3D}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TemplateGuid>{122416d6-6b49-4ee2-a1e8-b825f31c79fe}</TemplateGuid>
<RootNamespace>osu.Android</RootNamespace> <RootNamespace>osu.Android</RootNamespace>
<AssemblyName>osu.Android</AssemblyName> <AssemblyName>osu.Android</AssemblyName>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest> <UseMauiEssentials>true</UseMauiEssentials>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis> <!-- This currently causes random lockups during gameplay. https://github.com/mono/mono/issues/18973 -->
<EnableLLVM>false</EnableLLVM> <!-- This currently causes random lockups during gameplay. https://github.com/mono/mono/issues/18973 --> <EnableLLVM>false</EnableLLVM>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<MandroidI18n>cjk;mideast;other;rare;west</MandroidI18n>
<AndroidDexTool>d8</AndroidDexTool>
<AndroidLinkTool>r8</AndroidLinkTool>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AndroidLinkMode>None</AndroidLinkMode>
<MandroidI18n>cjk;mideast;other;rare;west</MandroidI18n>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AndroidJoystickSettings.cs" /> <ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
<Compile Include="AndroidMouseSettings.cs" /> <ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
<Compile Include="GameplayScreenRotationLocker.cs" /> <ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
<Compile Include="OsuGameActivity.cs" /> <ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
<Compile Include="OsuGameAndroid.cs" /> <ProjectReference Include="..\osu.Game\osu.Game.csproj" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj">
<Project>{58f6c80c-1253-4a0e-a465-b8c85ebeadf3}</Project>
<Name>osu.Game.Rulesets.Catch</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj">
<Project>{48f4582b-7687-4621-9cbe-5c24197cb536}</Project>
<Name>osu.Game.Rulesets.Mania</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj">
<Project>{c92a607b-1fdd-4954-9f92-03ff547d9080}</Project>
<Name>osu.Game.Rulesets.Osu</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj">
<Project>{f167e17a-7de6-4af5-b920-a5112296c695}</Project>
<Name>osu.Game.Rulesets.Taiko</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{2a66dd92-adb1-4994-89e2-c94e04acda0d}</Project>
<Name>osu.Game</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\lazer.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Formats.Asn1">
<Version>5.0.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Essentials" Version="1.7.0" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project> </Project>

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
using System; using System;
using System.Text; using System.Text;
using DiscordRPC; using DiscordRPC;
@ -22,19 +20,19 @@ using LogLevel = osu.Framework.Logging.LogLevel;
namespace osu.Desktop namespace osu.Desktop
{ {
internal class DiscordRichPresence : Component internal partial class DiscordRichPresence : Component
{ {
private const string client_id = "367827983903490050"; private const string client_id = "367827983903490050";
private DiscordRpcClient client; private DiscordRpcClient client = null!;
[Resolved] [Resolved]
private IBindable<RulesetInfo> ruleset { get; set; } private IBindable<RulesetInfo> ruleset { get; set; } = null!;
private IBindable<APIUser> user; private IBindable<APIUser> user = null!;
[Resolved] [Resolved]
private IAPIProvider api { get; set; } private IAPIProvider api { get; set; } = null!;
private readonly IBindable<UserStatus> status = new Bindable<UserStatus>(); private readonly IBindable<UserStatus> status = new Bindable<UserStatus>();
private readonly IBindable<UserActivity> activity = new Bindable<UserActivity>(); private readonly IBindable<UserActivity> activity = new Bindable<UserActivity>();
@ -130,7 +128,7 @@ namespace osu.Desktop
presence.Assets.LargeImageText = string.Empty; presence.Assets.LargeImageText = string.Empty;
else else
{ {
if (user.Value.RulesetsStatistics != null && user.Value.RulesetsStatistics.TryGetValue(ruleset.Value.ShortName, out UserStatistics statistics)) if (user.Value.RulesetsStatistics != null && user.Value.RulesetsStatistics.TryGetValue(ruleset.Value.ShortName, out UserStatistics? statistics))
presence.Assets.LargeImageText = $"{user.Value.Username}" + (statistics.GlobalRank > 0 ? $" (rank #{statistics.GlobalRank:N0})" : string.Empty); presence.Assets.LargeImageText = $"{user.Value.Username}" + (statistics.GlobalRank > 0 ? $" (rank #{statistics.GlobalRank:N0})" : string.Empty);
else else
presence.Assets.LargeImageText = $"{user.Value.Username}" + (user.Value.Statistics?.GlobalRank > 0 ? $" (rank #{user.Value.Statistics.GlobalRank:N0})" : string.Empty); presence.Assets.LargeImageText = $"{user.Value.Username}" + (user.Value.Statistics?.GlobalRank > 0 ? $" (rank #{user.Value.Statistics.GlobalRank:N0})" : string.Empty);
@ -164,7 +162,7 @@ namespace osu.Desktop
}); });
} }
private IBeatmapInfo getBeatmap(UserActivity activity) private IBeatmapInfo? getBeatmap(UserActivity activity)
{ {
switch (activity) switch (activity)
{ {
@ -183,10 +181,10 @@ namespace osu.Desktop
switch (activity) switch (activity)
{ {
case UserActivity.InGame game: case UserActivity.InGame game:
return game.BeatmapInfo.ToString(); return game.BeatmapInfo.ToString() ?? string.Empty;
case UserActivity.Editing edit: case UserActivity.Editing edit:
return edit.BeatmapInfo.ToString(); return edit.BeatmapInfo.ToString() ?? string.Empty;
case UserActivity.InLobby lobby: case UserActivity.InLobby lobby:
return privacyMode.Value == DiscordRichPresenceMode.Limited ? string.Empty : lobby.Room.Name.Value; return privacyMode.Value == DiscordRichPresenceMode.Limited ? string.Empty : lobby.Room.Name.Value;

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
namespace osu.Desktop.LegacyIpc namespace osu.Desktop.LegacyIpc
{ {
/// <summary> /// <summary>
@ -13,7 +11,7 @@ namespace osu.Desktop.LegacyIpc
/// </remarks> /// </remarks>
public class LegacyIpcDifficultyCalculationRequest public class LegacyIpcDifficultyCalculationRequest
{ {
public string BeatmapFile { get; set; } public string BeatmapFile { get; set; } = string.Empty;
public int RulesetId { get; set; } public int RulesetId { get; set; }
public int Mods { get; set; } public int Mods { get; set; }
} }

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
namespace osu.Desktop.LegacyIpc namespace osu.Desktop.LegacyIpc
{ {
/// <summary> /// <summary>

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
using osu.Framework.Platform; using osu.Framework.Platform;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -39,17 +37,20 @@ namespace osu.Desktop.LegacyIpc
public new object Value public new object Value
{ {
get => base.Value; get => base.Value;
set => base.Value = new Data set => base.Value = new Data(value.GetType().Name, value);
{
MessageType = value.GetType().Name,
MessageData = value
};
} }
public class Data public class Data
{ {
public string MessageType { get; set; } public string MessageType { get; }
public object MessageData { get; set; }
public object MessageData { get; }
public Data(string messageType, object messageData)
{
MessageType = messageType;
MessageData = messageData;
}
} }
} }
} }

View File

@ -18,23 +18,15 @@ using osu.Framework;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Game.Updater; using osu.Game.Updater;
using osu.Desktop.Windows; using osu.Desktop.Windows;
using osu.Framework.Input.Handlers;
using osu.Framework.Input.Handlers.Joystick;
using osu.Framework.Input.Handlers.Mouse;
using osu.Framework.Input.Handlers.Tablet;
using osu.Framework.Input.Handlers.Touch;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.IO; using osu.Game.IO;
using osu.Game.IPC; using osu.Game.IPC;
using osu.Game.Overlays.Settings;
using osu.Game.Overlays.Settings.Sections;
using osu.Game.Overlays.Settings.Sections.Input;
using osu.Game.Utils; using osu.Game.Utils;
using SDL2; using SDL2;
namespace osu.Desktop namespace osu.Desktop
{ {
internal class OsuGameDesktop : OsuGame internal partial class OsuGameDesktop : OsuGame
{ {
private OsuSchemeLinkIPCChannel? osuSchemeLinkIPCChannel; private OsuSchemeLinkIPCChannel? osuSchemeLinkIPCChannel;
@ -137,37 +129,17 @@ namespace osu.Desktop
{ {
base.SetHost(host); base.SetHost(host);
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
var desktopWindow = (SDL2DesktopWindow)host.Window; var desktopWindow = (SDL2DesktopWindow)host.Window;
desktopWindow.CursorState |= CursorState.Hidden; var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
if (iconStream != null)
desktopWindow.SetIconFromStream(iconStream); desktopWindow.SetIconFromStream(iconStream);
desktopWindow.CursorState |= CursorState.Hidden;
desktopWindow.Title = Name; desktopWindow.Title = Name;
desktopWindow.DragDrop += f => fileDrop(new[] { f }); desktopWindow.DragDrop += f => fileDrop(new[] { f });
} }
public override SettingsSubsection CreateSettingsSubsectionFor(InputHandler handler)
{
switch (handler)
{
case ITabletHandler th:
return new TabletSettings(th);
case MouseHandler mh:
return new MouseSettings(mh);
case JoystickHandler jh:
return new JoystickSettings(jh);
case TouchHandler th:
return new InputSection.HandlerSection(th);
default:
return base.CreateSettingsSubsectionFor(handler);
}
}
protected override BatteryInfo CreateBatteryInfo() => new SDL2BatteryInfo(); protected override BatteryInfo CreateBatteryInfo() => new SDL2BatteryInfo();
private readonly List<string> importableFiles = new List<string>(); private readonly List<string> importableFiles = new List<string>();

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
using System; using System;
using System.IO; using System.IO;
using System.Runtime.Versioning; using System.Runtime.Versioning;
@ -21,9 +19,13 @@ namespace osu.Desktop
{ {
public static class Program public static class Program
{ {
#if DEBUG
private const string base_game_name = @"osu-development";
#else
private const string base_game_name = @"osu"; private const string base_game_name = @"osu";
#endif
private static LegacyTcpIpcProvider legacyIpc; private static LegacyTcpIpcProvider? legacyIpc;
[STAThread] [STAThread]
public static void Main(string[] args) public static void Main(string[] args)

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
using System; using System;
using System.Security.Principal; using System.Security.Principal;
using osu.Framework; using osu.Framework;
@ -18,10 +16,10 @@ namespace osu.Desktop.Security
/// <summary> /// <summary>
/// Checks if the game is running with elevated privileges (as admin in Windows, root in Unix) and displays a warning notification if so. /// Checks if the game is running with elevated privileges (as admin in Windows, root in Unix) and displays a warning notification if so.
/// </summary> /// </summary>
public class ElevatedPrivilegesChecker : Component public partial class ElevatedPrivilegesChecker : Component
{ {
[Resolved] [Resolved]
private INotificationOverlay notifications { get; set; } private INotificationOverlay notifications { get; set; } = null!;
private bool elevated; private bool elevated;
@ -65,7 +63,7 @@ namespace osu.Desktop.Security
return false; return false;
} }
private class ElevatedPrivilegesNotification : SimpleNotification private partial class ElevatedPrivilegesNotification : SimpleNotification
{ {
public override bool IsImportant => true; public override bool IsImportant => true;
@ -78,7 +76,7 @@ namespace osu.Desktop.Security
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
Icon = FontAwesome.Solid.ShieldAlt; Icon = FontAwesome.Solid.ShieldAlt;
IconBackground.Colour = colours.YellowDark; IconContent.Colour = colours.YellowDark;
} }
} }
} }

View File

@ -1,35 +1,28 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
using System; using System;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Game; using osu.Game;
using osu.Game.Graphics;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
using osuTK;
using osuTK.Graphics;
using Squirrel; using Squirrel;
using Squirrel.SimpleSplat; using Squirrel.SimpleSplat;
using LogLevel = Squirrel.SimpleSplat.LogLevel;
using UpdateManager = osu.Game.Updater.UpdateManager;
namespace osu.Desktop.Updater namespace osu.Desktop.Updater
{ {
[SupportedOSPlatform("windows")] [SupportedOSPlatform("windows")]
public class SquirrelUpdateManager : osu.Game.Updater.UpdateManager public partial class SquirrelUpdateManager : UpdateManager
{ {
private UpdateManager updateManager; private Squirrel.UpdateManager? updateManager;
private INotificationOverlay notificationOverlay; private INotificationOverlay notificationOverlay = null!;
public Task PrepareUpdateAsync() => UpdateManager.RestartAppWhenExited(); public Task PrepareUpdateAsync() => Squirrel.UpdateManager.RestartAppWhenExited();
private static readonly Logger logger = Logger.GetLogger("updater"); private static readonly Logger logger = Logger.GetLogger("updater");
@ -40,6 +33,9 @@ namespace osu.Desktop.Updater
private readonly SquirrelLogger squirrelLogger = new SquirrelLogger(); private readonly SquirrelLogger squirrelLogger = new SquirrelLogger();
[Resolved]
private OsuGameBase game { get; set; } = null!;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(INotificationOverlay notifications) private void load(INotificationOverlay notifications)
{ {
@ -50,12 +46,12 @@ namespace osu.Desktop.Updater
protected override async Task<bool> PerformUpdateCheck() => await checkForUpdateAsync().ConfigureAwait(false); protected override async Task<bool> PerformUpdateCheck() => await checkForUpdateAsync().ConfigureAwait(false);
private async Task<bool> checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null) private async Task<bool> checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification? notification = null)
{ {
// should we schedule a retry on completion of this check? // should we schedule a retry on completion of this check?
bool scheduleRecheck = true; bool scheduleRecheck = true;
const string github_token = null; // TODO: populate. const string? github_token = null; // TODO: populate.
try try
{ {
@ -68,7 +64,14 @@ namespace osu.Desktop.Updater
if (updatePending) if (updatePending)
{ {
// the user may have dismissed the completion notice, so show it again. // the user may have dismissed the completion notice, so show it again.
notificationOverlay.Post(new UpdateCompleteNotification(this)); notificationOverlay.Post(new UpdateApplicationCompleteNotification
{
Activated = () =>
{
restartToApplyUpdate();
return true;
},
});
return true; return true;
} }
@ -80,19 +83,21 @@ namespace osu.Desktop.Updater
if (notification == null) if (notification == null)
{ {
notification = new UpdateProgressNotification(this) { State = ProgressNotificationState.Active }; notification = new UpdateProgressNotification
{
CompletionClickAction = restartToApplyUpdate,
};
Schedule(() => notificationOverlay.Post(notification)); Schedule(() => notificationOverlay.Post(notification));
} }
notification.Progress = 0; notification.StartDownload();
notification.Text = @"Downloading update...";
try try
{ {
await updateManager.DownloadReleases(info.ReleasesToApply, p => notification.Progress = p / 100f).ConfigureAwait(false); await updateManager.DownloadReleases(info.ReleasesToApply, p => notification.Progress = p / 100f).ConfigureAwait(false);
notification.Progress = 0; notification.StartInstall();
notification.Text = @"Installing update...";
await updateManager.ApplyReleases(info, p => notification.Progress = p / 100f).ConfigureAwait(false); await updateManager.ApplyReleases(info, p => notification.Progress = p / 100f).ConfigureAwait(false);
@ -112,9 +117,7 @@ namespace osu.Desktop.Updater
else else
{ {
// In the case of an error, a separate notification will be displayed. // In the case of an error, a separate notification will be displayed.
notification.State = ProgressNotificationState.Cancelled; notification.FailDownload();
notification.Close();
Logger.Error(e, @"update failed!"); Logger.Error(e, @"update failed!");
} }
} }
@ -136,84 +139,24 @@ namespace osu.Desktop.Updater
return true; return true;
} }
private bool restartToApplyUpdate()
{
PrepareUpdateAsync()
.ContinueWith(_ => Schedule(() => game.AttemptExit()));
return true;
}
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);
updateManager?.Dispose(); updateManager?.Dispose();
} }
private class UpdateCompleteNotification : ProgressCompletionNotification
{
[Resolved]
private OsuGame game { get; set; }
public UpdateCompleteNotification(SquirrelUpdateManager updateManager)
{
Text = @"Update ready to install. Click to restart!";
Activated = () =>
{
updateManager.PrepareUpdateAsync()
.ContinueWith(_ => updateManager.Schedule(() => game?.AttemptExit()));
return true;
};
}
}
private class UpdateProgressNotification : ProgressNotification
{
private readonly SquirrelUpdateManager updateManager;
public UpdateProgressNotification(SquirrelUpdateManager updateManager)
{
this.updateManager = updateManager;
}
protected override Notification CreateCompletionNotification()
{
return new UpdateCompleteNotification(updateManager);
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
IconContent.AddRange(new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientVertical(colours.YellowDark, colours.Yellow)
},
new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.Upload,
Colour = Color4.White,
Size = new Vector2(20),
}
});
}
public override void Close()
{
// cancelling updates is not currently supported by the underlying updater.
// only allow dismissing for now.
switch (State)
{
case ProgressNotificationState.Cancelled:
base.Close();
break;
}
}
}
private class SquirrelLogger : ILogger, IDisposable private class SquirrelLogger : ILogger, IDisposable
{ {
public Squirrel.SimpleSplat.LogLevel Level { get; set; } = Squirrel.SimpleSplat.LogLevel.Info; public LogLevel Level { get; set; } = LogLevel.Info;
public void Write(string message, Squirrel.SimpleSplat.LogLevel logLevel) public void Write(string message, LogLevel logLevel)
{ {
if (logLevel < Level) if (logLevel < Level)
return; return;

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -12,14 +10,14 @@ using osu.Game.Screens.Play;
namespace osu.Desktop.Windows namespace osu.Desktop.Windows
{ {
public class GameplayWinKeyBlocker : Component public partial class GameplayWinKeyBlocker : Component
{ {
private Bindable<bool> disableWinKey; private Bindable<bool> disableWinKey = null!;
private IBindable<bool> localUserPlaying; private IBindable<bool> localUserPlaying = null!;
private IBindable<bool> isActive; private IBindable<bool> isActive = null!;
[Resolved] [Resolved]
private GameHost host { get; set; } private GameHost host { get; set; } = null!;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(ILocalUserPlayInfo localUserInfo, OsuConfigManager config) private void load(ILocalUserPlayInfo localUserInfo, OsuConfigManager config)

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -21,7 +19,7 @@ namespace osu.Desktop.Windows
private const int wm_syskeyup = 261; private const int wm_syskeyup = 261;
//Resharper disable once NotAccessedField.Local //Resharper disable once NotAccessedField.Local
private static LowLevelKeyboardProcDelegate keyboardHookDelegate; // keeping a reference alive for the GC private static LowLevelKeyboardProcDelegate? keyboardHookDelegate; // keeping a reference alive for the GC
private static IntPtr keyHook; private static IntPtr keyHook;
[StructLayout(LayoutKind.Explicit)] [StructLayout(LayoutKind.Explicit)]

View File

@ -27,12 +27,7 @@
<PackageReference Include="Clowd.Squirrel" Version="2.9.42" /> <PackageReference Include="Clowd.Squirrel" Version="2.9.42" />
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" /> <PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="System.IO.Packaging" Version="6.0.0" /> <PackageReference Include="System.IO.Packaging" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.14" /> <PackageReference Include="DiscordRichPresence" Version="1.1.1.14" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.14">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="DiscordRichPresence" Version="1.0.175" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Resources"> <ItemGroup Label="Resources">
<EmbeddedResource Include="lazer.ico" /> <EmbeddedResource Include="lazer.ico" />

View File

@ -7,9 +7,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" /> <PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
<PackageReference Include="nunit" Version="3.13.3" /> <PackageReference Include="nunit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- using a different name because package name cannot contain 'catch' --> <!-- using a different name because package name cannot contain 'catch' -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Catch_Tests.Android" android:installLocation="auto"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Catch_Tests.Android" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29" /> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!catch Test" /> <application android:allowBackup="true" android:supportsRtl="true" android:label="osu!catch Test" />
</manifest> </manifest>

View File

@ -1,49 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\osu.Android.props" /> <Import Project="..\osu.Android.props" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFramework>net6.0-android</TargetFramework>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <OutputType>Exe</OutputType>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TemplateGuid>{122416d6-6b49-4ee2-a1e8-b825f31c79fe}</TemplateGuid>
<RootNamespace>osu.Game.Rulesets.Catch.Tests</RootNamespace> <RootNamespace>osu.Game.Rulesets.Catch.Tests</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Catch.Tests.Android</AssemblyName> <AssemblyName>osu.Game.Rulesets.Catch.Tests.Android</AssemblyName>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AndroidLinkMode>None</AndroidLinkMode>
<MandroidI18n>cjk;mideast;other;rare;west</MandroidI18n>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MainActivity.cs" /> <Compile Include="..\osu.Game.Rulesets.Catch.Tests\**\*.cs" Exclude="**\obj\**">
</ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\osu.Game.Rulesets.Catch.Tests\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile> </Compile>
<!-- TargetPath is relative to RootNamespace,
and DllResourceStore is relative to AssemblyName. -->
<EmbeddedResource Include="..\osu.Game.Rulesets.Catch.Tests\**\Resources\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<TargetPath>Android\%(RecursiveDir)%(Filename)%(Extension)</TargetPath>
</EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj"> <ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
<Project>{58f6c80c-1253-4a0e-a465-b8c85ebeadf3}</Project> <ProjectReference Include="..\osu.Game\osu.Game.csproj" />
<Name>osu.Game.Rulesets.Catch</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}</Project>
<Name>osu.Game</Name>
</ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="System.Formats.Asn1">
<Version>5.0.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project> </Project>

View File

@ -3,7 +3,6 @@
#nullable disable #nullable disable
using osu.Framework.iOS;
using UIKit; using UIKit;
namespace osu.Game.Rulesets.Catch.Tests.iOS namespace osu.Game.Rulesets.Catch.Tests.iOS
@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Catch.Tests.iOS
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate)); UIApplication.Main(args, null, typeof(AppDelegate));
} }
} }
} }

View File

@ -13,7 +13,7 @@
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>10.0</string> <string>13.4</string>
<key>UIDeviceFamily</key> <key>UIDeviceFamily</key>
<array> <array>
<integer>1</integer> <integer>1</integer>

View File

@ -1,35 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{4004C7B7-1A62-43F1-9DF2-52450FA67E70}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net6.0-ios</TargetFramework>
<SupportedOSPlatformVersion>13.4</SupportedOSPlatformVersion>
<RootNamespace>osu.Game.Rulesets.Catch.Tests</RootNamespace> <RootNamespace>osu.Game.Rulesets.Catch.Tests</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Catch.Tests.iOS</AssemblyName> <AssemblyName>osu.Game.Rulesets.Catch.Tests.iOS</AssemblyName>
</PropertyGroup> </PropertyGroup>
<Import Project="..\osu.iOS.props" /> <Import Project="..\osu.iOS.props" />
<ItemGroup> <ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
<LinkDescription Include="..\osu.iOS\Linker.xml">
<Link>Linker.xml</Link>
</LinkDescription>
<Compile Include="Application.cs" />
<Compile Include="AppDelegate.cs" />
<Compile Include="..\osu.Game.Rulesets.Catch.Tests\**\*.cs" Exclude="**\obj\**"> <Compile Include="..\osu.Game.Rulesets.Catch.Tests\**\*.cs" Exclude="**\obj\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<ItemGroup Label="Project References"> <ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game\osu.Game.csproj"> <ProjectReference Include="..\osu.Game\osu.Game.csproj" />
<Project>{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}</Project> <ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
<Name>osu.Game</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj">
<Project>{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}</Project>
<Name>osu.Game.Rulesets.Catch</Name>
</ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project> </Project>

View File

@ -7,7 +7,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests namespace osu.Game.Rulesets.Catch.Tests
{ {
public abstract class CatchSkinnableTestScene : SkinnableTestScene public abstract partial class CatchSkinnableTestScene : SkinnableTestScene
{ {
protected override Ruleset CreateRulesetForSkinProvider() => new CatchRuleset(); protected override Ruleset CreateRulesetForSkinProvider() => new CatchRuleset();
} }

View File

@ -16,7 +16,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests.Editor namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
public class CatchEditorTestSceneContainer : Container public partial class CatchEditorTestSceneContainer : Container
{ {
[Cached(typeof(Playfield))] [Cached(typeof(Playfield))]
public readonly ScrollingPlayfield Playfield; public readonly ScrollingPlayfield Playfield;
@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
}; };
} }
private class TestCatchPlayfield : CatchEditorPlayfield private partial class TestCatchPlayfield : CatchEditorPlayfield
{ {
public TestCatchPlayfield() public TestCatchPlayfield()
: base(new BeatmapDifficulty { CircleSize = 0 }) : base(new BeatmapDifficulty { CircleSize = 0 })

View File

@ -21,7 +21,7 @@ using osuTK.Input;
namespace osu.Game.Rulesets.Catch.Tests.Editor namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
public abstract class CatchPlacementBlueprintTestScene : PlacementBlueprintTestScene public abstract partial class CatchPlacementBlueprintTestScene : PlacementBlueprintTestScene
{ {
protected const double TIME_SNAP = 100; protected const double TIME_SNAP = 100;

View File

@ -17,7 +17,7 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests.Editor namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
public abstract class CatchSelectionBlueprintTestScene : SelectionBlueprintTestScene public abstract partial class CatchSelectionBlueprintTestScene : SelectionBlueprintTestScene
{ {
protected ScrollingHitObjectContainer HitObjectContainer => contentContainer.Playfield.HitObjectContainer; protected ScrollingHitObjectContainer HitObjectContainer => contentContainer.Playfield.HitObjectContainer;
@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
InputManager.MoveMouseTo(pos); InputManager.MoveMouseTo(pos);
}); });
private class EditorBeatmapDependencyContainer : Container private partial class EditorBeatmapDependencyContainer : Container
{ {
[Cached] [Cached]
private readonly EditorClock editorClock; private readonly EditorClock editorClock;
@ -70,10 +70,17 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
[Cached] [Cached]
private readonly BindableBeatDivisor beatDivisor; private readonly BindableBeatDivisor beatDivisor;
protected override Container<Drawable> Content { get; } = new Container { RelativeSizeAxes = Axes.Both };
public EditorBeatmapDependencyContainer(IBeatmap beatmap, BindableBeatDivisor beatDivisor) public EditorBeatmapDependencyContainer(IBeatmap beatmap, BindableBeatDivisor beatDivisor)
{ {
editorClock = new EditorClock(beatmap, beatDivisor);
this.beatDivisor = beatDivisor; this.beatDivisor = beatDivisor;
InternalChildren = new Drawable[]
{
editorClock = new EditorClock(beatmap, beatDivisor),
Content,
};
} }
} }
} }

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor.Checks
[TestFixture] [TestFixture]
public class TestCheckBananaShowerGap public class TestCheckBananaShowerGap
{ {
private CheckBananaShowerGap check; private CheckBananaShowerGap check = null!;
[SetUp] [SetUp]
public void Setup() public void Setup()

View File

@ -20,7 +20,7 @@ using osuTK.Input;
namespace osu.Game.Rulesets.Catch.Tests.Editor namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
public class TestSceneBananaShowerPlacementBlueprint : CatchPlacementBlueprintTestScene public partial class TestSceneBananaShowerPlacementBlueprint : CatchPlacementBlueprintTestScene
{ {
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableBananaShower((BananaShower)hitObject); protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableBananaShower((BananaShower)hitObject);

View File

@ -20,7 +20,7 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests.Editor namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
public class TestSceneCatchDistanceSnapGrid : OsuManualInputManagerTestScene public partial class TestSceneCatchDistanceSnapGrid : OsuManualInputManagerTestScene
{ {
private readonly ManualClock manualClock = new ManualClock(); private readonly ManualClock manualClock = new ManualClock();

View File

@ -9,7 +9,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests.Editor namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
[TestFixture] [TestFixture]
public class TestSceneEditor : EditorTestScene public partial class TestSceneEditor : EditorTestScene
{ {
protected override Ruleset CreateEditorRuleset() => new CatchRuleset(); protected override Ruleset CreateEditorRuleset() => new CatchRuleset();
} }

View File

@ -17,7 +17,7 @@ using osuTK.Input;
namespace osu.Game.Rulesets.Catch.Tests.Editor namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
public class TestSceneFruitPlacementBlueprint : CatchPlacementBlueprintTestScene public partial class TestSceneFruitPlacementBlueprint : CatchPlacementBlueprintTestScene
{ {
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableFruit((Fruit)hitObject); protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableFruit((Fruit)hitObject);

View File

@ -19,7 +19,7 @@ using osuTK.Input;
namespace osu.Game.Rulesets.Catch.Tests.Editor namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
public class TestSceneJuiceStreamPlacementBlueprint : CatchPlacementBlueprintTestScene public partial class TestSceneJuiceStreamPlacementBlueprint : CatchPlacementBlueprintTestScene
{ {
private const double velocity_factor = 0.5; private const double velocity_factor = 0.5;

View File

@ -19,7 +19,7 @@ using osuTK.Input;
namespace osu.Game.Rulesets.Catch.Tests.Editor namespace osu.Game.Rulesets.Catch.Tests.Editor
{ {
public class TestSceneJuiceStreamSelectionBlueprint : CatchSelectionBlueprintTestScene public partial class TestSceneJuiceStreamSelectionBlueprint : CatchSelectionBlueprintTestScene
{ {
private JuiceStream hitObject; private JuiceStream hitObject;

View File

@ -0,0 +1,23 @@
// 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.Game.Rulesets.Catch.Mods;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests.Mods
{
public partial class TestSceneCatchModFlashlight : ModTestScene
{
protected override Ruleset CreatePlayerRuleset() => new CatchRuleset();
[TestCase(1f)]
[TestCase(0.5f)]
[TestCase(1.25f)]
[TestCase(1.5f)]
public void TestSizeMultiplier(float sizeMultiplier) => CreateModTest(new ModTestData { Mod = new CatchModFlashlight { SizeMultiplier = { Value = sizeMultiplier } }, PassCondition = () => true });
[Test]
public void TestComboBasedSize([Values] bool comboBasedSize) => CreateModTest(new ModTestData { Mod = new CatchModFlashlight { ComboBasedSize = { Value = comboBasedSize } }, PassCondition = () => true });
}
}

View File

@ -14,7 +14,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests.Mods namespace osu.Game.Rulesets.Catch.Tests.Mods
{ {
public class TestSceneCatchModNoScope : ModTestScene public partial class TestSceneCatchModNoScope : ModTestScene
{ {
protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); protected override Ruleset CreatePlayerRuleset() => new CatchRuleset();

View File

@ -11,7 +11,7 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests.Mods namespace osu.Game.Rulesets.Catch.Tests.Mods
{ {
public class TestSceneCatchModPerfect : ModPerfectTestScene public partial class TestSceneCatchModPerfect : ModPerfectTestScene
{ {
protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); protected override Ruleset CreatePlayerRuleset() => new CatchRuleset();

View File

@ -4,8 +4,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics.Cursor;
using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Catch.Mods;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Catch.UI;
@ -16,7 +18,7 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests.Mods namespace osu.Game.Rulesets.Catch.Tests.Mods
{ {
public class TestSceneCatchModRelax : ModTestScene public partial class TestSceneCatchModRelax : ModTestScene
{ {
protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); protected override Ruleset CreatePlayerRuleset() => new CatchRuleset();
@ -55,6 +57,21 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods
} }
}); });
[Test]
public void TestGameCursorHidden()
{
CreateModTest(new ModTestData
{
Mod = new CatchModRelax(),
Autoplay = false,
PassCondition = () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<DrawableCatchRuleset>().Single());
return this.ChildrenOfType<MenuCursorContainer>().Single().State.Value == Visibility.Hidden;
}
});
}
private bool passCondition() private bool passCondition()
{ {
var playfield = this.ChildrenOfType<CatchPlayfield>().Single(); var playfield = this.ChildrenOfType<CatchPlayfield>().Single();

View File

@ -16,7 +16,7 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests namespace osu.Game.Rulesets.Catch.Tests
{ {
public class TestSceneAutoJuiceStream : TestSceneCatchPlayer public partial class TestSceneAutoJuiceStream : TestSceneCatchPlayer
{ {
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{ {

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