1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 20:22:55 +08:00

Merge branch 'master' into flow_container_insert

This commit is contained in:
Dean Herbert 2019-07-11 22:53:57 +09:00 committed by GitHub
commit 19e8198bff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
159 changed files with 4198 additions and 948 deletions

1
.gitignore vendored
View File

@ -198,6 +198,7 @@ ClientBin/
*.publishsettings
node_modules/
orleans.codegen.cs
Resource.designer.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)

View File

@ -1,3 +1,7 @@
<p align="center">
<img width="256" height="256" src="assets/lazer.png">
</p>
# osu!
[![Build status](https://ci.appveyor.com/api/projects/status/u2p01nx7l6og8buh?svg=true)](https://ci.appveyor.com/project/peppy/osu) [![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu) [![dev chat](https://discordapp.com/api/guilds/188630481301012481/widget.png?style=shield)](https://discord.gg/ppy)
@ -22,8 +26,6 @@ Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh
### Releases
![](https://puu.sh/DCmvA/f6a74f5fbb.png)
If you are not interested in developing the game, you can still consume our [binary releases](https://github.com/ppy/osu/releases).
**Latest build:**
@ -92,11 +94,13 @@ Code analysis can be run with `powershell ./build.ps1` or `build.sh`. This is cu
We welcome all contributions, but keep in mind that we already have a lot of the UI designed. If you wish to work on something with the intention on having it included in the official distribution, please open an issue for discussion and we will give you what you need from a design perspective to proceed. If you want to make *changes* to the design, we recommend you open an issue with your intentions before spending too much time, to ensure no effort is wasted.
Please make sure you are familiar with the [development and testing](https://github.com/ppy/osu-framework/wiki/Development-and-Testing) procedure we have set up. New component development, and where possible, bug fixing and debugging existing components **should always be done under VisualTests**.
If you're unsure of what you can help with, check out the [list of open issues](https://github.com/ppy/osu/issues) (especially those with the ["good first issue"](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22) label).
Contributions can be made via pull requests to this repository. We hope to credit and reward larger contributions via a [bounty system](https://www.bountysource.com/teams/ppy). If you're unsure of what you can help with, check out the [list of open issues](https://github.com/ppy/osu/issues).
Before starting, please make sure you are familiar with the [development and testing](https://github.com/ppy/osu-framework/wiki/Development-and-Testing) procedure we have set up. New component development, and where possible, bug fixing and debugging existing components **should always be done under VisualTests**.
Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured; with any libraries we are using; with any processes involved with contributing, *please* bring it up. I welcome all feedback so we can make contributing to this project as pain-free as possible.
Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured; with any libraries we are using; with any processes involved with contributing, *please* bring it up. We welcome all feedback so we can make contributing to this project as pain-free as possible.
For those interested, we love to reward quality contributions via bounties, paid out via paypal or osu! supporter tags. Don't hesitate to [request a bounty](https://docs.google.com/forms/d/e/1FAIpQLSet_8iFAgPMG526pBZ2Kic6HSh7XPM3fE8xPcnWNkMzINDdYg/viewform) for your work on this project.
## Licence

BIN
assets/lazer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

68
osu.Android.props Normal file
View File

@ -0,0 +1,68 @@
<Project>
<PropertyGroup>
<OutputPath>bin\$(Configuration)</OutputPath>
<WarningLevel>4</WarningLevel>
<SchemaVersion>2.0</SchemaVersion>
<BundleAssemblies>false</BundleAssemblies>
<AotAssemblies>false</AotAssemblies>
<LangVersion>default</LangVersion>
<OutputType>Library</OutputType>
<FileAlignment>512</FileAlignment>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AndroidApplication>True</AndroidApplication>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>False</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<EnableLLVM>false</EnableLLVM>
<AndroidManagedSymbols>false</AndroidManagedSymbols>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<AndroidUseSharedRuntime>true</AndroidUseSharedRuntime>
<EmbedAssembliesIntoApk>false</EmbedAssembliesIntoApk>
<MandroidI18n>cjk,mideast,other,rare,west</MandroidI18n>
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>false</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<ErrorReport>prompt</ErrorReport>
<EnableLLVM>true</EnableLLVM>
<AndroidManagedSymbols>false</AndroidManagedSymbols>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
<MandroidI18n>cjk,mideast,other,rare,west</MandroidI18n>
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\osu.licenseheader">
<Link>osu.licenseheader</Link>
</None>
<AndroidNativeLibrary Include="$(MSBuildThisFileDirectory)\osu.Android\lib\**\*.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</AndroidNativeLibrary>
</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="2019.702.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.711.0" />
</ItemGroup>
</Project>

126
osu.Android.sln Normal file
View File

@ -0,0 +1,126 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28516.95
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game", "osu.Game\osu.Game.csproj", "{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Osu", "osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj", "{C92A607B-1FDD-4954-9F92-03FF547D9080}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Catch", "osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj", "{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Taiko", "osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj", "{F167E17A-7DE6-4AF5-B920-A5112296C695}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Mania", "osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj", "{48F4582B-7687-4621-9CBE-5C24197CB536}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Android", "osu.Android\osu.Android.csproj", "{D1D5F9A8-B40B-40E6-B02F-482D03346D3D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Catch.Tests.Android", "osu.Game.Rulesets.Catch.Tests.Android\osu.Game.Rulesets.Catch.Tests.Android.csproj", "{C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Mania.Tests.Android", "osu.Game.Rulesets.Mania.Tests.Android\osu.Game.Rulesets.Mania.Tests.Android.csproj", "{531F1092-DB27-445D-AA33-2A77C7187C99}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Osu.Tests.Android", "osu.Game.Rulesets.Osu.Tests.Android\osu.Game.Rulesets.Osu.Tests.Android.csproj", "{90CAB706-39CB-4B93-9629-3218A6FF8E9B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Taiko.Tests.Android", "osu.Game.Rulesets.Taiko.Tests.Android\osu.Game.Rulesets.Taiko.Tests.Android.csproj", "{3701A0A1-8476-42C6-B5C4-D24129B4A484}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Tests.Android", "osu.Game.Tests.Android\osu.Game.Tests.Android.csproj", "{5CC222DC-5716-4499-B897-DCBDDA4A5CF9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Release|Any CPU.Build.0 = Release|Any CPU
{C92A607B-1FDD-4954-9F92-03FF547D9080}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C92A607B-1FDD-4954-9F92-03FF547D9080}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C92A607B-1FDD-4954-9F92-03FF547D9080}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C92A607B-1FDD-4954-9F92-03FF547D9080}.Release|Any CPU.Build.0 = Release|Any CPU
{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}.Release|Any CPU.Build.0 = Release|Any CPU
{F167E17A-7DE6-4AF5-B920-A5112296C695}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F167E17A-7DE6-4AF5-B920-A5112296C695}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F167E17A-7DE6-4AF5-B920-A5112296C695}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F167E17A-7DE6-4AF5-B920-A5112296C695}.Release|Any CPU.Build.0 = Release|Any CPU
{48F4582B-7687-4621-9CBE-5C24197CB536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{48F4582B-7687-4621-9CBE-5C24197CB536}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48F4582B-7687-4621-9CBE-5C24197CB536}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48F4582B-7687-4621-9CBE-5C24197CB536}.Release|Any CPU.Build.0 = Release|Any CPU
{D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Release|Any CPU.Build.0 = Release|Any CPU
{D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Release|Any CPU.Deploy.0 = Release|Any CPU
{C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Release|Any CPU.Build.0 = Release|Any CPU
{C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Release|Any CPU.Deploy.0 = Release|Any CPU
{531F1092-DB27-445D-AA33-2A77C7187C99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{531F1092-DB27-445D-AA33-2A77C7187C99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{531F1092-DB27-445D-AA33-2A77C7187C99}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{531F1092-DB27-445D-AA33-2A77C7187C99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{531F1092-DB27-445D-AA33-2A77C7187C99}.Release|Any CPU.Build.0 = Release|Any CPU
{531F1092-DB27-445D-AA33-2A77C7187C99}.Release|Any CPU.Deploy.0 = Release|Any CPU
{90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Release|Any CPU.Build.0 = Release|Any CPU
{90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Release|Any CPU.Deploy.0 = Release|Any CPU
{3701A0A1-8476-42C6-B5C4-D24129B4A484}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3701A0A1-8476-42C6-B5C4-D24129B4A484}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3701A0A1-8476-42C6-B5C4-D24129B4A484}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{3701A0A1-8476-42C6-B5C4-D24129B4A484}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3701A0A1-8476-42C6-B5C4-D24129B4A484}.Release|Any CPU.Build.0 = Release|Any CPU
{3701A0A1-8476-42C6-B5C4-D24129B4A484}.Release|Any CPU.Deploy.0 = Release|Any CPU
{5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Release|Any CPU.Build.0 = Release|Any CPU
{5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {671B0BEC-2403-45B0-9357-2C97CC517668}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.TextStylePolicy = $1
$1.EolMarker = Windows
$1.inheritsSet = VisualStudio
$1.inheritsScope = text/plain
$1.scope = text/x-csharp
$0.CSharpFormattingPolicy = $2
$2.IndentSwitchSection = True
$2.NewLinesForBracesInProperties = True
$2.NewLinesForBracesInAccessors = True
$2.NewLinesForBracesInAnonymousMethods = True
$2.NewLinesForBracesInControlBlocks = True
$2.NewLinesForBracesInAnonymousTypes = True
$2.NewLinesForBracesInObjectCollectionArrayInitializers = True
$2.NewLinesForBracesInLambdaExpressionBody = True
$2.NewLineForElse = True
$2.NewLineForCatch = True
$2.NewLineForFinally = True
$2.NewLineForMembersInObjectInit = True
$2.NewLineForMembersInAnonymousTypes = True
$2.NewLineForClausesInQuery = True
$2.SpacingAfterMethodDeclarationName = False
$2.SpaceAfterMethodCallName = False
$2.SpaceBeforeOpenSquareBracket = False
$2.inheritsSet = Mono
$2.inheritsScope = text/x-csharp
$2.scope = text/x-csharp
EndGlobalSection
EndGlobal

815
osu.Android.sln.DotSettings Normal file
View File

@ -0,0 +1,815 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Efnt/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Emp3/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Epng/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Ewav/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=2A66DD92_002DADB1_002D4994_002D89E2_002DC94E04ACDA0D_002Fd_003AMigrations/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=D9A367C9_002D4C1A_002D489F_002D9B05_002DA0CEA2B53B58/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">SOLUTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeAccessorOwnerBody/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeModifiersOrder/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeRedundantParentheses/@EntryIndexedValue"></s:String>
<s:Boolean x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeRedundantParentheses/@EntryIndexRemoved">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeMemberModifiers/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeModifiers/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AssignedValueIsNeverUsed/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AssignNullToNotNullAttribute/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AutoPropertyCanBeMadeGetOnly_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AutoPropertyCanBeMadeGetOnly_002ELocal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CanBeReplacedWithTryCastAndCheckForNull/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CheckForReferenceEqualityInstead_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CheckForReferenceEqualityInstead_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ClassNeverInstantiated_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ClassNeverInstantiated_002ELocal/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ClassWithVirtualMembersNeverInherited_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CollectionNeverQueried_002EGlobal/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CollectionNeverQueried_002ELocal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CompareOfFloatsByEqualityOperator/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertClosureToMethodGroup/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfDoToWhile/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToConditionalTernaryExpression/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToNullCoalescingExpression/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfToOrExpression/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertNullableToShortForm/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertPropertyToExpressionBody/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToAutoProperty/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToConstant_002ELocal/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToLambdaExpression/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToLocalFunction/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToStaticClass/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=DoubleNegationOperator/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EmptyGeneralCatchClause/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EventNeverSubscribedTo_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EventNeverSubscribedTo_002ELocal/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002ELocal/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ForCanBeConvertedToForeach/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ImpureMethodCallOnReadonlyValueField/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InheritdocConsiderUsage/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InlineOutVariableDeclaration/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InvertIf/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InvokeAsExtensionMethod/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=JoinDeclarationAndInitializer/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=JoinNullCheckWithUsage/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeMadeStatic_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBePrivate_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBePrivate_002ELocal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeProtected_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MergeCastWithTypeCheck/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MergeConditionalExpression/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MergeSequentialChecks/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MethodSupportsCancellation/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MoreSpecificForeachVariableTypeAvailable/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=NestedStringInterpolation/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=NotAccessedField_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ParameterHidesMember/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ParameterOnlyUsedForPreconditionCheck_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ParameterOnlyUsedForPreconditionCheck_002ELocal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PossibleMultipleEnumeration/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PrivateVariableCanBeMadeReadonly/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PublicConstructorInAbstractClass/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantArrayCreationExpression/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantAttributeParentheses/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantAttributeUsageProperty/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantCaseLabel/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantCommaInAttributeList/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantCommaInEnumDeclaration/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantCommaInInitializer/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantEmptyObjectCreationArgumentList/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantExplicitParamsArrayCreation/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantImmediateDelegateInvocation/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantLambdaSignatureParentheses/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantUsingDirective/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantStringInterpolation/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantVerbatimPrefix/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantVerbatimStringPrefix/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RemoveRedundantOrStatement_002EFalse/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RemoveRedundantOrStatement_002ETrue/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RemoveToList_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RemoveToList_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithFirstOrDefault_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithFirstOrDefault_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithFirstOrDefault_002E3/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithFirstOrDefault_002E4/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithLastOrDefault_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithLastOrDefault_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithLastOrDefault_002E3/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithLastOrDefault_002E4/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002E3/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002EAny_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002EAny_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ECount_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ECount_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002EFirst_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002EFirst_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002EFirstOrDefault_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002EFirstOrDefault_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ELast_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ELast_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ELastOrDefault_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ELastOrDefault_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ELongCount/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ESingle_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ESingle_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ESingleOrDefault_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002ESingleOrDefault_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithOfType_002EWhere/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSimpleAssignment_002EFalse/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSimpleAssignment_002ETrue/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleAssignment_002EFalse/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleAssignment_002ETrue/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToAny/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToCount/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToFirst/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToFirstOrDefault/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToLast/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToLastOrDefault/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToSingle/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToSingleOrDefault/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E1/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E2/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E3/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E4/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SwitchStatementMissingSomeCases/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TooWideLocalVariableScope/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TryCastAlwaysSucceeds/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnassignedField_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnnecessaryWhitespace/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMemberHierarchy_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMemberInSuper_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMember_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMember_002ELocal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMethodReturnValue_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMethodReturnValue_002ELocal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedParameter_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseCollectionCountProperty/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseFormatSpecifierInFormatString/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseFormatSpecifierInInterpolation/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseNameofExpression/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseNullPropagation/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UsePatternMatching/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseStringInterpolation/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VariableCanBeMadeConst/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VirtualMemberCallInConstructor/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VirtualMemberNeverOverridden_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VirtualMemberNeverOverridden_002ELocal/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Code_0020Cleanup_0020_0028peppy_0029/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Code Cleanup (peppy)"&gt;&lt;CSArrangeThisQualifier&gt;True&lt;/CSArrangeThisQualifier&gt;&lt;CSUseVar&gt;&lt;BehavourStyle&gt;CAN_CHANGE_TO_EXPLICIT&lt;/BehavourStyle&gt;&lt;LocalVariableStyle&gt;ALWAYS_EXPLICIT&lt;/LocalVariableStyle&gt;&lt;ForeachVariableStyle&gt;ALWAYS_EXPLICIT&lt;/ForeachVariableStyle&gt;&lt;/CSUseVar&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;CSUpdateFileHeader&gt;True&lt;/CSUpdateFileHeader&gt;&lt;CSCodeStyleAttributes ArrangeTypeAccessModifier="False" ArrangeTypeMemberAccessModifier="False" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="False" ArrangeBraces="False" ArrangeAttributes="False" ArrangeArgumentsStyle="False" /&gt;&lt;XAMLCollapseEmptyTags&gt;False&lt;/XAMLCollapseEmptyTags&gt;&lt;CSFixBuiltinTypeReferences&gt;True&lt;/CSFixBuiltinTypeReferences&gt;&lt;CSArrangeQualifiers&gt;True&lt;/CSArrangeQualifiers&gt;&lt;/Profile&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/CodeCleanup/RecentlyUsedProfile/@EntryValue">Code Cleanup (peppy)</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_LINQ_QUERY/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_FOR_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_PARAMETER/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTIPLE_DECLARATION/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTLINE_TYPE_PARAMETER_CONSTRAINS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTLINE_TYPE_PARAMETER_LIST/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">NEXT_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INITIALIZER_BRACES/@EntryValue">NEXT_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_CONSTRUCTOR_INITIALIZER_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AROUND_MULTIPLICATIVE_OP/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_SIZEOF_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_TYPEOF_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHING_EMPTY_BRACES/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/STICK_COMMENT/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARRAY_INITIALIZER_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_BINARY_OPSIGN/@EntryValue">True</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">200</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_OBJECT_AND_COLLECTION_INITIALIZER_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:Boolean x:Key="/Default/CodeStyle/EncapsulateField/MakeFieldPrivate/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/EncapsulateField/UseAutoProperty/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AABB/@EntryIndexedValue">AABB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=API/@EntryIndexedValue">API</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BPM/@EntryIndexedValue">BPM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GC/@EntryIndexedValue">GC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GL/@EntryIndexedValue">GL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GLSL/@EntryIndexedValue">GLSL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HID/@EntryIndexedValue">HID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HUD/@EntryIndexedValue">HUD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IPC/@EntryIndexedValue">IPC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LTRB/@EntryIndexedValue">LTRB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MD/@EntryIndexedValue">MD5</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NS/@EntryIndexedValue">NS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OS/@EntryIndexedValue">OS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RGB/@EntryIndexedValue">RGB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RNG/@EntryIndexedValue">RNG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SHA/@EntryIndexedValue">SHA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SRGB/@EntryIndexedValue">SRGB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TK/@EntryIndexedValue">TK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SS/@EntryIndexedValue">SS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PP/@EntryIndexedValue">PP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GMT/@EntryIndexedValue">GMT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QAT/@EntryIndexedValue">QAT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BNG/@EntryIndexedValue">BNG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UI/@EntryIndexedValue">UI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&#xD;
&lt;Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"&gt;&#xD;
&lt;TypePattern DisplayName="COM interfaces or structs"&gt;&#xD;
&lt;TypePattern.Match&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Kind Is="Interface" /&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" /&gt;&#xD;
&lt;HasAttribute Name="System.Runtime.InteropServices.ComImport" /&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;Kind Is="Struct" /&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/TypePattern.Match&gt;&#xD;
&lt;/TypePattern&gt;&#xD;
&lt;TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All"&gt;&#xD;
&lt;TypePattern.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Kind Is="Class" /&gt;&#xD;
&lt;HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/TypePattern.Match&gt;&#xD;
&lt;Entry DisplayName="Setup/Teardown Methods"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" /&gt;&#xD;
&lt;HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" /&gt;&#xD;
&lt;HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" /&gt;&#xD;
&lt;HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" /&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="All other members" /&gt;&#xD;
&lt;Entry Priority="100" DisplayName="Test Methods"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;HasAttribute Name="NUnit.Framework.TestAttribute" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;Entry.SortBy&gt;&#xD;
&lt;Name /&gt;&#xD;
&lt;/Entry.SortBy&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/TypePattern&gt;&#xD;
&lt;TypePattern DisplayName="Default Pattern"&gt;&#xD;
&lt;Group DisplayName="Fields/Properties"&gt;&#xD;
&lt;Group DisplayName="Public Fields"&gt;&#xD;
&lt;Entry DisplayName="Constant Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Public" /&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;Kind Is="Constant" /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Static Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Public" /&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Field" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Normal Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Public" /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Field" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;Entry DisplayName="Public Properties"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Public" /&gt;&#xD;
&lt;Kind Is="Property" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Group DisplayName="Internal Fields"&gt;&#xD;
&lt;Entry DisplayName="Constant Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Internal" /&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;Kind Is="Constant" /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Static Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Internal" /&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Field" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Normal Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Internal" /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Field" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;Entry DisplayName="Internal Properties"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Internal" /&gt;&#xD;
&lt;Kind Is="Property" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Group DisplayName="Protected Fields"&gt;&#xD;
&lt;Entry DisplayName="Constant Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Protected" /&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;Kind Is="Constant" /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Static Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Protected" /&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Field" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Normal Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Protected" /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Field" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;Entry DisplayName="Protected Properties"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Protected" /&gt;&#xD;
&lt;Kind Is="Property" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Group DisplayName="Private Fields"&gt;&#xD;
&lt;Entry DisplayName="Constant Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Private" /&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;Kind Is="Constant" /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Static Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Private" /&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Field" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Normal Fields"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Private" /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Readonly /&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Field" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;Entry DisplayName="Private Properties"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Private" /&gt;&#xD;
&lt;Kind Is="Property" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;Group DisplayName="Constructor/Destructor"&gt;&#xD;
&lt;Entry DisplayName="Ctor"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;Kind Is="Constructor" /&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Region Name="Disposal"&gt;&#xD;
&lt;Entry DisplayName="Dtor"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;Kind Is="Destructor" /&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Dispose()"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Public" /&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;Name Is="Dispose" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Dispose(true)"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Protected" /&gt;&#xD;
&lt;Or&gt;&#xD;
&lt;Virtual /&gt;&#xD;
&lt;Override /&gt;&#xD;
&lt;/Or&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;Name Is="Dispose" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/Region&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;Group DisplayName="Methods"&gt;&#xD;
&lt;Group DisplayName="Public"&gt;&#xD;
&lt;Entry DisplayName="Static Methods"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Public" /&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Methods"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Public" /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;Group DisplayName="Internal"&gt;&#xD;
&lt;Entry DisplayName="Static Methods"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Internal" /&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Methods"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Internal" /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;Group DisplayName="Protected"&gt;&#xD;
&lt;Entry DisplayName="Static Methods"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Protected" /&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Methods"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Protected" /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;Group DisplayName="Private"&gt;&#xD;
&lt;Entry DisplayName="Static Methods"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Private" /&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;Entry DisplayName="Methods"&gt;&#xD;
&lt;Entry.Match&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Access Is="Private" /&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;Static /&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;Kind Is="Method" /&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Entry.Match&gt;&#xD;
&lt;/Entry&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;/Group&gt;&#xD;
&lt;/TypePattern&gt;&#xD;
&lt;/Patterns&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">Copyright (c) ppy Pty Ltd &lt;contact@ppy.sh&gt;. Licensed under the MIT Licence.&#xD;
See the LICENCE file in the repository root for full licence text.&#xD;
</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=LocalConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=LocalFunctions/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"&gt;&lt;ExtraRule Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=9d1af99b_002Dbefe_002D48a4_002D9eb3_002D661384e29869/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="private methods"&gt;&lt;ElementKinds&gt;&lt;Kind Name="ASYNC_METHOD" /&gt;&lt;Kind Name="METHOD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=9ffbe43b_002Dc610_002D411b_002D9839_002D1416a146d9b0/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public" Description="internal/protected/public methods"&gt;&lt;ElementKinds&gt;&lt;Kind Name="ASYNC_METHOD" /&gt;&lt;Kind Name="METHOD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a4c2df6c_002Db202_002D48d5_002Db077_002De678cb548c25/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="private properties"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PROPERTY" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=fd562728_002Dc23d_002D417f_002Da19f_002D9d854247fbea/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public" Description="internal/protected/public properties"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PROPERTY" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FCONSTANT/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FFUNCTION/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FVARIABLE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FCLASS/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FCONSTRUCTOR/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FFUNCTION/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FGLOBAL_005FVARIABLE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLABEL/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLOCAL_005FCONSTRUCTOR/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLOCAL_005FVARIABLE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FOBJECT_005FPROPERTY_005FOF_005FFUNCTION/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FPARAMETER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FCLASS/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FENUM/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FENUM_005FMEMBER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FINTERFACE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMIXED_005FENUM/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE_005FEXPORTED/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE_005FLOCAL/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FMEMBER_005FACCESSOR/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FTYPE_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FTYPE_005FMETHOD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FMEMBER_005FACCESSOR/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FTYPE_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FTYPE_005FMETHOD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FMEMBER_005FACCESSOR/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FTYPE_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FTYPE_005FMETHOD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FTYPE_005FALIAS/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FTYPE_005FPARAMETER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FHTML_005FCONTROL/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FTAG_005FNAME/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FTAG_005FPREFIX/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=NAMESPACE_005FALIAS/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FRESOURCE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Description/@EntryValue">o!f Object Initializer: Anchor&amp;Origin</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Field/=anchor/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Field/=anchor/Expression/@EntryValue">constant("Centre")</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Field/=anchor/Order/@EntryValue">0</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Shortcut/@EntryValue">ofao</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=28A2A5FC43E07C488A4BC7430879479E/Text/@EntryValue">Anchor = Anchor.$anchor$,
Origin = Anchor.$anchor$,</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=2A3ECBA387AF6D468F6ABDA35DED325A/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=2A3ECBA387AF6D468F6ABDA35DED325A/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=2A3ECBA387AF6D468F6ABDA35DED325A/Description/@EntryValue">o!f InternalChildren = []</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=2A3ECBA387AF6D468F6ABDA35DED325A/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=2A3ECBA387AF6D468F6ABDA35DED325A/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=2A3ECBA387AF6D468F6ABDA35DED325A/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=2A3ECBA387AF6D468F6ABDA35DED325A/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=2A3ECBA387AF6D468F6ABDA35DED325A/Shortcut/@EntryValue">ofic</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=2A3ECBA387AF6D468F6ABDA35DED325A/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=2A3ECBA387AF6D468F6ABDA35DED325A/Text/@EntryValue">InternalChildren = new Drawable[]
{
$END$
};</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=62B70E4DCA5E284A9E383E16C13789C1/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=62B70E4DCA5E284A9E383E16C13789C1/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=62B70E4DCA5E284A9E383E16C13789C1/Description/@EntryValue">o!f new GridContainer { .. }</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=62B70E4DCA5E284A9E383E16C13789C1/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=62B70E4DCA5E284A9E383E16C13789C1/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=62B70E4DCA5E284A9E383E16C13789C1/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=62B70E4DCA5E284A9E383E16C13789C1/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=62B70E4DCA5E284A9E383E16C13789C1/Shortcut/@EntryValue">ofgc</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=62B70E4DCA5E284A9E383E16C13789C1/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=62B70E4DCA5E284A9E383E16C13789C1/Text/@EntryValue">new GridContainer
{
RelativeSizeAxes = Axes.Both,
Content = new[]
{
new Drawable[] { $END$ },
new Drawable[] { }
}
};</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=72BD3C3DCA42C84DA1E71F1D05A903C4/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=72BD3C3DCA42C84DA1E71F1D05A903C4/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=72BD3C3DCA42C84DA1E71F1D05A903C4/Description/@EntryValue">o!f new FillFlowContainer { .. }</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=72BD3C3DCA42C84DA1E71F1D05A903C4/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=72BD3C3DCA42C84DA1E71F1D05A903C4/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=72BD3C3DCA42C84DA1E71F1D05A903C4/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=72BD3C3DCA42C84DA1E71F1D05A903C4/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=72BD3C3DCA42C84DA1E71F1D05A903C4/Shortcut/@EntryValue">offf</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=72BD3C3DCA42C84DA1E71F1D05A903C4/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=72BD3C3DCA42C84DA1E71F1D05A903C4/Text/@EntryValue">new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
$END$
}
},</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=750A3C67E083484FAEEA0ED2382181CC/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=750A3C67E083484FAEEA0ED2382181CC/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=750A3C67E083484FAEEA0ED2382181CC/Description/@EntryValue">o!f new Container { .. }</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=750A3C67E083484FAEEA0ED2382181CC/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=750A3C67E083484FAEEA0ED2382181CC/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=750A3C67E083484FAEEA0ED2382181CC/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=750A3C67E083484FAEEA0ED2382181CC/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=750A3C67E083484FAEEA0ED2382181CC/Shortcut/@EntryValue">ofcont</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=750A3C67E083484FAEEA0ED2382181CC/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=750A3C67E083484FAEEA0ED2382181CC/Text/@EntryValue">new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
$END$
}
},</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=78D9C2B1742FD449BD69CD18437E0C07/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=78D9C2B1742FD449BD69CD18437E0C07/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=78D9C2B1742FD449BD69CD18437E0C07/Description/@EntryValue">o!f BackgroundDependencyLoader load()</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=78D9C2B1742FD449BD69CD18437E0C07/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=78D9C2B1742FD449BD69CD18437E0C07/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=78D9C2B1742FD449BD69CD18437E0C07/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=78D9C2B1742FD449BD69CD18437E0C07/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=78D9C2B1742FD449BD69CD18437E0C07/Shortcut/@EntryValue">ofbdl</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=78D9C2B1742FD449BD69CD18437E0C07/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=78D9C2B1742FD449BD69CD18437E0C07/Text/@EntryValue">[BackgroundDependencyLoader]
private void load()
{
$END$
}</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=CC879477D8841A4CBD724C2DCD249435/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=CC879477D8841A4CBD724C2DCD249435/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=CC879477D8841A4CBD724C2DCD249435/Description/@EntryValue">o!f new Box { .. }</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=CC879477D8841A4CBD724C2DCD249435/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=CC879477D8841A4CBD724C2DCD249435/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=CC879477D8841A4CBD724C2DCD249435/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=CC879477D8841A4CBD724C2DCD249435/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=CC879477D8841A4CBD724C2DCD249435/Shortcut/@EntryValue">ofbox</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=CC879477D8841A4CBD724C2DCD249435/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=CC879477D8841A4CBD724C2DCD249435/Text/@EntryValue">new Box
{
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
},</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F5B3CB743153774F99FB9FCA0FC744EE/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F5B3CB743153774F99FB9FCA0FC744EE/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F5B3CB743153774F99FB9FCA0FC744EE/Description/@EntryValue">o!f Children = []</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F5B3CB743153774F99FB9FCA0FC744EE/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F5B3CB743153774F99FB9FCA0FC744EE/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F5B3CB743153774F99FB9FCA0FC744EE/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F5B3CB743153774F99FB9FCA0FC744EE/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F5B3CB743153774F99FB9FCA0FC744EE/Shortcut/@EntryValue">ofc</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F5B3CB743153774F99FB9FCA0FC744EE/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F5B3CB743153774F99FB9FCA0FC744EE/Text/@EntryValue">Children = new Drawable[]
{
$END$
};</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Beatmap/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=beatmaps/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=beatmap_0027s/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=bindable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Catmull/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Drawables/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=gameplay/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=hitobjects/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=keymods/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kiai/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Leaderboard/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Leaderboards/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Playfield/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=resampler/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ruleset/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=rulesets/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taiko/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unranked/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -0,0 +1,25 @@
// 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 Android.App;
using Android.Content.PM;
using Android.OS;
using Android.Views;
using osu.Framework.Android;
namespace osu.Android
{
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.FullSensor, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize, HardwareAccelerated = true)]
public class OsuGameActivity : AndroidGameActivity
{
protected override Framework.Game CreateGame() => new OsuGameAndroid();
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Window.AddFlags(WindowManagerFlags.Fullscreen);
Window.AddFlags(WindowManagerFlags.KeepScreenOn);
}
}
}

View File

@ -0,0 +1,14 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using Android.App;
using osu.Game;
namespace osu.Android
{
public class OsuGameAndroid : OsuGame
{
public override Version AssemblyVersion => new Version(Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionName);
}
}

View File

@ -0,0 +1,10 @@
<?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="28" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!" android:icon="@drawable/lazer" />
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<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>
<RootNamespace>osu.Android</RootNamespace>
<AssemblyName>osu.Android</AssemblyName>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<MandroidI18n>cjk;mideast;other;rare;west</MandroidI18n>
<AndroidDexTool>d8</AndroidDexTool>
<AndroidLinkTool>r8</AndroidLinkTool>
</PropertyGroup>
<ItemGroup>
<Compile Include="OsuGameActivity.cs" />
<Compile Include="OsuGameAndroid.cs" />
</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>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -129,7 +129,7 @@ namespace osu.Desktop.Updater
Activated = () =>
{
updateManager.PrepareUpdateAsync()
.ContinueWith(_ => Schedule(() => game.GracefullyExit()));
.ContinueWith(_ => updateManager.Schedule(() => game.GracefullyExit()));
return true;
}
};

View File

@ -0,0 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using Android.App;
using Android.Content.PM;
using osu.Framework.Android;
using osu.Game.Tests;
namespace osu.Game.Rulesets.Catch.Tests.Android
{
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.SensorLandscape, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MainActivity : AndroidGameActivity
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
}
}

View File

@ -0,0 +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.Catch.Tests.Android" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!catch Test" />
</manifest>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<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>
<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>
<ItemGroup>
<Compile Include="MainActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\osu.Game.Rulesets.Catch.Tests\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
</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>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Catch.Tests.iOS
{
public static void Main(string[] args)
{
UIApplication.Main(args, null, "AppDelegate");
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
}
}
}

View File

@ -0,0 +1,160 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Tests.Visual;
using osuTK;
namespace osu.Game.Rulesets.Catch.Tests
{
public class TestSceneDrawableHitObjects : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(CatcherArea.Catcher),
typeof(DrawableCatchRuleset),
typeof(DrawableFruit),
typeof(DrawableJuiceStream),
typeof(DrawableBanana)
};
private DrawableCatchRuleset drawableRuleset;
private double playfieldTime => drawableRuleset.Playfield.Time.Current;
[BackgroundDependencyLoader]
private void load()
{
var controlPointInfo = new ControlPointInfo();
controlPointInfo.TimingPoints.Add(new TimingControlPoint());
WorkingBeatmap beatmap = CreateWorkingBeatmap(new Beatmap
{
HitObjects = new List<HitObject> { new Fruit() },
BeatmapInfo = new BeatmapInfo
{
BaseDifficulty = new BeatmapDifficulty(),
Metadata = new BeatmapMetadata
{
Artist = @"Unknown",
Title = @"You're breathtaking",
AuthorString = @"Everyone",
},
Ruleset = new CatchRuleset().RulesetInfo
},
ControlPointInfo = controlPointInfo
});
Add(new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Children = new[]
{
drawableRuleset = new DrawableCatchRuleset(new CatchRuleset(), beatmap, Array.Empty<Mod>())
}
});
AddStep("miss fruits", () => spawnFruits());
AddStep("hit fruits", () => spawnFruits(true));
AddStep("miss juicestream", () => spawnJuiceStream());
AddStep("hit juicestream", () => spawnJuiceStream(true));
AddStep("miss bananas", () => spawnBananas());
AddStep("hit bananas", () => spawnBananas(true));
}
private void spawnFruits(bool hit = false)
{
for (int i = 1; i <= 4; i++)
{
var fruit = new Fruit
{
X = getXCoords(hit),
LastInCombo = i % 4 == 0,
StartTime = playfieldTime + 800 + (200 * i)
};
fruit.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
addToPlayfield(new DrawableFruit(fruit));
}
}
private void spawnJuiceStream(bool hit = false)
{
var xCoords = getXCoords(hit);
var juice = new JuiceStream
{
X = xCoords,
StartTime = playfieldTime + 1000,
Path = new SliderPath(PathType.Linear, new[]
{
Vector2.Zero,
new Vector2(0, 200)
})
};
juice.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
if (juice.NestedHitObjects.Last() is CatchHitObject tail)
tail.LastInCombo = true; // usually the (Catch)BeatmapProcessor would do this for us when necessary
addToPlayfield(new DrawableJuiceStream(juice, drawableRuleset.CreateDrawableRepresentation));
}
private void spawnBananas(bool hit = false)
{
for (int i = 1; i <= 4; i++)
{
var banana = new Banana
{
X = getXCoords(hit),
LastInCombo = i % 4 == 0,
StartTime = playfieldTime + 800 + (200 * i)
};
banana.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
addToPlayfield(new DrawableBanana(banana));
}
}
private float getXCoords(bool hit)
{
const float x_offset = 0.2f;
float xCoords = drawableRuleset.Playfield.Width / 2;
if (drawableRuleset.Playfield is CatchPlayfield catchPlayfield)
catchPlayfield.CatcherArea.MovableCatcher.X = xCoords - x_offset;
if (hit)
xCoords -= x_offset;
else
xCoords += x_offset;
return xCoords;
}
private void addToPlayfield(DrawableCatchHitObject drawable)
{
foreach (var mod in Mods.Value.OfType<IApplicableToDrawableHitObjects>())
mod.ApplyToDrawableHitObjects(new[] { drawable });
drawableRuleset.Playfield.Add(drawable);
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Rulesets.Catch.Mods;
namespace osu.Game.Rulesets.Catch.Tests
{
public class TestSceneDrawableHitObjectsHidden : TestSceneDrawableHitObjects
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(CatchModHidden) }).ToList();
public TestSceneDrawableHitObjectsHidden()
{
Mods.Value = new[] { new CatchModHidden() };
}
}
}

View File

@ -2,7 +2,7 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -1,7 +1,11 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Catch.Mods
{
@ -9,5 +13,36 @@ namespace osu.Game.Rulesets.Catch.Mods
{
public override string Description => @"Play with fading fruits.";
public override double ScoreMultiplier => 1.06;
private const double fade_out_offset_multiplier = 0.6;
private const double fade_out_duration_multiplier = 0.44;
protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
{
if (!(drawable is DrawableCatchHitObject catchDrawable))
return;
if (catchDrawable.NestedHitObjects.Any())
{
foreach (var nestedDrawable in catchDrawable.NestedHitObjects)
{
if (nestedDrawable is DrawableCatchHitObject nestedCatchDrawable)
fadeOutHitObject(nestedCatchDrawable);
}
}
else
fadeOutHitObject(catchDrawable);
}
private void fadeOutHitObject(DrawableCatchHitObject drawable)
{
var hitObject = drawable.HitObject;
var offset = hitObject.TimePreempt * fade_out_offset_multiplier;
var duration = offset - hitObject.TimePreempt * fade_out_duration_multiplier;
using (drawable.BeginAbsoluteSequence(hitObject.StartTime - offset, true))
drawable.FadeOut(duration);
}
}
}

View File

@ -14,6 +14,8 @@ namespace osu.Game.Rulesets.Catch.Objects
public float X { get; set; }
public double TimePreempt = 1000;
public int IndexInBeatmap { get; set; }
public virtual FruitVisualRepresentation VisualRepresentation => (FruitVisualRepresentation)(ComboIndex % 4);
@ -54,6 +56,8 @@ namespace osu.Game.Rulesets.Catch.Objects
{
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450);
Scale = 1.0f - 0.7f * (difficulty.CircleSize - 5) / 5;
}

