Merge branch 'master' into legacy-slider-body

This commit is contained in:
Dean Herbert 2019-12-17 23:42:31 +09:00 committed by GitHub
commit 4443d2196b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 389 additions and 133 deletions

58
CodeAnalysis/osu.ruleset Normal file
View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="osu! Rule Set" Description=" " ToolsVersion="16.0">
<Rules AnalyzerId="Microsoft.CodeQuality.Analyzers" RuleNamespace="Microsoft.CodeQuality.Analyzers">
<Rule Id="CA1016" Action="None" />
<Rule Id="CA1028" Action="None" />
<Rule Id="CA1031" Action="None" />
<Rule Id="CA1034" Action="None" />
<Rule Id="CA1036" Action="None" />
<Rule Id="CA1040" Action="None" />
<Rule Id="CA1044" Action="None" />
<Rule Id="CA1051" Action="None" />
<Rule Id="CA1054" Action="None" />
<Rule Id="CA1056" Action="None" />
<Rule Id="CA1062" Action="None" />
<Rule Id="CA1063" Action="None" />
<Rule Id="CA1067" Action="None" />
<Rule Id="CA1707" Action="None" />
<Rule Id="CA1710" Action="None" />
<Rule Id="CA1714" Action="None" />
<Rule Id="CA1716" Action="None" />
<Rule Id="CA1717" Action="None" />
<Rule Id="CA1720" Action="None" />
<Rule Id="CA1721" Action="None" />
<Rule Id="CA1724" Action="None" />
<Rule Id="CA1801" Action="None" />
<Rule Id="CA1806" Action="None" />
<Rule Id="CA1812" Action="None" />
<Rule Id="CA1814" Action="None" />
<Rule Id="CA1815" Action="None" />
<Rule Id="CA1819" Action="None" />
<Rule Id="CA1822" Action="None" />
<Rule Id="CA1823" Action="None" />
<Rule Id="CA2007" Action="None" />
<Rule Id="CA2214" Action="None" />
<Rule Id="CA2227" Action="None" />
</Rules>
<Rules AnalyzerId="Microsoft.CodeQuality.CSharp.Analyzers" RuleNamespace="Microsoft.CodeQuality.CSharp.Analyzers">
<Rule Id="CA1001" Action="None" />
<Rule Id="CA1032" Action="None" />
</Rules>
<Rules AnalyzerId="Microsoft.NetCore.Analyzers" RuleNamespace="Microsoft.NetCore.Analyzers">
<Rule Id="CA1303" Action="None" />
<Rule Id="CA1304" Action="None" />
<Rule Id="CA1305" Action="None" />
<Rule Id="CA1307" Action="None" />
<Rule Id="CA1308" Action="None" />
<Rule Id="CA1816" Action="None" />
<Rule Id="CA1826" Action="None" />
<Rule Id="CA2000" Action="None" />
<Rule Id="CA2008" Action="None" />
<Rule Id="CA2213" Action="None" />
<Rule Id="CA2235" Action="None" />
</Rules>
<Rules AnalyzerId="Microsoft.NetCore.CSharp.Analyzers" RuleNamespace="Microsoft.NetCore.CSharp.Analyzers">
<Rule Id="CA1309" Action="Warning" />
<Rule Id="CA2201" Action="Warning" />
</Rules>
</RuleSet>

View File

@ -18,7 +18,11 @@
<ItemGroup Label="Code Analysis">
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="2.9.8" PrivateAssets="All" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
</ItemGroup>
<PropertyGroup Label="Code Analysis">
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodeAnalysis\osu.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Label="Documentation">
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>

View File

@ -16,14 +16,20 @@ using osu.Game.Rulesets.Replays.Types;
using osu.Game.Beatmaps.Legacy;
using osu.Game.Rulesets.Catch.Beatmaps;
using osu.Game.Rulesets.Catch.Difficulty;
using osu.Game.Rulesets.Catch.Scoring;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using System;
namespace osu.Game.Rulesets.Catch
{
public class CatchRuleset : Ruleset
{
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableCatchRuleset(this, beatmap, mods);
public override ScoreProcessor CreateScoreProcessor(IBeatmap beatmap) => new CatchScoreProcessor(beatmap);
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
@ -114,7 +120,7 @@ namespace osu.Game.Rulesets.Catch
};
default:
return new Mod[] { };
return Array.Empty<Mod>();
}
}

View File

@ -10,10 +10,8 @@ using osu.Game.Replays;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Catch.Replays;
using osu.Game.Rulesets.Catch.Scoring;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
@ -32,8 +30,6 @@ namespace osu.Game.Rulesets.Catch.UI
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
}
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(Beatmap);
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, CreateDrawableRepresentation);

View File

@ -25,6 +25,8 @@ using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Configuration;
using osu.Game.Rulesets.Mania.Difficulty;
using osu.Game.Rulesets.Mania.Edit;
using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.Mania
@ -32,7 +34,11 @@ namespace osu.Game.Rulesets.Mania
public class ManiaRuleset : Ruleset
{
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableManiaRuleset(this, beatmap, mods);
public override ScoreProcessor CreateScoreProcessor(IBeatmap beatmap) => new ManiaScoreProcessor(beatmap);
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score);
public const string SHORT_NAME = "mania";
@ -160,7 +166,7 @@ namespace osu.Game.Rulesets.Mania
};
default:
return new Mod[] { };
return Array.Empty<Mod>();
}
}
@ -270,7 +276,7 @@ namespace osu.Game.Rulesets.Mania
return stage1Bindings.Concat(stage2Bindings);
}
return new KeyBinding[0];
return Array.Empty<KeyBinding>();
}
public override string GetVariantName(int variant)

