1
0
mirror of https://github.com/ppy/osu.git synced 2024-05-15 06:10:21 +08:00

Merge pull request #21629 from peppy/guard-url-protocols

Update framework
This commit is contained in:
Dan Balasescu 2022-12-19 21:27:44 +09:00 committed by GitHub
commit 1262c44dfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
144 changed files with 508 additions and 885 deletions

View File

@ -31,7 +31,7 @@ jobs:
run: dotnet tool restore
- name: Restore Packages
run: dotnet restore
run: dotnet restore osu.Desktop.slnf
- name: Restore inspectcode cache
uses: actions/cache@v3
@ -113,27 +113,36 @@ jobs:
with:
dotnet-version: "6.0.x"
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1
- name: Install .NET workloads
run: dotnet workload install maui-android
- name: Build
run: msbuild osu.Android/osu.Android.csproj /restore /p:Configuration=Debug
- name: Compile
run: dotnet build -c Debug osu.Android.slnf
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
steps:
- name: Checkout
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
uses: actions/setup-dotnet@v1
with:
dotnet-version: "6.0.x"
# Contrary to seemingly any other msbuild, msbuild running on macOS/Mono
# cannot accept .sln(f) files as arguments.
# Build just the main game for now.
- name: Install .NET Workloads
run: dotnet workload install maui-ios
- name: Build
run: msbuild osu.iOS/osu.iOS.csproj /restore /p:Configuration=Debug
run: dotnet build -c Debug osu.iOS

View File

@ -32,7 +32,7 @@ If you are looking to install or test osu! without setting up a development envi
**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.

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
clone_depth: 1
version: '{branch}-{build}'
image: Visual Studio 2019
image: Visual Studio 2022
cache:
- '%LOCALAPPDATA%\NuGet\v3-cache -> appveyor.yml'
@ -11,6 +11,8 @@ dotnet_csproj:
before_build:
- 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
build:

6
global.json Normal file
View File

@ -0,0 +1,6 @@
{
"sdk": {
"version": "6.0.300",
"rollForward": "major"
}
}

View File

@ -1,58 +1,16 @@
<Project>
<PropertyGroup>
<LangVersion>8.0</LangVersion>
<OutputPath>bin\$(Configuration)</OutputPath>
<WarningLevel>4</WarningLevel>
<SchemaVersion>2.0</SchemaVersion>
<BundleAssemblies>false</BundleAssemblies>
<AotAssemblies>false</AotAssemblies>
<OutputType>Library</OutputType>
<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>
<SupportedOSPlatformVersion>21.0</SupportedOSPlatformVersion>
<RuntimeIdentifiers>android-x86;android-arm;android-arm64</RuntimeIdentifiers>
<AndroidPackageFormat>apk</AndroidPackageFormat>
<MandroidI18n>CJK;Mideast;Rare;West;Other;</MandroidI18n>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidMessageHandler</AndroidHttpClientHandlerType>
<!-- NullabilityInfoContextSupport is disabled by default for Android -->
<NullabilityInfoContextSupport>true</NullabilityInfoContextSupport>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\osu.licenseheader">
<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.1207.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.1208.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.1216.1" />
</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. -->
@ -61,4 +19,9 @@
<ItemGroup>
<LinkDescription Include="$(MSBuildThisFileDirectory)\osu.Android\Linker.xml"/>
</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>

View File

@ -1,5 +1,5 @@
<?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">
<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" />
</manifest>

View File

@ -7,6 +7,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
@ -74,11 +75,23 @@ namespace osu.Android
Debug.Assert(Resources?.DisplayMetrics != null);
Point displaySize = new Point();
#pragma warning disable 618 // GetSize is deprecated
WindowManager.DefaultDisplay.GetSize(displaySize);
#pragma warning restore 618
float smallestWidthDp = Math.Min(displaySize.X, displaySize.Y) / Resources.DisplayMetrics.Density;
bool isTablet = smallestWidthDp >= 600f;
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);
@ -127,7 +140,7 @@ namespace osu.Android
cursor.MoveToFirst();
int filenameColumn = cursor.GetColumnIndex(OpenableColumns.DisplayName);
int filenameColumn = cursor.GetColumnIndex(IOpenableColumns.DisplayName);
string filename = cursor.GetString(filenameColumn);
// SharpCompress requires archive streams to be seekable, which the stream opened by

View File

