1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-05 10:52:54 +08:00

Merge branch 'master' into beatmap-cancellation-token

This commit is contained in:
Dean Herbert 2021-11-17 11:15:31 +09:00
commit 0715d40ea0
69 changed files with 315 additions and 137 deletions

View File

@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.EmptyFreeform
{ {
public class EmptyFreeformDifficultyCalculator : DifficultyCalculator public class EmptyFreeformDifficultyCalculator : DifficultyCalculator
{ {
public EmptyFreeformDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) public EmptyFreeformDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
: base(ruleset, beatmap) : base(ruleset, beatmap)
{ {
} }

View File

@ -30,8 +30,8 @@ namespace osu.Game.Rulesets.EmptyFreeform
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) =>
new EmptyFreeformBeatmapConverter(beatmap, this); new EmptyFreeformBeatmapConverter(beatmap, this);
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) =>
new EmptyFreeformDifficultyCalculator(this, beatmap); new EmptyFreeformDifficultyCalculator(RulesetInfo, beatmap);
public override IEnumerable<Mod> GetModsFor(ModType type) public override IEnumerable<Mod> GetModsFor(ModType type)
{ {

View File

@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Pippidon
{ {
public class PippidonDifficultyCalculator : DifficultyCalculator public class PippidonDifficultyCalculator : DifficultyCalculator
{ {
public PippidonDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) public PippidonDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
: base(ruleset, beatmap) : base(ruleset, beatmap)
{ {
} }

View File

@ -26,8 +26,8 @@ namespace osu.Game.Rulesets.Pippidon
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) =>
new PippidonBeatmapConverter(beatmap, this); new PippidonBeatmapConverter(beatmap, this);
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) =>
new PippidonDifficultyCalculator(this, beatmap); new PippidonDifficultyCalculator(RulesetInfo, beatmap);
public override IEnumerable<Mod> GetModsFor(ModType type) public override IEnumerable<Mod> GetModsFor(ModType type)
{ {

View File

@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.EmptyScrolling
{ {
public class EmptyScrollingDifficultyCalculator : DifficultyCalculator public class EmptyScrollingDifficultyCalculator : DifficultyCalculator
{ {
public EmptyScrollingDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) public EmptyScrollingDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
: base(ruleset, beatmap) : base(ruleset, beatmap)
{ {
} }

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.EmptyScrolling
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new EmptyScrollingBeatmapConverter(beatmap, this); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new EmptyScrollingBeatmapConverter(beatmap, this);
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new EmptyScrollingDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new EmptyScrollingDifficultyCalculator(RulesetInfo, beatmap);
public override IEnumerable<Mod> GetModsFor(ModType type) public override IEnumerable<Mod> GetModsFor(ModType type)
{ {

View File

@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Pippidon
{ {
public class PippidonDifficultyCalculator : DifficultyCalculator public class PippidonDifficultyCalculator : DifficultyCalculator
{ {
public PippidonDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) public PippidonDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
: base(ruleset, beatmap) : base(ruleset, beatmap)
{ {
} }

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Pippidon
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new PippidonBeatmapConverter(beatmap, this); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new PippidonBeatmapConverter(beatmap, this);
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new PippidonDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new PippidonDifficultyCalculator(RulesetInfo, beatmap);
public override IEnumerable<Mod> GetModsFor(ModType type) public override IEnumerable<Mod> GetModsFor(ModType type)
{ {

View File

@ -93,6 +93,11 @@ namespace osu.Desktop
protected override UpdateManager CreateUpdateManager() protected override UpdateManager CreateUpdateManager()
{ {
string packageManaged = Environment.GetEnvironmentVariable("OSU_EXTERNAL_UPDATE_PROVIDER");
if (!string.IsNullOrEmpty(packageManaged))
return new NoActionUpdateManager();
switch (RuntimeInfo.OS) switch (RuntimeInfo.OS)
{ {
case RuntimeInfo.Platform.Windows: case RuntimeInfo.Platform.Windows:

View File

@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.Tests
public void TestClockRateAdjusted(double expected, string name) public void TestClockRateAdjusted(double expected, string name)
=> Test(expected, name, new CatchModDoubleTime()); => Test(expected, name, new CatchModDoubleTime());
protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(new CatchRuleset(), beatmap); protected override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new CatchDifficultyCalculator(new CatchRuleset().RulesetInfo, beatmap);
protected override Ruleset CreateRuleset() => new CatchRuleset(); protected override Ruleset CreateRuleset() => new CatchRuleset();
} }

View File

@ -178,7 +178,7 @@ namespace osu.Game.Rulesets.Catch
return base.GetDisplayNameForHitResult(result); return base.GetDisplayNameForHitResult(result);
} }
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new CatchDifficultyCalculator(RulesetInfo, beatmap);
public override ISkin CreateLegacySkinProvider(ISkin skin, IBeatmap beatmap) => new CatchLegacySkinTransformer(skin); public override ISkin CreateLegacySkinProvider(ISkin skin, IBeatmap beatmap) => new CatchLegacySkinTransformer(skin);

View File

@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
private float halfCatcherWidth; private float halfCatcherWidth;
public CatchDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) public CatchDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
: base(ruleset, beatmap) : base(ruleset, beatmap)
{ {
} }

View File

@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Tests
public void TestClockRateAdjusted(double expected, string name) public void TestClockRateAdjusted(double expected, string name)
=> Test(expected, name, new ManiaModDoubleTime()); => Test(expected, name, new ManiaModDoubleTime());
protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(new ManiaRuleset(), beatmap); protected override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new ManiaDifficultyCalculator(new ManiaRuleset().RulesetInfo, beatmap);
protected override Ruleset CreateRuleset() => new ManiaRuleset(); protected override Ruleset CreateRuleset() => new ManiaRuleset();
} }

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Extensions;
using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Difficulty.Skills;
@ -28,11 +29,11 @@ namespace osu.Game.Rulesets.Mania.Difficulty
private readonly bool isForCurrentRuleset; private readonly bool isForCurrentRuleset;
private readonly double originalOverallDifficulty; private readonly double originalOverallDifficulty;
public ManiaDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) public ManiaDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
: base(ruleset, beatmap) : base(ruleset, beatmap)
{ {
isForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(ruleset.RulesetInfo); isForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.MatchesOnlineID(ruleset);
originalOverallDifficulty = beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty; originalOverallDifficulty = beatmap.BeatmapInfo.Difficulty.OverallDifficulty;
} }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)

View File

@ -272,7 +272,7 @@ namespace osu.Game.Rulesets.Mania
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetMania }; public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetMania };
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new ManiaDifficultyCalculator(RulesetInfo, beatmap);
public int LegacyID => 3; public int LegacyID => 3;

View File

@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Tests
public void TestClockRateAdjusted(double expected, string name) public void TestClockRateAdjusted(double expected, string name)
=> Test(expected, name, new OsuModDoubleTime()); => Test(expected, name, new OsuModDoubleTime());
protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(new OsuRuleset(), beatmap); protected override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new OsuDifficultyCalculator(new OsuRuleset().RulesetInfo, beatmap);
protected override Ruleset CreateRuleset() => new OsuRuleset(); protected override Ruleset CreateRuleset() => new OsuRuleset();
} }

View File

@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
private const double difficulty_multiplier = 0.0675; private const double difficulty_multiplier = 0.0675;
private double hitWindowGreat; private double hitWindowGreat;
public OsuDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) public OsuDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
: base(ruleset, beatmap) : base(ruleset, beatmap)
{ {
} }

View File

@ -208,7 +208,7 @@ namespace osu.Game.Rulesets.Osu
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetOsu }; public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetOsu };
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new OsuDifficultyCalculator(RulesetInfo, beatmap);
public override PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => new OsuPerformanceCalculator(this, attributes, score); public override PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => new OsuPerformanceCalculator(this, attributes, score);

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
public void TestClockRateAdjusted(double expected, string name) public void TestClockRateAdjusted(double expected, string name)
=> Test(expected, name, new TaikoModDoubleTime()); => Test(expected, name, new TaikoModDoubleTime());
protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(new TaikoRuleset(), beatmap); protected override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new TaikoDifficultyCalculator(new TaikoRuleset().RulesetInfo, beatmap);
protected override Ruleset CreateRuleset() => new TaikoRuleset(); protected override Ruleset CreateRuleset() => new TaikoRuleset();
} }

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
private const double colour_skill_multiplier = 0.01; private const double colour_skill_multiplier = 0.01;
private const double stamina_skill_multiplier = 0.02; private const double stamina_skill_multiplier = 0.02;
public TaikoDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) public TaikoDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
: base(ruleset, beatmap) : base(ruleset, beatmap)
{ {
} }

View File

@ -168,7 +168,7 @@ namespace osu.Game.Rulesets.Taiko
public override HitObjectComposer CreateHitObjectComposer() => new TaikoHitObjectComposer(this); public override HitObjectComposer CreateHitObjectComposer() => new TaikoHitObjectComposer(this);
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => new TaikoDifficultyCalculator(RulesetInfo, beatmap);
public override PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => new TaikoPerformanceCalculator(this, attributes, score); public override PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => new TaikoPerformanceCalculator(this, attributes, score);

View File

@ -156,7 +156,7 @@ namespace osu.Game.Tests.Mods
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }

View File

@ -3,6 +3,7 @@
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Extensions;
namespace osu.Game.Tests.NonVisual namespace osu.Game.Tests.NonVisual
{ {
@ -15,7 +16,8 @@ namespace osu.Game.Tests.NonVisual
var ourInfo = new BeatmapSetInfo { OnlineID = 123 }; var ourInfo = new BeatmapSetInfo { OnlineID = 123 };
var otherInfo = new BeatmapSetInfo { OnlineID = 123 }; var otherInfo = new BeatmapSetInfo { OnlineID = 123 };
Assert.AreEqual(ourInfo, otherInfo); Assert.AreNotEqual(ourInfo, otherInfo);
Assert.IsTrue(ourInfo.MatchesOnlineID(otherInfo));
} }
[Test] [Test]
@ -33,7 +35,8 @@ namespace osu.Game.Tests.NonVisual
var ourInfo = new BeatmapSetInfo { ID = 123, OnlineID = 12 }; var ourInfo = new BeatmapSetInfo { ID = 123, OnlineID = 12 };
var otherInfo = new BeatmapSetInfo { OnlineID = 12 }; var otherInfo = new BeatmapSetInfo { OnlineID = 12 };
Assert.AreEqual(ourInfo, otherInfo); Assert.AreNotEqual(ourInfo, otherInfo);
Assert.IsTrue(ourInfo.MatchesOnlineID(otherInfo));
} }
[Test] [Test]

View File

@ -128,7 +128,7 @@ namespace osu.Game.Tests.Online
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException(); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException();
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new NotImplementedException(); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => throw new NotImplementedException();
public override string Description { get; } = string.Empty; public override string Description { get; } = string.Empty;
public override string ShortName { get; } = string.Empty; public override string ShortName { get; } = string.Empty;

View File

@ -90,7 +90,7 @@ namespace osu.Game.Tests.Online
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new System.NotImplementedException(); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new System.NotImplementedException();
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new System.NotImplementedException(); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => throw new System.NotImplementedException();
public override string Description { get; } = string.Empty; public override string Description { get; } = string.Empty;
public override string ShortName { get; } = string.Empty; public override string ShortName { get; } = string.Empty;

View File

@ -79,7 +79,7 @@ namespace osu.Game.Tests.Testing
public override IEnumerable<Mod> GetModsFor(ModType type) => Array.Empty<Mod>(); public override IEnumerable<Mod> GetModsFor(ModType type) => Array.Empty<Mod>();
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => null; public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => null;
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => null; public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => null;
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => null; public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => null;
} }
private class TestRulesetConfigManager : IRulesetConfigManager private class TestRulesetConfigManager : IRulesetConfigManager

View File

@ -293,7 +293,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TestBeatmapConverter(beatmap, null); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TestBeatmapConverter(beatmap, null);
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new NotImplementedException(); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => throw new NotImplementedException();
public override string Description { get; } = string.Empty; public override string Description { get; } = string.Empty;

View File

@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) =>
throw new System.NotImplementedException(); throw new System.NotImplementedException();
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) =>
throw new System.NotImplementedException(); throw new System.NotImplementedException();
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0)

View File

@ -182,7 +182,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TestBeatmapConverter(beatmap, this); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TestBeatmapConverter(beatmap, this);
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new NotImplementedException(); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => throw new NotImplementedException();
public override string Description { get; } = string.Empty; public override string Description { get; } = string.Empty;

View File

