1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 06:33:20 +08:00

Merge pull request #14022 from peppy/fix-invalid-ruleset-causing-crash

Fix invalid/unavailable ruleset causing game-wide crash
This commit is contained in:
Dan Balasescu 2021-07-27 02:39:26 +09:00 committed by GitHub
commit 7ae1b5bae7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 7 deletions

View File

@ -10,6 +10,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Textures;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
@ -32,6 +33,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual
{
[TestFixture]
[HeadlessTest]
public class TestSceneOsuGame : OsuTestScene
{
private IReadOnlyList<Type> requiredGameDependencies => new[]
@ -83,10 +85,15 @@ namespace osu.Game.Tests.Visual
typeof(PreviewTrackManager),
};
private OsuGame game;
[Resolved]
private OsuGameBase gameBase { get; set; }
[BackgroundDependencyLoader]
private void load(GameHost host, OsuGameBase gameBase)
private void load(GameHost host)
{
OsuGame game = new OsuGame();
game = new OsuGame();
game.SetHost(host);
Children = new Drawable[]
@ -100,7 +107,39 @@ namespace osu.Game.Tests.Visual
};
AddUntilStep("wait for load", () => game.IsLoaded);
}
[Test]
public void TestNullRulesetHandled()
{
RulesetInfo ruleset = null;
AddStep("store current ruleset", () => ruleset = Ruleset.Value);
AddStep("set global ruleset to null value", () => Ruleset.Value = null);
AddAssert("ruleset still valid", () => Ruleset.Value.Available);
AddAssert("ruleset unchanged", () => ReferenceEquals(Ruleset.Value, ruleset));
}
[Test]
public void TestUnavailableRulesetHandled()
{
RulesetInfo ruleset = null;
AddStep("store current ruleset", () => ruleset = Ruleset.Value);
AddStep("set global ruleset to invalid value", () => Ruleset.Value = new RulesetInfo
{
Name = "unavailable",
Available = false,
});
AddAssert("ruleset still valid", () => Ruleset.Value.Available);
AddAssert("ruleset unchanged", () => ReferenceEquals(Ruleset.Value, ruleset));
}
[Test]
public void TestAvailableDependencies()
{
AddAssert("check OsuGame DI members", () =>
{
foreach (var type in requiredGameDependencies)
@ -111,6 +150,7 @@ namespace osu.Game.Tests.Visual
return true;
});
AddAssert("check OsuGameBase DI members", () =>
{
foreach (var type in requiredGameBaseDependencies)

View File

@ -476,13 +476,17 @@ namespace osu.Game
private void onRulesetChanged(ValueChangedEvent<RulesetInfo> r)
{
if (r.NewValue?.Available != true)
{
// reject the change if the ruleset is not available.
Ruleset.Value = r.OldValue;
return;
}
var dict = new Dictionary<ModType, IReadOnlyList<Mod>>();
if (r.NewValue?.Available == true)
{
foreach (ModType type in Enum.GetValues(typeof(ModType)))
dict[type] = r.NewValue.CreateInstance().GetModsFor(type).ToList();
}
foreach (ModType type in Enum.GetValues(typeof(ModType)))
dict[type] = r.NewValue.CreateInstance().GetModsFor(type).ToList();
if (!SelectedMods.Disabled)
SelectedMods.Value = Array.Empty<Mod>();