View File

@ -68,11 +68,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
AccentColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
}
private const float preempt = 1000;
protected override void UpdateState(ArmedState state)
{
using (BeginAbsoluteSequence(HitObject.StartTime - preempt))
using (BeginAbsoluteSequence(HitObject.StartTime - HitObject.TimePreempt))
this.FadeIn(200);
var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime;

View File

@ -10,3 +10,4 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Catch.Tests")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Catch.Tests.Dynamic")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Catch.Tests.iOS")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Catch.Tests.Android")]

View File

@ -0,0 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using Android.App;
using Android.Content.PM;
using osu.Framework.Android;
using osu.Game.Tests;
namespace osu.Game.Rulesets.Mania.Tests.Android
{
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.SensorLandscape, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MainActivity : AndroidGameActivity
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
}
}

View File

@ -0,0 +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="28" />
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!mania Test" />
</manifest>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<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>
<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>
<ItemGroup>
<Compile Include="MainActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\osu.Game.Rulesets.Mania.Tests\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
</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>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Mania.Tests.iOS
{
public static void Main(string[] args)
{
UIApplication.Main(args, null, "AppDelegate");
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
}
}
}

View File

@ -2,7 +2,7 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -10,3 +10,4 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Mania.Tests")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Mania.Tests.Dynamic")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Mania.Tests.iOS")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Mania.Tests.Android")]