@ -7,6 +7,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Extensions;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
@ -102,8 +103,8 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
BeatmapSetInfo catchSet = null, mixedSet = null; BeatmapSetInfo catchSet = null, mixedSet = null;
AddStep("create catch beatmapset", () => catchSet = importBeatmapSet(0, new[] { new CatchRuleset().RulesetInfo })); AddStep("create catch beatmapset", () => catchSet = importBeatmapSet(1, new[] { new CatchRuleset().RulesetInfo }));
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(1, AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(2,
new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo })); new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo }));
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { catchSet, mixedSet })); AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { catchSet, mixedSet }));
@ -120,8 +121,8 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
BeatmapSetInfo osuSet = null, mixedSet = null; BeatmapSetInfo osuSet = null, mixedSet = null;
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(0, new[] { new OsuRuleset().RulesetInfo })); AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(1, new[] { new OsuRuleset().RulesetInfo }));
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(1, AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(2,
new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo })); new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo }));
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, mixedSet })); AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, mixedSet }));
@ -138,8 +139,8 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
BeatmapSetInfo osuSet = null, mixedSet = null; BeatmapSetInfo osuSet = null, mixedSet = null;
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(0, new[] { new OsuRuleset().RulesetInfo })); AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(1, new[] { new OsuRuleset().RulesetInfo }));
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(1, AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(2,
new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new TaikoRuleset().RulesetInfo })); new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new TaikoRuleset().RulesetInfo }));
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, mixedSet })); AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, mixedSet }));
@ -156,8 +157,8 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
BeatmapSetInfo osuSet = null, maniaSet = null; BeatmapSetInfo osuSet = null, maniaSet = null;
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(0, new[] { new OsuRuleset().RulesetInfo })); AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(1, new[] { new OsuRuleset().RulesetInfo }));
AddStep("create mania beatmapset", () => maniaSet = importBeatmapSet(1, Enumerable.Repeat(new ManiaRuleset().RulesetInfo, 10))); AddStep("create mania beatmapset", () => maniaSet = importBeatmapSet(2, Enumerable.Repeat(new ManiaRuleset().RulesetInfo, 10)));
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, maniaSet })); AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, maniaSet }));
@ -203,11 +204,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("present beatmap", () => Game.PresentBeatmap(getImport())); AddStep("present beatmap", () => Game.PresentBeatmap(getImport()));
AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect); AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect);
AddUntilStep("recommended beatmap displayed", () => AddUntilStep("recommended beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.MatchesOnlineID(getImport().Beatmaps[expectedDiff - 1]));
{
int? expectedID = getImport().Beatmaps[expectedDiff - 1].OnlineID;
return Game.Beatmap.Value.BeatmapInfo.OnlineID == expectedID;
});
} }
} }
} }

View File

@ -199,7 +199,7 @@ namespace osu.Game.Tests.Visual.UserInterface
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException(); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException();
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new NotImplementedException(); public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => throw new NotImplementedException();
public override string Description { get; } = "test"; public override string Description { get; } = "test";
public override string ShortName { get; } = "tst"; public override string ShortName { get; } = "tst";

View File