View File

@ -14,11 +14,9 @@ using osu.Game.Rulesets.Mania.Configuration;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.Replays;
using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
using osuTK;
@ -67,8 +65,6 @@ namespace osu.Game.Rulesets.Mania.UI
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages);
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(Beatmap);
public override int Variant => (int)(Beatmap.Stages.Count == 1 ? PlayfieldType.Single : PlayfieldType.Dual) + Beatmap.TotalColumns;
protected override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant);

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using JetBrains.Annotations;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit.Compose.Components;
@ -10,7 +11,7 @@ namespace osu.Game.Rulesets.Osu.Edit
public class OsuDistanceSnapGrid : CircularDistanceSnapGrid
{
public OsuDistanceSnapGrid(OsuHitObject hitObject, [CanBeNull] OsuHitObject nextHitObject = null)
: base(hitObject.StackedPosition, hitObject.StartTime, nextHitObject?.StartTime)
: base(hitObject.StackedEndPosition, hitObject.GetEndTime(), nextHitObject?.StartTime)
{
Masking = true;
}

View File

@ -92,7 +92,24 @@ namespace osu.Game.Rulesets.Osu.Edit
return null;
OsuHitObject sourceObject = EditorBeatmap.HitObjects[sourceIndex];
OsuHitObject targetObject = sourceIndex + targetOffset < EditorBeatmap.HitObjects.Count ? EditorBeatmap.HitObjects[sourceIndex + targetOffset] : null;
int targetIndex = sourceIndex + targetOffset;
OsuHitObject targetObject = null;
// Keep advancing the target object while its start time falls before the end time of the source object
while (true)
{
if (targetIndex >= EditorBeatmap.HitObjects.Count)
break;
if (EditorBeatmap.HitObjects[targetIndex].StartTime >= sourceObject.GetEndTime())
{
targetObject = EditorBeatmap.HitObjects[targetIndex];
break;
}
targetIndex++;
}
return new OsuDistanceSnapGrid(sourceObject, targetObject);
}

View File

@ -23,16 +23,23 @@ using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Osu.Beatmaps;
using osu.Game.Rulesets.Osu.Configuration;
using osu.Game.Rulesets.Osu.Difficulty;
using osu.Game.Rulesets.Osu.Scoring;
using osu.Game.Rulesets.Osu.Skinning;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Skinning;
using System;
namespace osu.Game.Rulesets.Osu
{
public class OsuRuleset : Ruleset
{
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableOsuRuleset(this, beatmap, mods);
public override ScoreProcessor CreateScoreProcessor(IBeatmap beatmap) => new OsuScoreProcessor(beatmap);
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap);
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap);
public const string SHORT_NAME = "osu";
@ -151,7 +158,7 @@ namespace osu.Game.Rulesets.Osu
};
default:
return new Mod[] { };
return Array.Empty<Mod>();
}
}

View File

@ -14,8 +14,6 @@ using osu.Game.Rulesets.Osu.Configuration;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.Replays;
using osu.Game.Rulesets.Osu.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using osuTK;
@ -33,8 +31,6 @@ namespace osu.Game.Rulesets.Osu.UI
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; // always show the gameplay cursor
public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(Beatmap);
protected override Playfield CreatePlayfield() => new OsuPlayfield();
protected override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo);

View File

@ -105,19 +105,19 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
}
}
public abstract class DrawableTaikoHitObject<TaikoHitType> : DrawableTaikoHitObject
where TaikoHitType : TaikoHitObject
public abstract class DrawableTaikoHitObject<TTaikoHit> : DrawableTaikoHitObject
where TTaikoHit : TaikoHitObject
{
public override Vector2 OriginPosition => new Vector2(DrawHeight / 2);
public new TaikoHitType HitObject;
public new TTaikoHit HitObject;
protected readonly Vector2 BaseSize;
protected readonly TaikoPiece MainPiece;
private readonly Container<DrawableStrongNestedHit> strongHitContainer;
protected DrawableTaikoHitObject(TaikoHitType hitObject)
protected DrawableTaikoHitObject(TTaikoHit hitObject)
: base(hitObject)
{
HitObject = hitObject;

View File

@ -15,15 +15,21 @@ using osu.Game.Rulesets.Replays.Types;
using osu.Game.Rulesets.Taiko.Replays;
using osu.Game.Beatmaps.Legacy;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Beatmaps;
using osu.Game.Rulesets.Taiko.Difficulty;
using osu.Game.Rulesets.Taiko.Scoring;
using osu.Game.Scoring;
using System;
namespace osu.Game.Rulesets.Taiko
{
public class TaikoRuleset : Ruleset
{
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableTaikoRuleset(this, beatmap, mods);
public override ScoreProcessor CreateScoreProcessor(IBeatmap beatmap) => new TaikoScoreProcessor(beatmap);
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap);
public const string SHORT_NAME = "taiko";
@ -113,7 +119,7 @@ namespace osu.Game.Rulesets.Taiko
};
default:
return new Mod[] { };
return Array.Empty<Mod>();
}
}