View File

@ -0,0 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using Android.App;
using Android.Content.PM;
using osu.Framework.Android;
using osu.Game.Tests;
namespace osu.Game.Rulesets.Osu.Tests.Android
{
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.SensorLandscape, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MainActivity : AndroidGameActivity
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
}
}

View File

@ -0,0 +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="28" />
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!standard Test" />
</manifest>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<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>
<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>
<ItemGroup>
<Compile Include="MainActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\osu.Game.Rulesets.Osu.Tests\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
</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>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Osu.Tests.iOS
{
public static void Main(string[] args)
{
UIApplication.Main(args, null, "AppDelegate");
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
}
}
}

View File

@ -2,7 +2,7 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -0,0 +1,20 @@
// 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.Graphics.Sprites;
namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModDeflate : OsuModeObjectScaleTween
{
public override string Name => "Deflate";
public override string Acronym => "DF";
public override IconUsage Icon => FontAwesome.Solid.CompressArrowsAlt;
public override string Description => "Hit them at the right size!";
protected override float StartScale => 2f;
}
}

View File

@ -1,20 +1,11 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Configuration;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Mods
{
internal class OsuModGrow : Mod, IReadFromConfig, IApplicableToDrawableHitObjects
internal class OsuModGrow : OsuModeObjectScaleTween
{
public override string Name => "Grow";
@ -22,65 +13,8 @@ namespace osu.Game.Rulesets.Osu.Mods
public override IconUsage Icon => FontAwesome.Solid.ArrowsAltV;
public override ModType Type => ModType.Fun;
public override string Description => "Hit them at the right size!";
public override double ScoreMultiplier => 1;
private Bindable<bool> increaseFirstObjectVisibility = new Bindable<bool>();
public void ReadFromConfig(OsuConfigManager config)
{
increaseFirstObjectVisibility = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility);
}
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
{
foreach (var drawable in drawables.Skip(increaseFirstObjectVisibility.Value ? 1 : 0))
{
switch (drawable)
{
case DrawableSpinner _:
continue;
default:
drawable.ApplyCustomUpdateState += ApplyCustomState;
break;
}
}
}
protected virtual void ApplyCustomState(DrawableHitObject drawable, ArmedState state)
{
var h = (OsuHitObject)drawable.HitObject;
// apply grow effect
switch (drawable)
{
case DrawableSliderHead _:
case DrawableSliderTail _:
// special cases we should *not* be scaling.
break;
case DrawableSlider _:
case DrawableHitCircle _:
{
using (drawable.BeginAbsoluteSequence(h.StartTime - h.TimePreempt, true))
drawable.ScaleTo(0.5f).Then().ScaleTo(1, h.TimePreempt, Easing.OutSine);
break;
}
}
// remove approach circles
switch (drawable)
{
case DrawableHitCircle circle:
// we don't want to see the approach circle
using (circle.BeginAbsoluteSequence(h.StartTime - h.TimePreempt, true))
circle.ApproachCircle.Hide();
break;
}
}
protected override float StartScale => 0.5f;
}
}

