1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 23:23:32 +08:00

Compare commits

...

1397 Commits

1478 changed files with 58249 additions and 26140 deletions
+9 -12
View File
@@ -3,28 +3,25 @@
"isRoot": true,
"tools": {
"jetbrains.resharper.globaltools": {
"version": "2023.3.3",
"version": "2025.2.3",
"commands": [
"jb"
]
},
"nvika": {
"version": "4.0.0",
"commands": [
"nvika"
]
],
"rollForward": false
},
"codefilesanity": {
"version": "0.0.37",
"version": "0.0.41",
"commands": [
"CodeFileSanity"
]
],
"rollForward": false
},
"ppy.localisationanalyser.tools": {
"version": "2024.802.0",
"version": "2025.1208.0",
"commands": [
"localisation"
]
],
"rollForward": false
}
}
}
+1 -1
View File
@@ -44,7 +44,7 @@ jobs:
steps:
- name: Checkout diffcalc-sheet-generator
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
path: ${{ inputs.id }}
repository: 'smoogipoo/diffcalc-sheet-generator'
+50 -17
View File
@@ -6,6 +6,7 @@ concurrency:
permissions:
contents: read # to fetch code (actions/checkout)
security-events: write # for reporting InspectCode issues
jobs:
inspect-code:
@@ -13,10 +14,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Install .NET 8.0.x
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: "8.0.x"
@@ -27,7 +28,7 @@ jobs:
run: dotnet restore osu.Desktop.slnf
- name: Restore inspectcode cache
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ${{ github.workspace }}/inspectcode
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
@@ -49,10 +50,14 @@ jobs:
exit $exit_code
- name: InspectCode
run: dotnet jb inspectcode $(pwd)/osu.Desktop.slnf --no-build --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN
- name: NVika
run: dotnet nvika parsereport "${{github.workspace}}/inspectcodereport.xml" --treatwarningsaserrors
uses: JetBrains/ReSharper-InspectCode@v0.12
with:
# this is WTF tier but if you don't specify *both* of these the defaults assume `build: true`
build: false
no-build: true
solution: ./osu.Desktop.slnf
caches-home: inspectcode
verbosity: WARN
test:
name: Test
@@ -71,10 +76,10 @@ jobs:
timeout-minutes: 120
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Install .NET 8.0.x
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: "8.0.x"
@@ -96,30 +101,58 @@ jobs:
NUnit.ConsoleOut=0
# Attempt to upload results even if test fails.
# https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#always
# https://docs.github.com/en/actions/reference/workflows-and-actions/expressions#cancelled
- name: Upload Test Results
uses: actions/upload-artifact@v4
if: ${{ always() }}
uses: actions/upload-artifact@v7
if: ${{ !cancelled() }}
with:
name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
path: ${{github.workspace}}/TestResults/TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx
test-results:
name: Test results
runs-on: ubuntu-latest
# we want to wait for the `test` job to complete, but run regardless of whether it succeeds or fails
# https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#example-not-requiring-successful-dependent-jobs
if: ${{ !cancelled() }}
needs: test
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download results
uses: actions/download-artifact@v8
with:
pattern: osu-test-results-*
merge-multiple: true
- name: Add test results summary to workflow run
uses: dorny/test-reporter@v3.0.0
with:
name: Results
path: "*.trx"
reporter: dotnet-trx
list-suites: 'failed'
list-tests: 'failed'
use-actions-summary: 'true'
build-only-android:
name: Build only (Android)
runs-on: windows-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Setup JDK 11
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: microsoft
java-version: 11
- name: Install .NET 8.0.x
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: "8.0.x"
@@ -135,10 +168,10 @@ jobs:
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Install .NET 8.0.x
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: "8.0.x"
+5 -4
View File
@@ -3,7 +3,8 @@ name: Pack and nuget
on:
push:
tags:
- '*'
- '*.*.*'
- '!*-*'
jobs:
notify_pending_production_deploy:
@@ -43,14 +44,14 @@ jobs:
environment: production
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set artifacts directory
id: artifactsPath
run: echo "::set-output name=nuget_artifacts::${{github.workspace}}/artifacts"
- name: Install .NET 8.0.x
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: "8.0.x"
@@ -76,7 +77,7 @@ jobs:
dotnet pack -c Release Templates /p:Version=${{ github.ref_name }} -o ${{steps.artifactsPath.outputs.nuget_artifacts}}
- name: Upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: osu
path: |
-45
View File
@@ -1,45 +0,0 @@
# This is a workaround to allow PRs to report their coverage. This will run inside the base repository.
# See:
# * https://github.com/dorny/test-reporter#recommended-setup-for-public-repositories
# * https://docs.github.com/en/actions/reference/authentication-in-a-workflow#permissions-for-the-github_token
name: Annotate CI run with test results
on:
workflow_run:
workflows: [ "Continuous Integration" ]
types:
- completed
permissions:
contents: read
actions: read
checks: write
jobs:
annotate:
name: Annotate CI run with test results
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion != 'cancelled' }}
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v4
with:
repository: ${{ github.event.workflow_run.repository.full_name }}
ref: ${{ github.event.workflow_run.head_sha }}
- name: Download results
uses: actions/download-artifact@v4
with:
pattern: osu-test-results-*
merge-multiple: true
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Annotate CI run with test results
uses: dorny/test-reporter@v1.8.0
with:
name: Results
path: "*.trx"
reporter: dotnet-trx
list-suites: 'failed'
list-tests: 'failed'
+2 -2
View File
@@ -13,12 +13,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Create Sentry release
uses: getsentry/action-release@v1
uses: getsentry/action-release@v3
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ppy
@@ -38,8 +38,12 @@ jobs:
run: ./UseLocalOsu.sh
working-directory: ./osu-tools
- name: Build tools
run: dotnet build PerformanceCalculator --nologo --verbosity quiet
working-directory: ./osu-tools
- name: Regenerate mod definitions
run: dotnet run --project PerformanceCalculator -- mods > ../osu-web/database/mods.json
run: dotnet run --project PerformanceCalculator --no-build -- mods > ../osu-web/database/mods.json
working-directory: ./osu-tools
- name: Create pull request with changes
+13
View File
@@ -13,6 +13,19 @@
"preLaunchTask": "Build osu! (Debug)",
"console": "internalConsole"
},
{
"name": "osu! (Debug, Second Client)",
"type": "coreclr",
"request": "launch",
"program": "dotnet",
"args": [
"${workspaceRoot}/osu.Desktop/bin/Debug/net8.0/osu!.dll",
"--debug-client-id=1"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Debug)",
"console": "internalConsole"
},
{
"name": "osu! (Release)",
"type": "coreclr",
+8 -3
View File
@@ -2,6 +2,10 @@
Thank you for showing interest in the development of osu!. We aim to provide a good collaborating environment for everyone involved, and as such have decided to list some of the most important things to keep in mind in the process. The guidelines below have been chosen based on past experience.
## Foreword on AI usage
Our team believes in **human contributions**. Any contribution be it an issue report or a pull request which is created by, documented by, or aided by AI/LLM usage will typically be **closed and locked without further discussion**.
## Table of contents
1. [Reporting bugs](#reporting-bugs)
@@ -55,9 +59,7 @@ When in doubt, it's probably best to start with a discussion first. We will esca
While pull requests from unaffiliated contributors are welcome, please note that due to significant community interest and limited review throughput, the core team's primary focus is on the issues which are currently [on the roadmap](https://github.com/orgs/ppy/projects/7/views/6). Reviewing PRs that fall outside of the scope of the roadmap is done on a best-effort basis, so please be aware that it may take a while before a core maintainer gets around to review your change.
The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues to start with. We also have a [`good first issue`](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label, although from experience it is not used very often, as it is relatively rare that we can spot an issue that will definitively be a good first issue for a new contributor regardless of their programming experience.
In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive.
The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues to start with. In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive.
If you'd like to propose a subjective change to one of the visual aspects of the game, or there is a bigger task you'd like to work on, but there is no corresponding issue or discussion thread yet for it, **please open a discussion or issue first** to avoid wasted effort. This in particular applies if you want to work on [one of the available designs from the osu! Figma master library](https://www.figma.com/file/VIkXMYNPMtQem2RJg9k2iQ/Master-Library).
@@ -73,6 +75,9 @@ Aside from the above, below is a brief checklist of things to watch out when you
After you're done with your changes and you wish to open the PR, please observe the following recommendations:
- Please submit the pull request from a [topic branch](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows#_topic_branch) (not `master`), and keep the *Allow edits from maintainers* check box selected, so that we can push fixes to your PR if necessary.
- Please pick the following target branch for your pull request:
- `pp-dev`, if the change impacts star rating or performance points calculations for any of the rulesets,
- `master`, otherwise.
- Please avoid pushing untested or incomplete code.
- Please do not force-push or rebase unless we ask you to.
- Please do not merge `master` continually if there are no conflicts to resolve. We will do this for you when the change is ready for merge.
+2
View File
@@ -138,6 +138,8 @@ If you wish to help with localisation efforts, head over to [crowdin](https://cr
We love to reward quality contributions. If you have made a large contribution, or are a regular contributor, you are welcome to [submit an expense via opencollective](https://opencollective.com/ppy/expenses/new). If you have any questions, feel free to [reach out to peppy](mailto:pe@ppy.sh) before doing so.
Our team believes in **human contributions**. Any contribution be it an issue report or a pull request which is created by, documented by, or aided by AI/LLM usage will typically be **closed and locked without further discussion**.
## Licence
*osu!*'s code and framework are licensed under the [MIT licence](https://opensource.org/licenses/MIT). Please see [the licence file](LICENCE) for more information. [tl;dr](https://tldrlegal.com/license/mit-license) you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.
@@ -10,8 +10,8 @@
</PropertyGroup>
<ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="NUnit" Version="4.5.1" />
<PackageReference Include="NUnit3TestAdapter" Version="6.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.EmptyFreeform\osu.Game.Rulesets.EmptyFreeform.csproj" />
@@ -10,8 +10,8 @@
</PropertyGroup>
<ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="NUnit" Version="4.5.1" />
<PackageReference Include="NUnit3TestAdapter" Version="6.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.Pippidon\osu.Game.Rulesets.Pippidon.csproj" />
@@ -10,8 +10,8 @@
</PropertyGroup>
<ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="NUnit" Version="4.5.1" />
<PackageReference Include="NUnit3TestAdapter" Version="6.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.EmptyScrolling\osu.Game.Rulesets.EmptyScrolling.csproj" />
@@ -10,8 +10,8 @@
</PropertyGroup>
<ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="NUnit" Version="4.5.1" />
<PackageReference Include="NUnit3TestAdapter" Version="6.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.Pippidon\osu.Game.Rulesets.Pippidon.csproj" />
+1 -1
View File
@@ -10,7 +10,7 @@
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.Android" Version="2025.930.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2026.513.0" />
</ItemGroup>
<PropertyGroup>
<!-- Fody does not handle Android build well, and warns when unchanged.
+9 -12
View File
@@ -5,16 +5,13 @@
android:supportsRtl="true"
android:label="osu!"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher" />
<!-- for editor usage -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<!--
READ_MEDIA_* permissions are available only on API 33 or greater. Devices with older android versions
don't understand the new permissions, so request the old READ_EXTERNAL_STORAGE permission to get storage access.
Since the old permission has no effect on >= API 33, don't request it.
Care needs to be taken to ensure runtime permission checks target the correct permission for the API level.
-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
android:roundIcon="@mipmap/ic_launcher">
<provider android:name="androidx.core.content.FileProvider"
android:authorities="sh.ppy.osulazer.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
</application>
</manifest>
+18 -7
View File
@@ -20,13 +20,24 @@ using Uri = Android.Net.Uri;
namespace osu.Android
{
[Activity(ConfigurationChanges = DEFAULT_CONFIG_CHANGES, Exported = true, LaunchMode = DEFAULT_LAUNCH_MODE, MainLauncher = true)]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osz", DataHost = "*", DataMimeType = "*/*")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osk", DataHost = "*", DataMimeType = "*/*")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osr", DataHost = "*", DataMimeType = "*/*")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataMimeType = "application/x-osu-beatmap-archive")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataMimeType = "application/x-osu-skin-archive")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataMimeType = "application/x-osu-replay")]
[IntentFilter(new[] { Intent.ActionSend, Intent.ActionSendMultiple }, Categories = new[] { Intent.CategoryDefault }, DataMimeTypes = new[]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import beatmap", DataScheme = "content", DataPathPattern = ".*\\\\.osz", DataHost = "*",
DataMimeType = "*/*")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import skin", DataScheme = "content", DataPathPattern = ".*\\\\.osk", DataHost = "*",
DataMimeType = "*/*")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import replay", DataScheme = "content", DataPathPattern = ".*\\\\.osr", DataHost = "*",
DataMimeType = "*/*")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import beatmap", DataScheme = "content", DataMimeType = "application/x-osu-beatmap-archive")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import skin", DataScheme = "content", DataMimeType = "application/x-osu-skin-archive")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import replay", DataScheme = "content", DataMimeType = "application/x-osu-replay")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import file", DataScheme = "content", DataMimeTypes = new[]
{
"application/zip",
"application/octet-stream",
"application/download",
"application/x-zip",
"application/x-zip-compressed",
})]
[IntentFilter(new[] { Intent.ActionSend, Intent.ActionSendMultiple }, Categories = new[] { Intent.CategoryDefault }, Label = "Import", DataMimeTypes = new[]
{
"application/zip",
"application/octet-stream",
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<!-- https://developer.android.com/reference/androidx/core/content/FileProvider -->
<external-files-path path="logs" name="logs" />
<external-files-path path="exports" name="exports" />
</paths>
+2 -1
View File
@@ -58,6 +58,7 @@ namespace osu.Desktop
private readonly RichPresence presence = new RichPresence
{
Assets = new Assets { LargeImageKey = "osu_logo_lazer" },
Timestamps = Timestamps.Now,
Secrets = new Secrets
{
JoinSecret = null,
@@ -189,7 +190,7 @@ namespace osu.Desktop
}
// user party
if (!hideIdentifiableInformation && multiplayerClient.Room != null)
if (!hideIdentifiableInformation && multiplayerClient.Room != null && !multiplayerClient.Room.Settings.MatchType.IsMatchmakingType())
{
MultiplayerRoom room = multiplayerClient.Room;
@@ -0,0 +1,13 @@
// 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 Newtonsoft.Json;
namespace osu.Desktop.IPC.Messages
{
public class HitCountMessage : OsuWebSocketMessage
{
[JsonProperty("new_hits")]
public long NewHits { get; init; }
}
}
@@ -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 Newtonsoft.Json;
using osu.Framework.Extensions.TypeExtensions;
namespace osu.Desktop.IPC.Messages
{
public abstract class OsuWebSocketMessage
{
[JsonProperty("type")]
public string Type { get; }
protected OsuWebSocketMessage()
{
Type = GetType().ReadableName();
}
}
}
+75
View File
@@ -0,0 +1,75 @@
// 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.Linq;
using System.Threading;
using osu.Desktop.IPC.Messages;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Game.Configuration;
using osu.Game.IPC;
using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using JsonConvert = Newtonsoft.Json.JsonConvert;
namespace osu.Desktop.IPC
{
public partial class OsuWebSocketProvider : Component
{
private WebSocketServer? server;
private readonly Bindable<ScoreInfo> lastLocalScore = new Bindable<ScoreInfo>();
[BackgroundDependencyLoader]
private void load(SessionStatics sessionStatics)
{
server = new WebSocketServer(49727);
server.StartAsync().FireAndForget(onError: ex => Logger.Error(ex, "Failed to start websocket"));
sessionStatics.BindWith(Static.LastLocalUserScore, lastLocalScore);
}
protected override void LoadComplete()
{
base.LoadComplete();
lastLocalScore.BindValueChanged(val =>
{
if (val.NewValue == null)
return;
if (server?.IsRunning != true)
return;
var msg = new HitCountMessage { NewHits = val.NewValue.Statistics.Where(kv => kv.Key.IsBasic() && kv.Key.IsHit()).Sum(kv => kv.Value) };
broadcast(msg);
});
}
private void broadcast(OsuWebSocketMessage message)
{
if (server?.IsRunning != true)
return;
string messageString = JsonConvert.SerializeObject(message);
server.BroadcastAsync(messageString).FireAndForget();
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (server?.IsRunning == true)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(10));
server.StopAsync(cts.Token).WaitSafely();
server = null;
}
}
}
}
@@ -0,0 +1,55 @@
// 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.IO;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Localisation;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
namespace osu.Desktop.MacOS
{
/// <summary>
/// Checks if the game is located at `Applications` folder and displays a warning notification if not so.
/// </summary>
public partial class MacOSAppLocationChecker : Component
{
[Resolved]
private INotificationOverlay notification { get; set; } = null!;
protected override void LoadComplete()
{
base.LoadComplete();
string assemblyPath = RuntimeInfo.EntryAssembly.Location;
bool inRootApp = assemblyPath.StartsWith("/Applications/", StringComparison.Ordinal);
bool inUserApp = assemblyPath.StartsWith(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Applications/"), StringComparison.Ordinal);
if (!inRootApp && !inUserApp)
notification.Post(new MacOSAppLocationNotification());
Expire();
}
private partial class MacOSAppLocationNotification : SimpleNotification
{
public MacOSAppLocationNotification()
{
Text = NotificationsStrings.MacOSAppLocation(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Icon = FontAwesome.Solid.ShieldAlt;
IconContent.Colour = colours.YellowDark;
}
}
}
}
+26 -8
View File
@@ -5,8 +5,8 @@ using System;
using System.IO;
using System.Reflection;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using Microsoft.Win32;
using osu.Desktop.IPC;
using osu.Desktop.Performance;
using osu.Desktop.Security;
using osu.Framework.Platform;
@@ -15,12 +15,12 @@ using osu.Desktop.Updater;
using osu.Framework;
using osu.Framework.Logging;
using osu.Game.Updater;
using osu.Desktop.MacOS;
using osu.Desktop.Windows;
using osu.Framework.Allocation;
using osu.Game.Configuration;
using osu.Game.IO;
using osu.Game.IPC;
using osu.Game.Online.Multiplayer;
using osu.Game.Performance;
using osu.Game.Utils;
@@ -36,6 +36,8 @@ namespace osu.Desktop
public bool IsFirstRun { get; init; }
public bool EnableWebSocketServer { get; init; }
public OsuGameDesktop(string[]? args = null)
: base(args)
{
@@ -123,7 +125,7 @@ namespace osu.Desktop
public override bool RestartAppWhenExited()
{
Task.Run(() => Velopack.UpdateExe.Start(waitPid: (uint)Environment.ProcessId)).FireAndForget();
RestartOnExitAction = () => Velopack.UpdateExe.Start(waitPid: (uint)Environment.ProcessId);
return true;
}
@@ -133,22 +135,38 @@ namespace osu.Desktop
LoadComponentAsync(new DiscordRichPresence(), Add);
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
LoadComponentAsync(new GameplayWinKeyBlocker(), Add);
switch (RuntimeInfo.OS)
{
case RuntimeInfo.Platform.Windows:
LoadComponentAsync(new GameplayWinKeyBlocker(), Add);
break;
case RuntimeInfo.Platform.macOS when !IsPackageManaged && IsDeployedBuild:
if (!IsPackageManaged && IsDeployedBuild)
LoadComponentAsync(new MacOSAppLocationChecker(), Add);
break;
}
LoadComponentAsync(new ElevatedPrivilegesChecker(), Add);
osuSchemeLinkIPCChannel = new OsuSchemeLinkIPCChannel(Host, this);
archiveImportIPCChannel = new ArchiveImportIPCChannel(Host, this);
if (EnableWebSocketServer)
Add(new OsuWebSocketProvider());
}
public override void SetHost(GameHost host)
{
base.SetHost(host);
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
if (iconStream != null)
host.Window.SetIconFromStream(iconStream);
// Apple operating systems use a better icon provided via external assets.
if (!RuntimeInfo.IsApple)
{
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
if (iconStream != null)
host.Window.SetIconFromStream(iconStream);
}
host.Window.Title = Name;
}
+2 -1
View File
@@ -140,7 +140,8 @@ namespace osu.Desktop
{
host.Run(new OsuGameDesktop(args)
{
IsFirstRun = isFirstRun
IsFirstRun = isFirstRun,
EnableWebSocketServer = Environment.GetEnvironmentVariable("OSU_WEBSOCKET_SERVER") == "1",
});
}
}
@@ -7,6 +7,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Localisation;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
@@ -26,13 +27,15 @@ namespace osu.Desktop.Security
if (Environment.IsPrivilegedProcess)
notifications.Post(new ElevatedPrivilegesNotification());
Expire();
}
private partial class ElevatedPrivilegesNotification : SimpleNotification
{
public ElevatedPrivilegesNotification()
{
Text = $"Running osu! as {(RuntimeInfo.IsUnix ? "root" : "administrator")} does not improve performance, may break integrations and poses a security risk. Please run the game as a normal user.";
Text = NotificationsStrings.ElevatedPrivileges(RuntimeInfo.IsUnix ? "root" : "Administrator");
}
[BackgroundDependencyLoader]
+4 -4
View File
@@ -146,11 +146,11 @@ namespace osu.Desktop.Updater
action();
}
private void restartToApplyUpdate(Velopack.UpdateManager updateManager, UpdateInfo update) => Task.Run(async () =>
private void restartToApplyUpdate(Velopack.UpdateManager updateManager, UpdateInfo update)
{
await updateManager.WaitExitThenApplyUpdatesAsync(update.TargetFullRelease).ConfigureAwait(false);
Schedule(() => game.AttemptExit());
});
game.RestartOnExitAction = () => updateManager.WaitExitThenApplyUpdates(update.TargetFullRelease);
game.AttemptExit();
}
private static void log(string text) => Logger.Log($"VelopackUpdateManager: {text}");
}
+3 -2
View File
@@ -24,8 +24,9 @@
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="System.IO.Packaging" Version="9.0.2" />
<PackageReference Include="DiscordRichPresence" Version="1.2.1.24" />
<PackageReference Include="System.IO.Packaging" Version="10.0.5" />
<!-- Held back due to invite bug in newer versions. See https://github.com/Lachee/discord-rpc-csharp/issues/286-->
<PackageReference Include="DiscordRichPresence" Version="1.5.0.51" />
<PackageReference Include="Velopack" Version="0.0.1298" />
</ItemGroup>
<ItemGroup Label="Resources">
@@ -5,7 +5,7 @@ using BenchmarkDotNet.Attributes;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Carousel;
using osu.Game.Tests.NonVisual.Filtering;
namespace osu.Game.Benchmarks
{
@@ -42,7 +42,7 @@ namespace osu.Game.Benchmarks
Status = BeatmapOnlineStatus.Loved
};
private CarouselBeatmap carouselBeatmap = null!;
private FilterMatchingTest.CarouselBeatmap carouselBeatmap = null!;
private FilterCriteria criteria1 = null!;
private FilterCriteria criteria2 = null!;
private FilterCriteria criteria3 = null!;
@@ -55,7 +55,7 @@ namespace osu.Game.Benchmarks
var beatmap = getExampleBeatmap();
beatmap.OnlineID = 20201010;
beatmap.BeatmapSet = new BeatmapSetInfo { OnlineID = 1535 };
carouselBeatmap = new CarouselBeatmap(beatmap);
carouselBeatmap = new FilterMatchingTest.CarouselBeatmap(beatmap);
criteria1 = new FilterCriteria();
criteria2 = new FilterCriteria
{
@@ -7,9 +7,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
<PackageReference Include="nunit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
<PackageReference Include="nunit" Version="4.5.1" />
<PackageReference Include="NUnit3TestAdapter" Version="6.1.0" />
</ItemGroup>
<ItemGroup>
+1 -3
View File
@@ -35,11 +35,9 @@
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict>
</plist>
</plist>
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using NUnit.Framework.Legacy;
using osu.Framework.IO.Stores;
using osu.Game.Rulesets.Catch.Skinning;
using osu.Game.Rulesets.Catch.Skinning.Legacy;
@@ -21,9 +22,9 @@ namespace osu.Game.Rulesets.Catch.Tests
var skinSource = new SkinProvidingContainer(rawSkin);
var skin = new CatchLegacySkinTransformer(skinSource);
Assert.AreEqual(new Color4(232, 185, 35, 255), skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDash)?.Value);
Assert.AreEqual(new Color4(232, 74, 35, 255), skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDashAfterImage)?.Value);
Assert.AreEqual(new Color4(0, 255, 255, 255), skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDashFruit)?.Value);
ClassicAssert.AreEqual(new Color4(232, 185, 35, 255), skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDash)?.Value);
ClassicAssert.AreEqual(new Color4(232, 74, 35, 255), skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDashAfterImage)?.Value);
ClassicAssert.AreEqual(new Color4(0, 255, 255, 255), skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDashFruit)?.Value);
}
private class TestLegacySkin : LegacySkin
@@ -193,20 +193,20 @@ namespace osu.Game.Rulesets.Catch.Tests
{
public Color4 HyperDashColour
{
get => Configuration.CustomColours[CatchSkinColour.HyperDash.ToString()];
set => Configuration.CustomColours[CatchSkinColour.HyperDash.ToString()] = value;
get => Configuration.CustomColours[nameof(CatchSkinColour.HyperDash)];
set => Configuration.CustomColours[nameof(CatchSkinColour.HyperDash)] = value;
}
public Color4 HyperDashAfterImageColour
{
get => Configuration.CustomColours[CatchSkinColour.HyperDashAfterImage.ToString()];
set => Configuration.CustomColours[CatchSkinColour.HyperDashAfterImage.ToString()] = value;
get => Configuration.CustomColours[nameof(CatchSkinColour.HyperDashAfterImage)];
set => Configuration.CustomColours[nameof(CatchSkinColour.HyperDashAfterImage)] = value;
}
public Color4 HyperDashFruitColour
{
get => Configuration.CustomColours[CatchSkinColour.HyperDashFruit.ToString()];
set => Configuration.CustomColours[CatchSkinColour.HyperDashFruit.ToString()] = value;
get => Configuration.CustomColours[nameof(CatchSkinColour.HyperDashFruit)];
set => Configuration.CustomColours[nameof(CatchSkinColour.HyperDashFruit)] = value;
}
public TestSkin()
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
<PackageReference Include="NUnit" Version="4.5.1" />
<PackageReference Include="NUnit3TestAdapter" Version="6.1.0" />
</ItemGroup>
<PropertyGroup Label="Project">
<OutputType>WinExe</OutputType>
+8 -2
View File
@@ -155,6 +155,7 @@ namespace osu.Game.Rulesets.Catch
new CatchModMuted(),
new CatchModNoScope(),
new CatchModMovingFast(),
new CatchModSynesthesia(),
};
case ModType.System:
@@ -176,15 +177,20 @@ namespace osu.Game.Rulesets.Catch
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch };
protected override IEnumerable<HitResult> GetValidHitResults()
public override IEnumerable<HitResult> GetValidHitResults()
{
return new[]
{
HitResult.Great,
HitResult.Miss,
HitResult.LargeTickHit,
HitResult.LargeTickMiss,
HitResult.SmallTickHit,
HitResult.SmallTickMiss,
HitResult.LargeBonus,
HitResult.IgnoreHit,
HitResult.IgnoreMiss,
};
}
@@ -300,7 +306,7 @@ namespace osu.Game.Rulesets.Catch
Description = "Affects how early fruits fade in on the screen.",
AdditionalMetrics =
[
new RulesetBeatmapAttribute.AdditionalMetric("Fade-in time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(effectiveDifficulty.ApproachRate, CatchHitObject.PREEMPT_RANGE):#,0.##} ms"))
new RulesetBeatmapAttribute.AdditionalMetric("Fade-in time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRangeInt(effectiveDifficulty.ApproachRate, CatchHitObject.PREEMPT_RANGE):#,0.##} ms"))
]
};
yield return new RulesetBeatmapAttribute(SongSelectStrings.HPDrain, @"HP", originalDifficulty.DrainRate, effectiveDifficulty.DrainRate, 10)
@@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
private float halfCatcherWidth;
public override int Version => 20250306;
public override int Version => 20251020;
public CatchDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
: base(ruleset, beatmap)
@@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
private double placementStartTime;
private double placementEndTime;
protected override bool IsValidForPlacement => Precision.DefinitelyBigger(HitObject.Duration, 0);
protected override bool IsValidForPlacement => base.IsValidForPlacement && (PlacementActive == PlacementState.Waiting || Precision.DefinitelyBigger(HitObject.Duration, 0));
public BananaShowerPlacementBlueprint()
{
@@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components
private readonly Path drawablePath;
private readonly List<(double Time, float X)> vertices = new List<(double, float)>();
private readonly List<Vector2> sliderVertices = new List<Vector2>();
public ScrollingPath()
{
@@ -47,9 +48,8 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components
private void computeTimeXs(JuiceStream hitObject)
{
vertices.Clear();
var sliderVertices = new List<Vector2>();
hitObject.Path.GetPathToProgress(sliderVertices, 0, 1);
sliderVertices.Clear();
sliderVertices.AddRange(hitObject.Path.CalculatedPath);
if (sliderVertices.Count == 0)
return;
@@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
private InputManager inputManager = null!;
protected override bool IsValidForPlacement => Precision.DefinitelyBigger(HitObject.Duration, 0);
protected override bool IsValidForPlacement => base.IsValidForPlacement && (PlacementActive == PlacementState.Waiting || Precision.DefinitelyBigger(HitObject.Duration, 0));
public JuiceStreamPlacementBlueprint()
{
@@ -14,6 +14,9 @@ namespace osu.Game.Rulesets.Catch.Edit
{
private readonly List<ICheck> checks = new List<ICheck>
{
// Audio
new CheckCatchFewHitsounds(),
// Compose
new CheckBananaShowerGap(),
new CheckConcurrentObjects(),
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using osu.Framework.Allocation;
@@ -224,7 +225,8 @@ namespace osu.Game.Rulesets.Catch.Edit
#region Clipboard handling
public override string ConvertSelectionToString()
=> string.Join(',', EditorBeatmap.SelectedHitObjects.Cast<CatchHitObject>().OrderBy(h => h.StartTime).Select(h => (h.IndexInCurrentCombo + 1).ToString()));
=> string.Join(',', EditorBeatmap.SelectedHitObjects.Cast<CatchHitObject>().OrderBy(h => h.StartTime)
.Select(h => (h.IndexInCurrentCombo + 1).ToString(CultureInfo.InvariantCulture)));
// 1,2,3,4 ...
private static readonly Regex selection_regex = new Regex(@"^\d+(,\d+)*$", RegexOptions.Compiled);
@@ -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 osu.Game.Rulesets.Edit.Checks;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Catch.Objects;
namespace osu.Game.Rulesets.Catch.Edit.Checks
{
public class CheckCatchFewHitsounds : CheckFewHitsounds
{
protected override bool IsExcludedFromHitsounding(HitObject hitObject) => hitObject is BananaShower;
}
}
@@ -117,6 +117,15 @@ namespace osu.Game.Rulesets.Catch.Edit.Setup
Beatmap.Difficulty.CircleSize = circleSizeSlider.Current.Value;
Beatmap.Difficulty.DrainRate = healthDrainSlider.Current.Value;
Beatmap.Difficulty.ApproachRate = approachRateSlider.Current.Value;
// in lazer catch, Overall Difficulty does *nothing* - as it should be in a sane world.
// in stable, it does *one extremely specific thing* which is influence the infamous `difficultyPeppyStars`
// which in turn affects score V1 (see `LegacyRulesetExtensions.CalculateDifficultyPeppyStars()`).
// there is a Ranking Criteria rule saying that Overall Difficulty and Approach Rate should match:
// https://osu.ppy.sh/wiki/en/Ranking_criteria/osu!catch
// the one case wherein that breaks stable is on some marathon maps;
// on those setting Overall Difficulty too high can lead to score V1 exceeding 32 bits ("score overflow").
// that case can be manually handled by mappers.
Beatmap.Difficulty.OverallDifficulty = approachRateSlider.Current.Value;
Beatmap.Difficulty.SliderMultiplier = baseVelocitySlider.Current.Value;
Beatmap.Difficulty.SliderTickRate = tickRateSlider.Current.Value;
@@ -51,7 +51,8 @@ namespace osu.Game.Rulesets.Catch.Mods
return string.Empty;
string format(string acronym, DifficultyBindable bindable) => $"{acronym}{bindable.Value!.Value.ToStandardFormattedString(1)}";
string format(string acronym, DifficultyBindable bindable)
=> $"{acronym}{bindable.Value!.Value.ToStandardFormattedString(1)}";
}
}
@@ -0,0 +1,60 @@
// 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.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Screens.Edit;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Catch.Mods
{
/// <summary>
/// Mod that colours <see cref="HitObject"/>s based on the musical division they are on
/// </summary>
public class CatchModSynesthesia : ModSynesthesia, IApplicableToBeatmap, IApplicableToDrawableHitObject
{
private readonly OsuColour colours = new OsuColour();
private IBeatmap? currentBeatmap { get; set; }
public void ApplyToBeatmap(IBeatmap beatmap)
{
//Store a reference to the current beatmap to look up the beat divisor when notes are drawn
if (currentBeatmap != beatmap)
currentBeatmap = beatmap;
}
public void ApplyToDrawableHitObject(DrawableHitObject d)
{
if (currentBeatmap == null) return;
Color4? timingBasedColour = null;
d.HitObjectApplied += _ =>
{
// Block bananas from getting coloured.
if (d.HitObject is not Banana)
{
timingBasedColour = BindableBeatDivisor.GetColourFor(currentBeatmap.ControlPointInfo.GetClosestBeatDivisor(d.HitObject.StartTime), colours);
}
// Colour droplets into a solid colour, as droplets aren't generated snapped to timeline ticks.
if (d.HitObject is Droplet)
{
timingBasedColour = Color4.LightGreen;
}
};
// Need to set this every update to ensure it doesn't get overwritten by DrawableHitObject.OnApply() -> UpdateComboColour().
d.OnUpdate += _ =>
{
if (timingBasedColour != null)
d.AccentColour.Value = timingBasedColour.Value;
};
}
}
}
+17 -4
View File
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using osu.Game.Audio;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Types;
@@ -53,13 +54,25 @@ namespace osu.Game.Rulesets.Catch.Objects
public override IEnumerable<string> LookupNames => lookup_names;
public BananaHitSampleInfo(int volume = 100)
: base(string.Empty, volume: volume)
public BananaHitSampleInfo()
: this(string.Empty)
{
}
public sealed override HitSampleInfo With(Optional<string> newName = default, Optional<string> newBank = default, Optional<string?> newSuffix = default, Optional<int> newVolume = default, Optional<bool> newEditorAutoBank = default)
=> new BananaHitSampleInfo(newVolume.GetOr(Volume));
public BananaHitSampleInfo(HitSampleInfo info)
: this(info.Name, info.Bank, info.Suffix, info.Volume, info.EditorAutoBank, info.UseBeatmapSamples)
{
}
private BananaHitSampleInfo(string name, string bank = SampleControlPoint.DEFAULT_BANK, string? suffix = null, int volume = 100, bool editorAutoBank = true, bool useBeatmapSamples = false)
: base(name, bank, suffix, volume, editorAutoBank, useBeatmapSamples)
{
}
public sealed override HitSampleInfo With(Optional<string> newName = default, Optional<string> newBank = default, Optional<string?> newSuffix = default, Optional<int> newVolume = default,
Optional<bool> newEditorAutoBank = default, Optional<bool> newUseBeatmapSamples = default)
=> new BananaHitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank), newSuffix.GetOr(Suffix), newVolume.GetOr(Volume),
newEditorAutoBank.GetOr(EditorAutoBank), newUseBeatmapSamples.GetOr(UseBeatmapSamples));
public bool Equals(BananaHitSampleInfo? other)
=> other != null;
@@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{
StartTime = time,
BananaIndex = count,
Samples = new List<HitSampleInfo> { new Banana.BananaHitSampleInfo(CreateHitSampleInfo().Volume) }
Samples = new List<HitSampleInfo> { new Banana.BananaHitSampleInfo(CreateHitSampleInfo()) }
});
count++;
@@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
TimePreempt = (float)IBeatmapDifficultyInfo.DifficultyRange(difficulty.ApproachRate, PREEMPT_RANGE);
TimePreempt = IBeatmapDifficultyInfo.DifficultyRangeInt(difficulty.ApproachRate, PREEMPT_RANGE);
Scale = LegacyRulesetExtensions.CalculateScaleFromCircleSize(difficulty.CircleSize);
}
@@ -175,8 +175,7 @@ namespace osu.Game.Rulesets.Catch.Objects
/// </remarks>
public void ConvertFromSliderPath(SliderPath sliderPath, double velocity)
{
var sliderPathVertices = new List<Vector2>();
sliderPath.GetPathToProgress(sliderPathVertices, 0, 1);
var sliderPathVertices = sliderPath.CalculatedPath;
double time = 0;
@@ -72,6 +72,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
leaderboard.Origin = Anchor.CentreLeft;
leaderboard.X = 10;
}
foreach (var d in container.OfType<ISerialisableDrawable>())
d.UsesFixedAnchor = true;
})
{
Children = new Drawable[]
@@ -19,6 +19,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
<ProjectReference Include="..\osu.Game.Tests\osu.Game.Tests.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
</Project>
+1 -3
View File
@@ -35,11 +35,9 @@
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict>
</plist>
</plist>
@@ -13,6 +13,7 @@
</Compile>
</ItemGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game.Tests\osu.Game.Tests.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
</ItemGroup>
@@ -0,0 +1,351 @@
// 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 NUnit.Framework;
using osu.Framework.Testing;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Tests.Visual;
using osuTK;
using osuTK.Input;
using DragArea = osu.Game.Screens.Edit.Compose.Components.Timeline.TimelineHitObjectBlueprint.DragArea;
namespace osu.Game.Rulesets.Mania.Tests.Editor
{
public partial class TestSceneHoldNoteTailDrag : EditorTestScene
{
protected override Ruleset CreateEditorRuleset() => new ManiaRuleset();
[SetUpSteps]
public override void SetUpSteps()
{
base.SetUpSteps();
AddStep("Clear objects", () => EditorBeatmap.Clear());
}
[Test]
public void TestSimpleTailDragForward()
{
AddStep("Add hold note", () =>
{
EditorBeatmap.Add(new HoldNote { StartTime = 2170, Duration = 937.5 });
});
AddStep("Drag tail", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().Single();
dragForward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Duration is higher", () => ((HoldNote)EditorBeatmap.HitObjects.First())!.Duration > 937.5f);
}
[Test]
public void TestSimpleTailDragBackwards()
{
AddStep("Add hold note", () =>
{
EditorBeatmap.Add(new HoldNote { StartTime = 2170, Duration = 937.5 });
});
AddStep("Drag tail", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().Single();
dragBackward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Duration is lower", () => ((HoldNote)EditorBeatmap.HitObjects[0]).Duration < 937.5f);
}
[Test]
public void TestSamePositionButNotSelectedDragForward()
{
AddStep("Add hold notes", () =>
{
EditorBeatmap.AddRange([
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 0 },
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 1 }
]);
});
AddStep("Drag tail", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().First();
dragForward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Duration is higher, other is unchanged", () =>
((HoldNote)EditorBeatmap.HitObjects[0]).Duration > 937.5f &&
((HoldNote)EditorBeatmap.HitObjects[^1]).Duration == 937.5f
);
}
[Test]
public void TestSamePositionButNotSelectedDragBackward()
{
AddStep("Add hold notes", () =>
{
EditorBeatmap.AddRange([
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 0 },
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 1 }
]);
});
AddStep("Drag tail", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().First();
dragBackward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Duration is lower, other is unchanged", () =>
((HoldNote)EditorBeatmap.HitObjects[0]).Duration < 937.5f &&
((HoldNote)EditorBeatmap.HitObjects[^1]).Duration == 937.5f
);
}
[Test]
public void TestSamePositionSelectedDragForward()
{
AddStep("Add hold notes", () =>
{
EditorBeatmap.AddRange([
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 0 },
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 1 }
]);
});
AddStep("Select all", () =>
{
EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects);
});
AddStep("Drag tail", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().First();
dragForward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Both durations are higher", () =>
((HoldNote)EditorBeatmap.HitObjects[0]).Duration > 937.5f &&
((HoldNote)EditorBeatmap.HitObjects[^1]).Duration > 937.5f
);
}
[Test]
public void TestSamePositionSelectedDragBackward()
{
AddStep("Add hold notes", () =>
{
EditorBeatmap.AddRange([
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 0 },
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 1 }
]);
});
AddStep("Select all", () =>
{
EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects);
});
AddStep("Drag tail", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().First();
dragBackward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Both durations are lower", () =>
((HoldNote)EditorBeatmap.HitObjects[0]).Duration < 937.5f &&
((HoldNote)EditorBeatmap.HitObjects[^1]).Duration < 937.5f
);
}
[Test]
public void TestSelectedButDifferentPositions()
{
AddStep("Add hold notes", () =>
{
EditorBeatmap.AddRange([
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 0 },
new HoldNote { StartTime = 2404, Duration = 937.5, Column = 1 }
]);
});
AddStep("Select all", () =>
{
EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects);
});
AddStep("Drag tail", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().First();
dragBackward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Duration is unchanged, other is lower", () =>
((HoldNote)EditorBeatmap.HitObjects[0]).Duration == 937.5f &&
((HoldNote)EditorBeatmap.HitObjects[^1]).Duration < 937.5f
);
}
[Test]
public void TestSelectedSameStartTimeDifferentDurations()
{
AddStep("Add hold notes", () =>
{
EditorBeatmap.AddRange([
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 0 },
new HoldNote { StartTime = 2170, Duration = 1171.8, Column = 1 }
]);
});
AddStep("Select all", () =>
{
EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects);
});
AddStep("Drag until both match", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().First();
InputManager.MoveMouseTo(blueprintDragArea);
InputManager.PressKey(Key.LShift);
InputManager.PressButton(MouseButton.Left);
InputManager.MoveMouseTo(new Vector2(1000, 110));
});
AddStep("Continue the drag", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().First();
dragBackward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Duration is unchanged, other is lower", () =>
((HoldNote)EditorBeatmap.HitObjects[0]).Duration == 937.5f &&
((HoldNote)EditorBeatmap.HitObjects[^1]).Duration < 937.5f
);
}
[Test]
public void TestSelectedSameDurationDifferentStartTimes()
{
AddStep("Add hold notes", () =>
{
EditorBeatmap.AddRange([
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 0 },
new HoldNote { StartTime = 2638.7, Duration = 937.5, Column = 1 }
]);
});
AddStep("Select all", () =>
{
EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects);
});
AddStep("Drag tail", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().First();
dragBackward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Duration is unchanged, other is lower", () =>
((HoldNote)EditorBeatmap.HitObjects[0]).Duration == 937.5f &&
((HoldNote)EditorBeatmap.HitObjects[^1]).Duration < 937.5f
);
}
[Test]
public void TestDragNoteOutsideOfSelection()
{
AddStep("Add hold notes", () =>
{
EditorBeatmap.AddRange([
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 0 },
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 1 }
]);
});
AddStep("Select the back stack slider", () =>
{
EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects.Last());
});
AddStep("Drag tail", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().First();
dragBackward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Duration is lower, other is unchanged", () =>
((HoldNote)EditorBeatmap.HitObjects[0]).Duration < 937.5f &&
((HoldNote)EditorBeatmap.HitObjects[^1]).Duration == 937.5f
);
}
[Test]
public void TestDragHoldNoteWithNotes()
{
AddStep("Add notes", () =>
{
EditorBeatmap.AddRange([
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 0 },
new Note { StartTime = 2170, Column = 1 },
new Note { StartTime = 3107.5, Column = 2 },
new HoldNote { StartTime = 2170, Duration = 937.5, Column = 3 }
]);
});
AddStep("Select all", () =>
{
EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects);
});
AddStep("Drag tail", () =>
{
var blueprintDragArea = this.ChildrenOfType<DragArea>().First();
dragBackward(blueprintDragArea);
});
AddStep("Release tail", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("Both durations are lower", () =>
{
var holdNotes = EditorBeatmap.HitObjects.OfType<HoldNote>();
return holdNotes.First().Duration < 937.5f && holdNotes.Last().Duration < 937.5f;
}
);
}
private void dragForward(DragArea dragArea)
{
InputManager.MoveMouseTo(dragArea);
InputManager.PressButton(MouseButton.Left);
InputManager.MoveMouseTo(new Vector2(1100, 110));
}
private void dragBackward(DragArea dragArea)
{
InputManager.MoveMouseTo(dragArea);
InputManager.PressButton(MouseButton.Left);
InputManager.MoveMouseTo(new Vector2(700, 110));
}
}
}
@@ -20,10 +20,10 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
[Test]
public void TestKeyCountChange()
{
FormSliderBar<float> keyCount = null!;
FormSliderBar<int> keyCount = null!;
AddStep("go to setup screen", () => InputManager.Key(Key.F4));
AddUntilStep("retrieve key count slider", () => keyCount = Editor.ChildrenOfType<SetupScreen>().Single().ChildrenOfType<FormSliderBar<float>>().First(), () => Is.Not.Null);
AddUntilStep("retrieve key count slider", () => keyCount = Editor.ChildrenOfType<SetupScreen>().Single().ChildrenOfType<FormSliderBar<int>>().First(), () => Is.Not.Null);
AddAssert("key count is 5", () => keyCount.Current.Value, () => Is.EqualTo(5));
AddStep("change key count to 8", () =>
{
@@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
});
AddUntilStep("dialog visible", () => Game.ChildrenOfType<IDialogOverlay>().SingleOrDefault()?.CurrentDialog, Is.InstanceOf<SaveAndReloadEditorDialog>);
AddStep("refuse", () => InputManager.Key(Key.Number2));
AddAssert("key count is 5", () => keyCount.Current.Value, () => Is.EqualTo(5));
AddUntilStep("key count is 5", () => keyCount.Current.Value, () => Is.EqualTo(5));
AddStep("change key count to 8 again", () =>
{
@@ -41,5 +41,32 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
AddStep("acquiesce", () => InputManager.Key(Key.Number1));
AddUntilStep("beatmap became 8K", () => Game.Beatmap.Value.BeatmapInfo.Difficulty.CircleSize, () => Is.EqualTo(8));
}
[Test]
public void TestDualStagesChange()
{
FormCheckBox dualStages = null!;
FormSliderBar<int> keyCount = null!;
AddStep("go to setup screen", () => InputManager.Key(Key.F4));
AddUntilStep("retrieve dual stages checkbox", () => dualStages = Editor.ChildrenOfType<SetupScreen>().Single().ChildrenOfType<FormCheckBox>().First(), () => Is.Not.Null);
AddUntilStep("retrieve key count slider", () => keyCount = Editor.ChildrenOfType<SetupScreen>().Single().ChildrenOfType<FormSliderBar<int>>().First(), () => Is.Not.Null);
AddAssert("key count is 5", () => keyCount.Current.Value, () => Is.EqualTo(5));
AddStep("set dual stages", () =>
{
dualStages.Current.Value = true;
});
AddUntilStep("dialog visible", () => Game.ChildrenOfType<IDialogOverlay>().SingleOrDefault()?.CurrentDialog, Is.InstanceOf<SaveAndReloadEditorDialog>);
AddStep("refuse", () => InputManager.Key(Key.Number2));
AddUntilStep("key count is 5", () => keyCount.Current.Value, () => Is.EqualTo(5));
AddStep("set dual stages again", () =>
{
dualStages.Current.Value = true;
});
AddUntilStep("dialog visible", () => Game.ChildrenOfType<IDialogOverlay>().Single().CurrentDialog, Is.InstanceOf<SaveAndReloadEditorDialog>);
AddStep("acquiesce", () => InputManager.Key(Key.Number1));
AddUntilStep("beatmap became 12K", () => Game.Beatmap.Value.BeatmapInfo.Difficulty.CircleSize, () => Is.EqualTo(12));
}
}
}
@@ -5,6 +5,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Testing;
using osu.Game.Rulesets.Edit;
@@ -16,6 +17,7 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Screens.Edit;
using osu.Game.Tests.Visual;
using osuTK.Input;
@@ -36,21 +38,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
[Test]
public void TestPlaceBeforeCurrentTimeDownwards()
{
AddStep("seek to 200", () => HitObjectContainer.Dependencies.Get<EditorClock>().Seek(200));
AddStep("move mouse before current time", () =>
{
var column = this.ChildrenOfType<Column>().Single();
InputManager.MoveMouseTo(column.ScreenSpacePositionAtTime(-100));
});
AddStep("click", () => InputManager.Click(MouseButton.Left));
AddAssert("note start time < 0", () => getNote().StartTime < 0);
}
[Test]
public void TestPlaceAfterCurrentTimeDownwards()
{
AddStep("move mouse after current time", () =>
{
var column = this.ChildrenOfType<Column>().Single();
InputManager.MoveMouseTo(column.ScreenSpacePositionAtTime(100));
@@ -58,7 +47,22 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
AddStep("click", () => InputManager.Click(MouseButton.Left));
AddAssert("note start time > 0", () => getNote().StartTime > 0);
AddAssert("note start time < 200", () => getNote().StartTime < 200);
}
[Test]
public void TestPlaceAfterCurrentTimeDownwards()
{
AddStep("seek to 200", () => HitObjectContainer.Dependencies.Get<EditorClock>().Seek(200));
AddStep("move mouse after current time", () =>
{
var column = this.ChildrenOfType<Column>().Single();
InputManager.MoveMouseTo(column.ScreenSpacePositionAtTime(300));
});
AddStep("click", () => InputManager.Click(MouseButton.Left));
AddAssert("note start time > 200", () => getNote().StartTime > 200);
}
private Note getNote() => this.ChildrenOfType<DrawableNote>().FirstOrDefault()?.HitObject;
@@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
AddStep("change seek setting to true", () => config.SetValue(OsuSetting.EditorAutoSeekOnPlacement, true));
placeObject();
AddUntilStep("wait for seek to complete", () => !EditorClock.IsSeeking);
AddAssert("seeked forward to object", () => EditorClock.CurrentTime, () => Is.GreaterThan(initialTime));
AddAssert("seeked forward to object", () => EditorClock.CurrentTime, () => Is.GreaterThan(initialTime!));
}
[Test]
@@ -57,6 +57,28 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
AddAssert("time is unchanged", () => EditorClock.CurrentTime, () => Is.EqualTo(initialTime));
}
[Test]
public void TestNoTwoObjectsAtSameTimeAndColumn()
{
AddStep("change seek setting to false", () => config.SetValue(OsuSetting.EditorAutoSeekOnPlacement, false));
AddStep("clear beatmap", () => EditorBeatmap.Clear());
AddStep("select note placement tool", () => InputManager.Key(Key.Number2));
AddStep("move mouse to centre of last column", () => InputManager.MoveMouseTo(this.ChildrenOfType<Column>().Last().ScreenSpaceDrawQuad.Centre));
AddStep("place note", () => InputManager.Click(MouseButton.Left));
AddAssert("beatmap has 1 object", () => EditorBeatmap.HitObjects, () => Has.Count.EqualTo(1));
AddStep("select note placement tool", () => InputManager.Key(Key.Number2));
AddStep("move mouse to centre of first column", () => InputManager.MoveMouseTo(this.ChildrenOfType<Column>().First().ScreenSpaceDrawQuad.Centre));
AddStep("place note", () => InputManager.Click(MouseButton.Left));
AddAssert("beatmap has 2 objects", () => EditorBeatmap.HitObjects, () => Has.Count.EqualTo(2));
AddStep("select note placement tool", () => InputManager.Key(Key.Number2));
AddStep("move mouse to centre of last column", () => InputManager.MoveMouseTo(this.ChildrenOfType<Column>().Last().ScreenSpaceDrawQuad.Centre));
AddStep("place note", () => InputManager.Click(MouseButton.Left));
AddAssert("beatmap has 2 objects", () => EditorBeatmap.HitObjects, () => Has.Count.EqualTo(2));
}
private void placeObject()
{
AddStep("select note placement tool", () => InputManager.Key(Key.Number2));
@@ -18,15 +18,11 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
public void TestNormalSelection()
{
addStepClickLink("00:05:920 (5920|3,6623|3,6857|2,7326|1)");
AddAssert("selected group", () => checkSnapAndSelectColumn(5_920, new List<(int, int)>
{ (5_920, 3), (6_623, 3), (6_857, 2), (7_326, 1) }
));
AddAssert("selected group", () => checkSnapAndSelectColumn(5_920, [(5_920, 3), (6_623, 3), (6_857, 2), (7_326, 1)]));
addReset();
addStepClickLink("00:42:716 (42716|3,43420|2,44123|0,44357|1,45295|1)");
AddAssert("selected ungrouped", () => checkSnapAndSelectColumn(42_716, new List<(int, int)>
{ (42_716, 3), (43_420, 2), (44_123, 0), (44_357, 1), (45_295, 1) }
));
AddAssert("selected ungrouped", () => checkSnapAndSelectColumn(42_716, [(42_716, 3), (43_420, 2), (44_123, 0), (44_357, 1), (45_295, 1)]));
addReset();
AddStep("add notes to row", () =>
@@ -41,15 +37,20 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
EditorBeatmap.AddRange(new[] { second, third, forth });
});
addStepClickLink("00:11:545 (11545|0,11545|1,11545|2,11545|3)");
AddAssert("selected in row", () => checkSnapAndSelectColumn(11_545, new List<(int, int)>
{ (11_545, 0), (11_545, 1), (11_545, 2), (11_545, 3) }
));
AddAssert("selected in row", () => checkSnapAndSelectColumn(11_545, [(11_545, 0), (11_545, 1), (11_545, 2), (11_545, 3)]));
addReset();
addStepClickLink("01:36:623 (96623|1,97560|1,97677|1,97795|1,98966|1)");
AddAssert("selected in column", () => checkSnapAndSelectColumn(96_623, new List<(int, int)>
{ (96_623, 1), (97_560, 1), (97_677, 1), (97_795, 1), (98_966, 1) }
));
AddAssert("selected in column", () => checkSnapAndSelectColumn(96_623, [(96_623, 1), (97_560, 1), (97_677, 1), (97_795, 1), (98_966, 1)]));
}
[Test]
public void TestRoundingToNearestMillisecondApplied()
{
AddStep("resnap note to have fractional coordinates",
() => EditorBeatmap.HitObjects.OfType<ManiaHitObject>().Single(ho => ho.StartTime == 85_373 && ho.Column == 1).StartTime = 85_373.125);
addStepClickLink("01:25:373 (85373|1)");
AddAssert("selected note", () => checkSnapAndSelectColumn(85_373.125, [(85_373.125, 1)]));
}
[Test]
@@ -75,7 +76,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
private void addReset() => addStepClickLink("00:00:000", "reset", false);
private bool checkSnapAndSelectColumn(double startTime, IReadOnlyCollection<(int, int)>? columnPairs = null)
private bool checkSnapAndSelectColumn(double startTime, IReadOnlyCollection<(double, int)>? columnPairs = null)
{
bool checkColumns = columnPairs != null
? EditorBeatmap.SelectedHitObjects.All(x => columnPairs.Any(col => isNoteAt(x, col.Item1, col.Item2)))
@@ -27,6 +27,24 @@ namespace osu.Game.Rulesets.Mania.Tests
[TestCase("100374")]
[TestCase("1450162")]
[TestCase("4869637")]
[TestCase("1K")]
[TestCase("2K")]
[TestCase("3K")]
[TestCase("4K")]
[TestCase("5K")]
[TestCase("6K")]
[TestCase("7K")]
[TestCase("8K")]
[TestCase("9K")]
[TestCase("10K")]
// [TestCase("11K")] <- See comment in `ManiaBeatmapConverter` ctor for disable reason.
[TestCase("12K")]
// [TestCase("13K")] <- See comment in `ManiaBeatmapConverter` ctor for disable reason.
[TestCase("14K")]
// [TestCase("15K")] <- See comment in `ManiaBeatmapConverter` ctor for disable reason.
[TestCase("16K")]
// [TestCase("17K")] <- See comment in `ManiaBeatmapConverter` ctor for disable reason.
[TestCase("18K")]
public void Test(string name) => base.Test(name);
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)
@@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Mania.Tests
[TestCase("mania-samples")]
[TestCase("mania-slider")] // e.g. second and fourth notes of https://osu.ppy.sh/beatmapsets/73883#mania/216407
[TestCase("slider-convert-samples")]
[TestCase("spinner-convert-samples")]
public void Test(string name) => base.Test(name);
protected override IEnumerable<SampleConvertValue> CreateConvertValue(HitObject hitObject)
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using NUnit.Framework.Legacy;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Screens.Select;
@@ -18,19 +19,19 @@ namespace osu.Game.Rulesets.Mania.Tests
var criteria = new ManiaFilterCriteria();
criteria.TryParseCustomKeywordCriteria("keys", Operator.Equal, "1");
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 1 }),
new FilterCriteria()));
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 2 }),
new FilterCriteria()));
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 3 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new RulesetInfo { OnlineID = 0 }, new BeatmapDifficulty { CircleSize = 4 }),
new FilterCriteria
{
@@ -44,19 +45,19 @@ namespace osu.Game.Rulesets.Mania.Tests
var criteria = new ManiaFilterCriteria();
criteria.TryParseCustomKeywordCriteria("keys", Operator.Equal, "1,3,5,7");
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 1 }),
new FilterCriteria()));
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 2 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 3 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new RulesetInfo { OnlineID = 0 }, new BeatmapDifficulty { CircleSize = 4 }),
new FilterCriteria
{
@@ -70,19 +71,19 @@ namespace osu.Game.Rulesets.Mania.Tests
var criteria = new ManiaFilterCriteria();
criteria.TryParseCustomKeywordCriteria("keys", Operator.NotEqual, "1");
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 1 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 2 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 3 }),
new FilterCriteria()));
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new RulesetInfo { OnlineID = 0 }, new BeatmapDifficulty { CircleSize = 4 }),
new FilterCriteria
{
@@ -96,19 +97,19 @@ namespace osu.Game.Rulesets.Mania.Tests
var criteria = new ManiaFilterCriteria();
criteria.TryParseCustomKeywordCriteria("keys", Operator.NotEqual, "1,3,5,7");
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 1 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 2 }),
new FilterCriteria()));
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 3 }),
new FilterCriteria()));
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new RulesetInfo { OnlineID = 0 }, new BeatmapDifficulty { CircleSize = 4 }),
new FilterCriteria
{
@@ -122,23 +123,23 @@ namespace osu.Game.Rulesets.Mania.Tests
var criteria = new ManiaFilterCriteria();
criteria.TryParseCustomKeywordCriteria("keys", Operator.GreaterOrEqual, "4");
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 1 }),
new FilterCriteria()));
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 2 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 4 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 5 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new RulesetInfo { OnlineID = 0 }, new BeatmapDifficulty { CircleSize = 3 }),
new FilterCriteria
{
@@ -153,23 +154,23 @@ namespace osu.Game.Rulesets.Mania.Tests
criteria.TryParseCustomKeywordCriteria("keys", Operator.Greater, "4");
criteria.TryParseCustomKeywordCriteria("keys", Operator.NotEqual, "7");
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 3 }),
new FilterCriteria()));
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 4 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 5 }),
new FilterCriteria()));
Assert.False(criteria.Matches(
ClassicAssert.False(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 7 }),
new FilterCriteria()));
Assert.True(criteria.Matches(
ClassicAssert.True(criteria.Matches(
new BeatmapInfo(new ManiaRuleset().RulesetInfo, new BeatmapDifficulty { CircleSize = 9 }),
new FilterCriteria()));
}
@@ -179,9 +180,9 @@ namespace osu.Game.Rulesets.Mania.Tests
{
var criteria = new ManiaFilterCriteria();
Assert.False(criteria.TryParseCustomKeywordCriteria("keys", Operator.Equal, "some text"));
Assert.False(criteria.TryParseCustomKeywordCriteria("keys", Operator.NotEqual, "4,some text"));
Assert.False(criteria.TryParseCustomKeywordCriteria("keys", Operator.GreaterOrEqual, "4,5,6"));
ClassicAssert.False(criteria.TryParseCustomKeywordCriteria("keys", Operator.Equal, "some text"));
ClassicAssert.False(criteria.TryParseCustomKeywordCriteria("keys", Operator.NotEqual, "4,some text"));
ClassicAssert.False(criteria.TryParseCustomKeywordCriteria("keys", Operator.GreaterOrEqual, "4,5,6"));
}
[TestCase]
@@ -199,7 +200,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 0,
EndTimeObjectCount = 0
};
Assert.True(criteria.Matches(beatmapInfo1, filterCriteria));
ClassicAssert.True(criteria.Matches(beatmapInfo1, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "0");
BeatmapInfo beatmapInfo2 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
@@ -207,7 +208,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 100,
EndTimeObjectCount = 0
};
Assert.True(criteria.Matches(beatmapInfo2, filterCriteria));
ClassicAssert.True(criteria.Matches(beatmapInfo2, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "100");
BeatmapInfo beatmapInfo3 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
@@ -215,7 +216,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 100,
EndTimeObjectCount = 100
};
Assert.True(criteria.Matches(beatmapInfo3, filterCriteria));
ClassicAssert.True(criteria.Matches(beatmapInfo3, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "1");
BeatmapInfo beatmapInfo4 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
@@ -223,7 +224,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 100,
EndTimeObjectCount = 1
};
Assert.True(criteria.Matches(beatmapInfo4, filterCriteria));
ClassicAssert.True(criteria.Matches(beatmapInfo4, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "0.1");
BeatmapInfo beatmapInfo5 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
@@ -231,7 +232,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 1000,
EndTimeObjectCount = 1
};
Assert.True(criteria.Matches(beatmapInfo5, filterCriteria));
ClassicAssert.True(criteria.Matches(beatmapInfo5, filterCriteria));
}
[TestCase]
@@ -249,7 +250,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 0,
EndTimeObjectCount = 0
};
Assert.True(criteria.Matches(beatmapInfo1, filterCriteria));
ClassicAssert.True(criteria.Matches(beatmapInfo1, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "0");
BeatmapInfo beatmapInfo2 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
@@ -257,7 +258,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 100,
EndTimeObjectCount = 0
};
Assert.True(criteria.Matches(beatmapInfo2, filterCriteria));
ClassicAssert.True(criteria.Matches(beatmapInfo2, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "100");
BeatmapInfo beatmapInfo3 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
@@ -265,7 +266,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 100,
EndTimeObjectCount = 100
};
Assert.True(criteria.Matches(beatmapInfo3, filterCriteria));
ClassicAssert.True(criteria.Matches(beatmapInfo3, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "1");
BeatmapInfo beatmapInfo4 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
@@ -273,7 +274,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 100,
EndTimeObjectCount = 1
};
Assert.True(criteria.Matches(beatmapInfo4, filterCriteria));
ClassicAssert.True(criteria.Matches(beatmapInfo4, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "0.1");
BeatmapInfo beatmapInfo5 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
@@ -281,7 +282,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 1000,
EndTimeObjectCount = 1
};
Assert.True(criteria.Matches(beatmapInfo5, filterCriteria));
ClassicAssert.True(criteria.Matches(beatmapInfo5, filterCriteria));
}
[TestCase]
@@ -299,7 +300,7 @@ namespace osu.Game.Rulesets.Mania.Tests
TotalObjectCount = 100,
EndTimeObjectCount = 50
};
Assert.False(criteria.Matches(beatmapInfo, filterCriteria));
ClassicAssert.False(criteria.Matches(beatmapInfo, filterCriteria));
}
[TestCase]
@@ -307,8 +308,8 @@ namespace osu.Game.Rulesets.Mania.Tests
{
var criteria = new ManiaFilterCriteria();
Assert.False(criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "some text"));
Assert.False(criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "1some text"));
ClassicAssert.False(criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "some text"));
ClassicAssert.False(criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "1some text"));
}
}
}
@@ -0,0 +1,45 @@
// 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.IO.Stores;
using static osu.Game.Tests.Beatmaps.Formats.LegacyBeatmapEncoderTest;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class ManiaLegacyBeatmapEncoderTest
{
private static readonly DllResourceStore beatmaps_resource_store = new DllResourceStore(typeof(ManiaLegacyBeatmapEncoderTest).Assembly);
[TestCase("1K")]
[TestCase("2K")]
[TestCase("3K")]
[TestCase("4K")]
[TestCase("5K")]
[TestCase("6K")]
[TestCase("7K")]
[TestCase("8K")]
[TestCase("9K")]
[TestCase("10K")]
// [TestCase("11K")] <- See comment in `ManiaBeatmapConverter` ctor for disable reason.
[TestCase("12K")]
// [TestCase("13K")] <- See comment in `ManiaBeatmapConverter` ctor for disable reason.
[TestCase("14K")]
// [TestCase("15K")] <- See comment in `ManiaBeatmapConverter` ctor for disable reason.
[TestCase("16K")]
// [TestCase("17K")] <- See comment in `ManiaBeatmapConverter` ctor for disable reason.
[TestCase("18K")]
[TestCase("7K+1")]
public void TestEncodeDecodeStability(string name)
{
var decoded = DecodeFromLegacy(beatmaps_resource_store.GetStream($"Resources/Testing/Beatmaps/{name}.osu"), beatmaps_resource_store, name);
var decodedAfterEncode = DecodeFromLegacy(EncodeToLegacy(decoded), beatmaps_resource_store, name);
Sort(decoded.beatmap);
Sort(decodedAfterEncode.beatmap);
CompareBeatmaps(decoded, decodedAfterEncode);
}
}
}
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using osu.Game.Rulesets.Mania.Beatmaps;
using NUnit.Framework;
using NUnit.Framework.Legacy;
namespace osu.Game.Rulesets.Mania.Tests
{
@@ -35,7 +36,7 @@ namespace osu.Game.Rulesets.Mania.Tests
{
var definition = new StageDefinition(columns);
var results = getResults(definition);
Assert.AreEqual(special, results);
ClassicAssert.AreEqual(special, results);
}
private IEnumerable<bool> getResults(StageDefinition definition)
@@ -3,6 +3,7 @@
using System.Linq;
using NUnit.Framework;
using NUnit.Framework.Legacy;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Tests.Visual;
@@ -20,7 +21,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
public void TestMapHasNoHoldNotes()
{
var testBeatmap = createModdedBeatmap();
Assert.False(testBeatmap.HitObjects.OfType<HoldNote>().Any());
ClassicAssert.False(testBeatmap.HitObjects.OfType<HoldNote>().Any());
}
[Test]
@@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
{
public partial class TestSceneManiaModNoRelease : RateAdjustedBeatmapTestScene
{
protected override Ruleset CreateRuleset() => new ManiaRuleset();
private const double time_before_head = 250;
private const double time_head = 1500;
private const double time_during_hold_1 = 2500;
@@ -0,0 +1,10 @@
osu file format v14
[General]
Mode: 0
[TimingPoints]
0,300,4,0,2,100,1,0
[HitObjects]
444,320,1000,5,2,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":511,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":511,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":511,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":511,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":511,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":511,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":511,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]},{"RandomW":273326509,"RandomX":511,"RandomY":842502087,"RandomZ":3579807591,"StartTime":875.0,"Objects":[{"StartTime":875.0,"EndTime":875.0,"Column":7}]},{"RandomW":273326509,"RandomX":511,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1000.0,"Objects":[{"StartTime":1000.0,"EndTime":1000.0,"Column":8}]},{"RandomW":273326509,"RandomX":511,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1125.0,"Objects":[{"StartTime":1125.0,"EndTime":1125.0,"Column":9}]}]}
@@ -0,0 +1,46 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:10K
[Difficulty]
HPDrainRate:5
CircleSize:10
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
25,192,0,1,0,0:0:0:0:
76,192,125,1,0,0:0:0:0:
128,192,250,1,0,0:0:0:0:
179,192,375,1,0,0:0:0:0:
230,192,500,1,0,0:0:0:0:
281,192,625,1,0,0:0:0:0:
332,192,750,1,0,0:0:0:0:
384,192,875,1,0,0:0:0:0:
435,192,1000,1,0,0:0:0:0:
486,192,1125,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]},{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":875.0,"Objects":[{"StartTime":875.0,"EndTime":875.0,"Column":7}]},{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1000.0,"Objects":[{"StartTime":1000.0,"EndTime":1000.0,"Column":8}]},{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1125.0,"Objects":[{"StartTime":1125.0,"EndTime":1125.0,"Column":9}]},{"RandomW":273326509,"RandomX":531,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1250.0,"Objects":[{"StartTime":1250.0,"EndTime":1250.0,"Column":10}]}]}
@@ -0,0 +1,47 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:11K
[Difficulty]
HPDrainRate:5
CircleSize:11
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
23,192,0,1,0,0:0:0:0:
69,192,125,1,0,0:0:0:0:
116,192,250,1,0,0:0:0:0:
162,192,375,1,0,0:0:0:0:
209,192,500,1,0,0:0:0:0:
256,192,625,1,0,0:0:0:0:
302,192,750,1,0,0:0:0:0:
349,192,875,1,0,0:0:0:0:
395,192,1000,1,0,0:0:0:0:
442,192,1125,1,0,0:0:0:0:
488,192,1250,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":875.0,"Objects":[{"StartTime":875.0,"EndTime":875.0,"Column":7}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1000.0,"Objects":[{"StartTime":1000.0,"EndTime":1000.0,"Column":8}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1125.0,"Objects":[{"StartTime":1125.0,"EndTime":1125.0,"Column":9}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1250.0,"Objects":[{"StartTime":1250.0,"EndTime":1250.0,"Column":10}]},{"RandomW":273326509,"RandomX":551,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1375.0,"Objects":[{"StartTime":1375.0,"EndTime":1375.0,"Column":11}]}]}
@@ -0,0 +1,48 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:12K
[Difficulty]
HPDrainRate:5
CircleSize:12
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
21,192,0,1,0,0:0:0:0:
64,192,125,1,0,0:0:0:0:
106,192,250,1,0,0:0:0:0:
149,192,375,1,0,0:0:0:0:
192,192,500,1,0,0:0:0:0:
234,192,625,1,0,0:0:0:0:
277,192,750,1,0,0:0:0:0:
320,192,875,1,0,0:0:0:0:
362,192,1000,1,0,0:0:0:0:
405,192,1125,1,0,0:0:0:0:
448,192,1250,1,0,0:0:0:0:
490,192,1375,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":875.0,"Objects":[{"StartTime":875.0,"EndTime":875.0,"Column":7}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1000.0,"Objects":[{"StartTime":1000.0,"EndTime":1000.0,"Column":8}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1125.0,"Objects":[{"StartTime":1125.0,"EndTime":1125.0,"Column":9}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1250.0,"Objects":[{"StartTime":1250.0,"EndTime":1250.0,"Column":10}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1375.0,"Objects":[{"StartTime":1375.0,"EndTime":1375.0,"Column":11}]},{"RandomW":273326509,"RandomX":571,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1500.0,"Objects":[{"StartTime":1500.0,"EndTime":1500.0,"Column":12}]}]}
@@ -0,0 +1,49 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:13K
[Difficulty]
HPDrainRate:5
CircleSize:13
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
19,192,0,1,0,0:0:0:0:
59,192,125,1,0,0:0:0:0:
98,192,250,1,0,0:0:0:0:
137,192,375,1,0,0:0:0:0:
177,192,500,1,0,0:0:0:0:
216,192,625,1,0,0:0:0:0:
256,192,750,1,0,0:0:0:0:
295,192,875,1,0,0:0:0:0:
334,192,1000,1,0,0:0:0:0:
374,192,1125,1,0,0:0:0:0:
413,192,1250,1,0,0:0:0:0:
452,192,1375,1,0,0:0:0:0:
492,192,1500,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":875.0,"Objects":[{"StartTime":875.0,"EndTime":875.0,"Column":7}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1000.0,"Objects":[{"StartTime":1000.0,"EndTime":1000.0,"Column":8}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1125.0,"Objects":[{"StartTime":1125.0,"EndTime":1125.0,"Column":9}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1250.0,"Objects":[{"StartTime":1250.0,"EndTime":1250.0,"Column":10}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1375.0,"Objects":[{"StartTime":1375.0,"EndTime":1375.0,"Column":11}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1500.0,"Objects":[{"StartTime":1500.0,"EndTime":1500.0,"Column":12}]},{"RandomW":273326509,"RandomX":591,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1625.0,"Objects":[{"StartTime":1625.0,"EndTime":1625.0,"Column":13}]}]}
@@ -0,0 +1,50 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:14K
[Difficulty]
HPDrainRate:5
CircleSize:14
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
18,192,0,1,0,0:0:0:0:
54,192,125,1,0,0:0:0:0:
91,192,250,1,0,0:0:0:0:
128,192,375,1,0,0:0:0:0:
164,192,500,1,0,0:0:0:0:
201,192,625,1,0,0:0:0:0:
237,192,750,1,0,0:0:0:0:
274,192,875,1,0,0:0:0:0:
310,192,1000,1,0,0:0:0:0:
347,192,1125,1,0,0:0:0:0:
384,192,1250,1,0,0:0:0:0:
420,192,1375,1,0,0:0:0:0:
457,192,1500,1,0,0:0:0:0:
493,192,1625,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":875.0,"Objects":[{"StartTime":875.0,"EndTime":875.0,"Column":7}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1000.0,"Objects":[{"StartTime":1000.0,"EndTime":1000.0,"Column":8}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1125.0,"Objects":[{"StartTime":1125.0,"EndTime":1125.0,"Column":9}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1250.0,"Objects":[{"StartTime":1250.0,"EndTime":1250.0,"Column":10}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1375.0,"Objects":[{"StartTime":1375.0,"EndTime":1375.0,"Column":11}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1500.0,"Objects":[{"StartTime":1500.0,"EndTime":1500.0,"Column":12}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1625.0,"Objects":[{"StartTime":1625.0,"EndTime":1625.0,"Column":13}]},{"RandomW":273326509,"RandomX":611,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1750.0,"Objects":[{"StartTime":1750.0,"EndTime":1750.0,"Column":14}]}]}
@@ -0,0 +1,51 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:15K
[Difficulty]
HPDrainRate:5
CircleSize:15
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
17,192,0,1,0,0:0:0:0:
51,192,125,1,0,0:0:0:0:
85,192,250,1,0,0:0:0:0:
119,192,375,1,0,0:0:0:0:
153,192,500,1,0,0:0:0:0:
187,192,625,1,0,0:0:0:0:
221,192,750,1,0,0:0:0:0:
256,192,875,1,0,0:0:0:0:
290,192,1000,1,0,0:0:0:0:
324,192,1125,1,0,0:0:0:0:
358,192,1250,1,0,0:0:0:0:
392,192,1375,1,0,0:0:0:0:
426,192,1500,1,0,0:0:0:0:
460,192,1625,1,0,0:0:0:0:
494,192,1750,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":875.0,"Objects":[{"StartTime":875.0,"EndTime":875.0,"Column":7}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1000.0,"Objects":[{"StartTime":1000.0,"EndTime":1000.0,"Column":8}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1125.0,"Objects":[{"StartTime":1125.0,"EndTime":1125.0,"Column":9}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1250.0,"Objects":[{"StartTime":1250.0,"EndTime":1250.0,"Column":10}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1375.0,"Objects":[{"StartTime":1375.0,"EndTime":1375.0,"Column":11}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1500.0,"Objects":[{"StartTime":1500.0,"EndTime":1500.0,"Column":12}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1625.0,"Objects":[{"StartTime":1625.0,"EndTime":1625.0,"Column":13}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1750.0,"Objects":[{"StartTime":1750.0,"EndTime":1750.0,"Column":14}]},{"RandomW":273326509,"RandomX":631,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1875.0,"Objects":[{"StartTime":1875.0,"EndTime":1875.0,"Column":15}]}]}
@@ -0,0 +1,52 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:16K
[Difficulty]
HPDrainRate:5
CircleSize:16
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
16,192,0,1,0,0:0:0:0:
48,192,125,1,0,0:0:0:0:
80,192,250,1,0,0:0:0:0:
112,192,375,1,0,0:0:0:0:
144,192,500,1,0,0:0:0:0:
176,192,625,1,0,0:0:0:0:
208,192,750,1,0,0:0:0:0:
240,192,875,1,0,0:0:0:0:
272,192,1000,1,0,0:0:0:0:
304,192,1125,1,0,0:0:0:0:
336,192,1250,1,0,0:0:0:0:
368,192,1375,1,0,0:0:0:0:
400,192,1500,1,0,0:0:0:0:
432,192,1625,1,0,0:0:0:0:
464,192,1750,1,0,0:0:0:0:
496,192,1875,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":875.0,"Objects":[{"StartTime":875.0,"EndTime":875.0,"Column":7}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1000.0,"Objects":[{"StartTime":1000.0,"EndTime":1000.0,"Column":8}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1125.0,"Objects":[{"StartTime":1125.0,"EndTime":1125.0,"Column":9}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1250.0,"Objects":[{"StartTime":1250.0,"EndTime":1250.0,"Column":10}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1375.0,"Objects":[{"StartTime":1375.0,"EndTime":1375.0,"Column":11}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1500.0,"Objects":[{"StartTime":1500.0,"EndTime":1500.0,"Column":12}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1625.0,"Objects":[{"StartTime":1625.0,"EndTime":1625.0,"Column":13}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1750.0,"Objects":[{"StartTime":1750.0,"EndTime":1750.0,"Column":14}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1875.0,"Objects":[{"StartTime":1875.0,"EndTime":1875.0,"Column":15}]},{"RandomW":273326509,"RandomX":651,"RandomY":842502087,"RandomZ":3579807591,"StartTime":2000.0,"Objects":[{"StartTime":2000.0,"EndTime":2000.0,"Column":16}]}]}
@@ -0,0 +1,53 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:17K
[Difficulty]
HPDrainRate:5
CircleSize:17
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
15,192,0,1,0,0:0:0:0:
45,192,125,1,0,0:0:0:0:
75,192,250,1,0,0:0:0:0:
105,192,375,1,0,0:0:0:0:
135,192,500,1,0,0:0:0:0:
165,192,625,1,0,0:0:0:0:
195,192,750,1,0,0:0:0:0:
225,192,875,1,0,0:0:0:0:
256,192,1000,1,0,0:0:0:0:
286,192,1125,1,0,0:0:0:0:
316,192,1250,1,0,0:0:0:0:
346,192,1375,1,0,0:0:0:0:
376,192,1500,1,0,0:0:0:0:
406,192,1625,1,0,0:0:0:0:
436,192,1750,1,0,0:0:0:0:
466,192,1875,1,0,0:0:0:0:
496,192,2000,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":875.0,"Objects":[{"StartTime":875.0,"EndTime":875.0,"Column":7}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1000.0,"Objects":[{"StartTime":1000.0,"EndTime":1000.0,"Column":8}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1125.0,"Objects":[{"StartTime":1125.0,"EndTime":1125.0,"Column":9}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1250.0,"Objects":[{"StartTime":1250.0,"EndTime":1250.0,"Column":10}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1375.0,"Objects":[{"StartTime":1375.0,"EndTime":1375.0,"Column":11}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1500.0,"Objects":[{"StartTime":1500.0,"EndTime":1500.0,"Column":12}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1625.0,"Objects":[{"StartTime":1625.0,"EndTime":1625.0,"Column":13}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1750.0,"Objects":[{"StartTime":1750.0,"EndTime":1750.0,"Column":14}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":1875.0,"Objects":[{"StartTime":1875.0,"EndTime":1875.0,"Column":15}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":2000.0,"Objects":[{"StartTime":2000.0,"EndTime":2000.0,"Column":16}]},{"RandomW":273326509,"RandomX":671,"RandomY":842502087,"RandomZ":3579807591,"StartTime":2125.0,"Objects":[{"StartTime":2125.0,"EndTime":2125.0,"Column":17}]}]}
@@ -0,0 +1,54 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:18K
[Difficulty]
HPDrainRate:5
CircleSize:18
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
14,192,0,1,0,0:0:0:0:
42,192,125,1,0,0:0:0:0:
71,192,250,1,0,0:0:0:0:
99,192,375,1,0,0:0:0:0:
128,192,500,1,0,0:0:0:0:
156,192,625,1,0,0:0:0:0:
184,192,750,1,0,0:0:0:0:
213,192,875,1,0,0:0:0:0:
241,192,1000,1,0,0:0:0:0:
270,192,1125,1,0,0:0:0:0:
298,192,1250,1,0,0:0:0:0:
327,192,1375,1,0,0:0:0:0:
355,192,1500,1,0,0:0:0:0:
384,192,1625,1,0,0:0:0:0:
412,192,1750,1,0,0:0:0:0:
440,192,1875,1,0,0:0:0:0:
469,192,2000,1,0,0:0:0:0:
497,192,2125,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":331,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]}]}
@@ -0,0 +1,37 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:1K
[Difficulty]
HPDrainRate:5
CircleSize:1
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
256,192,0,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":351,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":351,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]}]}
@@ -0,0 +1,38 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:2K
[Difficulty]
HPDrainRate:5
CircleSize:2
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
128,192,0,1,0,0:0:0:0:
384,192,125,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":371,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":371,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":371,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]}]}
@@ -0,0 +1,39 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:3K
[Difficulty]
HPDrainRate:5
CircleSize:3
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
85,192,0,1,0,0:0:0:0:
256,192,125,1,0,0:0:0:0:
426,192,250,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":391,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":391,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":391,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":391,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]}]}
@@ -0,0 +1,40 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:4K
[Difficulty]
HPDrainRate:5
CircleSize:4
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
64,192,0,1,0,0:0:0:0:
192,192,125,1,0,0:0:0:0:
320,192,250,1,0,0:0:0:0:
448,192,375,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":411,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":411,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":411,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":411,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":411,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]}]}
@@ -0,0 +1,41 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:5K
[Difficulty]
HPDrainRate:5
CircleSize:5
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
51,192,0,1,0,0:0:0:0:
153,192,125,1,0,0:0:0:0:
256,192,250,1,0,0:0:0:0:
358,192,375,1,0,0:0:0:0:
460,192,500,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":431,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":431,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":431,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":431,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":431,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":431,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]}]}
@@ -0,0 +1,42 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:6K
[Difficulty]
HPDrainRate:5
CircleSize:6
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
42,192,0,1,0,0:0:0:0:
128,192,125,1,0,0:0:0:0:
213,192,250,1,0,0:0:0:0:
298,192,375,1,0,0:0:0:0:
384,192,500,1,0,0:0:0:0:
469,192,625,1,0,0:0:0:0:
@@ -0,0 +1,45 @@
osu file format v14
[General]
Mode: 3
SpecialStyle:1
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:8K
[Difficulty]
HPDrainRate:5
CircleSize:8
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
32,192,0,1,0,0:0:0:0:
96,192,125,1,0,0:0:0:0:
160,192,250,1,0,0:0:0:0:
224,192,375,1,0,0:0:0:0:
288,192,500,1,0,0:0:0:0:
352,192,625,1,0,0:0:0:0:
416,192,750,1,0,0:0:0:0:
480,192,875,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":451,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":451,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":451,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":451,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":451,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":451,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":451,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]}]}
@@ -0,0 +1,43 @@
osu file format v14
[General]
Mode: 3
[Metadata]
Title:keycount test
TitleUnicode:keycount test
Artist:mania
ArtistUnicode:mania
Creator:spaceman_atlas
Version:7K
[Difficulty]
HPDrainRate:5
CircleSize:7
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
36,192,0,1,0,0:0:0:0:
109,192,125,1,0,0:0:0:0:
182,192,250,1,0,0:0:0:0:
256,192,375,1,0,0:0:0:0:
329,192,500,1,0,0:0:0:0:
402,192,625,1,0,0:0:0:0:
475,192,750,1,0,0:0:0:0:
@@ -0,0 +1 @@
{"Mappings":[{"RandomW":273326509,"RandomX":471,"RandomY":842502087,"RandomZ":3579807591,"StartTime":0.0,"Objects":[{"StartTime":0.0,"EndTime":0.0,"Column":0}]},{"RandomW":273326509,"RandomX":471,"RandomY":842502087,"RandomZ":3579807591,"StartTime":125.0,"Objects":[{"StartTime":125.0,"EndTime":125.0,"Column":1}]},{"RandomW":273326509,"RandomX":471,"RandomY":842502087,"RandomZ":3579807591,"StartTime":250.0,"Objects":[{"StartTime":250.0,"EndTime":250.0,"Column":2}]},{"RandomW":273326509,"RandomX":471,"RandomY":842502087,"RandomZ":3579807591,"StartTime":375.0,"Objects":[{"StartTime":375.0,"EndTime":375.0,"Column":3}]},{"RandomW":273326509,"RandomX":471,"RandomY":842502087,"RandomZ":3579807591,"StartTime":500.0,"Objects":[{"StartTime":500.0,"EndTime":500.0,"Column":4}]},{"RandomW":273326509,"RandomX":471,"RandomY":842502087,"RandomZ":3579807591,"StartTime":625.0,"Objects":[{"StartTime":625.0,"EndTime":625.0,"Column":5}]},{"RandomW":273326509,"RandomX":471,"RandomY":842502087,"RandomZ":3579807591,"StartTime":750.0,"Objects":[{"StartTime":750.0,"EndTime":750.0,"Column":6}]},{"RandomW":273326509,"RandomX":471,"RandomY":842502087,"RandomZ":3579807591,"StartTime":875.0,"Objects":[{"StartTime":875.0,"EndTime":875.0,"Column":7}]}]}

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