@ -154,14 +154,17 @@ namespace osu.Game.Beatmaps
public bool Equals(BeatmapInfo other) public bool Equals(BeatmapInfo other)
{ {
if (ID == 0 || other?.ID == 0) if (ReferenceEquals(this, other)) return true;
// one of the two BeatmapInfos we are comparing isn't sourced from a database. if (other == null) return false;
// fall back to reference equality.
return ReferenceEquals(this, other);
return ID == other?.ID; if (ID != 0 && other.ID != 0)
return ID == other.ID;
return false;
} }
public bool Equals(IBeatmapInfo other) => other is BeatmapInfo b && Equals(b);
public bool AudioEquals(BeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && public bool AudioEquals(BeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null &&
BeatmapSet.Hash == other.BeatmapSet.Hash && BeatmapSet.Hash == other.BeatmapSet.Hash &&
(Metadata ?? BeatmapSet.Metadata).AudioFile == (other.Metadata ?? other.BeatmapSet.Metadata).AudioFile; (Metadata ?? BeatmapSet.Metadata).AudioFile == (other.Metadata ?? other.BeatmapSet.Metadata).AudioFile;

View File

@ -69,21 +69,17 @@ namespace osu.Game.Beatmaps
public bool Equals(BeatmapSetInfo other) public bool Equals(BeatmapSetInfo other)
{ {
if (other == null) if (ReferenceEquals(this, other)) return true;
return false; if (other == null) return false;
if (ID != 0 && other.ID != 0) if (ID != 0 && other.ID != 0)
return ID == other.ID; return ID == other.ID;
if (OnlineID.HasValue && other.OnlineID.HasValue) return false;
return OnlineID == other.OnlineID;
if (!string.IsNullOrEmpty(Hash) && !string.IsNullOrEmpty(other.Hash))
return Hash == other.Hash;
return ReferenceEquals(this, other);
} }
public bool Equals(IBeatmapSetInfo other) => other is BeatmapSetInfo b && Equals(b);
#region Implementation of IHasOnlineID #region Implementation of IHasOnlineID
int IHasOnlineID<int>.OnlineID => OnlineID ?? -1; int IHasOnlineID<int>.OnlineID => OnlineID ?? -1;

View File

@ -69,7 +69,7 @@ namespace osu.Game.Beatmaps
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new DummyBeatmapConverter { Beatmap = beatmap }; public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new DummyBeatmapConverter { Beatmap = beatmap };
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => null; public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => null;
public override string Description => "dummy"; public override string Description => "dummy";

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Rulesets; using osu.Game.Rulesets;
@ -11,7 +12,7 @@ namespace osu.Game.Beatmaps
/// <summary> /// <summary>
/// A single beatmap difficulty. /// A single beatmap difficulty.
/// </summary> /// </summary>
public interface IBeatmapInfo : IHasOnlineID<int> public interface IBeatmapInfo : IHasOnlineID<int>, IEquatable<IBeatmapInfo>
{ {
/// <summary> /// <summary>
/// The user-specified name given to this beatmap. /// The user-specified name given to this beatmap.

View File

@ -12,7 +12,7 @@ namespace osu.Game.Beatmaps
/// <summary> /// <summary>
/// A representation of a collection of beatmap difficulties, generally packaged as an ".osz" archive. /// A representation of a collection of beatmap difficulties, generally packaged as an ".osz" archive.
/// </summary> /// </summary>
public interface IBeatmapSetInfo : IHasOnlineID<int> public interface IBeatmapSetInfo : IHasOnlineID<int>, IEquatable<IBeatmapSetInfo>
{ {
/// <summary> /// <summary>
/// The date when this beatmap was imported. /// The date when this beatmap was imported.

View File

@ -95,7 +95,7 @@ namespace osu.Game.Beatmaps
/// <param name="cancellationToken">Cancellation token that cancels the beatmap loading process. If not provided, a default timeout of 10,000ms will be applied to the load process.</param> /// <param name="cancellationToken">Cancellation token that cancels the beatmap loading process. If not provided, a default timeout of 10,000ms will be applied to the load process.</param>
/// <returns>The converted <see cref="IBeatmap"/>.</returns> /// <returns>The converted <see cref="IBeatmap"/>.</returns>
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception> /// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, CancellationToken? cancellationToken = null); IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods = null, CancellationToken? cancellationToken = null);
/// <summary> /// <summary>
/// Load a new audio track instance for this beatmap. This should be called once before accessing <see cref="Track"/>. /// Load a new audio track instance for this beatmap. This should be called once before accessing <see cref="Track"/>.

View File

@ -78,7 +78,7 @@ namespace osu.Game.Beatmaps
/// <returns>The applicable <see cref="IBeatmapConverter"/>.</returns> /// <returns>The applicable <see cref="IBeatmapConverter"/>.</returns>
protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap); protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap);
public virtual IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, CancellationToken? cancellationToken = null) public virtual IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods = null, CancellationToken? cancellationToken = null)
{ {
var token = cancellationToken ?? new CancellationTokenSource(10000).Token; var token = cancellationToken ?? new CancellationTokenSource(10000).Token;
mods ??= Array.Empty<Mod>(); mods ??= Array.Empty<Mod>();

View File

@ -25,7 +25,7 @@ namespace osu.Game.Collections
/// <summary> /// <summary>
/// The beatmaps contained by the collection. /// The beatmaps contained by the collection.
/// </summary> /// </summary>
public readonly BindableList<BeatmapInfo> Beatmaps = new BindableList<BeatmapInfo>(); public readonly BindableList<IBeatmapInfo> Beatmaps = new BindableList<IBeatmapInfo>();
/// <summary> /// <summary>
/// The date when this collection was last modified. /// The date when this collection was last modified.

View File

@ -39,7 +39,7 @@ namespace osu.Game.Collections
} }
private readonly IBindableList<BeatmapCollection> collections = new BindableList<BeatmapCollection>(); private readonly IBindableList<BeatmapCollection> collections = new BindableList<BeatmapCollection>();
private readonly IBindableList<BeatmapInfo> beatmaps = new BindableList<BeatmapInfo>(); private readonly IBindableList<IBeatmapInfo> beatmaps = new BindableList<IBeatmapInfo>();
private readonly BindableList<CollectionFilterMenuItem> filters = new BindableList<CollectionFilterMenuItem>(); private readonly BindableList<CollectionFilterMenuItem> filters = new BindableList<CollectionFilterMenuItem>();
[Resolved(CanBeNull = true)] [Resolved(CanBeNull = true)]
@ -200,7 +200,7 @@ namespace osu.Game.Collections
private IBindable<WorkingBeatmap> beatmap { get; set; } private IBindable<WorkingBeatmap> beatmap { get; set; }
[CanBeNull] [CanBeNull]
private readonly BindableList<BeatmapInfo> collectionBeatmaps; private readonly BindableList<IBeatmapInfo> collectionBeatmaps;
[NotNull] [NotNull]
private readonly Bindable<string> collectionName; private readonly Bindable<string> collectionName;

View File

@ -1,11 +1,14 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System;
#nullable enable #nullable enable
namespace osu.Game.Database namespace osu.Game.Database
{ {
public interface IHasOnlineID<out T> public interface IHasOnlineID<out T>
where T : IEquatable<T>
{ {
/// <summary> /// <summary>
/// The server-side ID representing this instance, if one exists. Any value 0 or less denotes a missing ID (except in special cases where autoincrement is not used, like rulesets). /// The server-side ID representing this instance, if one exists. Any value 0 or less denotes a missing ID (except in special cases where autoincrement is not used, like rulesets).

View File

@ -2,10 +2,14 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Users; using osu.Game.Users;
#nullable enable
namespace osu.Game.Extensions namespace osu.Game.Extensions
{ {
public static class ModelExtensions public static class ModelExtensions
@ -22,9 +26,9 @@ namespace osu.Game.Extensions
/// extension method type inference rules cause this method to call itself and cause a stack overflow. /// extension method type inference rules cause this method to call itself and cause a stack overflow.
/// </para> /// </para>
/// </remarks> /// </remarks>
public static string GetDisplayString(this object model) public static string GetDisplayString(this object? model)
{ {
string result = null; string? result = null;
switch (model) switch (model)
{ {
@ -57,5 +61,59 @@ namespace osu.Game.Extensions
result ??= model?.ToString() ?? @"null"; result ??= model?.ToString() ?? @"null";
return result; return result;
} }
/// <summary>
/// Check whether the online ID of two <see cref="IBeatmapSetInfo"/>s match.
/// </summary>
/// <param name="instance">The instance to compare.</param>
/// <param name="other">The other instance to compare against.</param>
/// <returns>Whether online IDs match. If either instance is missing an online ID, this will return false.</returns>
public static bool MatchesOnlineID(this IBeatmapSetInfo? instance, IBeatmapSetInfo? other) => matchesOnlineID(instance, other);
/// <summary>
/// Check whether the online ID of two <see cref="IBeatmapInfo"/>s match.
/// </summary>
/// <param name="instance">The instance to compare.</param>
/// <param name="other">The other instance to compare against.</param>
/// <returns>Whether online IDs match. If either instance is missing an online ID, this will return false.</returns>
public static bool MatchesOnlineID(this IBeatmapInfo? instance, IBeatmapInfo? other) => matchesOnlineID(instance, other);
/// <summary>
/// Check whether the online ID of two <see cref="IRulesetInfo"/>s match.
/// </summary>
/// <param name="instance">The instance to compare.</param>
/// <param name="other">The other instance to compare against.</param>
/// <returns>Whether online IDs match. If either instance is missing an online ID, this will return false.</returns>
public static bool MatchesOnlineID(this IRulesetInfo? instance, IRulesetInfo? other) => matchesOnlineID(instance, other);
/// <summary>
/// Check whether the online ID of two <see cref="APIUser"/>s match.
/// </summary>
/// <param name="instance">The instance to compare.</param>
/// <param name="other">The other instance to compare against.</param>
/// <returns>Whether online IDs match. If either instance is missing an online ID, this will return false.</returns>
public static bool MatchesOnlineID(this APIUser? instance, APIUser? other) => matchesOnlineID(instance, other);
private static bool matchesOnlineID(this IHasOnlineID<long>? instance, IHasOnlineID<long>? other)
{
if (instance == null || other == null)
return false;
if (instance.OnlineID < 0 || other.OnlineID < 0)
return false;
return instance.OnlineID.Equals(other.OnlineID);
}
private static bool matchesOnlineID(this IHasOnlineID<int>? instance, IHasOnlineID<int>? other)
{
if (instance == null || other == null)
return false;
if (instance.OnlineID < 0 || other.OnlineID < 0)
return false;
return instance.OnlineID.Equals(other.OnlineID);
}
} }
} }

View File

@ -20,7 +20,7 @@ namespace osu.Game.Models
[ExcludeFromDynamicCompile] [ExcludeFromDynamicCompile]
[Serializable] [Serializable]
[MapTo("Beatmap")] [MapTo("Beatmap")]
public class RealmBeatmap : RealmObject, IHasGuidPrimaryKey, IBeatmapInfo public class RealmBeatmap : RealmObject, IHasGuidPrimaryKey, IBeatmapInfo, IEquatable<RealmBeatmap>
{ {
[PrimaryKey] [PrimaryKey]
public Guid ID { get; set; } = Guid.NewGuid(); public Guid ID { get; set; } = Guid.NewGuid();
@ -98,6 +98,16 @@ namespace osu.Game.Models
#endregion #endregion
public bool Equals(RealmBeatmap? other)
{
if (ReferenceEquals(this, other)) return true;
if (other == null) return false;
return ID == other.ID;
}
public bool Equals(IBeatmapInfo? other) => other is RealmBeatmap b && Equals(b);
public bool AudioEquals(RealmBeatmap? other) => other != null public bool AudioEquals(RealmBeatmap? other) => other != null
&& BeatmapSet != null && BeatmapSet != null
&& other.BeatmapSet != null && other.BeatmapSet != null

View File

@ -7,6 +7,7 @@ using System.Linq;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Extensions;
using Realms; using Realms;
#nullable enable #nullable enable
@ -53,25 +54,18 @@ namespace osu.Game.Models
/// <param name="filename">The name of the file to get the storage path of.</param> /// <param name="filename">The name of the file to get the storage path of.</param>
public string? GetPathForFile(string filename) => Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.File.StoragePath; public string? GetPathForFile(string filename) => Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.File.StoragePath;
public override string ToString() => Metadata?.ToString() ?? base.ToString();
public bool Equals(RealmBeatmapSet? other) public bool Equals(RealmBeatmapSet? other)
{ {
if (other == null) if (ReferenceEquals(this, other)) return true;
return false; if (other == null) return false;
if (IsManaged && other.IsManaged)
return ID == other.ID; return ID == other.ID;
if (OnlineID > 0 && other.OnlineID > 0)
return OnlineID == other.OnlineID;
if (!string.IsNullOrEmpty(Hash) && !string.IsNullOrEmpty(other.Hash))
return Hash == other.Hash;
return ReferenceEquals(this, other);
} }
public override string ToString() => Metadata?.GetDisplayString() ?? base.ToString();
public bool Equals(IBeatmapSetInfo? other) => other is RealmBeatmapSet b && Equals(b);
IEnumerable<IBeatmapInfo> IBeatmapSetInfo.Beatmaps => Beatmaps; IEnumerable<IBeatmapInfo> IBeatmapSetInfo.Beatmaps => Beatmaps;
IEnumerable<INamedFileUsage> IBeatmapSetInfo.Files => Files; IEnumerable<INamedFileUsage> IBeatmapSetInfo.Files => Files;

View File

@ -4,6 +4,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Extensions;
using osu.Game.Rulesets; using osu.Game.Rulesets;
#nullable enable #nullable enable
@ -103,5 +104,7 @@ namespace osu.Game.Online.API.Requests.Responses
public string Hash => throw new NotImplementedException(); public string Hash => throw new NotImplementedException();
#endregion #endregion
public bool Equals(IBeatmapInfo? other) => other is APIBeatmap b && this.MatchesOnlineID(b);
} }
} }

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Extensions;
#nullable enable #nullable enable
@ -141,5 +142,7 @@ namespace osu.Game.Online.API.Requests.Responses
double IBeatmapSetInfo.MaxBPM => BPM; double IBeatmapSetInfo.MaxBPM => BPM;
#endregion #endregion
public bool Equals(IBeatmapSetInfo? other) => other is APIBeatmapSet b && this.MatchesOnlineID(b);
} }
} }