View File

@ -13,13 +13,11 @@ using static osu.Game.Input.Handlers.ReplayInputHandler;
namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModRelax : ModRelax, IApplicableFailOverride, IUpdatableByPlayfield, IApplicableToDrawableRuleset<OsuHitObject>
public class OsuModRelax : ModRelax, IUpdatableByPlayfield, IApplicableToDrawableRuleset<OsuHitObject>
{
public override string Description => @"You don't need to click. Give your clicking/tapping fingers a break from the heat of things.";
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
public bool AllowFail => false;
public void Update(Playfield playfield)
{
bool requiresHold = false;

View File

@ -0,0 +1,84 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Configuration;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Mods
{
/// <summary>
/// Adjusts the size of hit objects during their fade in animation.
/// </summary>
public abstract class OsuModeObjectScaleTween : Mod, IReadFromConfig, IApplicableToDrawableHitObjects
{
public override ModType Type => ModType.Fun;
public override double ScoreMultiplier => 1;
protected virtual float StartScale => 1;
protected virtual float EndScale => 1;
private Bindable<bool> increaseFirstObjectVisibility = new Bindable<bool>();
public void ReadFromConfig(OsuConfigManager config)
{
increaseFirstObjectVisibility = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility);
}
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
{
foreach (var drawable in drawables.Skip(increaseFirstObjectVisibility.Value ? 1 : 0))
{
switch (drawable)
{
case DrawableSpinner _:
continue;
default:
drawable.ApplyCustomUpdateState += ApplyCustomState;
break;
}
}
}
protected virtual void ApplyCustomState(DrawableHitObject drawable, ArmedState state)
{
var h = (OsuHitObject)drawable.HitObject;
// apply grow effect
switch (drawable)
{
case DrawableSliderHead _:
case DrawableSliderTail _:
// special cases we should *not* be scaling.
break;
case DrawableSlider _:
case DrawableHitCircle _:
{
using (drawable.BeginAbsoluteSequence(h.StartTime - h.TimePreempt, true))
drawable.ScaleTo(StartScale).Then().ScaleTo(EndScale, h.TimePreempt, Easing.OutSine);
break;
}
}
// remove approach circles
switch (drawable)
{
case DrawableHitCircle circle:
// we don't want to see the approach circle
using (circle.BeginAbsoluteSequence(h.StartTime - h.TimePreempt, true))
circle.ApproachCircle.Hide();
break;
}
}
}
}

View File

@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Osu
{
new OsuModTransform(),
new OsuModWiggle(),
new OsuModGrow(),
new MultiMod(new OsuModGrow(), new OsuModDeflate()),
new MultiMod(new ModWindUp<OsuHitObject>(), new ModWindDown<OsuHitObject>()),
};

View File

@ -10,3 +10,4 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Osu.Tests")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Osu.Tests.Dynamic")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Osu.Tests.iOS")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Osu.Tests.Android")]

View File

@ -0,0 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using Android.App;
using Android.Content.PM;
using osu.Framework.Android;
using osu.Game.Tests;
namespace osu.Game.Rulesets.Taiko.Tests.Android
{
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.SensorLandscape, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MainActivity : AndroidGameActivity
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
}
}

View File

@ -0,0 +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="28" />
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!taiko Test" />
</manifest>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<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>
<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>
<ItemGroup>
<Compile Include="MainActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\osu.Game.Rulesets.Taiko.Tests\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
</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>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.iOS
{
public static void Main(string[] args)
{
UIApplication.Main(args, null, "AppDelegate");
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
}
}
}

View File

@ -2,7 +2,7 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -10,3 +10,4 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Taiko.Tests")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Taiko.Tests.Dynamic")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Taiko.Tests.iOS")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Taiko.Tests.Android")]

View File

@ -0,0 +1,15 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using Android.App;
using Android.Content.PM;
using osu.Framework.Android;
namespace osu.Game.Tests.Android
{
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.SensorLandscape, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize, HardwareAccelerated = true)]
public class MainActivity : AndroidGameActivity
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
}
}

View File

@ -0,0 +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="28" />
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!visual Test" />
</manifest>

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<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>
<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>
<ItemGroup>
<Compile Include="..\osu.Game.Tests\**\Beatmaps\**\*.cs">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<Compile Include="..\osu.Game.Tests\**\Chat\**\*.cs">
<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>
</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>
<PackageReference Include="DeepEqual">
<Version>2.0.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@ -9,7 +9,7 @@ namespace osu.Game.Tests.iOS
{
public static void Main(string[] args)
{
UIApplication.Main(args, null, "AppDelegate");
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
}
}
}

View File

@ -9,6 +9,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.MathUtils;
using osu.Framework.Screens;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
@ -16,12 +17,13 @@ using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Screens;
using osu.Game.Screens.Play;
using osu.Game.Screens.Play.PlayerSettings;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestScenePlayerLoader : ManualInputManagerTestScene
{
private PlayerLoader loader;
private TestPlayerLoader loader;
private OsuScreenStack stack;
[SetUp]
@ -31,19 +33,29 @@ namespace osu.Game.Tests.Visual.Gameplay
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
});
[Test]
public void TestBlockLoadViaMouseMovement()
{
AddStep("load dummy beatmap", () => stack.Push(loader = new TestPlayerLoader(() => new TestPlayer(false, false))));
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
AddRepeatStep("move mouse", () => InputManager.MoveMouseTo(loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft + (loader.VisualSettings.ScreenSpaceDrawQuad.BottomRight - loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft) * RNG.NextSingle()), 20);
AddAssert("loader still active", () => loader.IsCurrentScreen());
AddUntilStep("loads after idle", () => !loader.IsCurrentScreen());
}
[Test]
public void TestLoadContinuation()
{
Player player = null;
SlowLoadPlayer slowPlayer = null;
AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => player = new TestPlayer(false, false))));
AddStep("load dummy beatmap", () => stack.Push(loader = new TestPlayerLoader(() => player = new TestPlayer(false, false))));
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen());
AddStep("load slow dummy beatmap", () =>
{
stack.Push(loader = new PlayerLoader(() => slowPlayer = new SlowLoadPlayer(false, false)));
stack.Push(loader = new TestPlayerLoader(() => slowPlayer = new SlowLoadPlayer(false, false)));
Scheduler.AddDelayed(() => slowPlayer.AllowLoad.Set(), 5000);
});
@ -61,7 +73,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("load player", () =>
{
Mods.Value = new[] { gameMod = new TestMod() };
stack.Push(loader = new PlayerLoader(() => player = new TestPlayer()));
stack.Push(loader = new TestPlayerLoader(() => player = new TestPlayer()));
});
AddUntilStep("wait for loader to become current", () => loader.IsCurrentScreen());
@ -85,6 +97,16 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("player mods applied", () => playerMod2.Applied);
}
private class TestPlayerLoader : PlayerLoader
{
public new VisualSettings VisualSettings => base.VisualSettings;
public TestPlayerLoader(Func<Player> createPlayer)
: base(createPlayer)
{
}
}
private class TestMod : Mod, IApplicableToScoreProcessor
{
public override string Name => string.Empty;

View File

@ -0,0 +1,76 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Game.Online;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Osu;
using osu.Game.Scoring;
using osu.Game.Screens.Play;
using osu.Game.Users;
using osuTK;
using System;
using System.Collections.Generic;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestSceneReplayDownloadButton : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(ReplayDownloadButton)
};
private TestReplayDownloadButton downloadButton;
public TestSceneReplayDownloadButton()
{
createButton(true);
AddStep(@"downloading state", () => downloadButton.SetDownloadState(DownloadState.Downloading));
AddStep(@"locally available state", () => downloadButton.SetDownloadState(DownloadState.LocallyAvailable));
AddStep(@"not downloaded state", () => downloadButton.SetDownloadState(DownloadState.NotDownloaded));
createButton(false);
}
private void createButton(bool withReplay)
{
AddStep(withReplay ? @"create button with replay" : "create button without replay", () =>
{
Child = downloadButton = new TestReplayDownloadButton(getScoreInfo(withReplay))
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(80, 40),
};
});
}
private ScoreInfo getScoreInfo(bool replayAvailable)
{
return new APILegacyScoreInfo
{
ID = 1,
OnlineScoreID = 2553163309,
Ruleset = new OsuRuleset().RulesetInfo,
Replay = replayAvailable,
User = new User
{
Id = 39828,
Username = @"WubWoofWolf",
}
};
}
private class TestReplayDownloadButton : ReplayDownloadButton
{
public void SetDownloadState(DownloadState state) => State.Value = state;
public TestReplayDownloadButton(ScoreInfo score)
: base(score)
{
}
}
}
}

View File

@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Online
typeof(BasicStats),
typeof(BeatmapPicker),
typeof(Details),
typeof(DownloadButton),
typeof(HeaderDownloadButton),
typeof(FavouriteButton),
typeof(Header),
typeof(HeaderButton),
@ -108,6 +108,7 @@ namespace osu.Game.Tests.Visual.Online
{
StarDifficulty = 9.99,
Version = @"TEST",
Length = 456000,
Ruleset = maniaRuleset,
BaseDifficulty = new BeatmapDifficulty
{
@ -118,7 +119,6 @@ namespace osu.Game.Tests.Visual.Online
},
OnlineInfo = new BeatmapOnlineInfo
{
Length = 456000,
CircleCount = 111,
SliderCount = 12,
PlayCount = 222,
@ -181,6 +181,7 @@ namespace osu.Game.Tests.Visual.Online
{
StarDifficulty = 5.67,
Version = @"ANOTHER TEST",
Length = 123000,
Ruleset = taikoRuleset,
BaseDifficulty = new BeatmapDifficulty
{
@ -191,7 +192,6 @@ namespace osu.Game.Tests.Visual.Online
},
OnlineInfo = new BeatmapOnlineInfo
{
Length = 123000,
CircleCount = 123,
SliderCount = 45,
PlayCount = 567,

View File

@ -24,6 +24,7 @@ namespace osu.Game.Tests.Visual.Online
typeof(ChangelogListing),
typeof(ChangelogSingleBuild),
typeof(ChangelogBuild),
typeof(Comments),
};
protected override void LoadComplete()

View File

@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual.Online
});
channelTabControl.OnRequestLeave += channel => channelTabControl.RemoveChannel(channel);
channelTabControl.Current.ValueChanged += channel => currentText.Text = "Currently selected channel: " + channel.NewValue.ToString();
channelTabControl.Current.ValueChanged += channel => currentText.Text = "Currently selected channel: " + channel.NewValue;
AddStep("Add random private channel", addRandomPrivateChannel);
AddAssert("There is only one channels", () => channelTabControl.Items.Count() == 2);

View File

@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual.Online
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(DownloadButton)
typeof(PanelDownloadButton)
};
private TestDownloadButton downloadButton;
@ -143,7 +143,7 @@ namespace osu.Game.Tests.Visual.Online
return beatmap;
}
private class TestDownloadButton : DownloadButton
private class TestDownloadButton : PanelDownloadButton
{
public new bool DownloadEnabled => base.DownloadEnabled;

View File

@ -3,10 +3,8 @@
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Game.Beatmaps;
using osu.Game.Overlays;
using osu.Game.Rulesets;
namespace osu.Game.Tests.Visual.Online
{
@ -14,7 +12,6 @@ namespace osu.Game.Tests.Visual.Online
public class TestSceneDirectOverlay : OsuTestScene
{
private DirectOverlay direct;
private RulesetStore rulesets;
protected override void LoadComplete()
{
@ -25,18 +22,11 @@ namespace osu.Game.Tests.Visual.Online
AddStep(@"toggle", direct.ToggleVisibility);
AddStep(@"result counts", () => direct.ResultAmounts = new DirectOverlay.ResultCounts(1, 4, 13));
}
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
this.rulesets = rulesets;
AddStep(@"trigger disabled", () => Ruleset.Disabled = !Ruleset.Disabled);
}
private void newBeatmaps()
{
var ruleset = rulesets.GetRuleset(0);
direct.BeatmapSets = new[]
{
new BeatmapSetInfo
@ -65,7 +55,7 @@ namespace osu.Game.Tests.Visual.Online
{
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 5.35f,
Metadata = new BeatmapMetadata(),
},
@ -97,7 +87,7 @@ namespace osu.Game.Tests.Visual.Online
{
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 5.81f,
Metadata = new BeatmapMetadata(),
},
@ -129,23 +119,23 @@ namespace osu.Game.Tests.Visual.Online
{
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 0.9f,
Metadata = new BeatmapMetadata(),
},
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 1.1f,
},
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 2.02f,
},
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 3.49f,
},
},
@ -176,43 +166,43 @@ namespace osu.Game.Tests.Visual.Online
{
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 1.26f,
Metadata = new BeatmapMetadata(),
},
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 2.01f,
},
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 2.87f,
},
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 3.76f,
},
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 3.93f,
},
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 4.37f,
},
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 5.13f,
},
new BeatmapInfo
{
Ruleset = ruleset,
Ruleset = Ruleset.Value,
StarDifficulty = 5.42f,
},
},