View File

@ -5,10 +5,8 @@ using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.Taiko.Replays;
using osu.Framework.Input;
@ -40,8 +38,6 @@ namespace osu.Game.Rulesets.Taiko.UI
new BarLineGenerator<BarLine>(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar.Major ? new DrawableBarLineMajor(bar) : new DrawableBarLine(bar)));
}
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(Beatmap);
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer();
protected override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo);

View File

@ -25,7 +25,7 @@ namespace osu.Game.Tests.NonVisual
{
Assert.AreEqual(0, stack.Count);
Assert.Throws<IndexOutOfRangeException>(() =>
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
int unused = stack[0];
});
@ -55,7 +55,7 @@ namespace osu.Game.Tests.NonVisual
// e.g. indices 3, 4, 5, 6 (out of range)
for (int i = stack.Count; i < stack.Count + capacity; i++)
{
Assert.Throws<IndexOutOfRangeException>(() =>
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
int unused = stack[i];
});
@ -80,7 +80,7 @@ namespace osu.Game.Tests.NonVisual
// e.g. indices 3, 4, 5, 6 (out of range)
for (int i = stack.Count; i < stack.Count + capacity; i++)
{
Assert.Throws<IndexOutOfRangeException>(() =>
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
int unused = stack[i];
});

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
@ -31,7 +32,7 @@ namespace osu.Game.Tests.Visual.Gameplay
requestCount = 0;
increment = skip_time;
Child = gameplayClockContainer = new GameplayClockContainer(CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)), new Mod[] { }, 0)
Child = gameplayClockContainer = new GameplayClockContainer(CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)), Array.Empty<Mod>(), 0)
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]

View File

@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
});
AddStep(@"set max", () => Room.MaxParticipants.Value = 10);
AddStep(@"clear users", () => Room.Participants.Value = new User[] { });
AddStep(@"clear users", () => Room.Participants.Value = System.Array.Empty<User>());
AddStep(@"set max to null", () => Room.MaxParticipants.Value = null);
}
}

View File

@ -0,0 +1,42 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Overlays.Profile.Sections;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneProfileCounterPill : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(CounterPill)
};
private readonly CounterPill pill;
private readonly BindableInt value = new BindableInt();
public TestSceneProfileCounterPill()
{
Child = pill = new CounterPill
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Current = { BindTarget = value }
};
}
[Test]
public void TestVisibility()
{
AddStep("Set value to 0", () => value.Value = 0);
AddAssert("Check hidden", () => !pill.IsPresent);
AddStep("Set value to 10", () => value.Value = 10);
AddAssert("Check visible", () => pill.IsPresent);
}
}
}

View File

@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual.Online
},
Title = "osu!volunteer",
Colour = "ff0000",
Achievements = new User.UserAchievement[0],
Achievements = Array.Empty<User.UserAchievement>(),
};
public TestSceneUserProfileOverlay()

View File

@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Online
new User { PreviousUsernames = new[] { "longusername", "longerusername" } },
new User { PreviousUsernames = new[] { "test", "angelsim", "verylongusername" } },
new User { PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" } },
new User { PreviousUsernames = new string[0] },
new User { PreviousUsernames = Array.Empty<string>() },
null
};

View File

@ -111,7 +111,7 @@ namespace osu.Game.Tests.Visual
foreach (var type in requiredGameDependencies)
{
if (game.Dependencies.Get(type) == null)
throw new Exception($"{type} has not been cached");
throw new InvalidOperationException($"{type} has not been cached");
}
return true;
@ -121,7 +121,7 @@ namespace osu.Game.Tests.Visual
foreach (var type in requiredGameBaseDependencies)
{
if (gameBase.Dependencies.Get(type) == null)
throw new Exception($"{type} has not been cached");
throw new InvalidOperationException($"{type} has not been cached");
}
return true;

View File

@ -49,7 +49,7 @@ namespace osu.Game.Tournament.Screens.Editors
get
{
if (editorInfo == null)
return new MenuItem[0];
return Array.Empty<MenuItem>();
return new MenuItem[]
{

View File

@ -192,7 +192,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
get
{
if (editorInfo == null)
return new MenuItem[0];
return Array.Empty<MenuItem>();
return new MenuItem[]
{

View File

@ -98,7 +98,7 @@ namespace osu.Game.Beatmaps
{
if (string.IsNullOrEmpty(value))
{
Bookmarks = new int[0];
Bookmarks = Array.Empty<int>();
return;
}
@ -111,7 +111,7 @@ namespace osu.Game.Beatmaps
}
[NotMapped]
public int[] Bookmarks { get; set; } = new int[0];
public int[] Bookmarks { get; set; } = Array.Empty<int>();
public double DistanceSpacing { get; set; }
public int BeatDivisor { get; set; }

View File

@ -42,7 +42,7 @@ namespace osu.Game.Beatmaps
}
}
private string getPathForFile(string filename) => BeatmapSetInfo.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath;
private string getPathForFile(string filename) => BeatmapSetInfo.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
private TextureStore textureStore;

View File

@ -70,6 +70,6 @@ namespace osu.Game.Beatmaps.ControlPoints
public override bool EquivalentTo(ControlPoint other) =>
other is SampleControlPoint otherTyped &&
string.Equals(SampleBank, otherTyped.SampleBank) && SampleVolume == otherTyped.SampleVolume;
SampleBank == otherTyped.SampleBank && SampleVolume == otherTyped.SampleVolume;
}
}