@ -5,7 +5,7 @@
using System;
using Android.App;
using Android.OS;
using Microsoft.Maui.Devices;
using osu.Framework.Allocation;
using osu.Framework.Android.Input;
using osu.Framework.Input.Handlers;
@ -14,7 +14,6 @@ using osu.Game;
using osu.Game.Overlays.Settings;
using osu.Game.Updater;
using osu.Game.Utils;
using Xamarin.Essentials;
namespace osu.Android
{
@ -48,7 +47,7 @@ namespace osu.Android
// https://stackoverflow.com/questions/52977079/android-sdk-28-versioncode-in-packageinfo-has-been-deprecated
string versionName = string.Empty;
if (Build.VERSION.SdkInt >= BuildVersionCodes.P)
if (OperatingSystem.IsAndroidVersionAtLeast(28))
{
versionName = packageInfo.LongVersionCode.ToString();
// 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 ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\osu.Android.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<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>
<TargetFramework>net6.0-android</TargetFramework>
<OutputType>Exe</OutputType>
<RootNamespace>osu.Android</RootNamespace>
<AssemblyName>osu.Android</AssemblyName>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
<EnableLLVM>false</EnableLLVM> <!-- This currently causes random lockups during gameplay. https://github.com/mono/mono/issues/18973 -->
</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>
<UseMauiEssentials>true</UseMauiEssentials>
<!-- This currently causes random lockups during gameplay. https://github.com/mono/mono/issues/18973 -->
<EnableLLVM>false</EnableLLVM>
</PropertyGroup>
<ItemGroup>
<Compile Include="AndroidJoystickSettings.cs" />
<Compile Include="AndroidMouseSettings.cs" />
<Compile Include="GameplayScreenRotationLocker.cs" />
<Compile Include="OsuGameActivity.cs" />
<Compile Include="OsuGameAndroid.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</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,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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">
<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" />
</manifest>

View File

@ -1,49 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\osu.Android.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<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>
<TargetFramework>net6.0-android</TargetFramework>
<OutputType>Exe</OutputType>
<RootNamespace>osu.Game.Rulesets.Catch.Tests</RootNamespace>
<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>
<ItemGroup>
<Compile Include="MainActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\osu.Game.Rulesets.Catch.Tests\*.cs">
<Compile Include="..\osu.Game.Rulesets.Catch.Tests\**\*.cs" Exclude="**\obj\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</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>
<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\osu.Game.csproj">
<Project>{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}</Project>
<Name>osu.Game</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Formats.Asn1">
<Version>5.0.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -3,7 +3,6 @@
#nullable disable
using osu.Framework.iOS;
using UIKit;
namespace osu.Game.Rulesets.Catch.Tests.iOS
@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Catch.Tests.iOS
{
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>
<true/>
<key>MinimumOSVersion</key>
<string>10.0</string>
<string>13.4</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>

View File

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

View File

@ -121,9 +121,7 @@ namespace osu.Game.Rulesets.Catch.Edit
return new SnapResult(originPosition, StartTime);
}
return enumerateSnappingCandidates(time)
.OrderBy(pos => Vector2.DistanceSquared(screenSpacePosition, pos.ScreenSpacePosition))
.FirstOrDefault();
return enumerateSnappingCandidates(time).MinBy(pos => Vector2.DistanceSquared(screenSpacePosition, pos.ScreenSpacePosition));
}
private IEnumerable<SnapResult> enumerateSnappingCandidates(double time)

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Project">
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Library</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Description>catch the fruit. to the beat.</Description>
@ -15,4 +15,4 @@
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
</Project>
</Project>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Mania.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!mania Test" />
</manifest>

View File

@ -1,49 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\osu.Android.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{531F1092-DB27-445D-AA33-2A77C7187C99}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TemplateGuid>{122416d6-6b49-4ee2-a1e8-b825f31c79fe}</TemplateGuid>
<TargetFramework>net6.0-android</TargetFramework>
<OutputType>Exe</OutputType>
<RootNamespace>osu.Game.Rulesets.Mania.Tests</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Mania.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>
<ItemGroup>
<Compile Include="MainActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\osu.Game.Rulesets.Mania.Tests\*.cs">
<Compile Include="..\osu.Game.Rulesets.Mania.Tests\**\*.cs" Exclude="**\obj\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<!-- TargetPath is relative to RootNamespace,
and DllResourceStore is relative to AssemblyName. -->
<EmbeddedResource Include="..\osu.Game.Rulesets.Mania.Tests\**\Resources\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<TargetPath>Android\%(RecursiveDir)%(Filename)%(Extension)</TargetPath>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<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\osu.Game.csproj">
<Project>{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}</Project>
<Name>osu.Game</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Formats.Asn1">
<Version>5.0.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -3,7 +3,6 @@
#nullable disable
using osu.Framework.iOS;
using UIKit;
namespace osu.Game.Rulesets.Mania.Tests.iOS
@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Mania.Tests.iOS
{
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>
<true/>
<key>MinimumOSVersion</key>
<string>10.0</string>
<string>13.4</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>

View File

@ -1,35 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{39FD990E-B6CE-4B2A-999F-BC008CF2C64C}</ProjectGuid>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-ios</TargetFramework>
<SupportedOSPlatformVersion>13.4</SupportedOSPlatformVersion>
<RootNamespace>osu.Game.Rulesets.Mania.Tests</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Mania.Tests.iOS</AssemblyName>
</PropertyGroup>
<Import Project="..\osu.iOS.props" />
<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.Mania.Tests\**\*.cs" Exclude="**\obj\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
</ItemGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}</Project>
<Name>osu.Game</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\osu.Game.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>
</Project>

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Project">
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Library</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Description>smash the keys. to the beat.</Description>
@ -15,4 +15,4 @@
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
</Project>
</Project>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Osu.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!standard Test" />
</manifest>

View File

@ -1,49 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\osu.Android.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{90CAB706-39CB-4B93-9629-3218A6FF8E9B}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TemplateGuid>{122416d6-6b49-4ee2-a1e8-b825f31c79fe}</TemplateGuid>
<TargetFramework>net6.0-android</TargetFramework>
<OutputType>Exe</OutputType>
<RootNamespace>osu.Game.Rulesets.Osu.Tests</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Osu.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>
<ItemGroup>
<Compile Include="MainActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\osu.Game.Rulesets.Osu.Tests\*.cs">
<Compile Include="..\osu.Game.Rulesets.Osu.Tests\**\*.cs" Exclude="**\obj\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<!-- TargetPath is relative to RootNamespace,
and DllResourceStore is relative to AssemblyName. -->
<EmbeddedResource Include="..\osu.Game.Rulesets.Osu.Tests\**\Resources\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<TargetPath>Android\%(RecursiveDir)%(Filename)%(Extension)</TargetPath>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<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\osu.Game.csproj">
<Project>{2a66dd92-adb1-4994-89e2-c94e04acda0d}</Project>
<Name>osu.Game</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Formats.Asn1">
<Version>5.0.0</Version>
</PackageReference>
<PackageReference Include="Moq" Version="4.17.2" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -3,7 +3,6 @@
#nullable disable
using osu.Framework.iOS;
using UIKit;
namespace osu.Game.Rulesets.Osu.Tests.iOS
@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Osu.Tests.iOS
{
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>
<true/>
<key>MinimumOSVersion</key>
<string>10.0</string>
<string>13.4</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>

View File

@ -1,35 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{6653CA6F-DB06-4604-A3FD-762E25C2AF96}</ProjectGuid>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-ios</TargetFramework>
<SupportedOSPlatformVersion>13.4</SupportedOSPlatformVersion>
<OutputType>Exe</OutputType>
<RootNamespace>osu.Game.Rulesets.Osu.Tests</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Osu.Tests.iOS</AssemblyName>
</PropertyGroup>
<Import Project="..\osu.iOS.props" />
<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.Osu.Tests\**\*.cs" Exclude="**\obj\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
</ItemGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}</Project>
<Name>osu.Game</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\osu.Game.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>
</Project>

View File

@ -133,6 +133,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(e.NewItems != null);
// If inserting in the path (not appending),
// update indices of existing connections after insert location
if (e.NewStartingIndex < Pieces.Count)
@ -164,6 +166,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
break;
case NotifyCollectionChangedAction.Remove:
Debug.Assert(e.OldItems != null);
foreach (var point in e.OldItems.Cast<PathControlPoint>())
{
foreach (var piece in Pieces.Where(p => p.ControlPoint == point).ToArray())

View File

@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Osu.Replays
private class ReplayFrameComparer : IComparer<ReplayFrame>
{
public int Compare(ReplayFrame f1, ReplayFrame f2)
public int Compare(ReplayFrame? f1, ReplayFrame? f2)
{
if (f1 == null) throw new ArgumentNullException(nameof(f1));
if (f2 == null) throw new ArgumentNullException(nameof(f2));

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Project">
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Library</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Description>click the circles. to the beat.</Description>
@ -15,4 +15,4 @@
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
</Project>
</Project>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Taiko.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!taiko Test" />
</manifest>

View File

@ -1,49 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\osu.Android.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{3701A0A1-8476-42C6-B5C4-D24129B4A484}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TemplateGuid>{122416d6-6b49-4ee2-a1e8-b825f31c79fe}</TemplateGuid>
<TargetFramework>net6.0-android</TargetFramework>
<OutputType>Exe</OutputType>
<RootNamespace>osu.Game.Rulesets.Taiko.Tests</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Taiko.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>
<ItemGroup>
<Compile Include="MainActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\osu.Game.Rulesets.Taiko.Tests\*.cs">
<Compile Include="..\osu.Game.Rulesets.Taiko.Tests\**\*.cs" Exclude="**\obj\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<!-- TargetPath is relative to RootNamespace,
and DllResourceStore is relative to AssemblyName. -->
<EmbeddedResource Include="..\osu.Game.Rulesets.Taiko.Tests\**\Resources\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<TargetPath>Android\%(RecursiveDir)%(Filename)%(Extension)</TargetPath>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<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>
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Formats.Asn1">
<Version>5.0.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -3,7 +3,6 @@
#nullable disable
using osu.Framework.iOS;
using UIKit;
namespace osu.Game.Rulesets.Taiko.Tests.iOS
@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.iOS
{
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>
<true/>
<key>MinimumOSVersion</key>
<string>10.0</string>
<string>13.4</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>

View File

@ -1,35 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{7E408809-66AC-49D1-AF4D-98834F9B979A}</ProjectGuid>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-ios</TargetFramework>
<SupportedOSPlatformVersion>13.4</SupportedOSPlatformVersion>
<RootNamespace>osu.Game.Rulesets.Taiko.Tests</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Taiko.Tests.iOS</AssemblyName>
</PropertyGroup>
<Import Project="..\osu.iOS.props" />
<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.Taiko.Tests\**\*.cs" Exclude="**\obj\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
</ItemGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}</Project>
<Name>osu.Game</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" />
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>
</Project>

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Project">
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Library</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Description>bash the drum. to the beat.</Description>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.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!visual Test" />
</manifest>

View File

@ -3,7 +3,9 @@
#nullable disable
using System.Reflection;
using Android.App;
using Android.OS;
using osu.Framework.Android;
namespace osu.Game.Tests.Android
@ -12,5 +14,16 @@ namespace osu.Game.Tests.Android
public class MainActivity : AndroidGameActivity
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// See the comment in OsuGameActivity
Assembly.Load("osu.Game.Rulesets.Osu");
Assembly.Load("osu.Game.Rulesets.Taiko");
Assembly.Load("osu.Game.Rulesets.Catch");
Assembly.Load("osu.Game.Rulesets.Mania");
}
}
}

View File

@ -1,88 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\osu.Android.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{5CC222DC-5716-4499-B897-DCBDDA4A5CF9}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TemplateGuid>{122416d6-6b49-4ee2-a1e8-b825f31c79fe}</TemplateGuid>
<TargetFramework>net6.0-android</TargetFramework>
<OutputType>Exe</OutputType>
<RootNamespace>osu.Game.Tests</RootNamespace>
<AssemblyName>osu.Game.Tests.Android</AssemblyName>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
</PropertyGroup>
<ItemGroup>
<Compile Include="MainActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<PropertyGroup>
<NoWarn>$(NoWarn);CA2007</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AndroidLinkMode>None</AndroidLinkMode>
<MandroidI18n>cjk;mideast;other;rare;west</MandroidI18n>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\osu.Game.Tests\**\Beatmaps\**\*.cs">
<Compile Include="..\osu.Game.Tests\**\*.cs" Exclude="**\obj\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<Compile Remove="..\osu.Game.Tests\Beatmaps\Formats\OsuJsonDecoderTest.cs" />
<Compile Include="..\osu.Game.Tests\**\Chat\**\*.cs">
<!-- TargetPath is relative to RootNamespace,
and DllResourceStore is relative to AssemblyName. -->
<EmbeddedResource Include="..\osu.Game.Tests\**\Resources\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<Compile Include="..\osu.Game.Tests\**\NonVisual\**\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<Compile Include="..\osu.Game.Tests\**\Scores\**\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<Compile Include="..\osu.Game.Tests\**\ScrollAlgorithms\**\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<Compile Include="..\osu.Game.Tests\**\Visual\**\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<Compile Include="..\osu.Game.Tests\**\Resources\**\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<Compile Include="..\osu.Game.Tests\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<TargetPath>Android\%(RecursiveDir)%(Filename)%(Extension)</TargetPath>
</EmbeddedResource>
</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>
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="DeepEqual" Version="2.0.0" />
<PackageReference Include="Moq" Version="4.17.2" />
<PackageReference Include="System.Formats.Asn1">
<Version>5.0.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -3,7 +3,6 @@
#nullable disable
using osu.Framework.iOS;
using UIKit;
namespace osu.Game.Tests.iOS
@ -12,7 +11,7 @@ namespace osu.Game.Tests.iOS
{
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>
<true/>
<key>MinimumOSVersion</key>
<string>10.0</string>
<string>13.4</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>

View File

@ -1,54 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<OutputType>Exe</OutputType>
<ProjectGuid>{65FF8E19-6934-469B-B690-23C6D6E56A17}</ProjectGuid>
<TargetFramework>net6.0-ios</TargetFramework>
<SupportedOSPlatformVersion>13.4</SupportedOSPlatformVersion>
<RootNamespace>osu.Game.Tests</RootNamespace>
<AssemblyName>osu.Game.Tests.iOS</AssemblyName>
</PropertyGroup>
<Import Project="..\osu.iOS.props" />
<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.Tests\**\*.cs" Exclude="**\obj\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
</ItemGroup>
<PropertyGroup>
<NoWarn>$(NoWarn);CA2007</NoWarn>
</PropertyGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}</Project>
<Name>osu.Game</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.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.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" />
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="DeepEqual" Version="2.0.0" />
<PackageReference Include="Moq" Version="4.17.2" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>

View File

@ -26,6 +26,16 @@ namespace osu.Game.Tests.Chat
MessageFormatter.WebsiteRootUrl = originalWebsiteRootUrl;
}
[Test]
public void TestUnsupportedProtocolLink()
{
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a gopher://really-old-protocol we don't support." });
Assert.AreEqual(result.Content, result.DisplayContent);
Assert.AreEqual(1, result.Links.Count);
Assert.AreEqual("gopher://really-old-protocol", result.Links[0].Url);
}
[Test]
public void TestBareLink()
{

View File

@ -189,7 +189,7 @@ namespace osu.Game.Tests.Visual.Online
if (request is not CommentDeleteRequest req)
return false;
req.TriggerFailure(new Exception());
req.TriggerFailure(new InvalidOperationException());
delete = true;
return false;
};