View File

@ -3,19 +3,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.MathUtils;
using osu.Game.Graphics;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.BeatmapSet.Scores;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Users;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Online
{
@ -30,11 +29,9 @@ namespace osu.Game.Tests.Visual.Online
typeof(ScoreTableRowBackground),
};
private readonly Box background;
public TestSceneScoresContainer()
{
ScoresContainer scoresContainer;
TestScoresContainer scoresContainer;
Child = new Container
{
@ -44,108 +41,137 @@ namespace osu.Game.Tests.Visual.Online
Width = 0.8f,
Children = new Drawable[]
{
background = new Box { RelativeSizeAxes = Axes.Both },
scoresContainer = new ScoresContainer(),
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
scoresContainer = new TestScoresContainer(),
}
};
var scores = new List<ScoreInfo>
var allScores = new APILegacyScores
{
new ScoreInfo
Scores = new List<APILegacyScoreInfo>
{
User = new User
new APILegacyScoreInfo
{
Id = 6602580,
Username = @"waaiiru",
Country = new Country
User = new User
{
FullName = @"Spain",
FlagName = @"ES",
Id = 6602580,
Username = @"waaiiru",
Country = new Country
{
FullName = @"Spain",
FlagName = @"ES",
},
},
},
Mods = new Mod[]
{
new OsuModDoubleTime(),
new OsuModHidden(),
new OsuModFlashlight(),
new OsuModHardRock(),
},
Rank = ScoreRank.XH,
PP = 200,
MaxCombo = 1234,
TotalScore = 1234567890,
Accuracy = 1,
},
new ScoreInfo
{
User = new User
{
Id = 4608074,
Username = @"Skycries",
Country = new Country
Mods = new Mod[]
{
FullName = @"Brazil",
FlagName = @"BR",
new OsuModDoubleTime(),
new OsuModHidden(),
new OsuModFlashlight(),
new OsuModHardRock(),
},
Rank = ScoreRank.XH,
PP = 200,
MaxCombo = 1234,
TotalScore = 1234567890,
Accuracy = 1,
},
Mods = new Mod[]
new APILegacyScoreInfo
{
new OsuModDoubleTime(),
new OsuModHidden(),
new OsuModFlashlight(),
},
Rank = ScoreRank.S,
PP = 190,
MaxCombo = 1234,
TotalScore = 1234789,
Accuracy = 0.9997,
},
new ScoreInfo
{
User = new User
{
Id = 1014222,
Username = @"eLy",
Country = new Country
User = new User
{
FullName = @"Japan",
FlagName = @"JP",
Id = 4608074,
Username = @"Skycries",
Country = new Country
{
FullName = @"Brazil",
FlagName = @"BR",
},
},
},
Mods = new Mod[]
{
new OsuModDoubleTime(),
new OsuModHidden(),
},
Rank = ScoreRank.B,
PP = 180,
MaxCombo = 1234,
TotalScore = 12345678,
Accuracy = 0.9854,
},
new ScoreInfo
{
User = new User
{
Id = 1541390,
Username = @"Toukai",
Country = new Country
Mods = new Mod[]
{
FullName = @"Canada",
FlagName = @"CA",
new OsuModDoubleTime(),
new OsuModHidden(),
new OsuModFlashlight(),
},
Rank = ScoreRank.S,
PP = 190,
MaxCombo = 1234,
TotalScore = 1234789,
Accuracy = 0.9997,
},
Mods = new Mod[]
new APILegacyScoreInfo
{
new OsuModDoubleTime(),
User = new User
{
Id = 1014222,
Username = @"eLy",
Country = new Country
{
FullName = @"Japan",
FlagName = @"JP",
},
},
Mods = new Mod[]
{
new OsuModDoubleTime(),
new OsuModHidden(),
},
Rank = ScoreRank.B,
PP = 180,
MaxCombo = 1234,
TotalScore = 12345678,
Accuracy = 0.9854,
},
Rank = ScoreRank.C,
PP = 170,
MaxCombo = 1234,
TotalScore = 1234567,
Accuracy = 0.8765,
},
new ScoreInfo
new APILegacyScoreInfo
{
User = new User
{
Id = 1541390,
Username = @"Toukai",
Country = new Country
{
FullName = @"Canada",
FlagName = @"CA",
},
},
Mods = new Mod[]
{
new OsuModDoubleTime(),
},
Rank = ScoreRank.C,
PP = 170,
MaxCombo = 1234,
TotalScore = 1234567,
Accuracy = 0.8765,
},
new APILegacyScoreInfo
{
User = new User
{
Id = 7151382,
Username = @"Mayuri Hana",
Country = new Country
{
FullName = @"Thailand",
FlagName = @"TH",
},
},
Rank = ScoreRank.D,
PP = 160,
MaxCombo = 1234,
TotalScore = 123456,
Accuracy = 0.6543,
},
}
};
var myBestScore = new APILegacyUserTopScoreInfo
{
Score = new APILegacyScoreInfo
{
User = new User
{
@ -163,9 +189,42 @@ namespace osu.Game.Tests.Visual.Online
TotalScore = 123456,
Accuracy = 0.6543,
},
Position = 1337,
};
foreach (var s in scores)
var oneScore = new APILegacyScores
{
Scores = new List<APILegacyScoreInfo>
{
new APILegacyScoreInfo
{
User = new User
{
Id = 6602580,
Username = @"waaiiru",
Country = new Country
{
FullName = @"Spain",
FlagName = @"ES",
},
},
Mods = new Mod[]
{
new OsuModDoubleTime(),
new OsuModHidden(),
new OsuModFlashlight(),
new OsuModHardRock(),
},
Rank = ScoreRank.XH,
PP = 200,
MaxCombo = 1234,
TotalScore = 1234567890,
Accuracy = 1,
}
}
};
foreach (var s in allScores.Scores)
{
s.Statistics.Add(HitResult.Great, RNG.Next(2000));
s.Statistics.Add(HitResult.Good, RNG.Next(2000));
@ -173,15 +232,26 @@ namespace osu.Game.Tests.Visual.Online
s.Statistics.Add(HitResult.Miss, RNG.Next(2000));
}
AddStep("Load all scores", () => scoresContainer.Scores = scores);
AddStep("Load all scores", () =>
{
allScores.UserScore = null;
scoresContainer.Scores = allScores;
});
AddStep("Load null scores", () => scoresContainer.Scores = null);
AddStep("Load only one score", () => scoresContainer.Scores = new[] { scores.First() });
AddStep("Load only one score", () => scoresContainer.Scores = oneScore);
AddStep("Load scores with my best", () =>
{
allScores.UserScore = myBestScore;
scoresContainer.Scores = allScores;
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private class TestScoresContainer : ScoresContainer
{
background.Colour = colours.Gray2;
public new APILegacyScores Scores
{
set => base.Scores = value;
}
}
}
}

View File

@ -4,12 +4,9 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Online.Leaderboards;
using osu.Game.Rulesets;
using osu.Game.Scoring;
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Users;
@ -27,8 +24,6 @@ namespace osu.Game.Tests.Visual.SongSelect
typeof(RetrievalFailurePlaceholder),
};
private RulesetStore rulesets;
private readonly FailableLeaderboard leaderboard;
public TestSceneLeaderboard()
@ -47,13 +42,8 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"No supporter", () => leaderboard.SetRetrievalState(PlaceholderState.NotSupporter));
AddStep(@"Not logged in", () => leaderboard.SetRetrievalState(PlaceholderState.NotLoggedIn));
AddStep(@"Unavailable", () => leaderboard.SetRetrievalState(PlaceholderState.Unavailable));
AddStep(@"Real beatmap", realBeatmap);
}
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
this.rulesets = rulesets;
foreach (BeatmapSetOnlineStatus status in Enum.GetValues(typeof(BeatmapSetOnlineStatus)))
AddStep($"{status} beatmap", () => showBeatmapWithStatus(status));
}
private void newScores()
@ -245,34 +235,12 @@ namespace osu.Game.Tests.Visual.SongSelect
leaderboard.Scores = scores;
}
private void realBeatmap()
private void showBeatmapWithStatus(BeatmapSetOnlineStatus status)
{
leaderboard.Beatmap = new BeatmapInfo
{
StarDifficulty = 1.36,
Version = @"BASIC",
OnlineBeatmapID = 1113057,
Ruleset = rulesets.GetRuleset(0),
BaseDifficulty = new BeatmapDifficulty
{
CircleSize = 4,
DrainRate = 6.5f,
OverallDifficulty = 6.5f,
ApproachRate = 5,
},
OnlineInfo = new BeatmapOnlineInfo
{
Length = 115000,
CircleCount = 265,
SliderCount = 71,
PlayCount = 47906,
PassCount = 19899,
},
Metrics = new BeatmapMetrics
{
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(),
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(),
},
Status = status,
};
}

View File

@ -133,6 +133,9 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; });
AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; });
AddStep(@"Sort by Author", delegate { songSelect.FilterControl.Sort = SortMode.Author; });
AddStep(@"Sort by DateAdded", delegate { songSelect.FilterControl.Sort = SortMode.DateAdded; });
AddStep(@"Sort by BPM", delegate { songSelect.FilterControl.Sort = SortMode.BPM; });
AddStep(@"Sort by Length", delegate { songSelect.FilterControl.Sort = SortMode.Length; });
AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; });
}
@ -265,16 +268,21 @@ namespace osu.Game.Tests.Visual.SongSelect
{
int beatmapId = setId * 10 + i;
int length = RNG.Next(30000, 200000);
double bpm = RNG.NextSingle(80, 200);
beatmaps.Add(new BeatmapInfo
{
Ruleset = getRuleset(),
OnlineBeatmapID = beatmapId,
Path = "normal.osu",
Version = $"{beatmapId}",
Version = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})",
Length = length,
BPM = bpm,
BaseDifficulty = new BeatmapDifficulty
{
OverallDifficulty = 3.5f,
}
},
});
}
@ -286,10 +294,11 @@ namespace osu.Game.Tests.Visual.SongSelect
{
// Create random metadata, then we can check if sorting works based on these
Artist = "Some Artist " + RNG.Next(0, 9),
Title = $"Some Song (set id {setId})",
Title = $"Some Song (set id {setId}, max bpm {beatmaps.Max(b => b.BPM):0.#})",
AuthorString = "Some Guy " + RNG.Next(0, 9),
},
Beatmaps = beatmaps
Beatmaps = beatmaps,
DateAdded = DateTimeOffset.UtcNow,
};
}
}

View File

@ -14,8 +14,6 @@ namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneBackButton : OsuTestScene
{
private readonly BackButton button;
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(TwoLayerButton)
@ -23,6 +21,8 @@ namespace osu.Game.Tests.Visual.UserInterface
public TestSceneBackButton()
{
BackButton button;
Child = new Container
{
Anchor = Anchor.Centre,
@ -40,11 +40,12 @@ namespace osu.Game.Tests.Visual.UserInterface
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Action = () => button.Hide(),
}
}
};
button.Action = () => button.Hide();
AddStep("show button", () => button.Show());
AddStep("hide button", () => button.Hide());
}

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Shapes;
using osu.Game.Screens.Menu;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual.UserInterface
@ -23,11 +24,12 @@ namespace osu.Game.Tests.Visual.UserInterface
typeof(Button)
};
public TestSceneButtonSystem()
{
OsuLogo logo;
ButtonSystem buttons;
private OsuLogo logo;
private ButtonSystem buttons;
[SetUp]
public void SetUp() => Schedule(() =>
{
Children = new Drawable[]
{
new Box
@ -36,13 +38,47 @@ namespace osu.Game.Tests.Visual.UserInterface
RelativeSizeAxes = Axes.Both,
},
buttons = new ButtonSystem(),
logo = new OsuLogo { RelativePositionAxes = Axes.Both }
logo = new OsuLogo
{
RelativePositionAxes = Axes.Both,
Position = new Vector2(0.5f)
}
};
buttons.SetOsuLogo(logo);
});
[Test]
public void TestAllStates()
{
foreach (var s in Enum.GetValues(typeof(ButtonSystemState)).OfType<ButtonSystemState>().Skip(1))
AddStep($"State to {s}", () => buttons.State = s);
AddStep("Enter mode", performEnterMode);
AddStep("Return to menu", () =>
{
buttons.State = ButtonSystemState.Play;
buttons.FadeIn(MainMenu.FADE_IN_DURATION, Easing.OutQuint);
buttons.MoveTo(new Vector2(0), MainMenu.FADE_IN_DURATION, Easing.OutQuint);
logo.FadeColour(Color4.White, 100, Easing.OutQuint);
logo.FadeIn(100, Easing.OutQuint);
});
}
[Test]
public void TestSmoothExit()
{
AddStep("Enter mode", performEnterMode);
}
private void performEnterMode()
{
buttons.State = ButtonSystemState.EnteringMode;
buttons.FadeOut(MainMenu.FADE_OUT_DURATION, Easing.InSine);
buttons.MoveTo(new Vector2(-800, 0), MainMenu.FADE_OUT_DURATION, Easing.InSine);
logo.FadeOut(300, Easing.InSine)
.ScaleTo(0.2f, 300, Easing.InSine);
}
}
}

View File

@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual.UserInterface
},
};
breadcrumbs.Current.ValueChanged += screen => titleText.Text = $"Changed to {screen.NewValue.ToString()}";
breadcrumbs.Current.ValueChanged += screen => titleText.Text = $"Changed to {screen.NewValue}";
breadcrumbs.Current.TriggerChange();
waitForCurrent();

