diff --git a/osu.Android.props b/osu.Android.props
index 1513f6444d..183ac61c90 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,6 +52,6 @@
-
+
diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
index c32e359de6..0c35e9471d 100644
--- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
+++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
@@ -852,6 +852,21 @@ namespace osu.Game.Tests.Beatmaps.IO
}
}
+ public static async Task LoadQuickOszIntoOsu(OsuGameBase osu)
+ {
+ var temp = TestResources.GetQuickTestBeatmapForImport();
+
+ var manager = osu.Dependencies.Get();
+
+ var importedSet = await manager.Import(new ImportTask(temp));
+
+ ensureLoaded(osu);
+
+ waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000);
+
+ return manager.GetAllUsableBeatmapSets().Find(beatmapSet => beatmapSet.ID == importedSet.ID);
+ }
+
public static async Task LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false)
{
var temp = path ?? TestResources.GetTestBeatmapForImport(virtualTrack);
diff --git a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs
index 3ffb512b7f..8c30802ce3 100644
--- a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs
+++ b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs
@@ -52,7 +52,7 @@ namespace osu.Game.Tests.Online
{
beatmaps.AllowImport = new TaskCompletionSource();
- testBeatmapFile = TestResources.GetTestBeatmapForImport();
+ testBeatmapFile = TestResources.GetQuickTestBeatmapForImport();
testBeatmapInfo = getTestBeatmapInfo(testBeatmapFile);
testBeatmapSet = testBeatmapInfo.BeatmapSet;
diff --git a/osu.Game.Tests/Resources/Archives/241526 Soleily - Renatus_virtual_quick.osz b/osu.Game.Tests/Resources/Archives/241526 Soleily - Renatus_virtual_quick.osz
new file mode 100644
index 0000000000..e9f5fb0328
Binary files /dev/null and b/osu.Game.Tests/Resources/Archives/241526 Soleily - Renatus_virtual_quick.osz differ
diff --git a/osu.Game.Tests/Resources/TestResources.cs b/osu.Game.Tests/Resources/TestResources.cs
index e882229570..cef0532f9d 100644
--- a/osu.Game.Tests/Resources/TestResources.cs
+++ b/osu.Game.Tests/Resources/TestResources.cs
@@ -15,6 +15,28 @@ namespace osu.Game.Tests.Resources
public static Stream GetTestBeatmapStream(bool virtualTrack = false) => OpenResource($"Archives/241526 Soleily - Renatus{(virtualTrack ? "_virtual" : "")}.osz");
+ ///
+ /// Retrieve a path to a copy of a shortened (~10 second) beatmap archive with a virtual track.
+ ///
+ ///
+ /// This is intended for use in tests which need to run to completion as soon as possible and don't need to test a full length beatmap.
+ /// A path to a copy of a beatmap archive (osz). Should be deleted after use.
+ public static string GetQuickTestBeatmapForImport()
+ {
+ var tempPath = Path.GetTempFileName() + ".osz";
+ using (var stream = OpenResource("Archives/241526 Soleily - Renatus_virtual_quick.osz"))
+ using (var newFile = File.Create(tempPath))
+ stream.CopyTo(newFile);
+
+ Assert.IsTrue(File.Exists(tempPath));
+ return tempPath;
+ }
+
+ ///
+ /// Retrieve a path to a copy of a full-fledged beatmap archive.
+ ///
+ /// Whether the audio track should be virtual.
+ /// A path to a copy of a beatmap archive (osz). Should be deleted after use.
public static string GetTestBeatmapForImport(bool virtualTrack = false)
{
var tempPath = Path.GetTempFileName() + ".osz";
diff --git a/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs b/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs
index 4aebed0d31..f421a30283 100644
--- a/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs
+++ b/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs
@@ -118,6 +118,10 @@ namespace osu.Game.Tests.Rulesets
public BindableNumber Frequency => throw new NotImplementedException();
public BindableNumber Tempo => throw new NotImplementedException();
+ public void BindAdjustments(IAggregateAudioAdjustment component) => throw new NotImplementedException();
+
+ public void UnbindAdjustments(IAggregateAudioAdjustment component) => throw new NotImplementedException();
+
public void AddAdjustment(AdjustableProperty type, IBindable adjustBindable) => throw new NotImplementedException();
public void RemoveAdjustment(AdjustableProperty type, IBindable adjustBindable) => throw new NotImplementedException();
diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
index 7ade7725d9..ba4d12b19f 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
@@ -51,7 +51,7 @@ namespace osu.Game.Tests.Visual.Background
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default));
Dependencies.Cache(new OsuConfigManager(LocalStorage));
- manager.Import(TestResources.GetTestBeatmapForImport()).Wait();
+ manager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
Beatmap.SetDefault();
}
diff --git a/osu.Game.Tests/Visual/Collections/TestSceneManageCollectionsDialog.cs b/osu.Game.Tests/Visual/Collections/TestSceneManageCollectionsDialog.cs
index fef1605f0c..1655adf811 100644
--- a/osu.Game.Tests/Visual/Collections/TestSceneManageCollectionsDialog.cs
+++ b/osu.Game.Tests/Visual/Collections/TestSceneManageCollectionsDialog.cs
@@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.Collections
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, host, Beatmap.Default));
- beatmapManager.Import(TestResources.GetTestBeatmapForImport()).Wait();
+ beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
base.Content.AddRange(new Drawable[]
{
diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs
index e43e5ba3ce..49c1163c6c 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@@ -8,21 +9,17 @@ using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Storyboards;
+using osu.Game.Tests.Beatmaps;
+using osuTK;
namespace osu.Game.Tests.Visual.Gameplay
{
[HeadlessTest] // we alter unsafe properties on the game host to test inactive window state.
public class TestScenePauseWhenInactive : OsuPlayerTestScene
{
- protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
- {
- var beatmap = (Beatmap)base.CreateBeatmap(ruleset);
-
- beatmap.HitObjects.RemoveAll(h => h.StartTime < 30000);
-
- return beatmap;
- }
-
[Resolved]
private GameHost host { get; set; }
@@ -33,10 +30,57 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("resume player", () => Player.GameplayClockContainer.Start());
AddAssert("ensure not paused", () => !Player.GameplayClockContainer.IsPaused.Value);
+
+ AddStep("progress time to gameplay", () => Player.GameplayClockContainer.Seek(Player.DrawableRuleset.GameplayStartTime));
+ AddUntilStep("wait for pause", () => Player.GameplayClockContainer.IsPaused.Value);
+ }
+
+ ///
+ /// Tests that if a pause from focus lose is performed while in pause cooldown,
+ /// the player will still pause after the cooldown is finished.
+ ///
+ [Test]
+ public void TestPauseWhileInCooldown()
+ {
+ AddStep("move cursor outside", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopLeft - new Vector2(10)));
+
+ AddStep("resume player", () => Player.GameplayClockContainer.Start());
+ AddStep("skip to gameplay", () => Player.GameplayClockContainer.Seek(Player.DrawableRuleset.GameplayStartTime));
+
+ AddStep("set inactive", () => ((Bindable)host.IsActive).Value = false);
+ AddUntilStep("wait for pause", () => Player.GameplayClockContainer.IsPaused.Value);
+
+ AddStep("set active", () => ((Bindable)host.IsActive).Value = true);
+
+ AddStep("resume player", () => Player.Resume());
+ AddAssert("unpaused", () => !Player.GameplayClockContainer.IsPaused.Value);
+
+ bool pauseCooldownActive = false;
+
+ AddStep("set inactive again", () =>
+ {
+ pauseCooldownActive = Player.PauseCooldownActive;
+ ((Bindable)host.IsActive).Value = false;
+ });
+ AddAssert("pause cooldown active", () => pauseCooldownActive);
AddUntilStep("wait for pause", () => Player.GameplayClockContainer.IsPaused.Value);
- AddAssert("time of pause is after gameplay start time", () => Player.GameplayClockContainer.GameplayClock.CurrentTime >= Player.DrawableRuleset.GameplayStartTime);
}
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, true, true);
+
+ protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
+ {
+ return new Beatmap
+ {
+ HitObjects = new List
+ {
+ new HitCircle { StartTime = 30000 },
+ new HitCircle { StartTime = 35000 },
+ },
+ };
+ }
+
+ protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
+ => new TestWorkingBeatmap(beatmap, storyboard, Audio);
}
}
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerReadyButton.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerReadyButton.cs
index 3b3b1bee86..b44e5b1e5b 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerReadyButton.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerReadyButton.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default));
- beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).Wait();
+ beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
Add(beatmapTracker = new OnlinePlayBeatmapAvailablilityTracker
{
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
index d8380b2dd3..5d070b424a 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
@@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => new TestSongSelect());
- AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
+ AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
@@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Navigation
AddStep("press enter", () => InputManager.Key(Key.Enter));
AddUntilStep("wait for player", () => (player = Game.ScreenStack.CurrentScreen as Player) != null);
- AddStep("seek to end", () => beatmap().Track.Seek(beatmap().Track.Length));
+ AddStep("seek to end", () => player.ChildrenOfType().First().Seek(beatmap().Track.Length));
AddUntilStep("wait for pass", () => (results = Game.ScreenStack.CurrentScreen as ResultsScreen) != null && results.IsLoaded);
AddStep("attempt to retry", () => results.ChildrenOfType().First().Action());
AddUntilStep("wait for player", () => Game.ScreenStack.CurrentScreen != player && Game.ScreenStack.CurrentScreen is Player);
diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs
index 63bda08c88..0c199bfb62 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Online
ensureSoleilyRemoved();
createButtonWithBeatmap(createSoleily());
AddAssert("button state not downloaded", () => downloadButton.DownloadState == DownloadState.NotDownloaded);
- AddStep("import soleily", () => beatmaps.Import(TestResources.GetTestBeatmapForImport()));
+ AddStep("import soleily", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()));
AddUntilStep("wait for beatmap import", () => beatmaps.GetAllUsableBeatmapSets().Any(b => b.OnlineBeatmapSetID == 241526));
createButtonWithBeatmap(createSoleily());
AddAssert("button state downloaded", () => downloadButton.DownloadState == DownloadState.LocallyAvailable);
diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs
index cdcded8f61..be8032cde8 100644
--- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs
+++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs
@@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
-using System.Threading.Tasks;
using JetBrains.Annotations;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
@@ -76,7 +75,7 @@ namespace osu.Game.Tests.Visual.Playlists
AddStep("bind user score info handler", () =>
{
userScore = new TestScoreInfo(new OsuRuleset().RulesetInfo) { OnlineScoreID = currentScoreId++ };
- bindHandler(3000, userScore);
+ bindHandler(true, userScore);
});
createResults(() => userScore);
@@ -89,7 +88,7 @@ namespace osu.Game.Tests.Visual.Playlists
[Test]
public void TestShowNullUserScoreWithDelay()
{
- AddStep("bind delayed handler", () => bindHandler(3000));
+ AddStep("bind delayed handler", () => bindHandler(true));
createResults();
waitForDisplay();
@@ -103,7 +102,7 @@ namespace osu.Game.Tests.Visual.Playlists
createResults();
waitForDisplay();
- AddStep("bind delayed handler", () => bindHandler(3000));
+ AddStep("bind delayed handler", () => bindHandler(true));
for (int i = 0; i < 2; i++)
{
@@ -134,7 +133,7 @@ namespace osu.Game.Tests.Visual.Playlists
createResults(() => userScore);
waitForDisplay();
- AddStep("bind delayed handler", () => bindHandler(3000));
+ AddStep("bind delayed handler", () => bindHandler(true));
for (int i = 0; i < 2; i++)
{
@@ -169,70 +168,47 @@ namespace osu.Game.Tests.Visual.Playlists
AddWaitStep("wait for display", 5);
}
- private void bindHandler(double delay = 0, ScoreInfo userScore = null, bool failRequests = false) => ((DummyAPIAccess)API).HandleRequest = request =>
+ private void bindHandler(bool delayed = false, ScoreInfo userScore = null, bool failRequests = false) => ((DummyAPIAccess)API).HandleRequest = request =>
{
requestComplete = false;
- if (failRequests)
- {
- triggerFail(request, delay);
- return;
- }
+ double delay = delayed ? 3000 : 0;
- switch (request)
+ Scheduler.AddDelayed(() =>
{
- case ShowPlaylistUserScoreRequest s:
- if (userScore == null)
- triggerFail(s, delay);
- else
- triggerSuccess(s, createUserResponse(userScore), delay);
- break;
+ if (failRequests)
+ {
+ triggerFail(request);
+ return;
+ }
- case IndexPlaylistScoresRequest i:
- triggerSuccess(i, createIndexResponse(i), delay);
- break;
- }
+ switch (request)
+ {
+ case ShowPlaylistUserScoreRequest s:
+ if (userScore == null)
+ triggerFail(s);
+ else
+ triggerSuccess(s, createUserResponse(userScore));
+ break;
+
+ case IndexPlaylistScoresRequest i:
+ triggerSuccess(i, createIndexResponse(i));
+ break;
+ }
+ }, delay);
};
- private void triggerSuccess(APIRequest req, T result, double delay)
+ private void triggerSuccess(APIRequest req, T result)
where T : class
{
- if (delay == 0)
- success();
- else
- {
- Task.Run(async () =>
- {
- await Task.Delay(TimeSpan.FromMilliseconds(delay));
- Schedule(success);
- });
- }
-
- void success()
- {
- requestComplete = true;
- req.TriggerSuccess(result);
- }
+ requestComplete = true;
+ req.TriggerSuccess(result);
}
- private void triggerFail(APIRequest req, double delay)
+ private void triggerFail(APIRequest req)
{
- if (delay == 0)
- fail();
- else
- {
- Task.Run(async () =>
- {
- await Task.Delay(TimeSpan.FromMilliseconds(delay));
- Schedule(fail);
- });
- }
-
- void fail()
- {
- requestComplete = true;
- req.TriggerFailure(new WebException("Failed."));
- }
+ requestComplete = true;
+ req.TriggerFailure(new WebException("Failed."));
}
private MultiplayerScore createUserResponse([NotNull] ScoreInfo userScore)
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneFilterControl.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneFilterControl.cs
index 5d0fb248df..c13bdf0955 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneFilterControl.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneFilterControl.cs
@@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, host, Beatmap.Default));
- beatmapManager.Import(TestResources.GetTestBeatmapForImport()).Wait();
+ beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
base.Content.AddRange(new Drawable[]
{
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
index 81862448a8..d615f1f440 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
@@ -84,7 +84,7 @@ namespace osu.Game.Tests.Visual.UserInterface
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get(), dependencies.Get(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, null, ContextFactory));
- beatmap = beatmapManager.Import(new ImportTask(TestResources.GetTestBeatmapForImport())).Result.Beatmaps[0];
+ beatmap = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).Result.Beatmaps[0];
for (int i = 0; i < 50; i++)
{
diff --git a/osu.Game/Collections/CollectionManager.cs b/osu.Game/Collections/CollectionManager.cs
index a65d9a415d..fb9c230c7a 100644
--- a/osu.Game/Collections/CollectionManager.cs
+++ b/osu.Game/Collections/CollectionManager.cs
@@ -138,10 +138,10 @@ namespace osu.Game.Collections
PostNotification?.Invoke(notification);
- var collection = readCollections(stream, notification);
- await importCollections(collection);
+ var collections = readCollections(stream, notification);
+ await importCollections(collections);
- notification.CompletionText = $"Imported {collection.Count} collections";
+ notification.CompletionText = $"Imported {collections.Count} collections";
notification.State = ProgressNotificationState.Completed;
}
@@ -155,7 +155,7 @@ namespace osu.Game.Collections
{
foreach (var newCol in newCollections)
{
- var existing = Collections.FirstOrDefault(c => c.Name == newCol.Name);
+ var existing = Collections.FirstOrDefault(c => c.Name.Value == newCol.Name.Value);
if (existing == null)
Collections.Add(existing = new BeatmapCollection { Name = { Value = newCol.Name.Value } });
diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs
index 8ffa0221c8..ce01378b17 100644
--- a/osu.Game/Online/API/APIAccess.cs
+++ b/osu.Game/Online/API/APIAccess.cs
@@ -10,6 +10,7 @@ using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
+using osu.Framework;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ExceptionExtensions;
using osu.Framework.Extensions.ObjectExtensions;
@@ -246,7 +247,14 @@ namespace osu.Game.Online.API
this.password = password;
}
- public IHubClientConnector GetHubConnector(string clientName, string endpoint) => new HubClientConnector(clientName, endpoint, this, versionHash);
+ public IHubClientConnector GetHubConnector(string clientName, string endpoint)
+ {
+ // disabled until the underlying runtime issue is resolved, see https://github.com/mono/mono/issues/20805.
+ if (RuntimeInfo.OS == RuntimeInfo.Platform.iOS)
+ return null;
+
+ return new HubClientConnector(clientName, endpoint, this, versionHash);
+ }
public RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password)
{
diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs
index 707c59436d..e8871bef05 100644
--- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs
+++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using osu.Framework.IO.Network;
using osu.Game.Beatmaps;
namespace osu.Game.Online.API.Requests
@@ -15,6 +16,13 @@ namespace osu.Game.Online.API.Requests
this.noVideo = noVideo;
}
+ protected override WebRequest CreateWebRequest()
+ {
+ var req = base.CreateWebRequest();
+ req.Timeout = 60000;
+ return req;
+ }
+
protected override string Target => $@"beatmapsets/{Model.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}";
}
}
diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs
index bbaca7c80f..b31884d246 100644
--- a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs
+++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs
@@ -134,6 +134,10 @@ namespace osu.Game.Rulesets.UI
public IBindable AggregateTempo => throw new NotSupportedException();
+ public void BindAdjustments(IAggregateAudioAdjustment component) => throw new NotImplementedException();
+
+ public void UnbindAdjustments(IAggregateAudioAdjustment component) => throw new NotImplementedException();
+
public int PlaybackConcurrency
{
get => throw new NotSupportedException();
diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs
index 07de2bf601..d6f002ea2c 100644
--- a/osu.Game/Rulesets/UI/RulesetInputManager.cs
+++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs
@@ -16,7 +16,6 @@ using osu.Game.Configuration;
using osu.Game.Input.Bindings;
using osu.Game.Input.Handlers;
using osu.Game.Screens.Play;
-using osuTK.Input;
using static osu.Game.Input.Handlers.ReplayInputHandler;
namespace osu.Game.Rulesets.UI
@@ -109,9 +108,9 @@ namespace osu.Game.Rulesets.UI
{
switch (e)
{
- case MouseDownEvent mouseDown when mouseDown.Button == MouseButton.Left || mouseDown.Button == MouseButton.Right:
+ case MouseDownEvent _:
if (mouseDisabled.Value)
- return false;
+ return true; // importantly, block upwards propagation so global bindings also don't fire.
break;
diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs
index 81b1cb0bf1..f93bfd7705 100644
--- a/osu.Game/Screens/Menu/ButtonSystem.cs
+++ b/osu.Game/Screens/Menu/ButtonSystem.cs
@@ -172,6 +172,18 @@ namespace osu.Game.Screens.Menu
return;
}
+ // disabled until the underlying runtime issue is resolved, see https://github.com/mono/mono/issues/20805.
+ if (RuntimeInfo.OS == RuntimeInfo.Platform.iOS)
+ {
+ notifications?.Post(new SimpleNotification
+ {
+ Text = "Multiplayer is temporarily unavailable on iOS as we figure out some low level issues.",
+ Icon = FontAwesome.Solid.AppleAlt,
+ });
+
+ return;
+ }
+
OnMultiplayer?.Invoke();
}
diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs
index 1e130b7f88..e81efdac78 100644
--- a/osu.Game/Screens/Play/Player.cs
+++ b/osu.Game/Screens/Play/Player.cs
@@ -427,11 +427,18 @@ namespace osu.Game.Screens.Play
private void updatePauseOnFocusLostState()
{
- if (!PauseOnFocusLost || breakTracker.IsBreakTime.Value)
+ if (!PauseOnFocusLost || !pausingSupportedByCurrentState || breakTracker.IsBreakTime.Value)
return;
if (gameActive.Value == false)
- Pause();
+ {
+ bool paused = Pause();
+
+ // if the initial pause could not be satisfied, the pause cooldown may be active.
+ // reschedule the pause attempt until it can be achieved.
+ if (!paused)
+ Scheduler.AddOnce(updatePauseOnFocusLostState);
+ }
}
private IBeatmap loadPlayableBeatmap()
@@ -674,6 +681,9 @@ namespace osu.Game.Screens.Play
private double? lastPauseActionTime;
+ protected bool PauseCooldownActive =>
+ lastPauseActionTime.HasValue && GameplayClockContainer.GameplayClock.CurrentTime < lastPauseActionTime + pause_cooldown;
+
///
/// A set of conditionals which defines whether the current game state and configuration allows for
/// pausing to be attempted via . If false, the game should generally exit if a user pause
@@ -684,11 +694,9 @@ namespace osu.Game.Screens.Play
LoadedBeatmapSuccessfully && Configuration.AllowPause && ValidForResume
// replays cannot be paused and exit immediately
&& !DrawableRuleset.HasReplayLoaded.Value
+ // cannot pause if we are already in a fail state
&& !HasFailed;
- private bool pauseCooldownActive =>
- lastPauseActionTime.HasValue && GameplayClockContainer.GameplayClock.CurrentTime < lastPauseActionTime + pause_cooldown;
-
private bool canResume =>
// cannot resume from a non-paused state
GameplayClockContainer.IsPaused.Value
@@ -697,12 +705,12 @@ namespace osu.Game.Screens.Play
// already resuming
&& !IsResuming;
- public void Pause()
+ public bool Pause()
{
- if (!pausingSupportedByCurrentState) return;
+ if (!pausingSupportedByCurrentState) return false;
- if (!IsResuming && pauseCooldownActive)
- return;
+ if (!IsResuming && PauseCooldownActive)
+ return false;
if (IsResuming)
{
@@ -713,6 +721,7 @@ namespace osu.Game.Screens.Play
GameplayClockContainer.Stop();
PauseOverlay.Show();
lastPauseActionTime = GameplayClockContainer.GameplayClock.CurrentTime;
+ return true;
}
public void Resume()
diff --git a/osu.Game/Skinning/PoolableSkinnableSample.cs b/osu.Game/Skinning/PoolableSkinnableSample.cs
index abff57091b..9103a6a960 100644
--- a/osu.Game/Skinning/PoolableSkinnableSample.cs
+++ b/osu.Game/Skinning/PoolableSkinnableSample.cs
@@ -17,7 +17,7 @@ namespace osu.Game.Skinning
///
/// A sample corresponding to an that supports being pooled and responding to skin changes.
///
- public class PoolableSkinnableSample : SkinReloadableDrawable, IAggregateAudioAdjustment, IAdjustableAudioComponent
+ public class PoolableSkinnableSample : SkinReloadableDrawable, IAdjustableAudioComponent
{
///
/// The currently-loaded .
@@ -165,6 +165,10 @@ namespace osu.Game.Skinning
public BindableNumber Tempo => sampleContainer.Tempo;
+ public void BindAdjustments(IAggregateAudioAdjustment component) => sampleContainer.BindAdjustments(component);
+
+ public void UnbindAdjustments(IAggregateAudioAdjustment component) => sampleContainer.UnbindAdjustments(component);
+
public void AddAdjustment(AdjustableProperty type, IBindable adjustBindable) => sampleContainer.AddAdjustment(type, adjustBindable);
public void RemoveAdjustment(AdjustableProperty type, IBindable adjustBindable) => sampleContainer.RemoveAdjustment(type, adjustBindable);
diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs
index d3dfcb1dc0..57e20a8d31 100644
--- a/osu.Game/Skinning/SkinnableSound.cs
+++ b/osu.Game/Skinning/SkinnableSound.cs
@@ -176,6 +176,16 @@ namespace osu.Game.Skinning
public BindableNumber Tempo => samplesContainer.Tempo;
+ public void BindAdjustments(IAggregateAudioAdjustment component)
+ {
+ samplesContainer.BindAdjustments(component);
+ }
+
+ public void UnbindAdjustments(IAggregateAudioAdjustment component)
+ {
+ samplesContainer.UnbindAdjustments(component);
+ }
+
public void AddAdjustment(AdjustableProperty type, IBindable adjustBindable)
=> samplesContainer.AddAdjustment(type, adjustBindable);
@@ -192,6 +202,14 @@ namespace osu.Game.Skinning
public bool IsPlayed => samplesContainer.Any(s => s.Played);
+ public IBindable AggregateVolume => samplesContainer.AggregateVolume;
+
+ public IBindable AggregateBalance => samplesContainer.AggregateBalance;
+
+ public IBindable AggregateFrequency => samplesContainer.AggregateFrequency;
+
+ public IBindable AggregateTempo => samplesContainer.AggregateTempo;
+
#endregion
}
}
diff --git a/osu.Game/Tests/Visual/TestPlayer.cs b/osu.Game/Tests/Visual/TestPlayer.cs
index f47391ce6a..0addc9de75 100644
--- a/osu.Game/Tests/Visual/TestPlayer.cs
+++ b/osu.Game/Tests/Visual/TestPlayer.cs
@@ -34,6 +34,8 @@ namespace osu.Game.Tests.Visual
public new HealthProcessor HealthProcessor => base.HealthProcessor;
+ public new bool PauseCooldownActive => base.PauseCooldownActive;
+
public readonly List Results = new List();
public TestPlayer(bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false)
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 9c3d0c2020..37d730bf42 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -29,7 +29,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 99ab88a064..ca11952cc8 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -70,7 +70,7 @@
-
+
@@ -91,7 +91,7 @@
-
+