View File

@ -55,7 +55,7 @@ namespace osu.Game.Beatmaps
private class DummyRuleset : Ruleset
{
public override IEnumerable<Mod> GetModsFor(ModType type) => new Mod[] { };
public override IEnumerable<Mod> GetModsFor(ModType type) => Array.Empty<Mod>();
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
{

View File

@ -7,9 +7,9 @@ using osu.Framework.Platform;
namespace osu.Game.Database
{
public abstract class MutableDatabaseBackedStoreWithFileIncludes<T, U> : MutableDatabaseBackedStore<T>
where T : class, IHasPrimaryKey, ISoftDelete, IHasFiles<U>
where U : INamedFileInfo
public abstract class MutableDatabaseBackedStoreWithFileIncludes<T, TFileInfo> : MutableDatabaseBackedStore<T>
where T : class, IHasPrimaryKey, ISoftDelete, IHasFiles<TFileInfo>
where TFileInfo : INamedFileInfo
{
protected MutableDatabaseBackedStoreWithFileIncludes(IDatabaseContextFactory contextFactory, Storage storage = null)
: base(contextFactory, storage)

View File

@ -119,7 +119,7 @@ namespace osu.Game.Graphics
break;
default:
throw new ArgumentOutOfRangeException(nameof(screenshotFormat));
throw new InvalidOperationException($"Unknown enum member {nameof(ScreenshotFormat)} {screenshotFormat.Value}.");
}
notificationOverlay.Post(new SimpleNotification

View File

@ -7,15 +7,15 @@ using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterfaceV2
{
public abstract class LabelledComponent<T, U> : LabelledDrawable<T>, IHasCurrentValue<U>
where T : Drawable, IHasCurrentValue<U>
public abstract class LabelledComponent<TDrawable, TValue> : LabelledDrawable<TDrawable>, IHasCurrentValue<TValue>
where TDrawable : Drawable, IHasCurrentValue<TValue>
{
protected LabelledComponent(bool padded)
: base(padded)
{
}
public Bindable<U> Current
public Bindable<TValue> Current
{
get => Component.Current;
set => Component.Current = value;

View File

@ -116,13 +116,13 @@ namespace osu.Game.IO.Legacy
}
/// <summary> Reads a generic Dictionary from the buffer. </summary>
public IDictionary<T, U> ReadDictionary<T, U>()
public IDictionary<TKey, TValue> ReadDictionary<TKey, TValue>()
{
int count = ReadInt32();
if (count < 0) return null;
IDictionary<T, U> d = new Dictionary<T, U>();
for (int i = 0; i < count; i++) d[(T)ReadObject()] = (U)ReadObject();
IDictionary<TKey, TValue> d = new Dictionary<TKey, TValue>();
for (int i = 0; i < count; i++) d[(TKey)ReadObject()] = (TValue)ReadObject();
return d;
}
@ -192,7 +192,7 @@ namespace osu.Game.IO.Legacy
}
}
public class DynamicDeserializer
public static class DynamicDeserializer
{
private static VersionConfigToNamespaceAssemblyObjectBinder versionBinder;
private static BinaryFormatter formatter;

View File

@ -102,7 +102,7 @@ namespace osu.Game.IO.Legacy
}
/// <summary> Writes a generic IDictionary to the buffer. </summary>
public void Write<T, U>(IDictionary<T, U> d)
public void Write<TKey, TValue>(IDictionary<TKey, TValue> d)
{
if (d == null)
{
@ -112,7 +112,7 @@ namespace osu.Game.IO.Legacy
{
Write(d.Count);
foreach (KeyValuePair<T, U> kvp in d)
foreach (KeyValuePair<TKey, TValue> kvp in d)
{
WriteObject(kvp.Key);
WriteObject(kvp.Value);

View File

@ -10,6 +10,7 @@ using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ExceptionExtensions;
using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Game.Configuration;
@ -249,7 +250,7 @@ namespace osu.Game.Online.API
catch
{
// if we couldn't deserialize the error message let's throw the original exception outwards.
throw e;
e.Rethrow();
}
}

View File

@ -122,7 +122,7 @@ namespace osu.Game.Online.API
// attempt to decode a displayable error string.
var error = JsonConvert.DeserializeObject<DisplayableError>(responseString);
if (error != null)
e = new Exception(error.ErrorMessage, e);
e = new APIException(error.ErrorMessage, e);
}
catch
{
@ -154,6 +154,14 @@ namespace osu.Game.Online.API
}
}
public class APIException : InvalidOperationException
{
public APIException(string messsage, Exception innerException)
: base(messsage, innerException)
{
}
}
public delegate void APIFailureHandler(Exception e);
public delegate void APISuccessHandler();

View File

@ -19,7 +19,7 @@ using osuTK.Graphics;
namespace osu.Game.Online.Leaderboards
{
public abstract class Leaderboard<TScope, ScoreInfo> : Container, IOnlineComponent
public abstract class Leaderboard<TScope, TScoreInfo> : Container, IOnlineComponent
{
private const double fade_duration = 300;
@ -39,9 +39,9 @@ namespace osu.Game.Online.Leaderboards
protected override Container<Drawable> Content => content;
private IEnumerable<ScoreInfo> scores;
private IEnumerable<TScoreInfo> scores;
public IEnumerable<ScoreInfo> Scores
public IEnumerable<TScoreInfo> Scores
{
get => scores;
set
@ -288,7 +288,7 @@ namespace osu.Game.Online.Leaderboards
/// </summary>
/// <param name="scoresCallback">A callback which should be called when fetching is completed. Scheduling is not required.</param>
/// <returns>An <see cref="APIRequest"/> responsible for the fetch operation. This will be queued and performed automatically.</returns>
protected abstract APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback);
protected abstract APIRequest FetchScores(Action<IEnumerable<TScoreInfo>> scoresCallback);
private Placeholder currentPlaceholder;
@ -359,6 +359,6 @@ namespace osu.Game.Online.Leaderboards
}
}
protected abstract LeaderboardScore CreateDrawableScore(ScoreInfo model, int index);
protected abstract LeaderboardScore CreateDrawableScore(TScoreInfo model, int index);
}
}

View File

@ -116,7 +116,7 @@ namespace osu.Game.Overlays
Filter.Search.Current.ValueChanged += text =>
{
if (text.NewValue != string.Empty)
if (!string.IsNullOrEmpty(text.NewValue))
{
Header.Tabs.Current.Value = DirectTab.Search;

View File

@ -81,7 +81,7 @@ namespace osu.Game.Overlays.Mods
}
}
private ModButton[] buttons = { };
private ModButton[] buttons = Array.Empty<ModButton>();
protected override bool OnKeyDown(KeyDownEvent e)
{

View File

@ -239,7 +239,7 @@ namespace osu.Game.Overlays.Music
private class ItemSearchContainer : FillFlowContainer<PlaylistItem>, IHasFilterableChildren
{
public IEnumerable<string> FilterTerms => new string[] { };
public IEnumerable<string> FilterTerms => Array.Empty<string>();
public bool MatchingFilter
{

View File

@ -12,7 +12,7 @@ namespace osu.Game.Overlays
AccentColour = AccentColour,
};
private class OverlayHeaderTabItem : OverlayTabItem<string>
private class OverlayHeaderTabItem : OverlayTabItem
{
public OverlayHeaderTabItem(string value)
: base(value)

View File

@ -32,7 +32,7 @@ namespace osu.Game.Overlays
foreach (TabItem<T> tabItem in TabContainer)
{
((OverlayTabItem<T>)tabItem).AccentColour = value;
((OverlayTabItem)tabItem).AccentColour = value;
}
}
}
@ -59,9 +59,9 @@ namespace osu.Game.Overlays
protected override Dropdown<T> CreateDropdown() => null;
protected override TabItem<T> CreateTabItem(T value) => new OverlayTabItem<T>(value);
protected override TabItem<T> CreateTabItem(T value) => new OverlayTabItem(value);
protected class OverlayTabItem<U> : TabItem<U>
protected class OverlayTabItem : TabItem<T>
{
private readonly ExpandingBar bar;
@ -84,7 +84,7 @@ namespace osu.Game.Overlays
}
}
public OverlayTabItem(U value)
public OverlayTabItem(T value)
: base(value)
{
AutoSizeAxes = Axes.X;

View File

@ -38,5 +38,15 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
};
protected override int GetCount(User user) => type switch
{
BeatmapSetType.Favourite => user.FavouriteBeatmapsetCount,
BeatmapSetType.Graveyard => user.GraveyardBeatmapsetCount,
BeatmapSetType.Loved => user.LovedBeatmapsetCount,
BeatmapSetType.RankedAndApproved => user.RankedAndApprovedBeatmapsetCount,
BeatmapSetType.Unranked => user.UnrankedBeatmapsetCount,
_ => 0
};
}
}

View File

@ -0,0 +1,61 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Framework.Bindables;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Overlays.Profile.Sections
{
public class CounterPill : CircularContainer
{
private const int duration = 200;
public readonly BindableInt Current = new BindableInt();
private readonly OsuSpriteText counter;
public CounterPill()
{
AutoSizeAxes = Axes.Both;
Alpha = 0;
Masking = true;
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(0.05f)
},
counter = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Margin = new MarginPadding { Horizontal = 10, Vertical = 5 },
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold)
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
Current.BindValueChanged(onCurrentChanged, true);
}
private void onCurrentChanged(ValueChangedEvent<int> value)
{
if (value.NewValue == 0)
{
this.FadeOut(duration, Easing.OutQuint);
return;
}
counter.Text = value.NewValue.ToString();
this.FadeIn(duration, Easing.OutQuint);
}
}
}