View File

@ -30,9 +30,9 @@ namespace osu.Game.Tests
trackStore = audioManager.GetTrackStore(reader);
}
public override void Dispose()
protected override void Dispose(bool isDisposing)
{
base.Dispose();
base.Dispose(isDisposing);
stream?.Dispose();
reader?.Dispose();
trackStore?.Dispose();

View File

@ -3,7 +3,7 @@
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="DeepEqual" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />

View File

@ -5,9 +5,9 @@
</PropertyGroup>
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
</ItemGroup>
<PropertyGroup Label="Project">
<OutputType>WinExe</OutputType>

View File

@ -159,7 +159,7 @@ namespace osu.Game.Tournament.Components
}
var bpm = beatmap.BeatmapSet.OnlineInfo.BPM;
var length = beatmap.OnlineInfo.Length;
var length = beatmap.Length;
string hardRockExtra = "";
string srExtra = "";
@ -180,7 +180,7 @@ namespace osu.Game.Tournament.Components
panelContents.Children = new Drawable[]
{
new DiffPiece(("Length", TimeSpan.FromSeconds(length).ToString(@"mm\:ss")))
new DiffPiece(("Length", TimeSpan.FromMilliseconds(length).ToString(@"mm\:ss")))
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.BottomLeft,

View File

@ -51,6 +51,16 @@ namespace osu.Game.Beatmaps
[NotMapped]
public BeatmapOnlineInfo OnlineInfo { get; set; }
/// <summary>
/// The playable length in milliseconds of this beatmap.
/// </summary>
public double Length { get; set; }
/// <summary>
/// The most common BPM of this beatmap.
/// </summary>
public double BPM { get; set; }
public string Path { get; set; }
[JsonProperty("file_sha2")]

View File

@ -13,6 +13,7 @@ using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Textures;
using osu.Framework.Lists;
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Framework.Threading;
@ -22,6 +23,7 @@ using osu.Game.IO.Archives;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects.Types;
namespace osu.Game.Beatmaps
{
@ -81,6 +83,8 @@ namespace osu.Game.Beatmaps
protected override ArchiveDownloadRequest<BeatmapSetInfo> CreateDownloadRequest(BeatmapSetInfo set, bool minimiseDownloadSize) =>
new DownloadBeatmapSetRequest(set, minimiseDownloadSize);
protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path)?.ToLowerInvariant() == ".osz";
protected override Task Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive, CancellationToken cancellationToken = default)
{
if (archive != null)
@ -159,6 +163,8 @@ namespace osu.Game.Beatmaps
/// <param name="beatmap">The beatmap difficulty to restore.</param>
public void Restore(BeatmapInfo beatmap) => beatmaps.Restore(beatmap);
private readonly WeakList<WorkingBeatmap> workingCache = new WeakList<WorkingBeatmap>();
/// <summary>
/// Retrieve a <see cref="WorkingBeatmap"/> instance for the provided <see cref="BeatmapInfo"/>
/// </summary>
@ -173,14 +179,22 @@ namespace osu.Game.Beatmaps
if (beatmapInfo?.BeatmapSet == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo)
return DefaultBeatmap;
if (beatmapInfo.Metadata == null)
beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata;
lock (workingCache)
{
var working = workingCache.FirstOrDefault(w => w.BeatmapInfo?.ID == beatmapInfo.ID);
WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(Files.Store, new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager);
if (working == null)
{
if (beatmapInfo.Metadata == null)
beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata;
previous?.TransferTo(working);
workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store,
new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager));
}
return working;
previous?.TransferTo(working);
return working;
}
}
/// <summary>
@ -288,6 +302,8 @@ namespace osu.Game.Beatmaps
beatmap.BeatmapInfo.Ruleset = ruleset;
// TODO: this should be done in a better place once we actually need to dynamically update it.
beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating ?? 0;
beatmap.BeatmapInfo.Length = calculateLength(beatmap);
beatmap.BeatmapInfo.BPM = beatmap.ControlPointInfo.BPMMode;
beatmapInfos.Add(beatmap.BeatmapInfo);
}
@ -296,6 +312,19 @@ namespace osu.Game.Beatmaps
return beatmapInfos;
}
private double calculateLength(IBeatmap b)
{
if (!b.HitObjects.Any())
return 0;
var lastObject = b.HitObjects.Last();
double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime;
double startTime = b.HitObjects.First().StartTime;
return endTime - startTime;
}
/// <summary>
/// A dummy WorkingBeatmap for the purpose of retrieving a beatmap for star difficulty calculation.
/// </summary>

View File

@ -8,11 +8,6 @@ namespace osu.Game.Beatmaps
/// </summary>
public class BeatmapOnlineInfo
{
/// <summary>
/// The length in milliseconds of this beatmap's song.
/// </summary>
public double Length { get; set; }
/// <summary>
/// The amount of circles in this beatmap.
/// </summary>

View File

@ -35,8 +35,21 @@ namespace osu.Game.Beatmaps
[NotMapped]
public BeatmapSetMetrics Metrics { get; set; }
/// <summary>
/// The maximum star difficulty of all beatmaps in this set.
/// </summary>
public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarDifficulty) ?? 0;
/// <summary>
/// The maximum playable length in milliseconds of all beatmaps in this set.
/// </summary>
public double MaxLength => Beatmaps?.Max(b => b.Length) ?? 0;
/// <summary>
/// The maximum BPM of all beatmaps in this set.
/// </summary>
public double MaxBPM => Beatmaps?.Max(b => b.BPM) ?? 0;
[NotMapped]
public bool DeletePending { get; set; }

View File

@ -35,15 +35,15 @@ namespace osu.Game.Beatmaps.Drawables
protected override DelayedLoadWrapper CreateDelayedLoadWrapper(Func<Drawable> createContentFunc, double timeBeforeLoad)
=> new DelayedLoadUnloadWrapper(createContentFunc, timeBeforeLoad, UnloadDelay);
protected override double TransformDuration => 400;
protected override Drawable CreateDrawable(BeatmapInfo model)
{
Drawable drawable = getDrawableForModel(model);
var drawable = getDrawableForModel(model);
drawable.RelativeSizeAxes = Axes.Both;
drawable.Anchor = Anchor.Centre;
drawable.Origin = Anchor.Centre;
drawable.FillMode = FillMode.Fill;
drawable.OnLoadComplete += d => d.FadeInFromZero(400);
return drawable;
}

View File