View File

@ -136,7 +136,7 @@ namespace osu.Game.Tests.Visual.SongSelect
if (testRequest.Progress >= 0.5f)
{
testRequest.TriggerFailure(new Exception());
testRequest.TriggerFailure(new InvalidOperationException());
return true;
}
}

View File

@ -245,8 +245,10 @@ namespace osu.Game.Tournament.IPC
{
string stableInstallPath;
#pragma warning disable CA1416
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu"))
stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty)?.ToString()?.Split('"')[1].Replace("osu!.exe", "");
#pragma warning restore CA1416
if (ipcFileExistsInDirectory(stableInstallPath))
return stableInstallPath;

View File

@ -70,7 +70,7 @@ namespace osu.Game.Tournament
private async Task checkForChanges()
{
string serialisedLadder = await Task.Run(() => tournamentGame.GetSerialisedLadder());
string serialisedLadder = await Task.Run(() => tournamentGame.GetSerialisedLadder()).ConfigureAwait(false);
// If a save hasn't been triggered by the user yet, populate the initial value
lastSerialisedLadder ??= serialisedLadder;

View File

@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@ -54,8 +53,6 @@ namespace osu.Game.Tournament.Screens.Editors
});
}
Debug.Assert(countries != null);
foreach (var c in countries)
Storage.Add(c);
}

View File

@ -4,6 +4,7 @@
#nullable disable
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@ -102,10 +103,14 @@ namespace osu.Game.Tournament.Screens.Editors
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(args.NewItems != null);
args.NewItems.Cast<TModel>().ForEach(i => flow.Add(CreateDrawable(i)));
break;
case NotifyCollectionChangedAction.Remove:
Debug.Assert(args.OldItems != null);
args.OldItems.Cast<TModel>().ForEach(i => flow.RemoveAll(d => d.Model == i, true));
break;
}