View File

@ -23,6 +23,7 @@ namespace osu.Game.Overlays.Profile.Sections
private readonly OsuSpriteText missingText;
private APIRequest<List<TModel>> retrievalRequest;
private CancellationTokenSource loadCancellation;
private readonly BindableInt count = new BindableInt();
[Resolved]
private IAPIProvider api { get; set; }
@ -44,11 +45,28 @@ namespace osu.Game.Overlays.Profile.Sections
Children = new Drawable[]
{
new OsuSpriteText
new FillFlowContainer
{
Text = header,
Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold),
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5, 0),
Margin = new MarginPadding { Top = 10, Bottom = 10 },
Children = new Drawable[]
{
new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Text = header,
Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold),
},
new CounterPill
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Current = { BindTarget = count }
}
}
},
ItemsContainer = new FillFlowContainer
{
@ -91,7 +109,10 @@ namespace osu.Game.Overlays.Profile.Sections
ItemsContainer.Clear();
if (e.NewValue != null)
{
showMore();
count.Value = GetCount(e.NewValue);
}
}
private void showMore()
@ -124,6 +145,8 @@ namespace osu.Game.Overlays.Profile.Sections
}, loadCancellation.Token);
});
protected virtual int GetCount(User user) => 0;
protected abstract APIRequest<List<TModel>> CreateRequest();
protected abstract Drawable CreateDrawableItem(TModel model);