@ -11,7 +11,9 @@ using osu.Framework.IO.File;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Audio;
using osu.Framework.Statistics;
using osu.Game.IO.Serialization;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
@ -31,6 +33,8 @@ namespace osu.Game.Beatmaps
protected AudioManager AudioManager { get; }
private static readonly GlobalStatistic<int> total_count = GlobalStatistics.Get<int>(nameof(Beatmaps), $"Total {nameof(WorkingBeatmap)}s");
protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager)
{
AudioManager = audioManager;
@ -38,24 +42,13 @@ namespace osu.Game.Beatmaps
BeatmapSetInfo = beatmapInfo.BeatmapSet;
Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
beatmap = new RecyclableLazy<IBeatmap>(() =>
{
var b = GetBeatmap() ?? new Beatmap();
// The original beatmap version needs to be preserved as the database doesn't contain it
BeatmapInfo.BeatmapVersion = b.BeatmapInfo.BeatmapVersion;
// Use the database-backed info for more up-to-date values (beatmap id, ranked status, etc)
b.BeatmapInfo = BeatmapInfo;
return b;
});
track = new RecyclableLazy<Track>(() => GetTrack() ?? GetVirtualTrack());
background = new RecyclableLazy<Texture>(GetBackground, BackgroundStillValid);
waveform = new RecyclableLazy<Waveform>(GetWaveform);
storyboard = new RecyclableLazy<Storyboard>(GetStoryboard);
skin = new RecyclableLazy<Skin>(GetSkin);
total_count.Value++;
}
protected virtual Track GetVirtualTrack()
@ -153,10 +146,40 @@ namespace osu.Game.Beatmaps
public override string ToString() => BeatmapInfo.ToString();
public bool BeatmapLoaded => beatmap.IsResultAvailable;
public IBeatmap Beatmap => beatmap.Value;
public bool BeatmapLoaded => beatmapLoadTask?.IsCompleted ?? false;
public Task<IBeatmap> LoadBeatmapAsync() => (beatmapLoadTask ?? (beatmapLoadTask = Task.Factory.StartNew(() =>
{
// Todo: Handle cancellation during beatmap parsing
var b = GetBeatmap() ?? new Beatmap();
// The original beatmap version needs to be preserved as the database doesn't contain it
BeatmapInfo.BeatmapVersion = b.BeatmapInfo.BeatmapVersion;
// Use the database-backed info for more up-to-date values (beatmap id, ranked status, etc)
b.BeatmapInfo = BeatmapInfo;
return b;
}, beatmapCancellation.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)));
public IBeatmap Beatmap
{
get
{
try
{
return LoadBeatmapAsync().Result;
}
catch (TaskCanceledException)
{
return null;
}
}
}
private readonly CancellationTokenSource beatmapCancellation = new CancellationTokenSource();
protected abstract IBeatmap GetBeatmap();
private readonly RecyclableLazy<IBeatmap> beatmap;
private Task<IBeatmap> beatmapLoadTask;
public bool BackgroundLoaded => background.IsResultAvailable;
public Texture Background => background.Value;
@ -195,20 +218,46 @@ namespace osu.Game.Beatmaps
other.track = track;
}
public virtual void Dispose()
{
background.Recycle();
waveform.Recycle();
storyboard.Recycle();
skin.Recycle();
}
/// <summary>
/// Eagerly dispose of the audio track associated with this <see cref="WorkingBeatmap"/> (if any).
/// Accessing track again will load a fresh instance.
/// </summary>
public virtual void RecycleTrack() => track.Recycle();
#region Disposal
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private bool isDisposed;
protected virtual void Dispose(bool isDisposing)
{
if (isDisposed)
return;
isDisposed = true;
// recycling logic is not here for the time being, as components which use
// retrieved objects from WorkingBeatmap may not hold a reference to the WorkingBeatmap itself.
// this should be fine as each retrieved component do have their own finalizers.
// cancelling the beatmap load is safe for now since the retrieval is a synchronous
// operation. if we add an async retrieval method this may need to be reconsidered.
beatmapCancellation.Cancel();
total_count.Value--;
}
~WorkingBeatmap()
{
Dispose(false);
}
#endregion
public class RecyclableLazy<T>
{
private Lazy<T> lazy;

View File

@ -77,6 +77,7 @@ namespace osu.Game.Configuration
Set(OsuSetting.BlurLevel, 0, 0, 1, 0.01);
Set(OsuSetting.ShowInterface, true);
Set(OsuSetting.ShowHealthDisplayWhenCantFail, true);
Set(OsuSetting.KeyOverlay, false);
Set(OsuSetting.FloatingComments, false);
@ -131,6 +132,7 @@ namespace osu.Game.Configuration
KeyOverlay,
FloatingComments,
ShowInterface,
ShowHealthDisplayWhenCantFail,
MouseDisableButtons,
MouseDisableWheel,
AudioOffset,

View File

@ -1,4 +1,4 @@
// 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.
using System;
@ -114,7 +114,8 @@ namespace osu.Game.Database
lock (imported)
{
imported.Add(model);
if (model != null)
imported.Add(model);
current++;
notification.Text = $"Imported {current} of {paths.Length} {HumanisedModelName}s";
@ -140,7 +141,7 @@ namespace osu.Game.Database
{
notification.CompletionText = imported.Count == 1
? $"Imported {imported.First()}!"
: $"Imported {current} {HumanisedModelName}s!";
: $"Imported {imported.Count} {HumanisedModelName}s!";
if (imported.Count > 0 && PresentImport != null)
{
@ -176,7 +177,7 @@ namespace osu.Game.Database
// TODO: Add a check to prevent files from storage to be deleted.
try
{
if (import != null && File.Exists(path))
if (import != null && File.Exists(path) && ShouldDeleteArchive(path))
File.Delete(path);
}
catch (Exception e)
@ -207,7 +208,7 @@ namespace osu.Game.Database
{
model = CreateModel(archive);
if (model == null) return null;
if (model == null) return Task.FromResult<TModel>(null);
model.Hash = computeHash(archive);
}
@ -498,6 +499,18 @@ namespace osu.Game.Database
/// </summary>
protected virtual string ImportFromStablePath => null;
/// <summary>
/// Select paths to import from stable. Default implementation iterates all directories in <see cref="ImportFromStablePath"/>.
/// </summary>
protected virtual IEnumerable<string> GetStableImportPaths(Storage stableStoage) => stableStoage.GetDirectories(ImportFromStablePath);
/// <summary>
/// Whether this specified path should be removed after successful import.
/// </summary>
/// <param name="path">The path for consideration. May be a file or a directory.</param>
/// <returns>Whether to perform deletion.</returns>
protected virtual bool ShouldDeleteArchive(string path) => false;
/// <summary>
/// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future.
/// </summary>
@ -518,7 +531,7 @@ namespace osu.Game.Database
return Task.CompletedTask;
}
return Task.Run(async () => await Import(stable.GetDirectories(ImportFromStablePath).Select(f => stable.GetFullPath(f)).ToArray()));
return Task.Run(async () => await Import(GetStableImportPaths(GetStableStorage()).Select(f => stable.GetFullPath(f)).ToArray()));
}
#endregion

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Threading;
using Microsoft.EntityFrameworkCore.Storage;
using osu.Framework.Platform;
using osu.Framework.Statistics;
namespace osu.Game.Database
{
@ -31,11 +32,20 @@ namespace osu.Game.Database
recycleThreadContexts();
}
private static readonly GlobalStatistic<int> reads = GlobalStatistics.Get<int>("Database", "Get (Read)");
private static readonly GlobalStatistic<int> writes = GlobalStatistics.Get<int>("Database", "Get (Write)");
private static readonly GlobalStatistic<int> commits = GlobalStatistics.Get<int>("Database", "Commits");
private static readonly GlobalStatistic<int> rollbacks = GlobalStatistics.Get<int>("Database", "Rollbacks");
/// <summary>
/// Get a context for the current thread for read-only usage.
/// If a <see cref="DatabaseWriteUsage"/> is in progress, the existing write-safe context will be returned.
/// </summary>
public OsuDbContext Get() => threadContexts.Value;
public OsuDbContext Get()
{
reads.Value++;
return threadContexts.Value;
}
/// <summary>
/// Request a context for write usage. Can be consumed in a nested fashion (and will return the same underlying context).
@ -45,6 +55,7 @@ namespace osu.Game.Database
/// <returns>A usage containing a usable context.</returns>
public DatabaseWriteUsage GetForWrite(bool withTransaction = true)
{
writes.Value++;
Monitor.Enter(writeLock);
OsuDbContext context;
@ -90,9 +101,15 @@ namespace osu.Game.Database
if (usages == 0)
{
if (currentWriteDidError)
{
rollbacks.Value++;
currentWriteTransaction?.Rollback();
}
else
{
commits.Value++;
currentWriteTransaction?.Commit();
}
if (currentWriteDidWrite || currentWriteDidError)
{

View File

@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;
using osu.Framework.Logging;
using osu.Framework.Statistics;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.IO;
@ -34,10 +35,15 @@ namespace osu.Game.Database
private static readonly Lazy<OsuDbLoggerFactory> logger = new Lazy<OsuDbLoggerFactory>(() => new OsuDbLoggerFactory());
private static readonly GlobalStatistic<int> contexts = GlobalStatistics.Get<int>("Database", "Contexts");
static OsuDbContext()
{
// required to initialise native SQLite libraries on some platforms.
SQLitePCL.Batteries_V2.Init();
// https://github.com/aspnet/EntityFrameworkCore/issues/9994#issuecomment-508588678
SQLitePCL.raw.sqlite3_config(2 /*SQLITE_CONFIG_MULTITHREAD*/);
}
/// <summary>
@ -76,6 +82,8 @@ namespace osu.Game.Database
connection.Close();
throw;
}
contexts.Value++;
}
~OsuDbContext()
@ -85,6 +93,20 @@ namespace osu.Game.Database
Dispose();
}
private bool isDisposed;
public override void Dispose()
{
if (isDisposed) return;
isDisposed = true;
base.Dispose();
contexts.Value--;
GC.SuppressFinalize(this);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);

View File

@ -6,23 +6,28 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Transforms;
using osuTK;
namespace osu.Game.Graphics.Backgrounds
{
public class Background : BufferedContainer
/// <summary>
/// A background which offers blurring via a <see cref="BufferedContainer"/> on demand.
/// </summary>
public class Background : CompositeDrawable
{
public Sprite Sprite;
private readonly string textureName;
private BufferedContainer bufferedContainer;
public Background(string textureName = @"")
{
CacheDrawnFrameBuffer = true;
this.textureName = textureName;
RelativeSizeAxes = Axes.Both;
Add(Sprite = new Sprite
AddInternal(Sprite = new Sprite
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
@ -37,5 +42,28 @@ namespace osu.Game.Graphics.Backgrounds
if (!string.IsNullOrEmpty(textureName))
Sprite.Texture = textures.Get(textureName);
}
public Vector2 BlurSigma => bufferedContainer?.BlurSigma ?? Vector2.Zero;
/// <summary>
/// Smoothly adjusts <see cref="IBufferedContainer.BlurSigma"/> over time.
/// </summary>
/// <returns>A <see cref="TransformSequence{T}"/> to which further transforms can be added.</returns>
public void BlurTo(Vector2 newBlurSigma, double duration = 0, Easing easing = Easing.None)
{
if (bufferedContainer == null)
{
RemoveInternal(Sprite);
AddInternal(bufferedContainer = new BufferedContainer
{
CacheDrawnFrameBuffer = true,
RelativeSizeAxes = Axes.Both,
Child = Sprite
});
}
bufferedContainer.BlurTo(newBlurSigma, duration, easing);
}
}
}

View File

@ -15,7 +15,7 @@ using osu.Game.Overlays;
namespace osu.Game.Graphics.Containers
{
public class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler<GlobalAction>
public abstract class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler<GlobalAction>
{
private SampleChannel samplePopIn;
private SampleChannel samplePopOut;

View File

@ -29,6 +29,8 @@ namespace osu.Game.Graphics.Containers
protected override Container<Drawable> Content => contentContainer;
protected override bool StartHidden => true;
public Color4 FirstWaveColour
{
get => firstWave.Colour;
@ -95,6 +97,7 @@ namespace osu.Game.Graphics.Containers
AddInternal(contentContainer = new Container
{
RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.Both,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
});
@ -105,21 +108,15 @@ namespace osu.Game.Graphics.Containers
foreach (var w in wavesContainer.Children)
w.Show();
this.FadeIn(100, Easing.OutQuint);
contentContainer.MoveToY(0, APPEAR_DURATION, Easing.OutQuint);
this.FadeIn(100, Easing.OutQuint);
}
protected override void PopOut()
{
this.FadeOut(DISAPPEAR_DURATION, Easing.InQuint);
contentContainer.MoveToY(DrawHeight * 2f, DISAPPEAR_DURATION, Easing.In);
foreach (var w in wavesContainer.Children)
w.Hide();
this.FadeOut(DISAPPEAR_DURATION, Easing.InQuint);
contentContainer.MoveToY(2, DISAPPEAR_DURATION, Easing.In);
}
protected override void UpdateAfterChildren()
@ -128,7 +125,8 @@ namespace osu.Game.Graphics.Containers
// This is done as an optimization, such that invisible parts of the waves
// are masked away, and thus do not consume fill rate.
wavesContainer.Height = Math.Max(0, DrawHeight - (contentContainer.DrawHeight - contentContainer.Y));
// todo: revert https://github.com/ppy/osu/commit/aff9e3617da0c8fe252169fae287e39b44575b5e after FTB is fixed on iOS.
wavesContainer.Height = Math.Max(0, DrawHeight - (contentContainer.DrawHeight - contentContainer.Y * DrawHeight));
}
private class Wave : VisibilityContainer

View File

@ -0,0 +1,87 @@
// 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.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Game.Online;
using osuTK;
namespace osu.Game.Graphics.UserInterface
{
public class DownloadButton : OsuAnimatedButton
{
public readonly Bindable<DownloadState> State = new Bindable<DownloadState>();
private readonly SpriteIcon icon;
private readonly SpriteIcon checkmark;
private readonly Box background;
private OsuColour colours;
public DownloadButton()
{
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Depth = float.MaxValue
},
icon = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(13),
Icon = FontAwesome.Solid.Download,
},
checkmark = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
X = 8,
Size = Vector2.Zero,
Icon = FontAwesome.Solid.Check,
}
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
this.colours = colours;
State.BindValueChanged(updateState, true);
}
private void updateState(ValueChangedEvent<DownloadState> state)
{
switch (state.NewValue)
{
case DownloadState.NotDownloaded:
background.FadeColour(colours.Gray4, 500, Easing.InOutExpo);
icon.MoveToX(0, 500, Easing.InOutExpo);
checkmark.ScaleTo(Vector2.Zero, 500, Easing.InOutExpo);
break;
case DownloadState.Downloading:
background.FadeColour(colours.Blue, 500, Easing.InOutExpo);
icon.MoveToX(0, 500, Easing.InOutExpo);
checkmark.ScaleTo(Vector2.Zero, 500, Easing.InOutExpo);
break;
case DownloadState.Downloaded:
background.FadeColour(colours.Yellow, 500, Easing.InOutExpo);
break;
case DownloadState.LocallyAvailable:
background.FadeColour(colours.Green, 500, Easing.InOutExpo);
icon.MoveToX(-8, 500, Easing.InOutExpo);
checkmark.ScaleTo(new Vector2(13), 500, Easing.InOutExpo);
break;
}
}
}
}

View File

@ -37,6 +37,8 @@ namespace osu.Game.Graphics.UserInterface
text.Colour = AccentColour;
icon.Colour = AccentColour;
}
updateFade();
}
}
@ -48,39 +50,6 @@ namespace osu.Game.Graphics.UserInterface
private const float transition_length = 500;
private void fadeIn()
{
box.FadeIn(transition_length, Easing.OutQuint);
text.FadeColour(Color4.White, transition_length, Easing.OutQuint);
}
private void fadeOut()
{
box.FadeOut(transition_length, Easing.OutQuint);
text.FadeColour(AccentColour, transition_length, Easing.OutQuint);
}
protected override bool OnHover(HoverEvent e)
{
fadeIn();
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
if (!Current.Value)
fadeOut();
base.OnHoverLost(e);
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
if (accentColour == null)
AccentColour = colours.Blue;
}
public OsuTabControlCheckbox()
{
AutoSizeAxes = Axes.Both;
@ -115,19 +84,34 @@ namespace osu.Game.Graphics.UserInterface
}
};
Current.ValueChanged += selected =>
{
if (selected.NewValue)
{
fadeIn();
icon.Icon = FontAwesome.Regular.CheckCircle;
}
else
{
fadeOut();
icon.Icon = FontAwesome.Regular.Circle;
}
};
Current.ValueChanged += selected => { icon.Icon = selected.NewValue ? FontAwesome.Regular.CheckCircle : FontAwesome.Regular.Circle; };
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
if (accentColour == null)
AccentColour = colours.Blue;
}
protected override bool OnHover(HoverEvent e)
{
updateFade();
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
if (!Current.Value)
updateFade();
base.OnHoverLost(e);
}
private void updateFade()
{
box.FadeTo(IsHovered ? 1 : 0, transition_length, Easing.OutQuint);
text.FadeColour(IsHovered ? Color4.White : AccentColour, transition_length, Easing.OutQuint);
}
}
}

View File

@ -39,7 +39,7 @@ namespace osu.Game.Input.Bindings
new KeyBinding(InputKey.F4, GlobalAction.ToggleMute),
new KeyBinding(InputKey.Escape, GlobalAction.Back),
new KeyBinding(InputKey.MouseButton1, GlobalAction.Back),
new KeyBinding(InputKey.ExtraMouseButton1, GlobalAction.Back),
new KeyBinding(InputKey.Space, GlobalAction.Select),
new KeyBinding(InputKey.Enter, GlobalAction.Select),

View File