View File

@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@ -20,8 +21,6 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
{
public partial class LadderEditorSettings : PlayerSettingsGroup
{
private const int padding = 10;
private SettingsDropdown<TournamentRound> roundDropdown;
private PlayerCheckbox losersCheckbox;
private DateTextBox dateTimeBox;
@ -103,10 +102,14 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(args.NewItems != null);
args.NewItems.Cast<TournamentRound>().ForEach(add);
break;
case NotifyCollectionChangedAction.Remove:
Debug.Assert(args.OldItems != null);
args.OldItems.Cast<TournamentRound>().ForEach(i => Control.RemoveDropdownItem(i));
break;
}

View File

@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
@ -25,10 +26,14 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(args.NewItems != null);
args.NewItems.Cast<TournamentTeam>().ForEach(add);
break;
case NotifyCollectionChangedAction.Remove:
Debug.Assert(args.OldItems != null);
args.OldItems.Cast<TournamentTeam>().ForEach(i => Control.RemoveDropdownItem(i));
break;
}

View File

@ -4,6 +4,7 @@
#nullable disable
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Caching;
@ -81,11 +82,15 @@ namespace osu.Game.Tournament.Screens.Ladder
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(args.NewItems != null);
foreach (var p in args.NewItems.Cast<TournamentMatch>())
addMatch(p);
break;
case NotifyCollectionChangedAction.Remove:
Debug.Assert(args.OldItems != null);
foreach (var p in args.OldItems.Cast<TournamentMatch>())
{
foreach (var d in MatchesContainer.Where(d => d.Match == p))
@ -153,7 +158,7 @@ namespace osu.Game.Tournament.Screens.Ladder
foreach (var round in LadderInfo.Rounds)
{
var topMatch = MatchesContainer.Where(p => !p.Match.Losers.Value && p.Match.Round.Value == round).OrderBy(p => p.Y).FirstOrDefault();
var topMatch = MatchesContainer.Where(p => !p.Match.Losers.Value && p.Match.Round.Value == round).MinBy(p => p.Y);
if (topMatch == null) continue;
@ -167,7 +172,7 @@ namespace osu.Game.Tournament.Screens.Ladder
foreach (var round in LadderInfo.Rounds)
{
var topMatch = MatchesContainer.Where(p => p.Match.Losers.Value && p.Match.Round.Value == round).OrderBy(p => p.Y).FirstOrDefault();
var topMatch = MatchesContainer.Where(p => p.Match.Losers.Value && p.Match.Round.Value == round).MinBy(p => p.Y);
if (topMatch == null) continue;

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Project">
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Library</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Description>tools for tournaments.</Description>
@ -11,4 +11,4 @@
<ItemGroup Label="Package References">
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
</ItemGroup>
</Project>
</Project>

View File

@ -35,7 +35,7 @@ namespace osu.Game.Audio
public bool Equals(SampleInfo? other)
=> other != null && sampleNames.SequenceEqual(other.sampleNames);
public override bool Equals(object obj)
public override bool Equals(object? obj)
=> obj is SampleInfo other && Equals(other);
}
}

View File

@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps
public override async Task<Live<BeatmapSetInfo>?> ImportAsUpdate(ProgressNotification notification, ImportTask importTask, BeatmapSetInfo original)
{
var imported = await Import(notification, new[] { importTask });
var imported = await Import(notification, new[] { importTask }).ConfigureAwait(true);
if (!imported.Any())
return null;

View File

@ -178,7 +178,7 @@ namespace osu.Game.Beatmaps
{
try
{
await cacheDownloadRequest.PerformAsync();
await cacheDownloadRequest.PerformAsync().ConfigureAwait(false);
}
catch
{

View File

@ -16,7 +16,7 @@ namespace osu.Game.Beatmaps.ControlPoints
public void AttachGroup(ControlPointGroup pointGroup) => Time = pointGroup.Time;
public int CompareTo(ControlPoint other) => Time.CompareTo(other.Time);
public int CompareTo(ControlPoint? other) => Time.CompareTo(other?.Time);
public virtual Color4 GetRepresentingColour(OsuColour colours) => colours.Yellow;
@ -32,7 +32,7 @@ namespace osu.Game.Beatmaps.ControlPoints
/// </summary>
public ControlPoint DeepClone()
{
var copy = (ControlPoint)Activator.CreateInstance(GetType());
var copy = (ControlPoint)Activator.CreateInstance(GetType())!;
copy.CopyFrom(this);

View File

@ -26,7 +26,7 @@ namespace osu.Game.Beatmaps.ControlPoints
Time = time;
}
public int CompareTo(ControlPointGroup other) => Time.CompareTo(other.Time);
public int CompareTo(ControlPointGroup? other) => Time.CompareTo(other?.Time);
public void Add(ControlPoint point)
{

View File

@ -70,14 +70,14 @@ namespace osu.Game.Beatmaps.ControlPoints
/// </summary>
[JsonIgnore]
public double BPMMaximum =>
60000 / (TimingPoints.OrderBy(c => c.BeatLength).FirstOrDefault() ?? TimingControlPoint.DEFAULT).BeatLength;
60000 / (TimingPoints.MinBy(c => c.BeatLength) ?? TimingControlPoint.DEFAULT).BeatLength;
/// <summary>
/// Finds the minimum BPM represented by any timing control point.
/// </summary>
[JsonIgnore]
public double BPMMinimum =>
60000 / (TimingPoints.OrderByDescending(c => c.BeatLength).FirstOrDefault() ?? TimingControlPoint.DEFAULT).BeatLength;
60000 / (TimingPoints.MaxBy(c => c.BeatLength) ?? TimingControlPoint.DEFAULT).BeatLength;
/// <summary>
/// Remove all <see cref="ControlPointGroup"/>s and return to a pristine state.
@ -300,7 +300,7 @@ namespace osu.Game.Beatmaps.ControlPoints
public ControlPointInfo DeepClone()
{
var controlPointInfo = (ControlPointInfo)Activator.CreateInstance(GetType());
var controlPointInfo = (ControlPointInfo)Activator.CreateInstance(GetType())!;
foreach (var point in AllControlPoints)
controlPointInfo.Add(point.Time, point.DeepClone());

View File

@ -51,11 +51,11 @@ namespace osu.Game.Beatmaps
if (!recommendedDifficultyMapping.TryGetValue(r, out double recommendation))
continue;
BeatmapInfo beatmapInfo = beatmaps.Where(b => b.Ruleset.ShortName.Equals(r)).OrderBy(b =>
BeatmapInfo beatmapInfo = beatmaps.Where(b => b.Ruleset.ShortName.Equals(r, StringComparison.Ordinal)).MinBy(b =>
{
double difference = b.StarRating - recommendation;
return difference >= 0 ? difference * 2 : difference * -1; // prefer easier over harder
}).FirstOrDefault();
});
if (beatmapInfo != null)
return beatmapInfo;
@ -90,7 +90,7 @@ namespace osu.Game.Beatmaps
return recommendedDifficultyMapping
.OrderByDescending(pair => pair.Value)
.Select(pair => pair.Key)
.Where(r => !r.Equals(ruleset.Value.ShortName))
.Where(r => !r.Equals(ruleset.Value.ShortName, StringComparison.Ordinal))
.Prepend(ruleset.Value.ShortName);
}
}

View File

@ -91,15 +91,15 @@ namespace osu.Game.Configuration
OrderPosition = orderPosition;
}
public int CompareTo(SettingSourceAttribute other)
public int CompareTo(SettingSourceAttribute? other)
{
if (OrderPosition == other.OrderPosition)
if (OrderPosition == other?.OrderPosition)
return 0;
// unordered items come last (are greater than any ordered items).
if (OrderPosition == null)
return 1;
if (other.OrderPosition == null)
if (other?.OrderPosition == null)
return -1;
// ordered items are sorted by the order value.
@ -113,7 +113,7 @@ namespace osu.Game.Configuration
{
foreach (var (attr, property) in obj.GetOrderedSettingsSourceProperties())
{
object value = property.GetValue(obj);
object value = property.GetValue(obj)!;
if (attr.SettingControlType != null)
{
@ -121,7 +121,7 @@ namespace osu.Game.Configuration
if (controlType.EnumerateBaseTypes().All(t => !t.IsGenericType || t.GetGenericTypeDefinition() != typeof(SettingsItem<>)))
throw new InvalidOperationException($"{nameof(SettingSourceAttribute)} had an unsupported custom control type ({controlType.ReadableName()})");
var control = (Drawable)Activator.CreateInstance(controlType);
var control = (Drawable)Activator.CreateInstance(controlType)!;
controlType.GetProperty(nameof(SettingsItem<object>.SettingSourceObject))?.SetValue(control, obj);
controlType.GetProperty(nameof(SettingsItem<object>.LabelText))?.SetValue(control, attr.Label);
controlType.GetProperty(nameof(SettingsItem<object>.TooltipText))?.SetValue(control, attr.Description);
@ -188,7 +188,7 @@ namespace osu.Game.Configuration
case IBindable bindable:
var dropdownType = typeof(ModSettingsEnumDropdown<>).MakeGenericType(bindable.GetType().GetGenericArguments()[0]);
var dropdown = (Drawable)Activator.CreateInstance(dropdownType);
var dropdown = (Drawable)Activator.CreateInstance(dropdownType)!;
dropdownType.GetProperty(nameof(SettingsDropdown<object>.LabelText))?.SetValue(dropdown, attr.Label);
dropdownType.GetProperty(nameof(SettingsDropdown<object>.TooltipText))?.SetValue(dropdown, attr.Description);
@ -231,7 +231,7 @@ namespace osu.Game.Configuration
// An unknown (e.g. enum) generic type.
var valueMethod = u.GetType().GetProperty(nameof(IBindable<int>.Value));
Debug.Assert(valueMethod != null);
return valueMethod.GetValue(u);
return valueMethod.GetValue(u)!;
default:
// fall back for non-bindable cases.

View File

@ -79,16 +79,16 @@ namespace osu.Game.Database
switch (content)
{
case StableContent.Beatmaps:
return await new LegacyBeatmapImporter(beatmaps).GetAvailableCount(stableStorage);
return await new LegacyBeatmapImporter(beatmaps).GetAvailableCount(stableStorage).ConfigureAwait(false);
case StableContent.Skins:
return await new LegacySkinImporter(skins).GetAvailableCount(stableStorage);
return await new LegacySkinImporter(skins).GetAvailableCount(stableStorage).ConfigureAwait(false);
case StableContent.Collections:
return await new LegacyCollectionImporter(realmAccess).GetAvailableCount(stableStorage);
return await new LegacyCollectionImporter(realmAccess).GetAvailableCount(stableStorage).ConfigureAwait(false);
case StableContent.Scores:
return await new LegacyScoreImporter(scores).GetAvailableCount(stableStorage);
return await new LegacyScoreImporter(scores).GetAvailableCount(stableStorage).ConfigureAwait(false);
default:
throw new ArgumentException($"Only one {nameof(StableContent)} flag should be specified.");

View File

@ -61,6 +61,6 @@ namespace osu.Game.Database
public override int GetHashCode() => HashCode.Combine(ID);
public override string ToString() => PerformRead(i => i.ToString());
public override string? ToString() => PerformRead(i => i.ToString());
}
}

View File

@ -71,9 +71,9 @@ namespace osu.Game.Database
bool importSuccessful;
if (originalModel != null)
importSuccessful = (await importer.ImportAsUpdate(notification, new ImportTask(filename), originalModel)) != null;
importSuccessful = (await importer.ImportAsUpdate(notification, new ImportTask(filename), originalModel).ConfigureAwait(false)) != null;
else
importSuccessful = (await importer.Import(notification, new[] { new ImportTask(filename) })).Any();
importSuccessful = (await importer.Import(notification, new[] { new ImportTask(filename) }).ConfigureAwait(false)).Any();
// for now a failed import will be marked as a failed download for simplicity.
if (!importSuccessful)

View File

@ -481,7 +481,7 @@ namespace osu.Game.Database
// server, which we don't use. May want to report upstream or revisit in the future.
using (var realm = getRealmInstance())
// ReSharper disable once AccessToDisposedClosure (WriteAsync should be marked as [InstantHandle]).
await realm.WriteAsync(() => action(realm));
await realm.WriteAsync(() => action(realm)).ConfigureAwait(false);
pendingAsyncWrites.Signal();
});
@ -558,7 +558,7 @@ namespace osu.Game.Database
return new InvokeOnDisposal(() => model.PropertyChanged -= onPropertyChanged);
void onPropertyChanged(object sender, PropertyChangedEventArgs args)
void onPropertyChanged(object? sender, PropertyChangedEventArgs args)
{
if (args.PropertyName == propertyName)
onChanged(propLookupCompiled(model));

View File

@ -66,10 +66,10 @@ namespace osu.Game.Extensions
foreach (var (_, property) in component.GetSettingsSourceProperties())
{
if (!info.Settings.TryGetValue(property.Name.ToSnakeCase(), out object settingValue))
if (!info.Settings.TryGetValue(property.Name.ToSnakeCase(), out object? settingValue))
continue;
skinnable.CopyAdjustedSetting((IBindable)property.GetValue(component), settingValue);
skinnable.CopyAdjustedSetting(((IBindable)property.GetValue(component)!), settingValue);
}
}

View File

@ -37,7 +37,7 @@ namespace osu.Game.Extensions
if (cancellationToken.IsCancellationRequested)
{
tcs.SetCanceled();
tcs.SetCanceled(cancellationToken);
}
else
{

View File

@ -277,7 +277,7 @@ namespace osu.Game.Graphics.UserInterface
{
var samples = sampleMap[feedbackSampleType];
if (samples == null || samples.Length == 0)
if (samples.Length == 0)
return null;
return samples[RNG.Next(0, samples.Length)]?.GetChannel();

View File

@ -63,7 +63,7 @@ namespace osu.Game.IO.Serialization.Converters
throw new JsonException("Expected $type token.");
string typeName = lookupTable[(int)tok["$type"]];
var instance = (T)Activator.CreateInstance(Type.GetType(typeName).AsNonNull());
var instance = (T)Activator.CreateInstance(Type.GetType(typeName).AsNonNull())!;
serializer.Populate(itemReader, instance);
list.Add(instance);

View File

@ -27,7 +27,7 @@ namespace osu.Game.Models
public bool IsBot => false;
public bool Equals(RealmUser other)
public bool Equals(RealmUser? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;

View File

@ -39,7 +39,7 @@ namespace osu.Game.Online.API
foreach (var (_, property) in mod.GetSettingsSourceProperties())
{
var bindable = (IBindable)property.GetValue(mod);
var bindable = (IBindable)property.GetValue(mod)!;
if (!bindable.IsDefault)
Settings.Add(property.Name.ToSnakeCase(), bindable.GetUnderlyingSettingValue());
@ -60,16 +60,16 @@ namespace osu.Game.Online.API
{
foreach (var (_, property) in resultMod.GetSettingsSourceProperties())
{
if (!Settings.TryGetValue(property.Name.ToSnakeCase(), out object settingValue))
if (!Settings.TryGetValue(property.Name.ToSnakeCase(), out object? settingValue))
continue;
try
{
resultMod.CopyAdjustedSetting((IBindable)property.GetValue(resultMod), settingValue);
resultMod.CopyAdjustedSetting((IBindable)property.GetValue(resultMod)!, settingValue);
}
catch (Exception ex)
{
Logger.Log($"Failed to copy mod setting value '{settingValue ?? "null"}' to \"{property.Name}\": {ex.Message}");
Logger.Log($"Failed to copy mod setting value '{settingValue}' to \"{property.Name}\": {ex.Message}");
}
}
}
@ -79,7 +79,7 @@ namespace osu.Game.Online.API
public bool ShouldSerializeSettings() => Settings.Count > 0;
public bool Equals(APIMod other)
public bool Equals(APIMod? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;

View File

@ -143,7 +143,7 @@ namespace osu.Game.Online.API.Requests.Responses
public bool Equals(IRulesetInfo? other) => other is APIRuleset r && this.MatchesOnlineID(r);
public int CompareTo(IRulesetInfo other)
public int CompareTo(IRulesetInfo? other)
{
if (!(other is APIRuleset ruleset))
throw new ArgumentException($@"Object is not of type {nameof(APIRuleset)}.", nameof(other));

View File

@ -71,7 +71,7 @@ namespace osu.Game.Online.Chat
{
int index = m.Index - captureOffset;
string? displayText = string.Format(display,
string displayText = string.Format(display,
m.Groups[0],
m.Groups["text"].Value,
m.Groups["url"].Value).Trim();
@ -109,7 +109,7 @@ namespace osu.Game.Online.Chat
foreach (Match m in regex.Matches(result.Text, startIndex))
{
int index = m.Index;
string? linkText = m.Groups["link"].Value;
string linkText = m.Groups["link"].Value;
int indexLength = linkText.Length;
var details = GetLinkDetails(linkText);
@ -125,7 +125,7 @@ namespace osu.Game.Online.Chat
public static LinkDetails GetLinkDetails(string url)
{
string[]? args = url.Split('/', StringSplitOptions.RemoveEmptyEntries);
string[] args = url.Split('/', StringSplitOptions.RemoveEmptyEntries);
args[0] = args[0].TrimEnd(':');
switch (args[0])
@ -362,6 +362,6 @@ namespace osu.Game.Online.Chat
public bool Overlaps(Link otherLink) => Index < otherLink.Index + otherLink.Length && otherLink.Index < Index + Length;
public int CompareTo(Link otherLink) => Index > otherLink.Index ? 1 : -1;
public int CompareTo(Link? otherLink) => Index > otherLink?.Index ? 1 : -1;
}
}

View File

@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using osu.Framework.Allocation;
@ -61,12 +62,16 @@ namespace osu.Game.Online.Chat
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(e.NewItems != null);
foreach (var channel in e.NewItems.Cast<Channel>())
channel.NewMessagesArrived += checkNewMessages;
break;
case NotifyCollectionChangedAction.Remove:
Debug.Assert(e.OldItems != null);
foreach (var channel in e.OldItems.Cast<Channel>())
channel.NewMessagesArrived -= checkNewMessages;

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;
@ -59,17 +60,21 @@ namespace osu.Game.Online
var builder = new HubConnectionBuilder()
.WithUrl(endpoint, options =>
{
// Use HttpClient.DefaultProxy once on net6 everywhere.
// The credential setter can also be removed at this point.
options.Proxy = WebRequest.DefaultWebProxy;
if (options.Proxy != null)
options.Proxy.Credentials = CredentialCache.DefaultCredentials;
// Configuring proxies is not supported on iOS, see https://github.com/xamarin/xamarin-macios/issues/14632.
if (RuntimeInfo.OS != RuntimeInfo.Platform.iOS)
{
// Use HttpClient.DefaultProxy once on net6 everywhere.
// The credential setter can also be removed at this point.
options.Proxy = WebRequest.DefaultWebProxy;
if (options.Proxy != null)
options.Proxy.Credentials = CredentialCache.DefaultCredentials;
}
options.Headers.Add("Authorization", $"Bearer {api.AccessToken}");
options.Headers.Add("OsuVersionHash", versionHash);
});
if (RuntimeInfo.SupportsJIT && preferMessagePack)
if (RuntimeFeature.IsDynamicCodeCompiled && preferMessagePack)
{
builder.AddMessagePackProtocol(options =>
{

View File

@ -68,7 +68,7 @@ namespace osu.Game.Online.Metadata
while (true)
{
Logger.Log($"Requesting catch-up from {lastQueueId.Value}");
var catchUpChanges = await GetChangesSince(lastQueueId.Value);
var catchUpChanges = await GetChangesSince(lastQueueId.Value).ConfigureAwait(true);
lastQueueId.Value = catchUpChanges.LastProcessedQueueID;
@ -78,7 +78,7 @@ namespace osu.Game.Online.Metadata
break;
}
await ProcessChanges(catchUpChanges.BeatmapSetIDs);
await ProcessChanges(catchUpChanges.BeatmapSetIDs).ConfigureAwait(true);
}
}
catch (Exception e)
@ -101,7 +101,7 @@ namespace osu.Game.Online.Metadata
if (!catchingUp)
lastQueueId.Value = updates.LastProcessedQueueID;
await ProcessChanges(updates.BeatmapSetIDs);
await ProcessChanges(updates.BeatmapSetIDs).ConfigureAwait(false);
}
public override Task<BeatmapUpdates> GetChangesSince(int queueId)

View File

@ -822,7 +822,7 @@ namespace osu.Game.Online.Multiplayer
{
if (cancellationToken.IsCancellationRequested)
{
tcs.SetCanceled();
tcs.SetCanceled(cancellationToken);
return;
}

View File

@ -54,10 +54,10 @@ namespace osu.Game.Online.Multiplayer
return UserID == other.UserID;
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
if (obj?.GetType() != GetType()) return false;
return Equals((MultiplayerRoomUser)obj);
}

View File

@ -80,7 +80,7 @@ namespace osu.Game.Online.Multiplayer
try
{
return await connection.InvokeAsync<MultiplayerRoom>(nameof(IMultiplayerServer.JoinRoomWithPassword), roomId, password ?? string.Empty);
return await connection.InvokeAsync<MultiplayerRoom>(nameof(IMultiplayerServer.JoinRoomWithPassword), roomId, password ?? string.Empty).ConfigureAwait(false);
}
catch (HubException exception)
{
@ -88,8 +88,8 @@ namespace osu.Game.Online.Multiplayer
{
Debug.Assert(connector != null);
await connector.Reconnect();
return await JoinRoom(roomId, password);
await connector.Reconnect().ConfigureAwait(false);
return await JoinRoom(roomId, password).ConfigureAwait(false);
}
throw;

View File

@ -27,7 +27,7 @@ namespace osu.Game.Online.Notifications
protected sealed override async Task<PersistentEndpointClient> BuildConnectionAsync(CancellationToken cancellationToken)
{
var client = await BuildNotificationClientAsync(cancellationToken);
var client = await BuildNotificationClientAsync(cancellationToken).ConfigureAwait(false);
client.ChannelJoined = c => ChannelJoined?.Invoke(c);
client.ChannelParted = c => ChannelParted?.Invoke(c);

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Net;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
@ -36,11 +37,11 @@ namespace osu.Game.Online.Notifications.WebSocket
public override async Task ConnectAsync(CancellationToken cancellationToken)
{
await socket.ConnectAsync(new Uri(endpoint), cancellationToken).ConfigureAwait(false);
await sendMessage(new StartChatRequest(), CancellationToken.None);
await sendMessage(new StartChatRequest(), CancellationToken.None).ConfigureAwait(false);
runReadLoop(cancellationToken);
await base.ConnectAsync(cancellationToken);
await base.ConnectAsync(cancellationToken).ConfigureAwait(false);
}
private void runReadLoop(CancellationToken cancellationToken) => Task.Run(async () =>
@ -52,7 +53,7 @@ namespace osu.Game.Online.Notifications.WebSocket
{
try
{
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, cancellationToken);
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false);
switch (result.MessageType)
{
@ -72,7 +73,7 @@ namespace osu.Game.Online.Notifications.WebSocket
break;
}
await onMessageReceivedAsync(message);
await onMessageReceivedAsync(message).ConfigureAwait(false);
}
break;
@ -81,12 +82,12 @@ namespace osu.Game.Online.Notifications.WebSocket
throw new NotImplementedException("Binary message type not supported.");
case WebSocketMessageType.Close:
throw new Exception("Connection closed by remote host.");
throw new WebException("Connection closed by remote host.");
}
}
catch (Exception ex)
{
await InvokeClosed(ex);
await InvokeClosed(ex).ConfigureAwait(false);
return;
}
}
@ -109,7 +110,7 @@ namespace osu.Game.Online.Notifications.WebSocket
if (socket.State != WebSocketState.Open)
return;
await socket.SendAsync(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)), WebSocketMessageType.Text, true, cancellationToken);
await socket.SendAsync(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)), WebSocketMessageType.Text, true, cancellationToken).ConfigureAwait(false);
}
private async Task onMessageReceivedAsync(SocketMessage message)
@ -141,7 +142,7 @@ namespace osu.Game.Online.Notifications.WebSocket
Debug.Assert(messageData != null);
foreach (var msg in messageData.Messages)
HandleChannelJoined(await getChannel(msg.ChannelId));
HandleChannelJoined(await getChannel(msg.ChannelId).ConfigureAwait(false));
HandleMessages(messageData.Messages);
break;
@ -150,7 +151,7 @@ namespace osu.Game.Online.Notifications.WebSocket
private async Task<Channel> getChannel(long channelId)
{
if (channelsMap.TryGetValue(channelId, out Channel channel))
if (channelsMap.TryGetValue(channelId, out Channel? channel))
return channel;
var tsc = new TaskCompletionSource<Channel>();
@ -166,13 +167,13 @@ namespace osu.Game.Online.Notifications.WebSocket
API.Queue(req);
return await tsc.Task;
return await tsc.Task.ConfigureAwait(false);
}
public override async ValueTask DisposeAsync()
{
await base.DisposeAsync();
await closeAsync();
await base.DisposeAsync().ConfigureAwait(false);
await closeAsync().ConfigureAwait(false);
socket.Dispose();
}
}

View File

@ -32,7 +32,7 @@ namespace osu.Game.Online.Notifications.WebSocket
req.Failure += ex => tcs.SetException(ex);
api.Queue(req);
string endpoint = await tcs.Task;
string endpoint = await tcs.Task.ConfigureAwait(false);
ClientWebSocket socket = new ClientWebSocket();
socket.Options.SetRequestHeader(@"Authorization", @$"Bearer {api.AccessToken}");

View File

@ -65,11 +65,11 @@ namespace osu.Game.Online
{
case APIState.Failing:
case APIState.Offline:
await disconnect(true);
await disconnect(true).ConfigureAwait(true);
break;
case APIState.Online:
await connect();
await connect().ConfigureAwait(true);
break;
}
}
@ -147,7 +147,7 @@ namespace osu.Game.Online
{
bool hasBeenCancelled = cancellationToken.IsCancellationRequested;
await disconnect(true);
await disconnect(true).ConfigureAwait(false);
if (ex != null)
await handleErrorAndDelay(ex, CancellationToken.None).ConfigureAwait(false);

View File

@ -33,7 +33,8 @@ namespace osu.Game.Online
object? instance = Activator.CreateInstance(resolvedType);
jsonSerializer.Populate(obj["$value"]!.CreateReader(), instance);
if (instance != null)
jsonSerializer.Populate(obj["$value"]!.CreateReader(), instance);
return instance;
}

View File

@ -56,7 +56,7 @@ namespace osu.Game.Online.Spectator
try
{
await connection.InvokeAsync(nameof(ISpectatorServer.BeginPlaySession), scoreToken, state);
await connection.InvokeAsync(nameof(ISpectatorServer.BeginPlaySession), scoreToken, state).ConfigureAwait(false);
}
catch (Exception exception)
{
@ -64,8 +64,8 @@ namespace osu.Game.Online.Spectator
{
Debug.Assert(connector != null);
await connector.Reconnect();
await BeginPlayingInternal(scoreToken, state);
await connector.Reconnect().ConfigureAwait(false);
await BeginPlayingInternal(scoreToken, state).ConfigureAwait(false);
}
// Exceptions can occur if, for instance, the locally played beatmap doesn't have a server-side counterpart.

View File

@ -184,7 +184,7 @@ namespace osu.Game.Online.Spectator
Header = header;
}
public int CompareTo(TimedFrame other) => Time.CompareTo(other.Time);
public int CompareTo(TimedFrame? other) => Time.CompareTo(other?.Time);
}
}
}