View File

@ -32,6 +32,12 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
protected override APIRequest<List<APILegacyScoreInfo>> CreateRequest() =>
new GetUserScoresRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage);
protected override int GetCount(User user) => type switch
{
ScoreType.Firsts => user.ScoresFirstCount,
_ => 0
};
protected override Drawable CreateDrawableItem(APILegacyScoreInfo model)
{
switch (type)

View File

@ -12,11 +12,11 @@ namespace osu.Game.Overlays.Settings
{
}
public class SettingsSlider<T, U> : SettingsItem<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible
where U : OsuSliderBar<T>, new()
public class SettingsSlider<TValue, TSlider> : SettingsItem<TValue>
where TValue : struct, IEquatable<TValue>, IComparable<TValue>, IConvertible
where TSlider : OsuSliderBar<TValue>, new()
{
protected override Drawable CreateControl() => new U
protected override Drawable CreateControl() => new TSlider
{
Margin = new MarginPadding { Top = 5, Bottom = 5 },
RelativeSizeAxes = Axes.X
@ -24,14 +24,14 @@ namespace osu.Game.Overlays.Settings
public bool TransferValueOnCommit
{
get => ((U)Control).TransferValueOnCommit;
set => ((U)Control).TransferValueOnCommit = value;
get => ((TSlider)Control).TransferValueOnCommit;
set => ((TSlider)Control).TransferValueOnCommit = value;
}
public float KeyboardStep
{
get => ((U)Control).KeyboardStep;
set => ((U)Control).KeyboardStep = value;
get => ((TSlider)Control).KeyboardStep;
set => ((TSlider)Control).KeyboardStep = value;
}
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@ -55,10 +56,7 @@ namespace osu.Game.Overlays
new BeatmapsSection(),
new KudosuSection()
}
: new ProfileSection[]
{
//new AboutSection(),
};
: Array.Empty<ProfileSection>();
tabs = new ProfileTabControl
{
@ -167,7 +165,7 @@ namespace osu.Game.Overlays
AccentColour = colours.Seafoam;
}
private class ProfileTabItem : OverlayTabItem<ProfileSection>
private class ProfileTabItem : OverlayTabItem
{
public ProfileTabItem(ProfileSection value)
: base(value)

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Difficulty.Utils
public LimitedCapacityStack(int capacity)
{
if (capacity < 0)
throw new ArgumentOutOfRangeException();
throw new ArgumentOutOfRangeException(nameof(capacity));
this.capacity = capacity;
array = new T[capacity];
@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Difficulty.Utils
get
{
if (i < 0 || i > Count - 1)
throw new IndexOutOfRangeException();
throw new ArgumentOutOfRangeException(nameof(i));
i += marker;
if (i > capacity - 1)

View File

@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Mods
/// The mods this mod cannot be enabled with.
/// </summary>
[JsonIgnore]
public virtual Type[] IncompatibleMods => new Type[] { };
public virtual Type[] IncompatibleMods => Array.Empty<Type>();
/// <summary>
/// Creates a copy of this <see cref="Mod"/> initialised to a default state.

View File

@ -150,8 +150,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
if (HitObject.SampleControlPoint == null)
{
throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}."
+ $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}.");
throw new InvalidOperationException($"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}."
+ $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}.");
}
samples = samples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)).ToArray();

View File

@ -118,7 +118,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
int repeatCount = Parsing.ParseInt(split[6]);
if (repeatCount > 9000)
throw new ArgumentOutOfRangeException(nameof(repeatCount), @"Repeat count is way too high");
throw new FormatException(@"Repeat count is way too high");
// osu-stable treated the first span of the slider as a repeat, but no repeats are happening
repeatCount = Math.Max(0, repeatCount - 1);

View File

@ -18,6 +18,7 @@ using osu.Game.Beatmaps.Legacy;
using osu.Game.Configuration;
using osu.Game.Rulesets.Configuration;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Skinning;
@ -42,7 +43,7 @@ namespace osu.Game.Rulesets
/// </summary>
/// <param name="mods">The legacy enum which will be converted</param>
/// <returns>An enumerable of constructed <see cref="Mod"/>s</returns>
public virtual IEnumerable<Mod> ConvertLegacyMods(LegacyMods mods) => new Mod[] { };
public virtual IEnumerable<Mod> ConvertLegacyMods(LegacyMods mods) => Array.Empty<Mod>();
public ModAutoplay GetAutoplayMod() => GetAllMods().OfType<ModAutoplay>().First();
@ -62,6 +63,12 @@ namespace osu.Game.Rulesets
/// <returns></returns>
public abstract DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null);
/// <summary>
/// Creates a <see cref="ScoreProcessor"/> for a beatmap converted to this ruleset.
/// </summary>
/// <returns>The score processor.</returns>
public virtual ScoreProcessor CreateScoreProcessor(IBeatmap beatmap) => new ScoreProcessor(beatmap);
/// <summary>
/// Creates a <see cref="IBeatmapConverter"/> to convert a <see cref="IBeatmap"/> to one that is applicable for this <see cref="Ruleset"/>.
/// </summary>
@ -116,7 +123,7 @@ namespace osu.Game.Rulesets
/// </summary>
/// <param name="variant">A variant.</param>
/// <returns>A list of valid <see cref="KeyBinding"/>s.</returns>
public virtual IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new KeyBinding[] { };
public virtual IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => Array.Empty<KeyBinding>();
/// <summary>
/// Gets the name for a key binding variant. This is used for display in the settings overlay.