@ -0,0 +1,504 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using osu.Game.Database;
namespace osu.Game.Migrations
{
[DbContext(typeof(OsuDbContext))]
[Migration("20190708070844_AddBPMAndLengthColumns")]
partial class AddBPMAndLengthColumns
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<float>("ApproachRate");
b.Property<float>("CircleSize");
b.Property<float>("DrainRate");
b.Property<float>("OverallDifficulty");
b.Property<double>("SliderMultiplier");
b.Property<double>("SliderTickRate");
b.HasKey("ID");
b.ToTable("BeatmapDifficulty");
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<int>("AudioLeadIn");
b.Property<double>("BPM");
b.Property<int>("BaseDifficultyID");
b.Property<int>("BeatDivisor");
b.Property<int>("BeatmapSetInfoID");
b.Property<bool>("Countdown");
b.Property<double>("DistanceSpacing");
b.Property<int>("GridSize");
b.Property<string>("Hash");
b.Property<bool>("Hidden");
b.Property<double>("Length");
b.Property<bool>("LetterboxInBreaks");
b.Property<string>("MD5Hash");
b.Property<int?>("MetadataID");
b.Property<int?>("OnlineBeatmapID");
b.Property<string>("Path");
b.Property<int>("RulesetID");
b.Property<bool>("SpecialStyle");
b.Property<float>("StackLeniency");
b.Property<double>("StarDifficulty");
b.Property<int>("Status");
b.Property<string>("StoredBookmarks");
b.Property<double>("TimelineZoom");
b.Property<string>("Version");
b.Property<bool>("WidescreenStoryboard");
b.HasKey("ID");
b.HasIndex("BaseDifficultyID");
b.HasIndex("BeatmapSetInfoID");
b.HasIndex("Hash");
b.HasIndex("MD5Hash");
b.HasIndex("MetadataID");
b.HasIndex("OnlineBeatmapID")
.IsUnique();
b.HasIndex("RulesetID");
b.ToTable("BeatmapInfo");
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<string>("Artist");
b.Property<string>("ArtistUnicode");
b.Property<string>("AudioFile");
b.Property<string>("AuthorString")
.HasColumnName("Author");
b.Property<string>("BackgroundFile");
b.Property<int>("PreviewTime");
b.Property<string>("Source");
b.Property<string>("Tags");
b.Property<string>("Title");
b.Property<string>("TitleUnicode");
b.HasKey("ID");
b.ToTable("BeatmapMetadata");
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<int>("BeatmapSetInfoID");
b.Property<int>("FileInfoID");
b.Property<string>("Filename")
.IsRequired();
b.HasKey("ID");
b.HasIndex("BeatmapSetInfoID");
b.HasIndex("FileInfoID");
b.ToTable("BeatmapSetFileInfo");
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<DateTimeOffset>("DateAdded");
b.Property<bool>("DeletePending");
b.Property<string>("Hash");
b.Property<int?>("MetadataID");
b.Property<int?>("OnlineBeatmapSetID");
b.Property<bool>("Protected");
b.Property<int>("Status");
b.HasKey("ID");
b.HasIndex("DeletePending");
b.HasIndex("Hash")
.IsUnique();
b.HasIndex("MetadataID");
b.HasIndex("OnlineBeatmapSetID")
.IsUnique();
b.ToTable("BeatmapSetInfo");
});
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<string>("Key")
.HasColumnName("Key");
b.Property<int?>("RulesetID");
b.Property<int?>("SkinInfoID");
b.Property<string>("StringValue")
.HasColumnName("Value");
b.Property<int?>("Variant");
b.HasKey("ID");
b.HasIndex("SkinInfoID");
b.HasIndex("RulesetID", "Variant");
b.ToTable("Settings");
});
modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<string>("Hash");
b.Property<int>("ReferenceCount");
b.HasKey("ID");
b.HasIndex("Hash")
.IsUnique();
b.HasIndex("ReferenceCount");
b.ToTable("FileInfo");
});
modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<int>("IntAction")
.HasColumnName("Action");
b.Property<string>("KeysString")
.HasColumnName("Keys");
b.Property<int?>("RulesetID");
b.Property<int?>("Variant");
b.HasKey("ID");
b.HasIndex("IntAction");
b.HasIndex("RulesetID", "Variant");
b.ToTable("KeyBinding");
});
modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b =>
{
b.Property<int?>("ID")
.ValueGeneratedOnAdd();
b.Property<bool>("Available");
b.Property<string>("InstantiationInfo");
b.Property<string>("Name");
b.Property<string>("ShortName");
b.HasKey("ID");
b.HasIndex("Available");
b.HasIndex("ShortName")
.IsUnique();
b.ToTable("RulesetInfo");
});
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<int>("FileInfoID");
b.Property<string>("Filename")
.IsRequired();
b.Property<int?>("ScoreInfoID");
b.HasKey("ID");
b.HasIndex("FileInfoID");
b.HasIndex("ScoreInfoID");
b.ToTable("ScoreFileInfo");
});
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<double>("Accuracy")
.HasColumnType("DECIMAL(1,4)");
b.Property<int>("BeatmapInfoID");
b.Property<int>("Combo");
b.Property<DateTimeOffset>("Date");
b.Property<bool>("DeletePending");
b.Property<string>("Hash");
b.Property<int>("MaxCombo");
b.Property<string>("ModsJson")
.HasColumnName("Mods");
b.Property<long?>("OnlineScoreID");
b.Property<double?>("PP");
b.Property<int>("Rank");
b.Property<int>("RulesetID");
b.Property<string>("StatisticsJson")
.HasColumnName("Statistics");
b.Property<long>("TotalScore");
b.Property<long?>("UserID")
.HasColumnName("UserID");
b.Property<string>("UserString")
.HasColumnName("User");
b.HasKey("ID");
b.HasIndex("BeatmapInfoID");
b.HasIndex("OnlineScoreID")
.IsUnique();
b.HasIndex("RulesetID");
b.ToTable("ScoreInfo");
});
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<int>("FileInfoID");
b.Property<string>("Filename")
.IsRequired();
b.Property<int>("SkinInfoID");
b.HasKey("ID");
b.HasIndex("FileInfoID");
b.HasIndex("SkinInfoID");
b.ToTable("SkinFileInfo");
});
modelBuilder.Entity("osu.Game.Skinning.SkinInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<string>("Creator");
b.Property<bool>("DeletePending");
b.Property<string>("Hash");
b.Property<string>("Name");
b.HasKey("ID");
b.HasIndex("DeletePending");
b.HasIndex("Hash")
.IsUnique();
b.ToTable("SkinInfo");
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
{
b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty")
.WithMany()
.HasForeignKey("BaseDifficultyID")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet")
.WithMany("Beatmaps")
.HasForeignKey("BeatmapSetInfoID")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
.WithMany("Beatmaps")
.HasForeignKey("MetadataID");
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
.WithMany()
.HasForeignKey("RulesetID")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
{
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo")
.WithMany("Files")
.HasForeignKey("BeatmapSetInfoID")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
.WithMany()
.HasForeignKey("FileInfoID")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
{
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
.WithMany("BeatmapSets")
.HasForeignKey("MetadataID");
});
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
{
b.HasOne("osu.Game.Skinning.SkinInfo")
.WithMany("Settings")
.HasForeignKey("SkinInfoID");
});
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
{
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
.WithMany()
.HasForeignKey("FileInfoID")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("osu.Game.Scoring.ScoreInfo")
.WithMany("Files")
.HasForeignKey("ScoreInfoID");
});
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
{
b.HasOne("osu.Game.Beatmaps.BeatmapInfo", "Beatmap")
.WithMany("Scores")
.HasForeignKey("BeatmapInfoID")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
.WithMany()
.HasForeignKey("RulesetID")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
{
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
.WithMany()
.HasForeignKey("FileInfoID")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("osu.Game.Skinning.SkinInfo")
.WithMany("Files")
.HasForeignKey("SkinInfoID")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations
{
public partial class AddBPMAndLengthColumns : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<double>(
name: "BPM",
table: "BeatmapInfo",
nullable: false,
defaultValue: 0.0);
migrationBuilder.AddColumn<double>(
name: "Length",
table: "BeatmapInfo",
nullable: false,
defaultValue: 0.0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "BPM",
table: "BeatmapInfo");
migrationBuilder.DropColumn(
name: "Length",
table: "BeatmapInfo");
}
}
}

View File

@ -45,6 +45,8 @@ namespace osu.Game.Migrations
b.Property<int>("AudioLeadIn");
b.Property<double>("BPM");
b.Property<int>("BaseDifficultyID");
b.Property<int>("BeatDivisor");
@ -61,6 +63,8 @@ namespace osu.Game.Migrations
b.Property<bool>("Hidden");
b.Property<double>("Length");
b.Property<bool>("LetterboxInBreaks");
b.Property<string>("MD5Hash");

View File

@ -0,0 +1,19 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Scoring;
namespace osu.Game.Online.API.Requests
{
public class DownloadReplayRequest : ArchiveDownloadRequest<ScoreInfo>
{
public DownloadReplayRequest(ScoreInfo score)
: base(score)
{
}
protected override string FileExtension => ".osr";
protected override string Target => $@"scores/{Model.Ruleset.ShortName}/{Model.OnlineScoreID}/download";
}
}

View File

@ -5,8 +5,10 @@ using System;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Screens.Select.Leaderboards;
using osu.Framework.IO.Network;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods;
using System.Text;
using System.Collections.Generic;
namespace osu.Game.Online.API.Requests
{
@ -15,8 +17,9 @@ namespace osu.Game.Online.API.Requests
private readonly BeatmapInfo beatmap;
private readonly BeatmapLeaderboardScope scope;
private readonly RulesetInfo ruleset;
private readonly IEnumerable<Mod> mods;
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global)
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global, IEnumerable<Mod> mods = null)
{
if (!beatmap.OnlineBeatmapID.HasValue)
throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}.");
@ -27,6 +30,7 @@ namespace osu.Game.Online.API.Requests
this.beatmap = beatmap;
this.scope = scope;
this.ruleset = ruleset ?? throw new ArgumentNullException(nameof(ruleset));
this.mods = mods ?? Array.Empty<Mod>();
Success += onSuccess;
}
@ -34,20 +38,33 @@ namespace osu.Game.Online.API.Requests
private void onSuccess(APILegacyScores r)
{
foreach (APILegacyScoreInfo score in r.Scores)
{
score.Beatmap = beatmap;
score.Ruleset = ruleset;
}
var userScore = r.UserScore;
if (userScore != null)
{
userScore.Score.Beatmap = beatmap;
userScore.Score.Ruleset = ruleset;
}
}
protected override WebRequest CreateWebRequest()
protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores{createQueryParameters()}";
private string createQueryParameters()
{
var req = base.CreateWebRequest();
StringBuilder query = new StringBuilder(@"?");
req.Timeout = 30000;
req.AddParameter(@"type", scope.ToString().ToLowerInvariant());
req.AddParameter(@"mode", ruleset.ShortName);
query.Append($@"type={scope.ToString().ToLowerInvariant()}");
query.Append($@"&mode={ruleset.ShortName}");
return req;
foreach (var mod in mods)
query.Append($@"&mods[]={mod.Acronym}");
return query.ToString();
}
protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores";
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using Newtonsoft.Json;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
@ -71,6 +72,7 @@ namespace osu.Game.Online.API.Requests.Responses
StarDifficulty = starDifficulty,
OnlineBeatmapID = OnlineBeatmapID,
Version = version,
Length = TimeSpan.FromSeconds(length).TotalMilliseconds,
Status = Status,
BeatmapSet = set,
Metrics = metrics,
@ -85,7 +87,6 @@ namespace osu.Game.Online.API.Requests.Responses
{
PlayCount = playCount,
PassCount = passCount,
Length = length,
CircleCount = circleCount,
SliderCount = sliderCount,
},

View File

@ -33,6 +33,8 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty("versions")]
public VersionNavigation Versions { get; set; }
public string Url => $"https://osu.ppy.sh/home/changelog/{UpdateStream.Name}/{Version}";
public class VersionNavigation
{
[JsonProperty("next")]

View File

@ -32,12 +32,15 @@ namespace osu.Game.Online.API.Requests.Responses
set => User = value;
}
[JsonProperty(@"score_id")]
[JsonProperty(@"id")]
private long onlineScoreID
{
set => OnlineScoreID = value;
}
[JsonProperty(@"replay")]
public bool Replay { get; set; }
[JsonProperty(@"created_at")]
private DateTimeOffset date
{
@ -113,17 +116,6 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty(@"mods")]
private string[] modStrings { get; set; }
public override BeatmapInfo Beatmap
{
get => base.Beatmap;
set
{
base.Beatmap = value;
if (Beatmap.Ruleset != null)
Ruleset = value.Ruleset;
}
}
public override RulesetInfo Ruleset
{
get => base.Ruleset;

View File

@ -10,5 +10,17 @@ namespace osu.Game.Online.API.Requests.Responses
{
[JsonProperty(@"scores")]
public List<APILegacyScoreInfo> Scores;
[JsonProperty(@"userScore")]
public APILegacyUserTopScoreInfo UserScore;
}
public class APILegacyUserTopScoreInfo
{
[JsonProperty(@"position")]
public int Position;
[JsonProperty(@"score")]
public APILegacyScoreInfo Score;
}
}

View File

@ -11,7 +11,7 @@ using osu.Game.Online.API;
namespace osu.Game.Online
{
/// <summary>
/// A component which tracks a beatmap through potential download/import/deletion.
/// A component which tracks a <see cref="TModel"/> through potential download/import/deletion.
/// </summary>
public abstract class DownloadTrackingComposite<TModel, TModelManager> : CompositeDrawable
where TModel : class, IEquatable<TModel>
@ -22,7 +22,7 @@ namespace osu.Game.Online
private TModelManager manager;
/// <summary>
/// Holds the current download state of the beatmap, whether is has already been downloaded, is in progress, or is not downloaded.
/// Holds the current download state of the <see cref="TModel"/>, whether is has already been downloaded, is in progress, or is not downloaded.
/// </summary>
protected readonly Bindable<DownloadState> State = new Bindable<DownloadState>();
@ -54,6 +54,12 @@ namespace osu.Game.Online
attachDownload(download);
};
manager.DownloadFailed += download =>
{
if (download.Model.Equals(Model.Value))
attachDownload(null);
};
manager.ItemAdded += itemAdded;
manager.ItemRemoved += itemRemoved;
}

View File

@ -1,45 +1,131 @@
// 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.Extensions;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
using osu.Game.Scoring;
using System;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Online.Leaderboards
{
public class DrawableRank : Sprite
public class DrawableRank : CompositeDrawable
{
private readonly ScoreRank rank;
public DrawableRank(ScoreRank rank)
{
this.rank = rank;
RelativeSizeAxes = Axes.Both;
FillMode = FillMode.Fit;
FillAspectRatio = 2;
var rankColour = getRankColour();
InternalChild = new DrawSizePreservingFillContainer
{
TargetDrawSize = new Vector2(64, 32),
Strategy = DrawSizePreservationStrategy.Minimum,
Child = new CircularContainer
{
Masking = true,
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = rankColour,
},
new Triangles
{
RelativeSizeAxes = Axes.Both,
ColourDark = rankColour.Darken(0.1f),
ColourLight = rankColour.Lighten(0.1f),
Velocity = 0.25f,
},
new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Spacing = new Vector2(-3, 0),
Padding = new MarginPadding { Top = 5 },
Colour = getRankNameColour(),
Font = OsuFont.GetFont(Typeface.Venera, 25),
Text = getRankName(),
ShadowColour = Color4.Black.Opacity(0.3f),
ShadowOffset = new Vector2(0, 0.08f),
Shadow = true,
},
}
}
};
}
[BackgroundDependencyLoader(true)]
private void load(TextureStore ts)
{
if (ts == null)
throw new ArgumentNullException(nameof(ts));
private string getRankName() => rank.GetDescription().TrimEnd('+');
Texture = ts.Get($@"Grades/{getTextureName()}");
}
private string getTextureName()
/// <summary>
/// Retrieves the grade background colour.
/// </summary>
private Color4 getRankColour()
{
switch (rank)
{
default:
return rank.GetDescription();
case ScoreRank.XH:
case ScoreRank.X:
return OsuColour.FromHex(@"ce1c9d");
case ScoreRank.SH:
return "SPlus";
case ScoreRank.S:
return OsuColour.FromHex(@"00a8b5");
case ScoreRank.A:
return OsuColour.FromHex(@"7cce14");
case ScoreRank.B:
return OsuColour.FromHex(@"e3b130");
case ScoreRank.C:
return OsuColour.FromHex(@"f18252");
default:
return OsuColour.FromHex(@"e95353");
}
}
/// <summary>
/// Retrieves the grade text colour.
/// </summary>
private ColourInfo getRankNameColour()
{
switch (rank)
{
case ScoreRank.XH:
return "SSPlus";
case ScoreRank.SH:
return ColourInfo.GradientVertical(Color4.White, OsuColour.FromHex("afdff0"));
case ScoreRank.X:
case ScoreRank.S:
return ColourInfo.GradientVertical(OsuColour.FromHex(@"ffe7a8"), OsuColour.FromHex(@"ffb800"));
case ScoreRank.A:
return OsuColour.FromHex(@"275227");
case ScoreRank.B:
return OsuColour.FromHex(@"553a2b");
case ScoreRank.C:
return OsuColour.FromHex(@"473625");
default:
return OsuColour.FromHex(@"512525");
}
}
}

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