View File

@ -16,6 +16,7 @@ using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Configuration;
using osu.Framework.Extensions;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Extensions.TypeExtensions;
using osu.Framework.Graphics;
@ -332,7 +333,7 @@ namespace osu.Game
/// <param name="link">The link to load.</param>
public void HandleLink(LinkDetails link) => Schedule(() =>
{
string argString = link.Argument.ToString();
string argString = link.Argument.ToString() ?? string.Empty;
switch (link.Action)
{
@ -406,6 +407,16 @@ namespace osu.Game
if (url.StartsWith('/'))
url = $"{API.APIEndpointUrl}{url}";
if (!url.CheckIsValidUrl())
{
Notifications.Post(new SimpleErrorNotification
{
Text = $"The URL {url} has an unsupported or dangerous protocol and will not be opened.",
});
return;
}
externalLinkOpener.OpenUrlExternally(url, bypassExternalUrlWarning);
});
@ -1031,6 +1042,8 @@ namespace osu.Game
{
if (entry.Level < LogLevel.Important || entry.Target > LoggingTarget.Database) return;
Debug.Assert(entry.Target != null);
const int short_term_display_limit = 3;
if (recentLogCount < short_term_display_limit)
@ -1043,7 +1056,7 @@ namespace osu.Game
}
else if (recentLogCount == short_term_display_limit)
{
string logFile = $@"{entry.Target.ToString().ToLowerInvariant()}.log";
string logFile = $@"{entry.Target.Value.ToString().ToLowerInvariant()}.log";
Schedule(() => Notifications.Post(new SimpleNotification
{

View File

@ -352,11 +352,13 @@ namespace osu.Game.Overlays
protected virtual DrawableChannel CreateDrawableChannel(Channel newChannel) => new DrawableChannel(newChannel);
private void joinedChannelsChanged(object sender, NotifyCollectionChangedEventArgs args)
private void joinedChannelsChanged(object? sender, NotifyCollectionChangedEventArgs args)
{
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(args.NewItems != null);
IEnumerable<Channel> newChannels = args.NewItems.OfType<Channel>().Where(isChatChannel);
foreach (var channel in newChannels)
@ -365,6 +367,8 @@ namespace osu.Game.Overlays
break;
case NotifyCollectionChangedAction.Remove:
Debug.Assert(args.OldItems != null);
IEnumerable<Channel> leftChannels = args.OldItems.OfType<Channel>().Where(isChatChannel);
foreach (var channel in leftChannels)
@ -384,7 +388,7 @@ namespace osu.Game.Overlays
}
}
private void availableChannelsChanged(object sender, NotifyCollectionChangedEventArgs args)
private void availableChannelsChanged(object? sender, NotifyCollectionChangedEventArgs args)
=> channelListing.UpdateAvailableChannels(channelManager.AvailableChannels);
private void handleChatMessage(string message)

View File

@ -19,6 +19,7 @@ using System;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Extensions.IEnumerableExtensions;
using System.Collections.Specialized;
using System.Diagnostics;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Localisation;
using osu.Framework.Platform;
@ -360,6 +361,8 @@ namespace osu.Game.Overlays.Comments
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(args.NewItems != null);
onRepliesAdded(args.NewItems.Cast<DrawableComment>());
break;

View File

@ -301,7 +301,7 @@ namespace osu.Game.Overlays
if (currentStepIndex < steps.Count)
{
var nextScreen = (Screen)Activator.CreateInstance(steps[currentStepIndex.Value]);
var nextScreen = (Screen)Activator.CreateInstance(steps[currentStepIndex.Value])!;
loadingShowDelegate = Scheduler.AddDelayed(() => loading.Show(), 200);
nextScreen.OnLoadComplete += _ =>

View File

@ -3,7 +3,6 @@
#nullable disable
using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -131,8 +130,6 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
{
var metadata = beatmapInfo.Metadata;
Debug.Assert(metadata != null);
return new Drawable[]
{
new OsuSpriteText

View File

@ -4,7 +4,6 @@
#nullable disable
using System;
using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
@ -269,8 +268,6 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
{
var metadata = beatmapInfo.Metadata;
Debug.Assert(metadata != null);
return new Drawable[]
{
new OsuSpriteText

View File

@ -3,7 +3,6 @@
#nullable disable
using System.Diagnostics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
@ -29,8 +28,6 @@ namespace osu.Game.Overlays.Settings.Sections.Input
var r = ruleset.CreateInstance();
Debug.Assert(r != null);
foreach (int variant in r.AvailableVariants)
Add(new VariantBindingsSubsection(ruleset, variant));
}

View File

@ -55,6 +55,6 @@ namespace osu.Game.Rulesets.Mods
/// <summary>
/// Create a fresh <see cref="Mod"/> instance based on this mod.
/// </summary>
Mod CreateInstance() => (Mod)Activator.CreateInstance(GetType());
Mod CreateInstance() => (Mod)Activator.CreateInstance(GetType())!;
}
}

View File

@ -70,7 +70,7 @@ namespace osu.Game.Rulesets.Mods
foreach ((SettingSourceAttribute attr, PropertyInfo property) in this.GetOrderedSettingsSourceProperties())
{
var bindable = (IBindable)property.GetValue(this);
var bindable = (IBindable)property.GetValue(this)!;
if (!bindable.IsDefault)
tooltipTexts.Add($"{attr.Label} {bindable}");
@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Mods
/// </summary>
public virtual Mod DeepClone()
{
var result = (Mod)Activator.CreateInstance(GetType());
var result = (Mod)Activator.CreateInstance(GetType())!;
result.CopyFrom(this);
return result;
}
@ -150,8 +150,8 @@ namespace osu.Game.Rulesets.Mods
foreach (var (_, prop) in this.GetSettingsSourceProperties())
{
var targetBindable = (IBindable)prop.GetValue(this);
var sourceBindable = (IBindable)prop.GetValue(source);
var targetBindable = (IBindable)prop.GetValue(this)!;
var sourceBindable = (IBindable)prop.GetValue(source)!;
CopyAdjustedSetting(targetBindable, sourceBindable);
}
@ -183,9 +183,9 @@ namespace osu.Game.Rulesets.Mods
}
}
public bool Equals(IMod other) => other is Mod them && Equals(them);
public bool Equals(IMod? other) => other is Mod them && Equals(them);
public bool Equals(Mod other)
public bool Equals(Mod? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
@ -209,16 +209,16 @@ namespace osu.Game.Rulesets.Mods
/// <summary>
/// Reset all custom settings for this mod back to their defaults.
/// </summary>
public virtual void ResetSettingsToDefaults() => CopyFrom((Mod)Activator.CreateInstance(GetType()));
public virtual void ResetSettingsToDefaults() => CopyFrom((Mod)Activator.CreateInstance(GetType())!);
private class ModSettingsEqualityComparer : IEqualityComparer<IBindable>
{
public static ModSettingsEqualityComparer Default { get; } = new ModSettingsEqualityComparer();
public bool Equals(IBindable x, IBindable y)
public bool Equals(IBindable? x, IBindable? y)
{
object xValue = x.GetUnderlyingSettingValue();
object yValue = y.GetUnderlyingSettingValue();
object? xValue = x?.GetUnderlyingSettingValue();
object? yValue = y?.GetUnderlyingSettingValue();
return EqualityComparer<object>.Default.Equals(xValue, yValue);
}

View File

@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using Newtonsoft.Json;
using osu.Framework.Bindables;
@ -57,12 +58,16 @@ namespace osu.Game.Rulesets.Objects
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(args.NewItems != null);
foreach (var c in args.NewItems.Cast<PathControlPoint>())
c.Changed += invalidate;
break;
case NotifyCollectionChangedAction.Reset:
case NotifyCollectionChangedAction.Remove:
Debug.Assert(args.OldItems != null);
foreach (var c in args.OldItems.Cast<PathControlPoint>())
c.Changed -= invalidate;
break;

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