View File

@ -165,7 +165,7 @@ namespace osu.Game.Rulesets.Scoring
return miss;
default:
throw new ArgumentException(nameof(result));
throw new ArgumentException("Unknown enum member", nameof(result));
}
}

View File

@ -305,8 +305,6 @@ namespace osu.Game.Rulesets.UI
/// <returns>The Playfield.</returns>
protected abstract Playfield CreatePlayfield();
public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(Beatmap);
/// <summary>
/// Applies the active mods to this DrawableRuleset.
/// </summary>
@ -475,13 +473,6 @@ namespace osu.Game.Rulesets.UI
/// Invoked when the user requests to pause while the resume overlay is active.
/// </summary>
public abstract void CancelResume();
/// <summary>
/// Create a <see cref="ScoreProcessor"/> for the associated ruleset and link with this
/// <see cref="DrawableRuleset"/>.
/// </summary>
/// <returns>A score processor.</returns>
public abstract ScoreProcessor CreateScoreProcessor();
}
public class BeatmapInvalidForRulesetException : ArgumentException
@ -515,34 +506,34 @@ namespace osu.Game.Rulesets.UI
public Stream GetStream(string name) => primary.GetStream(name) ?? secondary.GetStream(name);
public IEnumerable<string> GetAvailableResources() => throw new NotImplementedException();
public IEnumerable<string> GetAvailableResources() => throw new NotSupportedException();
public void AddAdjustment(AdjustableProperty type, BindableNumber<double> adjustBindable) => throw new NotImplementedException();
public void AddAdjustment(AdjustableProperty type, BindableNumber<double> adjustBindable) => throw new NotSupportedException();
public void RemoveAdjustment(AdjustableProperty type, BindableNumber<double> adjustBindable) => throw new NotImplementedException();
public void RemoveAdjustment(AdjustableProperty type, BindableNumber<double> adjustBindable) => throw new NotSupportedException();
public BindableNumber<double> Volume => throw new NotImplementedException();
public BindableNumber<double> Volume => throw new NotSupportedException();
public BindableNumber<double> Balance => throw new NotImplementedException();
public BindableNumber<double> Balance => throw new NotSupportedException();
public BindableNumber<double> Frequency => throw new NotImplementedException();
public BindableNumber<double> Frequency => throw new NotSupportedException();
public BindableNumber<double> Tempo => throw new NotImplementedException();
public BindableNumber<double> Tempo => throw new NotSupportedException();
public IBindable<double> GetAggregate(AdjustableProperty type) => throw new NotImplementedException();
public IBindable<double> GetAggregate(AdjustableProperty type) => throw new NotSupportedException();
public IBindable<double> AggregateVolume => throw new NotImplementedException();
public IBindable<double> AggregateVolume => throw new NotSupportedException();
public IBindable<double> AggregateBalance => throw new NotImplementedException();
public IBindable<double> AggregateBalance => throw new NotSupportedException();
public IBindable<double> AggregateFrequency => throw new NotImplementedException();
public IBindable<double> AggregateFrequency => throw new NotSupportedException();
public IBindable<double> AggregateTempo => throw new NotImplementedException();
public IBindable<double> AggregateTempo => throw new NotSupportedException();
public int PlaybackConcurrency
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
get => throw new NotSupportedException();
set => throw new NotSupportedException();
}
public void Dispose()

View File

@ -57,7 +57,7 @@ namespace osu.Game.Scoring
}
protected override IEnumerable<string> GetStableImportPaths(Storage stableStorage)
=> stableStorage.GetFiles(ImportFromStablePath).Where(p => HandledExtensions.Any(ext => Path.GetExtension(p)?.Equals(ext, StringComparison.InvariantCultureIgnoreCase) ?? false));
=> stableStorage.GetFiles(ImportFromStablePath).Where(p => HandledExtensions.Any(ext => Path.GetExtension(p)?.Equals(ext, StringComparison.OrdinalIgnoreCase) ?? false));
public Score GetScore(ScoreInfo score) => new LegacyDatabasedScore(score, rulesets, beatmaps(), Files.Store);

View File