View File

@ -7,6 +7,7 @@ using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Extensions;
using osu.Game.Users; using osu.Game.Users;
namespace osu.Game.Online.API.Requests.Responses namespace osu.Game.Online.API.Requests.Responses
@ -240,6 +241,6 @@ namespace osu.Game.Online.API.Requests.Responses
public int OnlineID => Id; public int OnlineID => Id;
public bool Equals(APIUser other) => OnlineID == other?.OnlineID; public bool Equals(APIUser other) => this.MatchesOnlineID(other);
} }
} }

View File

@ -41,8 +41,10 @@ namespace osu.Game.Online.Chat
/// <param name="postingTextbox">Whether a textbox for posting new messages should be displayed.</param> /// <param name="postingTextbox">Whether a textbox for posting new messages should be displayed.</param>
public StandAloneChatDisplay(bool postingTextbox = false) public StandAloneChatDisplay(bool postingTextbox = false)
{ {
const float corner_radius = 10;
this.postingTextbox = postingTextbox; this.postingTextbox = postingTextbox;
CornerRadius = 10; CornerRadius = corner_radius;
Masking = true; Masking = true;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
@ -62,6 +64,7 @@ namespace osu.Game.Online.Chat
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Height = textbox_height, Height = textbox_height,
PlaceholderText = "type your message", PlaceholderText = "type your message",
CornerRadius = corner_radius,
ReleaseFocusOnCommit = false, ReleaseFocusOnCommit = false,
HoldFocus = true, HoldFocus = true,
Anchor = Anchor.BottomLeft, Anchor = Anchor.BottomLeft,

View File

@ -10,6 +10,7 @@ using Newtonsoft.Json.Converters;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring; using osu.Game.Scoring;
@ -62,7 +63,7 @@ namespace osu.Game.Online.Rooms
[CanBeNull] [CanBeNull]
public MultiplayerScoresAround ScoresAround { get; set; } public MultiplayerScoresAround ScoresAround { get; set; }
public ScoreInfo CreateScoreInfo(PlaylistItem playlistItem, [NotNull] BeatmapInfo beatmap) public ScoreInfo CreateScoreInfo(RulesetStore rulesets, PlaylistItem playlistItem, [NotNull] BeatmapInfo beatmap)
{ {
var rulesetInstance = playlistItem.Ruleset.Value.CreateInstance(); var rulesetInstance = playlistItem.Ruleset.Value.CreateInstance();
@ -73,7 +74,7 @@ namespace osu.Game.Online.Rooms
MaxCombo = MaxCombo, MaxCombo = MaxCombo,
BeatmapInfo = beatmap, BeatmapInfo = beatmap,
BeatmapInfoID = playlistItem.BeatmapID, BeatmapInfoID = playlistItem.BeatmapID,
Ruleset = playlistItem.Ruleset.Value, Ruleset = rulesets.GetRuleset(playlistItem.RulesetID),
RulesetID = playlistItem.RulesetID, RulesetID = playlistItem.RulesetID,
Statistics = Statistics, Statistics = Statistics,
User = User, User = User,

View File

@ -34,7 +34,7 @@ namespace osu.Game.Online.Rooms
public readonly Bindable<IBeatmapInfo> Beatmap = new Bindable<IBeatmapInfo>(); public readonly Bindable<IBeatmapInfo> Beatmap = new Bindable<IBeatmapInfo>();
[JsonIgnore] [JsonIgnore]
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>(); public readonly Bindable<IRulesetInfo> Ruleset = new Bindable<IRulesetInfo>();
[JsonIgnore] [JsonIgnore]
public readonly BindableList<Mod> AllowedMods = new BindableList<Mod>(); public readonly BindableList<Mod> AllowedMods = new BindableList<Mod>();
@ -66,7 +66,7 @@ namespace osu.Game.Online.Rooms
public PlaylistItem() public PlaylistItem()
{ {
Beatmap.BindValueChanged(beatmap => BeatmapID = beatmap.NewValue?.OnlineID ?? -1); Beatmap.BindValueChanged(beatmap => BeatmapID = beatmap.NewValue?.OnlineID ?? -1);
Ruleset.BindValueChanged(ruleset => RulesetID = ruleset.NewValue?.ID ?? 0); Ruleset.BindValueChanged(ruleset => RulesetID = ruleset.NewValue?.OnlineID ?? 0);
} }
public void MapObjects(RulesetStore rulesets) public void MapObjects(RulesetStore rulesets)

View File

@ -8,6 +8,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Extensions;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online; using osu.Game.Online;
@ -80,7 +81,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
case DownloadState.LocallyAvailable: case DownloadState.LocallyAvailable:
Predicate<BeatmapInfo> findPredicate = null; Predicate<BeatmapInfo> findPredicate = null;
if (SelectedBeatmap.Value != null) if (SelectedBeatmap.Value != null)
findPredicate = b => b.OnlineID == SelectedBeatmap.Value.OnlineID; findPredicate = b => b.MatchesOnlineID(SelectedBeatmap.Value);
game?.PresentBeatmap(beatmapSet, findPredicate); game?.PresentBeatmap(beatmapSet, findPredicate);
break; break;

View File

@ -14,6 +14,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables; using osu.Game.Beatmaps.Drawables;
using osu.Game.Extensions;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
@ -166,7 +167,7 @@ namespace osu.Game.Overlays.BeatmapSet
if (BeatmapSet != null) if (BeatmapSet != null)
{ {
Difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps Difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps
.Where(b => b.Ruleset.OnlineID == ruleset.Value?.OnlineID) .Where(b => b.Ruleset.MatchesOnlineID(ruleset.Value))
.OrderBy(b => b.StarRating) .OrderBy(b => b.StarRating)
.Select(b => new DifficultySelectorButton(b) .Select(b => new DifficultySelectorButton(b)
{ {

View File

@ -7,6 +7,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Extensions;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
@ -64,7 +65,7 @@ namespace osu.Game.Overlays.BeatmapSet
BeatmapSet.BindValueChanged(setInfo => BeatmapSet.BindValueChanged(setInfo =>
{ {
int beatmapsCount = setInfo.NewValue?.Beatmaps.Count(b => b.Ruleset.OnlineID == Value.OnlineID) ?? 0; int beatmapsCount = setInfo.NewValue?.Beatmaps.Count(b => b.Ruleset.MatchesOnlineID(Value)) ?? 0;
count.Text = beatmapsCount.ToString(); count.Text = beatmapsCount.ToString();
countContainer.FadeTo(beatmapsCount > 0 ? 1 : 0); countContainer.FadeTo(beatmapsCount > 0 ? 1 : 0);

View File

@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Music
var items = (SearchContainer<RearrangeableListItem<BeatmapSetInfo>>)ListContainer; var items = (SearchContainer<RearrangeableListItem<BeatmapSetInfo>>)ListContainer;
foreach (var item in items.OfType<PlaylistItem>()) foreach (var item in items.OfType<PlaylistItem>())
item.InSelectedCollection = criteria.Collection?.Beatmaps.Any(b => b.BeatmapSet.Equals(item.Model)) ?? true; item.InSelectedCollection = criteria.Collection?.Beatmaps.Any(b => item.Model.Equals(b.BeatmapSet)) ?? true;
items.SearchTerm = criteria.SearchText; items.SearchTerm = criteria.SearchText;
} }

View File

@ -28,10 +28,10 @@ namespace osu.Game.Rulesets.Difficulty
private Mod[] playableMods; private Mod[] playableMods;
private double clockRate; private double clockRate;
private readonly Ruleset ruleset; private readonly IRulesetInfo ruleset;
private readonly WorkingBeatmap beatmap; private readonly IWorkingBeatmap beatmap;
protected DifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) protected DifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
{ {
this.ruleset = ruleset; this.ruleset = ruleset;
this.beatmap = beatmap; this.beatmap = beatmap;
@ -145,7 +145,7 @@ namespace osu.Game.Rulesets.Difficulty
{ {
playableMods = mods.Select(m => m.DeepClone()).ToArray(); playableMods = mods.Select(m => m.DeepClone()).ToArray();
Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, playableMods, cancellationToken: cancellationToken); Beatmap = beatmap.GetPlayableBeatmap(ruleset, playableMods, cancellationToken);
var track = new TrackVirtual(10000); var track = new TrackVirtual(10000);
playableMods.OfType<IApplicableToTrack>().ForEach(m => m.ApplyToTrack(track)); playableMods.OfType<IApplicableToTrack>().ForEach(m => m.ApplyToTrack(track));

View File

@ -222,7 +222,7 @@ namespace osu.Game.Rulesets
/// <returns>The <see cref="IBeatmapProcessor"/>.</returns> /// <returns>The <see cref="IBeatmapProcessor"/>.</returns>
public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null; public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null;
public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); public abstract DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap);
/// <summary> /// <summary>
/// Optionally creates a <see cref="PerformanceCalculator"/> to generate performance data from the provided score. /// Optionally creates a <see cref="PerformanceCalculator"/> to generate performance data from the provided score.
@ -240,7 +240,7 @@ namespace osu.Game.Rulesets
/// <param name="score">The score to be processed.</param> /// <param name="score">The score to be processed.</param>
/// <returns>A performance calculator instance for the provided score.</returns> /// <returns>A performance calculator instance for the provided score.</returns>
[CanBeNull] [CanBeNull]
public PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) public PerformanceCalculator CreatePerformanceCalculator(IWorkingBeatmap beatmap, ScoreInfo score)
{ {
var difficultyCalculator = CreateDifficultyCalculator(beatmap); var difficultyCalculator = CreateDifficultyCalculator(beatmap);
var difficultyAttributes = difficultyCalculator.Calculate(score.Mods); var difficultyAttributes = difficultyCalculator.Calculate(score.Mods);

View File

@ -46,7 +46,7 @@ namespace osu.Game.Screens.OnlinePlay
private ModDisplay modDisplay; private ModDisplay modDisplay;
private readonly Bindable<IBeatmapInfo> beatmap = new Bindable<IBeatmapInfo>(); private readonly Bindable<IBeatmapInfo> beatmap = new Bindable<IBeatmapInfo>();
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>(); private readonly Bindable<IRulesetInfo> ruleset = new Bindable<IRulesetInfo>();
private readonly BindableList<Mod> requiredMods = new BindableList<Mod>(); private readonly BindableList<Mod> requiredMods = new BindableList<Mod>();
public readonly PlaylistItem Item; public readonly PlaylistItem Item;

View File

@ -82,7 +82,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
{ {
bool matchingFilter = true; bool matchingFilter = true;
matchingFilter &= r.Room.Playlist.Count == 0 || criteria.Ruleset == null || r.Room.Playlist.Any(i => i.Ruleset.Value.Equals(criteria.Ruleset)); matchingFilter &= r.Room.Playlist.Count == 0 || criteria.Ruleset == null || r.Room.Playlist.Any(i => i.Ruleset.Value.MatchesOnlineID(criteria.Ruleset));
if (!string.IsNullOrEmpty(criteria.SearchString)) if (!string.IsNullOrEmpty(criteria.SearchString))
matchingFilter &= r.FilterTerms.Any(term => term.Contains(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase)); matchingFilter &= r.FilterTerms.Any(term => term.Contains(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase));

View File

@ -18,6 +18,7 @@ using osu.Game.Beatmaps;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.OnlinePlay.Match.Components;
@ -59,6 +60,9 @@ namespace osu.Game.Screens.OnlinePlay.Match
[Resolved] [Resolved]
private BeatmapManager beatmapManager { get; set; } private BeatmapManager beatmapManager { get; set; }
[Resolved]
private RulesetStore rulesets { get; set; }
[Resolved(canBeNull: true)] [Resolved(canBeNull: true)]
protected OnlinePlayScreen ParentScreen { get; private set; } protected OnlinePlayScreen ParentScreen { get; private set; }
@ -344,7 +348,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
UpdateMods(); UpdateMods();
Ruleset.Value = selected.Ruleset.Value; Ruleset.Value = rulesets.GetRuleset(selected.RulesetID);
if (!selected.AllowedMods.Any()) if (!selected.AllowedMods.Any())
{ {

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Extensions;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Scoring; using osu.Game.Scoring;
@ -32,10 +33,10 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
private void load(IBindable<RulesetInfo> ruleset) private void load(IBindable<RulesetInfo> ruleset)
{ {
// Sanity checks to ensure that PlaylistsPlayer matches the settings for the current PlaylistItem // Sanity checks to ensure that PlaylistsPlayer matches the settings for the current PlaylistItem
if (Beatmap.Value.BeatmapInfo.OnlineID != PlaylistItem.Beatmap.Value.OnlineID) if (!Beatmap.Value.BeatmapInfo.MatchesOnlineID(PlaylistItem.Beatmap.Value))
throw new InvalidOperationException("Current Beatmap does not match PlaylistItem's Beatmap"); throw new InvalidOperationException("Current Beatmap does not match PlaylistItem's Beatmap");
if (ruleset.Value.ID != PlaylistItem.Ruleset.Value.ID) if (!ruleset.Value.MatchesOnlineID(PlaylistItem.Ruleset.Value))
throw new InvalidOperationException("Current Ruleset does not match PlaylistItem's Ruleset"); throw new InvalidOperationException("Current Ruleset does not match PlaylistItem's Ruleset");
if (!PlaylistItem.RequiredMods.All(m => Mods.Value.Any(m.Equals))) if (!PlaylistItem.RequiredMods.All(m => Mods.Value.Any(m.Equals)))

View File

@ -12,6 +12,7 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Rulesets;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Screens.Ranking; using osu.Game.Screens.Ranking;
@ -35,6 +36,9 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
[Resolved] [Resolved]
private ScoreManager scoreManager { get; set; } private ScoreManager scoreManager { get; set; }
[Resolved]
private RulesetStore rulesets { get; set; }
public PlaylistsResultsScreen(ScoreInfo score, long roomId, PlaylistItem playlistItem, bool allowRetry, bool allowWatchingReplay = true) public PlaylistsResultsScreen(ScoreInfo score, long roomId, PlaylistItem playlistItem, bool allowRetry, bool allowWatchingReplay = true)
: base(score, allowRetry, allowWatchingReplay) : base(score, allowRetry, allowWatchingReplay)
{ {
@ -169,7 +173,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
/// <param name="pivot">An optional pivot around which the scores were retrieved.</param> /// <param name="pivot">An optional pivot around which the scores were retrieved.</param>
private void performSuccessCallback([NotNull] Action<IEnumerable<ScoreInfo>> callback, [NotNull] List<MultiplayerScore> scores, [CanBeNull] MultiplayerScores pivot = null) private void performSuccessCallback([NotNull] Action<IEnumerable<ScoreInfo>> callback, [NotNull] List<MultiplayerScore> scores, [CanBeNull] MultiplayerScores pivot = null)
{ {
var scoreInfos = scores.Select(s => s.CreateScoreInfo(playlistItem, Beatmap.Value.BeatmapInfo)).ToArray(); var scoreInfos = scores.Select(s => s.CreateScoreInfo(rulesets, playlistItem, Beatmap.Value.BeatmapInfo)).ToArray();
// Score panels calculate total score before displaying, which can take some time. In order to count that calculation as part of the loading spinner display duration, // Score panels calculate total score before displaying, which can take some time. In order to count that calculation as part of the loading spinner display duration,
// calculate the total scores locally before invoking the success callback. // calculate the total scores locally before invoking the success callback.

View File

@ -216,7 +216,7 @@ namespace osu.Game.Screens.Play.HUD
this.gameplayBeatmap = gameplayBeatmap; this.gameplayBeatmap = gameplayBeatmap;
} }
public override IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, CancellationToken? cancellationToken = null) public override IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods = null, CancellationToken? cancellationToken = null)
=> gameplayBeatmap; => gameplayBeatmap;
protected override IBeatmap GetBeatmap() => gameplayBeatmap; protected override IBeatmap GetBeatmap() => gameplayBeatmap;

View File

@ -116,6 +116,8 @@ namespace osu.Game.Screens.Select.Leaderboards
loadCancellationSource?.Cancel(); loadCancellationSource?.Cancel();
loadCancellationSource = new CancellationTokenSource(); loadCancellationSource = new CancellationTokenSource();
var cancellationToken = loadCancellationSource.Token;
if (BeatmapInfo == null) if (BeatmapInfo == null)
{ {
PlaceholderState = PlaceholderState.NoneSelected; PlaceholderState = PlaceholderState.NoneSelected;
@ -140,7 +142,7 @@ namespace osu.Game.Screens.Select.Leaderboards
scores = scores.Where(s => s.Mods.Any(m => selectedMods.Contains(m.Acronym))); scores = scores.Where(s => s.Mods.Any(m => selectedMods.Contains(m.Acronym)));
} }
scoreManager.OrderByTotalScoreAsync(scores.ToArray(), loadCancellationSource.Token) scoreManager.OrderByTotalScoreAsync(scores.ToArray(), cancellationToken)
.ContinueWith(ordered => scoresCallback?.Invoke(ordered.Result), TaskContinuationOptions.OnlyOnRanToCompletion); .ContinueWith(ordered => scoresCallback?.Invoke(ordered.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
return null; return null;
@ -176,10 +178,10 @@ namespace osu.Game.Screens.Select.Leaderboards
req.Success += r => req.Success += r =>
{ {
scoreManager.OrderByTotalScoreAsync(r.Scores.Select(s => s.CreateScoreInfo(rulesets, BeatmapInfo)).ToArray(), loadCancellationSource.Token) scoreManager.OrderByTotalScoreAsync(r.Scores.Select(s => s.CreateScoreInfo(rulesets, BeatmapInfo)).ToArray(), cancellationToken)
.ContinueWith(ordered => Schedule(() => .ContinueWith(ordered => Schedule(() =>
{ {
if (loadCancellationSource.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
return; return;
scoresCallback?.Invoke(ordered.Result); scoresCallback?.Invoke(ordered.Result);

View File

@ -28,7 +28,7 @@ namespace osu.Game.Tests.Beatmaps
Assert.That(CreateDifficultyCalculator(getBeatmap(name)).Calculate(mods).StarRating, Is.EqualTo(expected).Within(0.00001)); Assert.That(CreateDifficultyCalculator(getBeatmap(name)).Calculate(mods).StarRating, Is.EqualTo(expected).Within(0.00001));
} }
private WorkingBeatmap getBeatmap(string name) private IWorkingBeatmap getBeatmap(string name)
{ {
using (var resStream = openResource($"{resource_namespace}.{name}.osu")) using (var resStream = openResource($"{resource_namespace}.{name}.osu"))
using (var stream = new LineBufferedReader(resStream)) using (var stream = new LineBufferedReader(resStream))
@ -53,7 +53,7 @@ namespace osu.Game.Tests.Beatmaps
return Assembly.LoadFrom(Path.Combine(localPath, $"{ResourceAssembly}.dll")).GetManifestResourceStream($@"{ResourceAssembly}.Resources.{name}"); return Assembly.LoadFrom(Path.Combine(localPath, $"{ResourceAssembly}.dll")).GetManifestResourceStream($@"{ResourceAssembly}.Resources.{name}");
} }
protected abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); protected abstract DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap);
protected abstract Ruleset CreateRuleset(); protected abstract Ruleset CreateRuleset();
} }

View File

@ -0,0 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using Newtonsoft.Json;
namespace osu.Game.Updater
{
public class GitHubAsset
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("browser_download_url")]
public string BrowserDownloadUrl { get; set; }
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using Newtonsoft.Json;
namespace osu.Game.Updater
{
public class GitHubRelease
{
[JsonProperty("html_url")]
public string HtmlUrl { get; set; }
[JsonProperty("tag_name")]
public string TagName { get; set; }
[JsonProperty("assets")]
public List<GitHubAsset> Assets { get; set; }
}
}

View File

@ -0,0 +1,67 @@
// 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 System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Platform;
using osu.Game.Online.API;
using osu.Game.Overlays.Notifications;
namespace osu.Game.Updater
{
/// <summary>
/// An update manager that shows notifications if a newer release is detected.
/// This is a case where updates are handled externally by a package manager or other means, so no action is performed on clicking the notification.
/// </summary>
public class NoActionUpdateManager : UpdateManager
{
private string version;
[Resolved]
private GameHost host { get; set; }
[BackgroundDependencyLoader]
private void load(OsuGameBase game)
{
version = game.Version;
}
protected override async Task<bool> PerformUpdateCheck()
{
try
{
var releases = new OsuJsonWebRequest<GitHubRelease>("https://api.github.com/repos/ppy/osu/releases/latest");
await releases.PerformAsync().ConfigureAwait(false);
var latest = releases.ResponseObject;
// avoid any discrepancies due to build suffixes for now.
// eventually we will want to support release streams and consider these.
version = version.Split('-').First();
string latestTagName = latest.TagName.Split('-').First();
if (latestTagName != version)
{
Notifications.Post(new SimpleNotification
{
Text = $"A newer release of osu! has been found ({version} → {latestTagName}).\n\n"
+ "Check with your package manager / provider to bring osu! up-to-date!",
Icon = FontAwesome.Solid.Upload,
});
return true;
}
}
catch
{
// we shouldn't crash on a web failure. or any failure for the matter.
return true;
}
return false;
}
}
}

View File

@ -2,10 +2,8 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json;
using osu.Framework; using osu.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
@ -104,26 +102,5 @@ namespace osu.Game.Updater
return bestAsset?.BrowserDownloadUrl ?? release.HtmlUrl; return bestAsset?.BrowserDownloadUrl ?? release.HtmlUrl;
} }
public class GitHubRelease
{
[JsonProperty("html_url")]
public string HtmlUrl { get; set; }
[JsonProperty("tag_name")]
public string TagName { get; set; }
[JsonProperty("assets")]
public List<GitHubAsset> Assets { get; set; }
}
public class GitHubAsset
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("browser_download_url")]
public string BrowserDownloadUrl { get; set; }
}
} }
} }

View File

@ -209,6 +209,8 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StructCanBeMadeReadOnly/@EntryIndexedValue">WARNING</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StructCanBeMadeReadOnly/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">SUGGESTION</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuspiciousTypeConversion_002EGlobal/@EntryIndexedValue"></s:String>
<s:Boolean x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuspiciousTypeConversion_002EGlobal/@EntryIndexRemoved">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SwitchStatementMissingSomeCases/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SwitchStatementMissingSomeCases/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TabsAndSpacesMismatch/@EntryIndexedValue">WARNING</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TabsAndSpacesMismatch/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TabsAreDisallowed/@EntryIndexedValue">WARNING</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TabsAreDisallowed/@EntryIndexedValue">WARNING</s:String>