@ -128,7 +128,7 @@ namespace osu.Game.Screens.Play
DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value);
ScoreProcessor = DrawableRuleset.CreateScoreProcessor();
ScoreProcessor = ruleset.CreateScoreProcessor(playableBeatmap);
ScoreProcessor.Mods.BindTo(Mods);
if (!ScoreProcessor.Mode.Disabled)

View File

@ -15,7 +15,7 @@ namespace osu.Game.Screens.Play
: base(() => new ReplayPlayer(score))
{
if (score.Replay == null)
throw new ArgumentNullException(nameof(score.Replay), $"{nameof(score)} must have a non-null {nameof(score.Replay)}.");
throw new ArgumentException($"{nameof(score)} must have a non-null {nameof(score.Replay)}.", nameof(score));
scoreInfo = score.ScoreInfo;
}

View File

@ -38,7 +38,7 @@ namespace osu.Game.Screens.Play
}
}
private float[] calculatedValues = { }; // values but adjusted to fit the amount of columns
private float[] calculatedValues = Array.Empty<float>(); // values but adjusted to fit the amount of columns
private int[] values;

View File

@ -37,13 +37,13 @@ namespace osu.Game.Screens.Select.Carousel
{
default:
case SortMode.Artist:
return string.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist, StringComparison.InvariantCultureIgnoreCase);
return string.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist, StringComparison.OrdinalIgnoreCase);
case SortMode.Title:
return string.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title, StringComparison.InvariantCultureIgnoreCase);
return string.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title, StringComparison.OrdinalIgnoreCase);
case SortMode.Author:
return string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.InvariantCultureIgnoreCase);
return string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.OrdinalIgnoreCase);
case SortMode.DateAdded:
return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded);

View File

@ -27,8 +27,8 @@ namespace osu.Game.Screens.Select.Details
metrics = value;
var retries = Metrics?.Retries ?? new int[0];
var fails = Metrics?.Fails ?? new int[0];
var retries = Metrics?.Retries ?? Array.Empty<int>();
var fails = Metrics?.Fails ?? Array.Empty<int>();
float maxValue = fails.Any() ? fails.Zip(retries, (fail, retry) => fail + retry).Max() : 0;
failGraph.MaxValue = maxValue;

View File

@ -105,7 +105,7 @@ namespace osu.Game.Screens.Select
public string SearchTerm;
public bool Equals(OptionalTextFilter other) => SearchTerm?.Equals(other.SearchTerm) ?? true;
public bool Equals(OptionalTextFilter other) => SearchTerm == other.SearchTerm;
}
}
}

View File

@ -34,7 +34,7 @@ namespace osu.Game.Skinning
}
private string getPathForFile(string filename) =>
source.Files.Find(f => string.Equals(f.Filename, filename, StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath;
source.Files.Find(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
public override IEnumerable<string> GetAvailableResources() => source.Files.Select(f => f.Filename);
}

View File

@ -71,7 +71,7 @@ namespace osu.Game.Storyboards.Drawables
{
var framePath = Animation.Path.Replace(".", frame + ".");
var path = beatmap.Value.BeatmapSetInfo.Files.Find(f => f.Filename.Equals(framePath, StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath;
var path = beatmap.Value.BeatmapSetInfo.Files.Find(f => f.Filename.Equals(framePath, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
if (path == null)
continue;

View File

@ -66,7 +66,7 @@ namespace osu.Game.Storyboards.Drawables
[BackgroundDependencyLoader]
private void load(IBindable<WorkingBeatmap> beatmap, TextureStore textureStore)
{
var path = beatmap.Value.BeatmapSetInfo?.Files?.Find(f => f.Filename.Equals(Sprite.Path, StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath;
var path = beatmap.Value.BeatmapSetInfo?.Files?.Find(f => f.Filename.Equals(Sprite.Path, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
if (path == null)
return;

View File

@ -126,6 +126,24 @@ namespace osu.Game.Users
[JsonProperty(@"follower_count")]
public int FollowerCount;
[JsonProperty(@"favourite_beatmapset_count")]
public int FavouriteBeatmapsetCount;
[JsonProperty(@"graveyard_beatmapset_count")]
public int GraveyardBeatmapsetCount;
[JsonProperty(@"loved_beatmapset_count")]
public int LovedBeatmapsetCount;
[JsonProperty(@"ranked_and_approved_beatmapset_count")]
public int RankedAndApprovedBeatmapsetCount;
[JsonProperty(@"unranked_beatmapset_count")]
public int UnrankedBeatmapsetCount;
[JsonProperty(@"scores_first_count")]
public int ScoresFirstCount;
[JsonProperty]
private string[] playstyle
{

View File

@ -63,7 +63,7 @@ namespace osu.Game.Users
private void load(UserProfileOverlay profile)
{
if (colours == null)
throw new ArgumentNullException(nameof(colours));
throw new InvalidOperationException($"{nameof(colours)} not initialized!");
FillFlowContainer infoContainer;

View File

@ -60,6 +60,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
global.json = global.json
osu.Android.props = osu.Android.props
osu.iOS.props = osu.iOS.props
CodeAnalysis\osu.ruleset = CodeAnalysis\osu.ruleset
osu.sln.DotSettings = osu.sln.DotSettings
osu.TestProject.props = osu.TestProject.props
EndProjectSection